]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/testsuite/lib/target-supports.exp
Revert "testsuite: Disable strub on AIX."
[thirdparty/gcc.git] / gcc / testsuite / lib / target-supports.exp
1 # Copyright (C) 1999-2024 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 # "/* Assembly" for assembly code,
34 # "// C++" for c++,
35 # "// D" for D,
36 # "! Fortran" for Fortran code,
37 # "/* ObjC", for ObjC
38 # "// ObjC++" for ObjC++
39 # "// Go" for Go
40 # "// Rust" for Rust
41 # and "(* Modula-2" for Modula-2
42 # If the tool is ObjC/ObjC++ then we overide the extension to .m/.mm to
43 # allow for ObjC/ObjC++ specific flags.
44
45 proc check_compile {basename type contents args} {
46 global tool
47 verbose "check_compile tool: $tool for $basename"
48
49 # Save additional_sources to avoid compiling testsuite's sources
50 # against check_compile's source.
51 global additional_sources
52 if [info exists additional_sources] {
53 set tmp_additional_sources "$additional_sources"
54 set additional_sources ""
55 }
56
57 if { [llength $args] > 0 } {
58 set options [list "additional_flags=[lindex $args 0]"]
59 } else {
60 set options ""
61 }
62 # Silence "command-line option [...] is valid for [...] but not for [...]"
63 # that we may easily run into here, if more than one language is involved.
64 lappend options additional_flags=-Wno-complain-wrong-lang
65
66 switch -glob -- $contents {
67 "*/\\* Assembly*" { set src ${basename}[pid].S }
68 "*! Fortran*" { set src ${basename}[pid].f90 }
69 "*// C++*" { set src ${basename}[pid].cc }
70 "*// D*" { set src ${basename}[pid].d }
71 "*// ObjC++*" { set src ${basename}[pid].mm }
72 "*/\\* ObjC*" { set src ${basename}[pid].m }
73 "*// Go*" { set src ${basename}[pid].go }
74 "*// Rust*" { set src ${basename}[pid].rs }
75 "*(\\* Modula-2*" { set src ${basename}[pid].mod }
76 default {
77 switch -- $tool {
78 "objc" { set src ${basename}[pid].m }
79 "obj-c++" { set src ${basename}[pid].mm }
80 default { set src ${basename}[pid].c }
81 }
82 }
83 }
84
85 set compile_type $type
86 switch -glob $type {
87 assembly { set output ${basename}[pid].s }
88 object { set output ${basename}[pid].o }
89 executable { set output ${basename}[pid].exe }
90 "tree-*" -
91 "rtl-*" {
92 set output ${basename}[pid].s
93 lappend options "additional_flags=-fdump-$type"
94 set compile_type assembly
95 }
96 }
97 set f [open $src "w"]
98 puts $f $contents
99 close $f
100 global compiler_flags
101 set save_compiler_flags $compiler_flags
102 set lines [${tool}_target_compile $src $output $compile_type "$options"]
103 set compiler_flags $save_compiler_flags
104 file delete $src
105
106 set scan_output $output
107 # Don't try folding this into the switch above; calling "glob" before the
108 # file is created won't work.
109 if [regexp "rtl-(.*)" $type dummy rtl_type] {
110 set scan_output "[glob $src.\[0-9\]\[0-9\]\[0-9\]r.$rtl_type]"
111 file delete $output
112 } elseif [regexp "tree-(.*)" $type dummy tree_type] {
113 set scan_output "[glob $src.\[0-9\]\[0-9\]\[0-9\]t.$tree_type]"
114 file delete $output
115 }
116
117 # Restore additional_sources.
118 if [info exists additional_sources] {
119 set additional_sources "$tmp_additional_sources"
120 }
121
122 return [list $lines $scan_output]
123 }
124
125 proc current_target_name { } {
126 global target_info
127 if [info exists target_info(target,name)] {
128 set answer $target_info(target,name)
129 } else {
130 set answer ""
131 }
132 return $answer
133 }
134
135 # Implement an effective-target check for property PROP by invoking
136 # the Tcl command ARGS and seeing if it returns true.
137
138 proc check_cached_effective_target { prop args } {
139 global et_cache
140
141 set target [current_target_name]
142 if {![info exists et_cache($prop,$target)]} {
143 verbose "check_cached_effective_target $prop: checking $target" 2
144 if {[string is true -strict $args] || [string is false -strict $args]} {
145 error {check_cached_effective_target condition already evaluated; did you pass [...] instead of the expected {...}?}
146 } else {
147 set code [catch {uplevel eval $args} result]
148 if {$code != 0 && $code != 2} {
149 return -code $code $result
150 }
151 set et_cache($prop,$target) $result
152 }
153 }
154 set value $et_cache($prop,$target)
155 verbose "check_cached_effective_target $prop: returning $value for $target" 2
156 return $value
157 }
158
159 # Implements a version of check_cached_effective_target that also takes et_index
160 # into account when creating the key for the cache.
161 proc check_cached_effective_target_indexed { prop args } {
162 global et_index
163 set key "$et_index $prop"
164 verbose "check_cached_effective_target_index $prop: returning $key" 2
165
166 return [check_cached_effective_target $key [list uplevel eval $args]]
167 }
168
169 # Clear effective-target cache. This is useful after testing
170 # effective-target features and overriding TEST_ALWAYS_FLAGS and/or
171 # ALWAYS_CXXFLAGS.
172 # If one changes ALWAYS_CXXFLAGS or TEST_ALWAYS_FLAGS then they should
173 # do a clear_effective_target_cache at the end as the target cache can
174 # make decisions based upon the flags, and those decisions need to be
175 # redone when the flags change. An example of this is the
176 # asan_init/asan_finish pair.
177
178 proc clear_effective_target_cache { } {
179 global et_cache
180 array unset et_cache
181 }
182
183 # Like check_compile, but delete the output file and return true if the
184 # compiler printed no messages.
185 proc check_no_compiler_messages_nocache {args} {
186 set result [eval check_compile $args]
187 set lines [lindex $result 0]
188 set output [lindex $result 1]
189 remote_file build delete $output
190 return [string match "" $lines]
191 }
192
193 # Like check_no_compiler_messages_nocache, but cache the result.
194 # PROP is the property we're checking, and doubles as a prefix for
195 # temporary filenames.
196 proc check_no_compiler_messages {prop args} {
197 return [check_cached_effective_target $prop {
198 eval [list check_no_compiler_messages_nocache $prop] $args
199 }]
200 }
201
202 # Like check_compile, but return true if the compiler printed no
203 # messages and if the contents of the output file satisfy PATTERN.
204 # If PATTERN has the form "!REGEXP", the contents satisfy it if they
205 # don't match regular expression REGEXP, otherwise they satisfy it
206 # if they do match regular expression PATTERN. (PATTERN can start
207 # with something like "[!]" if the regular expression needs to match
208 # "!" as the first character.)
209 #
210 # Delete the output file before returning. The other arguments are
211 # as for check_compile.
212 proc check_no_messages_and_pattern_nocache {basename pattern args} {
213 global tool
214
215 set result [eval [list check_compile $basename] $args]
216 set lines [lindex $result 0]
217 set output [lindex $result 1]
218
219 set ok 0
220 if { [string match "" $lines] } {
221 set chan [open "$output"]
222 set invert [regexp {^!(.*)} $pattern dummy pattern]
223 set ok [expr { [regexp $pattern [read $chan]] != $invert }]
224 close $chan
225 }
226
227 remote_file build delete $output
228 return $ok
229 }
230
231 # Like check_no_messages_and_pattern_nocache, but cache the result.
232 # PROP is the property we're checking, and doubles as a prefix for
233 # temporary filenames.
234 proc check_no_messages_and_pattern {prop pattern args} {
235 return [check_cached_effective_target $prop {
236 eval [list check_no_messages_and_pattern_nocache $prop $pattern] $args
237 }]
238 }
239
240 # Try to compile and run an executable from code CONTENTS. Return true
241 # if the compiler reports no messages and if execution "passes" in the
242 # usual DejaGNU sense. The arguments are as for check_compile, with
243 # TYPE implicitly being "executable".
244 proc check_runtime_nocache {basename contents args} {
245 global tool
246
247 set result [eval [list check_compile $basename executable $contents] $args]
248 set lines [lindex $result 0]
249 set output [lindex $result 1]
250
251 set ok 0
252 if { [string match "" $lines] } {
253 # No error messages, everything is OK.
254 set result [remote_load target "./$output" "" ""]
255 set status [lindex $result 0]
256 verbose "check_runtime_nocache $basename: status is <$status>" 2
257 if { $status == "pass" } {
258 set ok 1
259 }
260 }
261 remote_file build delete $output
262 return $ok
263 }
264
265 # Like check_runtime_nocache, but cache the result. PROP is the
266 # property we're checking, and doubles as a prefix for temporary
267 # filenames.
268 proc check_runtime {prop args} {
269 global tool
270
271 return [check_cached_effective_target $prop {
272 eval [list check_runtime_nocache $prop] $args
273 }]
274 }
275
276 # Return 1 if GCC was configured with $pattern.
277 proc check_configured_with { pattern } {
278 global tool
279
280 set options [list "additional_flags=-v"]
281 set gcc_output [${tool}_target_compile "" "" "none" $options]
282 if { [ regexp "Configured with: \[^\n\]*$pattern" $gcc_output ] } {
283 verbose "Matched: $pattern" 2
284 return 1
285 }
286
287 verbose "Failed to match: $pattern" 2
288 return 0
289 }
290
291 ###############################
292 # proc check_weak_available { }
293 ###############################
294
295 # weak symbols are only supported in some configs/object formats
296 # this proc returns 1 if they're supported, 0 if they're not, or -1 if unsure
297
298 proc check_weak_available { } {
299 global target_cpu
300
301 # All mips targets should support it
302
303 if { [ string first "mips" $target_cpu ] >= 0 } {
304 return 1
305 }
306
307 # All AIX targets should support it
308
309 if { [istarget *-*-aix*] } {
310 return 1
311 }
312
313 # All solaris2 targets should support it
314
315 if { [istarget *-*-solaris2*] } {
316 return 1
317 }
318
319 # Windows targets Cygwin and MingW32 support it
320
321 if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
322 return 1
323 }
324
325 # nvptx (nearly) supports it
326
327 if { [istarget nvptx-*-*] } {
328 return 1
329 }
330
331 # pdp11 doesn't support it
332
333 if { [istarget pdp11*-*-*] } {
334 return 0
335 }
336
337 # VxWorks hardly supports it (vx7 RTPs only)
338
339 if { [istarget *-*-vxworks*] } {
340 return 0
341 }
342
343 # ELF and ECOFF support it. a.out does with gas/gld but may also with
344 # other linkers, so we should try it
345
346 set objformat [gcc_target_object_format]
347
348 switch $objformat {
349 elf { return 1 }
350 ecoff { return 1 }
351 a.out { return 1 }
352 mach-o { return 1 }
353 som { return 1 }
354 unknown { return -1 }
355 default { return 0 }
356 }
357 }
358
359 # return options to add to enable weak undefined symbols.
360
361 proc add_options_for_weak_undefined { flags } {
362 if { [istarget *-*-darwin*] } {
363 lappend flags "-Wl,-undefined,dynamic_lookup"
364 if { [istarget *-*-darwin\[89\]*] } {
365 lappend flags "-Wl,-flat_namespace"
366 }
367 }
368 return $flags
369 }
370
371 # return 1 if weak undefined symbols are supported.
372
373 proc check_effective_target_weak_undefined { } {
374 if { [istarget hppa*-*-hpux*] } {
375 return 0
376 }
377 return [check_runtime weak_undefined {
378 extern void foo () __attribute__((weak));
379 int main (void) { if (foo) return 1; return 0; }
380 } [add_options_for_weak_undefined ""]]
381 }
382
383 ###############################
384 # proc check_weak_override_available { }
385 ###############################
386
387 # Like check_weak_available, but return 0 if weak symbol definitions
388 # cannot be overridden.
389
390 proc check_weak_override_available { } {
391 if { [istarget *-*-mingw*] } {
392 return 0
393 }
394 return [check_weak_available]
395 }
396
397 # Return 1 if VMA is equal to LMA for the .data section, 0
398 # otherwise. Cache the result.
399
400 proc check_effective_target_vma_equals_lma { } {
401 global tool
402
403 return [check_cached_effective_target vma_equals_lma {
404 set src vma_equals_lma[pid].c
405 set exe vma_equals_lma[pid].exe
406 verbose "check_effective_target_vma_equals_lma compiling testfile $src" 2
407 set f [open $src "w"]
408 puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif\n"
409 puts $f "int foo = 42; void main() {}"
410 close $f
411 set lines [${tool}_target_compile $src $exe executable ""]
412 file delete $src
413
414 if [string match "" $lines] then {
415 # No error messages
416
417 set objdump_name [find_binutils_prog objdump]
418 set output [remote_exec host "$objdump_name" "--section-headers --section=.data $exe"]
419 set output [lindex $output 1]
420
421 remote_file build delete $exe
422
423 # Example output of objdump:
424 #vma_equals_lma9059.exe: file format elf32-littlearm
425 #
426 #Sections:
427 #Idx Name Size VMA LMA File off Algn
428 # 6 .data 00000558 20000000 08002658 00020000 2**3
429 # CONTENTS, ALLOC, LOAD, DATA
430
431 # Capture LMA and VMA columns for .data section
432 if ![ regexp {\d*\d+\s+\.data\s+\d+\s+(\d+)\s+(\d+)} $output dummy vma lma ] {
433 verbose "Could not parse objdump output" 2
434 return 0
435 } else {
436 return [string equal $vma $lma]
437 }
438 } else {
439 remote_file build delete $exe
440 verbose "Could not determine if VMA is equal to LMA. Assuming not equal." 2
441 return 0
442 }
443 }]
444 }
445
446 # The "noinit" attribute is only supported by some targets.
447 # This proc returns 1 if it's supported, 0 if it's not.
448
449 proc check_effective_target_noinit { } {
450 if { [istarget arm*-*-eabi]
451 || [istarget msp430-*-*] } {
452 return 1
453 }
454
455 return 0
456 }
457
458 # The "persistent" attribute is only supported by some targets.
459 # This proc returns 1 if it's supported, 0 if it's not.
460
461 proc check_effective_target_persistent { } {
462 if { [istarget arm*-*-eabi]
463 || [istarget msp430-*-*] } {
464 return 1
465 }
466
467 return 0
468 }
469
470 ###############################
471 # proc check_visibility_available { what_kind }
472 ###############################
473
474 # The visibility attribute is only support in some object formats
475 # This proc returns 1 if it is supported, 0 if not.
476 # The argument is the kind of visibility, default/protected/hidden/internal.
477
478 proc check_visibility_available { what_kind } {
479 if [string match "" $what_kind] { set what_kind "hidden" }
480
481 return [check_no_compiler_messages visibility_available_$what_kind object "
482 void f() __attribute__((visibility(\"$what_kind\")));
483 void f() {}
484 "]
485 }
486
487 ###############################
488 # proc check_alias_available { }
489 ###############################
490
491 # Determine if the target toolchain supports the alias attribute.
492
493 # Returns 2 if the target supports aliases. Returns 1 if the target
494 # only supports weak aliased. Returns 0 if the target does not
495 # support aliases at all. Returns -1 if support for aliases could not
496 # be determined.
497
498 proc check_alias_available { } {
499 global tool
500
501 return [check_cached_effective_target alias_available {
502 set src alias[pid].c
503 set obj alias[pid].o
504 verbose "check_alias_available compiling testfile $src" 2
505 set f [open $src "w"]
506 # Compile a small test program. The definition of "g" is
507 # necessary to keep the Solaris assembler from complaining
508 # about the program.
509 puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif\n"
510 puts $f "void g() {} void f() __attribute__((alias(\"g\")));"
511 close $f
512 set lines [${tool}_target_compile $src $obj object ""]
513 file delete $src
514 remote_file build delete $obj
515
516 if [string match "" $lines] then {
517 # No error messages, everything is OK.
518 return 2
519 } else {
520 if [regexp "alias definitions not supported" $lines] {
521 verbose "check_alias_available target does not support aliases" 2
522
523 set objformat [gcc_target_object_format]
524
525 if { $objformat == "elf" } {
526 verbose "check_alias_available but target uses ELF format, so it ought to" 2
527 return -1
528 } else {
529 return 0
530 }
531 } else {
532 if [regexp "only weak aliases are supported" $lines] {
533 verbose "check_alias_available target supports only weak aliases" 2
534 return 1
535 } else {
536 return -1
537 }
538 }
539 }
540 }]
541 }
542
543 # Returns 1 if the target toolchain supports strong aliases, 0 otherwise.
544
545 proc check_effective_target_alias { } {
546 if { [check_alias_available] < 2 } {
547 return 0
548 } else {
549 return 1
550 }
551 }
552
553 # Returns 1 if the target uses the ELF object format, 0 otherwise.
554
555 proc check_effective_target_elf { } {
556 if { [gcc_target_object_format] == "elf" } {
557 return 1;
558 } else {
559 return 0;
560 }
561 }
562
563 # Returns 1 if the target toolchain supports ifunc, 0 otherwise.
564
565 proc check_ifunc_available { } {
566 return [check_no_compiler_messages ifunc_available object {
567 #ifdef __cplusplus
568 extern "C" {
569 #endif
570 extern void f_ ();
571 typedef void F (void);
572 F* g (void) { return &f_; }
573 void f () __attribute__ ((ifunc ("g")));
574 #ifdef __cplusplus
575 }
576 #endif
577 }]
578 }
579
580 # Returns true if --gc-sections is supported on the target.
581
582 proc check_gc_sections_available { } {
583 global tool
584
585 return [check_cached_effective_target gc_sections_available {
586 # Some targets don't support gc-sections despite whatever's
587 # advertised by ld's options.
588 if { [istarget alpha*-*-*]
589 || [istarget ia64-*-*] } {
590 return 0
591 }
592
593 # elf2flt uses -q (--emit-relocs), which is incompatible with
594 # --gc-sections.
595 if { [board_info target exists ldflags]
596 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
597 return 0
598 }
599
600 # VxWorks kernel modules are relocatable objects linked with -r,
601 # while RTP executables are linked with -q (--emit-relocs).
602 # Both of these options are incompatible with --gc-sections.
603 if { [istarget *-*-vxworks*] } {
604 return 0
605 }
606
607 # Check if the ld used by gcc supports --gc-sections.
608 set options [list "additional_flags=-print-prog-name=ld"]
609 set gcc_ld [lindex [${tool}_target_compile "" "" "none" $options] 0]
610 set ld_output [remote_exec host "$gcc_ld" "--help"]
611 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
612 return 1
613 } else {
614 return 0
615 }
616 }]
617 }
618
619 # Returns 1 if "dot" is supported on the host.
620
621 proc check_dot_available { } {
622 verbose "check_dot_available" 2
623
624 set status [remote_exec host "dot" "-V"]
625 verbose " status: $status" 2
626 if { [lindex $status 0] != 0 } {
627 return 0
628 }
629 return 1
630 }
631
632 # Return 1 if according to target_info struct and explicit target list
633 # target is supposed to support trampolines.
634
635 proc check_effective_target_trampolines { } {
636 if [target_info exists gcc,no_trampolines] {
637 return 0
638 }
639 if { [istarget avr-*-*]
640 || [istarget msp430-*-*]
641 || [istarget nvptx-*-*]
642 || [istarget pru-*-*]
643 || [istarget bpf-*-*] } {
644 return 0;
645 }
646 return 1
647 }
648
649 # Return 1 if target has limited stack size.
650
651 proc check_effective_target_stack_size { } {
652 # For nvptx target, stack size limits are relevant for execution only.
653 if { [istarget nvptx-*-*] } {
654 # Find 'dg-do-what' in an outer frame.
655 set level 1
656 while true {
657 upvar $level dg-do-what dg-do-what
658 if [info exists dg-do-what] then break
659 incr level
660 }
661 verbose "check_effective_target_stack_size: found dg-do-what at level $level" 2
662
663 if { ![string equal [lindex ${dg-do-what} 0] run] } {
664 return 0
665 }
666 }
667
668 if [target_info exists gcc,stack_size] {
669 return 1
670 }
671 return 0
672 }
673
674 # Return the value attribute of an effective target, otherwise return 0.
675
676 proc dg-effective-target-value { effective_target } {
677 if { "$effective_target" == "stack_size" } {
678 if [check_effective_target_stack_size] {
679 return [target_info gcc,stack_size]
680 }
681 }
682
683 return 0
684 }
685
686 # Return 1 if signal.h is supported.
687
688 proc check_effective_target_signal { } {
689 if [target_info exists gcc,signal_suppress] {
690 return 0
691 }
692 return 1
693 }
694
695 # Return 1 if according to target_info struct and explicit target list
696 # target disables -fdelete-null-pointer-checks. Targets should return 0
697 # if they simply default to -fno-delete-null-pointer-checks but obey
698 # -fdelete-null-pointer-checks when passed explicitly (and tests that
699 # depend on this option should do that).
700
701 proc check_effective_target_keeps_null_pointer_checks { } {
702 if [target_info exists keeps_null_pointer_checks] {
703 return 1
704 }
705 if { [istarget msp430-*-*]
706 || [istarget avr-*-*] } {
707 return 1;
708 }
709 return 0
710 }
711
712 # Return the autofdo profile wrapper
713
714 # Linux by default allows 516KB of perf event buffers
715 # in /proc/sys/kernel/perf_event_mlock_kb
716 # Each individual perf tries to grab it
717 # This causes problems with parallel test suite runs. Instead
718 # limit us to 8 pages (32K), which should be good enough
719 # for the small test programs. With the default settings
720 # this allows parallelism of 16 and higher of parallel gcc-auto-profile
721 proc profopt-perf-wrapper { } {
722 global srcdir
723 return "$srcdir/../config/i386/gcc-auto-profile --all -m8 "
724 }
725
726 # Return true if profiling is supported on the target.
727
728 proc check_profiling_available { test_what } {
729 verbose "Profiling argument is <$test_what>" 1
730
731 # These conditions depend on the argument so examine them before
732 # looking at the cache variable.
733
734 # Tree profiling requires TLS runtime support.
735 if { $test_what == "-fprofile-generate" } {
736 if { ![check_effective_target_tls_runtime] } {
737 return 0
738 }
739 }
740
741 if { $test_what == "-fauto-profile" } {
742 if { !([istarget i?86-*-linux*] || [istarget x86_64-*-linux*]) } {
743 verbose "autofdo only supported on linux"
744 return 0
745 }
746 # not cross compiling?
747 if { ![isnative] } {
748 verbose "autofdo not supported for non native builds"
749 return 0
750 }
751 set event [profopt-perf-wrapper]
752 if {$event == "" } {
753 verbose "autofdo not supported"
754 return 0
755 }
756 global srcdir
757 set status [remote_exec host "$srcdir/../config/i386/gcc-auto-profile" "-m8 true -v >/dev/null"]
758 if { [lindex $status 0] != 0 } {
759 verbose "autofdo not supported because perf does not work"
760 return 0
761 }
762
763 # no good way to check this in advance -- check later instead.
764 #set status [remote_exec host "create_gcov" "2>/dev/null"]
765 #if { [lindex $status 0] != 255 } {
766 # verbose "autofdo not supported due to missing create_gcov"
767 # return 0
768 #}
769 }
770
771 # Support for -p on solaris2 relies on mcrt1.o which comes with the
772 # vendor compiler. We cannot reliably predict the directory where the
773 # vendor compiler (and thus mcrt1.o) is installed so we can't
774 # necessarily find mcrt1.o even if we have it.
775 if { [istarget *-*-solaris2*] && $test_what == "-p" } {
776 return 0
777 }
778
779 # We don't yet support profiling for MIPS16.
780 if { [istarget mips*-*-*]
781 && ![check_effective_target_nomips16]
782 && ($test_what == "-p" || $test_what == "-pg") } {
783 return 0
784 }
785
786 # MinGW does not support -p.
787 if { [istarget *-*-mingw*] && $test_what == "-p" } {
788 return 0
789 }
790
791 # cygwin does not support -p.
792 if { [istarget *-*-cygwin*] && $test_what == "-p" } {
793 return 0
794 }
795
796 # uClibc does not have gcrt1.o.
797 if { [check_effective_target_uclibc]
798 && ($test_what == "-p" || $test_what == "-pg") } {
799 return 0
800 }
801
802 # Now examine the cache variable.
803 set profiling_working \
804 [check_cached_effective_target profiling_available {
805 # Some targets don't have any implementation of __bb_init_func or are
806 # missing other needed machinery.
807 if {[istarget aarch64*-*-elf]
808 || [istarget am3*-*-linux*]
809 || [istarget amdgcn-*-*]
810 || [istarget arm*-*-eabi*]
811 || [istarget arm*-*-elf]
812 || [istarget arm*-*-symbianelf*]
813 || [istarget avr-*-*]
814 || [istarget bfin-*-*]
815 || [istarget cris-*-*]
816 || [istarget csky-*-elf*]
817 || [istarget fido-*-elf]
818 || [istarget h8300-*-*]
819 || [istarget lm32-*-*]
820 || [istarget m32c-*-elf]
821 || [istarget m68k-*-elf]
822 || [istarget m68k-*-uclinux*]
823 || [istarget mips*-*-elf*]
824 || [istarget mmix-*-*]
825 || [istarget mn10300-*-elf*]
826 || [istarget moxie-*-elf*]
827 || [istarget msp430-*-*]
828 || [istarget nds32*-*-elf]
829 || [istarget nios2-*-elf]
830 || [istarget nvptx-*-*]
831 || [istarget powerpc-*-eabi*]
832 || [istarget powerpc-*-elf]
833 || [istarget pru-*-*]
834 || [istarget rx-*-*]
835 || [istarget tic6x-*-elf]
836 || [istarget visium-*-*]
837 || [istarget xstormy16-*]
838 || [istarget xtensa*-*-elf]
839 || [istarget *-*-rtems*]
840 || [istarget *-*-vxworks*] } {
841 return 0
842 } else {
843 return 1
844 }
845 }]
846
847 # -pg link test result can't be cached since it may change between
848 # runs.
849 if { $profiling_working == 1
850 && ![check_no_compiler_messages_nocache profiling executable {
851 int main() { return 0; } } "-pg"] } {
852 set profiling_working 0
853 }
854
855 return $profiling_working
856 }
857
858 # Check to see if a target is "freestanding". This is as per the definition
859 # in Section 4 of C99 standard. Effectively, it is a target which supports no
860 # extra headers or libraries other than what is considered essential.
861 proc check_effective_target_freestanding { } {
862 if { [istarget nvptx-*-*] } {
863 return 1
864 }
865 return 0
866 }
867
868 # Check to see that file I/O functions are available.
869 proc check_effective_target_fileio { } {
870 return [check_no_compiler_messages fileio_available executable {
871 #include <stdio.h>
872 int main() {
873 char *n = tmpnam (NULL);
874 FILE *f = fopen (n, "w");
875 fclose (f);
876 remove (n);
877 return 0;
878 } } ""]
879 }
880
881 # Return 1 if target has packed layout of structure members by
882 # default, 0 otherwise. Note that this is slightly different than
883 # whether the target has "natural alignment": both attributes may be
884 # false.
885
886 proc check_effective_target_default_packed { } {
887 return [check_no_compiler_messages default_packed assembly {
888 struct x { char a; long b; } c;
889 int s[sizeof (c) == sizeof (char) + sizeof (long) ? 1 : -1];
890 }]
891 }
892
893 # Return 1 if target has PCC_BITFIELD_TYPE_MATTERS defined. See
894 # documentation, where the test also comes from.
895
896 proc check_effective_target_pcc_bitfield_type_matters { } {
897 # PCC_BITFIELD_TYPE_MATTERS isn't just about unnamed or empty
898 # bitfields, but let's stick to the example code from the docs.
899 return [check_no_compiler_messages pcc_bitfield_type_matters assembly {
900 struct foo1 { char x; char :0; char y; };
901 struct foo2 { char x; int :0; char y; };
902 int s[sizeof (struct foo1) != sizeof (struct foo2) ? 1 : -1];
903 }]
904 }
905
906 # Add to FLAGS all the target-specific flags needed to use thread-local storage.
907
908 proc add_options_for_tls { flags } {
909 # On AIX, __tls_get_addr/___tls_get_addr only lives in
910 # libthread, so always pass -pthread for native TLS.
911 # Need to duplicate native TLS check from
912 # check_effective_target_tls_native to avoid recursion.
913 if { ([istarget powerpc-ibm-aix*]) &&
914 [check_no_messages_and_pattern tls_native "!emutls" assembly {
915 __thread int i;
916 int f (void) { return i; }
917 void g (int j) { i = j; }
918 }] } {
919 return "-pthread [g++_link_flags [get_multilibs "-pthread"] ] $flags "
920 }
921 return $flags
922 }
923
924 # Return 1 if indirect jumps are supported, 0 otherwise.
925
926 proc check_effective_target_indirect_jumps {} {
927 if { [istarget nvptx-*-*] || [istarget bpf-*-*] } {
928 return 0
929 }
930 return 1
931 }
932
933 # Return 1 if nonlocal goto is supported, 0 otherwise.
934
935 proc check_effective_target_nonlocal_goto {} {
936 if { [istarget nvptx-*-*] || [istarget bpf-*-*] } {
937 return 0
938 }
939 return 1
940 }
941
942 # Return 1 if global constructors are supported, 0 otherwise.
943
944 proc check_effective_target_global_constructor {} {
945 if { [istarget nvptx-*-*]
946 || [istarget bpf-*-*] } {
947 return 0
948 }
949 return 1
950 }
951
952 # Return 1 if taking label values is supported, 0 otherwise.
953
954 proc check_effective_target_label_values {} {
955 if { [istarget nvptx-*-*] || [target_info exists gcc,no_label_values] } {
956 return 0
957 }
958
959 return 1
960 }
961
962 # Return 1 if builtin_return_address and builtin_frame_address are
963 # supported, 0 otherwise.
964
965 proc check_effective_target_return_address {} {
966 if { [istarget nvptx-*-*] } {
967 return 0
968 }
969 # No notion of return address in eBPF.
970 if { [istarget bpf-*-*] } {
971 return 0
972 }
973 # It could be supported on amdgcn, but isn't yet.
974 if { [istarget amdgcn*-*-*] } {
975 return 0
976 }
977 return 1
978 }
979
980 # Return 1 if the assembler does not verify function types against
981 # calls, 0 otherwise. Such verification will typically show up problems
982 # with K&R C function declarations.
983
984 proc check_effective_target_untyped_assembly {} {
985 if { [istarget nvptx-*-*] } {
986 return 0
987 }
988 return 1
989 }
990
991 # Return 1 if alloca is supported, 0 otherwise.
992
993 proc check_effective_target_alloca {} {
994 if { [istarget bpf-*-*] } {
995 return 0
996 }
997 if { [istarget nvptx-*-*] } {
998 return [check_no_compiler_messages alloca assembly {
999 void f (void*);
1000 void g (int n) { f (__builtin_alloca (n)); }
1001 }]
1002 }
1003 return 1
1004 }
1005
1006 # Return 1 if thread local storage (TLS) is supported, 0 otherwise.
1007
1008 proc check_effective_target_tls {} {
1009 return [check_no_compiler_messages tls assembly {
1010 __thread int i;
1011 int f (void) { return i; }
1012 void g (int j) { i = j; }
1013 }]
1014 }
1015
1016 # Return 1 if *native* thread local storage (TLS) is supported, 0 otherwise.
1017
1018 proc check_effective_target_tls_native {} {
1019 # VxWorks uses emulated TLS machinery, but with non-standard helper
1020 # functions, so we fail to automatically detect it.
1021 if { [istarget *-*-vxworks*] } {
1022 return 0
1023 }
1024
1025 return [check_no_messages_and_pattern tls_native "!emutls" assembly {
1026 __thread int i;
1027 int f (void) { return i; }
1028 void g (int j) { i = j; }
1029 }]
1030 }
1031
1032 # Return 1 if *emulated* thread local storage (TLS) is supported, 0 otherwise.
1033
1034 proc check_effective_target_tls_emulated {} {
1035 # VxWorks uses emulated TLS machinery, but with non-standard helper
1036 # functions, so we fail to automatically detect it.
1037 if { [istarget *-*-vxworks*] } {
1038 return 1
1039 }
1040
1041 return [check_no_messages_and_pattern tls_emulated "emutls" assembly {
1042 __thread int i;
1043 int f (void) { return i; }
1044 void g (int j) { i = j; }
1045 }]
1046 }
1047
1048 # Return 1 if TLS executables can run correctly, 0 otherwise.
1049
1050 proc check_effective_target_tls_runtime {} {
1051 return [check_runtime tls_runtime {
1052 __thread int thr __attribute__((tls_model("global-dynamic"))) = 0;
1053 int main (void) { return thr; }
1054 } [add_options_for_tls ""]]
1055 }
1056
1057 # Return 1 if atomic compare-and-swap is supported on 'int'
1058
1059 proc check_effective_target_cas_char {} {
1060 return [check_no_compiler_messages cas_char assembly {
1061 #ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
1062 #error unsupported
1063 #endif
1064 } ""]
1065 }
1066
1067 proc check_effective_target_cas_int {} {
1068 return [check_no_compiler_messages cas_int assembly {
1069 #if __INT_MAX__ == 0x7fff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
1070 /* ok */
1071 #elif __INT_MAX__ == 0x7fffffff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
1072 /* ok */
1073 #else
1074 #error unsupported
1075 #endif
1076 } ""]
1077 }
1078
1079 # Return 1 if -ffunction-sections is supported, 0 otherwise.
1080
1081 proc check_effective_target_function_sections {} {
1082 # Darwin has its own scheme and silently accepts -ffunction-sections.
1083 if { [istarget *-*-darwin*] } {
1084 return 0
1085 }
1086
1087 return [check_no_compiler_messages functionsections assembly {
1088 void foo (void) { }
1089 } "-ffunction-sections"]
1090 }
1091
1092 # Return 1 if instruction scheduling is available, 0 otherwise.
1093
1094 proc check_effective_target_scheduling {} {
1095 return [check_no_compiler_messages scheduling object {
1096 void foo (void) { }
1097 } "-fschedule-insns"]
1098 }
1099
1100 # Return 1 if trapping arithmetic is available, 0 otherwise.
1101
1102 proc check_effective_target_trapping {} {
1103 return [check_no_compiler_messages trapping object {
1104 int add (int a, int b) { return a + b; }
1105 } "-ftrapv"]
1106 }
1107
1108 # Return 1 if compilation with -fgraphite is error-free for trivial
1109 # code, 0 otherwise.
1110
1111 proc check_effective_target_fgraphite {} {
1112 return [check_no_compiler_messages fgraphite object {
1113 void foo (void) { }
1114 } "-O1 -fgraphite"]
1115 }
1116
1117 # Return 1 if compiled with --enable-offload-targets=
1118 # This affects host compilation as ENABLE_OFFLOAD then evaluates to true.
1119 proc check_effective_target_offloading_enabled {} {
1120 return [check_configured_with "--enable-offload-targets"]
1121 }
1122
1123 # Return 1 if compilation with -fopenacc is error-free for trivial
1124 # code, 0 otherwise.
1125
1126 proc check_effective_target_fopenacc {} {
1127 # nvptx/amdgcn can be built with the device-side bits of openacc, but it
1128 # does not make sense to test it as an openacc host.
1129 if [istarget nvptx-*-*] { return 0 }
1130 if [istarget amdgcn-*-*] { return 0 }
1131
1132 return [check_no_compiler_messages fopenacc object {
1133 void foo (void) { }
1134 } "-fopenacc"]
1135 }
1136
1137 # Return 1 if compilation with -fopenmp is error-free for trivial
1138 # code, 0 otherwise.
1139
1140 proc check_effective_target_fopenmp {} {
1141 # nvptx/amdgcn can be built with the device-side bits of libgomp, but it
1142 # does not make sense to test it as an openmp host.
1143 if [istarget nvptx-*-*] { return 0 }
1144 if [istarget amdgcn-*-*] { return 0 }
1145
1146 return [check_no_compiler_messages fopenmp object {
1147 void foo (void) { }
1148 } "-fopenmp"]
1149 }
1150
1151 # Return 1 if compilation with -fgnu-tm is error-free for trivial
1152 # code, 0 otherwise.
1153
1154 proc check_effective_target_fgnu_tm {} {
1155 return [check_no_compiler_messages fgnu_tm object {
1156 void foo (void) { }
1157 } "-fgnu-tm"]
1158 }
1159
1160 # Return 1 if the target supports mmap, 0 otherwise.
1161
1162 proc check_effective_target_mmap {} {
1163 return [check_function_available "mmap"]
1164 }
1165
1166 # Return 1 if the target supports sysconf, 0 otherwise.
1167
1168 proc check_effective_target_sysconf {} {
1169 # VxWorks has sysconf in rtp mode only, but our way to test can't
1170 # tell kernel mode doesn't, as we're doing partial links for
1171 # kernel modules. We can tell by checking for a declaration, or
1172 # for some sysconf parm, because configurations that don't offer
1173 # sysconf don't have either.
1174 if { [istarget *-*-vxworks*] } {
1175 return [check_no_compiler_messages sysconfdecl assembly {
1176 #include <unistd.h>
1177 int f() { return sysconf(_SC_PAGESIZE); }
1178 }];
1179 }
1180 return [check_function_available "sysconf"]
1181 }
1182
1183 # Return 1 if the target supports dlopen, 0 otherwise.
1184 proc check_effective_target_dlopen {} {
1185 return [check_no_compiler_messages dlopen executable {
1186 #include <dlfcn.h>
1187 int main(void) { dlopen ("dummy.so", RTLD_NOW); }
1188 } [add_options_for_dlopen ""]]
1189 }
1190
1191 proc add_options_for_dlopen { flags } {
1192 return "$flags -ldl"
1193 }
1194
1195 # Return 1 if the target supports clone, 0 otherwise.
1196 proc check_effective_target_clone {} {
1197 return [check_function_available "clone"]
1198 }
1199
1200 # Return 1 if the target supports posix_memalign, 0 otherwise.
1201 proc check_effective_target_posix_memalign {} {
1202 if { [istarget *-*-vxworks*] } {
1203 # VxWorks doesn't have posix_memalign but our way to test
1204 # can't tell as we're doing partial links for kernel modules.
1205 return 0
1206 }
1207 return [check_function_available "posix_memalign"]
1208 }
1209
1210 # Return 1 if the target supports setrlimit, 0 otherwise.
1211 proc check_effective_target_setrlimit {} {
1212 # Darwin has non-posix compliant RLIMIT_AS
1213 if { [istarget *-*-darwin*] } {
1214 return 0
1215 }
1216 return [check_function_available "setrlimit"]
1217 }
1218
1219 # Return 1 if the target supports gettimeofday, 0 otherwise.
1220 proc check_effective_target_gettimeofday {} {
1221 return [check_function_available "gettimeofday"]
1222 }
1223
1224 # Return 1 if the target supports swapcontext, 0 otherwise.
1225 proc check_effective_target_swapcontext {} {
1226 return [check_no_compiler_messages swapcontext executable {
1227 #include <ucontext.h>
1228 int main (void)
1229 {
1230 ucontext_t orig_context,child_context;
1231 if (swapcontext(&child_context, &orig_context) < 0) { }
1232 }
1233 }]
1234 }
1235
1236 # Return 1 if the target supports POSIX threads, 0 otherwise.
1237 proc check_effective_target_pthread {} {
1238 return [check_no_compiler_messages pthread object {
1239 #include <pthread.h>
1240 void foo (void) { }
1241 } "-pthread"]
1242 }
1243
1244 # Return 1 if the target supports both Unix and internet sockets, 0 otherwise.
1245 proc check_effective_target_sockets {} {
1246 return [check_no_compiler_messages socket executable {
1247 #include <sys/socket.h>
1248 #include <sys/un.h>
1249 #include <netinet/in.h>
1250 int main (void) {
1251 socket(AF_UNIX, SOCK_STREAM, 0);
1252 socket(AF_INET, SOCK_DGRAM, 0);
1253 return 0;
1254 }
1255 } ""]
1256 }
1257
1258 # Return 1 if compilation with -mpe-aligned-commons is error-free
1259 # for trivial code, 0 otherwise.
1260
1261 proc check_effective_target_pe_aligned_commons {} {
1262 if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
1263 return [check_no_compiler_messages pe_aligned_commons object {
1264 int foo;
1265 } "-mpe-aligned-commons"]
1266 }
1267 return 0
1268 }
1269
1270 # Return 1 if the target supports -static
1271 proc check_effective_target_static {} {
1272 if { [istarget arm*-*-uclinuxfdpiceabi] } {
1273 return 0;
1274 }
1275 return [check_no_compiler_messages static executable {
1276 int main (void) { return 0; }
1277 } "-static"]
1278 }
1279
1280 # Return 1 if the target supports -fstack-protector
1281 proc check_effective_target_fstack_protector {} {
1282 if { [istarget hppa*-*-*] } {
1283 return 0;
1284 }
1285 return [check_runtime fstack_protector {
1286 #include <string.h>
1287 int main (int argc, char *argv[]) {
1288 char buf[64];
1289 return !strcpy (buf, strrchr (argv[0], '/'));
1290 }
1291 } "-fstack-protector"]
1292 }
1293
1294 # Return 1 if the target supports -fstack-check or -fstack-check=$stack_kind
1295 proc check_stack_check_available { stack_kind } {
1296 if [string match "" $stack_kind] then {
1297 set stack_opt "-fstack-check"
1298 } else { set stack_opt "-fstack-check=$stack_kind" }
1299
1300 return [check_no_compiler_messages stack_check_$stack_kind executable {
1301 int main (void) { return 0; }
1302 } "$stack_opt"]
1303 }
1304
1305 # Return 1 if the target supports stack scrubbing.
1306 proc check_effective_target_strub {} {
1307 return [check_no_compiler_messages strub assembly {
1308 void __attribute__ ((__strub__)) fn (void) {}
1309 } ""]
1310 }
1311
1312 # Return 1 if compilation with -freorder-blocks-and-partition is error-free
1313 # for trivial code, 0 otherwise. As some targets (ARM for example) only
1314 # warn when -fprofile-use is also supplied we test that combination too.
1315
1316 proc check_effective_target_freorder {} {
1317 if { [check_no_compiler_messages freorder object {
1318 void foo (void) { }
1319 } "-freorder-blocks-and-partition"]
1320 && [check_no_compiler_messages fprofile_use_freorder object {
1321 void foo (void) { }
1322 } "-fprofile-use -freorder-blocks-and-partition -Wno-missing-profile"] } {
1323 return 1
1324 }
1325 return 0
1326 }
1327
1328 # Return 1 if -fpic and -fPIC are supported, as in no warnings or errors
1329 # emitted, 0 otherwise. Whether a shared library can actually be built is
1330 # out of scope for this test.
1331
1332 proc check_effective_target_fpic { } {
1333 # Note that M68K has a multilib that supports -fpic but not
1334 # -fPIC, so we need to check both. We test with a program that
1335 # requires GOT references.
1336 foreach arg {fpic fPIC} {
1337 if [check_no_compiler_messages $arg object {
1338 extern int foo (void); extern int bar;
1339 int baz (void) { return foo () + bar; }
1340 } "-$arg"] {
1341 return 1
1342 }
1343 }
1344 return 0
1345 }
1346
1347 # On AArch64, if -fpic is not supported, then we will fall back to -fPIC
1348 # silently. So, we can't rely on above "check_effective_target_fpic" as it
1349 # assumes compiler will give warning if -fpic not supported. Here we check
1350 # whether binutils supports those new -fpic relocation modifiers, and assume
1351 # -fpic is supported if there is binutils support. GCC configuration will
1352 # enable -fpic for AArch64 in this case.
1353 #
1354 # "check_effective_target_aarch64_small_fpic" is dedicated for checking small
1355 # memory model -fpic relocation types.
1356
1357 proc check_effective_target_aarch64_small_fpic { } {
1358 if { [istarget aarch64*-*-*] } {
1359 return [check_no_compiler_messages aarch64_small_fpic object {
1360 void foo (void) { asm ("ldr x0, [x2, #:gotpage_lo15:globalsym]"); }
1361 }]
1362 } else {
1363 return 0
1364 }
1365 }
1366
1367 # On AArch64, instruction sequence for TLS LE under -mtls-size=32 will utilize
1368 # the relocation modifier "tprel_g0_nc" together with MOVK, it's only supported
1369 # in binutils since 2015-03-04 as PR gas/17843.
1370 #
1371 # This test directive make sure binutils support all features needed by TLS LE
1372 # under -mtls-size=32 on AArch64.
1373
1374 proc check_effective_target_aarch64_tlsle32 { } {
1375 if { [istarget aarch64*-*-*] } {
1376 return [check_no_compiler_messages aarch64_tlsle32 object {
1377 void foo (void) { asm ("movk x1,#:tprel_g0_nc:t1"); }
1378 }]
1379 } else {
1380 return 0
1381 }
1382 }
1383
1384 # Return 1 if -shared is supported, as in no warnings or errors
1385 # emitted, 0 otherwise.
1386
1387 proc check_effective_target_shared { } {
1388 # Note that M68K has a multilib that supports -fpic but not
1389 # -fPIC, so we need to check both. We test with a program that
1390 # requires GOT references, and with a libc symbol that would
1391 # bring in significant parts of a static-only libc. Absent a
1392 # shared libc, this would make -shared tests fail, so we don't
1393 # want to enable the shared effective target then.
1394 return [check_no_compiler_messages shared executable {
1395 #include <stdlib.h>
1396 extern int foo (void); extern int bar;
1397 char *baz (void) {
1398 return foo () + (char*) malloc (bar);
1399 }
1400 } "-shared -fpic"]
1401 }
1402
1403 # Return 1 if -pie, -fpie and -fPIE are supported, 0 otherwise.
1404
1405 proc check_effective_target_pie { } {
1406 if { [istarget *-*-darwin\[912\]*]
1407 || [istarget *-*-dragonfly*]
1408 || [istarget *-*-freebsd*]
1409 || [istarget *-*-linux*]
1410 || [istarget arm*-*-uclinuxfdpiceabi]
1411 || [istarget *-*-gnu*]
1412 || [istarget *-*-amdhsa]} {
1413 return 1;
1414 }
1415 if { [istarget *-*-solaris2.1\[1-9\]*] } {
1416 # Full PIE support was added in Solaris 11.3, but gcc errors out
1417 # if missing, so check for that.
1418 return [check_no_compiler_messages pie executable {
1419 int main (void) { return 0; }
1420 } "-pie -fpie"]
1421 }
1422 return 0
1423 }
1424
1425 # Return true if the target supports -mpaired-single (as used on MIPS).
1426
1427 proc check_effective_target_mpaired_single { args } {
1428 return [check_no_compiler_messages mpaired_single object {
1429 void foo (void) { }
1430 } "$args"]
1431 }
1432
1433 # Return true if the target has access to FPU instructions.
1434
1435 proc check_effective_target_hard_float { } {
1436 # This should work on cores that only have single-precision,
1437 # and should also correctly handle legacy cores that had thumb1 and
1438 # lacked FP support for that, but had it in Arm state.
1439 if { [istarget arm*-*-*] } {
1440 return [check_no_compiler_messages hard_float assembly {
1441 #if __ARM_FP == 0
1442 #error __arm_soft_float
1443 #endif
1444 }]
1445 }
1446
1447 if { [istarget loongarch*-*-*] } {
1448 return [check_no_compiler_messages hard_float assembly {
1449 #if (defined __loongarch_soft_float)
1450 #error __loongarch_soft_float
1451 #endif
1452 }]
1453 }
1454
1455 if { [istarget mips*-*-*] } {
1456 return [check_no_compiler_messages hard_float assembly {
1457 #if (defined __mips_soft_float || defined __mips16)
1458 #error __mips_soft_float || __mips16
1459 #endif
1460 }]
1461 }
1462
1463 # This proc is actually checking the availabilty of FPU
1464 # support for doubles, so on the RX we must fail if the
1465 # 64-bit double multilib has been selected.
1466 if { [istarget rx-*-*] } {
1467 return 0
1468 # return [check_no_compiler_messages hard_float assembly {
1469 #if defined __RX_64_BIT_DOUBLES__
1470 #error __RX_64_BIT_DOUBLES__
1471 #endif
1472 # }]
1473 }
1474
1475 # The generic test doesn't work for C-SKY because some cores have
1476 # hard float for single precision only.
1477 if { [istarget csky*-*-*] } {
1478 return [check_no_compiler_messages hard_float assembly {
1479 #if defined __csky_soft_float__
1480 #error __csky_soft_float__
1481 #endif
1482 }]
1483 }
1484
1485 # The generic test equates hard_float with "no call for adding doubles".
1486 return [check_no_messages_and_pattern hard_float "!\\(call" rtl-expand {
1487 double a (double b, double c) { return b + c; }
1488 }]
1489 }
1490
1491 # Return true if the target is a 64-bit MIPS target.
1492
1493 proc check_effective_target_mips64 { } {
1494 return [check_no_compiler_messages mips64 assembly {
1495 #ifndef __mips64
1496 #error !__mips64
1497 #endif
1498 }]
1499 }
1500
1501 # Return true if the target is a MIPS target that does not produce
1502 # MIPS16 code.
1503
1504 proc check_effective_target_nomips16 { } {
1505 return [check_no_compiler_messages nomips16 object {
1506 #ifndef __mips
1507 #error !__mips
1508 #else
1509 /* A cheap way of testing for -mflip-mips16. */
1510 void foo (void) { asm ("addiu $20,$20,1"); }
1511 void bar (void) { asm ("addiu $20,$20,1"); }
1512 #endif
1513 }]
1514 }
1515
1516 # Add the options needed for MIPS16 function attributes. At the moment,
1517 # we don't support MIPS16 PIC.
1518
1519 proc add_options_for_mips16_attribute { flags } {
1520 return "$flags -mno-abicalls -fno-pic -DMIPS16=__attribute__((mips16))"
1521 }
1522
1523 # Return true if we can force a mode that allows MIPS16 code generation.
1524 # We don't support MIPS16 PIC, and only support MIPS16 -mhard-float
1525 # for o32 and o64.
1526
1527 proc check_effective_target_mips16_attribute { } {
1528 return [check_no_compiler_messages mips16_attribute assembly {
1529 #ifdef PIC
1530 #error PIC
1531 #endif
1532 #if defined __mips_hard_float \
1533 && (!defined _ABIO32 || _MIPS_SIM != _ABIO32) \
1534 && (!defined _ABIO64 || _MIPS_SIM != _ABIO64)
1535 #error __mips_hard_float && (!_ABIO32 || !_ABIO64)
1536 #endif
1537 } [add_options_for_mips16_attribute ""]]
1538 }
1539
1540 # Return 1 if the target supports long double larger than double when
1541 # using the new ABI, 0 otherwise.
1542
1543 proc check_effective_target_mips_newabi_large_long_double { } {
1544 return [check_no_compiler_messages mips_newabi_large_long_double object {
1545 int dummy[sizeof(long double) > sizeof(double) ? 1 : -1];
1546 } "-mabi=64"]
1547 }
1548
1549 # Return true if the target is a MIPS target that has access
1550 # to the LL and SC instructions.
1551
1552 proc check_effective_target_mips_llsc { } {
1553 if { ![istarget mips*-*-*] } {
1554 return 0
1555 }
1556 # Assume that these instructions are always implemented for
1557 # non-elf* targets, via emulation if necessary.
1558 if { ![istarget *-*-elf*] } {
1559 return 1
1560 }
1561 # Otherwise assume LL/SC support for everything but MIPS I.
1562 return [check_no_compiler_messages mips_llsc assembly {
1563 #if __mips == 1
1564 #error __mips == 1
1565 #endif
1566 }]
1567 }
1568
1569 # Return true if the target is a MIPS target that uses in-place relocations.
1570
1571 proc check_effective_target_mips_rel { } {
1572 if { ![istarget mips*-*-*] } {
1573 return 0
1574 }
1575 return [check_no_compiler_messages mips_rel object {
1576 #if (defined _ABIN32 && _MIPS_SIM == _ABIN32) \
1577 || (defined _ABI64 && _MIPS_SIM == _ABI64)
1578 #error _ABIN32 && (_ABIN32 || _ABI64)
1579 #endif
1580 }]
1581 }
1582
1583 # Return true if the target is a MIPS target that uses the EABI.
1584
1585 proc check_effective_target_mips_eabi { } {
1586 if { ![istarget mips*-*-*] } {
1587 return 0
1588 }
1589 return [check_no_compiler_messages mips_eabi object {
1590 #ifndef __mips_eabi
1591 #error !__mips_eabi
1592 #endif
1593 }]
1594 }
1595
1596 # Return 1 if the current multilib does not generate PIC by default.
1597
1598 proc check_effective_target_nonpic { } {
1599 return [check_no_compiler_messages nonpic assembly {
1600 #if __PIC__
1601 #error __PIC__
1602 #endif
1603 }]
1604 }
1605
1606 # Return 1 if the current multilib generates PIE by default.
1607
1608 proc check_effective_target_pie_enabled { } {
1609 return [check_no_compiler_messages pie_enabled assembly {
1610 #ifndef __PIE__
1611 #error unsupported
1612 #endif
1613 }]
1614 }
1615
1616 # Return 1 if the target generates -fstack-protector by default.
1617
1618 proc check_effective_target_fstack_protector_enabled {} {
1619 return [ check_no_compiler_messages fstack_protector_enabled assembly {
1620 #if !defined(__SSP__) && !defined(__SSP_ALL__) && \
1621 !defined(__SSP_STRONG__) && !defined(__SSP_EXPICIT__)
1622 #error unsupported
1623 #endif
1624 }]
1625 }
1626
1627 # Return 1 if the target does not use a status wrapper.
1628
1629 proc check_effective_target_unwrapped { } {
1630 if { [target_info needs_status_wrapper] != "" \
1631 && [target_info needs_status_wrapper] != "0" } {
1632 return 0
1633 }
1634 return 1
1635 }
1636
1637 # Return true if iconv is supported on the target. In particular IBM1047.
1638
1639 proc check_iconv_available { test_what } {
1640 global libiconv
1641
1642 # If the tool configuration file has not set libiconv, try "-liconv"
1643 if { ![info exists libiconv] } {
1644 set libiconv "-liconv"
1645 }
1646 set test_what [lindex $test_what 1]
1647 return [check_runtime_nocache $test_what [subst {
1648 #include <iconv.h>
1649 int main (void)
1650 {
1651 iconv_t cd;
1652
1653 cd = iconv_open ("$test_what", "UTF-8");
1654 if (cd == (iconv_t) -1)
1655 return 1;
1656 return 0;
1657 }
1658 }] $libiconv]
1659 }
1660
1661 # Return true if the atomic library is supported on the target.
1662 proc check_effective_target_libatomic_available { } {
1663 return [check_no_compiler_messages libatomic_available executable {
1664 int main (void) { return 0; }
1665 } "-latomic"]
1666 }
1667
1668 # Return 1 if an ASCII locale is supported on this host, 0 otherwise.
1669
1670 proc check_ascii_locale_available { } {
1671 return 1
1672 }
1673
1674 # Return true if named sections are supported on this target.
1675
1676 proc check_named_sections_available { } {
1677 return [check_no_compiler_messages named_sections assembly {
1678 int __attribute__ ((section("whatever"))) foo;
1679 }]
1680 }
1681
1682 # Return true if the "naked" function attribute is supported on this target.
1683
1684 proc check_effective_target_naked_functions { } {
1685 return [check_no_compiler_messages naked_functions assembly {
1686 void f() __attribute__((naked));
1687 }]
1688 }
1689
1690 # Return 1 if the target supports Fortran real kinds larger than real(8),
1691 # 0 otherwise.
1692 #
1693 # When the target name changes, replace the cached result.
1694
1695 proc check_effective_target_fortran_large_real { } {
1696 return [check_no_compiler_messages fortran_large_real executable {
1697 ! Fortran
1698 integer,parameter :: k = selected_real_kind (precision (0.0_8) + 1)
1699 real(kind=k) :: x
1700 x = cos (x)
1701 end
1702 }]
1703 }
1704
1705 # Return 1 if the target supports Fortran real kind real(16),
1706 # 0 otherwise. Contrary to check_effective_target_fortran_large_real
1707 # this checks for Real(16) only; the other returned real(10) if
1708 # both real(10) and real(16) are available.
1709 #
1710 # When the target name changes, replace the cached result.
1711
1712 proc check_effective_target_fortran_real_16 { } {
1713 return [check_no_compiler_messages fortran_real_16 executable {
1714 ! Fortran
1715 real(kind=16) :: x
1716 x = cos (x)
1717 end
1718 }]
1719 }
1720
1721 # Return 1 if the target supports Fortran real kind 10,
1722 # 0 otherwise. Contrary to check_effective_target_fortran_large_real
1723 # this checks for real(10) only.
1724 #
1725 # When the target name changes, replace the cached result.
1726
1727 proc check_effective_target_fortran_real_10 { } {
1728 return [check_no_compiler_messages fortran_real_10 executable {
1729 ! Fortran
1730 real(kind=10) :: x
1731 x = cos (x)
1732 end
1733 }]
1734 }
1735
1736 # Return 1 if the target supports Fortran real kind C_FLOAT128,
1737 # 0 otherwise. This differs from check_effective_target_fortran_real_16
1738 # because _Float128 has the additional requirement that it be the
1739 # 128-bit IEEE encoding; even if _Float128 is available in C, it may not
1740 # have a corresponding Fortran kind on targets (PowerPC) that use some
1741 # other encoding for long double/TFmode/real(16).
1742 proc check_effective_target_fortran_real_c_float128 { } {
1743 return [check_no_compiler_messages fortran_real_c_float128 executable {
1744 ! Fortran
1745 use iso_c_binding
1746 real(kind=c_float128) :: x
1747 x = cos (x)
1748 end
1749 }]
1750 }
1751
1752 # Return 1 if the target supports Fortran's IEEE modules,
1753 # 0 otherwise.
1754 #
1755 # When the target name changes, replace the cached result.
1756
1757 proc check_effective_target_fortran_ieee { flags } {
1758 return [check_no_compiler_messages fortran_ieee executable {
1759 ! Fortran
1760 use, intrinsic :: ieee_features
1761 end
1762 } $flags ]
1763 }
1764
1765
1766 # Return 1 if the target supports SQRT for the largest floating-point
1767 # type. (Some targets lack the libm support for this FP type.)
1768 # On most targets, this check effectively checks either whether sqrtl is
1769 # available or on __float128 systems whether libquadmath is installed,
1770 # which provides sqrtq.
1771 #
1772 # When the target name changes, replace the cached result.
1773
1774 proc check_effective_target_fortran_largest_fp_has_sqrt { } {
1775 return [check_no_compiler_messages fortran_largest_fp_has_sqrt executable {
1776 ! Fortran
1777 use iso_fortran_env, only: real_kinds
1778 integer,parameter:: maxFP = real_kinds(ubound(real_kinds,dim=1))
1779 real(kind=maxFP), volatile :: x
1780 x = 2.0_maxFP
1781 x = sqrt (x)
1782 end
1783 }]
1784 }
1785
1786
1787 # Return 1 if the target supports Fortran integer kinds larger than
1788 # integer(8), 0 otherwise.
1789 #
1790 # When the target name changes, replace the cached result.
1791
1792 proc check_effective_target_fortran_large_int { } {
1793 return [check_no_compiler_messages fortran_large_int executable {
1794 ! Fortran
1795 integer,parameter :: k = selected_int_kind (range (0_8) + 1)
1796 integer(kind=k) :: i
1797 end
1798 }]
1799 }
1800
1801 # Return 1 if the target supports Fortran integer(16), 0 otherwise.
1802 #
1803 # When the target name changes, replace the cached result.
1804
1805 proc check_effective_target_fortran_integer_16 { } {
1806 return [check_no_compiler_messages fortran_integer_16 executable {
1807 ! Fortran
1808 integer(16) :: i
1809 end
1810 }]
1811 }
1812
1813 # Return 1 if we can statically link libgfortran, 0 otherwise.
1814 #
1815 # When the target name changes, replace the cached result.
1816
1817 proc check_effective_target_static_libgfortran { } {
1818 return [check_no_compiler_messages static_libgfortran executable {
1819 ! Fortran
1820 print *, 'test'
1821 end
1822 } "-static"]
1823 }
1824
1825 # Return 1 if we can use the -rdynamic option, 0 otherwise.
1826
1827 proc check_effective_target_rdynamic { } {
1828 return [check_no_compiler_messages rdynamic executable {
1829 int main() { return 0; }
1830 } "-rdynamic"]
1831 }
1832
1833 proc check_linker_plugin_available { } {
1834 return [check_no_compiler_messages_nocache linker_plugin executable {
1835 int main() { return 0; }
1836 } "-flto -fuse-linker-plugin"]
1837 }
1838
1839 # Return 1 if the target is RV32, 0 otherwise. Cache the result.
1840
1841 proc check_effective_target_rv32 { } {
1842 # Check that we are compiling for RV32 by checking the xlen size.
1843 return [check_no_compiler_messages riscv_rv32 assembly {
1844 #if !defined(__riscv_xlen)
1845 #error "__riscv_xlen not defined!"
1846 #else
1847 #if __riscv_xlen != 32
1848 #error "Not RV32"
1849 #endif
1850 #endif
1851 }]
1852 }
1853
1854 # Return 1 if the target is RV64, 0 otherwise. Cache the result.
1855
1856 proc check_effective_target_rv64 { } {
1857 # Check that we are compiling for RV64 by checking the xlen size.
1858 return [check_no_compiler_messages riscv_rv64 assembly {
1859 #if !defined(__riscv_xlen)
1860 #error "__riscv_xlen not defined!"
1861 #else
1862 #if __riscv_xlen != 64
1863 #error "Not RV64"
1864 #endif
1865 #endif
1866 }]
1867 }
1868
1869 # Return 1 if the target abi is __riscv_float_abi_soft, 0 otherwise.
1870 # Cache the result.
1871
1872 proc check_effective_target_rv_float_abi_soft { } {
1873 # Check that we are compiling for RV64 by checking the xlen size.
1874 return [check_no_compiler_messages riscv_riscv_float_abi_soft assembly {
1875 #ifndef __riscv_float_abi_soft
1876 #error "Not __riscv_float_abi_soft"
1877 #endif
1878 }]
1879 }
1880
1881 # Return 1 if the target arch supports the atomic extension, 0 otherwise.
1882 # Cache the result.
1883
1884 proc check_effective_target_riscv_a { } {
1885 return [check_no_compiler_messages riscv_ext_a assembly {
1886 #ifndef __riscv_a
1887 #error "Not __riscv_a"
1888 #endif
1889 }]
1890 }
1891
1892 # Return 1 if the target arch supports the double precision floating point
1893 # extension, 0 otherwise. Cache the result.
1894
1895 proc check_effective_target_riscv_d { } {
1896 return [check_no_compiler_messages riscv_ext_d assembly {
1897 #ifndef __riscv_d
1898 #error "Not __riscv_d"
1899 #endif
1900 }]
1901 }
1902
1903 # Return 1 if the target arch supports the vector extension, 0 otherwise.
1904 # Cache the result.
1905
1906 proc check_effective_target_riscv_v { } {
1907 return [check_no_compiler_messages riscv_ext_v assembly {
1908 #ifndef __riscv_v
1909 #error "Not __riscv_v"
1910 #endif
1911 }]
1912 }
1913
1914 # Return 1 if the target arch supports the Zvfh extension, 0 otherwise.
1915 # Cache the result.
1916
1917 proc check_effective_target_riscv_zvfh { } {
1918 return [check_no_compiler_messages riscv_ext_zvfh assembly {
1919 #ifndef __riscv_zvfh
1920 #error "Not __riscv_zvfh"
1921 #endif
1922 }]
1923 }
1924
1925 # Return 1 if the target arch supports half float, 0 otherwise.
1926 # Note, this differs from the test performed by
1927 # /* dg-skip-if "" { *-*-* } { "*" } { "-march=rv*zfh*" } */
1928 # in that it takes default behaviour into account.
1929 # Cache the result.
1930
1931 proc check_effective_target_riscv_zfh { } {
1932 return [check_no_compiler_messages riscv_ext_zfh assembly {
1933 #ifndef __riscv_zfh
1934 #error "Not __riscv_zfh"
1935 #endif
1936 }]
1937 }
1938
1939 # Return 1 if the target arch supports the TSO memory ordering extension,
1940 # 0 otherwise. Cache the result.
1941
1942 proc check_effective_target_riscv_ztso { } {
1943 return [check_no_compiler_messages riscv_ext_ztso assembly {
1944 #ifndef __riscv_ztso
1945 #error "Not __riscv_ztso"
1946 #endif
1947 }]
1948 }
1949
1950 # Return 1 if the target arch supports the Zbb extension, 0 otherwise.
1951 # Cache the result.
1952
1953 proc check_effective_target_riscv_zbb { } {
1954 return [check_no_compiler_messages riscv_ext_zbb assembly {
1955 #ifndef __riscv_zbb
1956 #error "Not __riscv_zbb"
1957 #endif
1958 }]
1959 }
1960
1961 # Return 1 if the target arch supports the XTheadVector extension, 0 otherwise.
1962 # Cache the result.
1963
1964 proc check_effective_target_riscv_xtheadvector { } {
1965 return [check_no_compiler_messages riscv_ext_xtheadvector assembly {
1966 #ifndef __riscv_xtheadvector
1967 #error "Not __riscv_xtheadvector"
1968 #endif
1969 }]
1970 }
1971
1972
1973 # Return 1 if we can execute code when using dg-add-options riscv_v
1974
1975 proc check_effective_target_riscv_v_ok { } {
1976 # If the target already supports v without any added options,
1977 # we may assume we can execute just fine.
1978 if { [check_effective_target_riscv_v] } {
1979 return 1
1980 }
1981
1982 # check if we can execute vector insns with the given hardware or
1983 # simulator
1984 set gcc_march [regsub {[[:alnum:]]*} [riscv_get_arch] &v]
1985 if { [check_runtime ${gcc_march}_exec {
1986 int main() { asm("vsetivli t0, 9, e8, m1, tu, ma"); return 0; } } "-march=${gcc_march}"] } {
1987 return 1
1988 }
1989
1990 # Possible future extensions: If the target is a simulator, dg-add-options
1991 # might change its config to make it allow vector insns, or we might use
1992 # options to set special elf flags / sections to effect that.
1993
1994 return 0
1995 }
1996
1997 # Return 1 if we can execute code when using dg-add-options riscv_zfh
1998
1999 proc check_effective_target_riscv_zfh_ok { } {
2000 # If the target already supports zfh without any added options,
2001 # we may assume we can execute just fine.
2002 # ??? Other cases we should consider:
2003 # - target / simulator already supports zfh extension - test for that.
2004 # - target is a simulator, and dg-add-options knows how to enable zfh support in that simulator
2005 if { [check_effective_target_riscv_zfh] } {
2006 return 1
2007 }
2008
2009 # check if we can execute zfh insns with the given hardware or
2010 # simulator
2011 set gcc_march [riscv_get_arch]
2012 if { [check_runtime ${gcc_march}_zfh_exec {
2013 int main() { asm("feq.h a3,fa5,fa4"); return 0; } } "-march=${gcc_march}_zfh"] } {
2014 return 1
2015 }
2016
2017 # Possible future extensions: If the target is a simulator, dg-add-options
2018 # might change its config to make it allow half float insns, or we might
2019 # use options to set special elf flags / sections to effect that.
2020
2021 return 0
2022 }
2023
2024 # Return 1 if we can execute code when using dg-add-options riscv_zvfh
2025
2026 proc check_effective_target_riscv_zvfh_ok { } {
2027 # If the target already supports v without any added options,
2028 # we may assume we can execute just fine.
2029 if { [check_effective_target_riscv_zvfh] } {
2030 return 1
2031 }
2032
2033 # check if we can execute vector insns with the given hardware or
2034 # simulator
2035 set gcc_march [regsub {[[:alnum:]]*} [riscv_get_arch] &v]
2036 if { [check_runtime ${gcc_march}_exec {
2037 int main()
2038 {
2039 asm ("vsetivli zero,8,e16,m1,ta,ma");
2040 asm ("vfadd.vv v8,v8,v16" : : : "v8");
2041 return 0;
2042 } } "-march=${gcc_march}"] } {
2043 return 1
2044 }
2045
2046 return 0
2047 }
2048
2049 proc riscv_get_arch { } {
2050 set gcc_march ""
2051 # ??? do we neeed to add more extensions to the list below?
2052 foreach ext { i m a f d q c v zicsr zifencei zfh zba zbb zbc zbs zvfh ztso } {
2053 if { [check_no_compiler_messages riscv_ext_$ext assembly [string map [list DEF __riscv_$ext] {
2054 #ifndef DEF
2055 #error "Not DEF"
2056 #endif
2057 }]] } {
2058 if { [string length $ext] > 1 } {
2059 set ext _${ext}
2060 }
2061 set gcc_march $gcc_march$ext
2062 }
2063 if { [string equal $gcc_march "imafd"] } {
2064 set gcc_march "g"
2065 }
2066 }
2067 if { [check_effective_target_rv32] } {
2068 set gcc_march rv32$gcc_march
2069 } elseif { [check_effective_target_rv64] } {
2070 set gcc_march rv64$gcc_march
2071 } else {
2072 set gcc_march ""
2073 }
2074 return "$gcc_march"
2075 }
2076
2077 proc add_options_for_riscv_a { flags } {
2078 if { [lsearch $flags -march=*] >= 0 } {
2079 # If there are multiple -march flags, we have to adjust all of them.
2080 set expanded_flags [regsub -all -- {((?:^|[[:space:]])-march=rv[[:digit:]]*)g+} $flags \\1imafd ]
2081 return [regsub -all -- {((?:^|[[:space:]])-march=rv[[:digit:]]*[b-eg-rt-wy]*)a*} $expanded_flags \\1a ]
2082 }
2083 if { [check_effective_target_riscv_a] } {
2084 return "$flags"
2085 }
2086 return "$flags -march=[regsub {(rv[[:digit:]]*[b-eg-rt-wy]*)a*} [riscv_get_arch] &a]"
2087 }
2088
2089 proc add_options_for_riscv_d { flags } {
2090 if { [lsearch $flags -march=*] >= 0 } {
2091 # If there are multiple -march flags, we have to adjust all of them.
2092 return [regsub -all -- {((?:^|[[:space:]])-march=rv[[:digit:]]*[a-ce-rt-wy]*)d*} $flags \\1d ]
2093 }
2094 if { [check_effective_target_riscv_d] } {
2095 return "$flags"
2096 }
2097 return "$flags -march=[regsub {[[:alnum:]]*} [riscv_get_arch] &d]"
2098 }
2099
2100 proc add_options_for_riscv_v { flags } {
2101 if { [lsearch $flags -march=*] >= 0 } {
2102 # If there are multiple -march flags, we have to adjust all of them.
2103 return [regsub -all -- {((?:^|[[:space:]])-march=rv[[:digit:]]*[a-rt-uwy]*)v*} $flags \\1v ]
2104 }
2105 if { [check_effective_target_riscv_v] } {
2106 return "$flags"
2107 }
2108 return "$flags -march=[regsub {[[:alnum:]]*} [riscv_get_arch] &v]"
2109 }
2110
2111 proc add_options_for_riscv_zfh { flags } {
2112 if { [lsearch $flags -march=*] >= 0 } {
2113 # If there are multiple -march flags, we have to adjust all of them.
2114 set flags [regsub -all -- {(?:^|[[:space:]])-march=[[:alnum:]_.]*} $flags &_zfh ]
2115 return [regsub -all -- {((?:^|[[:space:]])-march=[[:alnum:]_.]*_zfh[[:alnum:]_.]*)_zfh} $flags \\1 ]
2116 }
2117 if { [check_effective_target_riscv_zfh] } {
2118 return "$flags"
2119 }
2120 return "$flags -march=[riscv_get_arch]_zfh"
2121 }
2122
2123 proc add_options_for_riscv_ztso { flags } {
2124 if { [lsearch $flags -march=*] >= 0 } {
2125 # If there are multiple -march flags, we have to adjust all of them.
2126 set flags [regsub -all -- {(?:^|[[:space:]])-march=[[:alnum:]_.]*} $flags &_ztso ]
2127 return [regsub -all -- {((?:^|[[:space:]])-march=[[:alnum:]_.]*_ztso[[:alnum:]_.]*)_ztso} $flags \\1 ]
2128 }
2129 if { [check_effective_target_riscv_ztso] } {
2130 return "$flags"
2131 }
2132 return "$flags -march=[riscv_get_arch]_ztso"
2133 }
2134
2135 proc add_options_for_riscv_zvfh { flags } {
2136 if { [lsearch $flags -march=*] >= 0 } {
2137 # If there are multiple -march flags, we have to adjust all of them.
2138 set flags [regsub -all -- {(?:^|[[:space:]])-march=[[:alnum:]_.]*} $flags &_zvfh ]
2139 return [regsub -all -- {((?:^|[[:space:]])-march=[[:alnum:]_.]*_zvfh[[:alnum:]_.]*)_zvfh} $flags \\1 ]
2140 }
2141 if { [check_effective_target_riscv_zvfh] } {
2142 return "$flags"
2143 }
2144 return "$flags -march=[riscv_get_arch]_zvfh"
2145 }
2146
2147 # Return 1 if the target OS supports running SSE executables, 0
2148 # otherwise. Cache the result.
2149
2150 proc check_sse_os_support_available { } {
2151 return [check_cached_effective_target sse_os_support_available {
2152 # If this is not the right target then we can skip the test.
2153 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
2154 expr 0
2155 } else {
2156 expr 1
2157 }
2158 }]
2159 }
2160
2161 # Return 1 if the target OS supports running AVX executables, 0
2162 # otherwise. Cache the result.
2163
2164 proc check_avx_os_support_available { } {
2165 return [check_cached_effective_target avx_os_support_available {
2166 # If this is not the right target then we can skip the test.
2167 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
2168 expr 0
2169 } else {
2170 # Check that OS has AVX and SSE saving enabled.
2171 check_runtime_nocache avx_os_support_available {
2172 int main ()
2173 {
2174 unsigned int eax, edx;
2175
2176 asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0));
2177 return (eax & 0x06) != 0x06;
2178 }
2179 } ""
2180 }
2181 }]
2182 }
2183
2184 # Return 1 if the target OS supports running AVX executables, 0
2185 # otherwise. Cache the result.
2186
2187 proc check_avx512_os_support_available { } {
2188 return [check_cached_effective_target avx512_os_support_available {
2189 # If this is not the right target then we can skip the test.
2190 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
2191 expr 0
2192 } else {
2193 # Check that OS has AVX512, AVX and SSE saving enabled.
2194 check_runtime_nocache avx512_os_support_available {
2195 int main ()
2196 {
2197 unsigned int eax, edx;
2198
2199 asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0));
2200 return (eax & 0xe6) != 0xe6;
2201 }
2202 } ""
2203 }
2204 }]
2205 }
2206
2207 # Return 1 if the target supports executing SSE instructions, 0
2208 # otherwise. Cache the result.
2209
2210 proc check_sse_hw_available { } {
2211 return [check_cached_effective_target sse_hw_available {
2212 # If this is not the right target then we can skip the test.
2213 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
2214 expr 0
2215 } else {
2216 check_runtime_nocache sse_hw_available {
2217 #include "cpuid.h"
2218 int main ()
2219 {
2220 unsigned int eax, ebx, ecx, edx;
2221 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
2222 return 1;
2223
2224 return !(edx & bit_SSE);
2225 }
2226 } ""
2227 }
2228 }]
2229 }
2230
2231 # Return 1 if the target supports executing SSE2 instructions, 0
2232 # otherwise. Cache the result.
2233
2234 proc check_sse2_hw_available { } {
2235 return [check_cached_effective_target sse2_hw_available {
2236 # If this is not the right target then we can skip the test.
2237 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
2238 expr 0
2239 } else {
2240 check_runtime_nocache sse2_hw_available {
2241 #include "cpuid.h"
2242 int main ()
2243 {
2244 unsigned int eax, ebx, ecx, edx;
2245 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
2246 return 1;
2247
2248 return !(edx & bit_SSE2);
2249 }
2250 } ""
2251 }
2252 }]
2253 }
2254
2255 # Return 1 if the target supports executing SSE4 instructions, 0
2256 # otherwise. Cache the result.
2257
2258 proc check_sse4_hw_available { } {
2259 return [check_cached_effective_target sse4_hw_available {
2260 # If this is not the right target then we can skip the test.
2261 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
2262 expr 0
2263 } else {
2264 check_runtime_nocache sse4_hw_available {
2265 #include "cpuid.h"
2266 int main ()
2267 {
2268 unsigned int eax, ebx, ecx, edx;
2269 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
2270 return 1;
2271
2272 return !(ecx & bit_SSE4_2);
2273 }
2274 } ""
2275 }
2276 }]
2277 }
2278
2279 # Return 1 if the target supports executing AVX instructions, 0
2280 # otherwise. Cache the result.
2281
2282 proc check_avx_hw_available { } {
2283 return [check_cached_effective_target avx_hw_available {
2284 # If this is not the right target then we can skip the test.
2285 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
2286 expr 0
2287 } else {
2288 check_runtime_nocache avx_hw_available {
2289 #include "cpuid.h"
2290 int main ()
2291 {
2292 unsigned int eax, ebx, ecx, edx;
2293 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
2294 return 1;
2295
2296 return ((ecx & (bit_AVX | bit_OSXSAVE))
2297 != (bit_AVX | bit_OSXSAVE));
2298 }
2299 } ""
2300 }
2301 }]
2302 }
2303
2304 # Return 1 if the target supports executing AVX2 instructions, 0
2305 # otherwise. Cache the result.
2306
2307 proc check_avx2_hw_available { } {
2308 return [check_cached_effective_target avx2_hw_available {
2309 # If this is not the right target then we can skip the test.
2310 if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
2311 expr 0
2312 } else {
2313 check_runtime_nocache avx2_hw_available {
2314 #include <stddef.h>
2315 #include "cpuid.h"
2316 int main ()
2317 {
2318 unsigned int eax, ebx, ecx, edx;
2319
2320 if (__get_cpuid_max (0, NULL) < 7)
2321 return 1;
2322
2323 __cpuid (1, eax, ebx, ecx, edx);
2324
2325 if (!(ecx & bit_OSXSAVE))
2326 return 1;
2327
2328 __cpuid_count (7, 0, eax, ebx, ecx, edx);
2329
2330 return !(ebx & bit_AVX2);
2331 }
2332 } ""
2333 }
2334 }]
2335 }
2336
2337 # Return 1 if the target supports executing AVX512 foundation instructions, 0
2338 # otherwise. Cache the result.
2339
2340 proc check_avx512f_hw_available { } {
2341 return [check_cached_effective_target avx512f_hw_available {
2342 # If this is not the right target then we can skip the test.
2343 if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
2344 expr 0
2345 } else {
2346 check_runtime_nocache avx512f_hw_available {
2347 #include <stddef.h>
2348 #include "cpuid.h"
2349 int main ()
2350 {
2351 unsigned int eax, ebx, ecx, edx;
2352
2353 if (__get_cpuid_max (0, NULL) < 7)
2354 return 1;
2355
2356 __cpuid (1, eax, ebx, ecx, edx);
2357
2358 if (!(ecx & bit_OSXSAVE))
2359 return 1;
2360
2361 __cpuid_count (7, 0, eax, ebx, ecx, edx);
2362
2363 return !(ebx & bit_AVX512F);
2364 }
2365 } ""
2366 }
2367 }]
2368 }
2369
2370 # Return 1 if the target supports running SSE executables, 0 otherwise.
2371
2372 proc check_effective_target_sse_runtime { } {
2373 if { [check_effective_target_sse]
2374 && [check_sse_hw_available]
2375 && [check_sse_os_support_available] } {
2376 return 1
2377 }
2378 return 0
2379 }
2380
2381 # Return 1 if the target supports running SSE2 executables, 0 otherwise.
2382
2383 proc check_effective_target_sse2_runtime { } {
2384 if { [check_effective_target_sse2]
2385 && [check_sse2_hw_available]
2386 && [check_sse_os_support_available] } {
2387 return 1
2388 }
2389 return 0
2390 }
2391
2392 # Return 1 if the target supports running SSE4 executables, 0 otherwise.
2393
2394 proc check_effective_target_sse4_runtime { } {
2395 if { [check_effective_target_sse4]
2396 && [check_sse4_hw_available]
2397 && [check_sse_os_support_available] } {
2398 return 1
2399 }
2400 return 0
2401 }
2402
2403 # Return 1 if the target supports running AVX executables, 0 otherwise.
2404
2405 proc check_effective_target_avx_runtime { } {
2406 if { [check_effective_target_avx]
2407 && [check_avx_hw_available]
2408 && [check_avx_os_support_available] } {
2409 return 1
2410 }
2411 return 0
2412 }
2413
2414 # Return 1 if the target supports running AVX2 executables, 0 otherwise.
2415
2416 proc check_effective_target_avx2_runtime { } {
2417 if { [check_effective_target_avx2]
2418 && [check_avx2_hw_available]
2419 && [check_avx_os_support_available] } {
2420 return 1
2421 }
2422 return 0
2423 }
2424
2425 # Return 1 if the target supports running AVX512f executables, 0 otherwise.
2426
2427 proc check_effective_target_avx512f_runtime { } {
2428 if { [check_effective_target_avx512f]
2429 && [check_avx512f_hw_available]
2430 && [check_avx512_os_support_available] } {
2431 return 1
2432 }
2433 return 0
2434 }
2435
2436 # Return 1 if bmi2 instructions can be compiled.
2437 proc check_effective_target_bmi2 { } {
2438 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
2439 return 0
2440 }
2441 return [check_no_compiler_messages bmi2 object {
2442 unsigned int
2443 _bzhi_u32 (unsigned int __X, unsigned int __Y)
2444 {
2445 return __builtin_ia32_bzhi_si (__X, __Y);
2446 }
2447 } "-mbmi2" ]
2448 }
2449
2450 # Return 1 if the target supports executing MIPS Paired-Single instructions,
2451 # 0 otherwise. Cache the result.
2452
2453 proc check_mpaired_single_hw_available { } {
2454 return [check_cached_effective_target mpaired_single_hw_available {
2455 # If this is not the right target then we can skip the test.
2456 if { !([istarget mips*-*-*]) } {
2457 expr 0
2458 } else {
2459 check_runtime_nocache mpaired_single_hw_available {
2460 int main()
2461 {
2462 asm volatile ("pll.ps $f2,$f4,$f6");
2463 return 0;
2464 }
2465 } ""
2466 }
2467 }]
2468 }
2469
2470 # Return 1 if the target supports executing Loongson vector instructions,
2471 # 0 otherwise. Cache the result.
2472
2473 proc check_mips_loongson_mmi_hw_available { } {
2474 return [check_cached_effective_target mips_loongson_mmi_hw_available {
2475 # If this is not the right target then we can skip the test.
2476 if { !([istarget mips*-*-*]) } {
2477 expr 0
2478 } else {
2479 check_runtime_nocache mips_loongson_mmi_hw_available {
2480 #include <loongson-mmiintrin.h>
2481 int main()
2482 {
2483 asm volatile ("paddw $f2,$f4,$f6");
2484 return 0;
2485 }
2486 } "-mloongson-mmi"
2487 }
2488 }]
2489 }
2490
2491 # Return 1 if the target supports executing MIPS MSA instructions, 0
2492 # otherwise. Cache the result.
2493
2494 proc check_mips_msa_hw_available { } {
2495 return [check_cached_effective_target mips_msa_hw_available {
2496 # If this is not the right target then we can skip the test.
2497 if { !([istarget mips*-*-*]) } {
2498 expr 0
2499 } else {
2500 check_runtime_nocache mips_msa_hw_available {
2501 #if !defined(__mips_msa)
2502 #error "MSA NOT AVAIL"
2503 #else
2504 #if !(((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2))
2505 #error "MSA NOT AVAIL FOR ISA REV < 2"
2506 #endif
2507 #if !defined(__mips_hard_float)
2508 #error "MSA HARD_FLOAT REQUIRED"
2509 #endif
2510 #if __mips_fpr != 64
2511 #error "MSA 64-bit FPR REQUIRED"
2512 #endif
2513 #include <msa.h>
2514
2515 int main()
2516 {
2517 v8i16 v = __builtin_msa_ldi_h (0);
2518 v[0] = 0;
2519 return v[0];
2520 }
2521 #endif
2522 } "-mmsa"
2523 }
2524 }]
2525 }
2526
2527 # Return 1 if the target supports running MIPS Paired-Single
2528 # executables, 0 otherwise.
2529
2530 proc check_effective_target_mpaired_single_runtime { } {
2531 if { [check_effective_target_mpaired_single "-mpaired-single"]
2532 && [check_mpaired_single_hw_available] } {
2533 return 1
2534 }
2535 return 0
2536 }
2537
2538 # Return 1 if the target supports running Loongson executables, 0 otherwise.
2539
2540 proc check_effective_target_mips_loongson_mmi_runtime { } {
2541 if { [check_effective_target_mips_loongson_mmi "-mloongson-mmi"]
2542 && [check_mips_loongson_mmi_hw_available] } {
2543 return 1
2544 }
2545 return 0
2546 }
2547
2548 # Return 1 if the target supports running MIPS MSA executables, 0 otherwise.
2549
2550 proc check_effective_target_mips_msa_runtime { } {
2551 if { [check_effective_target_mips_msa "-mmsa"]
2552 && [check_mips_msa_hw_available] } {
2553 return 1
2554 }
2555 return 0
2556 }
2557
2558 # Return 1 if we are compiling for 64-bit PowerPC but we do not use direct
2559 # move instructions for moves from GPR to FPR.
2560
2561 proc check_effective_target_powerpc64_no_dm { } {
2562 # The "mulld" checks if we are generating PowerPC64 code. The "lfd"
2563 # checks if we do not use direct moves, but use the old-fashioned
2564 # slower move-via-the-stack.
2565 return [check_no_messages_and_pattern powerpc64_no_dm \
2566 {\mmulld\M.*\mlfd} assembly {
2567 double f(long long x) { return x*x; }
2568 } {-O2}]
2569 }
2570
2571 # Return 1 if the target supports the __builtin_cpu_supports built-in,
2572 # including having a new enough library to support the test. Cache the result.
2573 # Require at least a power7 to run on.
2574
2575 proc check_ppc_cpu_supports_hw_available { } {
2576 return [check_cached_effective_target ppc_cpu_supports_hw_available {
2577 # Some simulators are known to not support VSX/power8 instructions.
2578 # For now, disable on Darwin
2579 if { [istarget powerpc-*-eabi]
2580 || [istarget powerpc*-*-eabispe]
2581 || [istarget *-*-darwin*]} {
2582 expr 0
2583 } else {
2584 set options "-mvsx"
2585 check_runtime_nocache ppc_cpu_supports_hw_available {
2586 int main()
2587 {
2588 #ifdef __MACH__
2589 asm volatile ("xxlor vs0,vs0,vs0");
2590 #else
2591 asm volatile ("xxlor 0,0,0");
2592 #endif
2593 if (!__builtin_cpu_supports ("vsx"))
2594 return 1;
2595 return 0;
2596 }
2597 } $options
2598 }
2599 }]
2600 }
2601
2602 # Return 1 if the target supports executing 750CL paired-single instructions, 0
2603 # otherwise. Cache the result.
2604
2605 proc check_750cl_hw_available { } {
2606 return [check_cached_effective_target 750cl_hw_available {
2607 # If this is not the right target then we can skip the test.
2608 if { ![istarget powerpc-*paired*] } {
2609 expr 0
2610 } else {
2611 check_runtime_nocache 750cl_hw_available {
2612 int main()
2613 {
2614 #ifdef __MACH__
2615 asm volatile ("ps_mul v0,v0,v0");
2616 #else
2617 asm volatile ("ps_mul 0,0,0");
2618 #endif
2619 return 0;
2620 }
2621 } "-mpaired"
2622 }
2623 }]
2624 }
2625
2626 # Return 1 if the target supports executing power8 vector instructions, 0
2627 # otherwise. Cache the result.
2628
2629 proc check_p8vector_hw_available { } {
2630 return [check_cached_effective_target p8vector_hw_available {
2631 # Some simulators are known to not support VSX/power8 instructions.
2632 # For now, disable on Darwin
2633 if { [istarget powerpc-*-eabi]
2634 || [istarget powerpc*-*-eabispe]
2635 || [istarget *-*-darwin*]} {
2636 expr 0
2637 } else {
2638 set options "-mpower8-vector"
2639 check_runtime_nocache p8vector_hw_available {
2640 int main()
2641 {
2642 #ifdef __MACH__
2643 asm volatile ("xxlorc vs0,vs0,vs0");
2644 #else
2645 asm volatile ("xxlorc 0,0,0");
2646 #endif
2647 return 0;
2648 }
2649 } $options
2650 }
2651 }]
2652 }
2653
2654 # Return 1 if the target supports executing power9 vector instructions, 0
2655 # otherwise. Cache the result.
2656
2657 proc check_p9vector_hw_available { } {
2658 return [check_cached_effective_target p9vector_hw_available {
2659 # Some simulators are known to not support VSX/power8/power9
2660 # instructions. For now, disable on Darwin.
2661 if { [istarget powerpc-*-eabi]
2662 || [istarget powerpc*-*-eabispe]
2663 || [istarget *-*-darwin*]} {
2664 expr 0
2665 } else {
2666 set options "-mpower9-vector"
2667 check_runtime_nocache p9vector_hw_available {
2668 int main()
2669 {
2670 long e = -1;
2671 vector double v = (vector double) { 0.0, 0.0 };
2672 asm ("xsxexpdp %0,%1" : "+r" (e) : "wa" (v));
2673 return e;
2674 }
2675 } $options
2676 }
2677 }]
2678 }
2679
2680 # Return 1 if the PowerPC target generates PC-relative instructions
2681 # automatically for targets that support PC-relative instructions.
2682 proc check_effective_target_powerpc_pcrel { } {
2683 return [check_no_messages_and_pattern powerpc_pcrel \
2684 {\mpla\M} assembly {
2685 static unsigned short s;
2686 unsigned short *p_foo (void) { return &s; }
2687 } {-O2 -mcpu=power10}]
2688 }
2689
2690 # Return 1 if the PowerPC target generates prefixed instructions automatically
2691 # for targets that support prefixed instructions.
2692 proc check_effective_target_powerpc_prefixed_addr { } {
2693 return [check_no_messages_and_pattern powerpc_prefixed_addr \
2694 {\mplwz\M} assembly {
2695 unsigned int foo (unsigned int *p) { return p[0x12345]; }
2696 } {-O2 -mcpu=power10}]
2697 }
2698
2699 # Return 1 if the target supports executing power9 modulo instructions, 0
2700 # otherwise. Cache the result.
2701
2702 proc check_p9modulo_hw_available { } {
2703 return [check_cached_effective_target p9modulo_hw_available {
2704 # Some simulators are known to not support VSX/power8/power9
2705 # instructions. For now, disable on Darwin.
2706 if { [istarget powerpc-*-eabi]
2707 || [istarget powerpc*-*-eabispe]
2708 || [istarget *-*-darwin*]} {
2709 expr 0
2710 } else {
2711 set options "-mmodulo"
2712 check_runtime_nocache p9modulo_hw_available {
2713 int main()
2714 {
2715 int i = 5, j = 3, r = -1;
2716 asm ("modsw %0,%1,%2" : "+r" (r) : "r" (i), "r" (j));
2717 return (r != 2);
2718 }
2719 } $options
2720 }
2721 }]
2722 }
2723
2724
2725 # Return 1 if the target supports executing power10 instructions, 0 otherwise.
2726 # Cache the result. It is assumed that if a simulator does not support the
2727 # power10 instructions, that it will generate an error and this test will fail.
2728
2729 proc check_power10_hw_available { } {
2730 return [check_cached_effective_target power10_hw_available {
2731 check_runtime_nocache power10_hw_available {
2732 int main()
2733 {
2734 /* Set e first and use +r to check if pli actually works. */
2735 long e = -1;
2736 asm ("pli %0,%1" : "+r" (e) : "n" (0x12345));
2737 if (e == 0x12345)
2738 return 0;
2739 return 1;
2740 }
2741 } "-mcpu=power10"
2742 }]
2743 }
2744
2745 # Return 1 if the target supports executing MMA instructions, 0 otherwise.
2746 # Cache the result. It is assumed that if a simulator does not support the
2747 # MMA instructions, that it will generate an error and this test will fail.
2748
2749 proc check_ppc_mma_hw_available { } {
2750 return [check_cached_effective_target ppc_mma_hw_available {
2751 check_runtime_nocache ppc_mma_hw_available {
2752 #include <altivec.h>
2753 typedef double v4sf_t __attribute__ ((vector_size (16)));
2754
2755 int main()
2756 {
2757 __vector_quad acc0;
2758 v4sf_t result[4];
2759 result[0][0] = 1.0;
2760 __builtin_mma_xxsetaccz (&acc0);
2761 __builtin_mma_disassemble_acc (result, &acc0);
2762 if (result[0][0] != 0.0)
2763 return 1;
2764 return 0;
2765 }
2766 } "-mcpu=power10"
2767 }]
2768 }
2769
2770 # Return 1 if the target supports executing __float128 on PowerPC via software
2771 # emulation, 0 otherwise. Cache the result.
2772
2773 proc check_ppc_float128_sw_available { } {
2774 return [check_cached_effective_target ppc_float128_sw_available {
2775 # Some simulators are known to not support VSX/power8/power9
2776 # instructions. For now, disable on Darwin and VxWorks.
2777 if { [istarget *-*-vxworks*]
2778 || [istarget powerpc-*-eabi]
2779 || [istarget powerpc*-*-eabispe]
2780 || [istarget *-*-darwin*]} {
2781 expr 0
2782 } else {
2783 set options "-mfloat128 -mvsx"
2784 check_runtime_nocache ppc_float128_sw_available {
2785 volatile __float128 x = 1.0q;
2786 volatile __float128 y = 2.0q;
2787 int main()
2788 {
2789 __float128 z = x + y;
2790 return (z != 3.0q);
2791 }
2792 } $options
2793 }
2794 }]
2795 }
2796
2797 # Return 1 if the target supports executing __float128 on PowerPC via power9
2798 # hardware instructions, 0 otherwise. Cache the result.
2799
2800 proc check_ppc_float128_hw_available { } {
2801 return [check_cached_effective_target ppc_float128_hw_available {
2802 # Some simulators are known to not support VSX/power8/power9
2803 # instructions. For now, disable on Darwin.
2804 if { [istarget *-*-vxworks*]
2805 || [istarget powerpc-*-eabi]
2806 || [istarget powerpc*-*-eabispe]
2807 || [istarget *-*-darwin*]} {
2808 expr 0
2809 } else {
2810 set options "-mfloat128 -mvsx -mfloat128-hardware -mpower9-vector"
2811 check_runtime_nocache ppc_float128_hw_available {
2812 volatile __float128 x = 1.0q;
2813 volatile __float128 y = 2.0q;
2814 int main()
2815 {
2816 __float128 z = x + y;
2817 __float128 w = -1.0q;
2818
2819 __asm__ ("xsaddqp %0,%1,%2" : "+v" (w) : "v" (x), "v" (y));
2820 return ((z != 3.0q) || (z != w));
2821 }
2822 } $options
2823 }
2824 }]
2825 }
2826
2827 # See if the __ieee128 keyword is understood.
2828 proc check_effective_target_ppc_ieee128_ok { } {
2829 return [check_cached_effective_target ppc_ieee128_ok {
2830 # disable on AIX and VxWorks.
2831 if { [istarget *-*-aix*]
2832 || [istarget *-*-vxworks*]} {
2833 expr 0
2834 } else {
2835 set options "-mfloat128"
2836 check_runtime_nocache ppc_ieee128_ok {
2837 int main()
2838 {
2839 __ieee128 a;
2840 return 0;
2841 }
2842 } $options
2843 }
2844 }]
2845 }
2846
2847 # Check if GCC and GLIBC supports explicitly specifying that the long double
2848 # format uses the IBM 128-bit extended double format. Under little endian
2849 # PowerPC Linux, you need GLIBC 2.32 or later to be able to use a different
2850 # long double format for running a program than the system default.
2851
2852 proc check_effective_target_long_double_ibm128 { } {
2853 return [check_runtime_nocache long_double_ibm128 {
2854 #include <string.h>
2855 #include <stdio.h>
2856 /* use volatile to prevent optimization. */
2857 volatile __ibm128 a = (__ibm128) 3.0;
2858 volatile long double one = 1.0L;
2859 volatile long double two = 2.0L;
2860 volatile long double b;
2861 char buffer[20];
2862 int main()
2863 {
2864 __ibm128 a2;
2865 long double b2;
2866 if (sizeof (long double) != 16)
2867 return 1;
2868 b = one + two;
2869 /* eliminate removing volatile cast warning. */
2870 a2 = a;
2871 b2 = b;
2872 if (memcmp (&a2, &b2, 16) != 0)
2873 return 1;
2874 sprintf (buffer, "%lg", b);
2875 return strcmp (buffer, "3") != 0;
2876 }
2877 } [add_options_for_long_double_ibm128 ""]]
2878 }
2879
2880 # Return the appropriate options to specify that long double uses the IBM
2881 # 128-bit format on PowerPC.
2882
2883 proc add_options_for_long_double_ibm128 { flags } {
2884 if { [istarget powerpc*-*-*] } {
2885 return "$flags -mlong-double-128 -Wno-psabi -mabi=ibmlongdouble"
2886 }
2887 return "$flags"
2888 }
2889
2890 # Check if GCC and GLIBC supports explicitly specifying that the long double
2891 # format uses the IEEE 128-bit format. Under little endian PowerPC Linux, you
2892 # need GLIBC 2.32 or later to be able to use a different long double format for
2893 # running a program than the system default.
2894
2895 proc check_effective_target_long_double_ieee128 { } {
2896 return [check_runtime_nocache long_double_ieee128 {
2897 #include <string.h>
2898 #include <stdio.h>
2899 /* use volatile to prevent optimization. */
2900 volatile _Float128 a = 3.0f128;
2901 volatile long double one = 1.0L;
2902 volatile long double two = 2.0L;
2903 volatile long double b;
2904 char buffer[20];
2905 int main()
2906 {
2907 _Float128 a2;
2908 long double b2;
2909 if (sizeof (long double) != 16)
2910 return 1;
2911 b = one + two;
2912 /* eliminate removing volatile cast warning. */
2913 a2 = a;
2914 b2 = b;
2915 if (memcmp (&a2, &b2, 16) != 0)
2916 return 1;
2917 sprintf (buffer, "%lg", b);
2918 return strcmp (buffer, "3") != 0;
2919 }
2920 } [add_options_for_long_double_ieee128 ""]]
2921 }
2922
2923 # Return the appropriate options to specify that long double uses the IBM
2924 # 128-bit format on PowerPC.
2925 proc add_options_for_long_double_ieee128 { flags } {
2926 if { [istarget powerpc*-*-*] } {
2927 return "$flags -mlong-double-128 -Wno-psabi -mabi=ieeelongdouble"
2928 }
2929 return "$flags"
2930 }
2931
2932 # Check if GCC and GLIBC supports explicitly specifying that the long double
2933 # format uses the IEEE 64-bit. Under little endian PowerPC Linux, you need
2934 # GLIBC 2.32 or later to be able to use a different long double format for
2935 # running a program than the system default.
2936
2937 proc check_effective_target_long_double_64bit { } {
2938 return [check_runtime_nocache long_double_64bit {
2939 #include <string.h>
2940 #include <stdio.h>
2941 /* use volatile to prevent optimization. */
2942 volatile double a = 3.0;
2943 volatile long double one = 1.0L;
2944 volatile long double two = 2.0L;
2945 volatile long double b;
2946 char buffer[20];
2947 int main()
2948 {
2949 double a2;
2950 long double b2;
2951 if (sizeof (long double) != 8)
2952 return 1;
2953 b = one + two;
2954 /* eliminate removing volatile cast warning. */
2955 a2 = a;
2956 b2 = b;
2957 if (memcmp (&a2, &b2, 16) != 0)
2958 return 1;
2959 sprintf (buffer, "%lg", b);
2960 return strcmp (buffer, "3") != 0;
2961 }
2962 } [add_options_for_ppc_long_double_override_64bit ""]]
2963 }
2964
2965 # Return the appropriate options to specify that long double uses the IEEE
2966 # 64-bit format on PowerPC.
2967
2968 proc add_options_for_long_double_64bit { flags } {
2969 if { [istarget powerpc*-*-*] } {
2970 return "$flags -mlong-double-64"
2971 }
2972 return "$flags"
2973 }
2974
2975 # Return 1 if the target supports executing VSX instructions, 0
2976 # otherwise. Cache the result.
2977
2978 proc check_vsx_hw_available { } {
2979 return [check_cached_effective_target vsx_hw_available {
2980 # Some simulators are known to not support VSX instructions.
2981 # For now, disable on Darwin
2982 if { [istarget powerpc-*-eabi]
2983 || [istarget powerpc*-*-eabispe]
2984 || [istarget *-*-darwin*]} {
2985 expr 0
2986 } else {
2987 set options "-mvsx"
2988 check_runtime_nocache vsx_hw_available {
2989 int main()
2990 {
2991 #ifdef __MACH__
2992 asm volatile ("xxlor vs0,vs0,vs0");
2993 #else
2994 asm volatile ("xxlor 0,0,0");
2995 #endif
2996 return 0;
2997 }
2998 } $options
2999 }
3000 }]
3001 }
3002
3003 # Return 1 if the target supports executing AltiVec instructions, 0
3004 # otherwise. Cache the result.
3005
3006 proc check_vmx_hw_available { } {
3007 return [check_cached_effective_target vmx_hw_available {
3008 # Some simulators are known to not support VMX instructions.
3009 if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] } {
3010 expr 0
3011 } else {
3012 # Most targets don't require special flags for this test case, but
3013 # Darwin does. Just to be sure, make sure VSX is not enabled for
3014 # the altivec tests.
3015 if { [istarget *-*-darwin*]
3016 || [istarget *-*-aix*] } {
3017 set options "-maltivec -mno-vsx"
3018 } else {
3019 set options "-mno-vsx"
3020 }
3021 check_runtime_nocache vmx_hw_available {
3022 int main()
3023 {
3024 #ifdef __MACH__
3025 asm volatile ("vor v0,v0,v0");
3026 #else
3027 asm volatile ("vor 0,0,0");
3028 #endif
3029 return 0;
3030 }
3031 } $options
3032 }
3033 }]
3034 }
3035
3036 proc check_ppc_recip_hw_available { } {
3037 return [check_cached_effective_target ppc_recip_hw_available {
3038 # Some simulators may not support FRE/FRES/FRSQRTE/FRSQRTES
3039 # For now, disable on Darwin
3040 if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
3041 expr 0
3042 } else {
3043 set options "-mpowerpc-gfxopt -mpowerpc-gpopt -mpopcntb"
3044 check_runtime_nocache ppc_recip_hw_available {
3045 volatile double d_recip, d_rsqrt, d_four = 4.0;
3046 volatile float f_recip, f_rsqrt, f_four = 4.0f;
3047 int main()
3048 {
3049 asm volatile ("fres %0,%1" : "=f" (f_recip) : "f" (f_four));
3050 asm volatile ("fre %0,%1" : "=d" (d_recip) : "d" (d_four));
3051 asm volatile ("frsqrtes %0,%1" : "=f" (f_rsqrt) : "f" (f_four));
3052 asm volatile ("frsqrte %0,%1" : "=f" (d_rsqrt) : "d" (d_four));
3053 return 0;
3054 }
3055 } $options
3056 }
3057 }]
3058 }
3059
3060 # Return 1 if the target supports executing AltiVec and Cell PPU
3061 # instructions, 0 otherwise. Cache the result.
3062
3063 proc check_effective_target_cell_hw { } {
3064 return [check_cached_effective_target cell_hw_available {
3065 # Some simulators are known to not support VMX and PPU instructions.
3066 if { [istarget powerpc-*-eabi*] } {
3067 expr 0
3068 } else {
3069 # Most targets don't require special flags for this test
3070 # case, but Darwin and AIX do.
3071 if { [istarget *-*-darwin*]
3072 || [istarget *-*-aix*] } {
3073 set options "-maltivec -mcpu=cell"
3074 } else {
3075 set options "-mcpu=cell"
3076 }
3077 check_runtime_nocache cell_hw_available {
3078 int main()
3079 {
3080 #ifdef __MACH__
3081 asm volatile ("vor v0,v0,v0");
3082 asm volatile ("lvlx v0,r0,r0");
3083 #else
3084 asm volatile ("vor 0,0,0");
3085 asm volatile ("lvlx 0,0,0");
3086 #endif
3087 return 0;
3088 }
3089 } $options
3090 }
3091 }]
3092 }
3093
3094 # Return 1 if the target supports executing 64-bit instructions, 0
3095 # otherwise. Cache the result.
3096
3097 proc check_effective_target_powerpc64 { } {
3098 global powerpc64_available_saved
3099 global tool
3100
3101 if [info exists powerpc64_available_saved] {
3102 verbose "check_effective_target_powerpc64 returning saved $powerpc64_available_saved" 2
3103 } else {
3104 set powerpc64_available_saved 0
3105
3106 # Some simulators are known to not support powerpc64 instructions.
3107 if { [istarget powerpc-*-eabi*] || [istarget powerpc-ibm-aix*] } {
3108 verbose "check_effective_target_powerpc64 returning 0" 2
3109 return $powerpc64_available_saved
3110 }
3111
3112 # Set up, compile, and execute a test program containing a 64-bit
3113 # instruction. Include the current process ID in the file
3114 # names to prevent conflicts with invocations for multiple
3115 # testsuites.
3116 set src ppc[pid].c
3117 set exe ppc[pid].x
3118
3119 set f [open $src "w"]
3120 puts $f "int main() {"
3121 puts $f "#ifdef __MACH__"
3122 puts $f " asm volatile (\"extsw r0,r0\");"
3123 puts $f "#else"
3124 puts $f " asm volatile (\"extsw 0,0\");"
3125 puts $f "#endif"
3126 puts $f " return 0; }"
3127 close $f
3128
3129 set opts "additional_flags=-mcpu=G5"
3130
3131 verbose "check_effective_target_powerpc64 compiling testfile $src" 2
3132 set lines [${tool}_target_compile $src $exe executable "$opts"]
3133 file delete $src
3134
3135 if [string match "" $lines] then {
3136 # No error message, compilation succeeded.
3137 set result [${tool}_load "./$exe" "" ""]
3138 set status [lindex $result 0]
3139 remote_file build delete $exe
3140 verbose "check_effective_target_powerpc64 testfile status is <$status>" 2
3141
3142 if { $status == "pass" } then {
3143 set powerpc64_available_saved 1
3144 }
3145 } else {
3146 verbose "check_effective_target_powerpc64 testfile compilation failed" 2
3147 }
3148 }
3149
3150 return $powerpc64_available_saved
3151 }
3152
3153 # GCC 3.4.0 for powerpc64-*-linux* included an ABI fix for passing
3154 # complex float arguments. This affects gfortran tests that call cabsf
3155 # in libm built by an earlier compiler. Return 0 if libm uses the same
3156 # argument passing as the compiler under test, 1 otherwise.
3157
3158 proc check_effective_target_broken_cplxf_arg { } {
3159 # Skip the work for targets known not to be affected.
3160 if { ![istarget powerpc*-*-linux*] || ![is-effective-target lp64] } {
3161 return 0
3162 }
3163
3164 return [check_cached_effective_target broken_cplxf_arg {
3165 check_runtime_nocache broken_cplxf_arg {
3166 #include <complex.h>
3167 extern void abort (void);
3168 float fabsf (float);
3169 float cabsf (_Complex float);
3170 int main ()
3171 {
3172 _Complex float cf;
3173 float f;
3174 cf = 3 + 4.0fi;
3175 f = cabsf (cf);
3176 if (fabsf (f - 5.0) > 0.0001)
3177 /* Yes, it's broken. */
3178 return 0;
3179 /* All fine, not broken. */
3180 return 1;
3181 }
3182 } "-lm"
3183 }]
3184 }
3185
3186 # Return 1 is this is a TI C6X target supporting C67X instructions
3187 proc check_effective_target_ti_c67x { } {
3188 return [check_no_compiler_messages ti_c67x assembly {
3189 #if !defined(_TMS320C6700)
3190 #error !_TMS320C6700
3191 #endif
3192 }]
3193 }
3194
3195 # Return 1 is this is a TI C6X target supporting C64X+ instructions
3196 proc check_effective_target_ti_c64xp { } {
3197 return [check_no_compiler_messages ti_c64xp assembly {
3198 #if !defined(_TMS320C6400_PLUS)
3199 #error !_TMS320C6400_PLUS
3200 #endif
3201 }]
3202 }
3203
3204 # Check if a -march=... option is given, as part of (earlier) options.
3205 proc check_effective_target_march_option { } {
3206 return [check-flags [list "" { *-*-* } { "-march=*" } { "" } ]]
3207 }
3208
3209 proc check_alpha_max_hw_available { } {
3210 return [check_runtime alpha_max_hw_available {
3211 int main() { return __builtin_alpha_amask(1<<8) != 0; }
3212 }]
3213 }
3214
3215 # Returns true iff the FUNCTION is available on the target system.
3216 # (This is essentially a Tcl implementation of Autoconf's
3217 # AC_CHECK_FUNC.)
3218
3219 proc check_function_available { function } {
3220 return [check_no_compiler_messages ${function}_available \
3221 executable [subst {
3222 #ifdef __cplusplus
3223 extern "C"
3224 #endif
3225 char $function ();
3226 int main () { $function (); }
3227 }] "-fno-builtin" ]
3228 }
3229
3230 # Returns true iff "fork" is available on the target system.
3231
3232 proc check_fork_available {} {
3233 if { [istarget *-*-vxworks*] } {
3234 # VxWorks doesn't have fork but our way to test can't
3235 # tell as we're doing partial links for kernel modules.
3236 return 0
3237 }
3238 if { [istarget cris-*-*] } {
3239 # Compiling and linking works, and an executable running e.g.
3240 # gcc.dg/torture/ftrapv-1.c works on now-historical hardware,
3241 # but the GNU simulator emits an error for the fork syscall.
3242 return [check_effective_target_hw]
3243 }
3244 return [check_function_available "fork"]
3245 }
3246
3247 # Returns true iff "mkfifo" is available on the target system.
3248
3249 proc check_mkfifo_available {} {
3250 if { [istarget *-*-cygwin*] } {
3251 # Cygwin has mkfifo, but support is incomplete.
3252 return 0
3253 }
3254
3255 return [check_function_available "mkfifo"]
3256 }
3257
3258 # Returns true iff "__cxa_atexit" is used on the target system.
3259
3260 proc check_cxa_atexit_available { } {
3261 return [check_cached_effective_target cxa_atexit_available {
3262 if { [istarget *-*-vxworks] } {
3263 # vxworks doesn't have __cxa_atexit but subsequent test passes.
3264 expr 0
3265 } else {
3266 check_runtime_nocache cxa_atexit_available {
3267 // C++
3268 #include <stdlib.h>
3269 static unsigned int count;
3270 struct X
3271 {
3272 X() { count = 1; }
3273 ~X()
3274 {
3275 if (count != 3)
3276 exit(1);
3277 count = 4;
3278 }
3279 };
3280 void f()
3281 {
3282 static X x;
3283 }
3284 struct Y
3285 {
3286 Y() { f(); count = 2; }
3287 ~Y()
3288 {
3289 if (count != 2)
3290 exit(1);
3291 count = 3;
3292 }
3293 };
3294 Y y;
3295 int main() { return 0; }
3296 }
3297 }
3298 }]
3299 }
3300
3301 proc check_effective_target_objc2 { } {
3302 return [check_no_compiler_messages objc2 object {
3303 #ifdef __OBJC2__
3304 int dummy[1];
3305 #else
3306 #error !__OBJC2__
3307 #endif
3308 }]
3309 }
3310
3311 proc check_effective_target_next_runtime { } {
3312 return [check_no_compiler_messages objc2 object {
3313 #ifdef __NEXT_RUNTIME__
3314 int dummy[1];
3315 #else
3316 #error !__NEXT_RUNTIME__
3317 #endif
3318 }]
3319 }
3320
3321 # Return 1 if we're generating code for big-endian memory order.
3322
3323 proc check_effective_target_be { } {
3324 return [check_no_compiler_messages be object {
3325 int dummy[__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? 1 : -1];
3326 }]
3327 }
3328
3329 # Return 1 if we're generating code for little-endian memory order.
3330
3331 proc check_effective_target_le { } {
3332 return [check_no_compiler_messages le object {
3333 int dummy[__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ? 1 : -1];
3334 }]
3335 }
3336
3337 # Return 1 if we can link a program with 2+GB of data.
3338
3339 proc check_effective_target_two_plus_gigs { } {
3340 return [check_no_compiler_messages two_plus_gigs executable {
3341 char dummy[0x80000000];
3342 int main () { return 0; }
3343 }]
3344 }
3345
3346 # Return 1 if we're generating 32-bit code using default options, 0
3347 # otherwise.
3348
3349 proc check_effective_target_ilp32 { } {
3350 return [check_no_compiler_messages ilp32 object {
3351 int dummy[sizeof (int) == 4
3352 && sizeof (void *) == 4
3353 && sizeof (long) == 4 ? 1 : -1];
3354 }]
3355 }
3356
3357 # Return 1 if we're generating ia32 code using default options, 0
3358 # otherwise.
3359
3360 proc check_effective_target_ia32 { } {
3361 return [check_no_compiler_messages ia32 object {
3362 int dummy[sizeof (int) == 4
3363 && sizeof (void *) == 4
3364 && sizeof (long) == 4 ? 1 : -1] = { __i386__ };
3365 }]
3366 }
3367
3368 # Return 1 if we're generating x32 code using default options, 0
3369 # otherwise.
3370
3371 proc check_effective_target_x32 { } {
3372 return [check_no_compiler_messages x32 object {
3373 int dummy[sizeof (int) == 4
3374 && sizeof (void *) == 4
3375 && sizeof (long) == 4 ? 1 : -1] = { __x86_64__ };
3376 }]
3377 }
3378
3379 # Return 1 if we're generating 32-bit integers using default
3380 # options, 0 otherwise.
3381
3382 proc check_effective_target_int32 { } {
3383 return [check_no_compiler_messages int32 object {
3384 int dummy[sizeof (int) == 4 ? 1 : -1];
3385 }]
3386 }
3387
3388 # Return 1 if we're generating 32-bit or larger integers using default
3389 # options, 0 otherwise.
3390
3391 proc check_effective_target_int32plus { } {
3392 return [check_no_compiler_messages int32plus object {
3393 int dummy[sizeof (int) >= 4 ? 1 : -1];
3394 }]
3395 }
3396
3397 # Return 1 if we're generating 64-bit long long using default options,
3398 # 0 otherwise.
3399
3400 proc check_effective_target_longlong64 { } {
3401 return [check_no_compiler_messages longlong64 object {
3402 int dummy[sizeof (long long) == 8 ? 1 : -1];
3403 }]
3404 }
3405
3406 # Return 1 if we're generating 32-bit or larger pointers using default
3407 # options, 0 otherwise.
3408
3409 proc check_effective_target_ptr32plus { } {
3410 # The msp430 has 16-bit or 20-bit pointers. The 20-bit pointer is stored
3411 # in a 32-bit slot when in memory, so sizeof(void *) returns 4, but it
3412 # cannot really hold a 32-bit address, so we always return false here.
3413 if { [istarget msp430-*-*] } {
3414 return 0
3415 }
3416
3417 return [check_no_compiler_messages ptr32plus object {
3418 int dummy[sizeof (void *) >= 4 ? 1 : -1];
3419 }]
3420 }
3421
3422 # Return 1 if we support 16-bit or larger array and structure sizes
3423 # using default options, 0 otherwise.
3424 # This implies at least a 20-bit address space, as no targets have an address
3425 # space between 16 and 20 bits.
3426
3427 proc check_effective_target_size20plus { } {
3428 return [check_no_compiler_messages size20plus object {
3429 char dummy[65537L];
3430 }]
3431 }
3432
3433 # Return 1 if target supports function pointers, 0 otherwise.
3434
3435 proc check_effective_target_function_pointers { } {
3436 if { [istarget pru-*-*] } {
3437 return [check_no_compiler_messages func_ptr_avail assembly {
3438 #ifdef __PRU_EABI_GNU__
3439 #error unsupported
3440 #endif
3441 }]
3442 }
3443 return 1
3444 }
3445
3446 # Return 1 if target supports arbitrarily large return values, 0 otherwise.
3447
3448 proc check_effective_target_large_return_values { } {
3449 if { [istarget pru-*-*] } {
3450 return [check_no_compiler_messages large_return_values assembly {
3451 #ifdef __PRU_EABI_GNU__
3452 #error unsupported
3453 #endif
3454 }]
3455 }
3456 return 1
3457 }
3458 # Return 1 if we support 20-bit or larger array and structure sizes
3459 # using default options, 0 otherwise.
3460 # This implies at least a 24-bit address space, as no targets have an address
3461 # space between 20 and 24 bits.
3462
3463 proc check_effective_target_size24plus { } {
3464 return [check_no_compiler_messages size24plus object {
3465 char dummy[524289L];
3466 }]
3467 }
3468
3469 # Return 1 if we support 24-bit or larger array and structure sizes
3470 # using default options, 0 otherwise.
3471 # This implies at least a 32-bit address space, as no targets have an address
3472 # space between 24 and 32 bits.
3473
3474 proc check_effective_target_size32plus { } {
3475 return [check_no_compiler_messages size32plus object {
3476 char dummy[16777217L];
3477 }]
3478 }
3479
3480 # Returns 1 if we're generating 16-bit or smaller integers with the
3481 # default options, 0 otherwise.
3482
3483 proc check_effective_target_int16 { } {
3484 return [check_no_compiler_messages int16 object {
3485 int dummy[sizeof (int) < 4 ? 1 : -1];
3486 }]
3487 }
3488
3489 # Return 1 if we're generating 64-bit code using default options, 0
3490 # otherwise.
3491
3492 proc check_effective_target_lp64 { } {
3493 return [check_no_compiler_messages lp64 object {
3494 int dummy[sizeof (int) == 4
3495 && sizeof (void *) == 8
3496 && sizeof (long) == 8 ? 1 : -1];
3497 }]
3498 }
3499
3500 # Return 1 if we're generating 64-bit code using default llp64 options,
3501 # 0 otherwise.
3502
3503 proc check_effective_target_llp64 { } {
3504 return [check_no_compiler_messages llp64 object {
3505 int dummy[sizeof (int) == 4
3506 && sizeof (void *) == 8
3507 && sizeof (long long) == 8
3508 && sizeof (long) == 4 ? 1 : -1];
3509 }]
3510 }
3511
3512 # Return 1 if long and int have different sizes,
3513 # 0 otherwise.
3514
3515 proc check_effective_target_long_neq_int { } {
3516 return [check_no_compiler_messages long_ne_int object {
3517 int dummy[sizeof (int) != sizeof (long) ? 1 : -1];
3518 }]
3519 }
3520
3521 # Return 1 if int size is equal to float size,
3522 # 0 otherwise.
3523
3524 proc check_effective_target_int_eq_float { } {
3525 return [check_no_compiler_messages int_eq_float object {
3526 int dummy[sizeof (int) >= sizeof (float) ? 1 : -1];
3527 }]
3528 }
3529
3530 # Return 1 if short size is equal to int size,
3531 # 0 otherwise.
3532
3533 proc check_effective_target_short_eq_int { } {
3534 return [check_no_compiler_messages short_eq_int object {
3535 int dummy[sizeof (short) == sizeof (int) ? 1 : -1];
3536 }]
3537 }
3538
3539 # Return 1 if pointer size is equal to short size,
3540 # 0 otherwise.
3541
3542 proc check_effective_target_ptr_eq_short { } {
3543 return [check_no_compiler_messages ptr_eq_short object {
3544 int dummy[sizeof (void *) == sizeof (short) ? 1 : -1];
3545 }]
3546 }
3547
3548 # Return 1 if pointer size is equal to long size,
3549 # 0 otherwise.
3550
3551 proc check_effective_target_ptr_eq_long { } {
3552 # sizeof (void *) == 4 for msp430-elf -mlarge which is equal to
3553 # sizeof (long). Avoid false positive.
3554 if { [istarget msp430-*-*] } {
3555 return 0
3556 }
3557 return [check_no_compiler_messages ptr_eq_long object {
3558 int dummy[sizeof (void *) == sizeof (long) ? 1 : -1];
3559 }]
3560 }
3561
3562 # Return 1 if the target supports long double larger than double,
3563 # 0 otherwise.
3564
3565 proc check_effective_target_large_long_double { } {
3566 return [check_no_compiler_messages large_long_double object {
3567 int dummy[sizeof(long double) > sizeof(double) ? 1 : -1];
3568 }]
3569 }
3570
3571 # Return 1 if the target supports double larger than float,
3572 # 0 otherwise.
3573
3574 proc check_effective_target_large_double { } {
3575 return [check_no_compiler_messages large_double object {
3576 int dummy[sizeof(double) > sizeof(float) ? 1 : -1];
3577 }]
3578 }
3579
3580 # Return 1 if the target supports long double of 128 bits,
3581 # 0 otherwise.
3582
3583 proc check_effective_target_longdouble128 { } {
3584 return [check_no_compiler_messages longdouble128 object {
3585 int dummy[sizeof(long double) == 16 ? 1 : -1];
3586 }]
3587 }
3588
3589 # Return 1 if the target supports long double of 64 bits,
3590 # 0 otherwise.
3591
3592 proc check_effective_target_longdouble64 { } {
3593 return [check_no_compiler_messages longdouble64 object {
3594 int dummy[sizeof(long double) == 8 ? 1 : -1];
3595 }]
3596 }
3597
3598 # Return 1 if the target supports double of 64 bits,
3599 # 0 otherwise.
3600
3601 proc check_effective_target_double64 { } {
3602 return [check_no_compiler_messages double64 object {
3603 int dummy[sizeof(double) == 8 ? 1 : -1];
3604 }]
3605 }
3606
3607 # Return 1 if the target supports double of at least 64 bits,
3608 # 0 otherwise.
3609
3610 proc check_effective_target_double64plus { } {
3611 return [check_no_compiler_messages double64plus object {
3612 int dummy[sizeof(double) >= 8 ? 1 : -1];
3613 }]
3614 }
3615
3616 # Return 1 if the target supports 'w' suffix on floating constant
3617 # 0 otherwise.
3618
3619 proc check_effective_target_has_w_floating_suffix { } {
3620 set opts ""
3621 if [check_effective_target_c++] {
3622 append opts "-std=gnu++03"
3623 }
3624 return [check_no_compiler_messages w_fp_suffix object {
3625 float dummy = 1.0w;
3626 } "$opts"]
3627 }
3628
3629 # Return 1 if the target supports 'q' suffix on floating constant
3630 # 0 otherwise.
3631
3632 proc check_effective_target_has_q_floating_suffix { } {
3633 set opts ""
3634 if [check_effective_target_c++] {
3635 append opts "-std=gnu++03"
3636 }
3637 return [check_no_compiler_messages q_fp_suffix object {
3638 float dummy = 1.0q;
3639 } "$opts"]
3640 }
3641
3642 # Return 1 if the target supports the _FloatN / _FloatNx type
3643 # indicated in the function name, 0 otherwise.
3644
3645 proc check_effective_target_float16 {} {
3646 return [check_no_compiler_messages_nocache float16 object {
3647 _Float16 foo (_Float16 x) { return x; }
3648 } [add_options_for_float16 ""]]
3649 }
3650
3651 proc check_effective_target_float32 {} {
3652 return [check_no_compiler_messages_nocache float32 object {
3653 _Float32 x;
3654 } [add_options_for_float32 ""]]
3655 }
3656
3657 proc check_effective_target_float64 {} {
3658 return [check_no_compiler_messages_nocache float64 object {
3659 _Float64 x;
3660 } [add_options_for_float64 ""]]
3661 }
3662
3663 proc check_effective_target_float128 {} {
3664 return [check_no_compiler_messages_nocache float128 object {
3665 _Float128 x;
3666 } [add_options_for_float128 ""]]
3667 }
3668
3669 proc check_effective_target_float32x {} {
3670 return [check_no_compiler_messages_nocache float32x object {
3671 _Float32x x;
3672 } [add_options_for_float32x ""]]
3673 }
3674
3675 proc check_effective_target_float64x {} {
3676 return [check_no_compiler_messages_nocache float64x object {
3677 _Float64x x;
3678 } [add_options_for_float64x ""]]
3679 }
3680
3681 proc check_effective_target_float128x {} {
3682 return [check_no_compiler_messages_nocache float128x object {
3683 _Float128x x;
3684 } [add_options_for_float128x ""]]
3685 }
3686
3687 # Likewise, but runtime support for any special options used as well
3688 # as compile-time support is required.
3689
3690 proc check_effective_target_float16_runtime {} {
3691 return [check_effective_target_float16]
3692 }
3693
3694 proc check_effective_target_float32_runtime {} {
3695 return [check_effective_target_float32]
3696 }
3697
3698 proc check_effective_target_float64_runtime {} {
3699 return [check_effective_target_float64]
3700 }
3701
3702 proc check_effective_target_float128_runtime {} {
3703 if { ![check_effective_target_float128] } {
3704 return 0
3705 }
3706 if { [istarget powerpc*-*-*] } {
3707 return [check_effective_target_base_quadfloat_support]
3708 }
3709 return 1
3710 }
3711
3712 proc check_effective_target_float32x_runtime {} {
3713 return [check_effective_target_float32x]
3714 }
3715
3716 proc check_effective_target_float64x_runtime {} {
3717 if { ![check_effective_target_float64x] } {
3718 return 0
3719 }
3720 if { [istarget powerpc*-*-*] } {
3721 return [check_effective_target_base_quadfloat_support]
3722 }
3723 return 1
3724 }
3725
3726 proc check_effective_target_float128x_runtime {} {
3727 return [check_effective_target_float128x]
3728 }
3729
3730 # Return 1 if the target hardware supports any options added for
3731 # _FloatN and _FloatNx types, 0 otherwise.
3732
3733 proc check_effective_target_floatn_nx_runtime {} {
3734 if { [istarget powerpc*-*-aix*] } {
3735 return 0
3736 }
3737 if { [istarget powerpc*-*-*] } {
3738 return [check_effective_target_base_quadfloat_support]
3739 }
3740 return 1
3741 }
3742
3743 # Add options needed to use the _FloatN / _FloatNx type indicated in
3744 # the function name.
3745
3746 proc add_options_for_float16 { flags } {
3747 if { [istarget arm*-*-*] } {
3748 return "$flags -mfp16-format=ieee"
3749 }
3750 if { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
3751 return "$flags -msse2"
3752 }
3753 return "$flags"
3754 }
3755
3756 proc add_options_for_float32 { flags } {
3757 return "$flags"
3758 }
3759
3760 proc add_options_for_float64 { flags } {
3761 return "$flags"
3762 }
3763
3764 proc add_options_for_float128 { flags } {
3765 return [add_options_for___float128 "$flags"]
3766 }
3767
3768 proc add_options_for_float32x { flags } {
3769 return "$flags"
3770 }
3771
3772 proc add_options_for_float64x { flags } {
3773 return [add_options_for___float128 "$flags"]
3774 }
3775
3776 proc add_options_for_float128x { flags } {
3777 return "$flags"
3778 }
3779
3780 # Return 1 if the target supports __float128,
3781 # 0 otherwise.
3782
3783 proc check_effective_target___float128 { } {
3784 if { [istarget powerpc*-*-*] } {
3785 return [check_ppc_float128_sw_available]
3786 }
3787 if { [istarget ia64-*-*]
3788 || [istarget i?86-*-*] || [istarget x86_64-*-*] } {
3789 return 1
3790 }
3791 return 0
3792 }
3793
3794 proc add_options_for___float128 { flags } {
3795 if { [istarget powerpc*-*-linux*] } {
3796 return "$flags -mfloat128 -mvsx"
3797 }
3798 return "$flags"
3799 }
3800
3801 # Return 1 if the target supports any special run-time requirements
3802 # for __float128 or _Float128,
3803 # 0 otherwise.
3804
3805 proc check_effective_target_base_quadfloat_support { } {
3806 if { [istarget powerpc*-*-*] } {
3807 return [check_vsx_hw_available]
3808 }
3809 return 1
3810 }
3811
3812 # Return 1 if the target supports the __bf16 type, 0 otherwise.
3813
3814 proc check_effective_target_bfloat16 {} {
3815 return [check_no_compiler_messages_nocache bfloat16 object {
3816 __bf16 foo (__bf16 x) { return x + x; }
3817 } [add_options_for_bfloat16 ""]]
3818 }
3819
3820 proc check_effective_target_bfloat16_runtime {} {
3821 return [check_effective_target_bfloat16]
3822 }
3823
3824 proc add_options_for_bfloat16 { flags } {
3825 return "$flags"
3826 }
3827
3828 # Return 1 if the target supports all four forms of fused multiply-add
3829 # (fma, fms, fnma, and fnms) for both float and double.
3830
3831 proc check_effective_target_scalar_all_fma { } {
3832 if { [istarget aarch64*-*-*]
3833 || [istarget loongarch*-*-*]} {
3834 return 1
3835 }
3836 return 0
3837 }
3838
3839 # Return 1 if the target supports compiling fixed-point,
3840 # 0 otherwise.
3841
3842 proc check_effective_target_fixed_point { } {
3843 return [check_no_compiler_messages fixed_point object {
3844 _Sat _Fract x; _Sat _Accum y;
3845 }]
3846 }
3847
3848 # Return 1 if the target supports _BitInt(N), 0 otherwise.
3849
3850 proc check_effective_target_bitint { } {
3851 return [check_no_compiler_messages bitint object {
3852 _BitInt (2) a = 1wb;
3853 unsigned _BitInt (__BITINT_MAXWIDTH__) b = 0uwb;
3854 } "-std=c23"]
3855 }
3856
3857 # Return 1 if the target supports _BitInt(128), 0 otherwise.
3858
3859 proc check_effective_target_bitint128 { } {
3860 return [check_no_compiler_messages bitint128 object {
3861 _BitInt (2) a = 1wb;
3862 unsigned _BitInt (128) b = 0uwb;
3863 } "-std=c23"]
3864 }
3865
3866 # Return 1 if the target supports _BitInt(575), 0 otherwise.
3867
3868 proc check_effective_target_bitint575 { } {
3869 return [check_no_compiler_messages bitint575 object {
3870 _BitInt (2) a = 1wb;
3871 unsigned _BitInt (575) b = 0uwb;
3872 } "-std=c23"]
3873 }
3874
3875 # Return 1 if the target supports _BitInt(65535), 0 otherwise.
3876
3877 proc check_effective_target_bitint65535 { } {
3878 return [check_no_compiler_messages bitint65535 object {
3879 _BitInt (2) a = 1wb;
3880 unsigned _BitInt (65535) b = 0uwb;
3881 } "-std=c23"]
3882 }
3883
3884 # Return 1 if the target supports compiling decimal floating point,
3885 # 0 otherwise.
3886
3887 proc check_effective_target_dfp_nocache { } {
3888 verbose "check_effective_target_dfp_nocache: compiling source" 2
3889 set ret [check_no_compiler_messages_nocache dfp object {
3890 float x __attribute__((mode(DD)));
3891 }]
3892 verbose "check_effective_target_dfp_nocache: returning $ret" 2
3893 return $ret
3894 }
3895
3896 proc check_effective_target_dfprt_nocache { } {
3897 return [check_runtime_nocache dfprt {
3898 typedef float d64 __attribute__((mode(DD)));
3899 d64 x = 1.2df, y = 2.3dd, z;
3900 int main () { z = x + y; return 0; }
3901 }]
3902 }
3903
3904 # Return 1 if the target supports compiling Decimal Floating Point,
3905 # 0 otherwise.
3906 #
3907 # This won't change for different subtargets so cache the result.
3908
3909 proc check_effective_target_dfp { } {
3910 return [check_cached_effective_target dfp {
3911 check_effective_target_dfp_nocache
3912 }]
3913 }
3914
3915 # Return 1 if the target supports linking and executing Decimal Floating
3916 # Point, 0 otherwise.
3917 #
3918 # This won't change for different subtargets so cache the result.
3919
3920 proc check_effective_target_dfprt { } {
3921 return [check_cached_effective_target dfprt {
3922 check_effective_target_dfprt_nocache
3923 }]
3924 }
3925
3926 # Return 1 if the target uses the BID format for Decimal Floating
3927 # Point, 0 otherwise.
3928
3929 proc check_effective_target_dfp_bid { } {
3930 if { [istarget aarch64*-*-*]
3931 || [istarget i?86-*-*] || [istarget x86_64-*-*]} {
3932 return 1
3933 }
3934 return 0
3935 }
3936
3937 # Return 1 iff target has unsigned plain 'char' by default.
3938
3939 proc check_effective_target_unsigned_char {} {
3940 return [check_no_compiler_messages unsigned_char assembly {
3941 char ar[(char)-1];
3942 }]
3943 }
3944
3945 proc check_effective_target_powerpc_popcntb_ok { } {
3946 return [check_cached_effective_target powerpc_popcntb_ok {
3947
3948 # Disable on Darwin.
3949 if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
3950 expr 0
3951 } else {
3952 check_runtime_nocache powerpc_popcntb_ok {
3953 volatile int r;
3954 volatile int a = 0x12345678;
3955 int main()
3956 {
3957 asm volatile ("popcntb %0,%1" : "=r" (r) : "r" (a));
3958 return 0;
3959 }
3960 } "-mcpu=power5"
3961 }
3962 }]
3963 }
3964
3965 # Return 1 if the target supports executing DFP hardware instructions,
3966 # 0 otherwise. Cache the result.
3967
3968 proc check_dfp_hw_available { } {
3969 return [check_cached_effective_target dfp_hw_available {
3970 # For now, disable on Darwin
3971 if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
3972 expr 0
3973 } else {
3974 check_runtime_nocache dfp_hw_available {
3975 volatile _Decimal64 r;
3976 volatile _Decimal64 a = 4.0DD;
3977 volatile _Decimal64 b = 2.0DD;
3978 int main()
3979 {
3980 asm volatile ("dadd %0,%1,%2" : "=d" (r) : "d" (a), "d" (b));
3981 asm volatile ("dsub %0,%1,%2" : "=d" (r) : "d" (a), "d" (b));
3982 asm volatile ("dmul %0,%1,%2" : "=d" (r) : "d" (a), "d" (b));
3983 asm volatile ("ddiv %0,%1,%2" : "=d" (r) : "d" (a), "d" (b));
3984 return 0;
3985 }
3986 } "-mcpu=power6 -mhard-float"
3987 }
3988 }]
3989 }
3990
3991 # Return 1 if the target supports compiling and assembling UCN, 0 otherwise.
3992
3993 proc check_effective_target_ucn_nocache { } {
3994 # -std=c99 is only valid for C
3995 if [check_effective_target_c] {
3996 set ucnopts "-std=c99"
3997 } else {
3998 set ucnopts ""
3999 }
4000 verbose "check_effective_target_ucn_nocache: compiling source" 2
4001 set ret [check_no_compiler_messages_nocache ucn object {
4002 int \u00C0;
4003 } $ucnopts]
4004 verbose "check_effective_target_ucn_nocache: returning $ret" 2
4005 return $ret
4006 }
4007
4008 # Return 1 if the target supports compiling and assembling UCN, 0 otherwise.
4009 #
4010 # This won't change for different subtargets, so cache the result.
4011
4012 proc check_effective_target_ucn { } {
4013 return [check_cached_effective_target ucn {
4014 check_effective_target_ucn_nocache
4015 }]
4016 }
4017
4018 # Return 1 if the target needs a command line argument to enable a SIMD
4019 # instruction set.
4020
4021 proc check_effective_target_vect_cmdline_needed { } {
4022 global et_vect_cmdline_needed_target_name
4023
4024 if { ![info exists et_vect_cmdline_needed_target_name] } {
4025 set et_vect_cmdline_needed_target_name ""
4026 }
4027
4028 # If the target has changed since we set the cached value, clear it.
4029 set current_target [current_target_name]
4030 if { $current_target != $et_vect_cmdline_needed_target_name } {
4031 verbose "check_effective_target_vect_cmdline_needed: `$et_vect_cmdline_needed_target_name' `$current_target'" 2
4032 set et_vect_cmdline_needed_target_name $current_target
4033 if { [info exists et_vect_cmdline_needed_saved] } {
4034 verbose "check_effective_target_vect_cmdline_needed: removing cached result" 2
4035 unset et_vect_cmdline_needed_saved
4036 }
4037 }
4038
4039 return [check_cached_effective_target vect_cmdline_needed {
4040 if { [istarget alpha*-*-*]
4041 || [istarget ia64-*-*]
4042 || (([istarget i?86-*-*] || [istarget x86_64-*-*])
4043 && ![is-effective-target ia32])
4044 || ([istarget powerpc*-*-*]
4045 && ([check_effective_target_powerpc_spe]
4046 || [check_effective_target_powerpc_altivec]))
4047 || ([istarget sparc*-*-*] && [check_effective_target_sparc_vis])
4048 || ([istarget arm*-*-*] && [check_effective_target_arm_neon])
4049 || [istarget aarch64*-*-*]
4050 || [istarget amdgcn*-*-*]
4051 || [istarget riscv*-*-*]} {
4052 return 0
4053 } else {
4054 return 1
4055 }}]
4056 }
4057
4058 # Return 1 if the target supports hardware vectors of int, 0 otherwise.
4059 #
4060 # This won't change for different subtargets so cache the result.
4061
4062 proc check_effective_target_vect_int { } {
4063 return [check_cached_effective_target_indexed vect_int {
4064 expr {
4065 [istarget i?86-*-*] || [istarget x86_64-*-*]
4066 || ([istarget powerpc*-*-*]
4067 && ![istarget powerpc-*-linux*paired*])
4068 || [istarget amdgcn-*-*]
4069 || [istarget sparc*-*-*]
4070 || [istarget alpha*-*-*]
4071 || [istarget ia64-*-*]
4072 || [istarget aarch64*-*-*]
4073 || [is-effective-target arm_neon]
4074 || ([istarget mips*-*-*]
4075 && ([et-is-effective-target mips_loongson_mmi]
4076 || [et-is-effective-target mips_msa]))
4077 || ([istarget s390*-*-*]
4078 && [check_effective_target_s390_vx])
4079 || ([istarget riscv*-*-*]
4080 && [check_effective_target_riscv_v])
4081 || ([istarget loongarch*-*-*]
4082 && [check_effective_target_loongarch_sx])
4083 }}]
4084 }
4085
4086 # Return 1 if the target supports vectorization of early breaks,
4087 # 0 otherwise.
4088 #
4089 # This won't change for different subtargets so cache the result.
4090
4091 proc check_effective_target_vect_early_break { } {
4092 return [check_cached_effective_target_indexed vect_early_break {
4093 expr {
4094 [istarget aarch64*-*-*]
4095 || [check_effective_target_arm_v8_neon_ok]
4096 || [check_effective_target_sse4]
4097 }}]
4098 }
4099
4100 # Return 1 if the target supports hardware execution of early breaks,
4101 # 0 otherwise.
4102 #
4103 # This won't change for different subtargets so cache the result.
4104
4105 proc check_effective_target_vect_early_break_hw { } {
4106 return [check_cached_effective_target_indexed vect_early_break_hw {
4107 expr {
4108 [istarget aarch64*-*-*]
4109 || [check_effective_target_arm_v8_neon_hw]
4110 || [check_sse4_hw_available]
4111 }}]
4112 }
4113
4114 proc add_options_for_vect_early_break { flags } {
4115 if { ! [check_effective_target_vect_early_break] } {
4116 return "$flags"
4117 }
4118
4119 if { [check_effective_target_arm_v8_neon_ok] } {
4120 global et_arm_v8_neon_flags
4121 return "$flags $et_arm_v8_neon_flags -march=armv8-a"
4122 }
4123
4124 if { [check_effective_target_sse4] } {
4125 return "$flags -msse4.1"
4126 }
4127
4128 return "$flags"
4129 }
4130
4131 # Return 1 if the target supports hardware vectorization of complex additions of
4132 # byte, 0 otherwise.
4133 #
4134 # This won't change for different subtargets so cache the result.
4135
4136 proc check_effective_target_vect_complex_add_byte { } {
4137 return [check_cached_effective_target_indexed vect_complex_add_byte {
4138 expr {
4139 ([check_effective_target_aarch64_sve2]
4140 && [check_effective_target_aarch64_little_endian])
4141 || ([check_effective_target_arm_v8_1m_mve_fp_ok]
4142 && [check_effective_target_arm_little_endian])
4143 }}]
4144 }
4145
4146 # Return 1 if the target supports hardware vectorization of complex additions of
4147 # short, 0 otherwise.
4148 #
4149 # This won't change for different subtargets so cache the result.
4150
4151 proc check_effective_target_vect_complex_add_short { } {
4152 return [check_cached_effective_target_indexed vect_complex_add_short {
4153 expr {
4154 ([check_effective_target_aarch64_sve2]
4155 && [check_effective_target_aarch64_little_endian])
4156 || ([check_effective_target_arm_v8_1m_mve_fp_ok]
4157 && [check_effective_target_arm_little_endian])
4158 }}]
4159 }
4160
4161 # Return 1 if the target supports hardware vectorization of complex additions of
4162 # int, 0 otherwise.
4163 #
4164 # This won't change for different subtargets so cache the result.
4165
4166 proc check_effective_target_vect_complex_add_int { } {
4167 return [check_cached_effective_target_indexed vect_complex_add_int {
4168 expr {
4169 ([check_effective_target_aarch64_sve2]
4170 && [check_effective_target_aarch64_little_endian])
4171 || ([check_effective_target_arm_v8_1m_mve_fp_ok]
4172 && [check_effective_target_arm_little_endian])
4173 }}]
4174 }
4175
4176 # Return 1 if the target supports hardware vectorization of complex additions of
4177 # long, 0 otherwise.
4178 #
4179 # This won't change for different subtargets so cache the result.
4180
4181 proc check_effective_target_vect_complex_add_long { } {
4182 return [check_cached_effective_target_indexed vect_complex_add_long {
4183 expr {
4184 ([check_effective_target_aarch64_sve2]
4185 && [check_effective_target_aarch64_little_endian])
4186 || ([check_effective_target_arm_v8_1m_mve_fp_ok]
4187 && [check_effective_target_arm_little_endian])
4188 }}]
4189 }
4190
4191 # Return 1 if the target supports hardware vectorization of complex additions of
4192 # half, 0 otherwise.
4193 #
4194 # This won't change for different subtargets so cache the result.
4195
4196 proc check_effective_target_vect_complex_add_half { } {
4197 return [check_cached_effective_target_indexed vect_complex_add_half {
4198 expr {
4199 ([check_effective_target_arm_v8_3a_fp16_complex_neon_ok]
4200 && ([check_effective_target_aarch64_little_endian]
4201 || [check_effective_target_arm_little_endian]))
4202 || ([check_effective_target_aarch64_sve2]
4203 && [check_effective_target_aarch64_little_endian])
4204 || ([check_effective_target_arm_v8_1m_mve_fp_ok]
4205 && [check_effective_target_arm_little_endian])
4206 }}]
4207 }
4208
4209 # Return 1 if the target supports hardware vectorization of complex additions of
4210 # float, 0 otherwise.
4211 #
4212 # This won't change for different subtargets so cache the result.
4213
4214 proc check_effective_target_vect_complex_add_float { } {
4215 return [check_cached_effective_target_indexed vect_complex_add_float {
4216 expr {
4217 ([check_effective_target_arm_v8_3a_complex_neon_ok]
4218 && ([check_effective_target_aarch64_little_endian]
4219 || [check_effective_target_arm_little_endian]))
4220 || ([check_effective_target_aarch64_sve2]
4221 && [check_effective_target_aarch64_little_endian])
4222 || ([check_effective_target_arm_v8_1m_mve_fp_ok]
4223 && [check_effective_target_arm_little_endian])
4224 }}]
4225 }
4226
4227 # Return 1 if the target supports hardware vectorization of complex additions of
4228 # double, 0 otherwise.
4229 #
4230 # This won't change for different subtargets so cache the result.
4231
4232 proc check_effective_target_vect_complex_add_double { } {
4233 return [check_cached_effective_target_indexed vect_complex_add_double {
4234 expr {
4235 (([check_effective_target_arm_v8_3a_complex_neon_ok]
4236 && [check_effective_target_aarch64_little_endian])
4237 || ([check_effective_target_aarch64_sve2]
4238 && [check_effective_target_aarch64_little_endian]))
4239 }}]
4240 }
4241
4242 # Return 1 if the target supports signed int->float conversion
4243 #
4244
4245 proc check_effective_target_vect_intfloat_cvt { } {
4246 return [check_cached_effective_target_indexed vect_intfloat_cvt {
4247 expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
4248 || ([istarget powerpc*-*-*]
4249 && ![istarget powerpc-*-linux*paired*])
4250 || [is-effective-target arm_neon]
4251 || ([istarget mips*-*-*]
4252 && [et-is-effective-target mips_msa])
4253 || [istarget amdgcn-*-*]
4254 || ([istarget s390*-*-*]
4255 && [check_effective_target_s390_vxe2])
4256 || ([istarget riscv*-*-*]
4257 && [check_effective_target_riscv_v])
4258 || ([istarget loongarch*-*-*]
4259 && [check_effective_target_loongarch_sx]) }}]
4260 }
4261
4262 # Return 1 if the target supports signed double->int conversion
4263 #
4264
4265 proc check_effective_target_vect_doubleint_cvt { } {
4266 return [check_cached_effective_target_indexed vect_doubleint_cvt {
4267 expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
4268 && [check_no_compiler_messages vect_doubleint_cvt assembly {
4269 #ifdef __tune_atom__
4270 # error No double vectorizer support.
4271 #endif
4272 }])
4273 || [istarget aarch64*-*-*]
4274 || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
4275 || ([istarget mips*-*-*]
4276 && [et-is-effective-target mips_msa])
4277 || ([istarget s390*-*-*]
4278 && [check_effective_target_s390_vx])
4279 || ([istarget riscv*-*-*]
4280 && [check_effective_target_riscv_v])
4281 || ([istarget loongarch*-*-*]
4282 && [check_effective_target_loongarch_sx]) }}]
4283 }
4284
4285 # Return 1 if the target supports signed int->double conversion
4286 #
4287
4288 proc check_effective_target_vect_intdouble_cvt { } {
4289 return [check_cached_effective_target_indexed vect_intdouble_cvt {
4290 expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
4291 && [check_no_compiler_messages vect_intdouble_cvt assembly {
4292 #ifdef __tune_atom__
4293 # error No double vectorizer support.
4294 #endif
4295 }])
4296 || [istarget aarch64*-*-*]
4297 || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
4298 || ([istarget mips*-*-*]
4299 && [et-is-effective-target mips_msa])
4300 || ([istarget s390*-*-*]
4301 && [check_effective_target_s390_vx])
4302 || ([istarget riscv*-*-*]
4303 && [check_effective_target_riscv_v])
4304 || ([istarget loongarch*-*-*]
4305 && [check_effective_target_loongarch_sx]) }}]
4306 }
4307
4308 #Return 1 if we're supporting __int128 for target, 0 otherwise.
4309
4310 proc check_effective_target_int128 { } {
4311 return [check_no_compiler_messages int128 object {
4312 int dummy[
4313 #ifndef __SIZEOF_INT128__
4314 -1
4315 #else
4316 1
4317 #endif
4318 ];
4319 }]
4320 }
4321
4322 # Return 1 if the target supports unsigned int->float conversion
4323 #
4324
4325 proc check_effective_target_vect_uintfloat_cvt { } {
4326 return [check_cached_effective_target_indexed vect_uintfloat_cvt {
4327 expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
4328 || ([istarget powerpc*-*-*]
4329 && ![istarget powerpc-*-linux*paired*])
4330 || [istarget aarch64*-*-*]
4331 || [is-effective-target arm_neon]
4332 || ([istarget mips*-*-*]
4333 && [et-is-effective-target mips_msa])
4334 || [istarget amdgcn-*-*]
4335 || ([istarget s390*-*-*]
4336 && [check_effective_target_s390_vxe2])
4337 || ([istarget riscv*-*-*]
4338 && [check_effective_target_riscv_v])
4339 || ([istarget loongarch*-*-*]
4340 && [check_effective_target_loongarch_sx]) }}]
4341 }
4342
4343
4344 # Return 1 if the target supports signed float->int conversion
4345 #
4346
4347 proc check_effective_target_vect_floatint_cvt { } {
4348 return [check_cached_effective_target_indexed vect_floatint_cvt {
4349 expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
4350 || ([istarget powerpc*-*-*]
4351 && ![istarget powerpc-*-linux*paired*])
4352 || [is-effective-target arm_neon]
4353 || ([istarget mips*-*-*]
4354 && [et-is-effective-target mips_msa])
4355 || [istarget amdgcn-*-*]
4356 || ([istarget s390*-*-*]
4357 && [check_effective_target_s390_vxe2])
4358 || ([istarget riscv*-*-*]
4359 && [check_effective_target_riscv_v])
4360 || ([istarget loongarch*-*-*]
4361 && [check_effective_target_loongarch_sx]) }}]
4362 }
4363
4364 # Return 1 if the target supports unsigned float->int conversion
4365 #
4366
4367 proc check_effective_target_vect_floatuint_cvt { } {
4368 return [check_cached_effective_target_indexed vect_floatuint_cvt {
4369 expr { ([istarget powerpc*-*-*]
4370 && ![istarget powerpc-*-linux*paired*])
4371 || [is-effective-target arm_neon]
4372 || ([istarget mips*-*-*]
4373 && [et-is-effective-target mips_msa])
4374 || [istarget amdgcn-*-*]
4375 || ([istarget s390*-*-*]
4376 && [check_effective_target_s390_vxe2])
4377 || ([istarget riscv*-*-*]
4378 && [check_effective_target_riscv_v])
4379 || ([istarget loongarch*-*-*]
4380 && [check_effective_target_loongarch_sx]) }}]
4381 }
4382
4383 # Return 1 if the target supports vector integer char -> long long extend optab
4384 #
4385
4386 proc check_effective_target_vect_ext_char_longlong { } {
4387 return [check_cached_effective_target_indexed vect_ext_char_longlong {
4388 expr { ([istarget riscv*-*-*]
4389 && [check_effective_target_riscv_v])
4390 || ([istarget loongarch*-*-*]
4391 && [check_effective_target_loongarch_sx]) }}]
4392 }
4393
4394 # Return 1 if peeling for alignment might be profitable on the target
4395 #
4396
4397 proc check_effective_target_vect_peeling_profitable { } {
4398 return [check_cached_effective_target_indexed vect_peeling_profitable {
4399 expr { ([istarget s390*-*-*]
4400 && [check_effective_target_s390_vx])
4401 || [check_effective_target_vect_element_align_preferred] }}]
4402 }
4403
4404 # Return 1 if the target supports #pragma omp declare simd, 0 otherwise.
4405 #
4406 # This won't change for different subtargets so cache the result.
4407
4408 proc check_effective_target_vect_simd_clones { } {
4409 # On i?86/x86_64 #pragma omp declare simd builds a sse2, avx,
4410 # avx2 and avx512f clone. Only the right clone for the
4411 # specified arch will be chosen, but still we need to at least
4412 # be able to assemble avx512f.
4413 return [check_cached_effective_target_indexed vect_simd_clones {
4414 expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
4415 && [check_effective_target_avx512f])
4416 || [istarget amdgcn-*-*]
4417 || [istarget aarch64*-*-*] }}]
4418 }
4419
4420 # Return 1 if this is a AArch64 target supporting big endian
4421 proc check_effective_target_aarch64_big_endian { } {
4422 return [check_no_compiler_messages aarch64_big_endian assembly {
4423 #if !defined(__aarch64__) || !defined(__AARCH64EB__)
4424 #error !__aarch64__ || !__AARCH64EB__
4425 #endif
4426 }]
4427 }
4428
4429 # Return 1 if this is a AArch64 target supporting little endian
4430 proc check_effective_target_aarch64_little_endian { } {
4431 if { ![istarget aarch64*-*-*] } {
4432 return 0
4433 }
4434
4435 return [check_no_compiler_messages aarch64_little_endian assembly {
4436 #if !defined(__aarch64__) || defined(__AARCH64EB__)
4437 #error FOO
4438 #endif
4439 }]
4440 }
4441
4442 # Return 1 if this is an AArch64 target supporting SVE.
4443 proc check_effective_target_aarch64_sve { } {
4444 if { ![istarget aarch64*-*-*] } {
4445 return 0
4446 }
4447 return [check_no_compiler_messages aarch64_sve assembly {
4448 #if !defined (__ARM_FEATURE_SVE)
4449 #error FOO
4450 #endif
4451 }]
4452 }
4453
4454 # Return 1 if this is an AArch64 target supporting SVE2.
4455 proc check_effective_target_aarch64_sve2 { } {
4456 if { ![istarget aarch64*-*-*] } {
4457 return 0
4458 }
4459 return [check_no_compiler_messages aarch64_sve2 assembly {
4460 #if !defined (__ARM_FEATURE_SVE2)
4461 #error FOO
4462 #endif
4463 }]
4464 }
4465
4466 # Return 1 if this is an AArch64 target only supporting SVE (not SVE2).
4467 proc check_effective_target_aarch64_sve1_only { } {
4468 return [expr { [check_effective_target_aarch64_sve]
4469 && ![check_effective_target_aarch64_sve2] }]
4470 }
4471
4472 # Return the size in bits of an SVE vector, or 0 if the size is variable.
4473 proc aarch64_sve_bits { } {
4474 return [check_cached_effective_target aarch64_sve_bits {
4475 global tool
4476
4477 set src dummy[pid].c
4478 set f [open $src "w"]
4479 puts $f "int bits = __ARM_FEATURE_SVE_BITS;"
4480 close $f
4481 set output [${tool}_target_compile $src "" preprocess ""]
4482 file delete $src
4483
4484 regsub {.*bits = ([^;]*);.*} $output {\1} bits
4485 expr { $bits }
4486 }]
4487 }
4488
4489 # Return 1 if this is an AArch64 target that generates instructions for SME.
4490 proc check_effective_target_aarch64_sme { } {
4491 if { ![istarget aarch64*-*-*] } {
4492 return 0
4493 }
4494 return [check_no_compiler_messages aarch64_sme assembly {
4495 #if !defined (__ARM_FEATURE_SME)
4496 #error FOO
4497 #endif
4498 }]
4499 }
4500
4501 # Return 1 if this is an AArch64 target that generates instructions for SME.
4502 proc check_effective_target_aarch64_sme2 { } {
4503 if { ![istarget aarch64*-*-*] } {
4504 return 0
4505 }
4506 return [check_no_compiler_messages aarch64_sme2 assembly {
4507 #if !defined (__ARM_FEATURE_SME2)
4508 #error FOO
4509 #endif
4510 }]
4511 }
4512
4513 # Return 1 if this is a compiler supporting ARC atomic operations
4514 proc check_effective_target_arc_atomic { } {
4515 return [check_no_compiler_messages arc_atomic assembly {
4516 #if !defined(__ARC_ATOMIC__)
4517 #error FOO
4518 #endif
4519 }]
4520 }
4521
4522 # Return 1 if this is an arm target using 32-bit instructions
4523 proc check_effective_target_arm32 { } {
4524 if { ![istarget arm*-*-*] } {
4525 return 0
4526 }
4527
4528 return [check_no_compiler_messages arm32 assembly {
4529 #if !defined(__arm__) || (defined(__thumb__) && !defined(__thumb2__))
4530 #error !__arm || __thumb__ && !__thumb2__
4531 #endif
4532 }]
4533 }
4534
4535 # Return 1 if this is an arm target not using Thumb
4536 proc check_effective_target_arm_nothumb { } {
4537 if { ![istarget arm*-*-*] } {
4538 return 0
4539 }
4540
4541 return [check_no_compiler_messages arm_nothumb assembly {
4542 #if !defined(__arm__) || (defined(__thumb__) || defined(__thumb2__))
4543 #error !__arm__ || __thumb || __thumb2__
4544 #endif
4545 }]
4546 }
4547
4548 # Return 1 if this is a little-endian ARM target
4549 proc check_effective_target_arm_little_endian { } {
4550 if { ![istarget arm*-*-*] } {
4551 return 0
4552 }
4553
4554 return [check_no_compiler_messages arm_little_endian assembly {
4555 #if !defined(__arm__) || !defined(__ARMEL__)
4556 #error !__arm__ || !__ARMEL__
4557 #endif
4558 }]
4559 }
4560
4561 # Return 1 if this is an ARM target that only supports aligned vector accesses
4562 proc check_effective_target_arm_vect_no_misalign { } {
4563 if { ![istarget arm*-*-*] } {
4564 return 0
4565 }
4566
4567 return [check_no_compiler_messages arm_vect_no_misalign assembly {
4568 #if !defined(__arm__) \
4569 || (defined(__ARM_FEATURE_UNALIGNED) \
4570 && defined(__ARMEL__))
4571 #error !__arm__ || (__ARMEL__ && __ARM_FEATURE_UNALIGNED)
4572 #endif
4573 }]
4574 }
4575
4576
4577 # Return 1 if this is an ARM target supporting -mfloat-abi=soft. Some
4578 # multilibs may be incompatible with this option.
4579
4580 proc check_effective_target_arm_soft_ok { } {
4581 return [check_no_compiler_messages arm_soft_ok object {
4582 #include <stdint.h>
4583 int dummy;
4584 int main (void) { return 0; }
4585 } "-mfloat-abi=soft"]
4586 }
4587
4588 # Return 1 if this is an ARM target supporting -mfloat-abi=soft even
4589 # for linking. Some multilibs may be incompatible with this option,
4590 # and some linkers may reject incompatible options.
4591
4592 proc check_effective_target_arm_soft_ok_link { } {
4593 return [check_no_compiler_messages arm_soft_ok_link executable {
4594 #include <stdint.h>
4595 int dummy;
4596 int main (void) { return 0; }
4597 } "-mfloat-abi=soft"]
4598 }
4599
4600 # Return 1 if this is an ARM target supporting -mfpu=vfp with an
4601 # appropriate abi.
4602
4603 proc check_effective_target_arm_vfp_ok_nocache { } {
4604 global et_arm_vfp_flags
4605 set et_arm_vfp_flags ""
4606 if { [check_effective_target_arm32] } {
4607 foreach flags {"-mfpu=vfp" "-mfpu=vfp -mfloat-abi=softfp" "-mfpu=vfp -mfloat-abi=hard"} {
4608 if { [check_no_compiler_messages_nocache arm_vfp_ok object {
4609 #ifndef __ARM_FP
4610 #error __ARM_FP not defined
4611 #endif
4612 } "$flags"] } {
4613 set et_arm_vfp_flags $flags
4614 return 1
4615 }
4616 }
4617 }
4618
4619 return 0
4620 }
4621
4622 proc check_effective_target_arm_vfp_ok { } {
4623 return [check_cached_effective_target arm_vfp_ok \
4624 check_effective_target_arm_vfp_ok_nocache]
4625 }
4626
4627 # Add the options needed to compile code with -mfpu=vfp. We need either
4628 # -mfloat-abi=softfp or -mfloat-abi=hard, but if one is already
4629 # specified by the multilib, use it.
4630
4631 proc add_options_for_arm_vfp { flags } {
4632 if { ! [check_effective_target_arm_vfp_ok] } {
4633 return "$flags"
4634 }
4635 global et_arm_vfp_flags
4636 return "$flags $et_arm_vfp_flags"
4637 }
4638
4639 # Return 1 if this is an ARM target supporting -mfpu=vfp3
4640 # -mfloat-abi=softfp.
4641
4642 proc check_effective_target_arm_vfp3_ok { } {
4643 if { [check_effective_target_arm32] } {
4644 return [check_no_compiler_messages arm_vfp3_ok object {
4645 int dummy;
4646 } "-mfpu=vfp3 -mfloat-abi=softfp"]
4647 } else {
4648 return 0
4649 }
4650 }
4651
4652 # Return 1 if this is an ARM target supporting -mfpu=fp-armv8
4653 # -mfloat-abi=softfp.
4654 proc check_effective_target_arm_v8_vfp_ok {} {
4655 if { [check_effective_target_arm32] } {
4656 return [check_no_compiler_messages arm_v8_vfp_ok object {
4657 int foo (void)
4658 {
4659 __asm__ volatile ("vrinta.f32.f32 s0, s0");
4660 return 0;
4661 }
4662 } "-mfpu=fp-armv8 -mfloat-abi=softfp"]
4663 } else {
4664 return 0
4665 }
4666 }
4667
4668 # Return 1 if this is an ARM target supporting -mfpu=vfp
4669 # -mfloat-abi=hard. Some multilibs may be incompatible with these
4670 # options.
4671
4672 proc check_effective_target_arm_hard_vfp_ok { } {
4673 if { [check_effective_target_arm32]
4674 && ! [check-flags [list "" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" }]] } {
4675 return [check_no_compiler_messages arm_hard_vfp_ok executable {
4676 int main() { return 0;}
4677 } "-mfpu=vfp -mfloat-abi=hard"]
4678 } else {
4679 return 0
4680 }
4681 }
4682
4683 # Return 1 if this is an ARM target defining __ARM_FP. We may need
4684 # -mfloat-abi=softfp or equivalent options. Some multilibs may be
4685 # incompatible with these options. Also set et_arm_fp_flags to the
4686 # best options to add.
4687
4688 proc check_effective_target_arm_fp_ok_nocache { } {
4689 global et_arm_fp_flags
4690 set et_arm_fp_flags ""
4691 if { [check_effective_target_arm32] } {
4692 foreach flags {"" "-mfloat-abi=softfp" "-mfloat-abi=hard"} {
4693 if { [check_no_compiler_messages_nocache arm_fp_ok object {
4694 #ifndef __ARM_FP
4695 #error __ARM_FP not defined
4696 #endif
4697 } "$flags"] } {
4698 set et_arm_fp_flags $flags
4699 return 1
4700 }
4701 }
4702 }
4703
4704 return 0
4705 }
4706
4707 proc check_effective_target_arm_fp_ok { } {
4708 return [check_cached_effective_target arm_fp_ok \
4709 check_effective_target_arm_fp_ok_nocache]
4710 }
4711
4712 # Add the options needed to define __ARM_FP. We need either
4713 # -mfloat-abi=softfp or -mfloat-abi=hard, but if one is already
4714 # specified by the multilib, use it.
4715
4716 proc add_options_for_arm_fp { flags } {
4717 if { ! [check_effective_target_arm_fp_ok] } {
4718 return "$flags"
4719 }
4720 global et_arm_fp_flags
4721 return "$flags $et_arm_fp_flags"
4722 }
4723
4724 # Return 1 if this is an ARM target defining __ARM_FP with
4725 # double-precision support. We may need -mfloat-abi=softfp or
4726 # equivalent options. Some multilibs may be incompatible with these
4727 # options. Also set et_arm_fp_dp_flags to the best options to add.
4728
4729 proc check_effective_target_arm_fp_dp_ok_nocache { } {
4730 global et_arm_fp_dp_flags
4731 set et_arm_fp_dp_flags ""
4732 if { [check_effective_target_arm32] } {
4733 foreach flags {"" "-mfloat-abi=softfp" "-mfloat-abi=hard"} {
4734 if { [check_no_compiler_messages_nocache arm_fp_dp_ok object {
4735 #ifndef __ARM_FP
4736 #error __ARM_FP not defined
4737 #endif
4738 #if ((__ARM_FP & 8) == 0)
4739 #error __ARM_FP indicates that double-precision is not supported
4740 #endif
4741 } "$flags"] } {
4742 set et_arm_fp_dp_flags $flags
4743 return 1
4744 }
4745 }
4746 }
4747
4748 return 0
4749 }
4750
4751 proc check_effective_target_arm_fp_dp_ok { } {
4752 return [check_cached_effective_target arm_fp_dp_ok \
4753 check_effective_target_arm_fp_dp_ok_nocache]
4754 }
4755
4756 # Add the options needed to define __ARM_FP with double-precision
4757 # support. We need either -mfloat-abi=softfp or -mfloat-abi=hard, but
4758 # if one is already specified by the multilib, use it.
4759
4760 proc add_options_for_arm_fp_dp { flags } {
4761 if { ! [check_effective_target_arm_fp_dp_ok] } {
4762 return "$flags"
4763 }
4764 global et_arm_fp_dp_flags
4765 return "$flags $et_arm_fp_dp_flags"
4766 }
4767
4768 # Return 1 if this is an ARM target that supports DSP multiply with
4769 # current multilib flags.
4770
4771 proc check_effective_target_arm_dsp { } {
4772 return [check_no_compiler_messages arm_dsp assembly {
4773 #ifndef __ARM_FEATURE_DSP
4774 #error not DSP
4775 #endif
4776 #include <arm_acle.h>
4777 int i;
4778 }]
4779 }
4780
4781 # Return 1 if this is an ARM target that supports unaligned word/halfword
4782 # load/store instructions.
4783
4784 proc check_effective_target_arm_unaligned { } {
4785 return [check_no_compiler_messages arm_unaligned assembly {
4786 #ifndef __ARM_FEATURE_UNALIGNED
4787 #error no unaligned support
4788 #endif
4789 int i;
4790 }]
4791 }
4792
4793 # Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8
4794 # -mfloat-abi=softfp or equivalent options. Some multilibs may be
4795 # incompatible with these options. Also set et_arm_crypto_flags to the
4796 # best options to add.
4797
4798 proc check_effective_target_arm_crypto_ok_nocache { } {
4799 global et_arm_crypto_flags
4800 set et_arm_crypto_flags ""
4801 if { [check_effective_target_arm_v8_neon_ok] } {
4802 foreach flags {"" "-mfloat-abi=softfp" "-mfpu=crypto-neon-fp-armv8" "-mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp"} {
4803 if { [check_no_compiler_messages_nocache arm_crypto_ok object {
4804 #include "arm_neon.h"
4805 uint8x16_t
4806 foo (uint8x16_t a, uint8x16_t b)
4807 {
4808 return vaeseq_u8 (a, b);
4809 }
4810 } "$flags"] } {
4811 set et_arm_crypto_flags $flags
4812 return 1
4813 }
4814 }
4815 }
4816
4817 return 0
4818 }
4819
4820 # Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8
4821
4822 proc check_effective_target_arm_crypto_ok { } {
4823 return [check_cached_effective_target arm_crypto_ok \
4824 check_effective_target_arm_crypto_ok_nocache]
4825 }
4826
4827 # Add options for crypto extensions.
4828 proc add_options_for_arm_crypto { flags } {
4829 if { ! [check_effective_target_arm_crypto_ok] } {
4830 return "$flags"
4831 }
4832 global et_arm_crypto_flags
4833 return "$flags $et_arm_crypto_flags"
4834 }
4835
4836 # Add the options needed for NEON. We need either -mfloat-abi=softfp
4837 # or -mfloat-abi=hard, but if one is already specified by the
4838 # multilib, use it. Similarly, if a -mfpu option already enables
4839 # NEON, do not add -mfpu=neon.
4840
4841 proc add_options_for_arm_neon { flags } {
4842 if { ! [check_effective_target_arm_neon_ok] } {
4843 return "$flags"
4844 }
4845 global et_arm_neon_flags
4846 return "$flags $et_arm_neon_flags"
4847 }
4848
4849 proc add_options_for_arm_v8_vfp { flags } {
4850 if { ! [check_effective_target_arm_v8_vfp_ok] } {
4851 return "$flags"
4852 }
4853 return "$flags -mfpu=fp-armv8 -mfloat-abi=softfp"
4854 }
4855
4856 proc add_options_for_arm_v8_neon { flags } {
4857 if { ! [check_effective_target_arm_v8_neon_ok] } {
4858 return "$flags"
4859 }
4860 global et_arm_v8_neon_flags
4861 return "$flags $et_arm_v8_neon_flags -march=armv8-a"
4862 }
4863
4864 # Add the options needed for ARMv8.1 Adv.SIMD. Also adds the ARMv8 NEON
4865 # options for AArch64 and for ARM.
4866
4867 proc add_options_for_arm_v8_1a_neon { flags } {
4868 if { ! [check_effective_target_arm_v8_1a_neon_ok] } {
4869 return "$flags"
4870 }
4871 global et_arm_v8_1a_neon_flags
4872 return "$flags $et_arm_v8_1a_neon_flags"
4873 }
4874
4875 # Add the options needed for ARMv8.2 with the scalar FP16 extension.
4876 # Also adds the ARMv8 FP options for ARM and for AArch64.
4877
4878 proc add_options_for_arm_v8_2a_fp16_scalar { flags } {
4879 if { ! [check_effective_target_arm_v8_2a_fp16_scalar_ok] } {
4880 return "$flags"
4881 }
4882 global et_arm_v8_2a_fp16_scalar_flags
4883 return "$flags $et_arm_v8_2a_fp16_scalar_flags"
4884 }
4885
4886 # Add the options needed for ARMv8.2 with the FP16 extension. Also adds
4887 # the ARMv8 NEON options for ARM and for AArch64.
4888
4889 proc add_options_for_arm_v8_2a_fp16_neon { flags } {
4890 if { ! [check_effective_target_arm_v8_2a_fp16_neon_ok] } {
4891 return "$flags"
4892 }
4893 global et_arm_v8_2a_fp16_neon_flags
4894 return "$flags $et_arm_v8_2a_fp16_neon_flags"
4895 }
4896
4897 proc add_options_for_arm_crc { flags } {
4898 if { ! [check_effective_target_arm_crc_ok] } {
4899 return "$flags"
4900 }
4901 global et_arm_crc_flags
4902 return "$flags $et_arm_crc_flags"
4903 }
4904
4905 # Add the options needed for NEON. We need either -mfloat-abi=softfp
4906 # or -mfloat-abi=hard, but if one is already specified by the
4907 # multilib, use it. Similarly, if a -mfpu option already enables
4908 # NEON, do not add -mfpu=neon.
4909
4910 proc add_options_for_arm_neonv2 { flags } {
4911 if { ! [check_effective_target_arm_neonv2_ok] } {
4912 return "$flags"
4913 }
4914 global et_arm_neonv2_flags
4915 return "$flags $et_arm_neonv2_flags"
4916 }
4917
4918 # Add the options needed for vfp3.
4919 proc add_options_for_arm_vfp3 { flags } {
4920 if { ! [check_effective_target_arm_vfp3_ok] } {
4921 return "$flags"
4922 }
4923 return "$flags -mfpu=vfp3 -mfloat-abi=softfp"
4924 }
4925
4926 # Return 1 if this is an ARM target supporting -mfpu=neon
4927 # -mfloat-abi=softfp or equivalent options. Some multilibs may be
4928 # incompatible with these options. Also set et_arm_neon_flags to the
4929 # best options to add.
4930
4931 proc check_effective_target_arm_neon_ok_nocache { } {
4932 global et_arm_neon_flags
4933 set et_arm_neon_flags ""
4934 if { [check_effective_target_arm32] } {
4935 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"} {
4936 if { [check_no_compiler_messages_nocache arm_neon_ok object {
4937 #include <arm_neon.h>
4938 int dummy;
4939 #ifndef __ARM_NEON__
4940 #error not NEON
4941 #endif
4942 /* Avoid the case where a test adds -mfpu=neon, but the toolchain is
4943 configured for -mcpu=arm926ej-s, for example. */
4944 #if __ARM_ARCH < 7 || __ARM_ARCH_PROFILE == 'M'
4945 #error Architecture does not support NEON.
4946 #endif
4947 } "$flags"] } {
4948 set et_arm_neon_flags $flags
4949 return 1
4950 }
4951 }
4952 }
4953
4954 return 0
4955 }
4956
4957 proc check_effective_target_arm_neon_ok { } {
4958 return [check_cached_effective_target arm_neon_ok \
4959 check_effective_target_arm_neon_ok_nocache]
4960 }
4961
4962
4963 # Return 1 if this is an ARM target supporting the SIMD32 intrinsics
4964 # from arm_acle.h. Some multilibs may be incompatible with these options.
4965 # Also set et_arm_simd32_flags to the best options to add.
4966 # arm_acle.h includes stdint.h which can cause trouble with incompatible
4967 # -mfloat-abi= options.
4968
4969 proc check_effective_target_arm_simd32_ok_nocache { } {
4970 global et_arm_simd32_flags
4971 set et_arm_simd32_flags ""
4972 foreach flags {"" "-march=armv6" "-march=armv6 -mfloat-abi=softfp" "-march=armv6 -mfloat-abi=hard"} {
4973 if { [check_no_compiler_messages_nocache arm_simd32_ok object {
4974 #include <arm_acle.h>
4975 int dummy;
4976 #ifndef __ARM_FEATURE_SIMD32
4977 #error not SIMD32
4978 #endif
4979 } "$flags"] } {
4980 set et_arm_simd32_flags $flags
4981 return 1
4982 }
4983 }
4984
4985 return 0
4986 }
4987
4988 proc check_effective_target_arm_simd32_ok { } {
4989 return [check_cached_effective_target arm_simd32_ok \
4990 check_effective_target_arm_simd32_ok_nocache]
4991 }
4992
4993 proc add_options_for_arm_simd32 { flags } {
4994 if { ! [check_effective_target_arm_simd32_ok] } {
4995 return "$flags"
4996 }
4997 global et_arm_simd32_flags
4998 return "$flags $et_arm_simd32_flags"
4999 }
5000
5001 # Return 1 if this is an ARM target supporting the __ssat and __usat
5002 # saturation intrinsics from arm_acle.h. Some multilibs may be
5003 # incompatible with these options. Also set et_arm_sat_flags to the
5004 # best options to add. arm_acle.h includes stdint.h which can cause
5005 # trouble with incompatible -mfloat-abi= options.
5006
5007 proc check_effective_target_arm_sat_ok_nocache { } {
5008 global et_arm_sat_flags
5009 set et_arm_sat_flags ""
5010 foreach flags {"" "-march=armv6" "-march=armv6 -mfloat-abi=softfp" "-march=armv6 -mfloat-abi=hard -mfpu=vfp"} {
5011 if { [check_no_compiler_messages_nocache et_arm_sat_flags object {
5012 #include <arm_acle.h>
5013 int dummy;
5014 #ifndef __ARM_FEATURE_SAT
5015 #error not SAT
5016 #endif
5017 } "$flags"] } {
5018 set et_arm_sat_flags $flags
5019 return 1
5020 }
5021 }
5022
5023 return 0
5024 }
5025
5026 proc check_effective_target_arm_sat_ok { } {
5027 return [check_cached_effective_target et_arm_sat_flags \
5028 check_effective_target_arm_sat_ok_nocache]
5029 }
5030
5031 proc add_options_for_arm_sat { flags } {
5032 if { ! [check_effective_target_arm_sat_ok] } {
5033 return "$flags"
5034 }
5035 global et_arm_sat_flags
5036 return "$flags $et_arm_sat_flags"
5037 }
5038
5039 # Return 1 if this is an ARM target supporting the DSP intrinsics from
5040 # arm_acle.h. Some multilibs may be incompatible with these options.
5041 # Also set et_arm_dsp_flags to the best options to add.
5042 # arm_acle.h includes stdint.h which can cause trouble with incompatible
5043 # -mfloat-abi= options.
5044 # check_effective_target_arm_dsp also exists, which checks the current
5045 # multilib, without trying other options.
5046
5047 proc check_effective_target_arm_dsp_ok_nocache { } {
5048 global et_arm_dsp_flags
5049 set et_arm_dsp_flags ""
5050 foreach flags {"" "-march=armv5te" "-march=armv5te -mfloat-abi=softfp" "-march=armv5te -mfloat-abi=hard"} {
5051 if { [check_no_compiler_messages_nocache et_arm_dsp_ok object {
5052 #include <arm_acle.h>
5053 int dummy;
5054 #ifndef __ARM_FEATURE_DSP
5055 #error not DSP
5056 #endif
5057 } "$flags"] } {
5058 set et_arm_dsp_flags $flags
5059 return 1
5060 }
5061 }
5062
5063 return 0
5064 }
5065
5066 proc check_effective_target_arm_dsp_ok { } {
5067 return [check_cached_effective_target et_arm_dsp_flags \
5068 check_effective_target_arm_dsp_ok_nocache]
5069 }
5070
5071 proc add_options_for_arm_dsp { flags } {
5072 if { ! [check_effective_target_arm_dsp_ok] } {
5073 return "$flags"
5074 }
5075 global et_arm_dsp_flags
5076 return "$flags $et_arm_dsp_flags"
5077 }
5078
5079 # Return 1 if this is an ARM target supporting -mfpu=neon without any
5080 # -mfloat-abi= option. Useful in tests where add_options is not
5081 # supported (such as lto tests).
5082
5083 proc check_effective_target_arm_neon_ok_no_float_abi_nocache { } {
5084 if { [check_effective_target_arm32] } {
5085 foreach flags {"-mfpu=neon"} {
5086 if { [check_no_compiler_messages_nocache arm_neon_ok_no_float_abi object {
5087 #include <arm_neon.h>
5088 int dummy;
5089 #ifndef __ARM_NEON__
5090 #error not NEON
5091 #endif
5092 /* Avoid the case where a test adds -mfpu=neon, but the toolchain is
5093 configured for -mcpu=arm926ej-s, for example. */
5094 #if __ARM_ARCH < 7 || __ARM_ARCH_PROFILE == 'M'
5095 #error Architecture does not support NEON.
5096 #endif
5097 } "$flags"] } {
5098 return 1
5099 }
5100 }
5101 }
5102
5103 return 0
5104 }
5105
5106 proc check_effective_target_arm_neon_ok_no_float_abi { } {
5107 return [check_cached_effective_target arm_neon_ok_no_float_abi \
5108 check_effective_target_arm_neon_ok_no_float_abi_nocache]
5109 }
5110
5111 proc check_effective_target_arm_crc_ok_nocache { } {
5112 global et_arm_crc_flags
5113 set et_arm_crc_flags "-march=armv8-a+crc"
5114 return [check_no_compiler_messages_nocache arm_crc_ok object {
5115 #if !defined (__ARM_FEATURE_CRC32)
5116 #error FOO
5117 #endif
5118 #include <arm_acle.h>
5119 } "$et_arm_crc_flags"]
5120 }
5121
5122 proc check_effective_target_arm_crc_ok { } {
5123 return [check_cached_effective_target arm_crc_ok \
5124 check_effective_target_arm_crc_ok_nocache]
5125 }
5126
5127 # Return 1 if this is an ARM target supporting -mfpu=neon-fp16
5128 # -mfloat-abi=softfp or equivalent options. Some multilibs may be
5129 # incompatible with these options. Also set et_arm_neon_fp16_flags to
5130 # the best options to add.
5131
5132 proc check_effective_target_arm_neon_fp16_ok_nocache { } {
5133 global et_arm_neon_fp16_flags
5134 global et_arm_neon_flags
5135 set et_arm_neon_fp16_flags ""
5136 if { [check_effective_target_arm32]
5137 && [check_effective_target_arm_neon_ok] } {
5138 foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16"
5139 "-mfpu=neon-fp16 -mfloat-abi=softfp"
5140 "-mfp16-format=ieee"
5141 "-mfloat-abi=softfp -mfp16-format=ieee"
5142 "-mfpu=neon-fp16 -mfp16-format=ieee"
5143 "-mfpu=neon-fp16 -mfloat-abi=softfp -mfp16-format=ieee"} {
5144 if { [check_no_compiler_messages_nocache arm_neon_fp16_ok object {
5145 #include "arm_neon.h"
5146 float16x4_t
5147 foo (float32x4_t arg)
5148 {
5149 return vcvt_f16_f32 (arg);
5150 }
5151 } "$et_arm_neon_flags $flags"] } {
5152 set et_arm_neon_fp16_flags [concat $et_arm_neon_flags $flags]
5153 return 1
5154 }
5155 }
5156 }
5157
5158 return 0
5159 }
5160
5161 proc check_effective_target_arm_neon_fp16_ok { } {
5162 return [check_cached_effective_target arm_neon_fp16_ok \
5163 check_effective_target_arm_neon_fp16_ok_nocache]
5164 }
5165
5166 # Return 1 if this is an ARM target supporting -mfpu=neon-fp16
5167 # and -mfloat-abi=softfp together. Some multilibs may be
5168 # incompatible with these options. Also set et_arm_neon_softfp_fp16_flags to
5169 # the best options to add.
5170
5171 proc check_effective_target_arm_neon_softfp_fp16_ok_nocache { } {
5172 global et_arm_neon_softfp_fp16_flags
5173 global et_arm_neon_flags
5174 set et_arm_neon_softfp_fp16_flags ""
5175 if { [check_effective_target_arm32]
5176 && [check_effective_target_arm_neon_ok] } {
5177 foreach flags {"-mfpu=neon-fp16 -mfloat-abi=softfp"
5178 "-mfpu=neon-fp16 -mfloat-abi=softfp -mfp16-format=ieee"} {
5179 if { [check_no_compiler_messages_nocache arm_neon_softfp_fp16_ok object {
5180 #include "arm_neon.h"
5181 float16x4_t
5182 foo (float32x4_t arg)
5183 {
5184 return vcvt_f16_f32 (arg);
5185 }
5186 } "$et_arm_neon_flags $flags"] } {
5187 set et_arm_neon_softfp_fp16_flags [concat $et_arm_neon_flags $flags]
5188 return 1
5189 }
5190 }
5191 }
5192
5193 return 0
5194 }
5195
5196 proc check_effective_target_arm_neon_softfp_fp16_ok { } {
5197 return [check_cached_effective_target arm_neon_softfp_fp16_ok \
5198 check_effective_target_arm_neon_softfp_fp16_ok_nocache]
5199 }
5200
5201
5202
5203 proc check_effective_target_arm_neon_fp16_hw { } {
5204 if {! [check_effective_target_arm_neon_fp16_ok] } {
5205 return 0
5206 }
5207 global et_arm_neon_fp16_flags
5208 check_runtime arm_neon_fp16_hw {
5209 int
5210 main (int argc, char **argv)
5211 {
5212 asm ("vcvt.f32.f16 q1, d0");
5213 return 0;
5214 }
5215 } $et_arm_neon_fp16_flags
5216 }
5217
5218 proc add_options_for_arm_neon_fp16 { flags } {
5219 if { ! [check_effective_target_arm_neon_fp16_ok] } {
5220 return "$flags"
5221 }
5222 global et_arm_neon_fp16_flags
5223 return "$flags $et_arm_neon_fp16_flags"
5224 }
5225
5226 proc add_options_for_arm_neon_softfp_fp16 { flags } {
5227 if { ! [check_effective_target_arm_neon_softfp_fp16_ok] } {
5228 return "$flags"
5229 }
5230 global et_arm_neon_softfp_fp16_flags
5231 return "$flags $et_arm_neon_softfp_fp16_flags"
5232 }
5233
5234 proc add_options_for_aarch64_sve { flags } {
5235 if { ![istarget aarch64*-*-*] || [check_effective_target_aarch64_sve] } {
5236 return "$flags"
5237 }
5238 return "$flags -march=armv8.2-a+sve"
5239 }
5240
5241 # Return 1 if this is an ARM target supporting the FP16 alternative
5242 # format. Some multilibs may be incompatible with the options needed. Also
5243 # set et_arm_neon_fp16_flags to the best options to add.
5244
5245 proc check_effective_target_arm_fp16_alternative_ok_nocache { } {
5246 if { [istarget *-*-vxworks7*] } {
5247 # Not supported by the target system.
5248 return 0
5249 }
5250 global et_arm_neon_fp16_flags
5251 set et_arm_neon_fp16_flags ""
5252 if { [check_effective_target_arm32] } {
5253 foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16"
5254 "-mfpu=neon-fp16 -mfloat-abi=softfp"} {
5255 if { [check_no_compiler_messages_nocache \
5256 arm_fp16_alternative_ok object {
5257 #if !defined (__ARM_FP16_FORMAT_ALTERNATIVE)
5258 #error __ARM_FP16_FORMAT_ALTERNATIVE not defined
5259 #endif
5260 } "$flags -mfp16-format=alternative"] } {
5261 set et_arm_neon_fp16_flags "$flags -mfp16-format=alternative"
5262 return 1
5263 }
5264 }
5265 }
5266
5267 return 0
5268 }
5269
5270 proc check_effective_target_arm_fp16_alternative_ok { } {
5271 return [check_cached_effective_target arm_fp16_alternative_ok \
5272 check_effective_target_arm_fp16_alternative_ok_nocache]
5273 }
5274
5275 # Return 1 if this is an ARM target supports specifying the FP16 none
5276 # format. Some multilibs may be incompatible with the options needed.
5277
5278 proc check_effective_target_arm_fp16_none_ok_nocache { } {
5279 if { [check_effective_target_arm32] } {
5280 foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16"
5281 "-mfpu=neon-fp16 -mfloat-abi=softfp"} {
5282 if { [check_no_compiler_messages_nocache \
5283 arm_fp16_none_ok object {
5284 #if defined (__ARM_FP16_FORMAT_ALTERNATIVE)
5285 #error __ARM_FP16_FORMAT_ALTERNATIVE defined
5286 #endif
5287 #if defined (__ARM_FP16_FORMAT_IEEE)
5288 #error __ARM_FP16_FORMAT_IEEE defined
5289 #endif
5290 } "$flags -mfp16-format=none"] } {
5291 return 1
5292 }
5293 }
5294 }
5295
5296 return 0
5297 }
5298
5299 proc check_effective_target_arm_fp16_none_ok { } {
5300 return [check_cached_effective_target arm_fp16_none_ok \
5301 check_effective_target_arm_fp16_none_ok_nocache]
5302 }
5303
5304 # Return 1 if this is an ARM target supporting -mfpu=neon-fp-armv8
5305 # -mfloat-abi=softfp or equivalent options. Some multilibs may be
5306 # incompatible with these options. Also set et_arm_v8_neon_flags to the
5307 # best options to add.
5308
5309 proc check_effective_target_arm_v8_neon_ok_nocache { } {
5310 global et_arm_v8_neon_flags
5311 set et_arm_v8_neon_flags ""
5312 if { [check_effective_target_arm32] } {
5313 foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp-armv8" "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} {
5314 if { [check_no_compiler_messages_nocache arm_v8_neon_ok object {
5315 #if __ARM_ARCH < 8
5316 #error not armv8 or later
5317 #endif
5318 #include "arm_neon.h"
5319 void
5320 foo ()
5321 {
5322 __asm__ volatile ("vrintn.f32 q0, q0");
5323 }
5324 } "$flags -march=armv8-a"] } {
5325 set et_arm_v8_neon_flags $flags
5326 return 1
5327 }
5328 }
5329 }
5330
5331 return 0
5332 }
5333
5334 proc check_effective_target_arm_v8_neon_ok { } {
5335 return [check_cached_effective_target arm_v8_neon_ok \
5336 check_effective_target_arm_v8_neon_ok_nocache]
5337 }
5338
5339 # Return 1 if this is an ARM target supporting -mfpu=neon-vfpv4
5340 # -mfloat-abi=softfp or equivalent options. Some multilibs may be
5341 # incompatible with these options. Also set et_arm_neonv2_flags to the
5342 # best options to add.
5343
5344 proc check_effective_target_arm_neonv2_ok_nocache { } {
5345 global et_arm_neonv2_flags
5346 global et_arm_neon_flags
5347 set et_arm_neonv2_flags ""
5348 if { [check_effective_target_arm32]
5349 && [check_effective_target_arm_neon_ok] } {
5350 foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-vfpv4" "-mfpu=neon-vfpv4 -mfloat-abi=softfp"} {
5351 if { [check_no_compiler_messages_nocache arm_neonv2_ok object {
5352 #include "arm_neon.h"
5353 float32x2_t
5354 foo (float32x2_t a, float32x2_t b, float32x2_t c)
5355 {
5356 return vfma_f32 (a, b, c);
5357 }
5358 } "$et_arm_neon_flags $flags"] } {
5359 set et_arm_neonv2_flags [concat $et_arm_neon_flags $flags]
5360 return 1
5361 }
5362 }
5363 }
5364
5365 return 0
5366 }
5367
5368 proc check_effective_target_arm_neonv2_ok { } {
5369 return [check_cached_effective_target arm_neonv2_ok \
5370 check_effective_target_arm_neonv2_ok_nocache]
5371 }
5372
5373 # Add the options needed for VFP FP16 support. We need either
5374 # -mfloat-abi=softfp or -mfloat-abi=hard. If one is already specified by
5375 # the multilib, use it.
5376
5377 proc add_options_for_arm_fp16 { flags } {
5378 if { ! [check_effective_target_arm_fp16_ok] } {
5379 return "$flags"
5380 }
5381 global et_arm_fp16_flags
5382 return "$flags $et_arm_fp16_flags"
5383 }
5384
5385 # Add the options needed to enable support for IEEE format
5386 # half-precision support. This is valid for ARM targets.
5387
5388 proc add_options_for_arm_fp16_ieee { flags } {
5389 if { ! [check_effective_target_arm_fp16_ok] } {
5390 return "$flags"
5391 }
5392 global et_arm_fp16_flags
5393 return "$flags $et_arm_fp16_flags -mfp16-format=ieee"
5394 }
5395
5396 # Add the options needed to enable support for ARM Alternative format
5397 # half-precision support. This is valid for ARM targets.
5398
5399 proc add_options_for_arm_fp16_alternative { flags } {
5400 if { ! [check_effective_target_arm_fp16_ok] } {
5401 return "$flags"
5402 }
5403 global et_arm_fp16_flags
5404 return "$flags $et_arm_fp16_flags -mfp16-format=alternative"
5405 }
5406
5407 # Return 1 if this is an ARM target that can support a VFP fp16 variant.
5408 # Skip multilibs that are incompatible with these options and set
5409 # et_arm_fp16_flags to the best options to add. This test is valid for
5410 # ARM only.
5411
5412 proc check_effective_target_arm_fp16_ok_nocache { } {
5413 global et_arm_fp16_flags
5414 set et_arm_fp16_flags ""
5415 if { ! [check_effective_target_arm32] } {
5416 return 0;
5417 }
5418 if [check-flags \
5419 [list "" { *-*-* } { "-mfpu=*" } \
5420 { "-mfpu=*fp16*" "-mfpu=*fpv[4-9]*" \
5421 "-mfpu=*fpv[1-9][0-9]*" "-mfpu=*fp-armv8*" } ]] {
5422 # Multilib flags would override -mfpu.
5423 return 0
5424 }
5425 if [check-flags [list "" { *-*-* } { "-mfloat-abi=soft" } { "" } ]] {
5426 # Must generate floating-point instructions.
5427 return 0
5428 }
5429 if [check_effective_target_arm_hf_eabi] {
5430 # Use existing float-abi and force an fpu which supports fp16
5431 set et_arm_fp16_flags "-mfpu=vfpv4"
5432 return 1;
5433 }
5434 if [check-flags [list "" { *-*-* } { "-mfpu=*" } { "" } ]] {
5435 # The existing -mfpu value is OK; use it, but add softfp.
5436 set et_arm_fp16_flags "-mfloat-abi=softfp"
5437 return 1;
5438 }
5439 # Add -mfpu for a VFP fp16 variant since there is no preprocessor
5440 # macro to check for this support.
5441 set flags "-mfpu=vfpv4 -mfloat-abi=softfp"
5442 if { [check_no_compiler_messages_nocache arm_fp16_ok assembly {
5443 int dummy;
5444 } "$flags"] } {
5445 set et_arm_fp16_flags "$flags"
5446 return 1
5447 }
5448
5449 return 0
5450 }
5451
5452 proc check_effective_target_arm_fp16_ok { } {
5453 return [check_cached_effective_target arm_fp16_ok \
5454 check_effective_target_arm_fp16_ok_nocache]
5455 }
5456
5457 # Return 1 if the target supports executing VFP FP16 instructions, 0
5458 # otherwise. This test is valid for ARM only.
5459
5460 proc check_effective_target_arm_fp16_hw { } {
5461 if {! [check_effective_target_arm_fp16_ok] } {
5462 return 0
5463 }
5464 global et_arm_fp16_flags
5465 check_runtime arm_fp16_hw {
5466 int
5467 main (int argc, char **argv)
5468 {
5469 __fp16 a = 1.0;
5470 float r;
5471 asm ("vcvtb.f32.f16 %0, %1"
5472 : "=w" (r) : "w" (a)
5473 : /* No clobbers. */);
5474 return (r == 1.0) ? 0 : 1;
5475 }
5476 } "$et_arm_fp16_flags -mfp16-format=ieee"
5477 }
5478
5479 # Creates a series of routines that return 1 if the given architecture
5480 # can be selected and a routine to give the flags to select that architecture
5481 # Note: Extra flags may be added to disable options from newer compilers
5482 # (Thumb in particular - but others may be added in the future).
5483 # Warning: Do not use check_effective_target_arm_arch_*_ok for architecture
5484 # extension (eg. ARMv8.1-A) since there is no macro defined for them. See
5485 # how only __ARM_ARCH_8A__ is checked for ARMv8.1-A.
5486 # Usage: /* { dg-require-effective-target arm_arch_v5_ok } */
5487 # /* { dg-add-options arm_arch_v5t } */
5488 # /* { dg-require-effective-target arm_arch_v5t_multilib } */
5489 foreach { armfunc armflag armdefs } {
5490 v4 "-march=armv4 -marm" __ARM_ARCH_4__
5491 v4t "-march=armv4t -mfloat-abi=softfp" __ARM_ARCH_4T__
5492 v4t_arm "-march=armv4t -marm" "__ARM_ARCH_4T__ && !__thumb__"
5493 v4t_thumb "-march=armv4t -mthumb -mfloat-abi=softfp" "__ARM_ARCH_4T__ && __thumb__"
5494 v5t "-march=armv5t -mfloat-abi=softfp" __ARM_ARCH_5T__
5495 v5t_arm "-march=armv5t -marm" "__ARM_ARCH_5T__ && !__thumb__"
5496 v5t_thumb "-march=armv5t -mthumb -mfloat-abi=softfp" "__ARM_ARCH_5T__ && __thumb__"
5497 v5te "-march=armv5te+fp -mfloat-abi=softfp" __ARM_ARCH_5TE__
5498 v5te_arm "-march=armv5te+fp -marm" "__ARM_ARCH_5TE__ && !__thumb__"
5499 v5te_thumb "-march=armv5te+fp -mthumb -mfloat-abi=softfp" "__ARM_ARCH_5TE__ && __thumb__"
5500 xscale_arm "-mcpu=xscale -mfloat-abi=soft -marm" "__XSCALE__ && !__thumb__"
5501 v6 "-march=armv6+fp -mfloat-abi=softfp" __ARM_ARCH_6__
5502 v6_arm "-march=armv6+fp -marm" "__ARM_ARCH_6__ && !__thumb__"
5503 v6_thumb "-march=armv6+fp -mthumb -mfloat-abi=softfp" "__ARM_ARCH_6__ && __thumb__"
5504 v6k "-march=armv6k+fp -mfloat-abi=softfp" __ARM_ARCH_6K__
5505 v6k_arm "-march=armv6k+fp -marm" "__ARM_ARCH_6K__ && !__thumb__"
5506 v6k_thumb "-march=armv6k+fp -mthumb -mfloat-abi=softfp" "__ARM_ARCH_6K__ && __thumb__"
5507 v6t2 "-march=armv6t2+fp" __ARM_ARCH_6T2__
5508 v6z "-march=armv6z+fp -mfloat-abi=softfp" __ARM_ARCH_6Z__
5509 v6z_arm "-march=armv6z+fp -marm" "__ARM_ARCH_6Z__ && !__thumb__"
5510 v6z_thumb "-march=armv6z+fp -mthumb -mfloat-abi=softfp" "__ARM_ARCH_6Z__ && __thumb__"
5511 v6m "-march=armv6-m -mthumb -mfloat-abi=soft" __ARM_ARCH_6M__
5512 v7a "-march=armv7-a+fp" __ARM_ARCH_7A__
5513 v7a_arm "-march=armv7-a+fp -marm" "__ARM_ARCH_7A__ && !__thumb__"
5514 v7a_neon "-march=armv7-a+simd -mfpu=auto -mfloat-abi=softfp" "__ARM_ARCH_7A__ && __ARM_NEON__"
5515 v7r "-march=armv7-r+fp" __ARM_ARCH_7R__
5516 v7m "-march=armv7-m -mthumb -mfloat-abi=soft" __ARM_ARCH_7M__
5517 v7em "-march=armv7e-m+fp -mthumb" __ARM_ARCH_7EM__
5518 v7ve "-march=armv7ve+fp -marm"
5519 "__ARM_ARCH_7A__ && __ARM_FEATURE_IDIV"
5520 v8a "-march=armv8-a+simd" __ARM_ARCH_8A__
5521 v8a_hard "-march=armv8-a+simd -mfpu=auto -mfloat-abi=hard" __ARM_ARCH_8A__
5522 v8_1a "-march=armv8.1-a+simd" __ARM_ARCH_8A__
5523 v8_2a "-march=armv8.2-a+simd" __ARM_ARCH_8A__
5524 v8r "-march=armv8-r+fp.sp" __ARM_ARCH_8R__
5525 v8m_base "-march=armv8-m.base -mthumb -mfloat-abi=soft"
5526 __ARM_ARCH_8M_BASE__
5527 v8m_main "-march=armv8-m.main+fp -mthumb" __ARM_ARCH_8M_MAIN__
5528 v8_1m_main "-march=armv8.1-m.main+fp -mthumb" __ARM_ARCH_8M_MAIN__
5529 v9a "-march=armv9-a+simd" __ARM_ARCH_9A__ } {
5530 eval [string map [list FUNC $armfunc FLAG $armflag DEFS $armdefs ] {
5531 proc check_effective_target_arm_arch_FUNC_ok { } {
5532 return [check_no_compiler_messages arm_arch_FUNC_ok assembly {
5533 #if !(DEFS)
5534 #error !(DEFS)
5535 #endif
5536 int
5537 main (void)
5538 {
5539 return 0;
5540 }
5541 } "FLAG" ]
5542 }
5543
5544 proc add_options_for_arm_arch_FUNC { flags } {
5545 return "$flags FLAG"
5546 }
5547
5548 proc check_effective_target_arm_arch_FUNC_link { } {
5549 return [check_no_compiler_messages arm_arch_FUNC_link executable {
5550 #include <stdint.h>
5551 int dummy;
5552 int main (void) { return 0; }
5553 } [add_options_for_arm_arch_FUNC ""]]
5554 }
5555
5556 proc check_effective_target_arm_arch_FUNC_multilib { } {
5557 return [check_runtime arm_arch_FUNC_multilib {
5558 int
5559 main (void)
5560 {
5561 return 0;
5562 }
5563 } [add_options_for_arm_arch_FUNC ""]]
5564 }
5565 }]
5566 }
5567
5568 # Return 1 if GCC was configured with --with-mode=
5569 proc check_effective_target_default_mode { } {
5570
5571 return [check_configured_with "with-mode="]
5572 }
5573
5574 # Return 1 if this is an ARM target where -marm causes ARM to be
5575 # used (not Thumb)
5576
5577 proc check_effective_target_arm_arm_ok { } {
5578 return [check_no_compiler_messages arm_arm_ok assembly {
5579 #if !defined (__arm__) || defined (__thumb__) || defined (__thumb2__)
5580 #error !__arm__ || __thumb__ || __thumb2__
5581 #endif
5582 } "-marm"]
5583 }
5584
5585
5586 # Return 1 is this is an ARM target where -mthumb causes Thumb-1 to be
5587 # used.
5588
5589 proc check_effective_target_arm_thumb1_ok { } {
5590 return [check_no_compiler_messages arm_thumb1_ok assembly {
5591 #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__)
5592 #error !__arm__ || !__thumb__ || __thumb2__
5593 #endif
5594 int foo (int i) { return i; }
5595 } "-mthumb"]
5596 }
5597
5598 # Return 1 is this is an ARM target where -mthumb causes Thumb-2 to be
5599 # used.
5600
5601 proc check_effective_target_arm_thumb2_ok { } {
5602 return [check_no_compiler_messages arm_thumb2_ok assembly {
5603 #if !defined(__thumb2__)
5604 #error !__thumb2__
5605 #endif
5606 int foo (int i) { return i; }
5607 } "-mthumb"]
5608 }
5609
5610 # Return 1 if this is an ARM target where Thumb-1 is used without options
5611 # added by the test.
5612
5613 proc check_effective_target_arm_thumb1 { } {
5614 return [check_no_compiler_messages arm_thumb1 assembly {
5615 #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__)
5616 #error !__arm__ || !__thumb__ || __thumb2__
5617 #endif
5618 int i;
5619 } ""]
5620 }
5621
5622 # Return 1 if this is an ARM target where Thumb-2 is used without options
5623 # added by the test.
5624
5625 proc check_effective_target_arm_thumb2 { } {
5626 return [check_no_compiler_messages arm_thumb2 assembly {
5627 #if !defined(__thumb2__)
5628 #error !__thumb2__
5629 #endif
5630 int i;
5631 } ""]
5632 }
5633
5634 # Return 1 if this is an ARM target where conditional execution is available.
5635
5636 proc check_effective_target_arm_cond_exec { } {
5637 return [check_no_compiler_messages arm_cond_exec assembly {
5638 #if defined(__arm__) && defined(__thumb__) && !defined(__thumb2__)
5639 #error FOO
5640 #endif
5641 int i;
5642 } ""]
5643 }
5644
5645 # Return 1 if this is an ARM cortex-M profile cpu
5646
5647 proc check_effective_target_arm_cortex_m { } {
5648 if { ![istarget arm*-*-*] } {
5649 return 0
5650 }
5651 return [check_no_compiler_messages arm_cortex_m assembly {
5652 #if defined(__ARM_ARCH_ISA_ARM)
5653 #error __ARM_ARCH_ISA_ARM is defined
5654 #endif
5655 int i;
5656 } "-mthumb"]
5657 }
5658
5659 # Return 1 if this is an ARM target where -mthumb causes Thumb-1 to be
5660 # used and MOVT/MOVW instructions to be available.
5661
5662 proc check_effective_target_arm_thumb1_movt_ok {} {
5663 if [check_effective_target_arm_thumb1_ok] {
5664 return [check_no_compiler_messages arm_movt object {
5665 int
5666 foo (void)
5667 {
5668 asm ("movt r0, #42");
5669 }
5670 } "-mthumb"]
5671 } else {
5672 return 0
5673 }
5674 }
5675
5676 # Return 1 if this is an ARM target where -mthumb causes Thumb-1 to be
5677 # used and CBZ and CBNZ instructions are available.
5678
5679 proc check_effective_target_arm_thumb1_cbz_ok {} {
5680 if [check_effective_target_arm_thumb1_ok] {
5681 return [check_no_compiler_messages arm_cbz object {
5682 int
5683 foo (void)
5684 {
5685 asm ("cbz r0, 2f\n2:");
5686 }
5687 } "-mthumb"]
5688 } else {
5689 return 0
5690 }
5691 }
5692
5693 # Return 1 if this is an Arm target which supports the Armv6t2 extensions.
5694 # This can be either in Arm state or in Thumb state.
5695
5696 proc check_effective_target_arm_arch_v6t2_hw {} {
5697 if [check_effective_target_arm_arch_v6t2_ok] {
5698 return [check_runtime arm_arch_v6t2 {
5699 int
5700 main (void)
5701 {
5702 asm ("bfc r0, #1, #2");
5703 return 0;
5704 }
5705 } [add_options_for_arm_arch_v6t2 ""]]
5706 } else {
5707 return 0
5708 }
5709 }
5710
5711 # Return 1 if this is an ARM target where ARMv8-M Security Extensions is
5712 # available.
5713
5714 proc check_effective_target_arm_cmse_ok {} {
5715 return [check_no_compiler_messages arm_cmse object {
5716 int
5717 foo (void)
5718 {
5719 asm ("bxns r0");
5720 }
5721 } "-mcmse"];
5722 }
5723
5724 # Return 1 if the target supports executing CMSE instructions, 0
5725 # otherwise. Cache the result.
5726
5727 proc check_effective_target_arm_cmse_hw { } {
5728 return [check_runtime arm_cmse_hw_available {
5729 int main (void)
5730 {
5731 unsigned id_pfr1;
5732 asm ("ldr\t%0, =0xe000ed44\n" \
5733 "ldr\t%0, [%0]\n" \
5734 "sg" : "=l" (id_pfr1));
5735 /* Exit with code 0 iff security extension is available. */
5736 return !(id_pfr1 & 0xf0);
5737 }
5738 } "-mcmse"]
5739 }
5740
5741 # Return 1 if the target supports executing MVE instructions, 0
5742 # otherwise.
5743
5744 proc check_effective_target_arm_mve_hw {} {
5745 return [check_runtime arm_mve_hw_available {
5746 int
5747 main (void)
5748 {
5749 long long a = 16;
5750 int b = 3;
5751 asm ("sqrshrl %Q1, %R1, #64, %2"
5752 : "=l" (a)
5753 : "0" (a), "r" (b));
5754 return (a != 2);
5755 }
5756 } [add_options_for_arm_v8_1m_mve_fp ""]]
5757 }
5758
5759 # Return 1 if this is an ARM target where ARMv8-M Security Extensions with
5760 # clearing instructions (clrm, vscclrm, vstr/vldr with FPCXT) is available.
5761
5762 proc check_effective_target_arm_cmse_clear_ok {} {
5763 return [check_no_compiler_messages arm_cmse_clear object {
5764 int
5765 foo (void)
5766 {
5767 asm ("clrm {r1, r2}");
5768 }
5769 } "-mcmse"];
5770 }
5771
5772 # Return 1 if this is an ARM target supporting
5773 # -mbranch-protection=standard, 0 otherwise.
5774
5775 proc check_effective_target_mbranch_protection_ok {} {
5776
5777 return [check_no_compiler_messages mbranch_protection_ok object {
5778 int main (void) { return 0; }
5779 } "-mbranch-protection=standard"]
5780 }
5781
5782 # Return 1 if the target supports executing PACBTI instructions, 0
5783 # otherwise.
5784
5785 proc check_effective_target_arm_pacbti_hw {} {
5786 return [check_runtime arm_pacbti_hw_available {
5787 __attribute__ ((naked)) int
5788 main (void)
5789 {
5790 asm ("pac r12, lr, sp");
5791 asm ("mov r0, #0");
5792 asm ("autg r12, lr, sp");
5793 asm ("bx lr");
5794 }
5795 } "-march=armv8.1-m.main+pacbti+fp -mbranch-protection=standard -mthumb -mfloat-abi=hard"]
5796 }
5797
5798 # Return 1 if this compilation turns on string_ops_prefer_neon on.
5799
5800 proc check_effective_target_arm_tune_string_ops_prefer_neon { } {
5801 return [check_no_messages_and_pattern arm_tune_string_ops_prefer_neon "@string_ops_prefer_neon:\t1" assembly {
5802 int foo (void) { return 0; }
5803 } "-O2 -mprint-tune-info" ]
5804 }
5805
5806 # Return 1 if the target supports executing NEON instructions, 0
5807 # otherwise. Cache the result.
5808
5809 proc check_effective_target_arm_neon_hw { } {
5810 return [check_runtime arm_neon_hw_available {
5811 int
5812 main (void)
5813 {
5814 long long a = 0, b = 1;
5815 asm ("vorr %P0, %P1, %P2"
5816 : "=w" (a)
5817 : "0" (a), "w" (b));
5818 return (a != 1);
5819 }
5820 } [add_options_for_arm_neon ""]]
5821 }
5822
5823 # Return true if this is an AArch64 target that can run SVE code.
5824
5825 proc check_effective_target_aarch64_sve_hw { } {
5826 if { ![istarget aarch64*-*-*] } {
5827 return 0
5828 }
5829 return [check_runtime aarch64_sve_hw_available {
5830 int
5831 main (void)
5832 {
5833 asm volatile ("ptrue p0.b");
5834 return 0;
5835 }
5836 } [add_options_for_aarch64_sve ""]]
5837 }
5838
5839 # Return true if this is an AArch64 target that can run SVE2 code.
5840
5841 proc check_effective_target_aarch64_sve2_hw { } {
5842 if { ![istarget aarch64*-*-*] } {
5843 return 0
5844 }
5845 return [check_runtime aarch64_sve2_hw_available {
5846 int
5847 main (void)
5848 {
5849 asm volatile ("addp z0.b, p0/m, z0.b, z1.b");
5850 return 0;
5851 }
5852 }]
5853 }
5854
5855 # Return true if this is an AArch64 target that can run SVE code and
5856 # if its SVE vectors have exactly BITS bits.
5857
5858 proc aarch64_sve_hw_bits { bits } {
5859 if { ![check_effective_target_aarch64_sve_hw] } {
5860 return 0
5861 }
5862 return [check_runtime aarch64_sve${bits}_hw [subst {
5863 int
5864 main (void)
5865 {
5866 int res;
5867 asm volatile ("cntd %0" : "=r" (res));
5868 if (res * 64 != $bits)
5869 __builtin_abort ();
5870 return 0;
5871 }
5872 }] [add_options_for_aarch64_sve ""]]
5873 }
5874
5875 # Return true if this is an AArch64 target that can run SVE code and
5876 # if its SVE vectors have exactly 256 bits.
5877
5878 foreach N { 128 256 512 1024 2048 } {
5879 eval [string map [list N $N] {
5880 proc check_effective_target_aarch64_sveN_hw { } {
5881 return [aarch64_sve_hw_bits N]
5882 }
5883 }]
5884 }
5885
5886 proc check_effective_target_arm_neonv2_hw { } {
5887 return [check_runtime arm_neon_hwv2_available {
5888 #include "arm_neon.h"
5889 int
5890 main (void)
5891 {
5892 float32x2_t a, b, c;
5893 asm ("vfma.f32 %P0, %P1, %P2"
5894 : "=w" (a)
5895 : "w" (b), "w" (c));
5896 return 0;
5897 }
5898 } [add_options_for_arm_neonv2 ""]]
5899 }
5900
5901 # ID_AA64PFR1_EL1.BT using bits[3:0] == 1 implies BTI implimented.
5902 proc check_effective_target_aarch64_bti_hw { } {
5903 if { ![istarget aarch64*-*-*] } {
5904 return 0
5905 }
5906 return [check_runtime aarch64_bti_hw_available {
5907 int
5908 main (void)
5909 {
5910 int a;
5911 asm volatile ("mrs %0, id_aa64pfr1_el1" : "=r" (a));
5912 return !((a & 0xf) == 1);
5913 }
5914 } "-O2" ]
5915 }
5916
5917 # Return 1 if the target supports executing the armv8.3-a FJCVTZS
5918 # instruction.
5919 proc check_effective_target_aarch64_fjcvtzs_hw { } {
5920 if { ![istarget aarch64*-*-*] } {
5921 return 0
5922 }
5923 return [check_runtime aarch64_fjcvtzs_hw_available {
5924 int
5925 main (void)
5926 {
5927 double in = 25.1;
5928 int out;
5929 asm volatile ("fjcvtzs %w0, %d1"
5930 : "=r" (out)
5931 : "w" (in)
5932 : /* No clobbers. */);
5933 return out != 25;
5934 }
5935 } "-march=armv8.3-a" ]
5936 }
5937
5938 # Return 1 if GCC was configured with --enable-standard-branch-protection
5939 proc check_effective_target_default_branch_protection { } {
5940 return [check_configured_with "enable-standard-branch-protection"]
5941 }
5942
5943 # Return 1 if this is an ARM target supporting -mfloat-abi=softfp.
5944
5945 proc check_effective_target_arm_softfp_ok { } {
5946 return [check_no_compiler_messages arm_softfp_ok object {
5947 #include <stdint.h>
5948 int dummy;
5949 int main (void) { return 0; }
5950 } "-mfloat-abi=softfp"]
5951 }
5952
5953 # Return 1 if this is an ARM target supporting -mfloat-abi=hard.
5954
5955 proc check_effective_target_arm_hard_ok { } {
5956 return [check_no_compiler_messages arm_hard_ok object {
5957 #include <stdint.h>
5958 int dummy;
5959 int main (void) { return 0; }
5960 } "-mfloat-abi=hard"]
5961 }
5962
5963 # Return 1 if this is an ARM target supporting MVE.
5964 proc check_effective_target_arm_mve { } {
5965 if { ![istarget arm*-*-*] } {
5966 return 0
5967 }
5968 return [check_no_compiler_messages arm_mve assembly {
5969 #if !defined (__ARM_FEATURE_MVE)
5970 #error FOO
5971 #endif
5972 }]
5973 }
5974
5975 # Return 1 if the target supports ARMv8.1-M MVE with floating point
5976 # instructions, 0 otherwise. The test is valid for ARM.
5977 # Record the command line options needed.
5978
5979 proc check_effective_target_arm_v8_1m_mve_fp_ok_nocache { } {
5980 global et_arm_v8_1m_mve_fp_flags
5981 set et_arm_v8_1m_mve_fp_flags ""
5982
5983 if { ![istarget arm*-*-*] } {
5984 return 0;
5985 }
5986
5987 # Iterate through sets of options to find the compiler flags that
5988 # need to be added to the -march option.
5989 foreach flags {"" "-mfloat-abi=softfp -mfpu=auto -march=armv8.1-m.main+mve.fp" "-mfloat-abi=hard -mfpu=auto -march=armv8.1-m.main+mve.fp"} {
5990 if { [check_no_compiler_messages_nocache \
5991 arm_v8_1m_mve_fp_ok object {
5992 #include <arm_mve.h>
5993 #if !(__ARM_FEATURE_MVE & 2)
5994 #error "__ARM_FEATURE_MVE for floating point not defined"
5995 #endif
5996 #if __ARM_BIG_ENDIAN
5997 #error "MVE intrinsics are not supported in Big-Endian mode."
5998 #endif
5999 } "$flags -mthumb"] } {
6000 set et_arm_v8_1m_mve_fp_flags "$flags -mthumb --save-temps"
6001 return 1
6002 }
6003 }
6004
6005 return 0;
6006 }
6007
6008 proc check_effective_target_arm_v8_1m_mve_fp_ok { } {
6009 return [check_cached_effective_target arm_v8_1m_mve_fp_ok \
6010 check_effective_target_arm_v8_1m_mve_fp_ok_nocache]
6011 }
6012
6013 proc add_options_for_arm_v8_1m_mve_fp { flags } {
6014 if { ! [check_effective_target_arm_v8_1m_mve_fp_ok] } {
6015 return "$flags"
6016 }
6017 global et_arm_v8_1m_mve_fp_flags
6018 return "$flags $et_arm_v8_1m_mve_fp_flags"
6019 }
6020
6021 # Return 1 if the target supports the ARMv8.1 Adv.SIMD extension, 0
6022 # otherwise. The test is valid for AArch64 and ARM. Record the command
6023 # line options needed.
6024
6025 proc check_effective_target_arm_v8_1a_neon_ok_nocache { } {
6026 global et_arm_v8_1a_neon_flags
6027 set et_arm_v8_1a_neon_flags ""
6028
6029 if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
6030 return 0;
6031 }
6032
6033 # Iterate through sets of options to find the compiler flags that
6034 # need to be added to the -march option. Start with the empty set
6035 # since AArch64 only needs the -march setting.
6036 foreach flags {"" "-mfpu=neon-fp-armv8" "-mfloat-abi=softfp" \
6037 "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} {
6038 foreach arches { "-march=armv8-a+rdma" "-march=armv8.1-a" } {
6039 if { [check_no_compiler_messages_nocache arm_v8_1a_neon_ok object {
6040 #if !defined (__ARM_FEATURE_QRDMX)
6041 #error "__ARM_FEATURE_QRDMX not defined"
6042 #endif
6043 } "$flags $arches"] } {
6044 set et_arm_v8_1a_neon_flags "$flags $arches"
6045 return 1
6046 }
6047 }
6048 }
6049
6050 return 0;
6051 }
6052
6053 proc check_effective_target_arm_v8_1a_neon_ok { } {
6054 return [check_cached_effective_target arm_v8_1a_neon_ok \
6055 check_effective_target_arm_v8_1a_neon_ok_nocache]
6056 }
6057
6058 # Return 1 if the target supports ARMv8.2 scalar FP16 arithmetic
6059 # instructions, 0 otherwise. The test is valid for ARM and for AArch64.
6060 # Record the command line options needed.
6061
6062 proc check_effective_target_arm_v8_2a_fp16_scalar_ok_nocache { } {
6063 global et_arm_v8_2a_fp16_scalar_flags
6064 set et_arm_v8_2a_fp16_scalar_flags ""
6065
6066 if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
6067 return 0;
6068 }
6069
6070 # Iterate through sets of options to find the compiler flags that
6071 # need to be added to the -march option.
6072 foreach flags {"" "-mfpu=fp-armv8" "-mfloat-abi=softfp" \
6073 "-mfpu=fp-armv8 -mfloat-abi=softfp"} {
6074 if { [check_no_compiler_messages_nocache \
6075 arm_v8_2a_fp16_scalar_ok object {
6076 #if !defined (__ARM_FEATURE_FP16_SCALAR_ARITHMETIC)
6077 #error "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC not defined"
6078 #endif
6079 } "$flags -march=armv8.2-a+fp16"] } {
6080 set et_arm_v8_2a_fp16_scalar_flags "$flags -march=armv8.2-a+fp16"
6081 return 1
6082 }
6083 }
6084
6085 return 0;
6086 }
6087
6088 proc check_effective_target_arm_v8_2a_fp16_scalar_ok { } {
6089 return [check_cached_effective_target arm_v8_2a_fp16_scalar_ok \
6090 check_effective_target_arm_v8_2a_fp16_scalar_ok_nocache]
6091 }
6092
6093 # Return 1 if the target supports ARMv8.2 Adv.SIMD FP16 arithmetic
6094 # instructions, 0 otherwise. The test is valid for ARM and for AArch64.
6095 # Record the command line options needed.
6096
6097 proc check_effective_target_arm_v8_2a_fp16_neon_ok_nocache { } {
6098 global et_arm_v8_2a_fp16_neon_flags
6099 set et_arm_v8_2a_fp16_neon_flags ""
6100
6101 if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
6102 return 0;
6103 }
6104
6105 # Iterate through sets of options to find the compiler flags that
6106 # need to be added to the -march option.
6107 foreach flags {"" "-mfpu=neon-fp-armv8" "-mfloat-abi=softfp" \
6108 "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} {
6109 if { [check_no_compiler_messages_nocache \
6110 arm_v8_2a_fp16_neon_ok object {
6111 #if !defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
6112 #error "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC not defined"
6113 #endif
6114 } "$flags -march=armv8.2-a+fp16"] } {
6115 set et_arm_v8_2a_fp16_neon_flags "$flags -march=armv8.2-a+fp16"
6116 return 1
6117 }
6118 }
6119
6120 return 0;
6121 }
6122
6123 proc check_effective_target_arm_v8_2a_fp16_neon_ok { } {
6124 return [check_cached_effective_target arm_v8_2a_fp16_neon_ok \
6125 check_effective_target_arm_v8_2a_fp16_neon_ok_nocache]
6126 }
6127
6128 # Return 1 if the target supports ARMv8.2 Adv.SIMD Dot Product
6129 # instructions, 0 otherwise. The test is valid for ARM and for AArch64.
6130 # Record the command line options needed.
6131
6132 proc check_effective_target_arm_v8_2a_dotprod_neon_ok_nocache { } {
6133 global et_arm_v8_2a_dotprod_neon_flags
6134 set et_arm_v8_2a_dotprod_neon_flags ""
6135
6136 if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
6137 return 0;
6138 }
6139
6140 # Iterate through sets of options to find the compiler flags that
6141 # need to be added to the -march option.
6142 foreach flags {"" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" "-mfloat-abi=hard -mfpu=neon-fp-armv8"} {
6143 if { [check_no_compiler_messages_nocache \
6144 arm_v8_2a_dotprod_neon_ok object {
6145 #include <stdint.h>
6146 #if !defined (__ARM_FEATURE_DOTPROD)
6147 #error "__ARM_FEATURE_DOTPROD not defined"
6148 #endif
6149 } "$flags -march=armv8.2-a+dotprod"] } {
6150 set et_arm_v8_2a_dotprod_neon_flags "$flags -march=armv8.2-a+dotprod"
6151 return 1
6152 }
6153 }
6154
6155 return 0;
6156 }
6157
6158 # Return 1 if the target supports ARMv8.1-M MVE
6159 # instructions, 0 otherwise. The test is valid for ARM.
6160 # Record the command line options needed.
6161
6162 proc check_effective_target_arm_v8_1m_mve_ok_nocache { } {
6163 global et_arm_v8_1m_mve_flags
6164 set et_arm_v8_1m_mve_flags ""
6165
6166 if { ![istarget arm*-*-*] } {
6167 return 0;
6168 }
6169
6170 # Iterate through sets of options to find the compiler flags that
6171 # need to be added to the -march option.
6172 foreach flags {"" "-mfloat-abi=softfp -mfpu=auto -march=armv8.1-m.main+mve" "-mfloat-abi=hard -mfpu=auto -march=armv8.1-m.main+mve"} {
6173 if { [check_no_compiler_messages_nocache \
6174 arm_v8_1m_mve_ok object {
6175 #if !defined (__ARM_FEATURE_MVE)
6176 #error "__ARM_FEATURE_MVE not defined"
6177 #endif
6178 #if __ARM_BIG_ENDIAN
6179 #error "MVE intrinsics are not supported in Big-Endian mode."
6180 #endif
6181 #include <arm_mve.h>
6182 } "$flags -mthumb"] } {
6183 set et_arm_v8_1m_mve_flags "$flags -mthumb --save-temps"
6184 return 1
6185 }
6186 }
6187
6188 return 0;
6189 }
6190
6191 proc check_effective_target_arm_v8_1m_mve_ok { } {
6192 return [check_cached_effective_target arm_v8_1m_mve_ok \
6193 check_effective_target_arm_v8_1m_mve_ok_nocache]
6194 }
6195
6196 proc add_options_for_arm_v8_1m_mve { flags } {
6197 if { ! [check_effective_target_arm_v8_1m_mve_ok] } {
6198 return "$flags"
6199 }
6200 global et_arm_v8_1m_mve_flags
6201 return "$flags $et_arm_v8_1m_mve_flags"
6202 }
6203
6204 proc check_effective_target_arm_v8_2a_dotprod_neon_ok { } {
6205 return [check_cached_effective_target arm_v8_2a_dotprod_neon_ok \
6206 check_effective_target_arm_v8_2a_dotprod_neon_ok_nocache]
6207 }
6208
6209 proc add_options_for_arm_v8_2a_dotprod_neon { flags } {
6210 if { ! [check_effective_target_arm_v8_2a_dotprod_neon_ok] } {
6211 return "$flags"
6212 }
6213 global et_arm_v8_2a_dotprod_neon_flags
6214 return "$flags $et_arm_v8_2a_dotprod_neon_flags"
6215 }
6216
6217 # Return 1 if the target supports ARMv8.2+i8mm Adv.SIMD Dot Product
6218 # instructions, 0 otherwise. The test is valid for ARM and for AArch64.
6219 # Record the command line options needed.
6220
6221 proc check_effective_target_arm_v8_2a_i8mm_ok_nocache { } {
6222 global et_arm_v8_2a_i8mm_flags
6223 set et_arm_v8_2a_i8mm_flags ""
6224
6225 if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
6226 return 0;
6227 }
6228
6229 # Iterate through sets of options to find the compiler flags that
6230 # need to be added to the -march option.
6231 foreach flags {"" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" "-mfloat-abi=hard -mfpu=neon-fp-armv8" } {
6232 if { [check_no_compiler_messages_nocache \
6233 arm_v8_2a_i8mm_ok object {
6234 #include <arm_neon.h>
6235 #if !defined (__ARM_FEATURE_MATMUL_INT8)
6236 #error "__ARM_FEATURE_MATMUL_INT8 not defined"
6237 #endif
6238 } "$flags -march=armv8.2-a+i8mm"] } {
6239 set et_arm_v8_2a_i8mm_flags "$flags -march=armv8.2-a+i8mm"
6240 return 1
6241 }
6242 }
6243
6244 return 0;
6245 }
6246
6247 proc check_effective_target_arm_v8_2a_i8mm_ok { } {
6248 return [check_cached_effective_target arm_v8_2a_i8mm_ok \
6249 check_effective_target_arm_v8_2a_i8mm_ok_nocache]
6250 }
6251
6252 proc add_options_for_arm_v8_2a_i8mm { flags } {
6253 if { ! [check_effective_target_arm_v8_2a_i8mm_ok] } {
6254 return "$flags"
6255 }
6256 global et_arm_v8_2a_i8mm_flags
6257 return "$flags $et_arm_v8_2a_i8mm_flags"
6258 }
6259
6260 # Return 1 if the target supports FP16 VFMAL and VFMSL
6261 # instructions, 0 otherwise.
6262 # Record the command line options needed.
6263
6264 proc check_effective_target_arm_fp16fml_neon_ok_nocache { } {
6265 global et_arm_fp16fml_neon_flags
6266 set et_arm_fp16fml_neon_flags ""
6267
6268 if { ![istarget arm*-*-*] } {
6269 return 0;
6270 }
6271
6272 # Iterate through sets of options to find the compiler flags that
6273 # need to be added to the -march option.
6274 foreach flags {"" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" "-mfloat-abi=hard -mfpu=neon-fp-armv8"} {
6275 if { [check_no_compiler_messages_nocache \
6276 arm_fp16fml_neon_ok assembly {
6277 #include <arm_neon.h>
6278 float32x2_t
6279 foo (float32x2_t r, float16x4_t a, float16x4_t b)
6280 {
6281 return vfmlal_high_f16 (r, a, b);
6282 }
6283 } "$flags -march=armv8.2-a+fp16fml"] } {
6284 set et_arm_fp16fml_neon_flags "$flags -march=armv8.2-a+fp16fml"
6285 return 1
6286 }
6287 }
6288
6289 return 0;
6290 }
6291
6292 proc check_effective_target_arm_fp16fml_neon_ok { } {
6293 return [check_cached_effective_target arm_fp16fml_neon_ok \
6294 check_effective_target_arm_fp16fml_neon_ok_nocache]
6295 }
6296
6297 proc add_options_for_arm_fp16fml_neon { flags } {
6298 if { ! [check_effective_target_arm_fp16fml_neon_ok] } {
6299 return "$flags"
6300 }
6301 global et_arm_fp16fml_neon_flags
6302 return "$flags $et_arm_fp16fml_neon_flags"
6303 }
6304
6305 # Return 1 if the target supports BFloat16 SIMD instructions, 0 otherwise.
6306 # The test is valid for ARM and for AArch64.
6307
6308 proc check_effective_target_arm_v8_2a_bf16_neon_ok_nocache { } {
6309 global et_arm_v8_2a_bf16_neon_flags
6310 set et_arm_v8_2a_bf16_neon_flags ""
6311
6312 if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
6313 return 0;
6314 }
6315
6316 foreach flags {"" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" "-mfloat-abi=hard -mfpu=neon-fp-armv8" } {
6317 if { [check_no_compiler_messages_nocache arm_v8_2a_bf16_neon_ok object {
6318 #include <arm_neon.h>
6319 #if !defined (__ARM_FEATURE_BF16_VECTOR_ARITHMETIC)
6320 #error "__ARM_FEATURE_BF16_VECTOR_ARITHMETIC not defined"
6321 #endif
6322 } "$flags -march=armv8.2-a+bf16"] } {
6323 set et_arm_v8_2a_bf16_neon_flags "$flags -march=armv8.2-a+bf16"
6324 return 1
6325 }
6326 }
6327
6328 return 0;
6329 }
6330
6331 proc check_effective_target_arm_v8_2a_bf16_neon_ok { } {
6332 return [check_cached_effective_target arm_v8_2a_bf16_neon_ok \
6333 check_effective_target_arm_v8_2a_bf16_neon_ok_nocache]
6334 }
6335
6336 proc add_options_for_arm_v8_2a_bf16_neon { flags } {
6337 if { ! [check_effective_target_arm_v8_2a_bf16_neon_ok] } {
6338 return "$flags"
6339 }
6340 global et_arm_v8_2a_bf16_neon_flags
6341 return "$flags $et_arm_v8_2a_bf16_neon_flags"
6342 }
6343
6344 # A series of routines are created to 1) check if a given architecture is
6345 # effective (check_effective_target_*_ok) and then 2) give the corresponding
6346 # flags that enable the architecture (add_options_for_*).
6347 # The series includes:
6348 # arm_v8m_main_cde: Armv8-m CDE (Custom Datapath Extension).
6349 # arm_v8m_main_cde_fp: Armv8-m CDE with FP registers.
6350 # arm_v8_1m_main_cde_mve: Armv8.1-m CDE with MVE.
6351 # arm_v8_1m_main_cde_mve_fp: Armv8.1-m CDE with MVE with FP support.
6352 # Usage:
6353 # /* { dg-require-effective-target arm_v8m_main_cde_ok } */
6354 # /* { dg-add-options arm_v8m_main_cde } */
6355 # The tests are valid for Arm.
6356
6357 foreach { armfunc armflag armdef arminc } {
6358 arm_v8m_main_cde
6359 "-march=armv8-m.main+cdecp0+cdecp6 -mthumb"
6360 "defined (__ARM_FEATURE_CDE)"
6361 ""
6362 arm_v8m_main_cde_fp
6363 "-march=armv8-m.main+fp+cdecp0+cdecp6 -mthumb -mfpu=auto"
6364 "defined (__ARM_FEATURE_CDE) && defined (__ARM_FP)"
6365 ""
6366 arm_v8_1m_main_cde_mve
6367 "-march=armv8.1-m.main+mve+cdecp0+cdecp6 -mthumb -mfpu=auto"
6368 "defined (__ARM_FEATURE_CDE) && defined (__ARM_FEATURE_MVE)"
6369 "#include <arm_mve.h>"
6370 arm_v8_1m_main_cde_mve_fp
6371 "-march=armv8.1-m.main+mve.fp+cdecp0+cdecp6 -mthumb -mfpu=auto"
6372 "defined (__ARM_FEATURE_CDE) || __ARM_FEATURE_MVE == 3"
6373 "#include <arm_mve.h>"
6374 } {
6375 eval [string map [list FUNC $armfunc FLAG $armflag DEF $armdef INC $arminc ] {
6376 proc check_effective_target_FUNC_ok_nocache { } {
6377 global et_FUNC_flags
6378 set et_FUNC_flags ""
6379
6380 if { ![istarget arm*-*-*] } {
6381 return 0;
6382 }
6383
6384 if { [check_no_compiler_messages_nocache FUNC_ok assembly {
6385 #if !(DEF)
6386 #error "DEF failed"
6387 #endif
6388 #include <arm_cde.h>
6389 INC
6390 } "FLAG"] } {
6391 set et_FUNC_flags "FLAG"
6392 return 1
6393 }
6394
6395 return 0;
6396 }
6397
6398 proc check_effective_target_FUNC_ok { } {
6399 return [check_cached_effective_target FUNC_ok \
6400 check_effective_target_FUNC_ok_nocache]
6401 }
6402
6403 proc add_options_for_FUNC { flags } {
6404 if { ! [check_effective_target_FUNC_ok] } {
6405 return "$flags"
6406 }
6407 global et_FUNC_flags
6408 return "$flags $et_FUNC_flags"
6409 }
6410
6411 proc check_effective_target_FUNC_link { } {
6412 if { ! [check_effective_target_FUNC_ok] } {
6413 return 0;
6414 }
6415 return [check_no_compiler_messages FUNC_link executable {
6416 #if !(DEF)
6417 #error "DEF failed"
6418 #endif
6419 #include <arm_cde.h>
6420 INC
6421 int
6422 main (void)
6423 {
6424 return 0;
6425 }
6426 } [add_options_for_FUNC ""]]
6427 }
6428
6429 proc check_effective_target_FUNC_multilib { } {
6430 if { ! [check_effective_target_FUNC_ok] } {
6431 return 0;
6432 }
6433 return [check_runtime FUNC_multilib {
6434 #if !(DEF)
6435 #error "DEF failed"
6436 #endif
6437 #include <arm_cde.h>
6438 INC
6439 int
6440 main (void)
6441 {
6442 return 0;
6443 }
6444 } [add_options_for_FUNC ""]]
6445 }
6446 }]
6447 }
6448
6449 # Return 1 if the target supports executing ARMv8 NEON instructions, 0
6450 # otherwise.
6451
6452 proc check_effective_target_arm_v8_neon_hw { } {
6453 return [check_runtime arm_v8_neon_hw_available {
6454 #include "arm_neon.h"
6455 int
6456 main (void)
6457 {
6458 float32x2_t a = { 1.0f, 2.0f };
6459 #ifdef __ARM_ARCH_ISA_A64
6460 asm ("frinta %0.2s, %1.2s"
6461 : "=w" (a)
6462 : "w" (a));
6463 #else
6464 asm ("vrinta.f32 %P0, %P1"
6465 : "=w" (a)
6466 : "0" (a));
6467 #endif
6468 return a[0] == 2.0f;
6469 }
6470 } [add_options_for_arm_v8_neon ""]]
6471 }
6472
6473 # Return 1 if the target supports executing the ARMv8.1 Adv.SIMD extension, 0
6474 # otherwise. The test is valid for AArch64 and ARM.
6475
6476 proc check_effective_target_arm_v8_1a_neon_hw { } {
6477 if { ![check_effective_target_arm_v8_1a_neon_ok] } {
6478 return 0;
6479 }
6480 return [check_runtime arm_v8_1a_neon_hw_available {
6481 int
6482 main (void)
6483 {
6484 #ifdef __ARM_ARCH_ISA_A64
6485 __Int32x2_t a = {0, 1};
6486 __Int32x2_t b = {0, 2};
6487 __Int32x2_t result;
6488
6489 asm ("sqrdmlah %0.2s, %1.2s, %2.2s"
6490 : "=w"(result)
6491 : "w"(a), "w"(b)
6492 : /* No clobbers. */);
6493
6494 #else
6495
6496 __simd64_int32_t a = {0, 1};
6497 __simd64_int32_t b = {0, 2};
6498 __simd64_int32_t result;
6499
6500 asm ("vqrdmlah.s32 %P0, %P1, %P2"
6501 : "=w"(result)
6502 : "w"(a), "w"(b)
6503 : /* No clobbers. */);
6504 #endif
6505
6506 return result[0];
6507 }
6508 } [add_options_for_arm_v8_1a_neon ""]]
6509 }
6510
6511 # Return 1 if the target supports executing floating point instructions from
6512 # ARMv8.2 with the FP16 extension, 0 otherwise. The test is valid for ARM and
6513 # for AArch64.
6514
6515 proc check_effective_target_arm_v8_2a_fp16_scalar_hw { } {
6516 if { ![check_effective_target_arm_v8_2a_fp16_scalar_ok] } {
6517 return 0;
6518 }
6519 return [check_runtime arm_v8_2a_fp16_scalar_hw_available {
6520 int
6521 main (void)
6522 {
6523 __fp16 a = 1.0;
6524 __fp16 result;
6525
6526 #ifdef __ARM_ARCH_ISA_A64
6527
6528 asm ("fabs %h0, %h1"
6529 : "=w"(result)
6530 : "w"(a)
6531 : /* No clobbers. */);
6532
6533 #else
6534
6535 asm ("vabs.f16 %0, %1"
6536 : "=w"(result)
6537 : "w"(a)
6538 : /* No clobbers. */);
6539
6540 #endif
6541
6542 return (result == 1.0) ? 0 : 1;
6543 }
6544 } [add_options_for_arm_v8_2a_fp16_scalar ""]]
6545 }
6546
6547 # Return 1 if the target supports executing Adv.SIMD instructions from ARMv8.2
6548 # with the FP16 extension, 0 otherwise. The test is valid for ARM and for
6549 # AArch64.
6550
6551 proc check_effective_target_arm_v8_2a_fp16_neon_hw { } {
6552 if { ![check_effective_target_arm_v8_2a_fp16_neon_ok] } {
6553 return 0;
6554 }
6555 return [check_runtime arm_v8_2a_fp16_neon_hw_available {
6556 int
6557 main (void)
6558 {
6559 #ifdef __ARM_ARCH_ISA_A64
6560
6561 __Float16x4_t a = {1.0, -1.0, 1.0, -1.0};
6562 __Float16x4_t result;
6563
6564 asm ("fabs %0.4h, %1.4h"
6565 : "=w"(result)
6566 : "w"(a)
6567 : /* No clobbers. */);
6568
6569 #else
6570
6571 __simd64_float16_t a = {1.0, -1.0, 1.0, -1.0};
6572 __simd64_float16_t result;
6573
6574 asm ("vabs.f16 %P0, %P1"
6575 : "=w"(result)
6576 : "w"(a)
6577 : /* No clobbers. */);
6578
6579 #endif
6580
6581 return (result[0] == 1.0) ? 0 : 1;
6582 }
6583 } [add_options_for_arm_v8_2a_fp16_neon ""]]
6584 }
6585
6586 # Return 1 if the target supports executing AdvSIMD instructions from ARMv8.2
6587 # with the Dot Product extension, 0 otherwise. The test is valid for ARM and for
6588 # AArch64.
6589
6590 proc check_effective_target_arm_v8_2a_dotprod_neon_hw { } {
6591 if { ![check_effective_target_arm_v8_2a_dotprod_neon_ok] } {
6592 return 0;
6593 }
6594 return [check_runtime arm_v8_2a_dotprod_neon_hw_available {
6595 #include "arm_neon.h"
6596 int
6597 main (void)
6598 {
6599
6600 uint32x2_t results = {0,0};
6601 uint8x8_t a = {1,1,1,1,2,2,2,2};
6602 uint8x8_t b = {2,2,2,2,3,3,3,3};
6603
6604 #ifdef __ARM_ARCH_ISA_A64
6605 asm ("udot %0.2s, %1.8b, %2.8b"
6606 : "=w"(results)
6607 : "w"(a), "w"(b)
6608 : /* No clobbers. */);
6609
6610 #else
6611 asm ("vudot.u8 %P0, %P1, %P2"
6612 : "=w"(results)
6613 : "w"(a), "w"(b)
6614 : /* No clobbers. */);
6615 #endif
6616
6617 return (results[0] == 8 && results[1] == 24) ? 1 : 0;
6618 }
6619 } [add_options_for_arm_v8_2a_dotprod_neon ""]]
6620 }
6621
6622 # Return 1 if the target supports executing AdvSIMD instructions from ARMv8.2
6623 # with the i8mm extension, 0 otherwise. The test is valid for ARM and for
6624 # AArch64.
6625
6626 proc check_effective_target_arm_v8_2a_i8mm_neon_hw { } {
6627 if { ![check_effective_target_arm_v8_2a_i8mm_ok] } {
6628 return 0;
6629 }
6630 return [check_runtime arm_v8_2a_i8mm_neon_hw_available {
6631 #include "arm_neon.h"
6632 int
6633 main (void)
6634 {
6635
6636 uint32x2_t results = {0,0};
6637 uint8x8_t a = {1,1,1,1,2,2,2,2};
6638 int8x8_t b = {2,2,2,2,3,3,3,3};
6639
6640 #ifdef __ARM_ARCH_ISA_A64
6641 asm ("usdot %0.2s, %1.8b, %2.8b"
6642 : "=w"(results)
6643 : "w"(a), "w"(b)
6644 : /* No clobbers. */);
6645
6646 #else
6647 asm ("vusdot.u8 %P0, %P1, %P2"
6648 : "=w"(results)
6649 : "w"(a), "w"(b)
6650 : /* No clobbers. */);
6651 #endif
6652
6653 return (vget_lane_u32 (results, 0) == 8
6654 && vget_lane_u32 (results, 1) == 24) ? 1 : 0;
6655 }
6656 } [add_options_for_arm_v8_2a_i8mm ""]]
6657 }
6658
6659 # Return 1 if this is a ARM target with NEON enabled.
6660
6661 proc check_effective_target_arm_neon { } {
6662 if { [check_effective_target_arm32] } {
6663 return [check_no_compiler_messages arm_neon object {
6664 #ifndef __ARM_NEON__
6665 #error not NEON
6666 #else
6667 int dummy;
6668 #endif
6669 }]
6670 } else {
6671 return 0
6672 }
6673 }
6674
6675 proc check_effective_target_arm_neonv2 { } {
6676 if { [check_effective_target_arm32] } {
6677 return [check_no_compiler_messages arm_neon object {
6678 #ifndef __ARM_NEON__
6679 #error not NEON
6680 #else
6681 #ifndef __ARM_FEATURE_FMA
6682 #error not NEONv2
6683 #else
6684 int dummy;
6685 #endif
6686 #endif
6687 }]
6688 } else {
6689 return 0
6690 }
6691 }
6692
6693 # Return 1 if this is an ARM target with load acquire and store release
6694 # instructions for 8-, 16- and 32-bit types.
6695
6696 proc check_effective_target_arm_acq_rel { } {
6697 return [check_no_compiler_messages arm_acq_rel object {
6698 void
6699 load_acquire_store_release (void)
6700 {
6701 asm ("lda r0, [r1]\n\t"
6702 "stl r0, [r1]\n\t"
6703 "ldah r0, [r1]\n\t"
6704 "stlh r0, [r1]\n\t"
6705 "ldab r0, [r1]\n\t"
6706 "stlb r0, [r1]"
6707 : : : "r0", "memory");
6708 }
6709 }]
6710 }
6711
6712 # Add the options needed for MIPS Paired-Single.
6713
6714 proc add_options_for_mpaired_single { flags } {
6715 if { ! [check_effective_target_mpaired_single "-mpaired-single"] } {
6716 return "$flags"
6717 }
6718 return "$flags -mpaired-single"
6719 }
6720
6721 # Add the options needed for MIPS SIMD Architecture.
6722
6723 proc add_options_for_mips_msa { flags } {
6724 if { ! [check_effective_target_mips_msa "-mmsa"] } {
6725 return "$flags"
6726 }
6727 return "$flags -mmsa"
6728 }
6729
6730 # Add the options needed for MIPS Loongson MMI Architecture.
6731
6732 proc add_options_for_mips_loongson_mmi { flags } {
6733 if { ! [check_effective_target_mips_loongson_mmi "-mloongson-mmi"] } {
6734 return "$flags"
6735 }
6736 return "$flags -mloongson-mmi"
6737 }
6738
6739
6740 # Return 1 if this a Loongson-2E or -2F target using an ABI that supports
6741 # the Loongson vector modes.
6742
6743 proc check_effective_target_mips_loongson_mmi { args } {
6744 return [check_no_compiler_messages loongson assembly {
6745 #if !defined(__mips_loongson_mmi)
6746 #error !__mips_loongson_mmi
6747 #endif
6748 #if !defined(__mips_loongson_vector_rev)
6749 #error !__mips_loongson_vector_rev
6750 #endif
6751 } "$args"]
6752 }
6753
6754 # Return 1 if this is a MIPS target that supports the legacy NAN.
6755
6756 proc check_effective_target_mips_nanlegacy { } {
6757 return [check_no_compiler_messages nanlegacy assembly {
6758 #include <stdlib.h>
6759 int main () { return 0; }
6760 } "-mnan=legacy"]
6761 }
6762
6763 # Return 1 if an MSA program can be compiled to object
6764
6765 proc check_effective_target_mips_msa { args } {
6766 if ![check_effective_target_nomips16] {
6767 return 0
6768 }
6769 return [check_no_compiler_messages msa object {
6770 #if !defined(__mips_msa)
6771 #error "MSA NOT AVAIL"
6772 #else
6773 #if !(((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2))
6774 #error "MSA NOT AVAIL FOR ISA REV < 2"
6775 #endif
6776 #if !defined(__mips_hard_float)
6777 #error "MSA HARD_FLOAT REQUIRED"
6778 #endif
6779 #if __mips_fpr != 64
6780 #error "MSA 64-bit FPR REQUIRED"
6781 #endif
6782 #include <msa.h>
6783
6784 int main()
6785 {
6786 v8i16 v = __builtin_msa_ldi_h (1);
6787
6788 return v[0];
6789 }
6790 #endif
6791 } "$args"]
6792 }
6793
6794 # Return 1 if this is an ARM target that adheres to the ABI for the ARM
6795 # Architecture.
6796
6797 proc check_effective_target_arm_eabi { } {
6798 return [check_no_compiler_messages arm_eabi object {
6799 #ifndef __ARM_EABI__
6800 #error not EABI
6801 #else
6802 int dummy;
6803 #endif
6804 }]
6805 }
6806
6807 # Return 1 if this is an ARM target that adheres to the hard-float variant of
6808 # the ABI for the ARM Architecture (e.g. -mfloat-abi=hard).
6809
6810 proc check_effective_target_arm_hf_eabi { } {
6811 return [check_no_compiler_messages arm_hf_eabi object {
6812 #if !defined(__ARM_EABI__) || !defined(__ARM_PCS_VFP)
6813 #error not hard-float EABI
6814 #else
6815 int dummy;
6816 #endif
6817 }]
6818 }
6819
6820 # Return 1 if this is an ARM target uses emulated floating point
6821 # operations.
6822
6823 proc check_effective_target_arm_softfloat { } {
6824 return [check_no_compiler_messages arm_softfloat object {
6825 #if !defined(__SOFTFP__)
6826 #error not soft-float EABI
6827 #else
6828 int dummy;
6829 #endif
6830 }]
6831 }
6832
6833 # Return 1 if this is an ARM target supporting -mcpu=iwmmxt.
6834 # Some multilibs may be incompatible with this option.
6835
6836 proc check_effective_target_arm_iwmmxt_ok { } {
6837 if { [check_effective_target_arm32] } {
6838 return [check_no_compiler_messages arm_iwmmxt_ok object {
6839 int dummy;
6840 } "-mcpu=iwmmxt"]
6841 } else {
6842 return 0
6843 }
6844 }
6845
6846 # Return true if LDRD/STRD instructions are prefered over LDM/STM instructions
6847 # for an ARM target.
6848 proc check_effective_target_arm_prefer_ldrd_strd { } {
6849 if { ![check_effective_target_arm32] } {
6850 return 0;
6851 }
6852
6853 return [check_no_messages_and_pattern arm_prefer_ldrd_strd "strd\tr" assembly {
6854 void foo (void) { __asm__ ("" ::: "r4", "r5"); }
6855 } "-O2 -mthumb" ]
6856 }
6857
6858 # Return true if LDRD/STRD instructions are available on this target.
6859 proc check_effective_target_arm_ldrd_strd_ok { } {
6860 if { ![check_effective_target_arm32] } {
6861 return 0;
6862 }
6863
6864 return [check_no_compiler_messages arm_ldrd_strd_ok object {
6865 int main(void)
6866 {
6867 __UINT64_TYPE__ a = 1, b = 10;
6868 __UINT64_TYPE__ *c = &b;
6869 // `a` will be in a valid register since it's a DImode quantity.
6870 asm ("ldrd %0, %1"
6871 : "=r" (a)
6872 : "m" (c));
6873 return a == 10;
6874 }
6875 }]
6876 }
6877
6878 # Return 1 if this is a PowerPC target supporting -meabi.
6879
6880 proc check_effective_target_powerpc_eabi_ok { } {
6881 if { [istarget powerpc*-*-*] } {
6882 return [check_no_compiler_messages powerpc_eabi_ok object {
6883 int dummy;
6884 } "-meabi"]
6885 } else {
6886 return 0
6887 }
6888 }
6889
6890 # Return 1 if this is a PowerPC target with floating-point registers.
6891
6892 proc check_effective_target_powerpc_fprs { } {
6893 if { [istarget powerpc*-*-*]
6894 || [istarget rs6000-*-*] } {
6895 return [check_no_compiler_messages powerpc_fprs object {
6896 #ifdef __NO_FPRS__
6897 #error no FPRs
6898 #else
6899 int dummy;
6900 #endif
6901 }]
6902 } else {
6903 return 0
6904 }
6905 }
6906
6907 # Return 1 if this is a PowerPC target with hardware double-precision
6908 # floating point.
6909
6910 proc check_effective_target_powerpc_hard_double { } {
6911 if { [istarget powerpc*-*-*]
6912 || [istarget rs6000-*-*] } {
6913 return [check_no_compiler_messages powerpc_hard_double object {
6914 #ifdef _SOFT_DOUBLE
6915 #error soft double
6916 #else
6917 int dummy;
6918 #endif
6919 }]
6920 } else {
6921 return 0
6922 }
6923 }
6924
6925 # Return 1 if this is a PowerPC target with hardware floating point sqrt.
6926
6927 proc check_effective_target_powerpc_sqrt { } {
6928 # We need to be PowerPC, and we need to have hardware fp enabled.
6929 if {![check_effective_target_powerpc_fprs]} {
6930 return 0;
6931 }
6932
6933 return [check_no_compiler_messages powerpc_sqrt object {
6934 void test (void)
6935 {
6936 #ifndef _ARCH_PPCSQ
6937 #error _ARCH_PPCSQ is not defined
6938 #endif
6939 }
6940 } {}]
6941 }
6942
6943 # Return 1 if this is a PowerPC target supporting -maltivec.
6944
6945 proc check_effective_target_powerpc_altivec_ok { } {
6946 # Not PowerPC, then not ok
6947 if { !([istarget powerpc*-*-*] || [istarget rs6000-*-*]) } { return 0 }
6948
6949 # Paired Single, then not ok
6950 if { [istarget powerpc-*-linux*paired*] } { return 0 }
6951
6952 # AltiVec is not supported on AIX before 5.3.
6953 if { [istarget powerpc*-*-aix4*]
6954 || [istarget powerpc*-*-aix5.1*]
6955 || [istarget powerpc*-*-aix5.2*] } { return 0 }
6956
6957 # Return true iff compiling with -maltivec does not error.
6958 return [check_no_compiler_messages powerpc_altivec_ok object {
6959 int dummy;
6960 } "-maltivec"]
6961 }
6962
6963 # Return 1 if this is a PowerPC target supporting -mpower8-vector
6964
6965 proc check_effective_target_powerpc_p8vector_ok { } {
6966 if { ([istarget powerpc*-*-*]
6967 && ![istarget powerpc-*-linux*paired*])
6968 || [istarget rs6000-*-*] } {
6969 # AltiVec is not supported on AIX before 5.3.
6970 if { [istarget powerpc*-*-aix4*]
6971 || [istarget powerpc*-*-aix5.1*]
6972 || [istarget powerpc*-*-aix5.2*] } {
6973 return 0
6974 }
6975 # Darwin doesn't run on power8, so far.
6976 if { [istarget *-*-darwin*] } {
6977 return 0
6978 }
6979 return [check_no_compiler_messages powerpc_p8vector_ok object {
6980 int main (void) {
6981 asm volatile ("xxlorc 0,0,0");
6982 return 0;
6983 }
6984 } "-mpower8-vector"]
6985 } else {
6986 return 0
6987 }
6988 }
6989
6990 # Return 1 if this is a PowerPC target supporting -mpower9-vector
6991
6992 proc check_effective_target_powerpc_p9vector_ok { } {
6993 if { ([istarget powerpc*-*-*]
6994 && ![istarget powerpc-*-linux*paired*])
6995 || [istarget rs6000-*-*] } {
6996 # AltiVec is not supported on AIX before 5.3.
6997 if { [istarget powerpc*-*-aix4*]
6998 || [istarget powerpc*-*-aix5.1*]
6999 || [istarget powerpc*-*-aix5.2*] } {
7000 return 0
7001 }
7002 # Darwin doesn't run on power9, so far.
7003 if { [istarget *-*-darwin*] } {
7004 return 0
7005 }
7006 return [check_no_compiler_messages powerpc_p9vector_ok object {
7007 int main (void) {
7008 long e = -1;
7009 vector double v = (vector double) { 0.0, 0.0 };
7010 asm ("xsxexpdp %0,%1" : "+r" (e) : "wa" (v));
7011 return e;
7012 }
7013 } "-mpower9-vector"]
7014 } else {
7015 return 0
7016 }
7017 }
7018
7019 # Return 1 if this is a PowerPC target supporting -mmodulo
7020
7021 proc check_effective_target_powerpc_p9modulo_ok { } {
7022 if { ([istarget powerpc*-*-*]
7023 && ![istarget powerpc-*-linux*paired*])
7024 || [istarget rs6000-*-*] } {
7025 # AltiVec is not supported on AIX before 5.3.
7026 if { [istarget powerpc*-*-aix4*]
7027 || [istarget powerpc*-*-aix5.1*]
7028 || [istarget powerpc*-*-aix5.2*] } {
7029 return 0
7030 }
7031 return [check_no_compiler_messages powerpc_p9modulo_ok object {
7032 int main (void) {
7033 int i = 5, j = 3, r = -1;
7034 asm ("modsw %0,%1,%2" : "+r" (r) : "r" (i), "r" (j));
7035 return (r == 2);
7036 }
7037 } "-mmodulo"]
7038 } else {
7039 return 0
7040 }
7041 }
7042
7043 # return 1 if our compiler returns the ARCH_PWR defines with the options
7044 # as provided by the test.
7045 proc check_effective_target_has_arch_pwr5 { } {
7046 return [check_no_compiler_messages_nocache arch_pwr5 assembly {
7047 void test (void)
7048 {
7049 #ifndef _ARCH_PWR5
7050 #error does not have power5 support.
7051 #else
7052 /* "has power5 support" */
7053 #endif
7054 }
7055 } [current_compiler_flags]]
7056 }
7057
7058 proc check_effective_target_has_arch_pwr6 { } {
7059 return [check_no_compiler_messages_nocache arch_pwr6 assembly {
7060 void test (void)
7061 {
7062 #ifndef _ARCH_PWR6
7063 #error does not have power6 support.
7064 #else
7065 /* "has power6 support" */
7066 #endif
7067 }
7068 } [current_compiler_flags]]
7069 }
7070
7071 proc check_effective_target_has_arch_pwr7 { } {
7072 return [check_no_compiler_messages_nocache arch_pwr7 assembly {
7073 void test (void)
7074 {
7075 #ifndef _ARCH_PWR7
7076 #error does not have power7 support.
7077 #else
7078 /* "has power7 support" */
7079 #endif
7080 }
7081 } [current_compiler_flags]]
7082 }
7083
7084 proc check_effective_target_has_arch_pwr8 { } {
7085 return [check_no_compiler_messages_nocache arch_pwr8 assembly {
7086 void test (void)
7087 {
7088 #ifndef _ARCH_PWR8
7089 #error does not have power8 support.
7090 #else
7091 /* "has power8 support" */
7092 #endif
7093 }
7094 } [current_compiler_flags]]
7095 }
7096
7097 proc check_effective_target_has_arch_pwr9 { } {
7098 return [check_no_compiler_messages_nocache arch_pwr9 assembly {
7099 void test (void)
7100 {
7101 #ifndef _ARCH_PWR9
7102 #error does not have power9 support.
7103 #else
7104 /* "has power9 support" */
7105 #endif
7106 }
7107 } [current_compiler_flags]]
7108 }
7109
7110 proc check_effective_target_has_arch_pwr10 { } {
7111 return [check_no_compiler_messages_nocache arch_pwr10 assembly {
7112 void test (void)
7113 {
7114 #ifndef _ARCH_PWR10
7115 #error does not have power10 support.
7116 #else
7117 /* "has power10 support" */
7118 #endif
7119 }
7120 } [current_compiler_flags]]
7121 }
7122
7123 proc check_effective_target_has_arch_ppc64 { } {
7124 return [check_no_compiler_messages_nocache arch_ppc64 assembly {
7125 void test (void)
7126 {
7127 #ifndef _ARCH_PPC64
7128 #error does not have ppc64 support.
7129 #else
7130 /* "has ppc64 support" */
7131 #endif
7132 }
7133 } [current_compiler_flags]]
7134 }
7135
7136 # Return 1 if this is a PowerPC target supporting -mcpu=power10.
7137 # Limit this to 64-bit linux systems for now until other targets support
7138 # power10.
7139
7140 proc check_effective_target_power10_ok { } {
7141 if { ([istarget powerpc64*-*-linux*]) } {
7142 return [check_no_compiler_messages power10_ok object {
7143 int main (void) {
7144 long e;
7145 asm ("pli %0,%1" : "=r" (e) : "n" (0x12345));
7146 return e;
7147 }
7148 } "-mcpu=power10"]
7149 } else {
7150 return 0
7151 }
7152 }
7153
7154 # Return 1 if this is a PowerPC target supporting -mfloat128 via either
7155 # software emulation on power7/power8 systems or hardware support on power9.
7156
7157 proc check_effective_target_powerpc_float128_sw_ok { } {
7158 if { ([istarget powerpc*-*-*]
7159 && ![istarget powerpc-*-linux*paired*])
7160 || [istarget rs6000-*-*] } {
7161 # AltiVec is not supported on AIX before 5.3.
7162 if { [istarget powerpc*-*-aix4*]
7163 || [istarget powerpc*-*-aix5.1*]
7164 || [istarget powerpc*-*-aix5.2*] } {
7165 return 0
7166 }
7167 # Darwin doesn't have VSX, so no soft support for float128.
7168 if { [istarget *-*-darwin*] } {
7169 return 0
7170 }
7171 return [check_no_compiler_messages powerpc_float128_sw_ok object {
7172 volatile __float128 x = 1.0q;
7173 volatile __float128 y = 2.0q;
7174 int main() {
7175 __float128 z = x + y;
7176 return (z == 3.0q);
7177 }
7178 } "-mfloat128 -mvsx"]
7179 } else {
7180 return 0
7181 }
7182 }
7183
7184 # Return 1 if this is a PowerPC target supporting -mfloat128 via hardware
7185 # support on power9.
7186
7187 proc check_effective_target_powerpc_float128_hw_ok { } {
7188 if { ([istarget powerpc*-*-*]
7189 && ![istarget powerpc-*-linux*paired*])
7190 || [istarget rs6000-*-*] } {
7191 # AltiVec is not supported on AIX before 5.3.
7192 if { [istarget powerpc*-*-aix4*]
7193 || [istarget powerpc*-*-aix5.1*]
7194 || [istarget powerpc*-*-aix5.2*] } {
7195 return 0
7196 }
7197 # Darwin doesn't run on any machine with float128 h/w so far.
7198 if { [istarget *-*-darwin*] } {
7199 return 0
7200 }
7201 return [check_no_compiler_messages powerpc_float128_hw_ok object {
7202 volatile __float128 x = 1.0q;
7203 volatile __float128 y = 2.0q;
7204 int main() {
7205 __float128 z;
7206 __asm__ ("xsaddqp %0,%1,%2" : "=v" (z) : "v" (x), "v" (y));
7207 return (z == 3.0q);
7208 }
7209 } "-mfloat128-hardware"]
7210 } else {
7211 return 0
7212 }
7213 }
7214
7215 # Return 1 if current options define float128, 0 otherwise.
7216
7217 proc check_effective_target_ppc_float128 { } {
7218 return [check_no_compiler_messages_nocache ppc_float128 object {
7219 void test (void)
7220 {
7221 #ifndef __FLOAT128__
7222 nope no good
7223 #endif
7224 }
7225 }]
7226 }
7227
7228 # Return 1 if current options generate float128 insns, 0 otherwise.
7229
7230 proc check_effective_target_ppc_float128_insns { } {
7231 return [check_no_compiler_messages_nocache ppc_float128 object {
7232 void test (void)
7233 {
7234 #ifndef __FLOAT128_HARDWARE__
7235 nope no good
7236 #endif
7237 }
7238 }]
7239 }
7240
7241 # Return 1 if current options generate VSX instructions, 0 otherwise.
7242
7243 proc check_effective_target_powerpc_vsx { } {
7244 return [check_no_compiler_messages_nocache powerpc_vsx object {
7245 void test (void)
7246 {
7247 #ifndef __VSX__
7248 nope no vsx
7249 #endif
7250 }
7251 }]
7252 }
7253
7254 # Return 1 if this is a PowerPC target supporting -mvsx
7255
7256 proc check_effective_target_powerpc_vsx_ok { } {
7257 if { ([istarget powerpc*-*-*]
7258 && ![istarget powerpc-*-linux*paired*])
7259 || [istarget rs6000-*-*] } {
7260 # VSX is not supported on AIX before 7.1.
7261 if { [istarget powerpc*-*-aix4*]
7262 || [istarget powerpc*-*-aix5*]
7263 || [istarget powerpc*-*-aix6*] } {
7264 return 0
7265 }
7266 # Darwin doesn't have VSX, even if it's used with an assembler
7267 # which recognises the insns.
7268 if { [istarget *-*-darwin*] } {
7269 return 0
7270 }
7271 return [check_no_compiler_messages powerpc_vsx_ok object {
7272 int main (void) {
7273 asm volatile ("xxlor 0,0,0");
7274 return 0;
7275 }
7276 } "-mvsx"]
7277 } else {
7278 return 0
7279 }
7280 }
7281
7282 # Return 1 if this is a PowerPC target supporting -mhtm
7283
7284 proc check_effective_target_powerpc_htm_ok { } {
7285 if { ([istarget powerpc*-*-*]
7286 && ![istarget powerpc-*-linux*paired*])
7287 || [istarget rs6000-*-*] } {
7288 # HTM is not supported on AIX yet.
7289 if { [istarget powerpc*-*-aix*] } {
7290 return 0
7291 }
7292 return [check_no_compiler_messages powerpc_htm_ok object {
7293 int main (void) {
7294 asm volatile ("tbegin. 0");
7295 return 0;
7296 }
7297 } "-mhtm"]
7298 } else {
7299 return 0
7300 }
7301 }
7302
7303 # Return 1 if the target supports executing HTM hardware instructions,
7304 # 0 otherwise. Cache the result.
7305
7306 proc check_htm_hw_available { } {
7307 return [check_cached_effective_target htm_hw_available {
7308 # For now, disable on Darwin
7309 if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
7310 expr 0
7311 } else {
7312 check_runtime_nocache htm_hw_available {
7313 int main()
7314 {
7315 __builtin_ttest ();
7316 return 0;
7317 }
7318 } "-mhtm"
7319 }
7320 }]
7321 }
7322 # Return 1 if this is a PowerPC target supporting -mcpu=cell.
7323
7324 proc check_effective_target_powerpc_ppu_ok { } {
7325 if [check_effective_target_powerpc_altivec_ok] {
7326 return [check_no_compiler_messages cell_asm_available object {
7327 int main (void) {
7328 #ifdef __MACH__
7329 asm volatile ("lvlx v0,v0,v0");
7330 #else
7331 asm volatile ("lvlx 0,0,0");
7332 #endif
7333 return 0;
7334 }
7335 }]
7336 } else {
7337 return 0
7338 }
7339 }
7340
7341 # Return 1 if this is a PowerPC target that supports SPU.
7342
7343 proc check_effective_target_powerpc_spu { } {
7344 if { [istarget powerpc*-*-linux*] } {
7345 return [check_effective_target_powerpc_altivec_ok]
7346 } else {
7347 return 0
7348 }
7349 }
7350
7351 # Return 1 if this is a PowerPC SPE target. The check includes options
7352 # specified by dg-options for this test, so don't cache the result.
7353
7354 proc check_effective_target_powerpc_spe_nocache { } {
7355 if { [istarget powerpc*-*-*] } {
7356 return [check_no_compiler_messages_nocache powerpc_spe object {
7357 #ifndef __SPE__
7358 #error not SPE
7359 #else
7360 int dummy;
7361 #endif
7362 } [current_compiler_flags]]
7363 } else {
7364 return 0
7365 }
7366 }
7367
7368 # Return 1 if this is a PowerPC target with SPE enabled.
7369
7370 proc check_effective_target_powerpc_spe { } {
7371 if { [istarget powerpc*-*-*] } {
7372 return [check_no_compiler_messages powerpc_spe object {
7373 #ifndef __SPE__
7374 #error not SPE
7375 #else
7376 int dummy;
7377 #endif
7378 }]
7379 } else {
7380 return 0
7381 }
7382 }
7383
7384 # Return 1 if this is a PowerPC target with Altivec enabled.
7385
7386 proc check_effective_target_powerpc_altivec { } {
7387 if { [istarget powerpc*-*-*] } {
7388 return [check_no_compiler_messages powerpc_altivec object {
7389 #ifndef __ALTIVEC__
7390 #error not Altivec
7391 #else
7392 int dummy;
7393 #endif
7394 }]
7395 } else {
7396 return 0
7397 }
7398 }
7399
7400 # Return 1 if this is a PowerPC 405 target. The check includes options
7401 # specified by dg-options for this test, so don't cache the result.
7402
7403 proc check_effective_target_powerpc_405_nocache { } {
7404 if { [istarget powerpc*-*-*] || [istarget rs6000-*-*] } {
7405 return [check_no_compiler_messages_nocache powerpc_405 object {
7406 #ifdef __PPC405__
7407 int dummy;
7408 #else
7409 #error not a PPC405
7410 #endif
7411 } [current_compiler_flags]]
7412 } else {
7413 return 0
7414 }
7415 }
7416
7417 # Return 1 if this is a PowerPC target using the ELFv2 ABI.
7418
7419 proc check_effective_target_powerpc_elfv2 { } {
7420 if { [istarget powerpc*-*-*] } {
7421 return [check_no_compiler_messages powerpc_elfv2 object {
7422 #if _CALL_ELF != 2
7423 #error not ELF v2 ABI
7424 #else
7425 int dummy;
7426 #endif
7427 }]
7428 } else {
7429 return 0
7430 }
7431 }
7432
7433 # Return 1 if this is a PowerPC target supporting -mrop-protect
7434
7435 proc check_effective_target_rop_ok { } {
7436 return [check_effective_target_power10_ok] && [check_effective_target_powerpc_elfv2]
7437 }
7438
7439 # The VxWorks SPARC simulator accepts only EM_SPARC executables and
7440 # chokes on EM_SPARC32PLUS or EM_SPARCV9 executables. Return 1 if the
7441 # test environment appears to run executables on such a simulator.
7442
7443 proc check_effective_target_ultrasparc_hw { } {
7444 return [check_runtime ultrasparc_hw {
7445 int main() { return 0; }
7446 } "-mcpu=ultrasparc"]
7447 }
7448
7449 # Return 1 if the test environment supports executing UltraSPARC VIS2
7450 # instructions. We check this by attempting: "bmask %g0, %g0, %g0"
7451
7452 proc check_effective_target_ultrasparc_vis2_hw { } {
7453 return [check_runtime ultrasparc_vis2_hw {
7454 int main() { __asm__(".word 0x81b00320"); return 0; }
7455 } "-mcpu=ultrasparc3"]
7456 }
7457
7458 # Return 1 if the test environment supports executing UltraSPARC VIS3
7459 # instructions. We check this by attempting: "addxc %g0, %g0, %g0"
7460
7461 proc check_effective_target_ultrasparc_vis3_hw { } {
7462 return [check_runtime ultrasparc_vis3_hw {
7463 int main() { __asm__(".word 0x81b00220"); return 0; }
7464 } "-mcpu=niagara3"]
7465 }
7466
7467 # Return 1 if this is a SPARC-V9 target.
7468
7469 proc check_effective_target_sparc_v9 { } {
7470 if { [istarget sparc*-*-*] } {
7471 return [check_no_compiler_messages sparc_v9 object {
7472 int main (void) {
7473 asm volatile ("return %i7+8");
7474 return 0;
7475 }
7476 }]
7477 } else {
7478 return 0
7479 }
7480 }
7481
7482 # Return 1 if this is a SPARC target with VIS enabled.
7483
7484 proc check_effective_target_sparc_vis { } {
7485 if { [istarget sparc*-*-*] } {
7486 return [check_no_compiler_messages sparc_vis object {
7487 #ifndef __VIS__
7488 #error not VIS
7489 #else
7490 int dummy;
7491 #endif
7492 }]
7493 } else {
7494 return 0
7495 }
7496 }
7497
7498 # Return 1 if the target supports hardware vector shift operation.
7499
7500 proc check_effective_target_vect_shift { } {
7501 return [check_cached_effective_target_indexed vect_shift {
7502 expr {([istarget powerpc*-*-*]
7503 && ![istarget powerpc-*-linux*paired*])
7504 || [istarget ia64-*-*]
7505 || [istarget i?86-*-*] || [istarget x86_64-*-*]
7506 || [istarget aarch64*-*-*]
7507 || [is-effective-target arm_neon]
7508 || ([istarget mips*-*-*]
7509 && ([et-is-effective-target mips_msa]
7510 || [et-is-effective-target mips_loongson_mmi]))
7511 || ([istarget s390*-*-*]
7512 && [check_effective_target_s390_vx])
7513 || [istarget amdgcn-*-*]
7514 || ([istarget riscv*-*-*]
7515 && [check_effective_target_riscv_v])
7516 || ([istarget loongarch*-*-*]
7517 && [check_effective_target_loongarch_sx]) }}]
7518 }
7519
7520 # Return 1 if the target supports hardware vector shift by register operation.
7521
7522 proc check_effective_target_vect_var_shift { } {
7523 return [check_cached_effective_target_indexed vect_var_shift {
7524 expr {(([istarget i?86-*-*] || [istarget x86_64-*-*])
7525 && [check_avx2_available])
7526 || [istarget aarch64*-*-*]
7527 || ([istarget riscv*-*-*]
7528 && [check_effective_target_riscv_v])
7529 || ([istarget loongarch*-*-*]
7530 && [check_effective_target_loongarch_sx])
7531 }}]
7532 }
7533
7534 proc check_effective_target_whole_vector_shift { } {
7535 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
7536 || [istarget ia64-*-*]
7537 || [istarget aarch64*-*-*]
7538 || [istarget powerpc64*-*-*]
7539 || ([is-effective-target arm_neon]
7540 && [check_effective_target_arm_little_endian])
7541 || ([istarget mips*-*-*]
7542 && [et-is-effective-target mips_loongson_mmi])
7543 || ([istarget s390*-*-*]
7544 && [check_effective_target_s390_vx])
7545 || [istarget amdgcn-*-*]
7546 || ([istarget riscv*-*-*]
7547 && [check_effective_target_riscv_v])
7548 || ([istarget loongarch*-*-*]
7549 && [check_effective_target_loongarch_sx]) } {
7550 set answer 1
7551 } else {
7552 set answer 0
7553 }
7554
7555 verbose "check_effective_target_vect_long: returning $answer" 2
7556 return $answer
7557 }
7558
7559 # Return 1 if the target supports vector bswap operations.
7560
7561 proc check_effective_target_vect_bswap { } {
7562 return [check_cached_effective_target_indexed vect_bswap {
7563 expr { ([istarget aarch64*-*-*]
7564 || [is-effective-target arm_neon]
7565 || [istarget amdgcn-*-*])
7566 || [istarget loongarch*-*-*]
7567 || ([istarget s390*-*-*]
7568 && [check_effective_target_s390_vx]) }}]
7569 }
7570
7571 # Return 1 if the target supports comparison of bool vectors for at
7572 # least one vector length.
7573
7574 proc check_effective_target_vect_bool_cmp { } {
7575 return [check_cached_effective_target_indexed vect_bool_cmp {
7576 expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
7577 || [istarget aarch64*-*-*]
7578 || [is-effective-target arm_neon]
7579 || ([istarget riscv*-*-*]
7580 && [check_effective_target_riscv_v])
7581 || ([istarget loongarch*-*-*]
7582 && [check_effective_target_loongarch_sx]) }}]
7583 }
7584
7585 # Return 1 if the target supports addition of char vectors for at least
7586 # one vector length.
7587
7588 proc check_effective_target_vect_char_add { } {
7589 return [check_cached_effective_target_indexed vect_char_add {
7590 expr {
7591 [istarget i?86-*-*] || [istarget x86_64-*-*]
7592 || ([istarget powerpc*-*-*]
7593 && ![istarget powerpc-*-linux*paired*])
7594 || [istarget amdgcn-*-*]
7595 || [istarget ia64-*-*]
7596 || [istarget aarch64*-*-*]
7597 || [is-effective-target arm_neon]
7598 || ([istarget mips*-*-*]
7599 && ([et-is-effective-target mips_loongson_mmi]
7600 || [et-is-effective-target mips_msa]))
7601 || ([istarget s390*-*-*]
7602 && [check_effective_target_s390_vx])
7603 || ([istarget riscv*-*-*]
7604 && [check_effective_target_riscv_v])
7605 || ([istarget loongarch*-*-*]
7606 && [check_effective_target_loongarch_sx])
7607 }}]
7608 }
7609
7610 # Return 1 if the target supports hardware vector shift operation for char.
7611
7612 proc check_effective_target_vect_shift_char { } {
7613 return [check_cached_effective_target_indexed vect_shift_char {
7614 expr { ([istarget powerpc*-*-*]
7615 && ![istarget powerpc-*-linux*paired*])
7616 || [is-effective-target arm_neon]
7617 || ([istarget mips*-*-*]
7618 && [et-is-effective-target mips_msa])
7619 || ([istarget s390*-*-*]
7620 && [check_effective_target_s390_vx])
7621 || [istarget amdgcn-*-*]
7622 || ([istarget riscv*-*-*]
7623 && [check_effective_target_riscv_v])
7624 || ([istarget loongarch*-*-*]
7625 && [check_effective_target_loongarch_sx]) }}]
7626 }
7627
7628 # Return 1 if the target supports hardware vectors of long, 0 otherwise.
7629 #
7630 # This can change for different subtargets so do not cache the result.
7631
7632 proc check_effective_target_vect_long { } {
7633 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
7634 || (([istarget powerpc*-*-*]
7635 && ![istarget powerpc-*-linux*paired*])
7636 && [check_effective_target_ilp32])
7637 || [is-effective-target arm_neon]
7638 || ([istarget sparc*-*-*] && [check_effective_target_ilp32])
7639 || [istarget aarch64*-*-*]
7640 || ([istarget mips*-*-*]
7641 && [et-is-effective-target mips_msa])
7642 || ([istarget s390*-*-*]
7643 && [check_effective_target_s390_vx])
7644 || [istarget amdgcn-*-*]
7645 || ([istarget riscv*-*-*]
7646 && [check_effective_target_riscv_v])
7647 || ([istarget loongarch*-*-*]
7648 && [check_effective_target_loongarch_sx]) } {
7649 set answer 1
7650 } else {
7651 set answer 0
7652 }
7653
7654 verbose "check_effective_target_vect_long: returning $answer" 2
7655 return $answer
7656 }
7657
7658 # Return 1 if the target supports hardware vectors of float when
7659 # -funsafe-math-optimizations is enabled, 0 otherwise.
7660 #
7661 # This won't change for different subtargets so cache the result.
7662
7663 proc check_effective_target_vect_float { } {
7664 return [check_cached_effective_target_indexed vect_float {
7665 expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
7666 || [istarget powerpc*-*-*]
7667 || [istarget mips-sde-elf]
7668 || [istarget mipsisa64*-*-*]
7669 || [istarget ia64-*-*]
7670 || [istarget aarch64*-*-*]
7671 || ([istarget mips*-*-*]
7672 && [et-is-effective-target mips_msa])
7673 || [is-effective-target arm_neon]
7674 || ([istarget s390*-*-*]
7675 && [check_effective_target_s390_vxe])
7676 || [istarget amdgcn-*-*]
7677 || ([istarget riscv*-*-*]
7678 && [check_effective_target_riscv_v])
7679 || ([istarget loongarch*-*-*]
7680 && [check_effective_target_loongarch_sx]) }}]
7681 }
7682
7683 # Return 1 if the target supports hardware vectors of float without
7684 # -funsafe-math-optimizations being enabled, 0 otherwise.
7685
7686 proc check_effective_target_vect_float_strict { } {
7687 return [expr { [check_effective_target_vect_float]
7688 && ![istarget arm*-*-*] }]
7689 }
7690
7691 # Return 1 if the target supports hardware vectors of double, 0 otherwise.
7692 #
7693 # This won't change for different subtargets so cache the result.
7694
7695 proc check_effective_target_vect_double { } {
7696 return [check_cached_effective_target_indexed vect_double {
7697 expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
7698 && [check_no_compiler_messages vect_double assembly {
7699 #ifdef __tune_atom__
7700 # error No double vectorizer support.
7701 #endif
7702 }])
7703 || [istarget aarch64*-*-*]
7704 || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
7705 || ([istarget mips*-*-*]
7706 && [et-is-effective-target mips_msa])
7707 || ([istarget s390*-*-*]
7708 && [check_effective_target_s390_vx])
7709 || [istarget amdgcn-*-*]
7710 || ([istarget riscv*-*-*]
7711 && [check_effective_target_riscv_v])
7712 || ([istarget loongarch*-*-*]
7713 && [check_effective_target_loongarch_sx]) }}]
7714 }
7715
7716 # Return 1 if the target supports conditional addition, subtraction,
7717 # multiplication, division, minimum and maximum on vectors of double,
7718 # via the cond_ optabs. Return 0 otherwise.
7719
7720 proc check_effective_target_vect_double_cond_arith { } {
7721 return [expr { [check_effective_target_aarch64_sve]
7722 || [check_effective_target_riscv_v] }]
7723 }
7724
7725 # Return 1 if the target supports hardware vectors of long long, 0 otherwise.
7726 #
7727 # This won't change for different subtargets so cache the result.
7728
7729 proc check_effective_target_vect_long_long { } {
7730 return [check_cached_effective_target_indexed vect_long_long {
7731 expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
7732 || ([istarget mips*-*-*]
7733 && [et-is-effective-target mips_msa])
7734 || ([istarget s390*-*-*]
7735 && [check_effective_target_s390_vx])
7736 || ([istarget powerpc*-*-*]
7737 && ![istarget powerpc-*-linux*paired*]
7738 && [check_effective_target_has_arch_pwr8])
7739 || [istarget aarch64*-*-*]
7740 || ([istarget riscv*-*-*]
7741 && [check_effective_target_riscv_v])
7742 || ([istarget loongarch*-*-*]
7743 && [check_effective_target_loongarch_sx])}}]
7744 }
7745
7746
7747 # Return 1 if the target plus current options does not support a vector
7748 # max instruction on "int", 0 otherwise.
7749 #
7750 # This won't change for different subtargets so cache the result.
7751
7752 proc check_effective_target_vect_no_int_min_max { } {
7753 return [check_cached_effective_target_indexed vect_no_int_min_max {
7754 expr { [istarget sparc*-*-*]
7755 || [istarget alpha*-*-*]
7756 || ([istarget mips*-*-*]
7757 && [et-is-effective-target mips_loongson_mmi]) }}]
7758 }
7759
7760 # Return 1 if the target plus current options does not support a vector
7761 # add instruction on "int", 0 otherwise.
7762 #
7763 # This won't change for different subtargets so cache the result.
7764
7765 proc check_effective_target_vect_no_int_add { } {
7766 # Alpha only supports vector add on V8QI and V4HI.
7767 return [check_cached_effective_target_indexed vect_no_int_add {
7768 expr { [istarget alpha*-*-*] }}]
7769 }
7770
7771 # Return 1 if the target plus current options does not support vector
7772 # bitwise instructions, 0 otherwise.
7773 #
7774 # This won't change for different subtargets so cache the result.
7775
7776 proc check_effective_target_vect_no_bitwise { } {
7777 return [check_cached_effective_target_indexed vect_no_bitwise { return 0 }]
7778 }
7779
7780 # Return 1 if the target plus current options supports vector permutation,
7781 # 0 otherwise.
7782 #
7783 # This won't change for different subtargets so cache the result.
7784
7785 proc check_effective_target_vect_perm { } {
7786 return [check_cached_effective_target_indexed vect_perm {
7787 expr { [is-effective-target arm_neon]
7788 || [istarget aarch64*-*-*]
7789 || [istarget powerpc*-*-*]
7790 || [istarget i?86-*-*] || [istarget x86_64-*-*]
7791 || ([istarget mips*-*-*]
7792 && ([et-is-effective-target mpaired_single]
7793 || [et-is-effective-target mips_msa]))
7794 || ([istarget s390*-*-*]
7795 && [check_effective_target_s390_vx])
7796 || [istarget amdgcn-*-*]
7797 || ([istarget riscv*-*-*]
7798 && [check_effective_target_riscv_v])
7799 || ([istarget loongarch*-*-*]
7800 && [check_effective_target_loongarch_sx]) }}]
7801 }
7802
7803 # Return 1 if, for some VF:
7804 #
7805 # - the target's default vector size is VF * ELEMENT_BITS bits
7806 #
7807 # - it is possible to implement the equivalent of:
7808 #
7809 # int<ELEMENT_BITS>_t s1[COUNT][COUNT * VF], s2[COUNT * VF];
7810 # for (int i = 0; i < COUNT; ++i)
7811 # for (int j = 0; j < COUNT * VF; ++j)
7812 # s1[i][j] = s2[j - j % COUNT + i]
7813 #
7814 # using only a single 2-vector permute for each vector in s1.
7815 #
7816 # E.g. for COUNT == 3 and vector length 4, the two arrays would be:
7817 #
7818 # s2 | a0 a1 a2 a3 | b0 b1 b2 b3 | c0 c1 c2 c3
7819 # ------+-------------+-------------+------------
7820 # s1[0] | a0 a0 a0 a3 | a3 a3 b2 b2 | b2 c1 c1 c1
7821 # s1[1] | a1 a1 a1 b0 | b0 b0 b3 b3 | b3 c2 c2 c2
7822 # s1[2] | a2 a2 a2 b1 | b1 b1 c0 c0 | c0 c3 c3 c3
7823 #
7824 # Each s1 permute requires only two of a, b and c.
7825 #
7826 # The distance between the start of vector n in s1[0] and the start
7827 # of vector n in s2 is:
7828 #
7829 # A = (n * VF) % COUNT
7830 #
7831 # The corresponding value for the end of vector n is:
7832 #
7833 # B = (n * VF + VF - 1) % COUNT
7834 #
7835 # Subtracting i from each value gives the corresponding difference
7836 # for s1[i]. The condition being tested by this function is false
7837 # iff A - i > 0 and B - i < 0 for some i and n, such that the first
7838 # element for s1[i] comes from vector n - 1 of s2 and the last element
7839 # comes from vector n + 1 of s2. The condition is therefore true iff
7840 # A <= B for all n. This is turn means the condition is true iff:
7841 #
7842 # (n * VF) % COUNT + (VF - 1) % COUNT < COUNT
7843 #
7844 # for all n. COUNT - (n * VF) % COUNT is bounded by gcd (VF, COUNT),
7845 # and will be that value for at least one n in [0, COUNT), so we want:
7846 #
7847 # (VF - 1) % COUNT < gcd (VF, COUNT)
7848
7849 proc vect_perm_supported { count element_bits } {
7850 set vector_bits [lindex [available_vector_sizes] 0]
7851 # The number of vectors has to be a power of 2 when permuting
7852 # variable-length vectors.
7853 if { $vector_bits <= 0 && ($count & -$count) != $count } {
7854 return 0
7855 }
7856 set vf [expr { $vector_bits / $element_bits }]
7857
7858 # Compute gcd (VF, COUNT).
7859 set gcd $vf
7860 set temp1 $count
7861 while { $temp1 > 0 } {
7862 set temp2 [expr { $gcd % $temp1 }]
7863 set gcd $temp1
7864 set temp1 $temp2
7865 }
7866 return [expr { ($vf - 1) % $count < $gcd }]
7867 }
7868
7869 # Return 1 if the target supports SLP permutation of 3 vectors when each
7870 # element has 32 bits.
7871
7872 proc check_effective_target_vect_perm3_int { } {
7873 return [expr { [check_effective_target_vect_perm]
7874 && [vect_perm_supported 3 32] }]
7875 }
7876
7877 # Return 1 if the target plus current options supports vector permutation
7878 # on byte-sized elements, 0 otherwise.
7879 #
7880 # This won't change for different subtargets so cache the result.
7881
7882 proc check_effective_target_vect_perm_byte { } {
7883 return [check_cached_effective_target_indexed vect_perm_byte {
7884 expr { ([is-effective-target arm_neon]
7885 && [is-effective-target arm_little_endian])
7886 || ([istarget aarch64*-*-*]
7887 && [is-effective-target aarch64_little_endian])
7888 || [istarget powerpc*-*-*]
7889 || ([istarget mips-*.*]
7890 && [et-is-effective-target mips_msa])
7891 || ([istarget s390*-*-*]
7892 && [check_effective_target_s390_vx])
7893 || [istarget amdgcn-*-*]
7894 || ([istarget riscv*-*-*]
7895 && [check_effective_target_riscv_v])
7896 || ([istarget loongarch*-*-*]
7897 && [check_effective_target_loongarch_sx]) }}]
7898 }
7899
7900 # Return 1 if the target supports SLP permutation of 3 vectors when each
7901 # element has 8 bits.
7902
7903 proc check_effective_target_vect_perm3_byte { } {
7904 return [expr { [check_effective_target_vect_perm_byte]
7905 && [vect_perm_supported 3 8] }]
7906 }
7907
7908 # Return 1 if the target plus current options supports vector permutation
7909 # on short-sized elements, 0 otherwise.
7910 #
7911 # This won't change for different subtargets so cache the result.
7912
7913 proc check_effective_target_vect_perm_short { } {
7914 return [check_cached_effective_target_indexed vect_perm_short {
7915 expr { ([is-effective-target arm_neon]
7916 && [is-effective-target arm_little_endian])
7917 || ([istarget aarch64*-*-*]
7918 && [is-effective-target aarch64_little_endian])
7919 || [istarget powerpc*-*-*]
7920 || (([istarget i?86-*-*] || [istarget x86_64-*-*])
7921 && [check_ssse3_available])
7922 || ([istarget mips*-*-*]
7923 && [et-is-effective-target mips_msa])
7924 || ([istarget s390*-*-*]
7925 && [check_effective_target_s390_vx])
7926 || [istarget amdgcn-*-*]
7927 || ([istarget riscv*-*-*]
7928 && [check_effective_target_riscv_v])
7929 || ([istarget loongarch*-*-*]
7930 && [check_effective_target_loongarch_sx]) }}]
7931 }
7932
7933 # Return 1 if the target supports SLP permutation of 3 vectors when each
7934 # element has 16 bits.
7935
7936 proc check_effective_target_vect_perm3_short { } {
7937 return [expr { [check_effective_target_vect_perm_short]
7938 && [vect_perm_supported 3 16] }]
7939 }
7940
7941 # Return 1 if the target plus current options supports folding of
7942 # copysign into XORSIGN.
7943 #
7944 # This won't change for different subtargets so cache the result.
7945
7946 proc check_effective_target_xorsign { } {
7947 return [check_cached_effective_target_indexed xorsign {
7948 expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
7949 || [istarget aarch64*-*-*] || [istarget arm*-*-*] }}]
7950 }
7951
7952 # Return 1 if the target plus current options supports folding of
7953 # copysign into IFN_COPYSIGN.
7954 #
7955 # This won't change for different subtargets so cache the result.
7956
7957 proc check_effective_target_ifn_copysign { } {
7958 return [check_cached_effective_target_indexed ifn_copysign {
7959 expr {
7960 (([istarget i?86-*-*] || [istarget x86_64-*-*])
7961 && [is-effective-target sse])
7962 || ([istarget loongarch*-*-*]
7963 && [check_effective_target_hard_float])
7964 || ([istarget powerpc*-*-*]
7965 && ![istarget powerpc-*-linux*paired*])
7966 || [istarget alpha*-*-*]
7967 || [istarget aarch64*-*-*]
7968 || [is-effective-target arm_neon]
7969 || ([istarget s390*-*-*]
7970 && [check_effective_target_s390_vx])
7971 || ([istarget riscv*-*-*]
7972 && [check_effective_target_hard_float])
7973 }}]
7974 }
7975
7976 # Return 1 if the target plus current options supports a vector
7977 # widening summation of *short* args into *int* result, 0 otherwise.
7978 #
7979 # This won't change for different subtargets so cache the result.
7980
7981 proc check_effective_target_vect_widen_sum_hi_to_si_pattern { } {
7982 return [check_cached_effective_target_indexed vect_widen_sum_hi_to_si_pattern {
7983 expr { [istarget powerpc*-*-*]
7984 || ([istarget aarch64*-*-*]
7985 && ![check_effective_target_aarch64_sve])
7986 || [is-effective-target arm_neon]
7987 || [istarget ia64-*-*] }}]
7988 }
7989
7990 # Return 1 if the target plus current options supports a vector
7991 # widening summation of *short* args into *int* result, 0 otherwise.
7992 # A target can also support this widening summation if it can support
7993 # promotion (unpacking) from shorts to ints.
7994 #
7995 # This won't change for different subtargets so cache the result.
7996
7997 proc check_effective_target_vect_widen_sum_hi_to_si { } {
7998 return [check_cached_effective_target_indexed vect_widen_sum_hi_to_si {
7999 expr { [check_effective_target_vect_unpack]
8000 || [istarget powerpc*-*-*]
8001 || [istarget ia64-*-*]
8002 || [istarget loongarch*-*-*]
8003 || [istarget riscv*-*-*] }}]
8004 }
8005
8006 # Return 1 if the target plus current options supports a vector
8007 # widening summation of *char* args into *short* result, 0 otherwise.
8008 # A target can also support this widening summation if it can support
8009 # promotion (unpacking) from chars to shorts.
8010 #
8011 # This won't change for different subtargets so cache the result.
8012
8013 proc check_effective_target_vect_widen_sum_qi_to_hi { } {
8014 return [check_cached_effective_target_indexed vect_widen_sum_qi_to_hi {
8015 expr { [check_effective_target_vect_unpack]
8016 || [is-effective-target arm_neon]
8017 || [istarget ia64-*-*]
8018 || [istarget riscv*-*-*]
8019 || [istarget loongarch*-*-*] }}]
8020 }
8021
8022 # Return 1 if the target plus current options supports a vector
8023 # widening summation of *char* args into *int* result, 0 otherwise.
8024 #
8025 # This won't change for different subtargets so cache the result.
8026
8027 proc check_effective_target_vect_widen_sum_qi_to_si { } {
8028 return [check_cached_effective_target_indexed vect_widen_sum_qi_to_si {
8029 expr { [istarget powerpc*-*-*]
8030 || [istarget loongarch*-*-*]
8031 || [istarget riscv*-*-*] }}]
8032 }
8033
8034 # Return 1 if the target plus current options supports a vector
8035 # widening multiplication of *char* args into *short* result, 0 otherwise.
8036 # A target can also support this widening multplication if it can support
8037 # promotion (unpacking) from chars to shorts, and vect_short_mult (non-widening
8038 # multiplication of shorts).
8039 #
8040 # This won't change for different subtargets so cache the result.
8041
8042
8043 proc check_effective_target_vect_widen_mult_qi_to_hi { } {
8044 return [check_cached_effective_target_indexed vect_widen_mult_qi_to_hi {
8045 expr { ([check_effective_target_vect_unpack]
8046 && [check_effective_target_vect_short_mult])
8047 || ([istarget powerpc*-*-*]
8048 || ([istarget aarch64*-*-*]
8049 && ![check_effective_target_aarch64_sve])
8050 || [is-effective-target arm_neon]
8051 || ([istarget s390*-*-*]
8052 && [check_effective_target_s390_vx]))
8053 || [istarget amdgcn-*-*] }}]
8054 }
8055
8056 # Return 1 if the target plus current options supports a vector
8057 # widening multiplication of *short* args into *int* result, 0 otherwise.
8058 # A target can also support this widening multplication if it can support
8059 # promotion (unpacking) from shorts to ints, and vect_int_mult (non-widening
8060 # multiplication of ints).
8061 #
8062 # This won't change for different subtargets so cache the result.
8063
8064
8065 proc check_effective_target_vect_widen_mult_hi_to_si { } {
8066 return [check_cached_effective_target_indexed vect_widen_mult_hi_to_si {
8067 expr { ([check_effective_target_vect_unpack]
8068 && [check_effective_target_vect_int_mult])
8069 || ([istarget powerpc*-*-*]
8070 || [istarget ia64-*-*]
8071 || ([istarget aarch64*-*-*]
8072 && ![check_effective_target_aarch64_sve])
8073 || [istarget i?86-*-*] || [istarget x86_64-*-*]
8074 || [is-effective-target arm_neon]
8075 || ([istarget s390*-*-*]
8076 && [check_effective_target_s390_vx]))
8077 || [istarget amdgcn-*-*] }}]
8078 }
8079
8080 # Return 1 if the target plus current options supports a vector
8081 # widening multiplication of *char* args into *short* result, 0 otherwise.
8082 #
8083 # This won't change for different subtargets so cache the result.
8084
8085 proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } {
8086 return [check_cached_effective_target_indexed vect_widen_mult_qi_to_hi_pattern {
8087 expr { [istarget powerpc*-*-*]
8088 || ([is-effective-target arm_neon]
8089 && [check_effective_target_arm_little_endian])
8090 || ([istarget s390*-*-*]
8091 && [check_effective_target_s390_vx])
8092 || [istarget loongarch*-*-*]
8093 || [istarget amdgcn-*-*] }}]
8094 }
8095
8096 # Return 1 if the target plus current options supports a vector
8097 # widening multiplication of *short* args into *int* result, 0 otherwise.
8098 #
8099 # This won't change for different subtargets so cache the result.
8100
8101 proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } {
8102 return [check_cached_effective_target_indexed vect_widen_mult_hi_to_si_pattern {
8103 expr { [istarget powerpc*-*-*]
8104 || [istarget ia64-*-*]
8105 || [istarget loongarch*-*-*]
8106 || [istarget i?86-*-*] || [istarget x86_64-*-*]
8107 || ([is-effective-target arm_neon]
8108 && [check_effective_target_arm_little_endian])
8109 || ([istarget s390*-*-*]
8110 && [check_effective_target_s390_vx])
8111 || [istarget amdgcn-*-*] }}]
8112 }
8113
8114 # Return 1 if the target plus current options supports a vector
8115 # widening multiplication of *int* args into *long* result, 0 otherwise.
8116 #
8117 # This won't change for different subtargets so cache the result.
8118
8119 proc check_effective_target_vect_widen_mult_si_to_di_pattern { } {
8120 return [check_cached_effective_target_indexed vect_widen_mult_si_to_di_pattern {
8121 expr { [istarget ia64-*-*]
8122 || [istarget i?86-*-*] || [istarget x86_64-*-*]
8123 || [istarget loongarch*-*-*]
8124 || ([istarget s390*-*-*]
8125 && [check_effective_target_s390_vx]) }}]
8126 }
8127
8128 # Return 1 if the target plus current options supports a vector
8129 # widening shift, 0 otherwise.
8130 #
8131 # This won't change for different subtargets so cache the result.
8132
8133 proc check_effective_target_vect_widen_shift { } {
8134 return [check_cached_effective_target_indexed vect_widen_shift {
8135 expr { [is-effective-target arm_neon] }}]
8136 }
8137
8138 # Return 1 if the target plus current options supports a vector
8139 # dot-product of signed chars, 0 otherwise.
8140 #
8141 # This won't change for different subtargets so cache the result.
8142
8143 proc check_effective_target_vect_sdot_qi { } {
8144 return [check_cached_effective_target_indexed vect_sdot_qi {
8145 expr { [istarget ia64-*-*]
8146 || [istarget aarch64*-*-*]
8147 || [istarget arm*-*-*]
8148 || ([istarget mips*-*-*]
8149 && [et-is-effective-target mips_msa])
8150 || ([istarget riscv*-*-*]
8151 && [check_effective_target_riscv_v])
8152 || ([istarget loongarch*-*-*]
8153 && [check_effective_target_loongarch_sx]) }}]
8154 }
8155
8156 # Return 1 if the target plus current options supports a vector
8157 # dot-product of unsigned chars, 0 otherwise.
8158 #
8159 # This won't change for different subtargets so cache the result.
8160
8161 proc check_effective_target_vect_udot_qi { } {
8162 return [check_cached_effective_target_indexed vect_udot_qi {
8163 expr { [istarget powerpc*-*-*]
8164 || [istarget aarch64*-*-*]
8165 || [istarget arm*-*-*]
8166 || [istarget ia64-*-*]
8167 || ([istarget mips*-*-*]
8168 && [et-is-effective-target mips_msa])
8169 || ([istarget riscv*-*-*]
8170 && [check_effective_target_riscv_v])
8171 || ([istarget loongarch*-*-*]
8172 && [check_effective_target_loongarch_sx]) }}]
8173 }
8174
8175 # Return 1 if the target plus current options supports a vector
8176 # dot-product where one operand of the multiply is signed char
8177 # and the other unsigned chars, 0 otherwise.
8178 #
8179 # This won't change for different subtargets so cache the result.
8180
8181 proc check_effective_target_vect_usdot_qi { } {
8182 return [check_cached_effective_target_indexed vect_usdot_qi {
8183 expr { [istarget aarch64*-*-*]
8184 || [istarget arm*-*-*] }}]
8185 }
8186
8187
8188 # Return 1 if the target plus current options supports a vector
8189 # dot-product of signed shorts, 0 otherwise.
8190 #
8191 # This won't change for different subtargets so cache the result.
8192
8193 proc check_effective_target_vect_sdot_hi { } {
8194 return [check_cached_effective_target_indexed vect_sdot_hi {
8195 expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
8196 || [istarget ia64-*-*]
8197 || [istarget i?86-*-*] || [istarget x86_64-*-*]
8198 || ([istarget mips*-*-*]
8199 && [et-is-effective-target mips_msa])
8200 || ([istarget riscv*-*-*]
8201 && [check_effective_target_riscv_v])
8202 || ([istarget loongarch*-*-*]
8203 && [check_effective_target_loongarch_sx]) }}]
8204 }
8205
8206 # Return 1 if the target plus current options supports a vector
8207 # dot-product of unsigned shorts, 0 otherwise.
8208 #
8209 # This won't change for different subtargets so cache the result.
8210
8211 proc check_effective_target_vect_udot_hi { } {
8212 return [check_cached_effective_target_indexed vect_udot_hi {
8213 expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
8214 || ([istarget mips*-*-*]
8215 && [et-is-effective-target mips_msa])
8216 || ([istarget riscv*-*-*]
8217 && [check_effective_target_riscv_v])
8218 || ([istarget loongarch*-*-*]
8219 && [check_effective_target_loongarch_sx]) }}]
8220 }
8221
8222 # Return 1 if the target plus current options supports a vector
8223 # sad operation of unsigned chars, 0 otherwise.
8224 #
8225 # This won't change for different subtargets so cache the result.
8226
8227 proc check_effective_target_vect_usad_char { } {
8228 return [check_cached_effective_target_indexed vect_usad_char {
8229 expr { [istarget i?86-*-*]
8230 || [istarget x86_64-*-*]
8231 || ([istarget aarch64*-*-*]
8232 && ![check_effective_target_aarch64_sve])
8233 || ([istarget powerpc*-*-*]
8234 && [check_p9vector_hw_available])
8235 || ([istarget riscv*-*-*]
8236 && [check_effective_target_riscv_v])
8237 || ([istarget loongarch*-*-*]
8238 && [check_effective_target_loongarch_sx]) }}]
8239 }
8240
8241 # Return 1 if the target plus current options supports both signed
8242 # and unsigned average operations on vectors of bytes.
8243
8244 proc check_effective_target_vect_avg_qi {} {
8245 return [expr { ([istarget aarch64*-*-*]
8246 && ![check_effective_target_aarch64_sve1_only])
8247 || ([istarget riscv*-*-*]
8248 && [check_effective_target_riscv_v])
8249 || ([istarget loongarch*-*-*]
8250 && [check_effective_target_loongarch_sx]) }]
8251 }
8252
8253 # Return 1 if the target plus current options supports both signed
8254 # and unsigned multiply-high-with-round-and-scale operations
8255 # on vectors of half-words.
8256
8257 proc check_effective_target_vect_mulhrs_hi {} {
8258 return [expr { [istarget aarch64*-*-*]
8259 && [check_effective_target_aarch64_sve2] }]
8260 }
8261
8262 # Return 1 if the target plus current options supports signed division
8263 # by power-of-2 operations on vectors of 4-byte integers.
8264
8265 proc check_effective_target_vect_sdiv_pow2_si {} {
8266 return [expr { ([istarget aarch64*-*-*]
8267 && [check_effective_target_aarch64_sve]) }]
8268 }
8269
8270 # Return 1 if the target plus current options supports a vector
8271 # demotion (packing) of shorts (to chars) and ints (to shorts)
8272 # using modulo arithmetic, 0 otherwise.
8273 #
8274 # This won't change for different subtargets so cache the result.
8275
8276 proc check_effective_target_vect_pack_trunc { } {
8277 return [check_cached_effective_target_indexed vect_pack_trunc {
8278 expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
8279 || [istarget i?86-*-*] || [istarget x86_64-*-*]
8280 || [istarget aarch64*-*-*]
8281 || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]
8282 && [check_effective_target_arm_little_endian])
8283 || ([istarget mips*-*-*]
8284 && [et-is-effective-target mips_msa])
8285 || ([istarget s390*-*-*]
8286 && [check_effective_target_s390_vx])
8287 || [istarget amdgcn*-*-*]
8288 || ([istarget riscv*-*-*]
8289 && [check_effective_target_riscv_v])
8290 || ([istarget loongarch*-*-*]
8291 && [check_effective_target_loongarch_sx]) }}]
8292 }
8293
8294 # Return 1 if the target plus current options supports a vector
8295 # promotion (unpacking) of chars (to shorts) and shorts (to ints), 0 otherwise.
8296 #
8297 # This won't change for different subtargets so cache the result.
8298
8299 proc check_effective_target_vect_unpack { } {
8300 return [check_cached_effective_target_indexed vect_unpack {
8301 expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*])
8302 || [istarget i?86-*-*] || [istarget x86_64-*-*]
8303 || [istarget ia64-*-*]
8304 || [istarget aarch64*-*-*]
8305 || ([istarget mips*-*-*]
8306 && [et-is-effective-target mips_msa])
8307 || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]
8308 && [check_effective_target_arm_little_endian])
8309 || ([istarget s390*-*-*]
8310 && [check_effective_target_s390_vx])
8311 || [istarget amdgcn*-*-*]
8312 || ([istarget riscv*-*-*]
8313 && [check_effective_target_riscv_v])
8314 || ([istarget loongarch*-*-*]
8315 && [check_effective_target_loongarch_sx]) }}]
8316 }
8317
8318 # Return 1 if the target plus current options does not guarantee
8319 # that its STACK_BOUNDARY is >= the reguired vector alignment.
8320 #
8321 # This won't change for different subtargets so cache the result.
8322
8323 proc check_effective_target_unaligned_stack { } {
8324 return [check_cached_effective_target_indexed unaligned_stack { expr 0 }]
8325 }
8326
8327 # Return 1 if the target plus current options does not support a vector
8328 # alignment mechanism, 0 otherwise.
8329 #
8330 # This won't change for different subtargets so cache the result.
8331
8332 proc check_effective_target_vect_no_align { } {
8333 return [check_cached_effective_target_indexed vect_no_align {
8334 expr { [istarget mipsisa64*-*-*]
8335 || [istarget mips-sde-elf]
8336 || [istarget sparc*-*-*]
8337 || [istarget ia64-*-*]
8338 || [check_effective_target_arm_vect_no_misalign]
8339 || ([istarget powerpc*-*-*] && [check_p8vector_hw_available])
8340 || ([istarget mips*-*-*]
8341 && [et-is-effective-target mips_loongson_mmi]) }}]
8342 }
8343
8344 # Return 1 if the target supports a vector misalign access, 0 otherwise.
8345 #
8346 # This won't change for different subtargets so cache the result.
8347
8348 proc check_effective_target_vect_hw_misalign { } {
8349 return [check_cached_effective_target_indexed vect_hw_misalign {
8350 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
8351 || ([istarget powerpc*-*-*] && [check_p8vector_hw_available])
8352 || [istarget aarch64*-*-*]
8353 || ([istarget mips*-*-*] && [et-is-effective-target mips_msa])
8354 || ([istarget s390*-*-*]
8355 && [check_effective_target_s390_vx])
8356 || ([istarget riscv*-*-*])
8357 || ([istarget loongarch*-*-*]) } {
8358 return 1
8359 }
8360 if { [istarget arm*-*-*]
8361 && ![check_effective_target_arm_vect_no_misalign] } {
8362 return 1
8363 }
8364 return 0
8365 }]
8366 }
8367
8368
8369 # Return 1 if arrays are aligned to the vector alignment
8370 # boundary, 0 otherwise.
8371
8372 proc check_effective_target_vect_aligned_arrays { } {
8373 set et_vect_aligned_arrays 0
8374 if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
8375 && !([is-effective-target ia32]
8376 || ([check_avx_available] && ![check_prefer_avx128]))) } {
8377 set et_vect_aligned_arrays 1
8378 }
8379
8380 verbose "check_effective_target_vect_aligned_arrays:\
8381 returning $et_vect_aligned_arrays" 2
8382 return $et_vect_aligned_arrays
8383 }
8384
8385 # Return 1 if the biggest alignment required by target is 1 * BITS_PER_UNIT.
8386 # In such case the target does not impose any alignment constraints.
8387
8388 proc check_effective_target_no_alignment_constraints { } {
8389 return [check_runtime_nocache no_alignment_constraints {
8390 int
8391 main (void)
8392 {
8393 return __BIGGEST_ALIGNMENT__ == 1 ? 0 : 1;
8394 }
8395 }]
8396 }
8397
8398 # Return 1 if types of size 32 bit or less are naturally aligned
8399 # (aligned to their type-size), 0 otherwise.
8400 #
8401 # This won't change for different subtargets so cache the result.
8402
8403 proc check_effective_target_natural_alignment_32 { } {
8404 # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER.
8405 # FIXME: m68k has -malign-int
8406 return [check_cached_effective_target_indexed natural_alignment_32 {
8407 if { ([istarget *-*-darwin*] && [is-effective-target lp64])
8408 || [istarget avr-*-*]
8409 || [istarget m68k-*-linux*]
8410 || [istarget pru-*-*]
8411 || [istarget stormy16-*-*]
8412 || [istarget rl78-*-*]
8413 || [istarget pdp11-*-*]
8414 || [istarget msp430-*-*]
8415 || [istarget m32c-*-*]
8416 || [istarget cris-*-*] } {
8417 return 0
8418 } else {
8419 return 1
8420 }
8421 }]
8422 }
8423
8424 # Return 1 if types of size 64 bit or less are naturally aligned (aligned to their
8425 # type-size), 0 otherwise.
8426 #
8427 # This won't change for different subtargets so cache the result.
8428
8429 proc check_effective_target_natural_alignment_64 { } {
8430 return [check_cached_effective_target_indexed natural_alignment_64 {
8431 expr { [is-effective-target natural_alignment_32]
8432 && [is-effective-target lp64] && ![istarget *-*-darwin*] }
8433 }]
8434 }
8435
8436 # Return 1 if all vector types are naturally aligned (aligned to their
8437 # type-size), 0 otherwise.
8438
8439 proc check_effective_target_vect_natural_alignment { } {
8440 set et_vect_natural_alignment 1
8441 if { [check_effective_target_arm_eabi]
8442 || [istarget nvptx-*-*]
8443 || [istarget s390*-*-*]
8444 || [istarget amdgcn-*-*] } {
8445 set et_vect_natural_alignment 0
8446 }
8447 verbose "check_effective_target_vect_natural_alignment:\
8448 returning $et_vect_natural_alignment" 2
8449 return $et_vect_natural_alignment
8450 }
8451
8452 # Return true if the target supports the check_raw_ptrs and check_war_ptrs
8453 # optabs on vectors.
8454
8455 proc check_effective_target_vect_check_ptrs { } {
8456 return [check_effective_target_aarch64_sve2]
8457 }
8458
8459 # Return true if fully-masked loops are supported.
8460
8461 proc check_effective_target_vect_fully_masked { } {
8462 return [expr { [check_effective_target_aarch64_sve]
8463 || [istarget amdgcn*-*-*]
8464 || [check_effective_target_riscv_v] }]
8465 }
8466
8467 # Return true if the target supports the @code{len_load} and
8468 # @code{len_store} optabs.
8469
8470 proc check_effective_target_vect_len_load_store { } {
8471 return [expr { [check_effective_target_has_arch_pwr9]
8472 || [check_effective_target_s390_vx]
8473 || [check_effective_target_riscv_v] }]
8474 }
8475
8476 # Return the value of parameter vect-partial-vector-usage specified for
8477 # target by checking the output of "-Q --help=params". Return zero if
8478 # the desirable pattern isn't found.
8479
8480 proc check_vect_partial_vector_usage { } {
8481 global tool
8482
8483 return [check_cached_effective_target vect_partial_vector_usage {
8484 set result [check_compile vect_partial_vector_usage assembly {
8485 int i;
8486 } "-Q --help=params" ]
8487
8488 # Get compiler emitted messages and delete generated file.
8489 set lines [lindex $result 0]
8490 set output [lindex $result 1]
8491 remote_file build delete $output
8492
8493 set pattern {=vect-partial-vector-usage=<0,2>\s+([0-2])}
8494 # Capture the usage value to val, set it to zero if not found.
8495 if { ![regexp $pattern $lines whole val] } then {
8496 set val 0
8497 }
8498
8499 return $val
8500 }]
8501 }
8502
8503 # Return true if the target supports loop vectorization with partial vectors
8504 # and @code{vect-partial-vector-usage} is set to 1.
8505
8506 proc check_effective_target_vect_partial_vectors_usage_1 { } {
8507 return [expr { ([check_effective_target_vect_fully_masked]
8508 || [check_effective_target_vect_len_load_store])
8509 && [check_vect_partial_vector_usage] == 1 }]
8510 }
8511
8512 # Return true if the target supports loop vectorization with partial vectors
8513 # and @code{vect-partial-vector-usage} is set to 2.
8514
8515 proc check_effective_target_vect_partial_vectors_usage_2 { } {
8516 return [expr { ([check_effective_target_vect_fully_masked]
8517 || [check_effective_target_vect_len_load_store])
8518 && [check_vect_partial_vector_usage] == 2 }]
8519 }
8520
8521 # Return true if the target supports loop vectorization with partial vectors
8522 # and @code{vect-partial-vector-usage} is nonzero.
8523
8524 proc check_effective_target_vect_partial_vectors { } {
8525 return [expr { ([check_effective_target_vect_fully_masked]
8526 || [check_effective_target_vect_len_load_store])
8527 && [check_vect_partial_vector_usage] != 0 }]
8528 }
8529
8530 # Return 1 if the target doesn't prefer any alignment beyond element
8531 # alignment during vectorization.
8532
8533 proc check_effective_target_vect_element_align_preferred { } {
8534 return [expr { ([check_effective_target_aarch64_sve]
8535 && [check_effective_target_vect_variable_length])
8536 || [check_effective_target_riscv_v] }]
8537 }
8538
8539 # Return true if vectorization of v2qi/v4qi/v8qi/v16qi/v2hi store is enabed.
8540 # Return zero if the desirable pattern isn't found.
8541 # It's used by Warray-bounds/Wstringop-overflow testcases which are
8542 # regressed by O2 vectorization, refer to PR102697/PR102462/PR102706
8543 proc check_vect_slp_store_usage { pattern macro } {
8544 global tool
8545
8546 set result [check_compile slp_aligned_store_usage assembly {
8547 extern void sink (void* );
8548 #define Ac8 (AC8){ 0, 1, 2, 3, 4, 5, 6, 7 }
8549 #define Ac16 (AC16){ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }
8550 #ifdef TEST_V16QI
8551 typedef struct AC16 { char a[16]; } AC16;
8552 extern char a16[16];
8553 void
8554 foo1 ()
8555 {
8556 *(AC16*)a16 = Ac16;
8557 }
8558 #elif TEST_V8QI
8559 typedef struct AC8 { char a[8]; } AC8;
8560 extern char a8[8];
8561 void
8562 foo ()
8563 {
8564 *(AC8*)a8 = Ac8;
8565 }
8566 #elif TEST_V4QI
8567 struct A1
8568 {
8569 char n;
8570 char a[3];
8571 };
8572
8573 extern void sink (void*);
8574 void
8575 foo2 ()
8576 {
8577 struct A1 a = { 0, { } };
8578 a.a[0] = 3;
8579 a.a[1] = 4;
8580 a.a[2] = 5;
8581 sink (&a);
8582 }
8583 #elif TEST_V4QI_2
8584 extern char p[4];
8585 void
8586 foo2_2 ()
8587 {
8588 p[0] = 0;
8589 p[1] = 1;
8590 p[2] = 2;
8591 p[3] = 3;
8592 }
8593 #elif TEST_V4QI_3
8594 #define Ac4 (AC4){ 0, 1, 2, 3 }
8595 typedef struct AC4 { char a[4]; } AC4;
8596 extern char a[4];
8597 void
8598 foo ()
8599 {
8600 *(AC4*)a = Ac4;
8601 }
8602 #elif TEST_V2QI
8603 struct A2
8604 {
8605 char a[2];
8606 };
8607 void
8608 foo3 ()
8609 {
8610 struct A2 a;
8611 a.a[0] = 3;
8612 a.a[1] = 4;
8613 sink (&a);
8614 }
8615 #elif TEST_V2QI_2
8616 extern char p[2];
8617 void
8618 foo3_2 ()
8619 {
8620 p[0] = 0;
8621 p[1] = 1;
8622 }
8623 #elif TEST_V4HI
8624 struct Ax
8625 {
8626 int n;
8627 short a[4];
8628 };
8629 void
8630 foo5 (struct Ax *p)
8631 {
8632 p->a[0] = 0;
8633 p->a[1] = 1;
8634 p->a[2] = 2;
8635 p->a[3] = 3;
8636 }
8637 #elif TEST_V2HI
8638 extern char b[4];
8639 void
8640 foo4 ()
8641 {
8642 *(short*) b = 0;
8643 *(short*) (b + 2) = 1;
8644 }
8645 #elif TEST_V2HI_2
8646 struct Ax
8647 {
8648 int n;
8649 short a[2];
8650 };
8651 void
8652 foo4_2 (struct Ax *p)
8653 {
8654 p->a[0] = 0;
8655 p->a[1] = 1;
8656 }
8657 #elif TEST_V4SI
8658 struct A { int i; };
8659 struct B { int j; struct A a[4]; };
8660
8661 struct C
8662 {
8663 struct B b1;
8664 struct B b2;
8665 };
8666 char cbuf2[2 * sizeof (struct C)] = { };
8667 void
8668 foo6 ()
8669 {
8670 struct C *p = (struct C*)&cbuf2;
8671 p->b2.a[0].i = 0;
8672 p->b2.a[1].i = 0;
8673 p->b2.a[2].i = 0;
8674 p->b2.a[3].i = 0;
8675 }
8676 #elif TEST_V2SI
8677 struct A { int i; };
8678 struct B { int j; struct A a[2]; };
8679
8680 struct C
8681 {
8682 struct B b1;
8683 struct B b2;
8684 };
8685 char cbuf2[2 * sizeof (struct C)] = { };
8686 void
8687 foo6 ()
8688 {
8689 struct C *p = (struct C*)&cbuf2;
8690 p->b2.a[0].i = 0;
8691 p->b2.a[1].i = 0;
8692 }
8693
8694 #endif
8695 } "-O2 -fopt-info-all -D$macro" ]
8696
8697 # Get compiler emitted messages and delete generated file.
8698 set lines [lindex $result 0]
8699 set output [lindex $result 1]
8700 remote_file build delete $output
8701
8702 # Check pattern exits in lines, set it to zero if not found.
8703 if { [regexp $pattern $lines] } then {
8704 return 1
8705 }
8706
8707 return 0
8708 }
8709
8710 # Return the true if target support vectorization of 2-byte char stores
8711 # with 2-byte aligned address at plain O2.
8712 # NB: This target should be removed after real issues are fixed for
8713 # -Wstringop-overflow with O2 vect. Be careful if you want to reuse
8714 # this target since tests in check_vect_slp_store_usage
8715 # is the exact match of relative testcases
8716 proc check_effective_target_vect_slp_v2qi_store_align { } {
8717 set pattern {add new stmt: MEM <vector\(2\) char>}
8718 set macro "TEST_V2QI"
8719 return [check_cached_effective_target vect_slp_v2qi_store_align {
8720 expr [check_vect_slp_store_usage $pattern $macro] }]
8721 }
8722
8723 # Return the true if target support vectorization of 2-byte char stores
8724 # with unaligned address at plain O2.
8725 proc check_effective_target_vect_slp_v2qi_store_unalign { } {
8726 set pattern {add new stmt: MEM <vector\(2\) char>}
8727 set macro "TEST_V2QI_2"
8728 return [check_cached_effective_target vect_slp_v2qi_store_unalign {
8729 expr [check_vect_slp_store_usage $pattern $macro ] }]
8730 }
8731
8732 # Return the true if target support vectorization of 4-byte char stores
8733 # with 4-byte aligned address at plain O2.
8734 # NB: This target should be removed after real issues are fixed for
8735 # -Wstringop-overflow with O2 vect. Be careful if you want to reuse
8736 # this target since tests in check_vect_slp_store_usage
8737 # is the exact match of relative testcases
8738 proc check_effective_target_vect_slp_v4qi_store_align { } {
8739 set pattern {add new stmt: MEM <vector\(4\) char>}
8740 set macro "TEST_V4QI"
8741 return [check_cached_effective_target vect_slp_v4qi_store_align {
8742 expr [check_vect_slp_store_usage $pattern $macro ] }]
8743 }
8744
8745 # Return the true if target support vectorization of 4-byte char stores
8746 # with unaligned address at plain O2.
8747 proc check_effective_target_vect_slp_v4qi_store_unalign { } {
8748 set pattern {add new stmt: MEM <vector\(4\) char>}
8749 set macro "TEST_V4QI_2"
8750 return [check_cached_effective_target vect_slp_v4qi_store_unalign {
8751 expr [check_vect_slp_store_usage $pattern $macro ] }]
8752 }
8753
8754 # Return the true if target support block move for
8755 # 8-byte aligned 4-byte size struct initialization.
8756 proc check_effective_target_struct_4char_block_move { } {
8757 set pattern {not vectorized: more than one data ref in stmt:}
8758 set macro "TEST_V4QI_3"
8759 return [check_cached_effective_target struct_4char_block_move {
8760 expr [check_vect_slp_store_usage $pattern $macro ] }]
8761 }
8762
8763 # Return the true if target support vectorization of 4-byte char stores
8764 # with unaligned address or store them with a constant pool at plain O2.
8765 proc check_effective_target_vect_slp_v4qi_store_unalign_1 { } {
8766 set pattern {add new stmt: MEM <vector\(4\) char>}
8767 set macro "TEST_V4QI_3"
8768 return [check_cached_effective_target vect_slp_v4qi_store_unalign_1 {
8769 expr { [check_vect_slp_store_usage $pattern $macro ]
8770 || [check_effective_target_struct_4char_block_move] } }]
8771 }
8772
8773 # Return the true if target support block move for
8774 # 8-byte aligned 8-byte size struct initialization.
8775 proc check_effective_target_struct_8char_block_move { } {
8776 set pattern {not vectorized: more than one data ref in stmt:}
8777 set macro "TEST_V8QI"
8778 return [check_cached_effective_target struct_8char_block_move {
8779 expr [check_vect_slp_store_usage $pattern $macro ] }]
8780 }
8781
8782 # Return the true if target support vectorization of 8-byte char stores
8783 # with unaligned address or store them with a constant pool at plain O2.
8784 # NB: This target should be removed after real issues are fixed for
8785 # -Wstringop-overflow with O2 vect. Be careful if you want to reuse
8786 # this target since tests in check_vect_slp_store_usage
8787 # is the exact match of relative testcases
8788 proc check_effective_target_vect_slp_v8qi_store_unalign_1 { } {
8789 set pattern {add new stmt: MEM <vector\(8\) char>}
8790 set macro "TEST_V8QI"
8791 return [check_cached_effective_target vect_slp_v8qi_store_unalign_1 {
8792 expr { [check_vect_slp_store_usage $pattern $macro ]
8793 || [check_effective_target_struct_8char_block_move] } }]
8794 }
8795
8796 # Return the true if target support block move for
8797 # 8-byte aligned 16-byte size struct initialization.
8798 proc check_effective_target_struct_16char_block_move { } {
8799 set pattern {not vectorized: more than one data ref in stmt:}
8800 set macro "TEST_V16QI"
8801 return [check_cached_effective_target struct_16char_block_move {
8802 expr [check_vect_slp_store_usage $pattern $macro ] }]
8803 }
8804
8805 # Return the true if target support vectorization of 16-byte char stores
8806 # with unaligned address or store them with a constant pool at plain O2.
8807 # NB: This target should be removed after real issues are fixed for
8808 # -Wstringop-overflow with O2 vect. Be careful if you want to reuse
8809 # this target since tests in check_vect_slp_store_usage
8810 # is the exact match of relative testcases
8811 proc check_effective_target_vect_slp_v16qi_store_unalign_1 { } {
8812 set pattern {add new stmt: MEM <vector\(16\) char>}
8813 set macro "TEST_V16QI"
8814 return [check_cached_effective_target vect_slp_v16qi_store_unalign_1 {
8815 expr { [check_vect_slp_store_usage $pattern $macro ]
8816 || [check_effective_target_struct_16char_block_move] } }]
8817 }
8818
8819 # Return the true if target support vectorization of 4-byte short stores
8820 # with unaligned address at plain O2.
8821 # NB: This target should be removed after real issues are fixed for
8822 # -Wstringop-overflow with O2 vect. Be careful if you want to reuse
8823 # this target since tests in check_vect_slp_store_usage
8824 # is the exact match of relative testcases
8825 proc check_effective_target_vect_slp_v2hi_store_unalign { } {
8826 set pattern {add new stmt: MEM <vector\(2\) short int>}
8827 set macro "TEST_V2HI"
8828 return [check_cached_effective_target vect_slp_v2hi_store_unalign {
8829 expr [check_vect_slp_store_usage $pattern $macro ] }]
8830 }
8831
8832 # Return the true if target support vectorization of 4-byte short stores
8833 # with 4-byte aligned address at plain O2.
8834 proc check_effective_target_vect_slp_v2hi_store_align { } {
8835 set pattern {add new stmt: MEM <vector\(2\) short int>}
8836 set macro "TEST_V2HI_2"
8837 return [check_cached_effective_target vect_slp_v2hi_store_align {
8838 expr [check_vect_slp_store_usage $pattern $macro ] }]
8839 }
8840
8841 # Return the true if target support vectorization of 8-byte short stores
8842 # with unaligned address at plain O2.
8843 # NB: This target should be removed after real issues are fixed for
8844 # -Wstringop-overflow with O2 vect. Be careful if you want to reuse
8845 # this target since tests in check_vect_slp_store_usage
8846 # is the exact match of relative testcases
8847 proc check_effective_target_vect_slp_v4hi_store_unalign { } {
8848 set pattern {add new stmt: MEM <vector\(4\) short int>}
8849 set macro "TEST_V4HI"
8850 return [check_cached_effective_target vect_slp_v4hi_store_unalign {
8851 expr [check_vect_slp_store_usage $pattern $macro ] }]
8852 }
8853
8854 # Return the true if target support vectorization of 8-byte int stores
8855 # with 8-byte aligned address at plain O2.
8856 # NB: This target should be removed after real issues are fixed for
8857 # -Wstringop-overflow with O2 vect. Be careful if you want to reuse
8858 # this target since tests in check_vect_slp_store_usage
8859 # is the exact match of relative testcases
8860 proc check_effective_target_vect_slp_v2si_store_align { } {
8861 set pattern {add new stmt: MEM <vector\(2\) int>}
8862 set macro "TEST_V2SI"
8863 return [check_cached_effective_target vect_slp_v2si_store_align {
8864 expr [check_vect_slp_store_usage $pattern $macro ] }]
8865 }
8866
8867 # Return the true if target support vectorization of 16-byte int stores
8868 # with unaligned address at plain O2.
8869 # NB: This target should be removed after real issues are fixed for
8870 # -Wstringop-overflow with O2 vect. Be careful if you want to reuse
8871 # this target since tests in check_vect_slp_store_usage
8872 # is the exact match of relative testcases
8873 proc check_effective_target_vect_slp_v4si_store_unalign { } {
8874 set pattern {add new stmt: MEM <vector\(4\) int>}
8875 set macro "TEST_V4SI"
8876 return [check_cached_effective_target vect_slp_v4si_store_unalign {
8877 expr [check_vect_slp_store_usage $pattern $macro ] }]
8878 }
8879
8880 # Return 1 if we can align stack data to the preferred vector alignment.
8881
8882 proc check_effective_target_vect_align_stack_vars { } {
8883 if { [check_effective_target_aarch64_sve] } {
8884 return [check_effective_target_vect_variable_length]
8885 }
8886 return 1
8887 }
8888
8889 # Return 1 if vector alignment (for types of size 32 bit or less) is reachable, 0 otherwise.
8890
8891 proc check_effective_target_vector_alignment_reachable { } {
8892 set et_vector_alignment_reachable 0
8893 if { [check_effective_target_vect_aligned_arrays]
8894 || [check_effective_target_natural_alignment_32] } {
8895 set et_vector_alignment_reachable 1
8896 }
8897 verbose "check_effective_target_vector_alignment_reachable:\
8898 returning $et_vector_alignment_reachable" 2
8899 return $et_vector_alignment_reachable
8900 }
8901
8902 # Return 1 if vector alignment for 64 bit is reachable, 0 otherwise.
8903
8904 proc check_effective_target_vector_alignment_reachable_for_64bit { } {
8905 set et_vector_alignment_reachable_for_64bit 0
8906 if { [check_effective_target_vect_aligned_arrays]
8907 || [check_effective_target_natural_alignment_64] } {
8908 set et_vector_alignment_reachable_for_64bit 1
8909 }
8910 verbose "check_effective_target_vector_alignment_reachable_for_64bit:\
8911 returning $et_vector_alignment_reachable_for_64bit" 2
8912 return $et_vector_alignment_reachable_for_64bit
8913 }
8914
8915 # Return 1 if the target only requires element alignment for vector accesses
8916
8917 proc check_effective_target_vect_element_align { } {
8918 return [check_cached_effective_target_indexed vect_element_align {
8919 expr { ([istarget arm*-*-*]
8920 && ![check_effective_target_arm_vect_no_misalign])
8921 || [check_effective_target_vect_hw_misalign]
8922 || [istarget amdgcn-*-*] }}]
8923 }
8924
8925 # Return 1 if we expect to see unaligned accesses in at least some
8926 # vector dumps.
8927
8928 proc check_effective_target_vect_unaligned_possible { } {
8929 return [expr { ![check_effective_target_vect_element_align_preferred]
8930 && (![check_effective_target_vect_no_align]
8931 || [check_effective_target_vect_hw_misalign]) }]
8932 }
8933
8934 # Return 1 if the target supports vector LOAD_LANES operations, 0 otherwise.
8935
8936 proc check_effective_target_vect_load_lanes { } {
8937 # We don't support load_lanes correctly on big-endian arm.
8938 return [check_cached_effective_target vect_load_lanes {
8939 expr { ([check_effective_target_arm_little_endian]
8940 && [check_effective_target_arm_neon_ok])
8941 || [istarget aarch64*-*-*]
8942 || [istarget riscv*-*-*] }}]
8943 }
8944
8945 # Return 1 if the target supports vector masked loads.
8946
8947 proc check_effective_target_vect_masked_load { } {
8948 return [expr { [check_avx_available]
8949 || [check_effective_target_aarch64_sve]
8950 || [istarget amdgcn*-*-*]
8951 || [check_effective_target_riscv_v] } ]
8952 }
8953
8954 # Return 1 if the target supports vector masked stores.
8955
8956 proc check_effective_target_vect_masked_store { } {
8957 return [expr { [check_avx_available]
8958 || [check_effective_target_aarch64_sve]
8959 || [istarget amdgcn*-*-*]
8960 || [check_effective_target_riscv_v] }]
8961 }
8962
8963 # Return 1 if the target supports vector gather loads via internal functions.
8964
8965 proc check_effective_target_vect_gather_load_ifn { } {
8966 return [expr { [check_effective_target_aarch64_sve]
8967 || [istarget amdgcn*-*-*]
8968 || [check_effective_target_riscv_v] }]
8969 }
8970
8971 # Return 1 if the target supports vector scatter stores.
8972
8973 proc check_effective_target_vect_scatter_store { } {
8974 return [expr { [check_effective_target_aarch64_sve]
8975 || [istarget amdgcn*-*-*]
8976 || [check_effective_target_riscv_v]
8977 || [check_effective_target_loongarch_sx] }]
8978 }
8979
8980 # Return 1 if the target supports vector conditional operations, 0 otherwise.
8981
8982 proc check_effective_target_vect_condition { } {
8983 return [check_cached_effective_target_indexed vect_condition {
8984 expr { [istarget aarch64*-*-*]
8985 || [istarget powerpc*-*-*]
8986 || [istarget ia64-*-*]
8987 || [istarget i?86-*-*] || [istarget x86_64-*-*]
8988 || ([istarget mips*-*-*]
8989 && [et-is-effective-target mips_msa])
8990 || ([istarget arm*-*-*]
8991 && [check_effective_target_arm_neon_ok])
8992 || ([istarget s390*-*-*]
8993 && [check_effective_target_s390_vx])
8994 || [istarget amdgcn-*-*]
8995 || ([istarget riscv*-*-*]
8996 && [check_effective_target_riscv_v])
8997 || ([istarget loongarch*-*-*]
8998 && [check_effective_target_loongarch_sx]) }}]
8999 }
9000
9001 # Return 1 if the target supports vector conditional operations where
9002 # the comparison has different type from the lhs, 0 otherwise.
9003
9004 proc check_effective_target_vect_cond_mixed { } {
9005 return [check_cached_effective_target_indexed vect_cond_mixed {
9006 expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
9007 || [istarget aarch64*-*-*]
9008 || [istarget powerpc*-*-*]
9009 || ([istarget arm*-*-*]
9010 && [check_effective_target_arm_neon_ok])
9011 || ([istarget mips*-*-*]
9012 && [et-is-effective-target mips_msa])
9013 || ([istarget s390*-*-*]
9014 && [check_effective_target_s390_vx])
9015 || [istarget amdgcn-*-*]
9016 || ([istarget riscv*-*-*]
9017 && [check_effective_target_riscv_v])
9018 || ([istarget loongarch*-*-*]
9019 && [check_effective_target_loongarch_sx]) }}]
9020 }
9021
9022 # Return 1 if the target supports vector char multiplication, 0 otherwise.
9023
9024 proc check_effective_target_vect_char_mult { } {
9025 return [check_cached_effective_target_indexed vect_char_mult {
9026 expr { [istarget aarch64*-*-*]
9027 || [istarget ia64-*-*]
9028 || [istarget i?86-*-*] || [istarget x86_64-*-*]
9029 || [check_effective_target_arm32]
9030 || [check_effective_target_powerpc_altivec]
9031 || ([istarget mips*-*-*]
9032 && [et-is-effective-target mips_msa])
9033 || ([istarget s390*-*-*]
9034 && [check_effective_target_s390_vx])
9035 || [istarget amdgcn-*-*]
9036 || ([istarget riscv*-*-*]
9037 && [check_effective_target_riscv_v])
9038 || ([istarget loongarch*-*-*]
9039 && [check_effective_target_loongarch_sx]) }}]
9040 }
9041
9042 # Return 1 if the target supports vector short multiplication, 0 otherwise.
9043
9044 proc check_effective_target_vect_short_mult { } {
9045 return [check_cached_effective_target_indexed vect_short_mult {
9046 expr { [istarget ia64-*-*]
9047 || [istarget i?86-*-*] || [istarget x86_64-*-*]
9048 || [istarget powerpc*-*-*]
9049 || [istarget aarch64*-*-*]
9050 || [check_effective_target_arm32]
9051 || ([istarget mips*-*-*]
9052 && ([et-is-effective-target mips_msa]
9053 || [et-is-effective-target mips_loongson_mmi]))
9054 || ([istarget s390*-*-*]
9055 && [check_effective_target_s390_vx])
9056 || [istarget amdgcn-*-*]
9057 || ([istarget riscv*-*-*]
9058 && [check_effective_target_riscv_v])
9059 || ([istarget loongarch*-*-*]
9060 && [check_effective_target_loongarch_sx]) }}]
9061 }
9062
9063 # Return 1 if the target supports vector int multiplication, 0 otherwise.
9064
9065 proc check_effective_target_vect_int_mult { } {
9066 return [check_cached_effective_target_indexed vect_int_mult {
9067 expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
9068 || [istarget i?86-*-*] || [istarget x86_64-*-*]
9069 || [istarget ia64-*-*]
9070 || [istarget aarch64*-*-*]
9071 || ([istarget mips*-*-*]
9072 && [et-is-effective-target mips_msa])
9073 || [check_effective_target_arm32]
9074 || ([istarget s390*-*-*]
9075 && [check_effective_target_s390_vx])
9076 || [istarget amdgcn-*-*]
9077 || ([istarget riscv*-*-*]
9078 && [check_effective_target_riscv_v])
9079 || ([istarget loongarch*-*-*]
9080 && [check_effective_target_loongarch_sx]) }}]
9081 }
9082
9083 # Return 1 if the target supports 64 bit hardware vector
9084 # multiplication of long operands with a long result, 0 otherwise.
9085 #
9086 # This can change for different subtargets so do not cache the result.
9087
9088 proc check_effective_target_vect_long_mult { } {
9089 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
9090 || ([istarget powerpc*-*-*]
9091 && ([check_effective_target_ilp32]
9092 || ([check_effective_target_powerpc_vsx_ok]
9093 && [check_effective_target_has_arch_pwr10])))
9094 || [is-effective-target arm_neon]
9095 || ([istarget sparc*-*-*] && [check_effective_target_ilp32])
9096 || ([istarget aarch64*-*-*]
9097 && ([check_effective_target_ilp32]
9098 || [check_effective_target_aarch64_sve]))
9099 || ([istarget mips*-*-*]
9100 && [et-is-effective-target mips_msa])
9101 || ([istarget riscv*-*-*]
9102 && [check_effective_target_riscv_v])
9103 || ([istarget loongarch*-*-*]
9104 && [check_effective_target_loongarch_sx]) } {
9105 set answer 1
9106 } else {
9107 set answer 0
9108 }
9109
9110 verbose "check_effective_target_vect_long_mult: returning $answer" 2
9111 return $answer
9112 }
9113
9114 # Return 1 if the target supports vector int modulus, 0 otherwise.
9115
9116 proc check_effective_target_vect_int_mod { } {
9117 return [check_cached_effective_target_indexed vect_int_mod {
9118 expr { ([istarget powerpc*-*-*]
9119 && [check_effective_target_has_arch_pwr10])
9120 || [istarget amdgcn-*-*]
9121 || ([istarget loongarch*-*-*]
9122 && [check_effective_target_loongarch_sx])
9123 || ([istarget riscv*-*-*]
9124 && [check_effective_target_riscv_v]) }}]
9125 }
9126
9127 # Return 1 if the target supports vector even/odd elements extraction, 0 otherwise.
9128
9129 proc check_effective_target_vect_extract_even_odd { } {
9130 return [check_cached_effective_target_indexed extract_even_odd {
9131 expr { [istarget aarch64*-*-*]
9132 || [istarget powerpc*-*-*]
9133 || [is-effective-target arm_neon]
9134 || [istarget i?86-*-*] || [istarget x86_64-*-*]
9135 || [istarget ia64-*-*]
9136 || ([istarget mips*-*-*]
9137 && ([et-is-effective-target mips_msa]
9138 || [et-is-effective-target mpaired_single]))
9139 || ([istarget s390*-*-*]
9140 && [check_effective_target_s390_vx])
9141 || ([istarget riscv*-*-*]
9142 && [check_effective_target_riscv_v])
9143 || ([istarget loongarch*-*-*]
9144 && [check_effective_target_loongarch_sx]) }}]
9145 }
9146
9147 # Return 1 if the target supports vector interleaving, 0 otherwise.
9148
9149 proc check_effective_target_vect_interleave { } {
9150 return [check_cached_effective_target_indexed vect_interleave {
9151 expr { [istarget aarch64*-*-*]
9152 || [istarget powerpc*-*-*]
9153 || [is-effective-target arm_neon]
9154 || [istarget i?86-*-*] || [istarget x86_64-*-*]
9155 || [istarget ia64-*-*]
9156 || ([istarget mips*-*-*]
9157 && ([et-is-effective-target mpaired_single]
9158 || [et-is-effective-target mips_msa]))
9159 || ([istarget s390*-*-*]
9160 && [check_effective_target_s390_vx])
9161 || ([istarget riscv*-*-*]
9162 && [check_effective_target_riscv_v])
9163 || ([istarget loongarch*-*-*]
9164 && [check_effective_target_loongarch_sx]) }}]
9165 }
9166
9167 foreach N {2 3 4 5 6 7 8} {
9168 eval [string map [list N $N] {
9169 # Return 1 if the target supports 2-vector interleaving
9170 proc check_effective_target_vect_stridedN { } {
9171 return [check_cached_effective_target_indexed vect_stridedN {
9172 if { (N & -N) == N
9173 && [check_effective_target_vect_interleave]
9174 && [check_effective_target_vect_extract_even_odd] } {
9175 return 1
9176 }
9177 if { ([istarget arm*-*-*]
9178 || [istarget aarch64*-*-*]) && N >= 2 && N <= 4 } {
9179 return 1
9180 }
9181 if { ([istarget riscv*-*-*]) && N >= 2 && N <= 8 } {
9182 return 1
9183 }
9184 if [check_effective_target_vect_fully_masked] {
9185 return 1
9186 }
9187 return 0
9188 }]
9189 }
9190 }]
9191 }
9192
9193 # Return the list of vector sizes (in bits) that each target supports.
9194 # A vector length of "0" indicates variable-length vectors.
9195
9196 proc available_vector_sizes { } {
9197 set result {}
9198 if { [istarget aarch64*-*-*] } {
9199 if { [check_effective_target_aarch64_sve] } {
9200 lappend result [aarch64_sve_bits]
9201 }
9202 lappend result 128 64
9203 } elseif { [istarget arm*-*-*]
9204 && [check_effective_target_arm_neon_ok] } {
9205 lappend result 128 64
9206 } elseif { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
9207 if { [check_avx_available] && ![check_prefer_avx128] } {
9208 lappend result 256
9209 }
9210 lappend result 128
9211 if { ![is-effective-target ia32] } {
9212 lappend result 64
9213 }
9214 lappend result 32
9215 } elseif { [istarget sparc*-*-*] } {
9216 lappend result 64
9217 } elseif { [istarget amdgcn*-*-*] } {
9218 # 6 different lane counts, and 4 element sizes
9219 lappend result 4096 2048 1024 512 256 128 64 32 16 8 4 2
9220 } elseif { [istarget riscv*-*-*] } {
9221 if { [check_effective_target_riscv_v] } {
9222 lappend result 0 32 64 128
9223 }
9224 lappend result 128
9225 } else {
9226 # The traditional default asumption.
9227 lappend result 128
9228 }
9229 return $result
9230 }
9231
9232 # Return 1 if the target supports multiple vector sizes
9233
9234 proc check_effective_target_vect_multiple_sizes { } {
9235 return [expr { [llength [available_vector_sizes]] > 1 }]
9236 }
9237
9238 # Return true if variable-length vectors are supported.
9239
9240 proc check_effective_target_vect_variable_length { } {
9241 return [expr { [lindex [available_vector_sizes] 0] == 0 }]
9242 }
9243
9244 # Return 1 if the target supports vectors of 1024 bits.
9245
9246 proc check_effective_target_vect1024 { } {
9247 return [expr { [lsearch -exact [available_vector_sizes] 1024] >= 0 }]
9248 }
9249
9250 # Return 1 if the target supports vectors of 512 bits.
9251
9252 proc check_effective_target_vect512 { } {
9253 return [expr { [lsearch -exact [available_vector_sizes] 512] >= 0 }]
9254 }
9255
9256 # Return 1 if the target supports vectors of 256 bits.
9257
9258 proc check_effective_target_vect256 { } {
9259 return [expr { [lsearch -exact [available_vector_sizes] 256] >= 0 }]
9260 }
9261
9262 # Return 1 if the target supports vectors of 128 bits.
9263
9264 proc check_effective_target_vect128 { } {
9265 return [expr { [lsearch -exact [available_vector_sizes] 128] >= 0 }]
9266 }
9267
9268 # Return 1 if the target supports vectors of 64 bits.
9269
9270 proc check_effective_target_vect64 { } {
9271 return [expr { [lsearch -exact [available_vector_sizes] 64] >= 0 }]
9272 }
9273
9274 # Return 1 if the target supports vectors of 32 bits.
9275
9276 proc check_effective_target_vect32 { } {
9277 return [expr { [lsearch -exact [available_vector_sizes] 32] >= 0 }]
9278 }
9279
9280 # Return 1 if the target supports vector copysignf calls.
9281
9282 proc check_effective_target_vect_call_copysignf { } {
9283 return [check_cached_effective_target_indexed vect_call_copysignf {
9284 expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
9285 || [istarget powerpc*-*-*]
9286 || [istarget aarch64*-*-*]
9287 || [istarget amdgcn-*-*]
9288 || ([istarget riscv*-*-*]
9289 && [check_effective_target_riscv_v])
9290 || ([istarget loongarch*-*-*]
9291 && [check_effective_target_loongarch_sx]) }}]
9292 }
9293
9294 # Return 1 if the target supports hardware square root instructions.
9295
9296 proc check_effective_target_sqrt_insn { } {
9297 return [check_cached_effective_target sqrt_insn {
9298 expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
9299 || [check_effective_target_powerpc_sqrt]
9300 || [istarget aarch64*-*-*]
9301 || ([istarget arm*-*-*] && [check_effective_target_arm_vfp_ok])
9302 || ([istarget s390*-*-*]
9303 && [check_effective_target_s390_vx])
9304 || [istarget amdgcn-*-*] }}]
9305 }
9306
9307 # Return any additional options to enable square root intructions.
9308
9309 proc add_options_for_sqrt_insn { flags } {
9310 if { [istarget amdgcn*-*-*] } {
9311 return "$flags -ffast-math"
9312 }
9313 if { [istarget arm*-*-*] } {
9314 return [add_options_for_arm_vfp "$flags"]
9315 }
9316 return $flags
9317 }
9318
9319 # Return 1 if the target supports vector sqrtf calls.
9320
9321 proc check_effective_target_vect_call_sqrtf { } {
9322 return [check_cached_effective_target_indexed vect_call_sqrtf {
9323 expr { [istarget aarch64*-*-*]
9324 || [istarget i?86-*-*] || [istarget x86_64-*-*]
9325 || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
9326 || ([istarget s390*-*-*]
9327 && [check_effective_target_s390_vx])
9328 || [istarget amdgcn-*-*]
9329 || ([istarget riscv*-*-*]
9330 && [check_effective_target_riscv_v])
9331 || ([istarget loongarch*-*-*]
9332 && [check_effective_target_loongarch_sx]) }}]
9333 }
9334
9335 # Return 1 if the target supports vector lrint calls.
9336
9337 proc check_effective_target_vect_call_lrint { } {
9338 set et_vect_call_lrint 0
9339 if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
9340 && [check_effective_target_ilp32])
9341 || [istarget amdgcn-*-*]
9342 || [istarget loongarch*-*-*] } {
9343 set et_vect_call_lrint 1
9344 }
9345
9346 verbose "check_effective_target_vect_call_lrint: returning $et_vect_call_lrint" 2
9347 return $et_vect_call_lrint
9348 }
9349
9350 # Return 1 if the target supports vector btrunc calls.
9351
9352 proc check_effective_target_vect_call_btrunc { } {
9353 return [check_cached_effective_target_indexed vect_call_btrunc {
9354 expr { [istarget aarch64*-*-*]
9355 || [istarget amdgcn-*-*]
9356 || [istarget loongarch*-*-*] }}]
9357 }
9358
9359 # Return 1 if the target supports vector btruncf calls.
9360
9361 proc check_effective_target_vect_call_btruncf { } {
9362 return [check_cached_effective_target_indexed vect_call_btruncf {
9363 expr { [istarget aarch64*-*-*]
9364 || [istarget amdgcn-*-*]
9365 || [istarget loongarch*-*-*] }}]
9366 }
9367
9368 # Return 1 if the target supports vector ceil calls.
9369
9370 proc check_effective_target_vect_call_ceil { } {
9371 return [check_cached_effective_target_indexed vect_call_ceil {
9372 expr { [istarget aarch64*-*-*]
9373 || [istarget amdgcn-*-*]
9374 || [istarget loongarch*-*-*] }}]
9375 }
9376
9377 # Return 1 if the target supports vector ceilf calls.
9378
9379 proc check_effective_target_vect_call_ceilf { } {
9380 return [check_cached_effective_target_indexed vect_call_ceilf {
9381 expr { [istarget aarch64*-*-*]
9382 || [istarget amdgcn-*-*]
9383 || [istarget loongarch*-*-*] }}]
9384 }
9385
9386 # Return 1 if the target supports vector floor calls.
9387
9388 proc check_effective_target_vect_call_floor { } {
9389 return [check_cached_effective_target_indexed vect_call_floor {
9390 expr { [istarget aarch64*-*-*]
9391 || [istarget amdgcn-*-*]
9392 || [istarget loongarch*-*-*] }}]
9393 }
9394
9395 # Return 1 if the target supports vector floorf calls.
9396
9397 proc check_effective_target_vect_call_floorf { } {
9398 return [check_cached_effective_target_indexed vect_call_floorf {
9399 expr { [istarget aarch64*-*-*]
9400 || [istarget amdgcn-*-*]
9401 || [istarget loongarch*-*-*] }}]
9402 }
9403
9404 # Return 1 if the target supports vector lceil calls.
9405
9406 proc check_effective_target_vect_call_lceil { } {
9407 return [check_cached_effective_target_indexed vect_call_lceil {
9408 expr { [istarget aarch64*-*-*]
9409 || [istarget loongarch*-*-*] }}]
9410 }
9411
9412 # Return 1 if the target supports vector lfloor calls.
9413
9414 proc check_effective_target_vect_call_lfloor { } {
9415 return [check_cached_effective_target_indexed vect_call_lfloor {
9416 expr { [istarget aarch64*-*-*]
9417 || [istarget loongarch*-*-*] }}]
9418 }
9419
9420 # Return 1 if the target supports vector nearbyint calls.
9421
9422 proc check_effective_target_vect_call_nearbyint { } {
9423 return [check_cached_effective_target_indexed vect_call_nearbyint {
9424 expr { [istarget aarch64*-*-*] }}]
9425 }
9426
9427 # Return 1 if the target supports vector nearbyintf calls.
9428
9429 proc check_effective_target_vect_call_nearbyintf { } {
9430 return [check_cached_effective_target_indexed vect_call_nearbyintf {
9431 expr { [istarget aarch64*-*-*] }}]
9432 }
9433
9434 # Return 1 if the target supports vector round calls.
9435
9436 proc check_effective_target_vect_call_round { } {
9437 return [check_cached_effective_target_indexed vect_call_round {
9438 expr { [istarget aarch64*-*-*] }}]
9439 }
9440
9441 # Return 1 if the target supports vector roundf calls.
9442
9443 proc check_effective_target_vect_call_roundf { } {
9444 return [check_cached_effective_target_indexed vect_call_roundf {
9445 expr { [istarget aarch64*-*-*] }}]
9446 }
9447
9448 # Return 1 if the target supports AND, OR and XOR reduction.
9449
9450 proc check_effective_target_vect_logical_reduc { } {
9451 return [expr { [check_effective_target_aarch64_sve]
9452 || [istarget amdgcn-*-*]
9453 || [check_effective_target_riscv_v]
9454 || [check_effective_target_loongarch_sx]
9455 || [istarget i?86-*-*] || [istarget x86_64-*-*]}]
9456 }
9457
9458 # Return 1 if the target supports the fold_extract_last optab.
9459
9460 proc check_effective_target_vect_fold_extract_last { } {
9461 return [expr { [check_effective_target_aarch64_sve]
9462 || [istarget amdgcn*-*-*]
9463 || [check_effective_target_riscv_v] }]
9464 }
9465
9466 # Return 1 if the target supports section-anchors
9467
9468 proc check_effective_target_section_anchors { } {
9469 return [check_cached_effective_target section_anchors {
9470 expr { [istarget powerpc*-*-*]
9471 || [istarget arm*-*-*]
9472 || [istarget aarch64*-*-*]
9473 || [istarget loongarch*-*-*] }}]
9474 }
9475
9476 # Return 1 if the target supports atomic operations on "int_128" values.
9477
9478 proc check_effective_target_sync_int_128 { } {
9479 return 0
9480 }
9481
9482 # Return 1 if the target supports atomic operations on "int_128" values
9483 # and can execute them.
9484 # This requires support for both compare-and-swap and true atomic loads.
9485
9486 proc check_effective_target_sync_int_128_runtime { } {
9487 return 0
9488 }
9489
9490 # Return 1 if the target supports atomic operations on "long long".
9491 #
9492 # Note: 32bit x86 targets require -march=pentium in dg-options.
9493 # Note: 32bit s390 targets require -mzarch in dg-options.
9494
9495 proc check_effective_target_sync_long_long { } {
9496 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
9497 || [istarget aarch64*-*-*]
9498 || [istarget arm*-*-*]
9499 || [istarget alpha*-*-*]
9500 || ([istarget sparc*-*-*] && [check_effective_target_lp64])
9501 || [istarget s390*-*-*] } {
9502 return 1
9503 } else {
9504 return 0
9505 }
9506 }
9507
9508 # Return 1 if the target supports popcount on long.
9509
9510 proc check_effective_target_popcountl { } {
9511 return [check_no_messages_and_pattern popcountl "!\\(call" rtl-expand {
9512 int foo (long b)
9513 {
9514 return __builtin_popcountl (b);
9515 }
9516 } "" ]
9517 }
9518
9519 # Return 1 if the target supports popcount on long long.
9520
9521 proc check_effective_target_popcountll { } {
9522 return [check_no_messages_and_pattern popcountll "!\\(call" rtl-expand {
9523 int foo (long long b)
9524 {
9525 return __builtin_popcountll (b);
9526 }
9527 } "" ]
9528 }
9529
9530
9531 # Return 1 if the target supports popcount on int.
9532
9533 proc check_effective_target_popcount { } {
9534 return [check_no_messages_and_pattern popcount "!\\(call" rtl-expand {
9535 int foo (int b)
9536 {
9537 return __builtin_popcount (b);
9538 }
9539 } "" ]
9540 }
9541
9542 # Return 1 if the target supports clz on int.
9543
9544 proc check_effective_target_clz { } {
9545 return [check_no_messages_and_pattern clz "!\\(call" rtl-expand {
9546 int foo (int b)
9547 {
9548 return __builtin_clz (b);
9549 }
9550 } "" ]
9551 }
9552
9553 # Return 1 if the target supports clz on long.
9554
9555 proc check_effective_target_clzl { } {
9556 return [check_no_messages_and_pattern clzl "!\\(call" rtl-expand {
9557 int foo (long b)
9558 {
9559 return __builtin_clzl (b);
9560 }
9561 } "" ]
9562 }
9563
9564 # Return 1 if the target supports clz on long long.
9565
9566 proc check_effective_target_clzll { } {
9567 return [check_no_messages_and_pattern clzll "!\\(call" rtl-expand {
9568 int foo (long long b)
9569 {
9570 return __builtin_clzll (b);
9571 }
9572 } "" ]
9573 }
9574
9575 # Return 1 if the target supports ctz on int.
9576
9577 proc check_effective_target_ctz { } {
9578 return [check_no_messages_and_pattern ctz "!\\(call" rtl-expand {
9579 int foo (int b)
9580 {
9581 return __builtin_ctz (b);
9582 }
9583 } "" ]
9584 }
9585
9586 # Return 1 if the target supports ctz on long.
9587
9588 proc check_effective_target_ctzl { } {
9589 return [check_no_messages_and_pattern ctzl "!\\(call" rtl-expand {
9590 int foo (long b)
9591 {
9592 return __builtin_ctzl (b);
9593 }
9594 } "" ]
9595 }
9596
9597 # Return 1 if the target supports ctz on long long.
9598
9599 proc check_effective_target_ctzll { } {
9600 return [check_no_messages_and_pattern ctzll "!\\(call" rtl-expand {
9601 int foo (long long b)
9602 {
9603 return __builtin_ctzll (b);
9604 }
9605 } "" ]
9606 }
9607
9608 # Return 1 if the target supports atomic operations on "long long"
9609 # and can execute them.
9610 #
9611 # Note: 32bit x86 targets require -march=pentium in dg-options.
9612
9613 proc check_effective_target_sync_long_long_runtime { } {
9614 if { (([istarget x86_64-*-*] || [istarget i?86-*-*])
9615 && [check_cached_effective_target sync_long_long_available {
9616 check_runtime_nocache sync_long_long_available {
9617 #include "cpuid.h"
9618 int main ()
9619 {
9620 unsigned int eax, ebx, ecx, edx;
9621 if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
9622 return !(edx & bit_CMPXCHG8B);
9623 return 1;
9624 }
9625 } ""
9626 }])
9627 || [istarget aarch64*-*-*]
9628 || [istarget arm*-*-uclinuxfdpiceabi]
9629 || ([istarget arm*-*-linux-*]
9630 && [check_runtime sync_longlong_runtime {
9631 #include <stdlib.h>
9632 int main ()
9633 {
9634 long long l1;
9635
9636 if (sizeof (long long) != 8)
9637 exit (1);
9638
9639 /* Just check for native;
9640 checking for kernel fallback is tricky. */
9641 asm volatile ("ldrexd r0,r1, [%0]"
9642 : : "r" (&l1) : "r0", "r1");
9643 exit (0);
9644 }
9645 } "" ])
9646 || [istarget alpha*-*-*]
9647 || ([istarget sparc*-*-*]
9648 && [check_effective_target_lp64]
9649 && [check_effective_target_ultrasparc_hw])
9650 || ([istarget powerpc*-*-*] && [check_effective_target_lp64]) } {
9651 return 1
9652 } else {
9653 return 0
9654 }
9655 }
9656
9657 # Return 1 if the target supports byte swap instructions.
9658
9659 proc check_effective_target_bswap { } {
9660 return [check_cached_effective_target bswap {
9661 expr { [istarget aarch64*-*-*]
9662 || [istarget alpha*-*-*]
9663 || [istarget i?86-*-*] || [istarget x86_64-*-*]
9664 || [istarget m68k-*-*]
9665 || [istarget powerpc*-*-*]
9666 || [istarget rs6000-*-*]
9667 || [istarget s390*-*-*]
9668 || ([istarget riscv*-*-*]
9669 && [check_no_compiler_messages_nocache riscv_zbb object {
9670 #if __riscv_zbb <= 0
9671 #error ZBB is not enabled
9672 #endif
9673 int i;
9674 } ""])
9675 || ([istarget arm*-*-*]
9676 && [check_no_compiler_messages_nocache arm_v6_or_later object {
9677 #if __ARM_ARCH < 6
9678 #error not armv6 or later
9679 #endif
9680 int i;
9681 } ""]) }}]
9682 }
9683
9684 # Return 1 if the target supports atomic operations on "int" and "long".
9685
9686 proc check_effective_target_sync_int_long { } {
9687 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
9688 # load-reserved/store-conditional instructions.
9689 return [check_cached_effective_target sync_int_long {
9690 expr { [istarget ia64-*-*]
9691 || [istarget i?86-*-*] || [istarget x86_64-*-*]
9692 || [istarget aarch64*-*-*]
9693 || [istarget alpha*-*-*]
9694 || [istarget arm*-*-linux-*]
9695 || [istarget arm*-*-uclinuxfdpiceabi]
9696 || ([istarget arm*-*-*]
9697 && [check_effective_target_arm_acq_rel])
9698 || [istarget bfin*-*linux*]
9699 || [istarget hppa*-*linux*]
9700 || [istarget s390*-*-*]
9701 || [istarget powerpc*-*-*]
9702 || [istarget cris-*-*]
9703 || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9])
9704 || ([istarget arc*-*-*] && [check_effective_target_arc_atomic])
9705 || [check_effective_target_mips_llsc]
9706 || [istarget nvptx*-*-*]
9707 }}]
9708 }
9709
9710 # Return 1 if the target supports atomic operations on "int" and "long" on
9711 # stack addresses.
9712
9713 proc check_effective_target_sync_int_long_stack { } {
9714 return [check_cached_effective_target sync_int_long_stack {
9715 expr { ![istarget nvptx*-*-*]
9716 && [check_effective_target_sync_int_long]
9717 }}]
9718 }
9719
9720 # Return 1 if the target supports atomic operations on "char" and "short".
9721
9722 proc check_effective_target_sync_char_short { } {
9723 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
9724 # load-reserved/store-conditional instructions.
9725 return [check_cached_effective_target sync_char_short {
9726 expr { [istarget aarch64*-*-*]
9727 || [istarget ia64-*-*]
9728 || [istarget i?86-*-*] || [istarget x86_64-*-*]
9729 || [istarget alpha*-*-*]
9730 || [istarget arm*-*-linux-*]
9731 || [istarget arm*-*-uclinuxfdpiceabi]
9732 || ([istarget arm*-*-*]
9733 && [check_effective_target_arm_acq_rel])
9734 || [istarget hppa*-*linux*]
9735 || [istarget s390*-*-*]
9736 || [istarget powerpc*-*-*]
9737 || [istarget cris-*-*]
9738 || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9])
9739 || ([istarget arc*-*-*] && [check_effective_target_arc_atomic])
9740 || [istarget loongarch*-*-*]
9741 || [check_effective_target_mips_llsc] }}]
9742 }
9743
9744 # Return 1 if thread_fence does not rely on __sync_synchronize
9745 # library function
9746
9747 proc check_effective_target_thread_fence {} {
9748 return [check_no_compiler_messages thread_fence executable {
9749 int main () {
9750 __atomic_thread_fence (__ATOMIC_SEQ_CST);
9751 return 0;
9752 }
9753 } ""]
9754 }
9755
9756 # Return 1 if the target uses a ColdFire FPU.
9757
9758 proc check_effective_target_coldfire_fpu { } {
9759 return [check_no_compiler_messages coldfire_fpu assembly {
9760 #ifndef __mcffpu__
9761 #error !__mcffpu__
9762 #endif
9763 }]
9764 }
9765
9766 # Return true if this is a uClibc target.
9767
9768 proc check_effective_target_uclibc {} {
9769 return [check_no_compiler_messages uclibc object {
9770 #include <features.h>
9771 #if !defined (__UCLIBC__)
9772 #error !__UCLIBC__
9773 #endif
9774 }]
9775 }
9776
9777 # Return true if this is a uclibc target and if the uclibc feature
9778 # described by __$feature__ is not present.
9779
9780 proc check_missing_uclibc_feature {feature} {
9781 return [check_no_compiler_messages $feature object "
9782 #include <features.h>
9783 #if !defined (__UCLIBC) || defined (__${feature}__)
9784 #error FOO
9785 #endif
9786 "]
9787 }
9788
9789 # Return true if this is a Newlib target.
9790
9791 proc check_effective_target_newlib {} {
9792 return [check_no_compiler_messages newlib object {
9793 #include <newlib.h>
9794 }]
9795 }
9796
9797 # Return true if GCC was configured with --enable-newlib-nano-formatted-io
9798 proc check_effective_target_newlib_nano_io { } {
9799 return [check_configured_with "--enable-newlib-nano-formatted-io"]
9800 }
9801
9802 # Some newlib versions don't provide a frexpl and instead depend
9803 # on frexp to implement long double conversions in their printf-like
9804 # functions. This leads to broken results. Detect such versions here.
9805
9806 proc check_effective_target_newlib_broken_long_double_io {} {
9807 if { [is-effective-target newlib] && ![is-effective-target frexpl] } {
9808 return 1
9809 }
9810 return 0
9811 }
9812
9813 # Return true if this is NOT a Bionic target.
9814
9815 proc check_effective_target_non_bionic {} {
9816 return [check_no_compiler_messages non_bionic object {
9817 #include <ctype.h>
9818 #if defined (__BIONIC__)
9819 #error FOO
9820 #endif
9821 }]
9822 }
9823
9824 # Return true if this target has error.h header.
9825
9826 proc check_effective_target_error_h {} {
9827 return [check_no_compiler_messages error_h object {
9828 #include <error.h>
9829 }]
9830 }
9831
9832 # Return true if this target has tgmath.h header.
9833
9834 proc check_effective_target_tgmath_h {} {
9835 return [check_no_compiler_messages tgmath_h object {
9836 #include <tgmath.h>
9837 }]
9838 }
9839
9840 # Return true if target's libc supports complex functions.
9841
9842 proc check_effective_target_libc_has_complex_functions {} {
9843 return [check_no_compiler_messages libc_has_complex_functions object {
9844 #include <complex.h>
9845 }]
9846 }
9847
9848 # Return 1 if
9849 # (a) an error of a few ULP is expected in string to floating-point
9850 # conversion functions; and
9851 # (b) overflow is not always detected correctly by those functions.
9852
9853 proc check_effective_target_lax_strtofp {} {
9854 # By default, assume that all uClibc targets suffer from this.
9855 return [check_effective_target_uclibc]
9856 }
9857
9858 # Return 1 if this is a target for which wcsftime is a dummy
9859 # function that always returns 0.
9860
9861 proc check_effective_target_dummy_wcsftime {} {
9862 # By default, assume that all uClibc targets suffer from this.
9863 return [check_effective_target_uclibc]
9864 }
9865
9866 # Return 1 if constructors with initialization priority arguments are
9867 # supposed on this target.
9868
9869 proc check_effective_target_init_priority {} {
9870 return [check_no_compiler_messages init_priority assembly "
9871 void f() __attribute__((constructor (1000)));
9872 void f() \{\}
9873 "]
9874 }
9875
9876 # Return 1 if the target matches the effective target 'arg', 0 otherwise.
9877 # This can be used with any check_* proc that takes no argument and
9878 # returns only 1 or 0. It could be used with check_* procs that take
9879 # arguments with keywords that pass particular arguments.
9880
9881 proc is-effective-target { arg } {
9882 global et_index
9883 set selected 0
9884 if { ![info exists et_index] } {
9885 # Initialize the effective target index that is used in some
9886 # check_effective_target_* procs.
9887 set et_index 0
9888 }
9889 if { [info procs check_effective_target_${arg}] != [list] } {
9890 set selected [check_effective_target_${arg}]
9891 } else {
9892 switch $arg {
9893 "vmx_hw" { set selected [check_vmx_hw_available] }
9894 "vsx_hw" { set selected [check_vsx_hw_available] }
9895 "p8vector_hw" { set selected [check_p8vector_hw_available] }
9896 "p9vector_hw" { set selected [check_p9vector_hw_available] }
9897 "p9modulo_hw" { set selected [check_p9modulo_hw_available] }
9898 "power10_hw" { set selected [check_power10_hw_available] }
9899 "ppc_float128_sw" { set selected [check_ppc_float128_sw_available] }
9900 "ppc_float128_hw" { set selected [check_ppc_float128_hw_available] }
9901 "ppc_recip_hw" { set selected [check_ppc_recip_hw_available] }
9902 "ppc_cpu_supports_hw" { set selected [check_ppc_cpu_supports_hw_available] }
9903 "ppc_mma_hw" { set selected [check_ppc_mma_hw_available] }
9904 "dfp_hw" { set selected [check_dfp_hw_available] }
9905 "htm_hw" { set selected [check_htm_hw_available] }
9906 "named_sections" { set selected [check_named_sections_available] }
9907 "gc_sections" { set selected [check_gc_sections_available] }
9908 "cxa_atexit" { set selected [check_cxa_atexit_available] }
9909 default { error "unknown effective target keyword `$arg'" }
9910 }
9911 }
9912
9913 verbose "is-effective-target: $arg $selected" 2
9914 return $selected
9915 }
9916
9917 # Return 1 if the argument is an effective-target keyword, 0 otherwise.
9918
9919 proc is-effective-target-keyword { arg } {
9920 if { [info procs check_effective_target_${arg}] != [list] } {
9921 return 1
9922 } else {
9923 # These have different names for their check_* procs.
9924 switch $arg {
9925 "vmx_hw" { return 1 }
9926 "vsx_hw" { return 1 }
9927 "p8vector_hw" { return 1 }
9928 "p9vector_hw" { return 1 }
9929 "p9modulo_hw" { return 1 }
9930 "power10_hw" { return 1 }
9931 "ppc_float128_sw" { return 1 }
9932 "ppc_float128_hw" { return 1 }
9933 "ppc_recip_hw" { return 1 }
9934 "ppc_mma_hw" { return 1 }
9935 "dfp_hw" { return 1 }
9936 "htm_hw" { return 1 }
9937 "named_sections" { return 1 }
9938 "gc_sections" { return 1 }
9939 "cxa_atexit" { return 1 }
9940 "ppc_cpu_supports_hw" { return 1 }
9941 default { return 0 }
9942 }
9943 }
9944 }
9945
9946 # Execute tests for all targets in EFFECTIVE_TARGETS list. Set et_index to
9947 # indicate what target is currently being processed. This is for
9948 # the vectorizer tests, e.g. vect_int, to keep track what target supports
9949 # a given feature.
9950
9951 proc et-dg-runtest { runtest testcases flags default-extra-flags } {
9952 global dg-do-what-default
9953 global EFFECTIVE_TARGETS
9954 global et_index
9955
9956 if { [llength $EFFECTIVE_TARGETS] > 0 } {
9957 foreach target $EFFECTIVE_TARGETS {
9958 set target_flags $flags
9959 set dg-do-what-default compile
9960 set et_index [lsearch -exact $EFFECTIVE_TARGETS $target]
9961 if { [info procs add_options_for_${target}] != [list] } {
9962 set target_flags [add_options_for_${target} "$flags"]
9963 }
9964 if { [info procs check_effective_target_${target}_runtime]
9965 != [list] && [check_effective_target_${target}_runtime] } {
9966 set dg-do-what-default run
9967 }
9968 $runtest $testcases $target_flags ${default-extra-flags}
9969 }
9970 } else {
9971 set et_index 0
9972 $runtest $testcases $flags ${default-extra-flags}
9973 }
9974 }
9975
9976 # Return 1 if a target matches the target in EFFECTIVE_TARGETS at index
9977 # et_index, 0 otherwise.
9978
9979 proc et-is-effective-target { target } {
9980 global EFFECTIVE_TARGETS
9981 global et_index
9982
9983 if { [info exists EFFECTIVE_TARGETS] } {
9984 if { [llength $EFFECTIVE_TARGETS] > $et_index
9985 && [lindex $EFFECTIVE_TARGETS $et_index] == $target } {
9986 return 1
9987 } else {
9988 return 0
9989 }
9990 } else {
9991 return [check_effective_target_${target}]
9992 }
9993 }
9994
9995 # Return 1 if target default to short enums
9996
9997 proc check_effective_target_short_enums { } {
9998 return [check_no_compiler_messages short_enums assembly {
9999 enum foo { bar };
10000 int s[sizeof (enum foo) == 1 ? 1 : -1];
10001 }]
10002 }
10003
10004 # Return 1 if target supports merging string constants at link time.
10005
10006 proc check_effective_target_string_merging { } {
10007 return [check_no_messages_and_pattern string_merging \
10008 "rodata\\.str" assembly {
10009 const char *var = "String";
10010 } {-O2}]
10011 }
10012
10013 # Return 1 if target has the basic signed and unsigned types in
10014 # <stdint.h>, 0 otherwise. This will be obsolete when GCC ensures a
10015 # working <stdint.h> for all targets.
10016
10017 proc check_effective_target_stdint_types { } {
10018 return [check_no_compiler_messages stdint_types assembly {
10019 #include <stdint.h>
10020 int8_t a; int16_t b; int32_t c; int64_t d;
10021 uint8_t e; uint16_t f; uint32_t g; uint64_t h;
10022 }]
10023 }
10024
10025 # Like check_effective_target_stdint_types, but test what happens when
10026 # -mbig-endian is passed. This test only makes sense on targets that
10027 # support -mbig-endian; it will fail elsewhere.
10028
10029 proc check_effective_target_stdint_types_mbig_endian { } {
10030 return [check_no_compiler_messages stdint_types_mbig_endian assembly {
10031 #include <stdint.h>
10032 int8_t a; int16_t b; int32_t c; int64_t d;
10033 uint8_t e; uint16_t f; uint32_t g; uint64_t h;
10034 } "-mbig-endian"]
10035 }
10036
10037 # Return 1 if target has the basic signed and unsigned types in
10038 # <inttypes.h>, 0 otherwise. This is for tests that GCC's notions of
10039 # these types agree with those in the header, as some systems have
10040 # only <inttypes.h>.
10041
10042 proc check_effective_target_inttypes_types { } {
10043 return [check_no_compiler_messages inttypes_types assembly {
10044 #include <inttypes.h>
10045 int8_t a; int16_t b; int32_t c; int64_t d;
10046 uint8_t e; uint16_t f; uint32_t g; uint64_t h;
10047 }]
10048 }
10049
10050 # Return 1 if programs are intended to be run on a simulator
10051 # (i.e. slowly) rather than hardware (i.e. fast).
10052
10053 proc check_effective_target_simulator { } {
10054
10055 # All "src/sim" simulators set this one.
10056 if [board_info target exists is_simulator] {
10057 return [board_info target is_simulator]
10058 }
10059
10060 # The "sid" simulators don't set that one, but at least they set
10061 # this one.
10062 if [board_info target exists slow_simulator] {
10063 return [board_info target slow_simulator]
10064 }
10065
10066 return 0
10067 }
10068
10069 # Return 1 if programs are intended to be run on hardware rather than
10070 # on a simulator
10071
10072 proc check_effective_target_hw { } {
10073
10074 # All "src/sim" simulators set this one.
10075 if [board_info target exists is_simulator] {
10076 if [board_info target is_simulator] {
10077 return 0
10078 } else {
10079 return 1
10080 }
10081 }
10082
10083 # The "sid" simulators don't set that one, but at least they set
10084 # this one.
10085 if [board_info target exists slow_simulator] {
10086 if [board_info target slow_simulator] {
10087 return 0
10088 } else {
10089 return 1
10090 }
10091 }
10092
10093 return 1
10094 }
10095
10096 # Return 1 if the target is a VxWorks kernel.
10097
10098 proc check_effective_target_vxworks_kernel { } {
10099 return [check_no_compiler_messages vxworks_kernel assembly {
10100 #if !defined __vxworks || defined __RTP__
10101 #error NO
10102 #endif
10103 }]
10104 }
10105
10106 # Return 1 if the target is a VxWorks RTP.
10107
10108 proc check_effective_target_vxworks_rtp { } {
10109 return [check_no_compiler_messages vxworks_rtp assembly {
10110 #if !defined __vxworks || !defined __RTP__
10111 #error NO
10112 #endif
10113 }]
10114 }
10115
10116 # Return 1 if the target is expected to provide wide character support.
10117
10118 proc check_effective_target_wchar { } {
10119 if {[check_missing_uclibc_feature UCLIBC_HAS_WCHAR]} {
10120 return 0
10121 }
10122 return [check_no_compiler_messages wchar assembly {
10123 #include <wchar.h>
10124 }]
10125 }
10126
10127 # Return 1 if the target has <pthread.h>.
10128
10129 proc check_effective_target_pthread_h { } {
10130 return [check_no_compiler_messages pthread_h assembly {
10131 #include <pthread.h>
10132 }]
10133 }
10134
10135 # Return 1 if the target can truncate a file from a file-descriptor,
10136 # as used by libgfortran/io/unix.c:fd_truncate; i.e. ftruncate or
10137 # chsize. We test for a trivially functional truncation; no stubs.
10138 # As libgfortran uses _FILE_OFFSET_BITS 64, we do too; it'll cause a
10139 # different function to be used.
10140
10141 proc check_effective_target_fd_truncate { } {
10142 set prog {
10143 #define _FILE_OFFSET_BITS 64
10144 #include <unistd.h>
10145 #include <stdio.h>
10146 #include <stdlib.h>
10147 #include <string.h>
10148 int main ()
10149 {
10150 FILE *f = fopen ("tst.tmp", "wb");
10151 int fd;
10152 const char t[] = "test writing more than ten characters";
10153 char s[11];
10154 int status = 0;
10155 fd = fileno (f);
10156 write (fd, t, sizeof (t) - 1);
10157 lseek (fd, 0, 0);
10158 if (ftruncate (fd, 10) != 0)
10159 status = 1;
10160 close (fd);
10161 fclose (f);
10162 if (status)
10163 {
10164 unlink ("tst.tmp");
10165 exit (status);
10166 }
10167 f = fopen ("tst.tmp", "rb");
10168 if (fread (s, 1, sizeof (s), f) != 10 || strncmp (s, t, 10) != 0)
10169 status = 1;
10170 fclose (f);
10171 unlink ("tst.tmp");
10172 exit (status);
10173 }
10174 }
10175
10176 if { [check_runtime ftruncate $prog] } {
10177 return 1;
10178 }
10179
10180 regsub "ftruncate" $prog "chsize" prog
10181 return [check_runtime chsize $prog]
10182 }
10183
10184 # Add to FLAGS all the target-specific flags needed to enable
10185 # full IEEE compliance mode.
10186
10187 proc add_options_for_ieee { flags } {
10188 if { [istarget alpha*-*-*]
10189 || [istarget sh*-*-*] } {
10190 return "$flags -mieee"
10191 }
10192 if { [istarget rx-*-*] } {
10193 return "$flags -mnofpu"
10194 }
10195 return $flags
10196 }
10197
10198 if {![info exists flags_to_postpone]} {
10199 set flags_to_postpone ""
10200 }
10201
10202 # Add to FLAGS the flags needed to enable functions to bind locally
10203 # when using pic/PIC passes in the testsuite.
10204 proc add_options_for_bind_pic_locally { flags } {
10205 global flags_to_postpone
10206
10207 # Instead of returning 'flags' with the -fPIE or -fpie appended, we save it
10208 # in 'flags_to_postpone' and append it later in gcc_target_compile procedure in
10209 # order to make sure that the multilib_flags doesn't override this.
10210
10211 if {[check_no_compiler_messages using_pic2 assembly {
10212 #if __PIC__ != 2
10213 #error __PIC__ != 2
10214 #endif
10215 }]} {
10216 set flags_to_postpone "-fPIE"
10217 return $flags
10218 }
10219 if {[check_no_compiler_messages using_pic1 assembly {
10220 #if __PIC__ != 1
10221 #error __PIC__ != 1
10222 #endif
10223 }]} {
10224 set flags_to_postpone "-fpie"
10225 return $flags
10226 }
10227 return $flags
10228 }
10229
10230 # Add to FLAGS the flags needed to enable 64-bit vectors.
10231
10232 proc add_options_for_double_vectors { flags } {
10233 if [is-effective-target arm_neon_ok] {
10234 return "$flags -mvectorize-with-neon-double"
10235 }
10236
10237 return $flags
10238 }
10239
10240 # Add to FLAGS the flags needed to define the STACK_SIZE macro.
10241
10242 proc add_options_for_stack_size { flags } {
10243 if [is-effective-target stack_size] {
10244 set stack_size [dg-effective-target-value stack_size]
10245 return "$flags -DSTACK_SIZE=$stack_size"
10246 }
10247
10248 return $flags
10249 }
10250
10251 # Return 1 if the target provides a full C99 runtime.
10252
10253 proc check_effective_target_c99_runtime { } {
10254 return [check_cached_effective_target c99_runtime {
10255 global srcdir
10256
10257 set file [open "$srcdir/gcc.dg/builtins-config.h"]
10258 set contents [read $file]
10259 close $file
10260 append contents {
10261 #ifndef HAVE_C99_RUNTIME
10262 #error !HAVE_C99_RUNTIME
10263 #endif
10264 }
10265 check_no_compiler_messages_nocache c99_runtime assembly $contents
10266 }]
10267 }
10268
10269 # Return 1 if the target supports DWARF CFI directives.
10270
10271 proc check_effective_target_cfi { } {
10272 return [check_no_compiler_messages cfi assembly {
10273 #ifdef __GCC_HAVE_DWARF2_CFI_ASM
10274 /* ok */
10275 #else
10276 #error unsupported
10277 #endif
10278 } ""]
10279 }
10280
10281 # Return 1 if the target provides the D runtime.
10282
10283 proc check_effective_target_d_runtime { } {
10284 return [check_no_compiler_messages d_runtime executable {
10285 // D
10286 module mod;
10287
10288 extern(C) int main() {
10289 return 0;
10290 }
10291 }]
10292 }
10293
10294 # Return 1 if the target provides the D standard library.
10295
10296 proc check_effective_target_d_runtime_has_std_library { } {
10297 return [check_no_compiler_messages d_runtime_has_std_library executable {
10298 // D
10299 module mod;
10300
10301 extern(C) int main() {
10302 import std.math;
10303 real function(real) pcos = &cos;
10304 return 0;
10305 }
10306 }]
10307 }
10308
10309 # Return 1 if target wchar_t is at least 4 bytes.
10310
10311 proc check_effective_target_4byte_wchar_t { } {
10312 return [check_no_compiler_messages 4byte_wchar_t object {
10313 int dummy[sizeof (__WCHAR_TYPE__) >= 4 ? 1 : -1];
10314 }]
10315 }
10316
10317 # Return 1 if the target supports automatic stack alignment.
10318
10319 proc check_effective_target_automatic_stack_alignment { } {
10320 # Ordinarily x86 supports automatic stack alignment ...
10321 if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then {
10322 if { [istarget *-*-mingw*] || [istarget *-*-cygwin*] } {
10323 # ... except Win64 SEH doesn't. Succeed for Win32 though.
10324 return [check_effective_target_ilp32];
10325 }
10326 return 1;
10327 }
10328 return 0;
10329 }
10330
10331 # Return true if we are compiling for AVX target.
10332
10333 proc check_avx_available { } {
10334 if { [check_no_compiler_messages avx_available assembly {
10335 #ifndef __AVX__
10336 #error unsupported
10337 #endif
10338 } ""] } {
10339 return 1;
10340 }
10341 return 0;
10342 }
10343
10344 # Return true if we are compiling for AVX2 target.
10345
10346 proc check_avx2_available { } {
10347 if { [check_no_compiler_messages avx2_available assembly {
10348 #ifndef __AVX2__
10349 #error unsupported
10350 #endif
10351 } ""] } {
10352 return 1;
10353 }
10354 return 0;
10355 }
10356
10357 # Return true if we are compiling for SSSE3 target.
10358
10359 proc check_ssse3_available { } {
10360 if { [check_no_compiler_messages sse3a_available assembly {
10361 #ifndef __SSSE3__
10362 #error unsupported
10363 #endif
10364 } ""] } {
10365 return 1;
10366 }
10367 return 0;
10368 }
10369
10370 # Return true if 32- and 16-bytes vectors are available.
10371
10372 proc check_effective_target_vect_sizes_32B_16B { } {
10373 return [expr { [available_vector_sizes] == [list 256 128] }]
10374 }
10375
10376 # Return true if 16- and 8-bytes vectors are available.
10377
10378 proc check_effective_target_vect_sizes_16B_8B { } {
10379 if { [check_avx_available]
10380 || [is-effective-target arm_neon]
10381 || [istarget aarch64*-*-*]
10382 || [check_effective_target_riscv_v] } {
10383 return 1;
10384 } else {
10385 return 0;
10386 }
10387 }
10388
10389
10390 # Return true if 128-bits vectors are preferred even if 256-bits vectors
10391 # are available.
10392
10393 proc check_prefer_avx128 { } {
10394 if ![check_avx_available] {
10395 return 0;
10396 }
10397 return [check_no_messages_and_pattern avx_explicit "xmm" assembly {
10398 float a[1024],b[1024],c[1024];
10399 void foo (void) { int i; for (i = 0; i < 1024; i++) a[i]=b[i]+c[i];}
10400 } "-O2 -ftree-vectorize"]
10401 }
10402
10403
10404 # Return 1 if avx512fp16 instructions can be compiled.
10405
10406 proc check_effective_target_avx512fp16 { } {
10407 return [check_no_compiler_messages avx512fp16 object {
10408 void foo (void)
10409 {
10410 asm volatile ("vmovw %edi, %xmm0");
10411 asm volatile ("vfcmulcph %xmm1, %xmm2, %xmm3{%k1}");
10412 }
10413 } "-O2 -mavx512fp16" ]
10414 }
10415
10416 # Return 1 if avx512f instructions can be compiled.
10417
10418 proc check_effective_target_avx512f { } {
10419 return [check_no_compiler_messages avx512f object {
10420 typedef double __m512d __attribute__ ((__vector_size__ (64)));
10421 typedef double __m128d __attribute__ ((__vector_size__ (16)));
10422
10423 __m512d _mm512_add (__m512d a)
10424 {
10425 return __builtin_ia32_addpd512_mask (a, a, a, 1, 4);
10426 }
10427
10428 __m128d _mm128_add (__m128d a)
10429 {
10430 return __builtin_ia32_addsd_round (a, a, 8);
10431 }
10432
10433 __m128d _mm128_getmant (__m128d a)
10434 {
10435 return __builtin_ia32_getmantsd_round (a, a, 0, 8);
10436 }
10437 } "-O2 -mavx512f" ]
10438 }
10439
10440 # Return 1 if avx instructions can be compiled.
10441
10442 proc check_effective_target_avx { } {
10443 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
10444 return 0
10445 }
10446 return [check_no_compiler_messages avx object {
10447 void _mm256_zeroall (void)
10448 {
10449 __builtin_ia32_vzeroall ();
10450 }
10451 } "-O2 -mavx" ]
10452 }
10453
10454 # Return 1 if avx2 instructions can be compiled.
10455 proc check_effective_target_avx2 { } {
10456 return [check_no_compiler_messages avx2 object {
10457 typedef long long __v4di __attribute__ ((__vector_size__ (32)));
10458 __v4di
10459 mm256_is32_andnotsi256 (__v4di __X, __v4di __Y)
10460 {
10461 return __builtin_ia32_andnotsi256 (__X, __Y);
10462 }
10463 } "-O0 -mavx2" ]
10464 }
10465
10466 # Return 1 if avxvnni instructions can be compiled.
10467 proc check_effective_target_avxvnni { } {
10468 return [check_no_compiler_messages avxvnni object {
10469 typedef int __v8si __attribute__ ((__vector_size__ (32)));
10470 __v8si
10471 _mm256_dpbusd_epi32 (__v8si __A, __v8si __B, __v8si __C)
10472 {
10473 return __builtin_ia32_vpdpbusd_v8si (__A, __B, __C);
10474 }
10475 } "-mavxvnni" ]
10476 }
10477
10478 # Return 1 if avxifma instructions can be compiled.
10479 proc check_effective_target_avxifma { } {
10480 return [check_no_compiler_messages avxifma object {
10481 typedef long long __v4di __attribute__ ((__vector_size__ (32)));
10482 __v4di
10483 _mm256_maddlo_epu64 (__v4di __A, __v4di __B, __v4di __C)
10484 {
10485 return __builtin_ia32_vpmadd52luq256 (__A, __B, __C);
10486 }
10487 } "-O0 -mavxifma" ]
10488 }
10489
10490 # Return 1 if avxvnniint8 instructions can be compiled.
10491 proc check_effective_target_avxvnniint8 { } {
10492 return [check_no_compiler_messages avxvnniint8 object {
10493 typedef int __v8si __attribute__ ((__vector_size__ (32)));
10494 __v8si
10495 _mm256_dpbssd_epi32 (__v8si __A, __v8si __B, __v8si __C)
10496 {
10497 return __builtin_ia32_vpdpbssd256 (__A, __B, __C);
10498 }
10499 } "-O0 -mavxvnniint8" ]
10500 }
10501
10502 # Return 1 if avxneconvert instructions can be compiled.
10503 proc check_effective_target_avxneconvert { } {
10504 return [check_no_compiler_messages avxneconvert object {
10505 typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
10506 __m128
10507 _mm_bcstnebf16_ps (const void *__P)
10508 {
10509 return (__m128) __builtin_ia32_vbcstnebf162ps128 ((const __bf16 *) __P);
10510 }
10511 } "-O0 -mavxneconvert" ]
10512 }
10513
10514 # Return 1 if cmpccxadd instructions can be compiled.
10515 proc check_effective_target_cmpccxadd { } {
10516 return [check_no_compiler_messages cmpccxadd object {
10517 int _cmpccxadd_epi32 (int *__A, int __B, int __C, const int __D)
10518 {
10519 return (int)__builtin_ia32_cmpccxadd (__A, __B, __C, 1);
10520 }
10521 } "-mcmpccxadd" ]
10522 }
10523
10524 # Return 1 if raoint instructions can be compiled.
10525 proc check_effective_target_raoint { } {
10526 return [check_no_compiler_messages raoint object {
10527 void
10528 _aadd_si32 (int *__A, int __B)
10529 {
10530 return __builtin_ia32_aadd32((int *)__A, __B);
10531 }
10532 } "-mraoint" ]
10533 }
10534
10535 # Return 1 if amx-complex instructions can be compiled.
10536 proc check_effective_target_amx_complex { } {
10537 return [check_no_compiler_messages amx_complex object {
10538 void
10539 foo ()
10540 {
10541 __asm__ volatile ("tcmmimfp16ps\t%%tmm1, %%tmm2, %%tmm3" ::);
10542 }
10543 } "-mamx-complex" ]
10544 }
10545
10546 # Return 1 if avxvnniint16 instructions can be compiled.
10547 proc check_effective_target_avxvnniint16 { } {
10548 return [check_no_compiler_messages avxvnniint16 object {
10549 typedef int __v8si __attribute__ ((__vector_size__ (32)));
10550 __v8si
10551 _mm256_dpwsud_avx_epi32 (__v8si __A, __v8si __B, __v8si __C)
10552 {
10553 return __builtin_ia32_vpdpwsud256 (__A, __B, __C);
10554 }
10555 } "-O0 -mavxvnniint16" ]
10556 }
10557
10558 # Return 1 if sm3 instructions can be compiled.
10559 proc check_effective_target_sm3 { } {
10560 return [check_no_compiler_messages sm3 object {
10561 typedef long long __m128i __attribute__ ((__vector_size__ (16)));
10562 typedef int __v4si __attribute__ ((__vector_size__ (16)));
10563 __m128i
10564 _mm_sm3msg1_epi32 (__m128i __A, __m128i __B, __m128i __C)
10565 {
10566 return (__m128i) __builtin_ia32_vsm3msg1 ((__v4si) __A,
10567 (__v4si) __B,
10568 (__v4si) __C);
10569 }
10570 } "-msm3" ]
10571 }
10572
10573 # Return 1 if sha512 instructions can be compiled.
10574 proc check_effective_target_sha512 { } {
10575 return [check_no_compiler_messages sha512 object {
10576 typedef long long __m256i __attribute__ ((__vector_size__ (32)));
10577 typedef long long __v4di __attribute__ ((__vector_size__ (32)));
10578 __m256i
10579 _mm256_sha512msg2_epi64 (__m256i __A, __m256i __B)
10580 {
10581 return (__m256i) __builtin_ia32_vsha512msg2 ((__v4di) __A,
10582 (__v4di) __B);
10583 }
10584 } "-msha512" ]
10585 }
10586
10587 # Return 1 if sm4 instructions can be compiled.
10588 proc check_effective_target_sm4 { } {
10589 return [check_no_compiler_messages sm4 object {
10590 typedef long long __m128i __attribute__ ((__vector_size__ (16)));
10591 typedef int __v4si __attribute__ ((__vector_size__ (16)));
10592 __m128i
10593 _mm_sm4key4_epi32 (__m128i __A, __m128i __B)
10594 {
10595 return (__m128i) __builtin_ia32_vsm4key4128 ((__v4si) __A,
10596 (__v4si) __B);
10597 }
10598 } "-msm4" ]
10599 }
10600
10601 proc check_effective_target_apxf { } {
10602 return [check_no_compiler_messages apxf object {
10603 void
10604 foo ()
10605 {
10606 __asm__ volatile ("add\t%%r16, %%r31" ::);
10607 }
10608 } "-mapxf" ]
10609 }
10610
10611 # Return 1 if sse instructions can be compiled.
10612 proc check_effective_target_sse { } {
10613 return [check_no_compiler_messages sse object {
10614 int main ()
10615 {
10616 __builtin_ia32_stmxcsr ();
10617 return 0;
10618 }
10619 } "-O2 -msse" ]
10620 }
10621
10622 # Return 1 if sse2 instructions can be compiled.
10623 proc check_effective_target_sse2 { } {
10624 return [check_no_compiler_messages sse2 object {
10625 typedef long long __m128i __attribute__ ((__vector_size__ (16)));
10626
10627 __m128i _mm_srli_si128 (__m128i __A, int __N)
10628 {
10629 return (__m128i)__builtin_ia32_psrldqi128 (__A, 8);
10630 }
10631 } "-O2 -msse2" ]
10632 }
10633
10634 # Return 1 if sse4.1 instructions can be compiled.
10635 proc check_effective_target_sse4 { } {
10636 return [check_no_compiler_messages sse4.1 object {
10637 typedef long long __m128i __attribute__ ((__vector_size__ (16)));
10638 typedef int __v4si __attribute__ ((__vector_size__ (16)));
10639
10640 __m128i _mm_mullo_epi32 (__m128i __X, __m128i __Y)
10641 {
10642 return (__m128i) __builtin_ia32_pmulld128 ((__v4si)__X,
10643 (__v4si)__Y);
10644 }
10645 } "-O2 -msse4.1" ]
10646 }
10647
10648 # Return 1 if F16C instructions can be compiled.
10649
10650 proc check_effective_target_f16c { } {
10651 return [check_no_compiler_messages f16c object {
10652 #include "immintrin.h"
10653 float
10654 foo (unsigned short val)
10655 {
10656 return _cvtsh_ss (val);
10657 }
10658 } "-O2 -mf16c" ]
10659 }
10660
10661 proc check_effective_target_ms_hook_prologue { } {
10662 if { [check_no_compiler_messages ms_hook_prologue object {
10663 void __attribute__ ((__ms_hook_prologue__)) foo ();
10664 } ""] } {
10665 return 1
10666 } else {
10667 return 0
10668 }
10669 }
10670
10671 # Return 1 if 3dnow instructions can be compiled.
10672 proc check_effective_target_3dnow { } {
10673 return [check_no_compiler_messages 3dnow object {
10674 typedef int __m64 __attribute__ ((__vector_size__ (8)));
10675 typedef float __v2sf __attribute__ ((__vector_size__ (8)));
10676
10677 __m64 _m_pfadd (__m64 __A, __m64 __B)
10678 {
10679 return (__m64) __builtin_ia32_pfadd ((__v2sf)__A, (__v2sf)__B);
10680 }
10681 } "-O2 -m3dnow" ]
10682 }
10683
10684 # Return 1 if sse3 instructions can be compiled.
10685 proc check_effective_target_sse3 { } {
10686 return [check_no_compiler_messages sse3 object {
10687 typedef double __m128d __attribute__ ((__vector_size__ (16)));
10688 typedef double __v2df __attribute__ ((__vector_size__ (16)));
10689
10690 __m128d _mm_addsub_pd (__m128d __X, __m128d __Y)
10691 {
10692 return (__m128d) __builtin_ia32_addsubpd ((__v2df)__X, (__v2df)__Y);
10693 }
10694 } "-O2 -msse3" ]
10695 }
10696
10697 # Return 1 if ssse3 instructions can be compiled.
10698 proc check_effective_target_ssse3 { } {
10699 return [check_no_compiler_messages ssse3 object {
10700 typedef long long __m128i __attribute__ ((__vector_size__ (16)));
10701 typedef int __v4si __attribute__ ((__vector_size__ (16)));
10702
10703 __m128i _mm_abs_epi32 (__m128i __X)
10704 {
10705 return (__m128i) __builtin_ia32_pabsd128 ((__v4si)__X);
10706 }
10707 } "-O2 -mssse3" ]
10708 }
10709
10710 # Return 1 if aes instructions can be compiled.
10711 proc check_effective_target_aes { } {
10712 return [check_no_compiler_messages aes object {
10713 typedef long long __m128i __attribute__ ((__vector_size__ (16)));
10714 typedef long long __v2di __attribute__ ((__vector_size__ (16)));
10715
10716 __m128i _mm_aesimc_si128 (__m128i __X)
10717 {
10718 return (__m128i) __builtin_ia32_aesimc128 ((__v2di)__X);
10719 }
10720 } "-O2 -maes" ]
10721 }
10722
10723 # Return 1 if vaes instructions can be compiled.
10724 proc check_effective_target_vaes { } {
10725 return [check_no_compiler_messages vaes object {
10726 typedef long long __m128i __attribute__ ((__vector_size__ (16)));
10727 typedef long long __v2di __attribute__ ((__vector_size__ (16)));
10728
10729 __m128i _mm_aesimc_si128 (__m128i __X)
10730 {
10731 return (__m128i) __builtin_ia32_aesimc128 ((__v2di)__X);
10732 }
10733 } "-O2 -maes -mavx" ]
10734 }
10735
10736 # Return 1 if pclmul instructions can be compiled.
10737 proc check_effective_target_pclmul { } {
10738 return [check_no_compiler_messages pclmul object {
10739 typedef long long __m128i __attribute__ ((__vector_size__ (16)));
10740 typedef long long __v2di __attribute__ ((__vector_size__ (16)));
10741
10742 __m128i pclmulqdq_test (__m128i __X, __m128i __Y)
10743 {
10744 return (__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)__X,
10745 (__v2di)__Y,
10746 1);
10747 }
10748 } "-O2 -mpclmul" ]
10749 }
10750
10751 # Return 1 if vpclmul instructions can be compiled.
10752 proc check_effective_target_vpclmul { } {
10753 return [check_no_compiler_messages vpclmul object {
10754 typedef long long __m128i __attribute__ ((__vector_size__ (16)));
10755 typedef long long __v2di __attribute__ ((__vector_size__ (16)));
10756
10757 __m128i pclmulqdq_test (__m128i __X, __m128i __Y)
10758 {
10759 return (__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)__X,
10760 (__v2di)__Y,
10761 1);
10762 }
10763 } "-O2 -mpclmul -mavx" ]
10764 }
10765
10766 # Return 1 if sse4a instructions can be compiled.
10767 proc check_effective_target_sse4a { } {
10768 return [check_no_compiler_messages sse4a object {
10769 typedef long long __m128i __attribute__ ((__vector_size__ (16)));
10770 typedef long long __v2di __attribute__ ((__vector_size__ (16)));
10771
10772 __m128i _mm_insert_si64 (__m128i __X,__m128i __Y)
10773 {
10774 return (__m128i) __builtin_ia32_insertq ((__v2di)__X, (__v2di)__Y);
10775 }
10776 } "-O2 -msse4a" ]
10777 }
10778
10779 # Return 1 if fma4 instructions can be compiled.
10780 proc check_effective_target_fma4 { } {
10781 return [check_no_compiler_messages fma4 object {
10782 typedef float __m128 __attribute__ ((__vector_size__ (16)));
10783 typedef float __v4sf __attribute__ ((__vector_size__ (16)));
10784 __m128 _mm_macc_ps(__m128 __A, __m128 __B, __m128 __C)
10785 {
10786 return (__m128) __builtin_ia32_vfmaddps ((__v4sf)__A,
10787 (__v4sf)__B,
10788 (__v4sf)__C);
10789 }
10790 } "-O2 -mfma4" ]
10791 }
10792
10793 # Return 1 if fma instructions can be compiled.
10794 proc check_effective_target_fma { } {
10795 return [check_no_compiler_messages fma object {
10796 typedef float __m128 __attribute__ ((__vector_size__ (16)));
10797 typedef float __v4sf __attribute__ ((__vector_size__ (16)));
10798 __m128 _mm_macc_ps(__m128 __A, __m128 __B, __m128 __C)
10799 {
10800 return (__m128) __builtin_ia32_vfmaddps ((__v4sf)__A,
10801 (__v4sf)__B,
10802 (__v4sf)__C);
10803 }
10804 } "-O2 -mfma" ]
10805 }
10806
10807 # Return 1 if xop instructions can be compiled.
10808 proc check_effective_target_xop { } {
10809 return [check_no_compiler_messages xop object {
10810 typedef long long __m128i __attribute__ ((__vector_size__ (16)));
10811 typedef short __v8hi __attribute__ ((__vector_size__ (16)));
10812 __m128i _mm_maccs_epi16(__m128i __A, __m128i __B, __m128i __C)
10813 {
10814 return (__m128i) __builtin_ia32_vpmacssww ((__v8hi)__A,
10815 (__v8hi)__B,
10816 (__v8hi)__C);
10817 }
10818 } "-O2 -mxop" ]
10819 }
10820
10821 # Return 1 if lzcnt instruction can be compiled.
10822 proc check_effective_target_lzcnt { } {
10823 return [check_no_compiler_messages lzcnt object {
10824 unsigned short _lzcnt (unsigned short __X)
10825 {
10826 return __builtin_clzs (__X);
10827 }
10828 } "-mlzcnt" ]
10829 }
10830
10831 # Return 1 if bmi instructions can be compiled.
10832 proc check_effective_target_bmi { } {
10833 return [check_no_compiler_messages bmi object {
10834 unsigned int __bextr_u32 (unsigned int __X, unsigned int __Y)
10835 {
10836 return __builtin_ia32_bextr_u32 (__X, __Y);
10837 }
10838 } "-mbmi" ]
10839 }
10840
10841 # Return 1 if ADX instructions can be compiled.
10842 proc check_effective_target_adx { } {
10843 return [check_no_compiler_messages adx object {
10844 unsigned char
10845 _adxcarry_u32 (unsigned char __CF, unsigned int __X,
10846 unsigned int __Y, unsigned int *__P)
10847 {
10848 return __builtin_ia32_addcarryx_u32 (__CF, __X, __Y, __P);
10849 }
10850 } "-madx" ]
10851 }
10852
10853 # Return 1 if rtm instructions can be compiled.
10854 proc check_effective_target_rtm { } {
10855 return [check_no_compiler_messages rtm object {
10856 void
10857 _rtm_xend (void)
10858 {
10859 return __builtin_ia32_xend ();
10860 }
10861 } "-mrtm" ]
10862 }
10863
10864 # Return 1 if avx512vl instructions can be compiled.
10865 proc check_effective_target_avx512vl { } {
10866 return [check_no_compiler_messages avx512vl object {
10867 typedef long long __v4di __attribute__ ((__vector_size__ (32)));
10868 __v4di
10869 mm256_and_epi64 (__v4di __X, __v4di __Y)
10870 {
10871 __v4di __W;
10872 return __builtin_ia32_pandq256_mask (__X, __Y, __W, -1);
10873 }
10874 } "-mavx512vl" ]
10875 }
10876
10877 # Return 1 if avx512cd instructions can be compiled.
10878 proc check_effective_target_avx512cd { } {
10879 return [check_no_compiler_messages avx512cd_trans object {
10880 typedef long long __v8di __attribute__ ((__vector_size__ (64)));
10881 __v8di
10882 _mm512_conflict_epi64 (__v8di __W, __v8di __A)
10883 {
10884 return (__v8di) __builtin_ia32_vpconflictdi_512_mask ((__v8di) __A,
10885 (__v8di) __W,
10886 -1);
10887 }
10888 } "-Wno-psabi -mavx512cd" ]
10889 }
10890
10891 # Return 1 if avx512er instructions can be compiled.
10892 proc check_effective_target_avx512er { } {
10893 return [check_no_compiler_messages avx512er_trans object {
10894 typedef float __v16sf __attribute__ ((__vector_size__ (64)));
10895 __v16sf
10896 mm512_exp2a23_ps (__v16sf __X)
10897 {
10898 return __builtin_ia32_exp2ps_mask (__X, __X, -1, 4);
10899 }
10900 } "-Wno-psabi -mavx512er" ]
10901 }
10902
10903 # Return 1 if sha instructions can be compiled.
10904 proc check_effective_target_sha { } {
10905 return [check_no_compiler_messages sha object {
10906 typedef long long __m128i __attribute__ ((__vector_size__ (16)));
10907 typedef int __v4si __attribute__ ((__vector_size__ (16)));
10908
10909 __m128i _mm_sha1msg1_epu32 (__m128i __X, __m128i __Y)
10910 {
10911 return (__m128i) __builtin_ia32_sha1msg1 ((__v4si)__X,
10912 (__v4si)__Y);
10913 }
10914 } "-O2 -msha" ]
10915 }
10916
10917 # Return 1 if avx512dq instructions can be compiled.
10918 proc check_effective_target_avx512dq { } {
10919 return [check_no_compiler_messages avx512dq object {
10920 typedef long long __v8di __attribute__ ((__vector_size__ (64)));
10921 __v8di
10922 _mm512_mask_mullo_epi64 (__v8di __W, __v8di __A, __v8di __B)
10923 {
10924 return (__v8di) __builtin_ia32_pmullq512_mask ((__v8di) __A,
10925 (__v8di) __B,
10926 (__v8di) __W,
10927 -1);
10928 }
10929 } "-mavx512dq" ]
10930 }
10931
10932 # Return 1 if avx512bw instructions can be compiled.
10933 proc check_effective_target_avx512bw { } {
10934 return [check_no_compiler_messages avx512bw object {
10935 typedef short __v32hi __attribute__ ((__vector_size__ (64)));
10936 __v32hi
10937 _mm512_mask_mulhrs_epi16 (__v32hi __W, __v32hi __A, __v32hi __B)
10938 {
10939 return (__v32hi) __builtin_ia32_pmulhrsw512_mask ((__v32hi) __A,
10940 (__v32hi) __B,
10941 (__v32hi) __W,
10942 -1);
10943 }
10944 } "-mavx512bw" ]
10945 }
10946
10947 # Return 1 if -Wa,-march=+noavx512bw is supported.
10948 proc check_effective_target_assembler_march_noavx512bw {} {
10949 if { [istarget i?86*-*-*] || [istarget x86_64*-*-*] } {
10950 return [check_no_compiler_messages assembler_march_noavx512bw object {
10951 void foo (void) {}
10952 } "-mno-avx512bw -Wa,-march=+noavx512bw"]
10953 }
10954 return 0
10955 }
10956
10957 # Return 1 if avx512vp2intersect instructions can be compiled.
10958 proc check_effective_target_avx512vp2intersect { } {
10959 return [check_no_compiler_messages avx512vp2intersect object {
10960 typedef int __v16si __attribute__ ((__vector_size__ (64)));
10961 typedef short __mmask16;
10962 void
10963 _mm512_2intersect_epi32 (__v16si __A, __v16si __B, __mmask16 *__U,
10964 __mmask16 *__M)
10965 {
10966 __builtin_ia32_2intersectd512 (__U, __M, (__v16si) __A, (__v16si) __B);
10967 }
10968 } "-mavx512vp2intersect" ]
10969 }
10970
10971 # Return 1 if avx512ifma instructions can be compiled.
10972 proc check_effective_target_avx512ifma { } {
10973 return [check_no_compiler_messages avx512ifma object {
10974 typedef long long __v8di __attribute__ ((__vector_size__ (64)));
10975 __v8di
10976 _mm512_madd52lo_epu64 (__v8di __X, __v8di __Y, __v8di __Z)
10977 {
10978 return (__v8di) __builtin_ia32_vpmadd52luq512_mask ((__v8di) __X,
10979 (__v8di) __Y,
10980 (__v8di) __Z,
10981 -1);
10982 }
10983 } "-mavx512ifma" ]
10984 }
10985
10986 # Return 1 if avx512vbmi instructions can be compiled.
10987 proc check_effective_target_avx512vbmi { } {
10988 return [check_no_compiler_messages avx512vbmi object {
10989 typedef char __v64qi __attribute__ ((__vector_size__ (64)));
10990 __v64qi
10991 _mm512_multishift_epi64_epi8 (__v64qi __X, __v64qi __Y)
10992 {
10993 return (__v64qi) __builtin_ia32_vpmultishiftqb512_mask ((__v64qi) __X,
10994 (__v64qi) __Y,
10995 (__v64qi) __Y,
10996 -1);
10997 }
10998 } "-mavx512vbmi" ]
10999 }
11000
11001 # Return 1 if avx512_4fmaps instructions can be compiled.
11002 proc check_effective_target_avx5124fmaps { } {
11003 return [check_no_compiler_messages avx5124fmaps object {
11004 typedef float __v16sf __attribute__ ((__vector_size__ (64)));
11005 typedef float __v4sf __attribute__ ((__vector_size__ (16)));
11006
11007 __v16sf
11008 _mm512_mask_4fmadd_ps (__v16sf __DEST, __v16sf __A, __v16sf __B, __v16sf __C,
11009 __v16sf __D, __v16sf __E, __v4sf *__F)
11010 {
11011 return (__v16sf) __builtin_ia32_4fmaddps_mask ((__v16sf) __A,
11012 (__v16sf) __B,
11013 (__v16sf) __C,
11014 (__v16sf) __D,
11015 (__v16sf) __E,
11016 (const __v4sf *) __F,
11017 (__v16sf) __DEST,
11018 0xffff);
11019 }
11020 } "-mavx5124fmaps" ]
11021 }
11022
11023 # Return 1 if avx512_4vnniw instructions can be compiled.
11024 proc check_effective_target_avx5124vnniw { } {
11025 return [check_no_compiler_messages avx5124vnniw object {
11026 typedef int __v16si __attribute__ ((__vector_size__ (64)));
11027 typedef int __v4si __attribute__ ((__vector_size__ (16)));
11028
11029 __v16si
11030 _mm512_4dpwssd_epi32 (__v16si __A, __v16si __B, __v16si __C,
11031 __v16si __D, __v16si __E, __v4si *__F)
11032 {
11033 return (__v16si) __builtin_ia32_vp4dpwssd ((__v16si) __B,
11034 (__v16si) __C,
11035 (__v16si) __D,
11036 (__v16si) __E,
11037 (__v16si) __A,
11038 (const __v4si *) __F);
11039 }
11040 } "-mavx5124vnniw" ]
11041 }
11042
11043 # Return 1 if avx512_vpopcntdq instructions can be compiled.
11044 proc check_effective_target_avx512vpopcntdq { } {
11045 return [check_no_compiler_messages avx512vpopcntdq object {
11046 typedef int __v16si __attribute__ ((__vector_size__ (64)));
11047
11048 __v16si
11049 _mm512_popcnt_epi32 (__v16si __A)
11050 {
11051 return (__v16si) __builtin_ia32_vpopcountd_v16si ((__v16si) __A);
11052 }
11053 } "-mavx512vpopcntdq" ]
11054 }
11055
11056 # Return 1 if 128 or 256-bit avx512_vpopcntdq instructions can be compiled.
11057 proc check_effective_target_avx512vpopcntdqvl { } {
11058 return [check_no_compiler_messages avx512vpopcntdqvl object {
11059 typedef int __v8si __attribute__ ((__vector_size__ (32)));
11060
11061 __v8si
11062 _mm256_popcnt_epi32 (__v8si __A)
11063 {
11064 return (__v8si) __builtin_ia32_vpopcountd_v8si ((__v8si) __A);
11065 }
11066 } "-mavx512vpopcntdq -mavx512vl" ]
11067 }
11068
11069 # Return 1 if gfni instructions can be compiled.
11070 proc check_effective_target_gfni { } {
11071 return [check_no_compiler_messages gfni object {
11072 typedef char __v16qi __attribute__ ((__vector_size__ (16)));
11073
11074 __v16qi
11075 _mm_gf2p8affineinv_epi64_epi8 (__v16qi __A, __v16qi __B, const int __C)
11076 {
11077 return (__v16qi) __builtin_ia32_vgf2p8affineinvqb_v16qi ((__v16qi) __A,
11078 (__v16qi) __B,
11079 0);
11080 }
11081 } "-mgfni" ]
11082 }
11083
11084 # Return 1 if avx512vbmi2 instructions can be compiled.
11085 proc check_effective_target_avx512vbmi2 { } {
11086 return [check_no_compiler_messages avx512vbmi2 object {
11087 typedef char __v16qi __attribute__ ((__vector_size__ (16)));
11088 typedef unsigned long long __mmask16;
11089
11090 __v16qi
11091 _mm_mask_compress_epi8 (__v16qi __A, __mmask16 __B, __v16qi __C)
11092 {
11093 return (__v16qi) __builtin_ia32_compressqi128_mask((__v16qi)__C,
11094 (__v16qi)__A,
11095 (__mmask16)__B);
11096 }
11097 } "-mavx512vbmi2 -mavx512vl" ]
11098 }
11099
11100 # Return 1 if avx512vbmi2 instructions can be compiled.
11101 proc check_effective_target_avx512vnni { } {
11102 return [check_no_compiler_messages avx512vnni object {
11103 typedef int __v16si __attribute__ ((__vector_size__ (64)));
11104
11105 __v16si
11106 _mm_mask_compress_epi8 (__v16si __A, __v16si __B, __v16si __C)
11107 {
11108 return (__v16si) __builtin_ia32_vpdpbusd_v16si ((__v16si)__A,
11109 (__v16si)__B,
11110 (__v16si)__C);
11111 }
11112 } "-mavx512vnni -mavx512f" ]
11113 }
11114
11115 # Return 1 if vaes instructions can be compiled.
11116 proc check_effective_target_avx512vaes { } {
11117 return [check_no_compiler_messages avx512vaes object {
11118
11119 typedef int __v16si __attribute__ ((__vector_size__ (64)));
11120
11121 __v32qi
11122 _mm256_aesdec_epi128 (__v32qi __A, __v32qi __B)
11123 {
11124 return (__v32qi)__builtin_ia32_vaesdec_v32qi ((__v32qi) __A, (__v32qi) __B);
11125 }
11126 } "-mvaes" ]
11127 }
11128
11129 # Return 1 if amx-tile instructions can be compiled.
11130 proc check_effective_target_amx_tile { } {
11131 return [check_no_compiler_messages amx_tile object {
11132 void
11133 foo ()
11134 {
11135 __asm__ volatile ("tilerelease" ::);
11136 }
11137 } "-mamx-tile" ]
11138 }
11139
11140 # Return 1 if amx-int8 instructions can be compiled.
11141 proc check_effective_target_amx_int8 { } {
11142 return [check_no_compiler_messages amx_int8 object {
11143 void
11144 foo ()
11145 {
11146 __asm__ volatile ("tdpbssd\t%%tmm1, %%tmm2, %%tmm3" ::);
11147 }
11148 } "-mamx-int8" ]
11149 }
11150
11151 # Return 1 if amx-bf16 instructions can be compiled.
11152 proc check_effective_target_amx_bf16 { } {
11153 return [check_no_compiler_messages amx_bf16 object {
11154 void
11155 foo ()
11156 {
11157 __asm__ volatile ("tdpbf16ps\t%%tmm1, %%tmm2, %%tmm3" ::);
11158 }
11159 } "-mamx-bf16" ]
11160 }
11161
11162 # Return 1 if amx-fp16 instructions can be compiled.
11163 proc check_effective_target_amx_fp16 { } {
11164 return [check_no_compiler_messages amx_fp16 object {
11165 void
11166 foo ()
11167 {
11168 __asm__ volatile ("tdpfp16ps\t%%tmm1, %%tmm2, %%tmm3" ::);
11169 }
11170 } "-mamx-fp16" ]
11171 }
11172
11173 # Return 1 if vpclmulqdq instructions can be compiled.
11174 proc check_effective_target_vpclmulqdq { } {
11175 return [check_no_compiler_messages vpclmulqdq object {
11176 typedef long long __v4di __attribute__ ((__vector_size__ (32)));
11177
11178 __v4di
11179 _mm256_clmulepi64_epi128 (__v4di __A, __v4di __B)
11180 {
11181 return (__v4di) __builtin_ia32_vpclmulqdq_v4di (__A, __B, 0);
11182 }
11183 } "-mvpclmulqdq -mavx512vl" ]
11184 }
11185
11186 # Return 1 if avx512_bitalg instructions can be compiled.
11187 proc check_effective_target_avx512bitalg { } {
11188 return [check_no_compiler_messages avx512bitalg object {
11189 typedef short int __v32hi __attribute__ ((__vector_size__ (64)));
11190
11191 __v32hi
11192 _mm512_popcnt_epi16 (__v32hi __A)
11193 {
11194 return (__v32hi) __builtin_ia32_vpopcountw_v32hi ((__v32hi) __A);
11195 }
11196 } "-mavx512bitalg" ]
11197 }
11198
11199 # Return 1 if C wchar_t type is compatible with char16_t.
11200
11201 proc check_effective_target_wchar_t_char16_t_compatible { } {
11202 return [check_no_compiler_messages wchar_t_char16_t object {
11203 __WCHAR_TYPE__ wc;
11204 __CHAR16_TYPE__ *p16 = &wc;
11205 char t[(((__CHAR16_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1];
11206 }]
11207 }
11208
11209 # Return 1 if C wchar_t type is compatible with char32_t.
11210
11211 proc check_effective_target_wchar_t_char32_t_compatible { } {
11212 return [check_no_compiler_messages wchar_t_char32_t object {
11213 __WCHAR_TYPE__ wc;
11214 __CHAR32_TYPE__ *p32 = &wc;
11215 char t[(((__CHAR32_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1];
11216 }]
11217 }
11218
11219 # Return 1 if pow10 function exists.
11220
11221 proc check_effective_target_pow10 { } {
11222 return [check_runtime pow10 {
11223 #include <math.h>
11224 int main () {
11225 double x;
11226 x = pow10 (1);
11227 return 0;
11228 }
11229 } "-lm" ]
11230 }
11231
11232 # Return 1 if frexpl function exists.
11233
11234 proc check_effective_target_frexpl { } {
11235 return [check_runtime frexpl {
11236 #include <math.h>
11237 int main () {
11238 long double x;
11239 int y;
11240 x = frexpl (5.0, &y);
11241 return 0;
11242 }
11243 } "-lm" ]
11244 }
11245
11246
11247 # Return 1 if issignaling function exists.
11248 proc check_effective_target_issignaling {} {
11249 return [check_runtime issignaling {
11250 #define _GNU_SOURCE
11251 #include <math.h>
11252 int main ()
11253 {
11254 return issignaling (0.0);
11255 }
11256 } "-lm" ]
11257 }
11258
11259 # Return 1 if current options generate DFP instructions, 0 otherwise.
11260 proc check_effective_target_hard_dfp {} {
11261 return [check_no_messages_and_pattern hard_dfp "!adddd3" assembly {
11262 typedef float d64 __attribute__((mode(DD)));
11263 d64 x, y, z;
11264 void foo (void) { z = x + y; }
11265 }]
11266 }
11267
11268 # Return 1 if string.h and wchar.h headers provide C++ requires overloads
11269 # for strchr etc. functions.
11270
11271 proc check_effective_target_correct_iso_cpp_string_wchar_protos { } {
11272 return [check_no_compiler_messages correct_iso_cpp_string_wchar_protos assembly {
11273 #include <string.h>
11274 #include <wchar.h>
11275 #if !defined(__cplusplus) \
11276 || !defined(__CORRECT_ISO_CPP_STRING_H_PROTO) \
11277 || !defined(__CORRECT_ISO_CPP_WCHAR_H_PROTO)
11278 ISO C++ correct string.h and wchar.h protos not supported.
11279 #else
11280 int i;
11281 #endif
11282 }]
11283 }
11284
11285 # Return 1 if GNU as is used.
11286
11287 proc check_effective_target_gas { } {
11288 global use_gas_saved
11289 global tool
11290
11291 if {![info exists use_gas_saved]} {
11292 # Check if the as used by gcc is GNU as.
11293 set options [list "additional_flags=-print-prog-name=as"]
11294 set gcc_as [lindex [${tool}_target_compile "" "" "none" $options] 0]
11295 # Provide /dev/null as input, otherwise gas times out reading from
11296 # stdin.
11297 set status [remote_exec host "$gcc_as" "-v /dev/null"]
11298 set as_output [lindex $status 1]
11299 if { [ string first "GNU" $as_output ] >= 0 } {
11300 # Some Darwin versions have an assembler which is based on an old
11301 # version of GAS (and reports GNU assembler in its -v output) but
11302 # but doesn't support many of the modern GAS features.
11303 if { [ string first "cctools" $as_output ] >= 0 } {
11304 set use_gas_saved 0
11305 } else {
11306 set use_gas_saved 1
11307 }
11308 } else {
11309 set use_gas_saved 0
11310 }
11311 }
11312 return $use_gas_saved
11313 }
11314
11315 # Return 1 if GNU ld is used.
11316
11317 proc check_effective_target_gld { } {
11318 global use_gld_saved
11319 global tool
11320
11321 if {![info exists use_gld_saved]} {
11322 # Check if the ld used by gcc is GNU ld.
11323 set options [list "additional_flags=-print-prog-name=ld"]
11324 set gcc_ld [lindex [${tool}_target_compile "" "" "none" $options] 0]
11325 set status [remote_exec host "$gcc_ld" "--version"]
11326 set ld_output [lindex $status 1]
11327 if { [ string first "GNU" $ld_output ] >= 0 } {
11328 set use_gld_saved 1
11329 } else {
11330 set use_gld_saved 0
11331 }
11332 }
11333 return $use_gld_saved
11334 }
11335
11336 # Return 1 if the compiler has been configure with link-time optimization
11337 # (LTO) support.
11338
11339 proc check_effective_target_lto { } {
11340 if { [istarget *-*-vxworks*] } {
11341 # No LTO on VxWorks, with kernel modules
11342 # built with partial links
11343 return 0
11344 }
11345 if { [istarget nvptx-*-*]
11346 || [istarget amdgcn-*-*] } {
11347 return 0;
11348 }
11349 return [check_no_compiler_messages lto object {
11350 void foo (void) { }
11351 } "-flto"]
11352 }
11353
11354 # Return 1 if the compiler and linker support incremental link-time
11355 # optimization.
11356
11357 proc check_effective_target_lto_incremental { } {
11358 if ![check_effective_target_lto] {
11359 return 0
11360 }
11361 return [check_no_compiler_messages lto_incremental executable {
11362 int main () { return 0; }
11363 } "-flto -r -nostdlib"]
11364 }
11365
11366 # Return 1 if the compiler has been configured with analyzer support.
11367
11368 proc check_effective_target_analyzer { } {
11369 return [check_no_compiler_messages analyzer object {
11370 void foo (void) { }
11371 } "-fanalyzer"]
11372 }
11373
11374 # Return 1 if -mx32 -maddress-mode=short can compile, 0 otherwise.
11375
11376 proc check_effective_target_maybe_x32 { } {
11377 return [check_no_compiler_messages maybe_x32 object {
11378 void foo (void) {}
11379 } "-mx32 -maddress-mode=short"]
11380 }
11381
11382 # Return 1 if this target supports the -fsplit-stack option, 0
11383 # otherwise.
11384
11385 proc check_effective_target_split_stack {} {
11386 return [check_no_compiler_messages split_stack object {
11387 void foo (void) { }
11388 } "-fsplit-stack"]
11389 }
11390
11391 # Return 1 if this target supports the -masm=intel option, 0
11392 # otherwise
11393
11394 proc check_effective_target_masm_intel {} {
11395 return [check_no_compiler_messages masm_intel object {
11396 extern void abort (void);
11397 } "-masm=intel"]
11398 }
11399
11400 # Return 1 if the language for the compiler under test is C.
11401
11402 proc check_effective_target_c { } {
11403 global tool
11404 if [string match $tool "gcc"] {
11405 return 1
11406 }
11407 return 0
11408 }
11409
11410 # Return 1 if the language for the compiler under test is C++.
11411
11412 proc check_effective_target_c++ { } {
11413 global tool
11414 if { [string match $tool "g++"] || [string match $tool "libstdc++"] } {
11415 return 1
11416 }
11417 return 0
11418 }
11419
11420 set cxx_default "c++17"
11421 # Check whether the current active language standard supports the features
11422 # of C++11/C++14 by checking for the presence of one of the -std flags.
11423 # This assumes that the default for the compiler is $cxx_default, and that
11424 # there will never be multiple -std= arguments on the command line.
11425 proc check_effective_target_c++11_only { } {
11426 global cxx_default
11427 if ![check_effective_target_c++] {
11428 return 0
11429 }
11430 if [check-flags { { } { } { -std=c++0x -std=gnu++0x -std=c++11 -std=gnu++11 } }] {
11431 return 1
11432 }
11433 if { $cxx_default == "c++11" && [check-flags { { } { } { } { -std=* } }] } {
11434 return 1
11435 }
11436 return 0
11437 }
11438 proc check_effective_target_c++11 { } {
11439 if [check_effective_target_c++11_only] {
11440 return 1
11441 }
11442 return [check_effective_target_c++14]
11443 }
11444 proc check_effective_target_c++11_down { } {
11445 if ![check_effective_target_c++] {
11446 return 0
11447 }
11448 return [expr ![check_effective_target_c++14] ]
11449 }
11450
11451 proc check_effective_target_c++14_only { } {
11452 global cxx_default
11453 if ![check_effective_target_c++] {
11454 return 0
11455 }
11456 if [check-flags { { } { } { -std=c++14 -std=gnu++14 -std=c++14 -std=gnu++14 } }] {
11457 return 1
11458 }
11459 if { $cxx_default == "c++14" && [check-flags { { } { } { } { -std=* } }] } {
11460 return 1
11461 }
11462 return 0
11463 }
11464
11465 proc check_effective_target_c++14 { } {
11466 if [check_effective_target_c++14_only] {
11467 return 1
11468 }
11469 return [check_effective_target_c++17]
11470 }
11471 proc check_effective_target_c++14_down { } {
11472 if ![check_effective_target_c++] {
11473 return 0
11474 }
11475 return [expr ![check_effective_target_c++17] ]
11476 }
11477
11478 proc check_effective_target_c++98_only { } {
11479 global cxx_default
11480 if ![check_effective_target_c++] {
11481 return 0
11482 }
11483 if [check-flags { { } { } { -std=c++98 -std=gnu++98 -std=c++03 -std=gnu++03 } }] {
11484 return 1
11485 }
11486 if { $cxx_default == "c++98" && [check-flags { { } { } { } { -std=* } }] } {
11487 return 1
11488 }
11489 return 0
11490 }
11491
11492 proc check_effective_target_c++17_only { } {
11493 global cxx_default
11494 if ![check_effective_target_c++] {
11495 return 0
11496 }
11497 if [check-flags { { } { } { -std=c++17 -std=gnu++17 -std=c++1z -std=gnu++1z } }] {
11498 return 1
11499 }
11500 if { $cxx_default == "c++17" && [check-flags { { } { } { } { -std=* } }] } {
11501 return 1
11502 }
11503 return 0
11504 }
11505
11506 proc check_effective_target_c++17 { } {
11507 if [check_effective_target_c++17_only] {
11508 return 1
11509 }
11510 return [check_effective_target_c++2a]
11511 }
11512 proc check_effective_target_c++17_down { } {
11513 if ![check_effective_target_c++] {
11514 return 0
11515 }
11516 return [expr ![check_effective_target_c++2a] ]
11517 }
11518
11519 proc check_effective_target_c++2a_only { } {
11520 global cxx_default
11521 if ![check_effective_target_c++] {
11522 return 0
11523 }
11524 if [check-flags { { } { } { -std=c++2a -std=gnu++2a -std=c++20 -std=gnu++20 } }] {
11525 return 1
11526 }
11527 if { $cxx_default == "c++20" && [check-flags { { } { } { } { -std=* } }] } {
11528 return 1
11529 }
11530 return 0
11531 }
11532 proc check_effective_target_c++2a { } {
11533 if [check_effective_target_c++2a_only] {
11534 return 1
11535 }
11536 return [check_effective_target_c++23]
11537 }
11538
11539 proc check_effective_target_c++20_only { } {
11540 return [check_effective_target_c++2a_only]
11541 }
11542
11543 proc check_effective_target_c++20 { } {
11544 return [check_effective_target_c++2a]
11545 }
11546 proc check_effective_target_c++20_down { } {
11547 if ![check_effective_target_c++] {
11548 return 0
11549 }
11550 return [expr ![check_effective_target_c++23] ]
11551 }
11552
11553 proc check_effective_target_c++23_only { } {
11554 global cxx_default
11555 if ![check_effective_target_c++] {
11556 return 0
11557 }
11558 if [check-flags { { } { } { -std=c++23 -std=gnu++23 -std=c++2b -std=gnu++2b } }] {
11559 return 1
11560 }
11561 if { $cxx_default == "c++23" && [check-flags { { } { } { } { -std=* } }] } {
11562 return 1
11563 }
11564 return 0
11565 }
11566 proc check_effective_target_c++23 { } {
11567 if [check_effective_target_c++23_only] {
11568 return 1
11569 }
11570 return [check_effective_target_c++26]
11571 }
11572
11573 proc check_effective_target_c++23_down { } {
11574 if ![check_effective_target_c++] {
11575 return 0
11576 }
11577 return [expr ![check_effective_target_c++26] ]
11578 }
11579
11580 proc check_effective_target_c++26_only { } {
11581 global cxx_default
11582 if ![check_effective_target_c++] {
11583 return 0
11584 }
11585 if [check-flags { { } { } { -std=c++26 -std=gnu++26 -std=c++2c -std=gnu++2c } }] {
11586 return 1
11587 }
11588 if { $cxx_default == "c++26" && [check-flags { { } { } { } { -std=* } }] } {
11589 return 1
11590 }
11591 return 0
11592 }
11593
11594 proc check_effective_target_c++26 { } {
11595 return [check_effective_target_c++26_only]
11596 }
11597
11598 # Check for C++ Concepts support, i.e. -fconcepts flag.
11599 proc check_effective_target_concepts { } {
11600 if [check_effective_target_c++2a] {
11601 return 1
11602 }
11603 return [check-flags { "" { } { -fconcepts } }]
11604 }
11605
11606 proc check_effective_target_implicit_constexpr { } {
11607 return [check-flags { "" { } { -fimplicit-constexpr } }]
11608 }
11609
11610 # Return 1 if expensive testcases should be run.
11611
11612 proc check_effective_target_run_expensive_tests { } {
11613 if { [getenv GCC_TEST_RUN_EXPENSIVE] != "" } {
11614 return 1
11615 }
11616 return 0
11617 }
11618
11619 # Returns 1 if "mempcpy" is available on the target system.
11620
11621 proc check_effective_target_mempcpy {} {
11622 if { [istarget *-*-vxworks*] } {
11623 # VxWorks doesn't have mempcpy but our way to test fails
11624 # to detect as we're doing partial links for kernel modules.
11625 return 0
11626 }
11627 return [check_function_available "mempcpy"]
11628 }
11629
11630 # Returns 1 if "stpcpy" is available on the target system.
11631
11632 proc check_effective_target_stpcpy {} {
11633 return [check_function_available "stpcpy"]
11634 }
11635
11636 # Returns 1 if "sigsetjmp" is available on the target system.
11637 # Also check if "__sigsetjmp" is defined since that's what glibc
11638 # uses.
11639
11640 proc check_effective_target_sigsetjmp {} {
11641 if { [check_function_available "sigsetjmp"]
11642 || [check_function_available "__sigsetjmp"] } {
11643 return 1
11644 }
11645 return 0
11646 }
11647
11648 # Check whether the vectorizer tests are supported by the target and
11649 # append additional target-dependent compile flags to DEFAULT_VECTCFLAGS.
11650 # If a port wants to execute the tests more than once it should append
11651 # the supported target to EFFECTIVE_TARGETS instead, and the compile flags
11652 # will be added by a call to add_options_for_<target>.
11653 # Set dg-do-what-default to either compile or run, depending on target
11654 # capabilities. Do not set this if the supported target is appended to
11655 # EFFECTIVE_TARGETS. Flags and this variable will be set by et-dg-runtest
11656 # automatically. Return the number of effective targets if vectorizer tests
11657 # are supported, 0 otherwise.
11658
11659 proc check_vect_support_and_set_flags { } {
11660 global DEFAULT_VECTCFLAGS
11661 global dg-do-what-default
11662 global EFFECTIVE_TARGETS
11663
11664 if [istarget powerpc-*paired*] {
11665 lappend DEFAULT_VECTCFLAGS "-mpaired"
11666 if [check_750cl_hw_available] {
11667 set dg-do-what-default run
11668 } else {
11669 set dg-do-what-default compile
11670 }
11671 } elseif [istarget powerpc*-*-*] {
11672 # Skip targets not supporting -maltivec.
11673 if ![is-effective-target powerpc_altivec_ok] {
11674 return 0
11675 }
11676
11677 lappend DEFAULT_VECTCFLAGS "-maltivec"
11678 if [check_p9vector_hw_available] {
11679 lappend DEFAULT_VECTCFLAGS "-mpower9-vector"
11680 } elseif [check_p8vector_hw_available] {
11681 lappend DEFAULT_VECTCFLAGS "-mpower8-vector"
11682 } elseif [check_vsx_hw_available] {
11683 lappend DEFAULT_VECTCFLAGS "-mvsx" "-mno-allow-movmisalign"
11684 }
11685
11686 if [check_vmx_hw_available] {
11687 set dg-do-what-default run
11688 } else {
11689 if [is-effective-target ilp32] {
11690 # Specify a cpu that supports VMX for compile-only tests.
11691 lappend DEFAULT_VECTCFLAGS "-mcpu=970"
11692 }
11693 set dg-do-what-default compile
11694 }
11695 } elseif { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
11696 lappend DEFAULT_VECTCFLAGS "-msse2"
11697 if { [check_effective_target_sse2_runtime] } {
11698 set dg-do-what-default run
11699 } else {
11700 set dg-do-what-default compile
11701 }
11702 } elseif { [istarget mips*-*-*]
11703 && [check_effective_target_nomips16] } {
11704 if { [check_effective_target_mpaired_single "-mpaired-single"] } {
11705 lappend EFFECTIVE_TARGETS mpaired_single
11706 }
11707 if { [check_effective_target_mips_loongson_mmi "-mloongson-mmi"] } {
11708 lappend EFFECTIVE_TARGETS mips_loongson_mmi
11709 }
11710 if { [check_effective_target_mips_msa "-mmsa"] } {
11711 lappend EFFECTIVE_TARGETS mips_msa
11712 }
11713 return [llength $EFFECTIVE_TARGETS]
11714 } elseif [istarget sparc*-*-*] {
11715 lappend DEFAULT_VECTCFLAGS "-mcpu=ultrasparc" "-mvis"
11716 if [check_effective_target_ultrasparc_hw] {
11717 set dg-do-what-default run
11718 } else {
11719 set dg-do-what-default compile
11720 }
11721 } elseif [istarget alpha*-*-*] {
11722 # Alpha's vectorization capabilities are extremely limited.
11723 # It's more effort than its worth disabling all of the tests
11724 # that it cannot pass. But if you actually want to see what
11725 # does work, command out the return.
11726 return 0
11727
11728 lappend DEFAULT_VECTCFLAGS "-mmax"
11729 if [check_alpha_max_hw_available] {
11730 set dg-do-what-default run
11731 } else {
11732 set dg-do-what-default compile
11733 }
11734 } elseif [istarget ia64-*-*] {
11735 set dg-do-what-default run
11736 } elseif [is-effective-target arm_neon_ok] {
11737 eval lappend DEFAULT_VECTCFLAGS [add_options_for_arm_neon ""]
11738 # NEON does not support denormals, so is not used for vectorization by
11739 # default to avoid loss of precision. We must pass -ffast-math to test
11740 # vectorization of float operations.
11741 lappend DEFAULT_VECTCFLAGS "-ffast-math"
11742 if [is-effective-target arm_neon_hw] {
11743 set dg-do-what-default run
11744 } else {
11745 set dg-do-what-default compile
11746 }
11747 } elseif [istarget aarch64*-*-*] {
11748 set dg-do-what-default run
11749 } elseif [istarget s390*-*-*] {
11750 # The S/390 backend set a default of 2 for that value.
11751 # Override it to have the same situation as with other
11752 # targets.
11753 lappend DEFAULT_VECTCFLAGS "--param" "min-vect-loop-bound=1"
11754 lappend DEFAULT_VECTCFLAGS "--param" "max-unrolled-insns=200"
11755 lappend DEFAULT_VECTCFLAGS "--param" "max-unroll-times=8"
11756 lappend DEFAULT_VECTCFLAGS "--param" "max-completely-peeled-insns=200"
11757 lappend DEFAULT_VECTCFLAGS "--param" "max-completely-peel-times=16"
11758 if [check_effective_target_s390_vxe2] {
11759 lappend DEFAULT_VECTCFLAGS "-march=z15" "-mzarch"
11760 set dg-do-what-default run
11761 } elseif [check_effective_target_s390_vxe] {
11762 lappend DEFAULT_VECTCFLAGS "-march=z14" "-mzarch"
11763 set dg-do-what-default run
11764 } elseif [check_effective_target_s390_vx] {
11765 lappend DEFAULT_VECTCFLAGS "-march=z13" "-mzarch"
11766 set dg-do-what-default run
11767 } else {
11768 lappend DEFAULT_VECTCFLAGS "-march=z14" "-mzarch"
11769 set dg-do-what-default compile
11770 }
11771 } elseif [istarget amdgcn-*-*] {
11772 set dg-do-what-default run
11773 } elseif [istarget riscv*-*-*] {
11774 if [check_effective_target_riscv_v] {
11775 set dg-do-what-default run
11776 } else {
11777 foreach item [add_options_for_riscv_v ""] {
11778 lappend DEFAULT_VECTCFLAGS $item
11779 }
11780 set dg-do-what-default compile
11781 }
11782 } elseif [istarget loongarch*-*-*] {
11783 # Set the default vectorization option to "-mlsx" due to the problem
11784 # of non-aligned memory access when using 256-bit vectorization.
11785 lappend DEFAULT_VECTCFLAGS "-mdouble-float" "-mlsx"
11786 if [check_effective_target_loongarch_sx_hw] {
11787 set dg-do-what-default run
11788 } else {
11789 set dg-do-what-default compile
11790 }
11791 } else {
11792 return 0
11793 }
11794
11795 return 1
11796 }
11797
11798 # Return 1 if the target does *not* require strict alignment.
11799
11800 proc check_effective_target_non_strict_align {} {
11801
11802 # On ARM, the default is to use STRICT_ALIGNMENT, but there
11803 # are interfaces defined for misaligned access and thus
11804 # depending on the architecture levels unaligned access is
11805 # available.
11806 if [istarget "arm*-*-*"] {
11807 return [check_effective_target_arm_unaligned]
11808 }
11809
11810 return [check_no_compiler_messages non_strict_align assembly {
11811 char *y;
11812 typedef char __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) c;
11813 c *z;
11814 void foo(void) { z = (c *) y; }
11815 } "-Wcast-align"]
11816 }
11817
11818 # Return 1 if the target supports -mstrict-align (and -mno-strict-align).
11819
11820 proc check_effective_target_opt_mstrict_align {} {
11821 return [check_no_compiler_messages opt_mstrict_align assembly {
11822 void foo(void) {}
11823 } "-mstrict-align -mno-strict-align"]
11824 }
11825
11826 # Return 1 if the target has <ucontext.h>.
11827
11828 proc check_effective_target_ucontext_h { } {
11829 return [check_no_compiler_messages ucontext_h assembly {
11830 #include <ucontext.h>
11831 }]
11832 }
11833
11834 proc check_effective_target_aarch64_tiny { } {
11835 if { [istarget aarch64*-*-*] } {
11836 return [check_no_compiler_messages aarch64_tiny object {
11837 #ifdef __AARCH64_CMODEL_TINY__
11838 int dummy;
11839 #else
11840 #error target not AArch64 tiny code model
11841 #endif
11842 }]
11843 } else {
11844 return 0
11845 }
11846 }
11847
11848 # Create functions to check that the AArch64 assembler supports the
11849 # various architecture extensions via the .arch_extension pseudo-op.
11850
11851 foreach { aarch64_ext } { "fp" "simd" "crypto" "crc" "lse" "dotprod" "sve"
11852 "i8mm" "f32mm" "f64mm" "bf16" "sb" "sve2" "ls64"
11853 "sme" "sme-i16i64" "sme2" } {
11854 eval [string map [list FUNC $aarch64_ext] {
11855 proc check_effective_target_aarch64_asm_FUNC_ok { } {
11856 if { [istarget aarch64*-*-*] } {
11857 return [check_no_compiler_messages aarch64_FUNC_assembler object {
11858 __asm__ (".arch_extension FUNC");
11859 } "-march=armv8-a+FUNC"]
11860 } else {
11861 return 0
11862 }
11863 }
11864 }]
11865 }
11866
11867 proc check_effective_target_aarch64_small { } {
11868 if { [istarget aarch64*-*-*] } {
11869 return [check_no_compiler_messages aarch64_small object {
11870 #ifdef __AARCH64_CMODEL_SMALL__
11871 int dummy;
11872 #else
11873 #error target not AArch64 small code model
11874 #endif
11875 }]
11876 } else {
11877 return 0
11878 }
11879 }
11880
11881 proc check_effective_target_aarch64_large { } {
11882 if { [istarget aarch64*-*-*] } {
11883 return [check_no_compiler_messages aarch64_large object {
11884 #ifdef __AARCH64_CMODEL_LARGE__
11885 int dummy;
11886 #else
11887 #error target not AArch64 large code model
11888 #endif
11889 }]
11890 } else {
11891 return 0
11892 }
11893 }
11894
11895 # Return 1 if the assembler accepts the aarch64 .variant_pcs directive.
11896
11897 proc check_effective_target_aarch64_variant_pcs { } {
11898 if { [istarget aarch64*-*-*] } {
11899 return [check_no_compiler_messages aarch64_variant_pcs object {
11900 __asm__ (".variant_pcs foo");
11901 }]
11902 } else {
11903 return 0
11904 }
11905 }
11906
11907 # Return 1 if this is a reduced AVR Tiny core. Such cores have different
11908 # register set, instruction set, addressing capabilities and ABI.
11909
11910 proc check_effective_target_avr_tiny { } {
11911 if { [istarget avr*-*-*] } {
11912 return [check_no_compiler_messages avr_tiny object {
11913 #ifdef __AVR_TINY__
11914 int dummy;
11915 #else
11916 #error target not a reduced AVR Tiny core
11917 #endif
11918 }]
11919 } else {
11920 return 0
11921 }
11922 }
11923
11924 # Return 1 if <fenv.h> is available.
11925
11926 proc check_effective_target_fenv {} {
11927 return [check_no_compiler_messages fenv object {
11928 #include <fenv.h>
11929 } [add_options_for_ieee "-std=gnu99"]]
11930 }
11931
11932 # Return 1 if <fenv.h> is available with all the standard IEEE
11933 # exceptions and floating-point exceptions are raised by arithmetic
11934 # operations. (If the target requires special options for "inexact"
11935 # exceptions, those need to be specified in the testcases.)
11936
11937 proc check_effective_target_fenv_exceptions {} {
11938 return [check_runtime fenv_exceptions {
11939 #include <fenv.h>
11940 #include <stdlib.h>
11941 #ifndef FE_DIVBYZERO
11942 # error Missing FE_DIVBYZERO
11943 #endif
11944 #ifndef FE_INEXACT
11945 # error Missing FE_INEXACT
11946 #endif
11947 #ifndef FE_INVALID
11948 # error Missing FE_INVALID
11949 #endif
11950 #ifndef FE_OVERFLOW
11951 # error Missing FE_OVERFLOW
11952 #endif
11953 #ifndef FE_UNDERFLOW
11954 # error Missing FE_UNDERFLOW
11955 #endif
11956 volatile float a = 0.0f, r;
11957 int
11958 main (void)
11959 {
11960 r = a / a;
11961 if (fetestexcept (FE_INVALID))
11962 exit (0);
11963 else
11964 abort ();
11965 }
11966 } [add_options_for_ieee "-std=gnu99"]]
11967 }
11968
11969 # Return 1 if <fenv.h> is available with all the standard IEEE
11970 # exceptions and floating-point exceptions are raised by arithmetic
11971 # operations for decimal floating point. (If the target requires
11972 # special options for "inexact" exceptions, those need to be specified
11973 # in the testcases.)
11974
11975 proc check_effective_target_fenv_exceptions_dfp {} {
11976 return [check_runtime fenv_exceptions_dfp {
11977 #include <fenv.h>
11978 #include <stdlib.h>
11979 #ifndef FE_DIVBYZERO
11980 # error Missing FE_DIVBYZERO
11981 #endif
11982 #ifndef FE_INEXACT
11983 # error Missing FE_INEXACT
11984 #endif
11985 #ifndef FE_INVALID
11986 # error Missing FE_INVALID
11987 #endif
11988 #ifndef FE_OVERFLOW
11989 # error Missing FE_OVERFLOW
11990 #endif
11991 #ifndef FE_UNDERFLOW
11992 # error Missing FE_UNDERFLOW
11993 #endif
11994 volatile _Decimal64 a = 0.0DD, r;
11995 int
11996 main (void)
11997 {
11998 r = a / a;
11999 if (fetestexcept (FE_INVALID))
12000 exit (0);
12001 else
12002 abort ();
12003 }
12004 } [add_options_for_ieee "-std=gnu99"]]
12005 }
12006
12007 # Return 1 if <fenv.h> is available with all the standard IEEE
12008 # exceptions and floating-point exceptions are raised by arithmetic
12009 # operations. (If the target requires special options for "inexact"
12010 # exceptions, those need to be specified in the testcases.)
12011
12012 proc check_effective_target_fenv_exceptions_double {} {
12013 return [check_runtime fenv_exceptions_double {
12014 #include <fenv.h>
12015 #include <stdlib.h>
12016 #ifndef FE_DIVBYZERO
12017 # error Missing FE_DIVBYZERO
12018 #endif
12019 #ifndef FE_INEXACT
12020 # error Missing FE_INEXACT
12021 #endif
12022 #ifndef FE_INVALID
12023 # error Missing FE_INVALID
12024 #endif
12025 #ifndef FE_OVERFLOW
12026 # error Missing FE_OVERFLOW
12027 #endif
12028 #ifndef FE_UNDERFLOW
12029 # error Missing FE_UNDERFLOW
12030 #endif
12031 volatile double a = 0.0f, r;
12032 int
12033 main (void)
12034 {
12035 r = a / a;
12036 if (fetestexcept (FE_INVALID))
12037 exit (0);
12038 else
12039 abort ();
12040 }
12041 } [add_options_for_ieee "-std=gnu99"]]
12042 }
12043
12044 # Return 1 if <fenv.h> is available with all the standard IEEE
12045 # exceptions and floating-point exceptions are raised by arithmetic
12046 # operations. (If the target requires special options for "inexact"
12047 # exceptions, those need to be specified in the testcases.)
12048
12049 proc check_effective_target_fenv_exceptions_long_double {} {
12050 return [check_runtime fenv_exceptions_long_double {
12051 #include <fenv.h>
12052 #include <stdlib.h>
12053 #ifndef FE_DIVBYZERO
12054 # error Missing FE_DIVBYZERO
12055 #endif
12056 #ifndef FE_INEXACT
12057 # error Missing FE_INEXACT
12058 #endif
12059 #ifndef FE_INVALID
12060 # error Missing FE_INVALID
12061 #endif
12062 #ifndef FE_OVERFLOW
12063 # error Missing FE_OVERFLOW
12064 #endif
12065 #ifndef FE_UNDERFLOW
12066 # error Missing FE_UNDERFLOW
12067 #endif
12068 volatile long double a = 0.0f, r;
12069 int
12070 main (void)
12071 {
12072 r = a / a;
12073 if (fetestexcept (FE_INVALID))
12074 exit (0);
12075 else
12076 abort ();
12077 }
12078 } [add_options_for_ieee "-std=gnu99"]]
12079 }
12080
12081 # Return 1 if -fexceptions is supported.
12082
12083 proc check_effective_target_exceptions {} {
12084 if { [istarget amdgcn*-*-*] } {
12085 return 0
12086 }
12087 return 1
12088 }
12089
12090 # Used to check if the testing configuration supports exceptions.
12091 # Returns 0 if exceptions are unsupported or disabled (e.g. by passing
12092 # -fno-exceptions). Returns 1 if exceptions are enabled.
12093 proc check_effective_target_exceptions_enabled {} {
12094 return [check_cached_effective_target exceptions_enabled {
12095 if { [check_effective_target_exceptions] } {
12096 return [check_no_compiler_messages exceptions_enabled assembly {
12097 // C++
12098 void foo (void)
12099 {
12100 throw 1;
12101 }
12102 }]
12103 } else {
12104 # If exceptions aren't supported, then they're not enabled.
12105 return 0
12106 }
12107 }]
12108 }
12109
12110 proc check_effective_target_tiny {} {
12111 return [check_cached_effective_target tiny {
12112 if { [istarget aarch64*-*-*]
12113 && [check_effective_target_aarch64_tiny] } {
12114 return 1
12115 }
12116 if { [istarget avr-*-*]
12117 && [check_effective_target_avr_tiny] } {
12118 return 1
12119 }
12120 # PRU Program Counter is 16-bits, and trampolines are not supported.
12121 # Hence directly declare as a tiny target.
12122 if [istarget pru-*-*] {
12123 return 1
12124 }
12125 return 0
12126 }]
12127 }
12128
12129 # Return 1 if the target supports -mbranch-cost=N option.
12130
12131 proc check_effective_target_branch_cost {} {
12132 if { [ istarget arm*-*-*]
12133 || [istarget avr*-*-*]
12134 || [istarget csky*-*-*]
12135 || [istarget epiphany*-*-*]
12136 || [istarget frv*-*-*]
12137 || [istarget i?86-*-*] || [istarget x86_64-*-*]
12138 || [istarget loongarch*-*-*]
12139 || [istarget mips*-*-*]
12140 || [istarget s390*-*-*]
12141 || [istarget riscv*-*-*]
12142 || [istarget sh*-*-*] } {
12143 return 1
12144 }
12145 return 0
12146 }
12147
12148 # Record that dg-final test TEST requires convential compilation.
12149
12150 proc set_required_options_for { test } {
12151 if { [info proc $test] == "" } {
12152 perror "$test does not exist"
12153 exit 1
12154 }
12155 proc ${test}_required_options {} {
12156 global gcc_set_required_options
12157 upvar 1 extra_tool_flags extra_tool_flags
12158 if {[regexp -- "^scan-assembler" [info level 0]]
12159 && ![string match "*-fident*" $extra_tool_flags]} {
12160 # Do not let .ident confuse assembler scan tests
12161 return [list $gcc_set_required_options "-fno-ident"]
12162 }
12163 return $gcc_set_required_options
12164 }
12165 }
12166
12167 # Record that dg-final test scan-ltrans-tree-dump* requires -flto-partition=one
12168 # in order to force a single partition, allowing scan-ltrans-tree-dump* to scan
12169 # a dump file *.exe.ltrans0.*.
12170
12171 proc scan-ltrans-tree-dump_required_options {} {
12172 return "-flto-partition=one"
12173 }
12174 proc scan-ltrans-tree-dump-times_required_options {} {
12175 return "-flto-partition=one"
12176 }
12177 proc scan-ltrans-tree-dump-not_required_options {} {
12178 return "-flto-partition=one"
12179 }
12180 proc scan-ltrans-tree-dump-dem_required_options {} {
12181 return "-flto-partition=one"
12182 }
12183 proc scan-ltrans-tree-dump-dem-not_required_options {} {
12184 return "-flto-partition=one"
12185 }
12186
12187 # Return 1 if the x86-64 target supports PIE with copy reloc, 0
12188 # otherwise. Cache the result.
12189
12190 proc check_effective_target_pie_copyreloc { } {
12191 global tool
12192 global GCC_UNDER_TEST
12193
12194 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
12195 return 0
12196 }
12197
12198 # Need auto-host.h to check linker support.
12199 if { ![file exists ../../auto-host.h ] } {
12200 return 0
12201 }
12202
12203 return [check_cached_effective_target pie_copyreloc {
12204 # Set up and compile to see if linker supports PIE with copy
12205 # reloc. Include the current process ID in the file names to
12206 # prevent conflicts with invocations for multiple testsuites.
12207
12208 set src pie[pid].c
12209 set obj pie[pid].o
12210
12211 set f [open $src "w"]
12212 puts $f "#include \"../../auto-host.h\""
12213 puts $f "#if HAVE_LD_PIE_COPYRELOC == 0"
12214 puts $f "# error Linker does not support PIE with copy reloc."
12215 puts $f "#endif"
12216 close $f
12217
12218 verbose "check_effective_target_pie_copyreloc compiling testfile $src" 2
12219 set lines [${tool}_target_compile $src $obj object ""]
12220
12221 file delete $src
12222 file delete $obj
12223
12224 if [string match "" $lines] then {
12225 verbose "check_effective_target_pie_copyreloc testfile compilation passed" 2
12226 return 1
12227 } else {
12228 verbose "check_effective_target_pie_copyreloc testfile compilation failed" 2
12229 return 0
12230 }
12231 }]
12232 }
12233
12234 # Return 1 if the x86 target supports R_386_GOT32X relocation, 0
12235 # otherwise. Cache the result.
12236
12237 proc check_effective_target_got32x_reloc { } {
12238 global tool
12239 global GCC_UNDER_TEST
12240
12241 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
12242 return 0
12243 }
12244
12245 # Need auto-host.h to check linker support.
12246 if { ![file exists ../../auto-host.h ] } {
12247 return 0
12248 }
12249
12250 return [check_cached_effective_target got32x_reloc {
12251 # Include the current process ID in the file names to prevent
12252 # conflicts with invocations for multiple testsuites.
12253
12254 set src got32x[pid].c
12255 set obj got32x[pid].o
12256
12257 set f [open $src "w"]
12258 puts $f "#include \"../../auto-host.h\""
12259 puts $f "#if HAVE_AS_IX86_GOT32X == 0"
12260 puts $f "# error Assembler does not support R_386_GOT32X."
12261 puts $f "#endif"
12262 close $f
12263
12264 verbose "check_effective_target_got32x_reloc compiling testfile $src" 2
12265 set lines [${tool}_target_compile $src $obj object ""]
12266
12267 file delete $src
12268 file delete $obj
12269
12270 if [string match "" $lines] then {
12271 verbose "check_effective_target_got32x_reloc testfile compilation passed" 2
12272 return 1
12273 } else {
12274 verbose "check_effective_target_got32x_reloc testfile compilation failed" 2
12275 return 0
12276 }
12277 }]
12278
12279 return $got32x_reloc_available_saved
12280 }
12281
12282 # Return 1 if the x86 target supports calling ___tls_get_addr via GOT,
12283 # 0 otherwise. Cache the result.
12284
12285 proc check_effective_target_tls_get_addr_via_got { } {
12286 global tool
12287 global GCC_UNDER_TEST
12288
12289 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
12290 return 0
12291 }
12292
12293 # Need auto-host.h to check linker support.
12294 if { ![file exists ../../auto-host.h ] } {
12295 return 0
12296 }
12297
12298 return [check_cached_effective_target tls_get_addr_via_got {
12299 # Include the current process ID in the file names to prevent
12300 # conflicts with invocations for multiple testsuites.
12301
12302 set src tls_get_addr_via_got[pid].c
12303 set obj tls_get_addr_via_got[pid].o
12304
12305 set f [open $src "w"]
12306 puts $f "#include \"../../auto-host.h\""
12307 puts $f "#if HAVE_AS_IX86_TLS_GET_ADDR_GOT == 0"
12308 puts $f "# error Assembler/linker do not support calling ___tls_get_addr via GOT."
12309 puts $f "#endif"
12310 close $f
12311
12312 verbose "check_effective_target_tls_get_addr_via_got compiling testfile $src" 2
12313 set lines [${tool}_target_compile $src $obj object ""]
12314
12315 file delete $src
12316 file delete $obj
12317
12318 if [string match "" $lines] then {
12319 verbose "check_effective_target_tls_get_addr_via_got testfile compilation passed" 2
12320 return 1
12321 } else {
12322 verbose "check_effective_target_tls_get_addr_via_got testfile compilation failed" 2
12323 return 0
12324 }
12325 }]
12326 }
12327
12328 # Return 1 if the target uses comdat groups.
12329
12330 proc check_effective_target_comdat_group {} {
12331 return [check_no_messages_and_pattern comdat_group "\.section\[^\n\r]*,comdat|\.group\[^\n\r]*,#comdat" assembly {
12332 // C++
12333 inline int foo () { return 1; }
12334 int (*fn) () = foo;
12335 }]
12336 }
12337
12338 # Return 1 if target supports __builtin_eh_return
12339 proc check_effective_target_builtin_eh_return { } {
12340 return [check_no_compiler_messages builtin_eh_return object {
12341 void test (long l, void *p)
12342 {
12343 __builtin_eh_return (l, p);
12344 }
12345 } "" ]
12346 }
12347
12348 # Return 1 if the target supports max reduction for vectors.
12349
12350 proc check_effective_target_vect_max_reduc { } {
12351 if { [istarget aarch64*-*-*] || [is-effective-target arm_neon]
12352 || [check_effective_target_riscv_v]
12353 || [check_effective_target_loongarch_sx] } {
12354 return 1
12355 }
12356 return 0
12357 }
12358
12359 # Return 1 if the compiler has been configured with nvptx offloading.
12360
12361 proc check_effective_target_offload_nvptx { } {
12362 return [check_no_compiler_messages offload_nvptx assembly {
12363 int main () {return 0;}
12364 } "-foffload=nvptx-none" ]
12365 }
12366
12367 # Return 1 if the compiler has been configured with gcn offloading.
12368
12369 proc check_effective_target_offload_gcn { } {
12370 return [check_no_compiler_messages offload_gcn assembly {
12371 int main () {return 0;}
12372 } "-foffload=amdgcn-amdhsa" ]
12373 }
12374
12375 # Return 1 if the target support -fprofile-update=atomic
12376 proc check_effective_target_profile_update_atomic {} {
12377 return [check_no_compiler_messages profile_update_atomic assembly {
12378 int main (void) { return 0; }
12379 } "-fprofile-update=atomic -fprofile-generate"]
12380 }
12381
12382 # Return 1 if vector (va - vector add) instructions are understood by
12383 # the assembler and can be executed. This also covers checking for
12384 # the VX kernel feature. A kernel without that feature does not
12385 # enable the vector facility and the following check will die with a
12386 # signal.
12387 proc check_effective_target_s390_vx { } {
12388 if ![istarget s390*-*-*] then {
12389 return 0;
12390 }
12391
12392 return [check_runtime s390_check_vx {
12393 int main (void)
12394 {
12395 asm ("va %%v24, %%v26, %%v28, 3" : : : "v24", "v26", "v28");
12396 return 0;
12397 }
12398 } "-march=z13 -mzarch" ]
12399 }
12400
12401 # Same as above but for the z14 vector enhancement facility. Test
12402 # is performed with the vector nand instruction.
12403 proc check_effective_target_s390_vxe { } {
12404 if ![istarget s390*-*-*] then {
12405 return 0;
12406 }
12407
12408 return [check_runtime s390_check_vxe {
12409 int main (void)
12410 {
12411 asm ("vnn %%v24, %%v26, %%v28" : : : "v24", "v26", "v28");
12412 return 0;
12413 }
12414 } "-march=z14 -mzarch" ]
12415 }
12416
12417 # Same as above but for the arch13 vector enhancement facility. Test
12418 # is performed with the vector shift left double by bit instruction.
12419 proc check_effective_target_s390_vxe2 { } {
12420 if ![istarget s390*-*-*] then {
12421 return 0;
12422 }
12423
12424 return [check_runtime s390_check_vxe2 {
12425 int main (void)
12426 {
12427 asm ("vsld %%v24, %%v26, %%v28, 3" : : : "v24", "v26", "v28");
12428 return 0;
12429 }
12430 } "-march=arch13 -mzarch" ]
12431 }
12432
12433 # Same as above but for the arch14 NNPA facility.
12434 proc check_effective_target_s390_nnpa { } {
12435 if ![istarget s390*-*-*] then {
12436 return 0;
12437 }
12438
12439 return [check_runtime s390_check_nnpa {
12440 int main (void)
12441 {
12442 asm ("vzero %%v24\n\t"
12443 "vcrnf %%v24,%%v24,%%v24,0,2" : : : "v24");
12444 return 0;
12445 }
12446 } "-march=arch14 -mzarch" ]
12447 }
12448
12449 #For versions of ARM architectures that have hardware div insn,
12450 #disable the divmod transform
12451
12452 proc check_effective_target_arm_divmod_simode { } {
12453 return [check_no_compiler_messages arm_divmod assembly {
12454 #ifdef __ARM_ARCH_EXT_IDIV__
12455 #error has div insn
12456 #endif
12457 int i;
12458 }]
12459 }
12460
12461 # Return 1 if target supports divmod hardware insn or divmod libcall.
12462
12463 proc check_effective_target_divmod { } {
12464 #TODO: Add checks for all targets that have either hardware divmod insn
12465 # or define libfunc for divmod.
12466 if { [istarget arm*-*-*]
12467 || [istarget i?86-*-*] || [istarget x86_64-*-*]
12468 || [istarget amdgcn-*-*] } {
12469 return 1
12470 }
12471 return 0
12472 }
12473
12474 # Return 1 if target supports divmod for SImode. The reason for
12475 # separating this from check_effective_target_divmod is that
12476 # some versions of ARM architecture define div instruction
12477 # only for simode, and for these archs, we do not want to enable
12478 # divmod transform for simode.
12479
12480 proc check_effective_target_divmod_simode { } {
12481 if { [istarget arm*-*-*] } {
12482 return [check_effective_target_arm_divmod_simode]
12483 }
12484
12485 return [check_effective_target_divmod]
12486 }
12487
12488 # Return 1 if store merging optimization is applicable for target.
12489 # Store merging is not profitable for targets like the avr which
12490 # can load/store only one byte at a time. Use int size as a proxy
12491 # for the number of bytes the target can write, and skip for targets
12492 # with a smallish (< 32) size.
12493
12494 proc check_effective_target_store_merge { } {
12495 if { [is-effective-target non_strict_align ] && [is-effective-target int32plus] } {
12496 return 1
12497 }
12498
12499 return 0
12500 }
12501
12502 # Return 1 if we're able to assemble rdrand
12503
12504 proc check_effective_target_rdrand { } {
12505 return [check_no_compiler_messages_nocache rdrand object {
12506 unsigned int
12507 __foo(void)
12508 {
12509 unsigned int val;
12510 __builtin_ia32_rdrand32_step(&val);
12511 return val;
12512 }
12513 } "-mrdrnd" ]
12514 }
12515
12516 # Return 1 if the target supports coprocessor instructions: cdp, ldc, ldcl,
12517 # stc, stcl, mcr and mrc.
12518 proc check_effective_target_arm_coproc1_ok_nocache { } {
12519 if { ![istarget arm*-*-*] } {
12520 return 0
12521 }
12522 return [check_no_compiler_messages_nocache arm_coproc1_ok assembly {
12523 #if (__thumb__ && !__thumb2__) || __ARM_ARCH < 4
12524 #error FOO
12525 #endif
12526 #include <arm_acle.h>
12527 }]
12528 }
12529
12530 proc check_effective_target_arm_coproc1_ok { } {
12531 return [check_cached_effective_target arm_coproc1_ok \
12532 check_effective_target_arm_coproc1_ok_nocache]
12533 }
12534
12535 # Return 1 if the target supports all coprocessor instructions checked by
12536 # check_effective_target_arm_coproc1_ok in addition to the following: cdp2,
12537 # ldc2, ldc2l, stc2, stc2l, mcr2 and mrc2.
12538 proc check_effective_target_arm_coproc2_ok_nocache { } {
12539 if { ![check_effective_target_arm_coproc1_ok] } {
12540 return 0
12541 }
12542 return [check_no_compiler_messages_nocache arm_coproc2_ok assembly {
12543 #if (__thumb__ && !__thumb2__) || __ARM_ARCH < 5
12544 #error FOO
12545 #endif
12546 #include <arm_acle.h>
12547 }]
12548 }
12549
12550 proc check_effective_target_arm_coproc2_ok { } {
12551 return [check_cached_effective_target arm_coproc2_ok \
12552 check_effective_target_arm_coproc2_ok_nocache]
12553 }
12554
12555 # Return 1 if the target supports all coprocessor instructions checked by
12556 # check_effective_target_arm_coproc2_ok in addition the following: mcrr and
12557 # mrrc.
12558 proc check_effective_target_arm_coproc3_ok_nocache { } {
12559 if { ![check_effective_target_arm_coproc2_ok] } {
12560 return 0
12561 }
12562 return [check_no_compiler_messages_nocache arm_coproc3_ok assembly {
12563 #if (__thumb__ && !__thumb2__) \
12564 || (__ARM_ARCH < 6 && !defined (__ARM_ARCH_5TE__))
12565 #error FOO
12566 #endif
12567 #include <arm_acle.h>
12568 }]
12569 }
12570
12571 proc check_effective_target_arm_coproc3_ok { } {
12572 return [check_cached_effective_target arm_coproc3_ok \
12573 check_effective_target_arm_coproc3_ok_nocache]
12574 }
12575
12576 # Return 1 if the target supports all coprocessor instructions checked by
12577 # check_effective_target_arm_coproc3_ok in addition the following: mcrr2 and
12578 # mrcc2.
12579 proc check_effective_target_arm_coproc4_ok_nocache { } {
12580 if { ![check_effective_target_arm_coproc3_ok] } {
12581 return 0
12582 }
12583 return [check_no_compiler_messages_nocache arm_coproc4_ok assembly {
12584 #if (__thumb__ && !__thumb2__) || __ARM_ARCH < 6
12585 #error FOO
12586 #endif
12587 #include <arm_acle.h>
12588 }]
12589 }
12590
12591 proc check_effective_target_arm_coproc4_ok { } {
12592 return [check_cached_effective_target arm_coproc4_ok \
12593 check_effective_target_arm_coproc4_ok_nocache]
12594 }
12595
12596 # Return 1 if the target supports the auto_inc_dec optimization pass.
12597 proc check_effective_target_autoincdec { } {
12598 if { ![check_no_compiler_messages auto_incdec assembly { void f () { }
12599 } "-O2 -fdump-rtl-auto_inc_dec" ] } {
12600 return 0
12601 }
12602
12603 set dumpfile [glob -nocomplain "auto_incdec[pid].c.\[0-9\]\[0-9\]\[0-9\]r.auto_inc_dec"]
12604 if { [file exists $dumpfile ] } {
12605 file delete $dumpfile
12606 return 1
12607 }
12608 return 0
12609 }
12610
12611 # Return 1 if the target has support for stack probing designed
12612 # to avoid stack-clash style attacks.
12613 #
12614 # This is used to restrict the stack-clash mitigation tests to
12615 # just those targets that have been explicitly supported.
12616 #
12617 # In addition to the prologue work on those targets, each target's
12618 # properties should be described in the functions below so that
12619 # tests do not become a mess of unreadable target conditions.
12620 #
12621 proc check_effective_target_supports_stack_clash_protection { } {
12622
12623 if { [istarget x86_64-*-*] || [istarget i?86-*-*]
12624 || [istarget powerpc*-*-*] || [istarget rs6000*-*-*]
12625 || [istarget aarch64*-**] || [istarget s390*-*-*]
12626 || [istarget loongarch64*-**] } {
12627 return 1
12628 }
12629 return 0
12630 }
12631
12632 # Return 1 if the target creates a frame pointer for non-leaf functions
12633 # Note we ignore cases where we apply tail call optimization here.
12634 proc check_effective_target_frame_pointer_for_non_leaf { } {
12635 # Solaris/x86 defaults to -fno-omit-frame-pointer.
12636 if { [istarget i?86-*-solaris*] || [istarget x86_64-*-solaris*] } {
12637 return 1
12638 }
12639
12640 return 0
12641 }
12642
12643 # Return 1 if the target can perform tail-call optimizations of the
12644 # most trivial type.
12645 proc check_effective_target_tail_call { } {
12646 return [check_no_messages_and_pattern tail_call ",SIBCALL" rtl-expand {
12647 __attribute__((__noipa__)) void foo (void) { }
12648 __attribute__((__noipa__)) void bar (void) { foo(); }
12649 } {-O2 -fdump-rtl-expand-all}] ;# The "SIBCALL" note requires a detailed dump.
12650 }
12651
12652 # Return 1 if the target's calling sequence or its ABI
12653 # create implicit stack probes at or prior to function entry.
12654 proc check_effective_target_caller_implicit_probes { } {
12655
12656 # On x86/x86_64 the call instruction itself pushes the return
12657 # address onto the stack. That is an implicit probe of *sp.
12658 if { [istarget x86_64-*-*] || [istarget i?86-*-*] } {
12659 return 1
12660 }
12661
12662 # On PPC, the ABI mandates that the address of the outer
12663 # frame be stored at *sp. Thus each allocation of stack
12664 # space is itself an implicit probe of *sp.
12665 if { [istarget powerpc*-*-*] || [istarget rs6000*-*-*] } {
12666 return 1
12667 }
12668
12669 # s390's ABI has a register save area allocated by the
12670 # caller for use by the callee. The mere existence does
12671 # not constitute a probe by the caller, but when the slots
12672 # used by the callee those stores are implicit probes.
12673 if { [istarget s390*-*-*] } {
12674 return 1
12675 }
12676
12677 # Not strictly true on aarch64, but we have agreed that we will
12678 # consider any function that pushes SP more than 3kbytes into
12679 # the guard page as broken. This essentially means that we can
12680 # consider the aarch64 as having a caller implicit probe at
12681 # *(sp + 1k).
12682 if { [istarget aarch64*-*-*] } {
12683 return 1;
12684 }
12685
12686 if { [istarget loongarch64*-*-*] } {
12687 return 1;
12688 }
12689
12690 return 0
12691 }
12692
12693 # Targets that potentially realign the stack pointer often cause residual
12694 # stack allocations and make it difficult to elimination loops or residual
12695 # allocations for dynamic stack allocations
12696 proc check_effective_target_callee_realigns_stack { } {
12697 if { [istarget x86_64-*-*] || [istarget i?86-*-*] } {
12698 return 1
12699 }
12700 return 0
12701 }
12702
12703 # Return 1 if CET instructions can be compiled.
12704 proc check_effective_target_cet { } {
12705 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
12706 return 0
12707 }
12708 return [check_no_compiler_messages cet object {
12709 void foo (void)
12710 {
12711 asm ("setssbsy");
12712 }
12713 } "-O2 -fcf-protection" ]
12714 }
12715
12716 # Return 1 if target supports floating point "infinite"
12717 proc check_effective_target_inf { } {
12718 return [check_no_compiler_messages supports_inf assembly {
12719 const double pinf = __builtin_inf ();
12720 }]
12721 }
12722
12723 # Return 1 if target supports floating point "infinite" for float.
12724 proc check_effective_target_inff { } {
12725 return [check_no_compiler_messages supports_inff assembly {
12726 const float pinf = __builtin_inff ();
12727 }]
12728 }
12729
12730 # Return 1 if the target supports ARMv8.3 Adv.SIMD Complex instructions
12731 # instructions, 0 otherwise. The test is valid for ARM and for AArch64.
12732 # Record the command line options needed.
12733
12734 proc check_effective_target_arm_v8_3a_complex_neon_ok_nocache { } {
12735 global et_arm_v8_3a_complex_neon_flags
12736 set et_arm_v8_3a_complex_neon_flags ""
12737
12738 if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
12739 return 0;
12740 }
12741
12742 # Iterate through sets of options to find the compiler flags that
12743 # need to be added to the -march option.
12744 foreach flags {"" "-mfloat-abi=softfp -mfpu=auto" "-mfloat-abi=hard -mfpu=auto"} {
12745 if { [check_no_compiler_messages_nocache \
12746 arm_v8_3a_complex_neon_ok assembly {
12747 #if !defined (__ARM_FEATURE_COMPLEX)
12748 #error "__ARM_FEATURE_COMPLEX not defined"
12749 #endif
12750 } "$flags -march=armv8.3-a"] } {
12751 set et_arm_v8_3a_complex_neon_flags "$flags -march=armv8.3-a"
12752 return 1;
12753 }
12754 }
12755
12756 return 0;
12757 }
12758
12759 proc check_effective_target_arm_v8_3a_complex_neon_ok { } {
12760 return [check_cached_effective_target arm_v8_3a_complex_neon_ok \
12761 check_effective_target_arm_v8_3a_complex_neon_ok_nocache]
12762 }
12763
12764 proc add_options_for_arm_v8_3a_complex_neon { flags } {
12765 if { ! [check_effective_target_arm_v8_3a_complex_neon_ok] } {
12766 return "$flags"
12767 }
12768 global et_arm_v8_3a_complex_neon_flags
12769 return "$flags $et_arm_v8_3a_complex_neon_flags"
12770 }
12771
12772 # Return 1 if the target supports ARMv8.3 Adv.SIMD + FP16 Complex instructions
12773 # instructions, 0 otherwise. The test is valid for ARM and for AArch64.
12774 # Record the command line options needed.
12775
12776 proc check_effective_target_arm_v8_3a_fp16_complex_neon_ok_nocache { } {
12777 global et_arm_v8_3a_fp16_complex_neon_flags
12778 set et_arm_v8_3a_fp16_complex_neon_flags ""
12779
12780 if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
12781 return 0;
12782 }
12783
12784 # Iterate through sets of options to find the compiler flags that
12785 # need to be added to the -march option.
12786 foreach flags {"" "-mfloat-abi=softfp -mfpu=auto" "-mfloat-abi=hard -mfpu=auto"} {
12787 if { [check_no_compiler_messages_nocache \
12788 arm_v8_3a_fp16_complex_neon_ok assembly {
12789 #if !defined (__ARM_FEATURE_COMPLEX)
12790 #error "__ARM_FEATURE_COMPLEX not defined"
12791 #endif
12792 } "$flags -march=armv8.3-a+fp16"] } {
12793 set et_arm_v8_3a_fp16_complex_neon_flags \
12794 "$flags -march=armv8.3-a+fp16"
12795 return 1;
12796 }
12797 }
12798
12799 return 0;
12800 }
12801
12802 proc check_effective_target_arm_v8_3a_fp16_complex_neon_ok { } {
12803 return [check_cached_effective_target arm_v8_3a_fp16_complex_neon_ok \
12804 check_effective_target_arm_v8_3a_fp16_complex_neon_ok_nocache]
12805 }
12806
12807 proc add_options_for_arm_v8_3a_fp16_complex_neon { flags } {
12808 if { ! [check_effective_target_arm_v8_3a_fp16_complex_neon_ok] } {
12809 return "$flags"
12810 }
12811 global et_arm_v8_3a_fp16_complex_neon_flags
12812 return "$flags $et_arm_v8_3a_fp16_complex_neon_flags"
12813 }
12814
12815
12816 # Return 1 if the target supports executing AdvSIMD instructions from ARMv8.3
12817 # with the complex instruction extension, 0 otherwise. The test is valid for
12818 # ARM and for AArch64.
12819
12820 proc check_effective_target_arm_v8_3a_complex_neon_hw { } {
12821 if { ![check_effective_target_arm_v8_3a_complex_neon_ok] } {
12822 return 1;
12823 }
12824 return [check_runtime arm_v8_3a_complex_neon_hw_available {
12825 #include "arm_neon.h"
12826 int
12827 main (void)
12828 {
12829
12830 float32x2_t results = {-4.0,5.0};
12831 float32x2_t a = {1.0,3.0};
12832 float32x2_t b = {2.0,5.0};
12833
12834 #ifdef __ARM_ARCH_ISA_A64
12835 asm ("fcadd %0.2s, %1.2s, %2.2s, #90"
12836 : "=w"(results)
12837 : "w"(a), "w"(b)
12838 : /* No clobbers. */);
12839
12840 #else
12841 asm ("vcadd.f32 %P0, %P1, %P2, #90"
12842 : "=w"(results)
12843 : "w"(a), "w"(b)
12844 : /* No clobbers. */);
12845 #endif
12846
12847 return (results[0] == 8 && results[1] == 24) ? 0 : 1;
12848 }
12849 } [add_options_for_arm_v8_3a_complex_neon ""]]
12850 }
12851
12852 # Return 1 if the assembler supports assembling the Armv8.3 pointer authentication B key directive
12853 proc check_effective_target_arm_v8_3a_bkey_directive { } {
12854 return [check_no_compiler_messages cet object {
12855 int main(void) {
12856 asm (".cfi_b_key_frame");
12857 return 0;
12858 }
12859 }]
12860 }
12861
12862 # Return 1 if the target supports executing the Armv8.1-M Mainline Low
12863 # Overhead Loop, 0 otherwise. The test is valid for ARM.
12864
12865 proc check_effective_target_arm_v8_1_lob_ok { } {
12866 if { ![check_effective_target_arm_cortex_m] } {
12867 return 0;
12868 } else {
12869 return [check_runtime arm_v8_1_lob_hw_available {
12870 int
12871 main (void)
12872 { int i = 0;
12873 asm ("movw r3, #10\n\t" /* movs? */
12874 "dls lr, r3" : : : "r3", "lr");
12875 loop:
12876 i++;
12877 asm goto ("le lr, %l0" : : : "lr" : loop);
12878 return i != 10;
12879 }
12880 } "-march=armv8.1-m.main -mthumb" ]
12881 }
12882 }
12883
12884 # Return 1 if this is an ARM target where Thumb-2 is used without
12885 # options added by the test and the target does not support executing
12886 # the Armv8.1-M Mainline Low Overhead Loop, 0 otherwise. The test is
12887 # valid for ARM.
12888
12889 proc check_effective_target_arm_thumb2_no_arm_v8_1_lob { } {
12890 if { [check_effective_target_arm_thumb2]
12891 && ![check_effective_target_arm_v8_1_lob_ok] } {
12892 return 1
12893 }
12894 return 0
12895 }
12896
12897 # Return 1 if this is an ARM target where -mthumb causes Thumb-2 to be
12898 # used and the target does not support executing the Armv8.1-M
12899 # Mainline Low Overhead Loop, 0 otherwise. The test is valid for ARM.
12900
12901 proc check_effective_target_arm_thumb2_ok_no_arm_v8_1_lob { } {
12902 if { [check_effective_target_arm_thumb2_ok]
12903 && ![check_effective_target_arm_v8_1_lob_ok] } {
12904 return 1
12905 }
12906 return 0
12907 }
12908
12909 # Returns 1 if the target is using glibc, 0 otherwise.
12910
12911 proc check_effective_target_glibc { } {
12912 return [check_no_compiler_messages glibc_object assembly {
12913 #include <stdlib.h>
12914 #if !defined(__GLIBC__)
12915 #error undefined
12916 #endif
12917 }]
12918 }
12919
12920 # Return 1 if the target plus current options supports a vector
12921 # complex addition with rotate of half and single float modes, 0 otherwise.
12922 #
12923 # This won't change for different subtargets so cache the result.
12924
12925 foreach N {hf sf} {
12926 eval [string map [list N $N] {
12927 proc check_effective_target_vect_complex_rot_N { } {
12928 return [check_cached_effective_target_indexed vect_complex_rot_N {
12929 expr { [istarget aarch64*-*-*]
12930 || [istarget arm*-*-*] }}]
12931 }
12932 }]
12933 }
12934
12935 # Return 1 if the target plus current options supports a vector
12936 # complex addition with rotate of double float modes, 0 otherwise.
12937 #
12938 # This won't change for different subtargets so cache the result.
12939
12940 foreach N {df} {
12941 eval [string map [list N $N] {
12942 proc check_effective_target_vect_complex_rot_N { } {
12943 return [check_cached_effective_target_indexed vect_complex_rot_N {
12944 expr { [istarget aarch64*-*-*] }}]
12945 }
12946 }]
12947 }
12948
12949 # Return 1 if this target uses an LLVM assembler and/or linker
12950 proc check_effective_target_llvm_binutils { } {
12951 return [check_cached_effective_target llvm_binutils {
12952 expr { [istarget amdgcn*-*-*]
12953 || [check_effective_target_offload_gcn] }}]
12954 }
12955
12956 # Return 1 if the compiler supports '-mfentry'.
12957
12958 proc check_effective_target_mfentry { } {
12959 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
12960 return 0
12961 }
12962 return [check_no_compiler_messages mfentry object {
12963 void foo (void) { }
12964 } "-mfentry"]
12965 }
12966
12967 # Return 1 if this target supports indirect calls
12968 proc check_effective_target_indirect_calls { } {
12969 if { [istarget bpf-*-*] } {
12970 return 0
12971 }
12972 return 1
12973 }
12974
12975 # Return 1 if we can use the -lgccjit option, 0 otherwise.
12976
12977 proc check_effective_target_lgccjit { } {
12978 if { [info procs jit_target_compile] == "" } then {
12979 global GCC_UNDER_TEST
12980 if ![info exists GCC_UNDER_TEST] {
12981 set GCC_UNDER_TEST "[find_gcc]"
12982 }
12983 proc jit_target_compile { source dest type options } [info body gcc_target_compile]
12984 }
12985 return [check_no_compiler_messages lgccjit executable {
12986 int main() { return 0; }
12987 } "-lgccjit"]
12988 }
12989
12990 # Return 1 if the MSP430 small memory model is in use.
12991 proc check_effective_target_msp430_small {} {
12992 return [check_no_compiler_messages msp430_small assembly {
12993 #if (!defined __MSP430__ || defined __MSP430X_LARGE__)
12994 #error !msp430 || __MSP430X_LARGE__
12995 #endif
12996 } ""]
12997 }
12998
12999 # Return 1 if the MSP430 large memory model is in use.
13000 proc check_effective_target_msp430_large {} {
13001 return [check_no_compiler_messages msp430_large assembly {
13002 #ifndef __MSP430X_LARGE__
13003 #error __MSP430X_LARGE__
13004 #endif
13005 } ""]
13006 }
13007
13008 # Return 1 if GCC was configured with --with-tune=cortex-a76
13009 proc check_effective_target_tune_cortex_a76 { } {
13010 return [check_configured_with "with-tune=cortex-a76"]
13011 }
13012
13013 # Return 1 if the target has an efficient means to encode large initializers
13014 # in the assembly.
13015
13016 proc check_effective_target_large_initializer { } {
13017 if { [istarget nvptx*-*-*] } {
13018 return 0
13019 }
13020
13021 return 1
13022 }
13023
13024 # Return 1 if the target allows function prototype mismatches
13025 # in the assembly.
13026
13027 proc check_effective_target_non_strict_prototype { } {
13028 if { [istarget nvptx*-*-*] } {
13029 return 0
13030 }
13031
13032 return 1
13033 }
13034
13035 # Returns 1 if the target toolchain supports extended
13036 # syntax of .symver directive, 0 otherwise.
13037
13038 proc check_symver_available { } {
13039 return [check_no_compiler_messages symver_available object {
13040 int foo(void) { return 0; }
13041 int main (void) {
13042 asm volatile (".symver foo,foo@VER_1, local");
13043 return 0;
13044 }
13045 }]
13046 }
13047
13048 # Return 1 if emitted assembly contains .ident directive.
13049
13050 proc check_effective_target_ident_directive {} {
13051 return [check_no_messages_and_pattern ident_directive \
13052 "(?n)^\[\t\]+\\.ident" assembly {
13053 int i;
13054 }]
13055 }
13056
13057 # Return 1 if we're able to assemble movdiri and movdir64b
13058
13059 proc check_effective_target_movdir { } {
13060 return [check_no_compiler_messages movdir object {
13061 void
13062 foo (unsigned int *d, unsigned int s)
13063 {
13064 __builtin_ia32_directstoreu_u32 (d, s);
13065 }
13066 void
13067 bar (void *d, const void *s)
13068 {
13069 __builtin_ia32_movdir64b (d, s);
13070 }
13071 } "-mmovdiri -mmovdir64b" ]
13072 }
13073
13074 # Return 1 if the target does not support address sanitizer, 0 otherwise
13075
13076 proc check_effective_target_no_fsanitize_address {} {
13077 if ![check_no_compiler_messages fsanitize_address executable {
13078 int main (void) { return 0; }
13079 } "-fsanitize=address" ] {
13080 return 1;
13081 }
13082
13083 return 0;
13084 }
13085
13086 # Return 1 if this target supports 'R' flag in .section directive, 0
13087 # otherwise. Cache the result.
13088
13089 proc check_effective_target_R_flag_in_section { } {
13090 global tool
13091 global GCC_UNDER_TEST
13092
13093 # Need auto-host.h to check linker support.
13094 if { ![file exists ../../auto-host.h ] } {
13095 return 0
13096 }
13097
13098 return [check_cached_effective_target R_flag_in_section {
13099
13100 set src pie[pid].c
13101 set obj pie[pid].o
13102
13103 set f [open $src "w"]
13104 puts $f "#include \"../../auto-host.h\""
13105 puts $f "#if HAVE_GAS_SHF_GNU_RETAIN == 0 || HAVE_INITFINI_ARRAY_SUPPORT == 0"
13106 puts $f "# error Assembler does not support 'R' flag in .section directive."
13107 puts $f "#endif"
13108 close $f
13109
13110 verbose "check_effective_target_R_flag_in_section compiling testfile $src" 2
13111 set lines [${tool}_target_compile $src $obj assembly ""]
13112
13113 file delete $src
13114 file delete $obj
13115
13116 if [string match "" $lines] then {
13117 verbose "check_effective_target_R_flag_in_section testfile compilation passed" 2
13118 return 1
13119 } else {
13120 verbose "check_effective_target_R_flag_in_section testfile compilation failed" 2
13121 return 0
13122 }
13123 }]
13124 }
13125
13126 # Return 1 if this target supports 'o' flag in .section directive, 0
13127 # otherwise. Cache the result.
13128
13129 proc check_effective_target_o_flag_in_section { } {
13130 global tool
13131 global GCC_UNDER_TEST
13132
13133 # Need auto-host.h to check linker support.
13134 if { ![file exists ../../auto-host.h ] } {
13135 return 0
13136 }
13137
13138 return [check_cached_effective_target o_flag_in_section {
13139
13140 set src pie[pid].c
13141 set obj pie[pid].o
13142
13143 set f [open $src "w"]
13144 puts $f "#include \"../../auto-host.h\""
13145 puts $f "#if HAVE_GAS_SECTION_LINK_ORDER == 0"
13146 puts $f "# error Assembler does not support 'o' flag in .section directive."
13147 puts $f "#endif"
13148 close $f
13149
13150 verbose "check_effective_target_o_flag_in_section compiling testfile $src" 2
13151 set lines [${tool}_target_compile $src $obj object ""]
13152
13153 file delete $src
13154 file delete $obj
13155
13156 if [string match "" $lines] then {
13157 verbose "check_effective_target_o_flag_in_section testfile compilation passed" 2
13158 return 1
13159 } else {
13160 verbose "check_effective_target_o_flag_in_section testfile compilation failed" 2
13161 return 0
13162 }
13163 }]
13164 }
13165
13166 # Return 1 if the given assembler supports hardware transactional memory
13167 # instructions with machine type Power10, 0 otherwise. Cache the result.
13168
13169 proc check_effective_target_powerpc_as_p10_htm { } {
13170 global tool
13171 global GCC_UNDER_TEST
13172
13173 # Need auto-host.h to check linker support.
13174 if { ![file exists ../../auto-host.h ] } {
13175 return 0
13176 }
13177
13178 return [check_cached_effective_target powerpc_as_p10_htm {
13179
13180 set src pie[pid].c
13181 set obj pie[pid].o
13182
13183 set f [open $src "w"]
13184 puts $f "#include \"../../auto-host.h\""
13185 puts $f "#if HAVE_AS_POWER10_HTM == 0"
13186 puts $f "# error Assembler does not support htm insns with power10."
13187 puts $f "#endif"
13188 close $f
13189
13190 verbose "check_effective_target_powerpc_as_p10_htm compiling testfile $src" 2
13191 set lines [${tool}_target_compile $src $obj object ""]
13192
13193 file delete $src
13194 file delete $obj
13195
13196 if [string match "" $lines] then {
13197 verbose "check_effective_target_powerpc_as_p10_htm testfile compilation passed" 2
13198 return 1
13199 } else {
13200 verbose "check_effective_target_powerpc_as_p10_htm testfile compilation failed" 2
13201 return 0
13202 }
13203 }]
13204 }
13205
13206 # return 1 if LRA is supported.
13207
13208 proc check_effective_target_lra { } {
13209 if { [istarget hppa*-*-*] || [istarget avr-*-*] } {
13210 return 0
13211 }
13212 return 1
13213 }
13214
13215 # Test whether optimizations are enabled ('__OPTIMIZE__') per the
13216 # 'current_compiler_flags' (thus don't cache).
13217
13218 proc check_effective_target___OPTIMIZE__ {} {
13219 return [check_no_compiler_messages_nocache __OPTIMIZE__ assembly {
13220 #ifndef __OPTIMIZE__
13221 # error nein
13222 #endif
13223 /* Avoid pedwarn about empty TU. */
13224 int dummy;
13225 } [current_compiler_flags]]
13226 }
13227
13228 # Return 1 if python3 (>= 3.6) is available.
13229
13230 proc check_effective_target_recent_python3 { } {
13231 set result [remote_exec host "python3 -c \"import sys; assert sys.version_info >= (3, 6)\""]
13232 set status [lindex $result 0]
13233 if { $status == 0 } then {
13234 return 1;
13235 } else {
13236 return 0;
13237 }
13238 }
13239
13240 # Return 1 if python3 contains a module
13241
13242 proc check_effective_target_python3_module { module } {
13243 set result [remote_exec host "python3 -c \"import $module\""]
13244 set status [lindex $result 0]
13245 if { $status == 0 } then {
13246 return 1;
13247 } else {
13248 return 0;
13249 }
13250 }
13251
13252 # Return 1 if pytest module is available for python3.
13253
13254 proc check_effective_target_pytest3 { } {
13255 set result [remote_exec host "python3 -m pytest --color=no -rap -s --tb=no --version"]
13256 set status [lindex $result 0]
13257 if { $status == 0 } then {
13258 return 1;
13259 } else {
13260 return 0;
13261 }
13262 }
13263
13264 proc check_effective_target_property_1_needed { } {
13265 return [check_no_compiler_messages property_1_needed executable {
13266 /* Assembly code */
13267 #ifdef __LP64__
13268 # define __PROPERTY_ALIGN 3
13269 #else
13270 # define __PROPERTY_ALIGN 2
13271 #endif
13272
13273 .section ".note.gnu.property", "a"
13274 .p2align __PROPERTY_ALIGN
13275 .long 1f - 0f /* name length. */
13276 .long 4f - 1f /* data length. */
13277 /* NT_GNU_PROPERTY_TYPE_0. */
13278 .long 5 /* note type. */
13279 0:
13280 .asciz "GNU" /* vendor name. */
13281 1:
13282 .p2align __PROPERTY_ALIGN
13283 /* GNU_PROPERTY_1_NEEDED. */
13284 .long 0xb0008000 /* pr_type. */
13285 .long 3f - 2f /* pr_datasz. */
13286 2:
13287 /* GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. */
13288 .long 1
13289 3:
13290 .p2align __PROPERTY_ALIGN
13291 4:
13292 .text
13293 .globl main
13294 main:
13295 .byte 0
13296 } ""]
13297 }
13298
13299 # Return 1 if this target has prog named "$prog", 0 otherwise.
13300
13301 proc check_is_prog_name_available { prog } {
13302 global tool
13303
13304 set options [list "additional_flags=-print-prog-name=$prog"]
13305 set output [lindex [${tool}_target_compile "" "" "none" $options] 0]
13306
13307 if { $output == $prog } {
13308 return 0
13309 }
13310
13311 return 1
13312 }
13313
13314 # returns 1 if target does selects a readonly section for const volatile variables.
13315 proc check_effective_target_const_volatile_readonly_section { } {
13316
13317 if { [istarget powerpc-*-*]
13318 || [check-flags { "" { powerpc64-*-* } { -m32 } }] } {
13319 return 0
13320 }
13321 return 1
13322 }
13323
13324 # Return 1 if the CORE-V MAC extension is available.
13325 proc check_effective_target_cv_mac { } {
13326 if { !([istarget riscv*-*-*]) } {
13327 return 0
13328 }
13329 return [check_no_compiler_messages cv_mac object {
13330 void foo (void)
13331 {
13332 asm ("cv.mac t0, t1, t2");
13333 }
13334 } "-march=rv32i_xcvmac" ]
13335 }
13336
13337 # Return 1 if the CORE-V ALU extension is available.
13338 proc check_effective_target_cv_alu { } {
13339 if { !([istarget riscv*-*-*]) } {
13340 return 0
13341 }
13342 return [check_no_compiler_messages cv_alu object {
13343 void foo (void)
13344 {
13345 asm ("cv.addn t0, t1, t2, 0");
13346 }
13347 } "-march=rv32i_xcvalu" ]
13348 }
13349
13350 # Return 1 if the CORE-V ELW extension is available.
13351 proc check_effective_target_cv_elw { } {
13352 if { !([istarget riscv*-*-*]) } {
13353 return 0
13354 }
13355 return [check_no_compiler_messages cv_elw object {
13356 void foo (void)
13357 {
13358 asm ("cv.elw x0, 0(x0)");
13359 }
13360 } "-march=rv32i_xcvelw" ]
13361 }
13362
13363 # Return 1 if the CORE-V SIMD extension is available.
13364 proc check_effective_target_cv_simd { } {
13365 if { !([istarget riscv*-*-*]) } {
13366 return 0
13367 }
13368 return [check_no_compiler_messages cv_simd object {
13369 void foo (void)
13370 {
13371 asm ("cv.add.sc.b x0, x0, x0");
13372 }
13373 } "-march=rv32i_xcvsimd" ]
13374 }
13375
13376 proc check_effective_target_loongarch_sx { } {
13377 return [check_no_compiler_messages loongarch_lsx assembly {
13378 #if !defined(__loongarch_sx)
13379 #error "LSX not defined"
13380 #endif
13381 } "-mlsx"]
13382 }
13383
13384 proc check_effective_target_loongarch_sx_hw { } {
13385 return [check_runtime loongarch_sx_hw {
13386 #include <lsxintrin.h>
13387 int main (void)
13388 {
13389 __m128i a, b, c;
13390 c = __lsx_vand_v (a, b);
13391 return 0;
13392 }
13393 } "-mlsx"]
13394 }
13395
13396 proc check_effective_target_loongarch_asx { } {
13397 return [check_no_compiler_messages loongarch_asx assembly {
13398 #if !defined(__loongarch_asx)
13399 #error "LASX not defined"
13400 #endif
13401 } "-mlasx"]
13402 }
13403
13404 proc check_effective_target_loongarch_asx_hw { } {
13405 return [check_runtime loongarch_asx_hw {
13406 #include <lasxintrin.h>
13407 int main (void)
13408 {
13409 __m256i a, b, c;
13410 c = __lasx_xvand_v (a, b);
13411 return 0;
13412 }
13413 } "-mlasx"]
13414 }
13415
13416 # Check whether LoongArch binutils supports call36 relocation.
13417 proc check_effective_target_loongarch_call36_support { } {
13418 return [check_no_compiler_messages loongarch_call36_support object {
13419 /* Assembly code */
13420 pcaddu18i $r1,%call36(a)
13421 jirl $r1,$r1,0
13422 } ""]
13423 }
13424
13425 # Returns 1 if binutils supports TLS le Relax, 0 otherwise.
13426 proc check_effective_target_tls_le_relax { } {
13427 if [check_effective_target_tls_native] {
13428 return [check_no_compiler_messages loongarch_tls_le_relax object {
13429 /* Assembly code */
13430 lu12i.w $r12, %le_hi20_r(a)
13431 }]
13432 }
13433
13434 return 0;
13435 }
13436
13437 # Appends necessary Python flags to extra-tool-flags if Python.h is supported.
13438 # Otherwise, modifies dg-do-what.
13439 proc dg-require-python-h { args } {
13440 upvar dg-extra-tool-flags extra-tool-flags
13441
13442 verbose "ENTER dg-require-python-h" 2
13443
13444 set supported 0
13445 set result [remote_exec host "python3-config --includes"]
13446 set status [lindex $result 0]
13447 if { $status == 0 } {
13448 # Remove trailing newline from python3-config output.
13449 set python_flags [string trim [lindex $result 1]]
13450 if [check_no_compiler_messages python_h assembly {
13451 #include <Python.h>
13452 int main (void) { return 0; }
13453 } $python_flags] {
13454 set supported 1
13455 }
13456 }
13457
13458 if { $supported == 0 } {
13459 verbose "Python.h not supported" 2
13460 upvar dg-do-what dg-do-what
13461 set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
13462 return
13463 }
13464
13465 verbose "Python flags are: $python_flags" 2
13466
13467 verbose "Before appending, extra-tool-flags: ${extra-tool-flags}" 3
13468 eval lappend extra-tool-flags $python_flags
13469 verbose "After appending, extra-tool-flags: ${extra-tool-flags}" 3
13470 }