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