X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Ftestsuite%2Flib%2Ftarget-supports.exp;h=ba1454eaab8d2ba3daab93943d234bd863ea328c;hp=4c99345c866aca1cf22c24b3df7393cd7908b046;hb=8c85798c48b41342647c4126965e3f34584f87f2;hpb=373346232a7a067abeb6848616e5f190834e8aff diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 4c99345c866..ba1454eaab8 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -1,9 +1,9 @@ -# Copyright (C) 1999, 2001, 2003, 2004, 2005, 2006 -# Free Software Foundation, Inc. +# Copyright (C) 1999, 2001, 2003, 2004, 2005, 2006, 2007 +# Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, @@ -12,28 +12,26 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# along with GCC; see the file COPYING3. If not see +# . # Please email any bugs, comments, and/or additions to this file to: # gcc-patches@gcc.gnu.org # This file defines procs for determining features supported by the target. -# Try to compile some code and return the messages printed by the compiler, -# and optionally the contents for assembly files. Either a string or -# a list of two strings are returned, depending on WANT_OUTPUT. +# Try to compile the code given by CONTENTS into an output file of +# type TYPE, where TYPE is as for target_compile. Return a list +# whose first element contains the compiler messages and whose +# second element is the name of the output file. # -# BASENAME is a basename to use for temporary files. -# WANT_OUTPUT is a flag which is 0 to request returning just the -# compiler messages, or 1 to return the messages and the contents -# of the assembly file. TYPE should be "assembly" if WANT_OUTPUT -# is set. -# TYPE is the type of compilation to perform (see target_compile). -# CONTENTS gives the contents of the input file. -# The rest is optional: -# OPTIONS: additional compiler options to use. -proc get_compiler_messages {basename want_output type contents args} { +# BASENAME is a prefix to use for source and output files. +# If ARGS is not empty, its first element is a string that +# should be added to the command line. +# +# Assume by default that CONTENTS is C code. C++ code should contain +# "// C++" and Fortran code should contain "! Fortran". +proc check_compile {basename type contents args} { global tool if { [llength $args] > 0 } { @@ -41,39 +39,37 @@ proc get_compiler_messages {basename want_output type contents args} { } else { set options "" } - - set src ${basename}[pid].c - switch $type { + switch -glob -- $contents { + "*! Fortran*" { set src ${basename}[pid].f90 } + "*// C++*" { set src ${basename}[pid].cc } + default { set src ${basename}[pid].c } + } + set compile_type $type + switch -glob $type { assembly { set output ${basename}[pid].s } object { set output ${basename}[pid].o } + executable { set output ${basename}[pid].exe } + "rtl-*" { + set output ${basename}[pid].s + lappend options "additional_flags=-fdump-$type" + set compile_type assembly + } } set f [open $src "w"] puts $f $contents close $f - set lines [${tool}_target_compile $src $output $type "$options"] + set lines [${tool}_target_compile $src $output $compile_type "$options"] file delete $src - if { $want_output } { - if { $type != "assembly" } { - error "WANT_OUTPUT can only be used with assembly output" - } elseif { ![string match "" $lines] } { - # An error occurred. - set result [list $lines ""] - } else { - set text "" - set chan [open "$output"] - while {[gets $chan line] >= 0} { - append text "$line\n" - } - close $chan - set result [list $lines $text] - } - } else { - set result $lines + set scan_output $output + # Don't try folding this into the switch above; calling "glob" before the + # file is created won't work. + if [regexp "rtl-(.*)" $type dummy rtl_type] { + set scan_output "[glob $src.\[0-9\]\[0-9\]\[0-9\]r.$rtl_type]" + file delete $output } - remote_file build delete $output - return $result + return [list $lines $scan_output] } proc current_target_name { } { @@ -87,43 +83,114 @@ proc current_target_name { } { } # Implement an effective-target check for property PROP by invoking -# the compiler and seeing if it prints any messages. Assume that the -# property holds if the compiler doesn't print anything. The other -# arguments are as for get_compiler_messages, starting with TYPE. -proc check_no_compiler_messages {prop args} { +# the Tcl command ARGS and seeing if it returns true. + +proc check_cached_effective_target { prop args } { global et_cache set target [current_target_name] if {![info exists et_cache($prop,target)] || $et_cache($prop,target) != $target} { - verbose "check_no_compiler_messages $prop: compiling source for $target" 2 + verbose "check_cached_effective_target $prop: checking $target" 2 set et_cache($prop,target) $target - set et_cache($prop,value) \ - [string match "" [eval get_compiler_messages $prop 0 $args]] + set et_cache($prop,value) [uplevel eval $args] } set value $et_cache($prop,value) - verbose "check_no_compiler_messages $prop: returning $value for $target" 2 + verbose "check_cached_effective_target $prop: returning $value for $target" 2 return $value } -# Similar to check_no_compiler_messages, but also verify that the regular -# expression PATTERN matches the compiler's output. +# Like check_compile, but delete the output file and return true if the +# compiler printed no messages. +proc check_no_compiler_messages_nocache {args} { + set result [eval check_compile $args] + set lines [lindex $result 0] + set output [lindex $result 1] + remote_file build delete $output + return [string match "" $lines] +} + +# Like check_no_compiler_messages_nocache, but cache the result. +# PROP is the property we're checking, and doubles as a prefix for +# temporary filenames. +proc check_no_compiler_messages {prop args} { + return [check_cached_effective_target $prop { + eval [list check_no_compiler_messages_nocache $prop] $args + }] +} + +# Like check_compile, but return true if the compiler printed no +# messages and if the contents of the output file satisfy PATTERN. +# If PATTERN has the form "!REGEXP", the contents satisfy it if they +# don't match regular expression REGEXP, otherwise they satisfy it +# if they do match regular expression PATTERN. (PATTERN can start +# with something like "[!]" if the regular expression needs to match +# "!" as the first character.) +# +# Delete the output file before returning. The other arguments are +# as for check_compile. +proc check_no_messages_and_pattern_nocache {basename pattern args} { + global tool + + set result [eval [list check_compile $basename] $args] + set lines [lindex $result 0] + set output [lindex $result 1] + + set ok 0 + if { [string match "" $lines] } { + set chan [open "$output"] + set invert [regexp {^!(.*)} $pattern dummy pattern] + set ok [expr { [regexp $pattern [read $chan]] != $invert }] + close $chan + } + + remote_file build delete $output + return $ok +} + +# Like check_no_messages_and_pattern_nocache, but cache the result. +# PROP is the property we're checking, and doubles as a prefix for +# temporary filenames. proc check_no_messages_and_pattern {prop pattern args} { - global et_cache + return [check_cached_effective_target $prop { + eval [list check_no_messages_and_pattern_nocache $prop $pattern] $args + }] +} - set target [current_target_name] - if {![info exists et_cache($prop,target)] - || $et_cache($prop,target) != $target} { - verbose "check_no_messages_and_pattern $prop: compiling source for $target" 2 - set et_cache($prop,target) $target - set results [eval get_compiler_messages $prop 1 $args] - set et_cache($prop,value) \ - [expr [string match "" [lindex $results 0]] \ - && [regexp $pattern [lindex $results 1]]] +# Try to compile and run an executable from code CONTENTS. Return true +# if the compiler reports no messages and if execution "passes" in the +# usual DejaGNU sense. The arguments are as for check_compile, with +# TYPE implicitly being "executable". +proc check_runtime_nocache {basename contents args} { + global tool + + set result [eval [list check_compile $basename executable $contents] $args] + set lines [lindex $result 0] + set output [lindex $result 1] + + set ok 0 + if { [string match "" $lines] } { + # No error messages, everything is OK. + set result [remote_load target "./$output" "" ""] + set status [lindex $result 0] + verbose "check_runtime_nocache $basename: status is <$status>" 2 + if { $status == "pass" } { + set ok 1 + } } - set value $et_cache($prop,value) - verbose "check_no_messages_and_pattern $prop: returning $value for $target" 2 - return $value + remote_file build delete $output + return $ok +} + +# Like check_runtime_nocache, but cache the result. PROP is the +# property we're checking, and doubles as a prefix for temporary +# filenames. +proc check_runtime {prop args} { + global tool + + return [check_cached_effective_target $prop { + eval [list check_runtime_nocache $prop] $args + }] } ############################### @@ -286,6 +353,22 @@ proc check_gc_sections_available { } { return 0 } + # elf2flt uses -q (--emit-relocs), which is incompatible with + # --gc-sections. + if { [board_info target exists ldflags] + && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } { + set gc_sections_available_saved 0 + return 0 + } + + # VxWorks kernel modules are relocatable objects linked with -r, + # while RTP executables are linked with -q (--emit-relocs). + # Both of these options are incompatible with --gc-sections. + if { [istarget *-*-vxworks*] } { + set gc_sections_available_saved 0 + return 0 + } + # Check if the ld used by gcc supports --gc-sections. set gcc_spec [${tool}_target_compile "-dumpspecs" "" "none" ""] regsub ".*\n\*linker:\[ \t\]*\n(\[^ \t\n\]*).*" "$gcc_spec" {\1} linker @@ -332,6 +415,13 @@ proc check_profiling_available { test_what } { return 0 } + # uClibc does not have gcrt1.o. + if { [check_effective_target_uclibc] + && ([lindex $test_what 1] == "-p" + || [lindex $test_what 1] == "-pg") } { + return 0 + } + # Now examine the cache variable. if {![info exists profiling_available_saved]} { # Some targets don't have any implementation of __bb_init_func or are @@ -340,15 +430,21 @@ proc check_profiling_available { test_what } { || [istarget arm*-*-eabi*] || [istarget arm*-*-elf] || [istarget arm*-*-symbianelf*] + || [istarget bfin-*-*] || [istarget powerpc-*-eabi*] || [istarget strongarm*-*-elf] || [istarget xscale*-*-elf] || [istarget cris-*-*] + || [istarget crisv32-*-*] + || [istarget fido-*-elf] || [istarget h8300-*-*] || [istarget m32c-*-elf] || [istarget m68k-*-elf] - || [istarget mips*-*-elf] + || [istarget m68k-*-uclinux*] + || [istarget mips*-*-elf*] + || [istarget xstormy16-*] || [istarget xtensa-*-elf] + || [istarget *-*-vxworks*] || [istarget *-*-windiss] } { set profiling_available_saved 0 } else { @@ -389,33 +485,23 @@ proc check_effective_target_pcc_bitfield_type_matters { } { # This won't change for different subtargets so cache the result. proc check_effective_target_tls {} { - global et_tls_saved - global tool - - if [info exists et_tls_saved] { - verbose "check_effective_target_tls: using cached result" 2 - } else { - set et_tls_saved 1 + return [check_no_compiler_messages tls assembly { + __thread int i; + int f (void) { return i; } + void g (int j) { i = j; } + }] +} - set src tls[pid].c - set asm tls[pid].S - verbose "check_effective_target_tls: compiling testfile $src" 2 - set f [open $src "w"] - # Compile a small test program. - puts $f "__thread int i;\n" - close $f +# Return 1 if *native* thread local storage (TLS) is supported, 0 otherwise. +# +# This won't change for different subtargets so cache the result. - # Test for thread-local data supported by the platform. - set comp_output \ - [${tool}_target_compile $src $asm assembly ""] - file delete $src - if { [string match "*not supported*" $comp_output] } { - set et_tls_saved 0 - } - remove-build-file $asm - } - verbose "check_effective_target_tls: returning $et_tls_saved" 2 - return $et_tls_saved +proc check_effective_target_tls_native {} { + return [check_no_messages_and_pattern tls_native "!emutls" assembly { + __thread int i; + int f (void) { return i; } + void g (int j) { i = j; } + }] } # Return 1 if TLS executables can run correctly, 0 otherwise. @@ -423,45 +509,10 @@ proc check_effective_target_tls {} { # This won't change for different subtargets so cache the result. proc check_effective_target_tls_runtime {} { - global et_tls_runtime_saved - global tool - - if [info exists et_tls_runtime_saved] { - verbose "check_effective_target_tls_runtime: using cached result" 2 - } else { - set et_tls_runtime_saved 0 - - set src tls_runtime[pid].c - set exe tls_runtime[pid].x - verbose "check_effective_target_tls_runtime: compiling testfile $src" 2 - set f [open $src "w"] - # Compile a small test program. - puts $f "__thread int thr = 0;\n" - puts $f "int main(void)\n {\n return thr;\n}" - close $f - - set comp_output \ - [${tool}_target_compile $src $exe executable ""] - file delete $src - - if [string match "" $comp_output] then { - # No error messages, everything is OK. - - set result [remote_load target "./$exe" "" ""] - set status [lindex $result 0] - remote_file build delete $exe - - verbose "check_effective_target_tls_runtime status is <$status>" 2 - - if { $status == "pass" } { - set et_tls_runtime_saved 1 - } - - verbose "check_effective_target_tls_runtime: returning $et_tls_runtime_saved" 2 - } - } - - return $et_tls_runtime_saved + return [check_runtime tls_runtime { + __thread int thr = 0; + int main (void) { return thr; } + }] } # Return 1 if compilation with -fopenmp is error-free for trivial @@ -473,6 +524,22 @@ proc check_effective_target_fopenmp {} { } "-fopenmp"] } +# Return 1 if compilation with -pthread is error-free for trivial +# code, 0 otherwise. + +proc check_effective_target_pthread {} { + return [check_no_compiler_messages pthread object { + void foo (void) { } + } "-pthread"] +} + +# Return 1 if the target supports -fstack-protector +proc check_effective_target_fstack_protector {} { + return [check_runtime fstack_protector { + int main (void) { return 0; } + } "-fstack-protector"] +} + # Return 1 if compilation with -freorder-blocks-and-partition is error-free # for trivial code, 0 otherwise. @@ -509,48 +576,114 @@ proc check_effective_target_mpaired_single { } { } "-mpaired-single"] } -# Return true if iconv is supported on the target. In particular IBM1047. +# Return true if the target has access to FPU instructions. -proc check_iconv_available { test_what } { - global tool - global libiconv +proc check_effective_target_hard_float { } { + if { [istarget mips*-*-*] } { + return [check_no_compiler_messages hard_float assembly { + #if (defined __mips_soft_float || defined __mips16) + #error FOO + #endif + }] + } - set result "" + # The generic test equates hard_float with "no call for adding doubles". + return [check_no_messages_and_pattern hard_float "!\\(call" rtl-expand { + double a (double b, double c) { return b + c; } + }] +} - set src iconv[pid].c - set exe iconv[pid].x - verbose "check_iconv_available compiling testfile $src" 2 - set f [open $src "w"] - # Compile a small test program. - puts $f "#include \n" - puts $f "int main (void)\n {\n iconv_t cd; \n" - puts $f "cd = iconv_open (\"[lindex $test_what 1]\", \"UTF-8\");\n" - puts $f "if (cd == (iconv_t) -1)\n return 1;\n" - puts $f "return 0;\n}" - close $f +# Return true if the target is a 64-bit MIPS target. - # If the tool configuration file has not set libiconv, try "-liconv" - if { ![info exists libiconv] } { - set libiconv "-liconv" - } - set lines [${tool}_target_compile $src $exe executable "libs=$libiconv" ] - file delete $src +proc check_effective_target_mips64 { } { + return [check_no_compiler_messages mips64 assembly { + #ifndef __mips64 + #error FOO + #endif + }] +} - if [string match "" $lines] then { - # No error messages, everything is OK. +# Return true if the target is a MIPS target that does not produce +# MIPS16 code. - set result [${tool}_load "./$exe" "" ""] - set status [lindex $result 0] - remote_file build delete $exe +proc check_effective_target_nomips16 { } { + return [check_no_compiler_messages nomips16 object { + #ifndef __mips + #error FOO + #else + /* A cheap way of testing for -mflip-mips16. */ + void foo (void) { asm ("addiu $20,$20,1"); } + void bar (void) { asm ("addiu $20,$20,1"); } + #endif + }] +} - verbose "check_iconv_available status is <$status>" 2 +# Add the options needed for MIPS16 function attributes. At the moment, +# we don't support MIPS16 PIC. - if { $status == "pass" } then { - return 1 - } +proc add_options_for_mips16_attribute { flags } { + return "$flags -mno-abicalls -fno-pic" +} + +# Return true if we can force a mode that allows MIPS16 code generation. +# We don't support MIPS16 PIC, and only support MIPS16 -mhard-float +# for o32 and o64. + +proc check_effective_target_mips16_attribute { } { + return [check_no_compiler_messages mips16_attribute assembly { + #ifdef PIC + #error FOO + #endif + #if defined __mips_hard_float \ + && (!defined _ABIO32 || _MIPS_SIM != _ABIO32) \ + && (!defined _ABIO64 || _MIPS_SIM != _ABIO64) + #error FOO + #endif + } [add_options_for_mips16_attribute ""]] +} + +# Return 1 if the current multilib does not generate PIC by default. + +proc check_effective_target_nonpic { } { + return [check_no_compiler_messages nonpic assembly { + #if __PIC__ + #error FOO + #endif + }] +} + +# Return 1 if the target does not use a status wrapper. + +proc check_effective_target_unwrapped { } { + if { [target_info needs_status_wrapper] != "" \ + && [target_info needs_status_wrapper] != "0" } { + return 0 } + return 1 +} - return 0 +# Return true if iconv is supported on the target. In particular IBM1047. + +proc check_iconv_available { test_what } { + global libiconv + + # If the tool configuration file has not set libiconv, try "-liconv" + if { ![info exists libiconv] } { + set libiconv "-liconv" + } + set test_what [lindex $test_what 1] + return [check_runtime_nocache $test_what [subst { + #include + int main (void) + { + iconv_t cd; + + cd = iconv_open ("$test_what", "UTF-8"); + if (cd == (iconv_t) -1) + return 1; + return 0; + } + }] $libiconv] } # Return true if named sections are supported on this target. @@ -567,55 +700,13 @@ proc check_named_sections_available { } { # When the target name changes, replace the cached result. proc check_effective_target_fortran_large_real { } { - global et_fortran_large_real_saved - global et_fortran_large_real_target_name - global tool - - if { ![info exists et_fortran_large_real_target_name] } { - set et_fortran_large_real_target_name "" - } - - # If the target has changed since we set the cached value, clear it. - set current_target [current_target_name] - if { $current_target != $et_fortran_large_real_target_name } { - verbose "check_effective_target_fortran_large_real: `$et_fortran_large_real_target_name' `$current_target'" 2 - set et_fortran_large_real_target_name $current_target - if [info exists et_fortran_large_real_saved] { - verbose "check_effective_target_fortran_large_real: removing cached result" 2 - unset et_fortran_large_real_saved - } - } - - if [info exists et_fortran_large_real_saved] { - verbose "check_effective_target_fortran_large_real returning saved $et_fortran_large_real_saved" 2 - } else { - set et_fortran_large_real_saved 0 - - # Set up, compile, and execute a test program using large real - # kinds. Include the current process ID in the file names to - # prevent conflicts with invocations for multiple testsuites. - set src real[pid].f90 - set exe real[pid].x - - set f [open $src "w"] - puts $f "integer,parameter :: k = &" - puts $f " selected_real_kind (precision (0.0_8) + 1)" - puts $f "real(kind=k) :: x" - puts $f "x = cos (x);" - puts $f "end" - close $f - - verbose "check_effective_target_fortran_large_real compiling testfile $src" 2 - set lines [${tool}_target_compile $src $exe executable ""] - file delete $src - - if [string match "" $lines] then { - # No error message, compilation succeeded. - set et_fortran_large_real_saved 1 - } - } - - return $et_fortran_large_real_saved + return [check_no_compiler_messages fortran_large_real executable { + ! Fortran + integer,parameter :: k = selected_real_kind (precision (0.0_8) + 1) + real(kind=k) :: x + x = cos (x) + end + }] } # Return 1 if the target supports Fortran integer kinds larger than @@ -624,54 +715,12 @@ proc check_effective_target_fortran_large_real { } { # When the target name changes, replace the cached result. proc check_effective_target_fortran_large_int { } { - global et_fortran_large_int_saved - global et_fortran_large_int_target_name - global tool - - if { ![info exists et_fortran_large_int_target_name] } { - set et_fortran_large_int_target_name "" - } - - # If the target has changed since we set the cached value, clear it. - set current_target [current_target_name] - if { $current_target != $et_fortran_large_int_target_name } { - verbose "check_effective_target_fortran_large_int: `$et_fortran_large_int_target_name' `$current_target'" 2 - set et_fortran_large_int_target_name $current_target - if [info exists et_fortran_large_int_saved] { - verbose "check_effective_target_fortran_large_int: removing cached result" 2 - unset et_fortran_large_int_saved - } - } - - if [info exists et_fortran_large_int_saved] { - verbose "check_effective_target_fortran_large_int returning saved $et_fortran_large_int_saved" 2 - } else { - set et_fortran_large_int_saved 0 - - # Set up, compile, and execute a test program using large integer - # kinds. Include the current process ID in the file names to - # prevent conflicts with invocations for multiple testsuites. - set src int[pid].f90 - set exe int[pid].x - - set f [open $src "w"] - puts $f "integer,parameter :: k = &" - puts $f " selected_int_kind (range (0_8) + 1)" - puts $f "integer(kind=k) :: i" - puts $f "end" - close $f - - verbose "check_effective_target_fortran_large_int compiling testfile $src" 2 - set lines [${tool}_target_compile $src $exe executable ""] - file delete $src - - if [string match "" $lines] then { - # No error message, compilation succeeded. - set et_fortran_large_int_saved 1 - } - } - - return $et_fortran_large_int_saved + return [check_no_compiler_messages fortran_large_int executable { + ! Fortran + integer,parameter :: k = selected_int_kind (range (0_8) + 1) + integer(kind=k) :: i + end + }] } # Return 1 if we can statically link libgfortran, 0 otherwise. @@ -679,118 +728,67 @@ proc check_effective_target_fortran_large_int { } { # When the target name changes, replace the cached result. proc check_effective_target_static_libgfortran { } { - global et_static_libgfortran - global et_static_libgfortran_target_name - global tool - - if { ![info exists et_static_libgfortran_target_name] } { - set et_static_libgfortran_target_name "" - } - - # If the target has changed since we set the cached value, clear it. - set current_target [current_target_name] - if { $current_target != $et_static_libgfortran_target_name } { - verbose "check_effective_target_static_libgfortran: `$et_static_libgfortran_target_name' `$current_target'" 2 - set et_static_libgfortran_target_name $current_target - if [info exists et_static_libgfortran_saved] { - verbose "check_effective_target_static_libgfortran: removing cached result" 2 - unset et_static_libgfortran_saved - } - } - - if [info exists et_static_libgfortran_saved] { - verbose "check_effective_target_static_libgfortran returning saved $et_static_libgfortran_saved" 2 - } else { - set et_static_libgfortran_saved 0 - - # Set up, compile, and execute a test program using static linking. - # Include the current process ID in the file names to prevent - # conflicts with invocations for multiple testsuites. - set opts "additional_flags=-static" - set src static[pid].f - set exe static[pid].x - - set f [open $src "w"] - puts $f " print *, 'test'" - puts $f " end" - close $f - - verbose "check_effective_target_static_libgfortran compiling testfile $src" 2 - set lines [${tool}_target_compile $src $exe executable "$opts"] - file delete $src + return [check_no_compiler_messages static_libgfortran executable { + ! Fortran + print *, 'test' + end + } "-static"] +} - if [string match "" $lines] then { - # No error message, compilation succeeded. - set et_static_libgfortran_saved 1 - } - } +# Return 1 if the target supports executing 750CL paired-single instructions, 0 +# otherwise. Cache the result. - return $et_static_libgfortran_saved +proc check_750cl_hw_available { } { + return [check_cached_effective_target 750cl_hw_available { + # If this is not the right target then we can skip the test. + if { ![istarget powerpc-*paired*] } { + expr 0 + } else { + check_runtime_nocache 750cl_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("ps_mul v0,v0,v0"); + #else + asm volatile ("ps_mul 0,0,0"); + #endif + return 0; + } + } "-mpaired" + } + }] } # Return 1 if the target supports executing AltiVec instructions, 0 # otherwise. Cache the result. proc check_vmx_hw_available { } { - global vmx_hw_available_saved - global tool - - if [info exists vmx_hw_available_saved] { - verbose "check_hw_available returning saved $vmx_hw_available_saved" 2 - } else { - set vmx_hw_available_saved 0 - + return [check_cached_effective_target vmx_hw_available { # Some simulators are known to not support VMX instructions. if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] } { - verbose "check_hw_available returning 0" 2 - return $vmx_hw_available_saved - } - - # Set up, compile, and execute a test program containing VMX - # instructions. Include the current process ID in the file - # names to prevent conflicts with invocations for multiple - # testsuites. - set src vmx[pid].c - set exe vmx[pid].x - - set f [open $src "w"] - puts $f "int main() {" - puts $f "#ifdef __MACH__" - puts $f " asm volatile (\"vor v0,v0,v0\");" - puts $f "#else" - puts $f " asm volatile (\"vor 0,0,0\");" - puts $f "#endif" - puts $f " return 0; }" - close $f - - # Most targets don't require special flags for this test case, but - # Darwin does. - if [istarget *-*-darwin*] { - set opts "additional_flags=-maltivec" + expr 0 } else { - set opts "" - } - - verbose "check_vmx_hw_available compiling testfile $src" 2 - set lines [${tool}_target_compile $src $exe executable "$opts"] - file delete $src - - if [string match "" $lines] then { - # No error message, compilation succeeded. - set result [${tool}_load "./$exe" "" ""] - set status [lindex $result 0] - remote_file build delete $exe - verbose "check_vmx_hw_available testfile status is <$status>" 2 - - if { $status == "pass" } then { - set vmx_hw_available_saved 1 + # Most targets don't require special flags for this test case, but + # Darwin does. + if { [istarget *-*-darwin*] + || [istarget *-*-aix*] } { + set options "-maltivec" + } else { + set options "" } - } else { - verbose "check_vmx_hw_availalble testfile compilation failed" 2 + check_runtime_nocache vmx_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("vor v0,v0,v0"); + #else + asm volatile ("vor 0,0,0"); + #endif + return 0; + } + } $options } - } - - return $vmx_hw_available_saved + }] } # GCC 3.4.0 for powerpc64-*-linux* included an ABI fix for passing @@ -801,122 +799,37 @@ proc check_vmx_hw_available { } { # When the target name changes, replace the cached result. proc check_effective_target_broken_cplxf_arg { } { - global et_broken_cplxf_arg_saved - global et_broken_cplxf_arg_target_name - global tool - - # Skip the work for targets known not to be affected. - if { ![istarget powerpc64-*-linux*] } { - return 0 - } elseif { [is-effective-target ilp32] } { - return 0 - } - - if { ![info exists et_broken_cplxf_arg_target_name] } { - set et_broken_cplxf_arg_target_name "" - } - - # If the target has changed since we set the cached value, clear it. - set current_target [current_target_name] - if { $current_target != $et_broken_cplxf_arg_target_name } { - verbose "check_effective_target_broken_cplxf_arg: `$et_broken_cplxf_arg_target_name'" 2 - set et_broken_cplxf_arg_target_name $current_target - if [info exists et_broken_cplxf_arg_saved] { - verbose "check_effective_target_broken_cplxf_arg: removing cached result" 2 - unset et_broken_cplxf_arg_saved - } - } - - if [info exists et_broken_cplxf_arg_saved] { - verbose "check_effective_target_broken_cplxf_arg: using cached result" 2 - } else { - set et_broken_cplxf_arg_saved 0 - # This is only known to affect one target. - if { ![istarget powerpc64-*-linux*] || ![is-effective-target lp64] } { - set et_broken_cplxf_arg_saved 0 - verbose "check_effective_target_broken_cplxf_arg: caching 0" 2 - return $et_broken_cplxf_arg_saved - } - - # Set up, compile, and execute a C test program that calls cabsf. - set src cabsf[pid].c - set exe cabsf[pid].x - - set f [open $src "w"] - puts $f "#include " - puts $f "extern void abort (void);" - puts $f "float fabsf (float);" - puts $f "float cabsf (_Complex float);" - puts $f "int main ()" - puts $f "{" - puts $f " _Complex float cf;" - puts $f " float f;" - puts $f " cf = 3 + 4.0fi;" - puts $f " f = cabsf (cf);" - puts $f " if (fabsf (f - 5.0) > 0.0001) abort ();" - puts $f " return 0;" - puts $f "}" - close $f - - set lines [${tool}_target_compile $src $exe executable "-lm"] - file delete $src - - if [string match "" $lines] { - # No error message, compilation succeeded. - set result [${tool}_load "./$exe" "" ""] - set status [lindex $result 0] - remote_file build delete $exe - - verbose "check_effective_target_broken_cplxf_arg: status is <$status>" 2 - - if { $status != "pass" } { - set et_broken_cplxf_arg_saved 1 - } + return [check_cached_effective_target broken_cplxf_arg { + # Skip the work for targets known not to be affected. + if { ![istarget powerpc64-*-linux*] } { + expr 0 + } elseif { ![is-effective-target lp64] } { + expr 0 } else { - verbose "check_effective_target_broken_cplxf_arg: compilation failed" 2 + check_runtime_nocache broken_cplxf_arg { + #include + extern void abort (void); + float fabsf (float); + float cabsf (_Complex float); + int main () + { + _Complex float cf; + float f; + cf = 3 + 4.0fi; + f = cabsf (cf); + if (fabsf (f - 5.0) > 0.0001) + abort (); + return 0; + } + } "-lm" } - } - return $et_broken_cplxf_arg_saved + }] } proc check_alpha_max_hw_available { } { - global alpha_max_hw_available_saved - global tool - - if [info exists alpha_max_hw_available_saved] { - verbose "check_alpha_max_hw_available returning saved $alpha_max_hw_available_saved" 2 - } else { - set alpha_max_hw_available_saved 0 - - # Set up, compile, and execute a test program probing bit 8 of the - # architecture mask, which indicates presence of MAX instructions. - set src max[pid].c - set exe max[pid].x - - set f [open $src "w"] - puts $f "int main() { return __builtin_alpha_amask(1<<8) != 0; }" - close $f - - verbose "check_alpha_max_hw_available compiling testfile $src" 2 - set lines [${tool}_target_compile $src $exe executable ""] - file delete $src - - if [string match "" $lines] then { - # No error message, compilation succeeded. - set result [${tool}_load "./$exe" "" ""] - set status [lindex $result 0] - remote_file build delete $exe - verbose "check_alpha_max_hw_available testfile status is <$status>" 2 - - if { $status == "pass" } then { - set alpha_max_hw_available_saved 1 - } - } else { - verbose "check_alpha_max_hw_availalble testfile compilation failed" 2 - } - } - - return $alpha_max_hw_available_saved + return [check_runtime alpha_max_hw_available { + int main() { return __builtin_alpha_amask(1<<8) != 0; } + }] } # Returns true iff the FUNCTION is available on the target system. @@ -924,36 +837,14 @@ proc check_alpha_max_hw_available { } { # AC_CHECK_FUNC.) proc check_function_available { function } { - set var "${function}_available_saved" - global $var - global tool - - if {![info exists $var]} { - # Assume it exists. - set $var 1 - # Check to make sure. - set src "function[pid].c" - set exe "function[pid].exe" - - set f [open $src "w"] - puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif\n" - puts $f "char $function ();\n" - puts $f "int main () { $function (); }" - close $f - - set lines [${tool}_target_compile $src $exe executable ""] - file delete $src - file delete $exe - - if {![string match "" $lines]} then { - set $var 0 - verbose -log "$function is not available" - } else { - verbose -log "$function is available" - } - } - - eval return \$$var + return [check_no_compiler_messages ${function}_available \ + executable [subst { + #ifdef __cplusplus + extern "C" + #endif + char $function (); + int main () { $function (); } + }]] } # Returns true iff "fork" is available on the target system. @@ -964,102 +855,56 @@ proc check_fork_available {} { # Returns true iff "mkfifo" is available on the target system. -proc check_mkfifo_available {} { - if {[istarget *-*-cygwin*]} { - # Cygwin has mkfifo, but support is incomplete. - return 0 - } - - return [check_function_available "mkfifo"] -} - -# Returns true iff "__cxa_atexit" is used on the target system. - -proc check_cxa_atexit_available { } { - global et_cxa_atexit - global et_cxa_atexit_target_name - global tool - - if { ![info exists et_cxa_atexit_target_name] } { - set et_cxa_atexit_target_name "" - } - - # If the target has changed since we set the cached value, clear it. - set current_target [current_target_name] - if { $current_target != $et_cxa_atexit_target_name } { - verbose "check_cxa_atexit_available: `$et_cxa_atexit_target_name'" 2 - set et_cxa_atexit_target_name $current_target - if [info exists et_cxa_atexit] { - verbose "check_cxa_atexit_available: removing cached result" 2 - unset et_cxa_atexit - } - } - - if [info exists et_cxa_atexit] { - verbose "check_cxa_atexit_available: using cached result" 2 - } elseif { [istarget "hppa*-*-hpux10*"] } { - # HP-UX 10 doesn't have __cxa_atexit but subsequent test passes. - set et_cxa_atexit 0 - } else { - set et_cxa_atexit 0 - - # Set up, compile, and execute a C++ test program that depends - # on correct ordering of static object destructors. This is - # indicative of the presence and use of __cxa_atexit. - set src cxaatexit[pid].cc - set exe cxaatexit[pid].x - - set f [open $src "w"] - puts $f "#include " - puts $f "static unsigned int count;" - puts $f "struct X" - puts $f "{" - puts $f " X() { count = 1; }" - puts $f " ~X()" - puts $f " {" - puts $f " if (count != 3)" - puts $f " exit(1);" - puts $f " count = 4;" - puts $f " }" - puts $f "};" - puts $f "void f()" - puts $f "{" - puts $f " static X x;" - puts $f "}" - puts $f "struct Y" - puts $f "{" - puts $f " Y() { f(); count = 2; }" - puts $f " ~Y()" - puts $f " {" - puts $f " if (count != 2)" - puts $f " exit(1);" - puts $f " count = 3;" - puts $f " }" - puts $f "};" - puts $f "Y y;" - puts $f "int main()" - puts $f "{ return 0; }" - close $f - - set lines [${tool}_target_compile $src $exe executable ""] - file delete $src +proc check_mkfifo_available {} { + if {[istarget *-*-cygwin*]} { + # Cygwin has mkfifo, but support is incomplete. + return 0 + } - if [string match "" $lines] { - # No error message, compilation succeeded. - set result [${tool}_load "./$exe" "" ""] - set status [lindex $result 0] - remote_file build delete $exe + return [check_function_available "mkfifo"] +} - verbose "check_cxa_atexit_available: status is <$status>" 2 +# Returns true iff "__cxa_atexit" is used on the target system. - if { $status == "pass" } { - set et_cxa_atexit 1 - } +proc check_cxa_atexit_available { } { + return [check_cached_effective_target cxa_atexit_available { + if { [istarget "hppa*-*-hpux10*"] } { + # HP-UX 10 doesn't have __cxa_atexit but subsequent test passes. + expr 0 } else { - verbose "check_cxa_atexit_available: compilation failed" 2 + check_runtime_nocache cxa_atexit_available { + // C++ + #include + static unsigned int count; + struct X + { + X() { count = 1; } + ~X() + { + if (count != 3) + exit(1); + count = 4; + } + }; + void f() + { + static X x; + } + struct Y + { + Y() { f(); count = 2; } + ~Y() + { + if (count != 2) + exit(1); + count = 3; + } + }; + Y y; + int main() { return 0; } + } } - } - return $et_cxa_atexit + }] } @@ -1130,51 +975,32 @@ proc check_effective_target_large_long_double { } { }] } +# Return 1 if the target supports compiling fixed-point, +# 0 otherwise. + +proc check_effective_target_fixed_point { } { + return [check_no_compiler_messages fixed_point object { + _Sat _Fract x; _Sat _Accum y; + }] +} # Return 1 if the target supports compiling decimal floating point, # 0 otherwise. proc check_effective_target_dfp_nocache { } { verbose "check_effective_target_dfp_nocache: compiling source" 2 - set ret [string match "" [get_compiler_messages dfp 0 object { + set ret [check_no_compiler_messages_nocache dfp object { _Decimal32 x; _Decimal64 y; _Decimal128 z; - }]] + }] verbose "check_effective_target_dfp_nocache: returning $ret" 2 return $ret } proc check_effective_target_dfprt_nocache { } { - global tool - - set ret 0 - - verbose "check_effective_target_dfprt_nocache: compiling source" 2 - # Set up, compile, and execute a test program containing decimal - # float operations. - set src dfprt[pid].c - set exe dfprt[pid].x - - set f [open $src "w"] - puts $f "_Decimal32 x = 1.2df; _Decimal64 y = 2.3dd; _Decimal128 z;" - puts $f "int main () { z = x + y; return 0; }" - close $f - - verbose "check_effective_target_dfprt_nocache: compiling testfile $src" 2 - set lines [${tool}_target_compile $src $exe executable ""] - file delete $src - - if [string match "" $lines] then { - # No error message, compilation succeeded. - set result [${tool}_load "./$exe" "" ""] - set status [lindex $result 0] - remote_file build delete $exe - verbose "check_effective_target_dfprt_nocache: testfile status is <$status>" 2 - if { $status == "pass" } then { - set ret 1 - } - } - return $ret - verbose "check_effective_target_dfprt_nocache: returning $ret" 2 + return [check_runtime_nocache dfprt { + _Decimal32 x = 1.2df; _Decimal64 y = 2.3dd; _Decimal128 z; + int main () { z = x + y; return 0; } + }] } # Return 1 if the target supports compiling Decimal Floating Point, @@ -1183,15 +1009,9 @@ proc check_effective_target_dfprt_nocache { } { # This won't change for different subtargets so cache the result. proc check_effective_target_dfp { } { - global et_dfp_saved - - if [info exists et_dfp_saved] { - verbose "check_effective_target_dfp: using cached result" 2 - } else { - set et_dfp_saved [check_effective_target_dfp_nocache] - } - verbose "check_effective_target_dfp: returning $et_dfp_saved" 2 - return $et_dfp_saved + return [check_cached_effective_target dfp { + check_effective_target_dfp_nocache + }] } # Return 1 if the target supports linking and executing Decimal Floating @@ -1200,16 +1020,9 @@ proc check_effective_target_dfp { } { # This won't change for different subtargets so cache the result. proc check_effective_target_dfprt { } { - global et_dfprt_saved - global tool - - if [info exists et_dfprt_saved] { - verbose "check_effective_target_dfprt: using cached result" 2 - } else { - set et_dfprt_saved [check_effective_target_dfprt_nocache] - } - verbose "check_effective_target_dfprt: returning $et_dfprt_saved" 2 - return $et_dfprt_saved + return [check_cached_effective_target dfprt { + check_effective_target_dfprt_nocache + }] } # Return 1 if the target needs a command line argument to enable a SIMD @@ -1240,7 +1053,10 @@ proc check_effective_target_vect_cmdline_needed { } { set et_vect_cmdline_needed_saved 1 if { [istarget ia64-*-*] || (([istarget x86_64-*-*] || [istarget i?86-*-*]) - && [check_effective_target_lp64])} { + && [check_effective_target_lp64]) + || ([istarget powerpc*-*-*] + && ([check_effective_target_powerpc_spe] + || [check_effective_target_powerpc_altivec]))} { set et_vect_cmdline_needed_saved 0 } } @@ -1261,7 +1077,8 @@ proc check_effective_target_vect_int { } { } else { set et_vect_int_saved 0 if { [istarget i?86-*-*] - || [istarget powerpc*-*-*] + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) || [istarget spu-*-*] || [istarget x86_64-*-*] || [istarget sparc*-*-*] @@ -1275,41 +1092,56 @@ proc check_effective_target_vect_int { } { return $et_vect_int_saved } -# Return 1 is this is an arm target using 32-bit instructions -proc check_effective_target_arm32 { } { - global et_arm32_saved - global et_arm32_target_name - global compiler_flags +# Return 1 if the target supports int->float conversion +# - if { ![info exists et_arm32_target_name] } { - set et_arm32_target_name "" - } +proc check_effective_target_vect_intfloat_cvt { } { + global et_vect_intfloat_cvt_saved - # If the target has changed since we set the cached value, clear it. - set current_target [current_target_name] - if { $current_target != $et_arm32_target_name } { - verbose "check_effective_target_arm32: `$et_arm32_target_name' `$current_target'" 2 - set et_arm32_target_name $current_target - if { [info exists et_arm32_saved] } { - verbose "check_effective_target_arm32: removing cached result" 2 - unset et_arm32_saved - } + if [info exists et_vect_intfloat_cvt_saved] { + verbose "check_effective_target_vect_intfloat_cvt: using cached result" 2 + } else { + set et_vect_intfloat_cvt_saved 0 + if { [istarget i?86-*-*] + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget x86_64-*-*] } { + set et_vect_intfloat_cvt_saved 1 + } } - if [info exists et_arm32_saved] { - verbose "check-effective_target_arm32: using cached result" 2 + verbose "check_effective_target_vect_intfloat_cvt: returning $et_vect_intfloat_cvt_saved" 2 + return $et_vect_intfloat_cvt_saved +} + + +# Return 1 if the target supports float->int conversion +# + +proc check_effective_target_vect_floatint_cvt { } { + global et_vect_floatint_cvt_saved + + if [info exists et_vect_floatint_cvt_saved] { + verbose "check_effective_target_vect_floatint_cvt: using cached result" 2 } else { - set et_arm32_saved 0 - if { [istarget arm-*-*] - || [istarget strongarm*-*-*] - || [istarget xscale-*-*] } { - if ![string match "*-mthumb *" $compiler_flags] { - set et_arm32_saved 1 - } - } + set et_vect_floatint_cvt_saved 0 + if { [istarget i?86-*-*] + || [istarget x86_64-*-*] } { + set et_vect_floatint_cvt_saved 1 + } } - verbose "check_effective_target_arm32: returning $et_arm32_saved" 2 - return $et_arm32_saved + + verbose "check_effective_target_vect_floatint_cvt: returning $et_vect_floatint_cvt_saved" 2 + return $et_vect_floatint_cvt_saved +} + +# Return 1 is this is an arm target using 32-bit instructions +proc check_effective_target_arm32 { } { + return [check_no_compiler_messages arm32 assembly { + #if !defined(__arm__) || (defined(__thumb__) && !defined(__thumb2__)) + #error FOO + #endif + }] } # Return 1 if this is an ARM target supporting -mfpu=vfp @@ -1326,6 +1158,37 @@ proc check_effective_target_arm_vfp_ok { } { } } +# Return 1 if this is an ARM target supporting -mfpu=neon +# -mfloat-abi=softfp. Some multilibs may be incompatible with these +# options. + +proc check_effective_target_arm_neon_ok { } { + if { [check_effective_target_arm32] } { + return [check_no_compiler_messages arm_neon_ok object { + int dummy; + } "-mfpu=neon -mfloat-abi=softfp"] + } else { + return 0 + } +} + +# Return 1 if the target supports executing NEON instructions, 0 +# otherwise. Cache the result. + +proc check_effective_target_arm_neon_hw { } { + return [check_runtime arm_neon_hw_available { + int + main (void) + { + long long a = 0, b = 1; + asm ("vorr %P0, %P1, %P2" + : "=w" (a) + : "0" (a), "w" (b)); + return (a != 1); + } + } "-mfpu=neon -mfloat-abi=softfp"] +} + # Return 1 if this is a PowerPC target with floating-point registers. proc check_effective_target_powerpc_fprs { } { @@ -1346,10 +1209,13 @@ proc check_effective_target_powerpc_fprs { } { # Return 1 if this is a PowerPC target supporting -maltivec. proc check_effective_target_powerpc_altivec_ok { } { - if { [istarget powerpc*-*-*] + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) || [istarget rs6000-*-*] } { - # AltiVec is not supported on Aix. - if { [istarget powerpc*-*-aix*] } { + # AltiVec is not supported on AIX before 5.3. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5.1*] + || [istarget powerpc*-*-aix5.2*] } { return 0 } return [check_no_compiler_messages powerpc_altivec_ok object { @@ -1360,6 +1226,54 @@ proc check_effective_target_powerpc_altivec_ok { } { } } +# Return 1 if this is a PowerPC target that supports SPU. + +proc check_effective_target_powerpc_spu { } { + return [istarget powerpc*-*-linux*] +} + +# Return 1 if this is a PowerPC target with SPE enabled. + +proc check_effective_target_powerpc_spe { } { + if { [istarget powerpc*-*-*] } { + return [check_no_compiler_messages powerpc_spe object { + #ifndef __SPE__ + #error not SPE + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target with Altivec enabled. + +proc check_effective_target_powerpc_altivec { } { + if { [istarget powerpc*-*-*] } { + return [check_no_compiler_messages powerpc_altivec object { + #ifndef __ALTIVEC__ + #error not Altivec + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +# The VxWorks SPARC simulator accepts only EM_SPARC executables and +# chokes on EM_SPARC32PLUS or EM_SPARCV9 executables. Return 1 if the +# test environment appears to run executables on such a simulator. + +proc check_effective_target_ultrasparc_hw { } { + return [check_runtime ultrasparc_hw { + int main() { return 0; } + } "-mcpu=ultrasparc"] +} + # Return 1 if the target supports hardware vector shift operation. proc check_effective_target_vect_shift { } { @@ -1369,7 +1283,8 @@ proc check_effective_target_vect_shift { } { verbose "check_effective_target_vect_shift: using cached result" 2 } else { set et_vect_shift_saved 0 - if { [istarget powerpc*-*-*] + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) || [istarget ia64-*-*] || [istarget i?86-*-*] || [istarget x86_64-*-*] } { @@ -1387,7 +1302,9 @@ proc check_effective_target_vect_shift { } { proc check_effective_target_vect_long { } { if { [istarget i?86-*-*] - || ([istarget powerpc*-*-*] && [check_effective_target_ilp32]) + || (([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + && [check_effective_target_ilp32]) || [istarget x86_64-*-*] || ([istarget sparc*-*-*] && [check_effective_target_ilp32]) } { set answer 1 @@ -1446,26 +1363,6 @@ proc check_effective_target_vect_double { } { return $et_vect_double_saved } -# Return 0 if the target supports hardware comparison of vectors of double, 0 otherwise. -# -# This won't change for different subtargets so cache the result. - -proc check_effective_target_vect_no_compare_double { } { - global et_vect_no_compare_double_saved - - if [info exists et_vect_no_compare_double_saved] { - verbose "check_effective_target_vect_no_compare_double: using cached result" 2 - } else { - set et_vect_no_compare_double_saved 0 - if { [istarget spu-*-*] } { - set et_vect_no_compare_double_saved 1 - } - } - - verbose "check_effective_target_vect_no_compare_double: returning $et_vect_no_compare_double_saved" 2 - return $et_vect_no_compare_double_saved -} - # Return 1 if the target plus current options does not support a vector # max instruction on "int", 0 otherwise. # @@ -1540,7 +1437,8 @@ proc check_effective_target_vect_widen_sum_hi_to_si { } { verbose "check_effective_target_vect_widen_sum_hi_to_si: using cached result" 2 } else { set et_vect_widen_sum_hi_to_si_saved [check_effective_target_vect_unpack] - if { [istarget powerpc*-*-*] } { + if { [istarget powerpc*-*-*] + || [istarget ia64-*-*] } { set et_vect_widen_sum_hi_to_si_saved 1 } } @@ -1562,7 +1460,8 @@ proc check_effective_target_vect_widen_sum_qi_to_hi { } { verbose "check_effective_target_vect_widen_sum_qi_to_hi: using cached result" 2 } else { set et_vect_widen_sum_qi_to_hi_saved 0 - if { [check_effective_target_vect_unpack] } { + if { [check_effective_target_vect_unpack] + || [istarget ia64-*-*] } { set et_vect_widen_sum_qi_to_hi_saved 1 } } @@ -1641,6 +1540,7 @@ proc check_effective_target_vect_widen_mult_hi_to_si { } { set et_vect_widen_mult_hi_to_si_saved 0 } if { [istarget powerpc*-*-*] + || [istarget spu-*-*] || [istarget i?86-*-*] || [istarget x86_64-*-*] } { set et_vect_widen_mult_hi_to_si_saved 1 @@ -1699,7 +1599,7 @@ proc check_effective_target_vect_sdot_hi { } { verbose "check_effective_target_vect_sdot_hi: using cached result" 2 } else { set et_vect_sdot_hi_saved 0 - if { [istarget powerpc*-*-*] + if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) || [istarget i?86-*-*] || [istarget x86_64-*-*] } { set et_vect_sdot_hi_saved 1 @@ -1721,7 +1621,7 @@ proc check_effective_target_vect_udot_hi { } { verbose "check_effective_target_vect_udot_hi: using cached result" 2 } else { set et_vect_udot_hi_saved 0 - if { [istarget powerpc*-*-*] } { + if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) } { set et_vect_udot_hi_saved 1 } } @@ -1736,21 +1636,21 @@ proc check_effective_target_vect_udot_hi { } { # # This won't change for different subtargets so cache the result. -proc check_effective_target_vect_pack_mod { } { - global et_vect_pack_mod +proc check_effective_target_vect_pack_trunc { } { + global et_vect_pack_trunc - if [info exists et_vect_pack_mod_saved] { - verbose "check_effective_target_vect_pack_mod: using cached result" 2 + if [info exists et_vect_pack_trunc_saved] { + verbose "check_effective_target_vect_pack_trunc: using cached result" 2 } else { - set et_vect_pack_mod_saved 0 - if { [istarget powerpc*-*-*] + set et_vect_pack_trunc_saved 0 + if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) || [istarget i?86-*-*] || [istarget x86_64-*-*] } { - set et_vect_pack_mod_saved 1 + set et_vect_pack_trunc_saved 1 } } - verbose "check_effective_target_vect_pack_mod: returning $et_vect_pack_mod_saved" 2 - return $et_vect_pack_mod_saved + verbose "check_effective_target_vect_pack_trunc: returning $et_vect_pack_trunc_saved" 2 + return $et_vect_pack_trunc_saved } # Return 1 if the target plus current options supports a vector @@ -1765,9 +1665,10 @@ proc check_effective_target_vect_unpack { } { verbose "check_effective_target_vect_unpack: using cached result" 2 } else { set et_vect_unpack_saved 0 - if { [istarget powerpc*-*-*] + if { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*]) || [istarget i?86-*-*] - || [istarget x86_64-*-*] } { + || [istarget x86_64-*-*] + || [istarget spu-*-*] } { set et_vect_unpack_saved 1 } } @@ -1775,6 +1676,27 @@ proc check_effective_target_vect_unpack { } { return $et_vect_unpack_saved } +# Return 1 if the target plus current options does not guarantee +# that its STACK_BOUNDARY is >= the reguired vector alignment. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_unaligned_stack { } { + global et_unaligned_stack_saved + + if [info exists et_unaligned_stack_saved] { + verbose "check_effective_target_unaligned_stack: using cached result" 2 + } else { + set et_unaligned_stack_saved 0 + if { ( [istarget i?86-*-*] || [istarget x86_64-*-*] ) + && (! [istarget *-*-darwin*] ) } { + set et_unaligned_stack_saved 1 + } + } + verbose "check_effective_target_unaligned_stack: returning $et_unaligned_stack_saved" 2 + return $et_unaligned_stack_saved +} + # Return 1 if the target plus current options does not support a vector # alignment mechanism, 0 otherwise. # @@ -1789,7 +1711,7 @@ proc check_effective_target_vect_no_align { } { set et_vect_no_align_saved 0 if { [istarget mipsisa64*-*-*] || [istarget sparc*-*-*] - || [istarget ia64-*-*] } { + || [istarget ia64-*-*] } { set et_vect_no_align_saved 1 } } @@ -1797,6 +1719,112 @@ proc check_effective_target_vect_no_align { } { return $et_vect_no_align_saved } +# Return 1 if arrays are aligned to the vector alignment +# boundary, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_aligned_arrays { } { + global et_vect_aligned_arrays + + if [info exists et_vect_aligned_arrays_saved] { + verbose "check_effective_target_vect_aligned_arrays: using cached result" 2 + } else { + set et_vect_aligned_arrays_saved 0 + if { (([istarget x86_64-*-*] + || [istarget i?86-*-*]) && [is-effective-target lp64]) + || [istarget spu-*-*] } { + set et_vect_aligned_arrays_saved 1 + } + } + verbose "check_effective_target_vect_aligned_arrays: returning $et_vect_aligned_arrays_saved" 2 + return $et_vect_aligned_arrays_saved +} + +# Return 1 if types of size 32 bit or less are naturally aligned +# (aligned to their type-size), 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_natural_alignment_32 { } { + global et_natural_alignment_32 + + if [info exists et_natural_alignment_32_saved] { + verbose "check_effective_target_natural_alignment_32: using cached result" 2 + } else { + # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER. + set et_natural_alignment_32_saved 1 + if { ([istarget *-*-darwin*] && [is-effective-target lp64]) } { + set et_natural_alignment_32_saved 0 + } + } + verbose "check_effective_target_natural_alignment_32: returning $et_natural_alignment_32_saved" 2 + return $et_natural_alignment_32_saved +} + +# Return 1 if types of size 64 bit or less are naturally aligned (aligned to their +# type-size), 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_natural_alignment_64 { } { + global et_natural_alignment_64 + + if [info exists et_natural_alignment_64_saved] { + verbose "check_effective_target_natural_alignment_64: using cached result" 2 + } else { + set et_natural_alignment_64_saved 0 + if { ([is-effective-target lp64] && ![istarget *-*-darwin*]) + || [istarget spu-*-*] } { + set et_natural_alignment_64_saved 1 + } + } + verbose "check_effective_target_natural_alignment_64: returning $et_natural_alignment_64_saved" 2 + return $et_natural_alignment_64_saved +} + +# Return 1 if vector alignment (for types of size 32 bit or less) is reachable, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vector_alignment_reachable { } { + global et_vector_alignment_reachable + + if [info exists et_vector_alignment_reachable_saved] { + verbose "check_effective_target_vector_alignment_reachable: using cached result" 2 + } else { + if { [check_effective_target_vect_aligned_arrays] + || [check_effective_target_natural_alignment_32] } { + set et_vector_alignment_reachable_saved 1 + } else { + set et_vector_alignment_reachable_saved 0 + } + } + verbose "check_effective_target_vector_alignment_reachable: returning $et_vector_alignment_reachable_saved" 2 + return $et_vector_alignment_reachable_saved +} + +# Return 1 if vector alignment for 64 bit is reachable, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vector_alignment_reachable_for_64bit { } { + global et_vector_alignment_reachable_for_64bit + + if [info exists et_vector_alignment_reachable_for_64bit_saved] { + verbose "check_effective_target_vector_alignment_reachable_for_64bit: using cached result" 2 + } else { + if { [check_effective_target_vect_aligned_arrays] + || [check_effective_target_natural_alignment_64] } { + set et_vector_alignment_reachable_for_64bit_saved 1 + } else { + set et_vector_alignment_reachable_for_64bit_saved 0 + } + } + verbose "check_effective_target_vector_alignment_reachable_for_64bit: returning $et_vector_alignment_reachable_for_64bit_saved" 2 + return $et_vector_alignment_reachable_for_64bit_saved +} + # Return 1 if the target supports vector conditional operations, 0 otherwise. proc check_effective_target_vect_condition { } { @@ -1809,6 +1837,7 @@ proc check_effective_target_vect_condition { } { if { [istarget powerpc*-*-*] || [istarget ia64-*-*] || [istarget i?86-*-*] + || [istarget spu-*-*] || [istarget x86_64-*-*] } { set et_vect_cond_saved 1 } @@ -1848,6 +1877,7 @@ proc check_effective_target_vect_short_mult { } { } else { set et_vect_short_mult_saved 0 if { [istarget ia64-*-*] + || [istarget spu-*-*] || [istarget i?86-*-*] || [istarget x86_64-*-*] } { set et_vect_short_mult_saved 1 @@ -1867,7 +1897,8 @@ proc check_effective_target_vect_int_mult { } { verbose "check_effective_target_vect_int_mult: using cached result" 2 } else { set et_vect_int_mult_saved 0 - if { [istarget powerpc*-*-*] + if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) + || [istarget spu-*-*] || [istarget i?86-*-*] || [istarget x86_64-*-*] } { set et_vect_int_mult_saved 1 @@ -1916,6 +1947,24 @@ proc check_effective_target_vect_interleave { } { return $et_vect_interleave_saved } +# Return 1 if the target supports vector interleaving and extract even/odd, 0 otherwise. +proc check_effective_target_vect_strided { } { + global et_vect_strided_saved + + if [info exists et_vect_strided_saved] { + verbose "check_effective_target_vect_strided: using cached result" 2 + } else { + set et_vect_strided_saved 0 + if { [check_effective_target_vect_interleave] + && [check_effective_target_vect_extract_even_odd] } { + set et_vect_strided_saved 1 + } + } + + verbose "check_effective_target_vect_strided: returning $et_vect_strided_saved" 2 + return $et_vect_strided_saved +} + # Return 1 if the target supports section-anchors proc check_effective_target_section_anchors { } { @@ -1988,6 +2037,75 @@ proc check_effective_target_sync_char_short { } { return $et_sync_char_short_saved } +# Return 1 if the target uses a ColdFire FPU. + +proc check_effective_target_coldfire_fpu { } { + return [check_no_compiler_messages coldfire_fpu assembly { + #ifndef __mcffpu__ + #error FOO + #endif + }] +} + +# Return true if this is a uClibc target. + +proc check_effective_target_uclibc {} { + return [check_no_compiler_messages uclibc object { + #include + #if !defined (__UCLIBC__) + #error FOO + #endif + }] +} + +# Return true if this is a uclibc target and if the uclibc feature +# described by __$feature__ is not present. + +proc check_missing_uclibc_feature {feature} { + return [check_no_compiler_messages $feature object " + #include + #if !defined (__UCLIBC) || defined (__${feature}__) + #error FOO + #endif + "] +} + +# Return true if this is a Newlib target. + +proc check_effective_target_newlib {} { + return [check_no_compiler_messages newlib object { + #include + }] +} + +# Return 1 if +# (a) an error of a few ULP is expected in string to floating-point +# conversion functions; and +# (b) overflow is not always detected correctly by those functions. + +proc check_effective_target_lax_strtofp {} { + # By default, assume that all uClibc targets suffer from this. + return [check_effective_target_uclibc] +} + +# Return 1 if this is a target for which wcsftime is a dummy +# function that always returns 0. + +proc check_effective_target_dummy_wcsftime {} { + # By default, assume that all uClibc targets suffer from this. + return [check_effective_target_uclibc] +} + +# Return 1 if constructors with initialization priority arguments are +# supposed on this target. + +proc check_effective_target_init_priority {} { + return [check_no_compiler_messages init_priority assembly " + void f() __attribute__((constructor (1000))); + void f() \{\} + "] +} + # Return 1 if the target matches the effective target 'arg', 0 otherwise. # This can be used with any check_* proc that takes no argument and # returns only 1 or 0. It could be used with check_* procs that take @@ -2055,3 +2173,74 @@ proc check_effective_target_stdint_types { } { uint8_t e; uint16_t f; uint32_t g; uint64_t h; }] } + +# Return 1 if programs are intended to be run on a simulator +# (i.e. slowly) rather than hardware (i.e. fast). + +proc check_effective_target_simulator { } { + + # All "src/sim" simulators set this one. + if [board_info target exists is_simulator] { + return [board_info target is_simulator] + } + + # The "sid" simulators don't set that one, but at least they set + # this one. + if [board_info target exists slow_simulator] { + return [board_info target slow_simulator] + } + + return 0 +} + +# Return 1 if the target is a VxWorks RTP. + +proc check_effective_target_vxworks_kernel { } { + return [check_no_compiler_messages vxworks_kernel assembly { + #if !defined __vxworks || defined __RTP__ + #error NO + #endif + }] +} + +# Return 1 if the target is expected to provide wide character support. + +proc check_effective_target_wchar { } { + if {[check_missing_uclibc_feature UCLIBC_HAS_WCHAR]} { + return 0 + } + return [check_no_compiler_messages wchar assembly { + #include + }] +} + +# Add to FLAGS all the target-specific flags needed to access the c99 runtime. + +proc add_options_for_c99_runtime { flags } { + if { [istarget *-*-solaris2*] } { + return "$flags -std=c99" + } + if { [istarget powerpc-*-darwin*] } { + return "$flags -mmacosx-version-min=10.3" + } + return $flags +} + +# Return 1 if the target provides a full C99 runtime. + +proc check_effective_target_c99_runtime { } { + return [check_cached_effective_target c99_runtime { + global srcdir + + set file [open "$srcdir/gcc.dg/builtins-config.h"] + set contents [read $file] + close $file + append contents { + #ifndef HAVE_C99_RUNTIME + #error FOO + #endif + } + check_no_compiler_messages_nocache c99_runtime assembly \ + $contents [add_options_for_c99_runtime ""] + }] +}