X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftestsuite%2Flib%2Ftarget-supports.exp;h=bee879efa218fb63dfd2062401ecb91f7b2dc925;hb=6159737ca33df722cfff9837df8f6a1bd4d1f85c;hp=5a39b8608d21b2ebe1b7bda08a6520160e787ef6;hpb=7ca4b2b82d26ef69947e5710430fc8d2ed982f5c;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 5a39b8608d2..bee879efa21 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -1,4 +1,4 @@ -# Copyright (C) 1999, 2001, 2003, 2004, 2005, 2006, 2007 +# Copyright (C) 1999, 2001, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify @@ -20,20 +20,18 @@ # 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 + }] } ############################### @@ -184,6 +251,20 @@ proc check_weak_available { } { } ############################### +# proc check_weak_override_available { } +############################### + +# Like check_weak_available, but return 0 if weak symbol definitions +# cannot be overridden. + +proc check_weak_override_available { } { + if { [istarget "*-*-mingw*"] } { + return 0 + } + return [check_weak_available] +} + +############################### # proc check_visibility_available { what_kind } ############################### @@ -316,6 +397,35 @@ proc check_gc_sections_available { } { return $gc_sections_available_saved } +# Return 1 if according to target_info struct and explicit target list +# target is supposed to support trampolines. + +proc check_effective_target_trampolines { } { + if [target_info exists no_trampolines] { + return 0 + } + if { [istarget avr-*-*] + || [istarget hppa2.0w-hp-hpux11.23] + || [istarget hppa64-hp-hpux11.23] } { + return 0; + } + return 1 +} + +# Return 1 if according to target_info struct and explicit target list +# target is supposed to keep null pointer checks. This could be due to +# use of option fno-delete-null-pointer-checks or hardwired in target. + +proc check_effective_target_keeps_null_pointer_checks { } { + if [target_info exists keeps_null_pointer_checks] { + return 1 + } + if { [istarget avr-*-*] } { + return 1; + } + return 0 +} + # Return true if profiling is supported on the target. proc check_profiling_available { test_what } { @@ -343,8 +453,16 @@ proc check_profiling_available { test_what } { return 0 } - # At present, there is no profiling support on NetWare. - if { [istarget *-*-netware*] } { + # We don't yet support profiling for MIPS16. + if { [istarget mips*-*-*] + && ![check_effective_target_nomips16] + && ([lindex $test_what 1] == "-p" + || [lindex $test_what 1] == "-pg") } { + return 0 + } + + # MinGW does not support -p. + if { [istarget *-*-mingw*] && [lindex $test_what 1] == "-p" } { return 0 } @@ -361,22 +479,25 @@ proc check_profiling_available { test_what } { # missing other needed machinery. if { [istarget mmix-*-*] || [istarget arm*-*-eabi*] + || [istarget picochip-*-*] + || [istarget *-*-netware*] || [istarget arm*-*-elf] || [istarget arm*-*-symbianelf*] + || [istarget avr-*-*] || [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 m68k-*-uclinux*] || [istarget mips*-*-elf*] - || [istarget xtensa-*-elf] - || [istarget *-*-vxworks*] - || [istarget *-*-windiss] } { + || [istarget xstormy16-*] + || [istarget xtensa*-*-elf] + || [istarget *-*-rtems*] + || [istarget *-*-vxworks*] } { set profiling_available_saved 0 } else { set profiling_available_saved 1 @@ -386,6 +507,17 @@ proc check_profiling_available { test_what } { return $profiling_available_saved } +# Check to see if a target is "freestanding". This is as per the definition +# in Section 4 of C99 standard. Effectively, it is a target which supports no +# extra headers or libraries other than what is considered essential. +proc check_effective_target_freestanding { } { + if { [istarget picochip-*-*] } then { + return 1 + } else { + return 0 + } +} + # Return 1 if target has packed layout of structure members by # default, 0 otherwise. Note that this is slightly different than # whether the target has "natural alignment": both attributes may be @@ -416,37 +548,11 @@ 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 0 - - 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. Make sure that we test accesses - # as well as declarations. - puts $f "__thread int i;\n" - puts $f "int f (void) { return i; }\n" - puts $f "void g (int j) { i = j; }\n" - close $f - - # Test for thread-local data supported by the platform. - set comp_output \ - [${tool}_target_compile $src $asm assembly ""] - file delete $src - if { [string match "" $comp_output] } { - # No error messages, everything is OK. - set et_tls_saved 1 - } - remove-build-file $asm - } - verbose "check_effective_target_tls: returning $et_tls_saved" 2 - return $et_tls_saved + return [check_no_compiler_messages tls assembly { + __thread int i; + int f (void) { return i; } + void g (int j) { i = j; } + }] } # Return 1 if *native* thread local storage (TLS) is supported, 0 otherwise. @@ -454,43 +560,18 @@ proc check_effective_target_tls {} { # This won't change for different subtargets so cache the result. proc check_effective_target_tls_native {} { - global et_tls_native_saved - global tool - - if [info exists et_tls_saved] { - verbose "check_effective_target_tls_native: using cached result" 2 - } else { - set et_tls_native_saved 0 - - set src tls[pid].c - set asm tls[pid].S - verbose "check_effective_target_tls_native: compiling testfile $src" 2 - set f [open $src "w"] - # Compile a small test program. Make sure that we test accesses - # as well as declarations. - puts $f "__thread int i;\n" - puts $f "int f (void) { return i; }\n" - puts $f "void g (int j) { i = j; }\n" - close $f - - # Test for thread-local data supported by the platform. - set comp_output [${tool}_target_compile $src $asm assembly ""] - file delete $src - if { [string match "" $comp_output] } { - # No error messages, everything is OK. - set fd [open $asm r] - set text [read $fd] - close $fd - if { [string match "*emutls*" $text]} { - set et_tls_native_saved 0 - } else { - set et_tls_native_saved 1 - } - } - remove-build-file $asm + # VxWorks uses emulated TLS machinery, but with non-standard helper + # functions, so we fail to automatically detect it. + global target_triplet + if { [regexp ".*-.*-vxworks.*" $target_triplet] } { + return 0 } - verbose "check_effective_target_tls_native: returning $et_tls_native_saved" 2 - return $et_tls_native_saved + + 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. @@ -498,45 +579,19 @@ proc check_effective_target_tls_native {} { # 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 - } + return [check_runtime tls_runtime { + __thread int thr = 0; + int main (void) { return thr; } + }] +} - verbose "check_effective_target_tls_runtime: returning $et_tls_runtime_saved" 2 - } - } +# Return 1 if compilation with -fgraphite is error-free for trivial +# code, 0 otherwise. - return $et_tls_runtime_saved +proc check_effective_target_fgraphite {} { + return [check_no_compiler_messages fgraphite object { + void foo (void) { } + } "-O1 -fgraphite"] } # Return 1 if compilation with -fopenmp is error-free for trivial @@ -548,37 +603,20 @@ proc check_effective_target_fopenmp {} { } "-fopenmp"] } -# Return 1 if the target supports -fstack-protector -proc check_effective_target_fstack_protector {} { - global tool - set result "" - - set src stack_prot[pid].c - set exe stack_prot[pid].x - - verbose "check_effective_target_fstack_protector compiling testfile $src" 2 - - set f [open $src "w"] - # Compile a small test program. - puts $f "int main (void)\n { return 0; }\n" - close $f - - set opts "additional_flags=-fstack-protector" - set lines [${tool}_target_compile $src $exe executable "$opts" ] - file delete $src +# Return 1 if compilation with -pthread is error-free for trivial +# code, 0 otherwise. - if [string match "" $lines] then { - # No error messages, everything is OK. - set result [${tool}_load "./$exe" "" ""] - set status [lindex $result 0] - remote_file build delete $exe - verbose "check_iconv_available status is <$status>" 2 +proc check_effective_target_pthread {} { + return [check_no_compiler_messages pthread object { + void foo (void) { } + } "-pthread"] +} - if { $status == "pass" } then { - return 1 - } - } - return 0 +# 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 @@ -617,6 +655,72 @@ proc check_effective_target_mpaired_single { } { } "-mpaired-single"] } +# Return true if the target has access to FPU instructions. + +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 + }] + } + + # 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; } + }] +} + +# Return true if the target is a 64-bit MIPS target. + +proc check_effective_target_mips64 { } { + return [check_no_compiler_messages mips64 assembly { + #ifndef __mips64 + #error FOO + #endif + }] +} + +# Return true if the target is a MIPS target that does not produce +# MIPS16 code. + +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 + }] +} + +# Add the options needed for MIPS16 function attributes. At the moment, +# we don't support MIPS16 PIC. + +proc add_options_for_mips16_attribute { flags } { + return "$flags -mno-abicalls -fno-pic -DMIPS16=__attribute__((mips16))" +} + +# 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 { } { @@ -640,45 +744,25 @@ proc check_effective_target_unwrapped { } { # Return true if iconv is supported on the target. In particular IBM1047. proc check_iconv_available { test_what } { - global tool global libiconv - set result "" - - 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 - # 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 - - if [string match "" $lines] then { - # No error messages, everything is OK. - - set result [${tool}_load "./$exe" "" ""] - set status [lindex $result 0] - remote_file build delete $exe - - verbose "check_iconv_available status is <$status>" 2 - - if { $status == "pass" } then { - return 1 + 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; } - } - - return 0 + }] $libiconv] } # Return true if named sections are supported on this target. @@ -695,56 +779,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. - remote_file build delete $exe - 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 @@ -753,55 +794,24 @@ 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 + 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 + }] +} - if [string match "" $lines] then { - # No error message, compilation succeeded. - remote_file build delete $exe - set et_fortran_large_int_saved 1 - } - } +# Return 1 if the target supports Fortran integer(16), 0 otherwise. +# +# When the target name changes, replace the cached result. - return $et_fortran_large_int_saved +proc check_effective_target_fortran_integer_16 { } { + return [check_no_compiler_messages fortran_integer_16 executable { + ! Fortran + integer(16) :: i + end + }] } # Return 1 if we can statically link libgfortran, 0 otherwise. @@ -809,119 +819,90 @@ 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 + return [check_no_compiler_messages static_libgfortran executable { + ! Fortran + print *, 'test' + end + } "-static"] +} - set f [open $src "w"] - puts $f " print *, 'test'" - puts $f " end" - close $f +# Return 1 if the target supports executing 750CL paired-single instructions, 0 +# otherwise. Cache the result. - verbose "check_effective_target_static_libgfortran compiling testfile $src" 2 - set lines [${tool}_target_compile $src $exe executable "$opts"] - file delete $src +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" + } + }] +} - if [string match "" $lines] then { - # No error message, compilation succeeded. - remote_file build delete $exe - set et_static_libgfortran_saved 1 - } - } +# Return 1 if the target supports executing SSE2 instructions, 0 +# otherwise. Cache the result. - return $et_static_libgfortran_saved +proc check_sse2_hw_available { } { + return [check_cached_effective_target sse2_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } { + expr 0 + } else { + check_runtime_nocache sse2_hw_available { + #include "cpuid.h" + int main () + { + unsigned int eax, ebx, ecx, edx = 0; + if (__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return !(edx & bit_SSE2); + return 1; + } + } "" + } + }] } # 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 @@ -932,122 +913,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. @@ -1055,36 +951,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. @@ -1107,90 +981,44 @@ proc check_mkfifo_available {} { # 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 - - 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_cxa_atexit_available: status is <$status>" 2 - - if { $status == "pass" } { - set et_cxa_atexit 1 - } + 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 + }] } @@ -1244,11 +1072,23 @@ proc check_effective_target_int16 { } { # Return 1 if we're generating 64-bit code using default options, 0 # otherwise. -proc check_effective_target_lp64 { } { - return [check_no_compiler_messages lp64 object { +proc check_effective_target_lp64 { } { + return [check_no_compiler_messages lp64 object { + int dummy[sizeof (int) == 4 + && sizeof (void *) == 8 + && sizeof (long) == 8 ? 1 : -1]; + }] +} + +# Return 1 if we're generating 64-bit code using default llp64 options, +# 0 otherwise. + +proc check_effective_target_llp64 { } { + return [check_no_compiler_messages llp64 object { int dummy[sizeof (int) == 4 && sizeof (void *) == 8 - && sizeof (long) == 8 ? 1 : -1]; + && sizeof (long long) == 8 + && sizeof (long) == 4 ? 1 : -1]; }] } @@ -1261,51 +1101,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, @@ -1314,15 +1135,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 @@ -1331,16 +1146,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 @@ -1374,7 +1182,9 @@ proc check_effective_target_vect_cmdline_needed { } { && [check_effective_target_lp64]) || ([istarget powerpc*-*-*] && ([check_effective_target_powerpc_spe] - || [check_effective_target_powerpc_altivec]))} { + || [check_effective_target_powerpc_altivec])) + || [istarget spu-*-*] + || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } { set et_vect_cmdline_needed_saved 0 } } @@ -1395,12 +1205,14 @@ 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*-*-*] || [istarget alpha*-*-*] - || [istarget ia64-*-*] } { + || [istarget ia64-*-*] + || [check_effective_target_arm32] } { set et_vect_int_saved 1 } } @@ -1420,7 +1232,8 @@ proc check_effective_target_vect_intfloat_cvt { } { } else { set et_vect_intfloat_cvt_saved 0 if { [istarget i?86-*-*] - || [istarget powerpc*-*-*] + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) || [istarget x86_64-*-*] } { set et_vect_intfloat_cvt_saved 1 } @@ -1442,6 +1255,8 @@ proc check_effective_target_vect_floatint_cvt { } { } else { set et_vect_floatint_cvt_saved 0 if { [istarget i?86-*-*] + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) || [istarget x86_64-*-*] } { set et_vect_floatint_cvt_saved 1 } @@ -1451,7 +1266,6 @@ proc check_effective_target_vect_floatint_cvt { } { 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 { @@ -1489,58 +1303,59 @@ proc check_effective_target_arm_neon_ok { } { } } +# Return 1 is this is an ARM target where -mthumb causes Thumb-1 to be +# used. + +proc check_effective_target_arm_thumb1_ok { } { + return [check_no_compiler_messages arm_thumb1_ok assembly { + #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__) + #error FOO + #endif + } "-mthumb"] +} + # Return 1 if the target supports executing NEON instructions, 0 # otherwise. Cache the result. proc check_effective_target_arm_neon_hw { } { - global arm_neon_hw_available_saved - global tool + 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 ARM target with NEON enabled. - if [info exists arm_neon_hw_available_saved] { - verbose "check_arm_neon_hw_available returning saved $arm_neon_hw_avail -able_saved" 2 +proc check_effective_target_arm_neon { } { + if { [check_effective_target_arm32] } { + return [check_no_compiler_messages arm_neon object { + #ifndef __ARM_NEON__ + #error not NEON + #else + int dummy; + #endif + }] } else { - set arm_neon_hw_available_saved 0 - - # Set up, compile, and execute a test program containing NEON - # instructions. Include the current process ID in the file - # names to prevent conflicts with invocations for multiple - # testsuites. - set src neon[pid].c - set exe neon[pid].x - - set f [open $src "w"] - puts $f "int main() {" - puts $f " long long a = 0, b = 1;" - puts $f " asm (\"vorr %P0, %P1, %P2\"" - puts $f " : \"=w\" (a)" - puts $f " : \"0\" (a), \"w\" (b));" - puts $f " return (a != 1);" - puts $f "}" - close $f - - set opts "additional_flags=-mfpu=neon additional_flags=-mfloat-abi=softfp" - - verbose "check_arm_neon_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_arm_neon_hw_available testfile status is <$status>" 2 - - if { $status == "pass" } then { - set arm_neon_hw_available_saved 1 - } - } else { - verbose "check_arm_neon_hw_available testfile compilation failed" 2 - } + return 0 } +} + +# Return 1 if this a Loongson-2E or -2F target using an ABI that supports +# the Loongson vector modes. - return $arm_neon_hw_available_saved +proc check_effective_target_mips_loongson { } { + return [check_no_compiler_messages loongson assembly { + #if !defined(__mips_loongson_vector_rev) + #error FOO + #endif + }] } # Return 1 if this is a PowerPC target with floating-point registers. @@ -1560,13 +1375,34 @@ proc check_effective_target_powerpc_fprs { } { } } +# Return 1 if this is a PowerPC target with hardware double-precision +# floating point. + +proc check_effective_target_powerpc_hard_double { } { + if { [istarget powerpc*-*-*] + || [istarget rs6000-*-*] } { + return [check_no_compiler_messages powerpc_hard_double object { + #ifdef _SOFT_DOUBLE + #error soft double + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + # 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 { @@ -1577,6 +1413,35 @@ proc check_effective_target_powerpc_altivec_ok { } { } } +# Return 1 if this is a PowerPC target supporting -mcpu=cell. + +proc check_effective_target_powerpc_ppu_ok { } { + if [check_effective_target_powerpc_altivec_ok] { + return [check_no_compiler_messages cell_asm_available object { + int main (void) { +#ifdef __MACH__ + asm volatile ("lvlx v0,v0,v0"); +#else + asm volatile ("lvlx 0,0,0"); +#endif + return 0; + } + }] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target that supports SPU. + +proc check_effective_target_powerpc_spu { } { + if [istarget powerpc*-*-linux*] { + return [check_effective_target_powerpc_altivec_ok] + } else { + return 0 + } +} + # Return 1 if this is a PowerPC target with SPE enabled. proc check_effective_target_powerpc_spe { } { @@ -1609,49 +1474,44 @@ proc check_effective_target_powerpc_altivec { } { } } -# 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 { } { - global et_ultrasparc_hw_saved - global tool +# Return 1 if this is a PowerPC 405 target. The check includes options +# specified by dg-options for this test, so don't cache the result. - if [info exists et_ultrasparc_hw_saved] { - verbose "check_ultrasparc_hw_available returning saved $et_ultrasparc_hw_saved" 2 +proc check_effective_target_powerpc_405_nocache { } { + if { [istarget powerpc*-*-*] || [istarget rs6000-*-*] } { + return [check_no_compiler_messages_nocache powerpc_405 object { + #ifdef __PPC405__ + int dummy; + #else + #error not a PPC405 + #endif + } [current_compiler_flags]] } else { - set et_ultrasparc_hw_saved 0 - - # Set up, compile, and execute a simple test program. The - # program will be compiled with -mcpu=ultrasparc to instruct the - # assembler to produce EM_SPARC32PLUS executables. - set src svect[pid].c - set exe svect[pid].x - - set f [open $src "w"] - puts $f "int main() { return 0; }" - close $f + return 0 + } +} - verbose "check_ultrasparc_hw_available compiling testfile $src" 2 - set lines [${tool}_target_compile $src $exe executable "additional_flags=-mcpu=ultrasparc"] - file delete $src +# Return 1 if this is a SPU target with a toolchain that +# supports automatic overlay generation. - 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_ultrasparc_hw_available testfile status is <$status>" 2 - - if { $status == "pass" } then { - set et_ultrasparc_hw_saved 1 - } - } else { - verbose "check_ultrasparc_hw_available testfile compilation failed" 2 - } +proc check_effective_target_spu_auto_overlay { } { + if { [istarget spu*-*-elf*] } { + return [check_no_compiler_messages spu_auto_overlay executable { + int main (void) { } + } "-Wl,--auto-overlay" ] + } 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. - return $et_ultrasparc_hw_saved +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. @@ -1663,10 +1523,12 @@ 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-*-*] } { + || [istarget x86_64-*-*] + || [check_effective_target_arm32] } { set et_vect_shift_saved 1 } } @@ -1681,8 +1543,11 @@ 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-*-*] + || [check_effective_target_arm32] || ([istarget sparc*-*-*] && [check_effective_target_ilp32]) } { set answer 1 } else { @@ -1709,7 +1574,8 @@ proc check_effective_target_vect_float { } { || [istarget spu-*-*] || [istarget mipsisa64*-*-*] || [istarget x86_64-*-*] - || [istarget ia64-*-*] } { + || [istarget ia64-*-*] + || [check_effective_target_arm32] } { set et_vect_float_saved 1 } } @@ -1740,6 +1606,28 @@ proc check_effective_target_vect_double { } { return $et_vect_double_saved } +# Return 1 if the target supports hardware vectors of long long, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_long_long { } { + global et_vect_long_long_saved + + if [info exists et_vect_long_long_saved] { + verbose "check_effective_target_vect_long_long: using cached result" 2 + } else { + set et_vect_long_long_saved 0 + if { [istarget i?86-*-*] + || [istarget x86_64-*-*] } { + set et_vect_long_long_saved 1 + } + } + + verbose "check_effective_target_vect_long_long: returning $et_vect_long_long_saved" 2 + return $et_vect_long_long_saved +} + + # Return 1 if the target plus current options does not support a vector # max instruction on "int", 0 otherwise. # @@ -1800,6 +1688,28 @@ proc check_effective_target_vect_no_bitwise { } { return $et_vect_no_bitwise_saved } +# Return 1 if the target plus current options supports vector permutation, +# 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_perm { } { + global et_vect_perm + + if [info exists et_vect_perm_saved] { + verbose "check_effective_target_vect_perm: using cached result" 2 + } else { + set et_vect_perm_saved 0 + if { [istarget powerpc*-*-*] + || [istarget spu-*-*] } { + set et_vect_perm_saved 1 + } + } + verbose "check_effective_target_vect_perm: returning $et_vect_perm_saved" 2 + return $et_vect_perm_saved +} + + # Return 1 if the target plus current options supports a vector # widening summation of *short* args into *int* result, 0 otherwise. # A target can also support this widening summation if it can support @@ -1976,7 +1886,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 @@ -1998,7 +1908,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 } } @@ -2020,9 +1930,10 @@ proc check_effective_target_vect_pack_trunc { } { verbose "check_effective_target_vect_pack_trunc: using cached result" 2 } else { set et_vect_pack_trunc_saved 0 - if { [istarget powerpc*-*-*] + if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) || [istarget i?86-*-*] - || [istarget x86_64-*-*] } { + || [istarget x86_64-*-*] + || [istarget spu-*-*] } { set et_vect_pack_trunc_saved 1 } } @@ -2042,9 +1953,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 } } @@ -2052,6 +1964,23 @@ 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 + } + 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. # @@ -2066,7 +1995,8 @@ proc check_effective_target_vect_no_align { } { set et_vect_no_align_saved 0 if { [istarget mipsisa64*-*-*] || [istarget sparc*-*-*] - || [istarget ia64-*-*] } { + || [istarget ia64-*-*] + || [check_effective_target_arm32] } { set et_vect_no_align_saved 1 } } @@ -2086,8 +2016,9 @@ proc check_effective_target_vect_aligned_arrays { } { 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] } { + if { (([istarget x86_64-*-*] + || [istarget i?86-*-*]) && [is-effective-target lp64]) + || [istarget spu-*-*] } { set et_vect_aligned_arrays_saved 1 } } @@ -2095,28 +2026,49 @@ proc check_effective_target_vect_aligned_arrays { } { return $et_vect_aligned_arrays_saved } -# Return 1 if types are naturally aligned (aligned to their type-size), -# 0 otherwise. +# 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 { } { - global et_natural_alignment +proc check_effective_target_natural_alignment_64 { } { + global et_natural_alignment_64 - if [info exists et_natural_alignment_saved] { - verbose "check_effective_target_natural_alignment: using cached result" 2 + if [info exists et_natural_alignment_64_saved] { + verbose "check_effective_target_natural_alignment_64: using cached result" 2 } else { - # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER. - set et_natural_alignment_saved 1 - if { ([istarget *-*-darwin*] && [is-effective-target lp64]) } { - set et_natural_alignment_saved 0 + 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: returning $et_natural_alignment_saved" 2 - return $et_natural_alignment_saved + 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 is reachable, 0 otherwise. +# 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. @@ -2127,7 +2079,7 @@ proc check_effective_target_vector_alignment_reachable { } { verbose "check_effective_target_vector_alignment_reachable: using cached result" 2 } else { if { [check_effective_target_vect_aligned_arrays] - || [check_effective_target_natural_alignment] } { + || [check_effective_target_natural_alignment_32] } { set et_vector_alignment_reachable_saved 1 } else { set et_vector_alignment_reachable_saved 0 @@ -2137,24 +2089,25 @@ proc check_effective_target_vector_alignment_reachable { } { return $et_vector_alignment_reachable_saved } -# Return 1 if vector alignment for soubles is reachable, 0 otherwise. +# 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_double { } { - global et_vector_alignment_reachable_for_double +proc check_effective_target_vector_alignment_reachable_for_64bit { } { + global et_vector_alignment_reachable_for_64bit - if [info exists et_vector_alignment_reachable_for_double_saved] { - verbose "check_effective_target_vector_alignment_reachable_for_double: using cached result" 2 + 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] } { - set et_vector_alignment_reachable_for_double_saved 1 + 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_double_saved 0 + set et_vector_alignment_reachable_for_64bit_saved 0 } } - verbose "check_effective_target_vector_alignment_reachable_for_double: returning $et_vector_alignment_reachable_for_double_saved" 2 - return $et_vector_alignment_reachable_for_double_saved + 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. @@ -2209,8 +2162,10 @@ 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-*-*] } { + || [istarget x86_64-*-*] + || [istarget powerpc*-*-*] } { set et_vect_short_mult_saved 1 } } @@ -2228,10 +2183,11 @@ 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-*-*] } { + || [istarget x86_64-*-*] + || [check_effective_target_arm32] } { set et_vect_int_mult_saved 1 } } @@ -2249,7 +2205,8 @@ proc check_effective_target_vect_extract_even_odd { } { verbose "check_effective_target_vect_extract_even_odd: using cached result" 2 } else { set et_vect_extract_even_odd_saved 0 - if { [istarget powerpc*-*-*] } { + if { [istarget powerpc*-*-*] + || [istarget spu-*-*] } { set et_vect_extract_even_odd_saved 1 } } @@ -2258,6 +2215,28 @@ proc check_effective_target_vect_extract_even_odd { } { return $et_vect_extract_even_odd_saved } +# Return 1 if the target supports vector even/odd elements extraction of +# vectors with SImode elements or larger, 0 otherwise. + +proc check_effective_target_vect_extract_even_odd_wide { } { + global et_vect_extract_even_odd_wide_saved + + if [info exists et_vect_extract_even_odd_wide_saved] { + verbose "check_effective_target_vect_extract_even_odd_wide: using cached result" 2 + } else { + set et_vect_extract_even_odd_wide_saved 0 + if { [istarget powerpc*-*-*] + || [istarget i?86-*-*] + || [istarget x86_64-*-*] + || [istarget spu-*-*] } { + set et_vect_extract_even_odd_wide_saved 1 + } + } + + verbose "check_effective_target_vect_extract_even_wide_odd: returning $et_vect_extract_even_odd_wide_saved" 2 + return $et_vect_extract_even_odd_wide_saved +} + # Return 1 if the target supports vector interleaving, 0 otherwise. proc check_effective_target_vect_interleave { } { @@ -2269,7 +2248,8 @@ proc check_effective_target_vect_interleave { } { set et_vect_interleave_saved 0 if { [istarget powerpc*-*-*] || [istarget i?86-*-*] - || [istarget x86_64-*-*] } { + || [istarget x86_64-*-*] + || [istarget spu-*-*] } { set et_vect_interleave_saved 1 } } @@ -2296,6 +2276,25 @@ proc check_effective_target_vect_strided { } { return $et_vect_strided_saved } +# Return 1 if the target supports vector interleaving and extract even/odd +# for wide element types, 0 otherwise. +proc check_effective_target_vect_strided_wide { } { + global et_vect_strided_wide_saved + + if [info exists et_vect_strided_wide_saved] { + verbose "check_effective_target_vect_strided_wide: using cached result" 2 + } else { + set et_vect_strided_wide_saved 0 + if { [check_effective_target_vect_interleave] + && [check_effective_target_vect_extract_even_odd_wide] } { + set et_vect_strided_wide_saved 1 + } + } + + verbose "check_effective_target_vect_strided_wide: returning $et_vect_strided_wide_saved" 2 + return $et_vect_strided_wide_saved +} + # Return 1 if the target supports section-anchors proc check_effective_target_section_anchors { } { @@ -2332,7 +2331,8 @@ proc check_effective_target_sync_int_long { } { || [istarget s390*-*-*] || [istarget powerpc*-*-*] || [istarget sparc64-*-*] - || [istarget sparcv9-*-*] } { + || [istarget sparcv9-*-*] + || [istarget mips*-*-*] } { set et_sync_int_long_saved 1 } } @@ -2359,7 +2359,8 @@ proc check_effective_target_sync_char_short { } { || [istarget s390*-*-*] || [istarget powerpc*-*-*] || [istarget sparc64-*-*] - || [istarget sparcv9-*-*] } { + || [istarget sparcv9-*-*] + || [istarget mips*-*-*] } { set et_sync_char_short_saved 1 } } @@ -2524,7 +2525,7 @@ proc check_effective_target_simulator { } { return 0 } -# Return 1 if the target is a VxWorks RTP. +# Return 1 if the target is a VxWorks kernel. proc check_effective_target_vxworks_kernel { } { return [check_no_compiler_messages vxworks_kernel assembly { @@ -2534,6 +2535,16 @@ proc check_effective_target_vxworks_kernel { } { }] } +# Return 1 if the target is a VxWorks RTP. + +proc check_effective_target_vxworks_rtp { } { + return [check_no_compiler_messages vxworks_rtp 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 { } { @@ -2544,3 +2555,153 @@ proc check_effective_target_wchar { } { #include }] } + +# Return 1 if the target has . + +proc check_effective_target_pthread_h { } { + return [check_no_compiler_messages pthread_h assembly { + #include + }] +} + +# Return 1 if the target can truncate a file from a file-descriptor, +# as used by libgfortran/io/unix.c:fd_truncate; i.e. ftruncate or +# chsize. We test for a trivially functional truncation; no stubs. +# As libgfortran uses _FILE_OFFSET_BITS 64, we do too; it'll cause a +# different function to be used. + +proc check_effective_target_fd_truncate { } { + set prog { + #define _FILE_OFFSET_BITS 64 + #include + #include + #include + int main () + { + FILE *f = fopen ("tst.tmp", "wb"); + int fd; + const char t[] = "test writing more than ten characters"; + char s[11]; + fd = fileno (f); + write (fd, t, sizeof (t) - 1); + lseek (fd, 0, 0); + if (ftruncate (fd, 10) != 0) + exit (1); + close (fd); + f = fopen ("tst.tmp", "rb"); + if (fread (s, 1, sizeof (s), f) != 10 || strncmp (s, t, 10) != 0) + exit (1); + exit (0); + } + } + + if { [check_runtime ftruncate $prog] } { + return 1; + } + + regsub "ftruncate" $prog "chsize" prog + return [check_runtime chsize $prog] +} + +# 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 ""] + }] +} + +# Return 1 if target wchar_t is at least 4 bytes. + +proc check_effective_target_4byte_wchar_t { } { + return [check_no_compiler_messages 4byte_wchar_t object { + int dummy[sizeof (__WCHAR_TYPE__) >= 4 ? 1 : -1]; + }] +} + +# Return 1 if the target supports automatic stack alignment. + +proc check_effective_target_automatic_stack_alignment { } { + if { [istarget i?86*-*-*] + || [istarget x86_64-*-*] } then { + return 1 + } else { + return 0 + } +} + +# Return 1 if avx instructions can be compiled. + +proc check_effective_target_avx { } { + return [check_no_compiler_messages avx object { + void _mm256_zeroall (void) + { + __builtin_ia32_vzeroall (); + } + } "-O2 -mavx" ] +} + +# Return 1 if C wchar_t type is compatible with char16_t. + +proc check_effective_target_wchar_t_char16_t_compatible { } { + return [check_no_compiler_messages wchar_t_char16_t object { + __WCHAR_TYPE__ wc; + __CHAR16_TYPE__ *p16 = &wc; + char t[(((__CHAR16_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1]; + }] +} + +# Return 1 if C wchar_t type is compatible with char32_t. + +proc check_effective_target_wchar_t_char32_t_compatible { } { + return [check_no_compiler_messages wchar_t_char32_t object { + __WCHAR_TYPE__ wc; + __CHAR32_TYPE__ *p32 = &wc; + char t[(((__CHAR32_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1]; + }] +} + +# Return 1 if pow10 function exists. + +proc check_effective_target_pow10 { } { + return [check_runtime pow10 { + #include + int main () { + double x; + x = pow10 (1); + return 0; + } + } "-lm" ] +} + +# Return 1 if current options generate DFP instructions, 0 otherwise. + +proc check_effective_target_hard_dfp {} { + return [check_no_messages_and_pattern hard_dfp "!adddd3" assembly { + _Decimal64 x, y, z; + void foo (void) { z = x + y; } + }] +}