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