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