-# Copyright (C) 1999, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-# Free Software Foundation, Inc.
+# Copyright (C) 1999, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011, 2012 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
# "// C++" for c++,
# "! Fortran" for Fortran code,
# "/* ObjC", for ObjC
-# and "// ObjC++" for ObjC++
+# "// ObjC++" for ObjC++
+# and "// Go" for Go
# If the tool is ObjC/ObjC++ then we overide the extension to .m/.mm to
# allow for ObjC/ObjC++ specific flags.
proc check_compile {basename type contents args} {
"*// C++*" { set src ${basename}[pid].cc }
"*// ObjC++*" { set src ${basename}[pid].mm }
"*/* ObjC*" { set src ${basename}[pid].m }
+ "*// Go*" { set src ${basename}[pid].go }
default {
switch -- $tool {
"objc" { set src ${basename}[pid].m }
# this proc returns 1 if they're supported, 0 if they're not, or -1 if unsure
proc check_weak_available { } {
- global target_triplet
global target_cpu
# All mips targets should support it
# All solaris2 targets should support it
- if { [regexp ".*-solaris2.*" $target_triplet] } {
+ if { [istarget *-*-solaris2*] } {
return 1
}
# DEC OSF/1/Digital UNIX/Tru64 UNIX supports it
- if { [regexp "alpha.*osf.*" $target_triplet] } {
+ if { [istarget alpha*-dec-osf*] } {
return 1
}
# Windows targets Cygwin and MingW32 support it
- if { [regexp ".*mingw32|.*cygwin" $target_triplet] } {
+ if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
return 1
}
# HP-UX 10.X doesn't support it
- if { [istarget "hppa*-*-hpux10*"] } {
+ if { [istarget hppa*-*-hpux10*] } {
return 0
}
# cannot be overridden.
proc check_weak_override_available { } {
- if { [istarget "*-*-mingw*"] } {
+ if { [istarget *-*-mingw*] } {
return 0
}
return [check_weak_available]
# The argument is the kind of visibility, default/protected/hidden/internal.
proc check_visibility_available { what_kind } {
- global tool
- global target_triplet
-
- # On NetWare, support makes no sense.
- if { [istarget *-*-netware*] } {
- return 0
- }
-
if [string match "" $what_kind] { set what_kind "hidden" }
return [check_no_compiler_messages visibility_available_$what_kind object "
return $alias_available_saved
}
-###############################
-# proc check_ifunc_available { }
-###############################
-
-# Determine if the target toolchain supports the alias attribute.
-
-# Returns 2 if the target supports aliases. Returns 1 if the target
-# only supports weak aliased. Returns 0 if the target does not
-# support aliases at all. Returns -1 if support for aliases could not
-# be determined.
+# Returns 1 if the target toolchain supports ifunc, 0 otherwise.
proc check_ifunc_available { } {
- global ifunc_available_saved
- global tool
-
- if [info exists ifunc_available_saved] {
- verbose "check_ifunc_available returning saved $ifunc_available_saved" 2
- } else {
- set src ifunc[pid].c
- set obj ifunc[pid].o
- verbose "check_ifunc_available compiling testfile $src" 2
- set f [open $src "w"]
- # Compile a small test program. The definition of "g" is
- # necessary to keep the Solaris assembler from complaining
- # about the program.
- puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif\n"
- puts $f "void g() {} void f() __attribute__((ifunc(\"g\")));"
- close $f
- set lines [${tool}_target_compile $src $obj object ""]
- file delete $src
- remote_file build delete $obj
-
- if [string match "" $lines] then {
- # No error messages, everything is OK.
- set ifunc_available_saved 2
- } else {
- if [regexp "ifunc is not supported" $lines] {
- verbose "check_ifunc_available target does not support ifunc" 2
- set ifunc_available_saved 0
- } else {
- set ifunc_available_saved -1
- }
- }
-
- verbose "check_ifunc_available returning $ifunc_available_saved" 2
- }
-
- return $ifunc_available_saved
+ return [check_no_compiler_messages ifunc_available object {
+ #ifdef __cplusplus
+ extern "C"
+ #endif
+ void g() {}
+ void f() __attribute__((ifunc("g")));
+ }]
}
# Returns true if --gc-sections is supported on the target.
# These conditions depend on the argument so examine them before
# looking at the cache variable.
+ # Tree profiling requires TLS runtime support.
+ if { $test_what == "-fprofile-generate" } {
+ if { ![check_effective_target_tls_runtime] } {
+ return 0
+ }
+ }
+
# Support for -p on solaris2 relies on mcrt1.o which comes with the
# vendor compiler. We cannot reliably predict the directory where the
# vendor compiler (and thus mcrt1.o) is installed so we can't
# necessarily find mcrt1.o even if we have it.
- if { [istarget *-*-solaris2*] && [lindex $test_what 1] == "-p" } {
+ if { [istarget *-*-solaris2*] && $test_what == "-p" } {
return 0
}
# Support for -pg on irix relies on gcrt1.o which doesn't exist yet.
# See: http://gcc.gnu.org/ml/gcc/2002-10/msg00169.html
if { [istarget mips*-*-irix*]
- && ([lindex $test_what 1] == "-p" || [lindex $test_what 1] == "-pg") } {
+ && ($test_what == "-p" || $test_what == "-pg") } {
return 0
}
# 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") } {
+ && ($test_what == "-p" || $test_what == "-pg") } {
return 0
}
# MinGW does not support -p.
- if { [istarget *-*-mingw*] && [lindex $test_what 1] == "-p" } {
+ if { [istarget *-*-mingw*] && $test_what == "-p" } {
return 0
}
# cygwin does not support -p.
- if { [istarget *-*-cygwin*] && [lindex $test_what 1] == "-p" } {
+ if { [istarget *-*-cygwin*] && $test_what == "-p" } {
return 0
}
# uClibc does not have gcrt1.o.
if { [check_effective_target_uclibc]
- && ([lindex $test_what 1] == "-p"
- || [lindex $test_what 1] == "-pg") } {
+ && ($test_what == "-p" || $test_what == "-pg") } {
return 0
}
if {![info exists profiling_available_saved]} {
# Some targets don't have any implementation of __bb_init_func or are
# missing other needed machinery.
- if { [istarget mmix-*-*]
+ if { [istarget am3*-*-linux*]
|| [istarget arm*-*-eabi*]
- || [istarget picochip-*-*]
- || [istarget *-*-netware*]
|| [istarget arm*-*-elf]
|| [istarget arm*-*-symbianelf*]
|| [istarget avr-*-*]
|| [istarget bfin-*-*]
- || [istarget powerpc-*-eabi*]
- || [istarget powerpc-*-elf]
|| [istarget cris-*-*]
|| [istarget crisv32-*-*]
|| [istarget fido-*-elf]
|| [istarget h8300-*-*]
- || [istarget lm32-*-*]
- || [istarget m32c-*-elf]
+ || [istarget lm32-*-*]
+ || [istarget m32c-*-elf]
|| [istarget m68k-*-elf]
|| [istarget m68k-*-uclinux*]
|| [istarget mep-*-elf]
|| [istarget mips*-*-elf*]
+ || [istarget mmix-*-*]
+ || [istarget mn10300-*-elf*]
|| [istarget moxie-*-elf*]
+ || [istarget picochip-*-*]
+ || [istarget powerpc-*-eabi*]
+ || [istarget powerpc-*-elf]
|| [istarget rx-*-*]
+ || [istarget tic6x-*-elf]
|| [istarget xstormy16-*]
|| [istarget xtensa*-*-elf]
|| [istarget *-*-rtems*]
# Add to FLAGS all the target-specific flags needed to use thread-local storage.
proc add_options_for_tls { flags } {
+ # Tru64 UNIX uses emutls, which relies on a couple of pthread functions
+ # which only live in libpthread, so always pass -pthread for TLS.
+ if { [istarget alpha*-dec-osf*] } {
+ return "$flags -pthread"
+ }
# On Solaris 8 and 9, __tls_get_addr/___tls_get_addr only lives in
# libthread, so always pass -pthread for native TLS.
# Need to duplicate native TLS check from
proc check_effective_target_tls_native {} {
# 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] } {
+ if { [istarget *-*-vxworks*] } {
return 0
}
proc check_effective_target_tls_emulated {} {
# 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] } {
+ if { [istarget *-*-vxworks*] } {
return 1
}
return [check_runtime tls_runtime {
__thread int thr = 0;
int main (void) { return thr; }
- }]
+ } [add_options_for_tls ""]]
+}
+
+# Return 1 if atomic compare-and-swap is supported on 'int'
+
+proc check_effective_target_cas_char {} {
+ return [check_no_compiler_messages cas_char assembly {
+ #ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
+ #error unsupported
+ #endif
+ } ""]
+}
+
+proc check_effective_target_cas_int {} {
+ return [check_no_compiler_messages cas_int assembly {
+ #if __INT_MAX__ == 0x7fff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
+ /* ok */
+ #elif __INT_MAX__ == 0x7fffffff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+ /* ok */
+ #else
+ #error unsupported
+ #endif
+ } ""]
}
# Return 1 if -ffunction-sections is supported, 0 otherwise.
proc check_effective_target_function_sections {} {
# Darwin has its own scheme and silently accepts -ffunction-sections.
- global target_triplet
- if { [regexp ".*-.*-darwin.*" $target_triplet] } {
+ if { [istarget *-*-darwin*] } {
return 0
}
} "-ffunction-sections"]
}
+# Return 1 if instruction scheduling is available, 0 otherwise.
+
+proc check_effective_target_scheduling {} {
+ return [check_no_compiler_messages scheduling object {
+ void foo (void) { }
+ } "-fschedule-insns"]
+}
+
# Return 1 if compilation with -fgraphite is error-free for trivial
# code, 0 otherwise.
} "-fopenmp"]
}
+# Return 1 if compilation with -fgnu-tm is error-free for trivial
+# code, 0 otherwise.
+
+proc check_effective_target_fgnu_tm {} {
+ return [check_no_compiler_messages fgnu_tm object {
+ void foo (void) { }
+ } "-fgnu-tm"]
+}
+
+# Return 1 if the target supports mmap, 0 otherwise.
+
+proc check_effective_target_mmap {} {
+ return [check_function_available "mmap"]
+}
+
# Return 1 if compilation with -pthread is error-free for trivial
# code, 0 otherwise.
return 0
}
+# Return 1 if -pie, -fpie and -fPIE are supported, 0 otherwise.
+
+proc check_effective_target_pie { } {
+ if { [istarget *-*-darwin\[912\]*]
+ || [istarget *-*-linux*] } {
+ return 1;
+ }
+ return 0
+}
+
# Return true if the target supports -mpaired-single (as used on MIPS).
proc check_effective_target_mpaired_single { } {
} "-mabi=64"]
}
+# Return true if the target is a MIPS target that has access
+# to the LL and SC instructions.
+
+proc check_effective_target_mips_llsc { } {
+ if { ![istarget mips*-*-*] } {
+ return 0
+ }
+ # Assume that these instructions are always implemented for
+ # non-elf* targets, via emulation if necessary.
+ if { ![istarget *-*-elf*] } {
+ return 1
+ }
+ # Otherwise assume LL/SC support for everything but MIPS I.
+ return [check_no_compiler_messages mips_llsc assembly {
+ #if __mips == 1
+ #error FOO
+ #endif
+ }]
+}
+
+# Return true if the target is a MIPS target that uses in-place relocations.
+
+proc check_effective_target_mips_rel { } {
+ if { ![istarget mips*-*-*] } {
+ return 0
+ }
+ return [check_no_compiler_messages mips_rel object {
+ #if (defined _ABIN32 && _MIPS_SIM == _ABIN32) \
+ || (defined _ABI64 && _MIPS_SIM == _ABI64)
+ #error FOO
+ #endif
+ }]
+}
+
+# Return true if the target is a MIPS target that uses the EABI.
+
+proc check_effective_target_mips_eabi { } {
+ if { ![istarget mips*-*-*] } {
+ return 0
+ }
+ return [check_no_compiler_messages mips_eabi object {
+ #ifndef __mips_eabi
+ #error FOO
+ #endif
+ }]
+}
+
# Return 1 if the current multilib does not generate PIC by default.
proc check_effective_target_nonpic { } {
}] $libiconv]
}
+# Return 1 if an ASCII locale is supported on this host, 0 otherwise.
+
+proc check_ascii_locale_available { } {
+ if { ([ishost alpha*-dec-osf*] || [ishost mips-sgi-irix*]) } {
+ # Neither Tru64 UNIX nor IRIX support an ASCII locale.
+ return 0
+ } else {
+ return 1
+ }
+}
+
# Return true if named sections are supported on this target.
proc check_named_sections_available { } {
}]
}
+# Return 1 if the target supports Fortran real kind real(16),
+# 0 otherwise. Contrary to check_effective_target_fortran_large_real
+# this checks for Real(16) only; the other returned real(10) if
+# both real(10) and real(16) are available.
+#
+# When the target name changes, replace the cached result.
+
+proc check_effective_target_fortran_real_16 { } {
+ return [check_no_compiler_messages fortran_real_16 executable {
+ ! Fortran
+ real(kind=16) :: x
+ x = cos (x)
+ end
+ }]
+}
+
+
+# Return 1 if the target supports SQRT for the largest floating-point
+# type. (Some targets lack the libm support for this FP type.)
+# On most targets, this check effectively checks either whether sqrtl is
+# available or on __float128 systems whether libquadmath is installed,
+# which provides sqrtq.
+#
+# When the target name changes, replace the cached result.
+
+proc check_effective_target_fortran_largest_fp_has_sqrt { } {
+ return [check_no_compiler_messages fortran_largest_fp_has_sqrt executable {
+ ! Fortran
+ use iso_fortran_env, only: real_kinds
+ integer,parameter:: maxFP = real_kinds(ubound(real_kinds,dim=1))
+ real(kind=maxFP), volatile :: x
+ x = 2.0_maxFP
+ x = sqrt (x)
+ end
+ }]
+}
+
+
# Return 1 if the target supports Fortran integer kinds larger than
# integer(8), 0 otherwise.
#
check_runtime_nocache sse_os_support_available {
int main ()
{
- __asm__ volatile ("movss %xmm2,%xmm1");
- return 0;
+ asm volatile ("movaps %xmm0,%xmm0");
+ return 0;
}
} "-msse"
} else {
}]
}
+# Return 1 if the target OS supports running AVX executables, 0
+# otherwise. Cache the result.
+
+proc check_avx_os_support_available { } {
+ return [check_cached_effective_target avx_os_support_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 that OS has AVX and SSE saving enabled.
+ check_runtime_nocache avx_os_support_available {
+ int main ()
+ {
+ unsigned int eax, edx;
+
+ asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0));
+ return (eax & 6) != 6;
+ }
+ } ""
+ }
+ }]
+}
+
# Return 1 if the target supports executing SSE instructions, 0
# otherwise. Cache the result.
proc check_effective_target_avx_runtime { } {
if { [check_effective_target_avx]
- && [check_avx_hw_available] } {
+ && [check_avx_hw_available]
+ && [check_avx_os_support_available] } {
return 1
}
return 0
}]
}
+# Return 1 is this is a TI C6X target supporting C67X instructions
+proc check_effective_target_ti_c67x { } {
+ return [check_no_compiler_messages ti_c67x assembly {
+ #if !defined(_TMS320C6700)
+ #error FOO
+ #endif
+ }]
+}
+
+# Return 1 is this is a TI C6X target supporting C64X+ instructions
+proc check_effective_target_ti_c64xp { } {
+ return [check_no_compiler_messages ti_c64xp assembly {
+ #if !defined(_TMS320C6400_PLUS)
+ #error FOO
+ #endif
+ }]
+}
+
+
proc check_alpha_max_hw_available { } {
return [check_runtime alpha_max_hw_available {
int main() { return __builtin_alpha_amask(1<<8) != 0; }
#endif
char $function ();
int main () { $function (); }
- }]]
+ }] "-fno-builtin" ]
}
# Returns true iff "fork" is available on the target system.
# Returns true iff "mkfifo" is available on the target system.
proc check_mkfifo_available {} {
- if {[istarget *-*-cygwin*]} {
+ if { [istarget *-*-cygwin*] } {
# Cygwin has mkfifo, but support is incomplete.
return 0
}
proc check_cxa_atexit_available { } {
return [check_cached_effective_target cxa_atexit_available {
- if { [istarget "hppa*-*-hpux10*"] } {
+ if { [istarget hppa*-*-hpux10*] } {
# HP-UX 10 doesn't have __cxa_atexit but subsequent test passes.
expr 0
- } elseif { [istarget "*-*-vxworks"] } {
+ } elseif { [istarget *-*-vxworks] } {
# vxworks doesn't have __cxa_atexit but subsequent test passes.
expr 0
} else {
}]
}
+# Return 1 if we're generating ia32 code using default options, 0
+# otherwise.
+
+proc check_effective_target_ia32 { } {
+ return [check_no_compiler_messages ia32 object {
+ int dummy[sizeof (int) == 4
+ && sizeof (void *) == 4
+ && sizeof (long) == 4 ? 1 : -1] = { __i386__ };
+ }]
+}
+
+# Return 1 if we're generating x32 code using default options, 0
+# otherwise.
+
+proc check_effective_target_x32 { } {
+ return [check_no_compiler_messages x32 object {
+ int dummy[sizeof (int) == 4
+ && sizeof (void *) == 4
+ && sizeof (long) == 4 ? 1 : -1] = { __x86_64__ };
+ }]
+}
+
# Return 1 if we're generating 32-bit or larger integers using default
# options, 0 otherwise.
if { [istarget alpha*-*-*]
|| [istarget ia64-*-*]
|| (([istarget x86_64-*-*] || [istarget i?86-*-*])
- && [check_effective_target_lp64])
+ && ([check_effective_target_x32]
+ || [check_effective_target_lp64]))
|| ([istarget powerpc*-*-*]
&& ([check_effective_target_powerpc_spe]
|| [check_effective_target_powerpc_altivec]))
+ || ([istarget sparc*-*-*] && [check_effective_target_sparc_vis])
|| [istarget spu-*-*]
|| ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
set et_vect_cmdline_needed_saved 0
if { [istarget i?86-*-*]
|| ([istarget powerpc*-*-*]
&& ![istarget powerpc-*-linux*paired*])
- || [istarget x86_64-*-*] } {
+ || [istarget x86_64-*-*]
+ || ([istarget arm*-*-*]
+ && [check_effective_target_arm_neon_ok])} {
set et_vect_intfloat_cvt_saved 1
}
}
if { [istarget i?86-*-*]
|| ([istarget powerpc*-*-*]
&& ![istarget powerpc-*-linux*paired*])
- || [istarget x86_64-*-*] } {
+ || [istarget x86_64-*-*]
+ || ([istarget arm*-*-*]
+ && [check_effective_target_arm_neon_ok])} {
set et_vect_uintfloat_cvt_saved 1
}
}
if { [istarget i?86-*-*]
|| ([istarget powerpc*-*-*]
&& ![istarget powerpc-*-linux*paired*])
- || [istarget x86_64-*-*] } {
+ || [istarget x86_64-*-*]
+ || ([istarget arm*-*-*]
+ && [check_effective_target_arm_neon_ok])} {
set et_vect_floatint_cvt_saved 1
}
}
} else {
set et_vect_floatuint_cvt_saved 0
if { ([istarget powerpc*-*-*]
- && ![istarget powerpc-*-linux*paired*]) } {
+ && ![istarget powerpc-*-linux*paired*])
+ || ([istarget arm*-*-*]
+ && [check_effective_target_arm_neon_ok])} {
set et_vect_floatuint_cvt_saved 1
}
}
}]
}
+# Return 1 is this is an arm target not using Thumb
+proc check_effective_target_arm_nothumb { } {
+ return [check_no_compiler_messages arm_nothumb assembly {
+ #if (defined(__thumb__) || defined(__thumb2__))
+ #error FOO
+ #endif
+ }]
+}
+
+# Return 1 if this is a little-endian ARM target
+proc check_effective_target_arm_little_endian { } {
+ return [check_no_compiler_messages arm_little_endian assembly {
+ #if !defined(__arm__) || !defined(__ARMEL__)
+ #error FOO
+ #endif
+ }]
+}
+
+# Return 1 if this is an ARM target that only supports aligned vector accesses
+proc check_effective_target_arm_vect_no_misalign { } {
+ return [check_no_compiler_messages arm_vect_no_misalign assembly {
+ #if !defined(__arm__) \
+ || (defined(__ARMEL__) \
+ && (!defined(__thumb__) || defined(__thumb2__)))
+ #error FOO
+ #endif
+ }]
+}
+
+
# Return 1 if this is an ARM target supporting -mfpu=vfp
# -mfloat-abi=softfp. Some multilibs may be incompatible with these
# options.
}
}
+# Return 1 if this is an ARM target that supports DSP multiply with
+# current multilib flags.
+
+proc check_effective_target_arm_dsp { } {
+ return [check_no_compiler_messages arm_dsp assembly {
+ #ifndef __ARM_FEATURE_DSP
+ #error not DSP
+ #endif
+ int i;
+ }]
+}
+
+# Return 1 if this is an ARM target that supports unaligned word/halfword
+# load/store instructions.
+
+proc check_effective_target_arm_unaligned { } {
+ return [check_no_compiler_messages arm_unaligned assembly {
+ #ifndef __ARM_FEATURE_UNALIGNED
+ #error no unaligned support
+ #endif
+ int i;
+ }]
+}
+
# Add the options needed for NEON. We need either -mfloat-abi=softfp
# or -mfloat-abi=hard, but if one is already specified by the
# multilib, use it. Similarly, if a -mfpu option already enables
# or -mfloat-abi=hard, but if one is already specified by the
# multilib, use it.
-proc add_options_for_arm_neon_fp16 { flags } {
- if { ! [check_effective_target_arm_neon_fp16_ok] } {
+proc add_options_for_arm_fp16 { flags } {
+ if { ! [check_effective_target_arm_fp16_ok] } {
return "$flags"
}
- global et_arm_neon_fp16_flags
- return "$flags $et_arm_neon_fp16_flags"
+ global et_arm_fp16_flags
+ return "$flags $et_arm_fp16_flags"
}
-# Return 1 if this is an ARM target supporting -mfpu=neon-fp16
-# -mfloat-abi=softfp or equivalent options. Some multilibs may be
-# incompatible with these options. Also set et_arm_neon_flags to the
-# best options to add.
+# Return 1 if this is an ARM target that can support a VFP fp16 variant.
+# Skip multilibs that are incompatible with these options and set
+# et_arm_fp16_flags to the best options to add.
-proc check_effective_target_arm_neon_fp16_ok_nocache { } {
- global et_arm_neon_fp16_flags
- set et_arm_neon_fp16_flags ""
- if { [check_effective_target_arm32] } {
- # Always add -mfpu=neon-fp16, since there is no preprocessor
- # macro for FP16 support.
- foreach flags {"-mfpu=neon-fp16" "-mfpu=neon-fp16 -mfloat-abi=softfp"} {
- if { [check_no_compiler_messages_nocache arm_neon_fp16_ok object {
- #include "arm_neon.h"
- int dummy;
- } "$flags"] } {
- set et_arm_neon_fp16_flags $flags
- return 1
- }
- }
+proc check_effective_target_arm_fp16_ok_nocache { } {
+ global et_arm_fp16_flags
+ set et_arm_fp16_flags ""
+ if { ! [check_effective_target_arm32] } {
+ return 0;
+ }
+ if [check-flags [list "" { *-*-* } { "-mfpu=*" } { "-mfpu=*fp16*" "-mfpu=*fpv[4-9]*" "-mfpu=*fpv[1-9][0-9]*" } ]] {
+ # Multilib flags would override -mfpu.
+ return 0
+ }
+ if [check-flags [list "" { *-*-* } { "-mfloat-abi=soft" } { "" } ]] {
+ # Must generate floating-point instructions.
+ return 0
+ }
+ if [check-flags [list "" { *-*-* } { "-mfpu=*" } { "" } ]] {
+ # The existing -mfpu value is OK; use it, but add softfp.
+ set et_arm_fp16_flags "-mfloat-abi=softfp"
+ return 1;
+ }
+ # Add -mfpu for a VFP fp16 variant since there is no preprocessor
+ # macro to check for this support.
+ set flags "-mfpu=vfpv4 -mfloat-abi=softfp"
+ if { [check_no_compiler_messages_nocache arm_fp16_ok assembly {
+ int dummy;
+ } "$flags"] } {
+ set et_arm_fp16_flags "$flags"
+ return 1
}
return 0
}
-proc check_effective_target_arm_neon_fp16_ok { } {
- return [check_cached_effective_target arm_neon_fp16_ok \
- check_effective_target_arm_neon_fp16_ok_nocache]
+proc check_effective_target_arm_fp16_ok { } {
+ return [check_cached_effective_target arm_fp16_ok \
+ check_effective_target_arm_fp16_ok_nocache]
+}
+
+# Creates a series of routines that return 1 if the given architecture
+# can be selected and a routine to give the flags to select that architecture
+# Note: Extra flags may be added to disable options from newer compilers
+# (Thumb in particular - but others may be added in the future)
+# Usage: /* { dg-require-effective-target arm_arch_v5_ok } */
+# /* { dg-add-options arm_arch_v5 } */
+foreach { armfunc armflag armdef } { v5 "-march=armv5 -marm" __ARM_ARCH_5__
+ v6 "-march=armv6" __ARM_ARCH_6__
+ v6k "-march=armv6k" __ARM_ARCH_6K__
+ v7a "-march=armv7-a" __ARM_ARCH_7A__ } {
+ eval [string map [list FUNC $armfunc FLAG $armflag DEF $armdef ] {
+ proc check_effective_target_arm_arch_FUNC_ok { } {
+ if { [ string match "*-marm*" "FLAG" ] &&
+ ![check_effective_target_arm_arm_ok] } {
+ return 0
+ }
+ return [check_no_compiler_messages arm_arch_FUNC_ok assembly {
+ #if !defined (DEF)
+ #error FOO
+ #endif
+ } "FLAG" ]
+ }
+
+ proc add_options_for_arm_arch_FUNC { flags } {
+ return "$flags FLAG"
+ }
+ }]
+}
+
+# Return 1 if this is an ARM target where -marm causes ARM to be
+# used (not Thumb)
+
+proc check_effective_target_arm_arm_ok { } {
+ return [check_no_compiler_messages arm_arm_ok assembly {
+ #if !defined (__arm__) || defined (__thumb__) || defined (__thumb2__)
+ #error FOO
+ #endif
+ } "-marm"]
}
+
# Return 1 is this is an ARM target where -mthumb causes Thumb-1 to be
# used.
} "-mthumb"]
}
+# Return 1 if this is an ARM target where Thumb-1 is used without options
+# added by the test.
+
+proc check_effective_target_arm_thumb1 { } {
+ return [check_no_compiler_messages arm_thumb1 assembly {
+ #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__)
+ #error not thumb1
+ #endif
+ int i;
+ } ""]
+}
+
+# Return 1 if this is an ARM target where Thumb-2 is used without options
+# added by the test.
+
+proc check_effective_target_arm_thumb2 { } {
+ return [check_no_compiler_messages arm_thumb2 assembly {
+ #if !defined(__thumb2__)
+ #error FOO
+ #endif
+ int i;
+ } ""]
+}
+
+# Return 1 if this is an ARM cortex-M profile cpu
+
+proc check_effective_target_arm_cortex_m { } {
+ return [check_no_compiler_messages arm_cortex_m assembly {
+ #if !defined(__ARM_ARCH_7M__) \
+ && !defined (__ARM_ARCH_7EM__) \
+ && !defined (__ARM_ARCH_6M__)
+ #error FOO
+ #endif
+ int i;
+ } "-mthumb"]
+}
+
# Return 1 if the target supports executing NEON instructions, 0
# otherwise. Cache the result.
# Return 1 if this is a PowerPC target that supports SPU.
proc check_effective_target_powerpc_spu { } {
- if [istarget powerpc*-*-linux*] {
+ if { [istarget powerpc*-*-linux*] } {
return [check_effective_target_powerpc_altivec_ok]
} else {
return 0
} "-mcpu=ultrasparc"]
}
+# Return 1 if the test environment supports executing UltraSPARC VIS2
+# instructions. We check this by attempting: "bmask %g0, %g0, %g0"
+
+proc check_effective_target_ultrasparc_vis2_hw { } {
+ return [check_runtime ultrasparc_vis2_hw {
+ int main() { __asm__(".word 0x81b00320"); return 0; }
+ } "-mcpu=ultrasparc3"]
+}
+
+# Return 1 if the test environment supports executing UltraSPARC VIS3
+# instructions. We check this by attempting: "addxc %g0, %g0, %g0"
+
+proc check_effective_target_ultrasparc_vis3_hw { } {
+ return [check_runtime ultrasparc_vis3_hw {
+ int main() { __asm__(".word 0x81b00220"); return 0; }
+ } "-mcpu=niagara3"]
+}
+
+# Return 1 if this is a Sparc target with VIS enabled.
+
+proc check_effective_target_sparc_vis { } {
+ if { [istarget sparc*-*-*] } {
+ return [check_no_compiler_messages sparc_vis object {
+ #ifndef __VIS__
+ #error not VIS
+ #else
+ int dummy;
+ #endif
+ }]
+ } else {
+ return 0
+ }
+}
+
# Return 1 if the target supports hardware vector shift operation.
proc check_effective_target_vect_shift { } {
return $et_vect_shift_saved
}
+# Return 1 if the target supports hardware vector shift operation for char.
+
+proc check_effective_target_vect_shift_char { } {
+ global et_vect_shift_char_saved
+
+ if [info exists et_vect_shift_char_saved] {
+ verbose "check_effective_target_vect_shift_char: using cached result" 2
+ } else {
+ set et_vect_shift_char_saved 0
+ if { ([istarget powerpc*-*-*]
+ && ![istarget powerpc-*-linux*paired*])
+ || [check_effective_target_arm32] } {
+ set et_vect_shift_char_saved 1
+ }
+ }
+
+ verbose "check_effective_target_vect_shift_char: returning $et_vect_shift_char_saved" 2
+ return $et_vect_shift_char_saved
+}
+
# Return 1 if the target supports hardware vectors of long, 0 otherwise.
#
# This can change for different subtargets so do not cache the result.
verbose "check_effective_target_vect_perm: using cached result" 2
} else {
set et_vect_perm_saved 0
- if { [istarget powerpc*-*-*]
+ if { [is-effective-target arm_neon_ok]
+ || [istarget powerpc*-*-*]
|| [istarget spu-*-*]
|| [istarget i?86-*-*]
- || [istarget x86_64-*-*] } {
+ || [istarget x86_64-*-*]
+ || ([istarget mips*-*-*]
+ && [check_effective_target_mpaired_single]) } {
set et_vect_perm_saved 1
}
}
verbose "check_effective_target_vect_perm_byte: using cached result" 2
} else {
set et_vect_perm_byte_saved 0
- if { [istarget powerpc*-*-*]
+ if { [is-effective-target arm_neon_ok]
+ || [istarget powerpc*-*-*]
|| [istarget spu-*-*] } {
set et_vect_perm_byte_saved 1
}
verbose "check_effective_target_vect_perm_short: using cached result" 2
} else {
set et_vect_perm_short_saved 0
- if { [istarget powerpc*-*-*]
+ if { [is-effective-target arm_neon_ok]
+ || [istarget powerpc*-*-*]
|| [istarget spu-*-*] } {
set et_vect_perm_short_saved 1
}
verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern: using cached result" 2
} else {
set et_vect_widen_sum_hi_to_si_pattern_saved 0
- if { [istarget powerpc*-*-*] } {
+ if { [istarget powerpc*-*-*]
+ || [istarget ia64-*-*] } {
set et_vect_widen_sum_hi_to_si_pattern_saved 1
}
}
} else {
set et_vect_widen_mult_qi_to_hi_saved 0
}
- if { [istarget powerpc*-*-*] } {
+ if { [istarget powerpc*-*-*]
+ || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
set et_vect_widen_mult_qi_to_hi_saved 1
}
}
}
if { [istarget powerpc*-*-*]
|| [istarget spu-*-*]
+ || [istarget ia64-*-*]
|| [istarget i?86-*-*]
- || [istarget x86_64-*-*] } {
+ || [istarget x86_64-*-*]
+ || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
set et_vect_widen_mult_hi_to_si_saved 1
}
}
}
# Return 1 if the target plus current options supports a vector
+# widening multiplication of *char* args into *short* result, 0 otherwise.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } {
+ global et_vect_widen_mult_qi_to_hi_pattern
+
+ if [info exists et_vect_widen_mult_qi_to_hi_pattern_saved] {
+ verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern: using cached result" 2
+ } else {
+ set et_vect_widen_mult_qi_to_hi_pattern_saved 0
+ if { [istarget powerpc*-*-*]
+ || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
+ set et_vect_widen_mult_qi_to_hi_pattern_saved 1
+ }
+ }
+ verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern: returning $et_vect_widen_mult_qi_to_hi_pattern_saved" 2
+ return $et_vect_widen_mult_qi_to_hi_pattern_saved
+}
+
+# Return 1 if the target plus current options supports a vector
+# widening multiplication of *short* args into *int* result, 0 otherwise.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } {
+ global et_vect_widen_mult_hi_to_si_pattern
+
+ if [info exists et_vect_widen_mult_hi_to_si_pattern_saved] {
+ verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern: using cached result" 2
+ } else {
+ set et_vect_widen_mult_hi_to_si_pattern_saved 0
+ if { [istarget powerpc*-*-*]
+ || [istarget spu-*-*]
+ || [istarget ia64-*-*]
+ || [istarget i?86-*-*]
+ || [istarget x86_64-*-*]
+ || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
+ set et_vect_widen_mult_hi_to_si_pattern_saved 1
+ }
+ }
+ verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern: returning $et_vect_widen_mult_hi_to_si_pattern_saved" 2
+ return $et_vect_widen_mult_hi_to_si_pattern_saved
+}
+
+# Return 1 if the target plus current options supports a vector
+# widening shift, 0 otherwise.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_vect_widen_shift { } {
+ global et_vect_widen_shift_saved
+
+ if [info exists et_vect_shift_saved] {
+ verbose "check_effective_target_vect_widen_shift: using cached result" 2
+ } else {
+ set et_vect_widen_shift_saved 0
+ if { ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]) } {
+ set et_vect_widen_shift_saved 1
+ }
+ }
+ verbose "check_effective_target_vect_widen_shift: returning $et_vect_widen_shift_saved" 2
+ return $et_vect_widen_shift_saved
+}
+
+# Return 1 if the target plus current options supports a vector
# dot-product of signed chars, 0 otherwise.
#
# This won't change for different subtargets so cache the result.
verbose "check_effective_target_vect_sdot_qi: using cached result" 2
} else {
set et_vect_sdot_qi_saved 0
+ if { [istarget ia64-*-*] } {
+ set et_vect_udot_qi_saved 1
+ }
}
verbose "check_effective_target_vect_sdot_qi: returning $et_vect_sdot_qi_saved" 2
return $et_vect_sdot_qi_saved
verbose "check_effective_target_vect_udot_qi: using cached result" 2
} else {
set et_vect_udot_qi_saved 0
- if { [istarget powerpc*-*-*] } {
+ if { [istarget powerpc*-*-*]
+ || [istarget ia64-*-*] } {
set et_vect_udot_qi_saved 1
}
}
} else {
set et_vect_sdot_hi_saved 0
if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
+ || [istarget ia64-*-*]
|| [istarget i?86-*-*]
|| [istarget x86_64-*-*] } {
set et_vect_sdot_hi_saved 1
|| [istarget i?86-*-*]
|| [istarget x86_64-*-*]
|| [istarget spu-*-*]
- || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
+ || ([istarget arm*-*-*] && [check_effective_target_arm_neon]
+ && [check_effective_target_arm_little_endian]) } {
set et_vect_pack_trunc_saved 1
}
}
|| [istarget i?86-*-*]
|| [istarget x86_64-*-*]
|| [istarget spu-*-*]
- || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
+ || [istarget ia64-*-*]
+ || ([istarget arm*-*-*] && [check_effective_target_arm_neon]
+ && [check_effective_target_arm_little_endian]) } {
set et_vect_unpack_saved 1
}
}
if { [istarget mipsisa64*-*-*]
|| [istarget sparc*-*-*]
|| [istarget ia64-*-*]
- || [check_effective_target_arm32]
+ || [check_effective_target_arm_vect_no_misalign]
|| ([istarget mips*-*-*]
&& [check_effective_target_mips_loongson]) } {
set et_vect_no_align_saved 1
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-*-*] } {
+ if { ([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
+ if { ([is-effective-target lp64]
+ && ( ![check_avx_available]
+ || [check_prefer_avx128])) } {
+ set et_vect_aligned_arrays_saved 1
+ }
+ }
+ if [istarget spu-*-*] {
set et_vect_aligned_arrays_saved 1
}
}
return $et_vector_alignment_reachable_for_64bit_saved
}
+# Return 1 if the target only requires element alignment for vector accesses
+
+proc check_effective_target_vect_element_align { } {
+ global et_vect_element_align
+
+ if [info exists et_vect_element_align] {
+ verbose "check_effective_target_vect_element_align: using cached result" 2
+ } else {
+ set et_vect_element_align 0
+ if { ([istarget arm*-*-*]
+ && ![check_effective_target_arm_vect_no_misalign])
+ || [check_effective_target_vect_hw_misalign] } {
+ set et_vect_element_align 1
+ }
+ }
+
+ verbose "check_effective_target_vect_element_align: returning $et_vect_element_align" 2
+ return $et_vect_element_align
+}
+
# Return 1 if the target supports vector conditional operations, 0 otherwise.
proc check_effective_target_vect_condition { } {
|| [istarget ia64-*-*]
|| [istarget i?86-*-*]
|| [istarget spu-*-*]
- || [istarget x86_64-*-*] } {
+ || [istarget x86_64-*-*]
+ || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]) } {
set et_vect_cond_saved 1
}
}
return $et_vect_cond_saved
}
+# Return 1 if the target supports vector conditional operations where
+# the comparison has different type from the lhs, 0 otherwise.
+
+proc check_effective_target_vect_cond_mixed { } {
+ global et_vect_cond_mixed_saved
+
+ if [info exists et_vect_cond_mixed_saved] {
+ verbose "check_effective_target_vect_cond_mixed: using cached result" 2
+ } else {
+ set et_vect_cond_mixed_saved 0
+ if { [istarget i?86-*-*]
+ || [istarget x86_64-*-*]
+ || [istarget powerpc*-*-*] } {
+ set et_vect_cond_mixed_saved 1
+ }
+ }
+
+ verbose "check_effective_target_vect_cond_mixed: returning $et_vect_cond_mixed_saved" 2
+ return $et_vect_cond_mixed_saved
+}
+
# Return 1 if the target supports vector char multiplication, 0 otherwise.
proc check_effective_target_vect_char_mult { } {
|| [istarget spu-*-*]
|| [istarget i?86-*-*]
|| [istarget x86_64-*-*]
+ || [istarget ia64-*-*]
|| [check_effective_target_arm32] } {
set et_vect_int_mult_saved 1
}
} else {
set et_vect_extract_even_odd_saved 0
if { [istarget powerpc*-*-*]
+ || [is-effective-target arm_neon_ok]
|| [istarget i?86-*-*]
|| [istarget x86_64-*-*]
- || [istarget spu-*-*] } {
- set et_vect_extract_even_odd_saved 1
+ || [istarget ia64-*-*]
+ || [istarget spu-*-*]
+ || ([istarget mips*-*-*]
+ && [check_effective_target_mpaired_single]) } {
+ set et_vect_extract_even_odd_saved 1
}
}
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 { } {
} else {
set et_vect_interleave_saved 0
if { [istarget powerpc*-*-*]
+ || [is-effective-target arm_neon_ok]
|| [istarget i?86-*-*]
|| [istarget x86_64-*-*]
- || [istarget spu-*-*] } {
+ || [istarget ia64-*-*]
+ || [istarget spu-*-*]
+ || ([istarget mips*-*-*]
+ && [check_effective_target_mpaired_single]) } {
set et_vect_interleave_saved 1
}
}
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
+foreach N {2 3 4 8} {
+ eval [string map [list N $N] {
+ # Return 1 if the target supports 2-vector interleaving
+ proc check_effective_target_vect_stridedN { } {
+ global et_vect_stridedN_saved
- if [info exists et_vect_strided_saved] {
- verbose "check_effective_target_vect_strided: using cached result" 2
+ if [info exists et_vect_stridedN_saved] {
+ verbose "check_effective_target_vect_stridedN: using cached result" 2
+ } else {
+ set et_vect_stridedN_saved 0
+ if { (N & -N) == N
+ && [check_effective_target_vect_interleave]
+ && [check_effective_target_vect_extract_even_odd] } {
+ set et_vect_stridedN_saved 1
+ }
+ if { [istarget arm*-*-*] && N >= 2 && N <= 4 } {
+ set et_vect_stridedN_saved 1
+ }
+ }
+
+ verbose "check_effective_target_vect_stridedN: returning $et_vect_stridedN_saved" 2
+ return $et_vect_stridedN_saved
+ }
+ }]
+}
+
+# Return 1 if the target supports multiple vector sizes
+
+proc check_effective_target_vect_multiple_sizes { } {
+ global et_vect_multiple_sizes_saved
+
+ set et_vect_multiple_sizes_saved 0
+ if { ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
+ set et_vect_multiple_sizes_saved 1
+ }
+ if { ([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
+ if { ([check_avx_available] && ![check_prefer_avx128]) } {
+ set et_vect_multiple_sizes_saved 1
+ }
+ }
+
+ verbose "check_effective_target_vect_multiple_sizes: returning $et_vect_multiple_sizes_saved" 2
+ return $et_vect_multiple_sizes_saved
+}
+
+# Return 1 if the target supports vectors of 64 bits.
+
+proc check_effective_target_vect64 { } {
+ global et_vect64_saved
+
+ if [info exists et_vect64_saved] {
+ verbose "check_effective_target_vect64: 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
+ set et_vect64_saved 0
+ if { ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]) } {
+ set et_vect64_saved 1
}
}
- verbose "check_effective_target_vect_strided: returning $et_vect_strided_saved" 2
- return $et_vect_strided_saved
+ verbose "check_effective_target_vect64: returning $et_vect64_saved" 2
+ return $et_vect64_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
+# Return 1 if the target supports vector copysignf calls.
- if [info exists et_vect_strided_wide_saved] {
- verbose "check_effective_target_vect_strided_wide: using cached result" 2
+proc check_effective_target_vect_call_copysignf { } {
+ global et_vect_call_copysignf_saved
+
+ if [info exists et_vect_call_copysignf_saved] {
+ verbose "check_effective_target_vect_call_copysignf: 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
- }
+ set et_vect_call_copysignf_saved 0
+ if { [istarget i?86-*-*]
+ || [istarget x86_64-*-*]
+ || [istarget powerpc*-*-*] } {
+ set et_vect_call_copysignf_saved 1
+ }
+ }
+
+ verbose "check_effective_target_vect_call_copysignf: returning $et_vect_call_copysignf_saved" 2
+ return $et_vect_call_copysignf_saved
+}
+
+# Return 1 if the target supports vector sqrtf calls.
+
+proc check_effective_target_vect_call_sqrtf { } {
+ global et_vect_call_sqrtf_saved
+
+ if [info exists et_vect_call_sqrtf_saved] {
+ verbose "check_effective_target_vect_call_sqrtf: using cached result" 2
+ } else {
+ set et_vect_call_sqrtf_saved 0
+ if { [istarget i?86-*-*]
+ || [istarget x86_64-*-*]
+ || ([istarget powerpc*-*-*] && [check_vsx_hw_available]) } {
+ set et_vect_call_sqrtf_saved 1
+ }
}
- verbose "check_effective_target_vect_strided_wide: returning $et_vect_strided_wide_saved" 2
- return $et_vect_strided_wide_saved
+ verbose "check_effective_target_vect_call_sqrtf: returning $et_vect_call_sqrtf_saved" 2
+ return $et_vect_call_sqrtf_saved
+}
+
+# Return 1 if the target supports vector lrint calls.
+
+proc check_effective_target_vect_call_lrint { } {
+ set et_vect_call_lrint 0
+ if { ([istarget i?86-*-*] || [istarget x86_64-*-*]) && [check_effective_target_ilp32] } {
+ set et_vect_call_lrint 1
+ }
+
+ verbose "check_effective_target_vect_call_lrint: returning $et_vect_call_lrint" 2
+ return $et_vect_call_lrint
}
# Return 1 if the target supports section-anchors
return $et_section_anchors_saved
}
+# Return 1 if the target supports atomic operations on "int_128" values.
+
+proc check_effective_target_sync_int_128 { } {
+ if { ([istarget x86_64-*-*] || [istarget i?86-*-*])
+ && ![is-effective-target ia32] } {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+# Return 1 if the target supports atomic operations on "int_128" values
+# and can execute them.
+
+proc check_effective_target_sync_int_128_runtime { } {
+ if { ([istarget x86_64-*-*] || [istarget i?86-*-*])
+ && ![is-effective-target ia32] } {
+ return [check_cached_effective_target sync_int_128_available {
+ check_runtime_nocache sync_int_128_available {
+ #include "cpuid.h"
+ int main ()
+ {
+ unsigned int eax, ebx, ecx, edx;
+ if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+ return !(ecx & bit_CMPXCHG16B);
+ return 1;
+ }
+ } ""
+ }]
+ } else {
+ return 0
+ }
+}
+
+# Return 1 if the target supports atomic operations on "long long".
+#
+# Note: 32bit x86 targets require -march=pentium in dg-options.
+
+proc check_effective_target_sync_long_long { } {
+ if { [istarget x86_64-*-*]
+ || [istarget i?86-*-*])
+ || [istarget arm*-*-*]
+ || [istarget alpha*-*-*] } {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+# Return 1 if the target supports atomic operations on "long long"
+# and can execute them.
+#
+# Note: 32bit x86 targets require -march=pentium in dg-options.
+
+proc check_effective_target_sync_long_long_runtime { } {
+ if { [istarget x86_64-*-*]
+ || [istarget i?86-*-*] } {
+ return [check_cached_effective_target sync_long_long_available {
+ check_runtime_nocache sync_long_long_available {
+ #include "cpuid.h"
+ int main ()
+ {
+ unsigned int eax, ebx, ecx, edx;
+ if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+ return !(edx & bit_CMPXCHG8B);
+ return 1;
+ }
+ } ""
+ }]
+ } elseif { [istarget arm*-*-linux-gnueabi] } {
+ return [check_runtime sync_longlong_runtime {
+ #include <stdlib.h>
+ int main ()
+ {
+ long long l1;
+
+ if (sizeof (long long) != 8)
+ exit (1);
+
+ /* Just check for native; checking for kernel fallback is tricky. */
+ asm volatile ("ldrexd r0,r1, [%0]" : : "r" (&l1) : "r0", "r1");
+
+ exit (0);
+ }
+ } "" ]
+ } elseif { [istarget alpha*-*-*] } {
+ return 1
+ } else {
+ return 0
+ }
+}
+
# Return 1 if the target supports atomic operations on "int" and "long".
proc check_effective_target_sync_int_long { } {
|| [istarget powerpc*-*-*]
|| [istarget sparc64-*-*]
|| [istarget sparcv9-*-*]
- || [istarget mips*-*-*] } {
+ || [check_effective_target_mips_llsc] } {
set et_sync_int_long_saved 1
}
}
|| [istarget powerpc*-*-*]
|| [istarget sparc64-*-*]
|| [istarget sparcv9-*-*]
- || [istarget mips*-*-*] } {
+ || [check_effective_target_mips_llsc] } {
set et_sync_char_short_saved 1
}
}
int fd;
const char t[] = "test writing more than ten characters";
char s[11];
- fd = fileno (f);
+ int status = 0;
+ fd = fileno (f);
write (fd, t, sizeof (t) - 1);
lseek (fd, 0, 0);
if (ftruncate (fd, 10) != 0)
- exit (1);
+ status = 1;
close (fd);
+ fclose (f);
+ if (status)
+ {
+ unlink ("tst.tmp");
+ exit (status);
+ }
f = fopen ("tst.tmp", "rb");
if (fread (s, 1, sizeof (s), f) != 10 || strncmp (s, t, 10) != 0)
- exit (1);
- exit (0);
+ status = 1;
+ fclose (f);
+ unlink ("tst.tmp");
+ exit (status);
}
}
if { [istarget *-*-solaris2*] } {
return "$flags -std=c99"
}
+ if { [istarget mips-sgi-irix6.5*] } {
+ return "$flags -std=c99"
+ }
if { [istarget powerpc-*-darwin*] } {
return "$flags -mmacosx-version-min=10.3"
}
# full IEEE compliance mode.
proc add_options_for_ieee { flags } {
- if { [istarget "alpha*-*-*"]
- || [istarget "sh*-*-*"] } {
+ if { [istarget alpha*-*-*]
+ || [istarget sh*-*-*] } {
return "$flags -mieee"
}
+ if { [istarget rx-*-*] } {
+ return "$flags -mnofpu"
+ }
return $flags
}
return $flags
}
+# Add to FLAGS the flags needed to enable 64-bit vectors.
+
+proc add_options_for_double_vectors { flags } {
+ if [is-effective-target arm_neon_ok] {
+ return "$flags -mvectorize-with-neon-double"
+ }
+
+ return $flags
+}
+
# Return 1 if the target provides a full C99 runtime.
proc check_effective_target_c99_runtime { } {
# 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
+ # Ordinarily x86 supports automatic stack alignment ...
+ if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then {
+ if { [istarget *-*-mingw*] || [istarget *-*-cygwin*] } {
+ # ... except Win64 SEH doesn't. Succeed for Win32 though.
+ return [check_effective_target_ilp32];
+ }
+ return 1;
}
+ return 0;
}
+# Return true if we are compiling for AVX target.
+
+proc check_avx_available { } {
+ if { [check_no_compiler_messages avx_available assembly {
+ #ifndef __AVX__
+ #error unsupported
+ #endif
+ } ""] } {
+ return 1;
+ }
+ return 0;
+}
+
+# Return true if 32- and 16-bytes vectors are available.
+
+proc check_effective_target_vect_sizes_32B_16B { } {
+ return [check_avx_available];
+}
+
+# Return true if 128-bits vectors are preferred even if 256-bits vectors
+# are available.
+
+proc check_prefer_avx128 { } {
+ if ![check_avx_available] {
+ return 0;
+ }
+ return [check_no_messages_and_pattern avx_explicit "xmm" assembly {
+ float a[1024],b[1024],c[1024];
+ void foo (void) { int i; for (i = 0; i < 1024; i++) a[i]=b[i]+c[i];}
+ } "-O2 -ftree-vectorize"]
+}
+
+
# Return 1 if avx instructions can be compiled.
proc check_effective_target_avx { } {
return $use_gas_saved
}
+# Return 1 if GNU ld is used.
+
+proc check_effective_target_gld { } {
+ global use_gld_saved
+ global tool
+
+ if {![info exists use_gld_saved]} {
+ # Check if the ld used by gcc is GNU ld.
+ set gcc_ld [lindex [${tool}_target_compile "-print-prog-name=ld" "" "none" ""] 0]
+ set status [remote_exec host "$gcc_ld" "--version"]
+ set ld_output [lindex $status 1]
+ if { [ string first "GNU" $ld_output ] >= 0 } {
+ set use_gld_saved 1
+ } else {
+ set use_gld_saved 0
+ }
+ }
+ return $use_gld_saved
+}
+
# Return 1 if the compiler has been configure with link-time optimization
# (LTO) support.
return [info exists ENABLE_LTO]
}
+# Return 1 if this target supports the -fsplit-stack option, 0
+# otherwise.
+
+proc check_effective_target_split_stack {} {
+ return [check_no_compiler_messages split_stack object {
+ void foo (void) { }
+ } "-fsplit-stack"]
+}
+
# Return 1 if the language for the compiler under test is C.
proc check_effective_target_c { } {
return 0
}
+# Check which language standard is active by checking for the presence of
+# one of the C++11 -std flags. This assumes that the default for the
+# compiler is C++98, and that there will never be multiple -std= arguments
+# on the command line.
+proc check_effective_target_c++11 { } {
+ if ![check_effective_target_c++] {
+ return 0
+ }
+ return [check-flags { { } { } { -std=c++0x -std=gnu++0x -std=c++11 -std=gnu++11 } }]
+}
+
+proc check_effective_target_c++98 { } {
+ if ![check_effective_target_c++] {
+ return 0
+ }
+ return [check-flags { { } { } { } { -std=c++0x -std=gnu++0x -std=c++11 -std=gnu++11 } }]
+}
+
# Return 1 if expensive testcases should be run.
proc check_effective_target_run_expensive_tests { } {
}
return 0
}
+
+# Returns 1 if "mempcpy" is available on the target system.
+
+proc check_effective_target_mempcpy {} {
+ return [check_function_available "mempcpy"]
+}
+
+# Check whether the vectorizer tests are supported by the target and
+# append additional target-dependent compile flags to DEFAULT_VECTCFLAGS.
+# Set dg-do-what-default to either compile or run, depending on target
+# capabilities. Return 1 if vectorizer tests are supported by
+# target, 0 otherwise.
+
+proc check_vect_support_and_set_flags { } {
+ global DEFAULT_VECTCFLAGS
+ global dg-do-what-default
+
+ if [istarget powerpc-*paired*] {
+ lappend DEFAULT_VECTCFLAGS "-mpaired"
+ if [check_750cl_hw_available] {
+ set dg-do-what-default run
+ } else {
+ set dg-do-what-default compile
+ }
+ } elseif [istarget powerpc*-*-*] {
+ # Skip targets not supporting -maltivec.
+ if ![is-effective-target powerpc_altivec_ok] {
+ return 0
+ }
+
+ lappend DEFAULT_VECTCFLAGS "-maltivec"
+ if [check_vsx_hw_available] {
+ lappend DEFAULT_VECTCFLAGS "-mvsx" "-mno-allow-movmisalign"
+ }
+
+ if [check_vmx_hw_available] {
+ set dg-do-what-default run
+ } else {
+ if [is-effective-target ilp32] {
+ # Specify a cpu that supports VMX for compile-only tests.
+ lappend DEFAULT_VECTCFLAGS "-mcpu=970"
+ }
+ set dg-do-what-default compile
+ }
+ } elseif { [istarget spu-*-*] } {
+ set dg-do-what-default run
+ } elseif { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
+ lappend DEFAULT_VECTCFLAGS "-msse2"
+ if { [check_effective_target_sse2_runtime] } {
+ set dg-do-what-default run
+ } else {
+ set dg-do-what-default compile
+ }
+ } elseif { [istarget mips*-*-*]
+ && ([check_effective_target_mpaired_single]
+ || [check_effective_target_mips_loongson])
+ && [check_effective_target_nomips16] } {
+ if { [check_effective_target_mpaired_single] } {
+ lappend DEFAULT_VECTCFLAGS "-mpaired-single"
+ }
+ set dg-do-what-default run
+ } elseif [istarget sparc*-*-*] {
+ lappend DEFAULT_VECTCFLAGS "-mcpu=ultrasparc" "-mvis"
+ if [check_effective_target_ultrasparc_hw] {
+ set dg-do-what-default run
+ } else {
+ set dg-do-what-default compile
+ }
+ } elseif [istarget alpha*-*-*] {
+ # Alpha's vectorization capabilities are extremely limited.
+ # It's more effort than its worth disabling all of the tests
+ # that it cannot pass. But if you actually want to see what
+ # does work, command out the return.
+ return 0
+
+ lappend DEFAULT_VECTCFLAGS "-mmax"
+ if [check_alpha_max_hw_available] {
+ set dg-do-what-default run
+ } else {
+ set dg-do-what-default compile
+ }
+ } elseif [istarget ia64-*-*] {
+ set dg-do-what-default run
+ } elseif [is-effective-target arm_neon_ok] {
+ eval lappend DEFAULT_VECTCFLAGS [add_options_for_arm_neon ""]
+ # NEON does not support denormals, so is not used for vectorization by
+ # default to avoid loss of precision. We must pass -ffast-math to test
+ # vectorization of float operations.
+ lappend DEFAULT_VECTCFLAGS "-ffast-math"
+ if [is-effective-target arm_neon_hw] {
+ set dg-do-what-default run
+ } else {
+ set dg-do-what-default compile
+ }
+ } else {
+ return 0
+ }
+
+ return 1
+}
+
+proc check_effective_target_non_strict_align {} {
+ return [check_no_compiler_messages non_strict_align assembly {
+ char *y;
+ typedef char __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) c;
+ c *z;
+ void foo(void) { z = (c *) y; }
+ } "-Wcast-align"]
+}
+
+# Return 1 if the target has <ucontext.h>.
+
+proc check_effective_target_ucontext_h { } {
+ return [check_no_compiler_messages ucontext_h assembly {
+ #include <ucontext.h>
+ }]
+}