OSDN Git Service

Disable -mpreferred-stack-boundary options for Windows.
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / lib / target-supports.exp
index 1a36127..87b234d 100644 (file)
@@ -368,6 +368,47 @@ proc check_alias_available { } {
     return $alias_available_saved
 }
 
+###############################
+# proc check_ifunc_available { }
+###############################
+
+# Determine if the target toolchain supports the ifunc attribute.
+
+# Returns 1 if the target supports ifunc.  Returns 0 if the target
+# does not support ifunc.
+
+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"]
+       puts $f "#endif"
+       puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif"
+       puts $f "void g() {}"
+       puts $f "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 {
+           set ifunc_available_saved 1
+       } else {
+           set ifunc_available_saved 0
+       }
+
+       verbose "check_ifunc_available  returning $ifunc_available_saved" 2
+    }
+
+    return $ifunc_available_saved
+}
+
 # Returns true if --gc-sections is supported on the target.
 
 proc check_gc_sections_available { } {
@@ -569,6 +610,24 @@ proc check_effective_target_pcc_bitfield_type_matters { } {
     }]
 }
 
+# Add to FLAGS all the target-specific flags needed to use thread-local storage.
+
+proc add_options_for_tls { flags } {
+    # 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
+    # check_effective_target_tls_native to avoid recursion.
+    if { [istarget *-*-solaris2.\[89\]*] &&
+        [check_no_messages_and_pattern tls_native "!emutls" assembly {
+            __thread int i;
+            int f (void) { return i; }
+            void g (int j) { i = j; }
+        }] } {
+       return "$flags -pthread"
+    }
+    return $flags
+}
+
 # Return 1 if thread local storage (TLS) is supported, 0 otherwise.
 
 proc check_effective_target_tls {} {
@@ -596,6 +655,23 @@ proc check_effective_target_tls_native {} {
     }]
 }
 
+# Return 1 if *emulated* thread local storage (TLS) is supported, 0 otherwise.
+
+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] } {
+       return 1
+    }
+    
+    return [check_no_messages_and_pattern tls_emulated "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.
 
 proc check_effective_target_tls_runtime {} {
@@ -605,6 +681,20 @@ proc check_effective_target_tls_runtime {} {
     }]
 }
 
+# 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] } {
+       return 0
+    }
+    
+    return [check_no_compiler_messages functionsections assembly {
+       void foo (void) { }
+    } "-ffunction-sections"]
+}
+
 # Return 1 if compilation with -fgraphite is error-free for trivial 
 # code, 0 otherwise.
 
@@ -886,6 +976,12 @@ proc check_effective_target_static_libgfortran { } {
     } "-static"]
 }
 
+proc check_linker_plugin_available { } {
+  return [check_no_compiler_messages_nocache linker_plugin executable {
+     int main() { return 0; }
+  } "-flto -fuse-linker-plugin"]
+}
+
 # Return 1 if the target supports executing 750CL paired-single instructions, 0
 # otherwise.  Cache the result.
 
@@ -910,6 +1006,53 @@ proc check_750cl_hw_available { } {
     }]
 }
 
+# Return 1 if the target OS supports running SSE executables, 0
+# otherwise.  Cache the result.
+
+proc check_sse_os_support_available { } {
+    return [check_cached_effective_target sse_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
+       } elseif { [istarget i?86-*-solaris2*] } {
+           # The Solaris 2 kernel doesn't save and restore SSE registers
+           # before Solaris 9 4/04.  Before that, executables die with SIGILL.
+           check_runtime_nocache sse_os_support_available {
+               int main ()
+               {
+                   __asm__ volatile ("movss %xmm2,%xmm1");
+                   return 0;
+               }
+           } "-msse"
+       } else {
+           expr 1
+       }
+    }]
+}
+
+# Return 1 if the target supports executing SSE instructions, 0
+# otherwise.  Cache the result.
+
+proc check_sse_hw_available { } {
+    return [check_cached_effective_target sse_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 sse_hw_available {
+               #include "cpuid.h"
+               int main ()
+               {
+                 unsigned int eax, ebx, ecx, edx;
+                 if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+                   return !(edx & bit_SSE);
+                 return 1;
+               }
+           } ""
+       }
+    }]
+}
+
 # Return 1 if the target supports executing SSE2 instructions, 0
 # otherwise.  Cache the result.
 
@@ -923,7 +1066,7 @@ proc check_sse2_hw_available { } {
                #include "cpuid.h"
                int main ()
                {
-                 unsigned int eax, ebx, ecx, edx = 0;
+                 unsigned int eax, ebx, ecx, edx;
                  if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
                    return !(edx & bit_SSE2);
                  return 1;
@@ -933,6 +1076,62 @@ proc check_sse2_hw_available { } {
     }]
 }
 
+# Return 1 if the target supports executing AVX instructions, 0
+# otherwise.  Cache the result.
+
+proc check_avx_hw_available { } {
+    return [check_cached_effective_target avx_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 avx_hw_available {
+               #include "cpuid.h"
+               int main ()
+               {
+                 unsigned int eax, ebx, ecx, edx;
+                 if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+                   return ((ecx & (bit_AVX | bit_OSXSAVE))
+                           != (bit_AVX | bit_OSXSAVE));
+                 return 1;
+               }
+           } ""
+       }
+    }]
+}
+
+# Return 1 if the target supports running SSE executables, 0 otherwise.
+
+proc check_effective_target_sse_runtime { } {
+    if { [check_effective_target_sse]
+        && [check_sse_hw_available]
+        && [check_sse_os_support_available] } {
+       return 1
+    }
+    return 0
+}
+
+# Return 1 if the target supports running SSE2 executables, 0 otherwise.
+
+proc check_effective_target_sse2_runtime { } {
+    if { [check_effective_target_sse2]
+        && [check_sse2_hw_available]
+        && [check_sse_os_support_available] } {
+       return 1
+    }
+    return 0
+}
+
+# Return 1 if the target supports running AVX executables, 0 otherwise.
+
+proc check_effective_target_avx_runtime { } {
+    if { [check_effective_target_avx]
+        && [check_avx_hw_available] } {
+       return 1
+    }
+    return 0
+}
+
 # Return 1 if the target supports executing VSX instructions, 0
 # otherwise.  Cache the result.
 
@@ -992,6 +1191,30 @@ proc check_vmx_hw_available { } {
     }]
 }
 
+proc check_ppc_recip_hw_available { } {
+    return [check_cached_effective_target ppc_recip_hw_available {
+       # Some simulators may not support FRE/FRES/FRSQRTE/FRSQRTES
+       # For now, disable on Darwin
+       if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
+           expr 0
+       } else {
+           set options "-mpowerpc-gfxopt -mpowerpc-gpopt -mpopcntb"
+           check_runtime_nocache ppc_recip_hw_available {
+               volatile double d_recip, d_rsqrt, d_four = 4.0;
+               volatile float f_recip, f_rsqrt, f_four = 4.0f;
+               int main()
+               {
+                 asm volatile ("fres %0,%1" : "=f" (f_recip) : "f" (f_four));
+                 asm volatile ("fre %0,%1" : "=d" (d_recip) : "d" (d_four));
+                 asm volatile ("frsqrtes %0,%1" : "=f" (f_rsqrt) : "f" (f_four));
+                 asm volatile ("frsqrte %0,%1" : "=f" (d_rsqrt) : "d" (d_four));
+                 return 0;
+               }
+           } $options
+       }
+    }]
+}
+
 # Return 1 if the target supports executing AltiVec and Cell PPU
 # instructions, 0 otherwise.  Cache the result.
 
@@ -1469,7 +1692,9 @@ proc check_effective_target_vect_int { } {
              || [istarget sparc*-*-*]
              || [istarget alpha*-*-*]
              || [istarget ia64-*-*] 
-             || [check_effective_target_arm32] } {
+             || [check_effective_target_arm32]
+             || ([istarget mips*-*-*]
+                 && [check_effective_target_mips_loongson]) } {
           set et_vect_int_saved 1
        }
     }
@@ -1588,6 +1813,18 @@ proc check_effective_target_arm32 { } {
     }]
 }
 
+# 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.
@@ -2005,7 +2242,9 @@ proc check_effective_target_vect_shift { } {
             || [istarget ia64-*-*]
             || [istarget i?86-*-*]
             || [istarget x86_64-*-*]
-            || [check_effective_target_arm32] } {
+            || [check_effective_target_arm32]
+            || ([istarget mips*-*-*]
+                && [check_effective_target_mips_loongson]) } {
           set et_vect_shift_saved 1
        }
     }
@@ -2073,8 +2312,17 @@ proc check_effective_target_vect_double { } {
     } else {
        set et_vect_double_saved 0
        if { [istarget i?86-*-*]
-             || [istarget x86_64-*-*] 
-             || [istarget spu-*-*] } {
+             || [istarget x86_64-*-*] } {
+          if { [check_no_compiler_messages vect_double assembly {
+                #ifdef __tune_atom__
+                # error No double vectorizer support.
+                #endif
+               }] } {
+               set et_vect_double_saved 1
+           } else {
+               set et_vect_double_saved 0
+           }
+       } elseif { [istarget spu-*-*] } {
           set et_vect_double_saved 1
        }
     }
@@ -2119,7 +2367,9 @@ proc check_effective_target_vect_no_int_max { } {
        set et_vect_no_int_max_saved 0
        if { [istarget sparc*-*-*]
             || [istarget spu-*-*]
-            || [istarget alpha*-*-*] } {
+            || [istarget alpha*-*-*]
+            || ([istarget mips*-*-*]
+                && [check_effective_target_mips_loongson]) } {
            set et_vect_no_int_max_saved 1
        }
     }
@@ -2178,7 +2428,9 @@ proc check_effective_target_vect_perm { } {
     } else {
         set et_vect_perm_saved 0
         if { [istarget powerpc*-*-*]
-             || [istarget spu-*-*] } {
+             || [istarget spu-*-*]
+            || [istarget i?86-*-*]
+            || [istarget x86_64-*-*] } {
             set et_vect_perm_saved 1
         }
     }
@@ -2186,6 +2438,48 @@ proc check_effective_target_vect_perm { } {
     return $et_vect_perm_saved
 }
 
+# Return 1 if the target plus current options supports vector permutation
+# on byte-sized elements, 0 otherwise.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_vect_perm_byte { } {
+    global et_vect_perm_byte
+
+    if [info exists et_vect_perm_byte_saved] {
+        verbose "check_effective_target_vect_perm_byte: using cached result" 2
+    } else {
+        set et_vect_perm_byte_saved 0
+        if { [istarget powerpc*-*-*]
+             || [istarget spu-*-*] } {
+            set et_vect_perm_byte_saved 1
+        }
+    }
+    verbose "check_effective_target_vect_perm_byte: returning $et_vect_perm_byte_saved" 2
+    return $et_vect_perm_byte_saved
+}
+
+# Return 1 if the target plus current options supports vector permutation
+# on short-sized elements, 0 otherwise.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_vect_perm_short { } {
+    global et_vect_perm_short
+
+    if [info exists et_vect_perm_short_saved] {
+        verbose "check_effective_target_vect_perm_short: using cached result" 2
+    } else {
+        set et_vect_perm_short_saved 0
+        if { [istarget powerpc*-*-*]
+             || [istarget spu-*-*] } {
+            set et_vect_perm_short_saved 1
+        }
+    }
+    verbose "check_effective_target_vect_perm_short: returning $et_vect_perm_short_saved" 2
+    return $et_vect_perm_short_saved
+}
+
 # Return 1 if the target plus current options supports a vector
 # widening summation of *short* args into *int* result, 0 otherwise.
 #
@@ -2429,7 +2723,8 @@ proc check_effective_target_vect_pack_trunc { } {
         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
              || [istarget i?86-*-*]
              || [istarget x86_64-*-*]
-             || [istarget spu-*-*] } {
+             || [istarget spu-*-*]
+             || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
             set et_vect_pack_trunc_saved 1
         }
     }
@@ -2452,7 +2747,8 @@ proc check_effective_target_vect_unpack { } {
         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*])
              || [istarget i?86-*-*]
              || [istarget x86_64-*-*] 
-             || [istarget spu-*-*] } {
+             || [istarget spu-*-*]
+             || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
             set et_vect_unpack_saved 1
         }
     }
@@ -2492,7 +2788,9 @@ proc check_effective_target_vect_no_align { } {
        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
        }
     }
@@ -2627,6 +2925,25 @@ proc check_effective_target_vector_alignment_reachable_for_64bit { } {
     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_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 { } {
@@ -2682,8 +2999,10 @@ proc check_effective_target_vect_short_mult { } {
             || [istarget spu-*-*]
             || [istarget i?86-*-*]
             || [istarget x86_64-*-*]
-             || [istarget powerpc*-*-*]
-             || [check_effective_target_arm32] } {
+            || [istarget powerpc*-*-*]
+            || [check_effective_target_arm32]
+            || ([istarget mips*-*-*]
+                && [check_effective_target_mips_loongson]) } {
           set et_vect_short_mult_saved 1
        }
     }
@@ -2849,7 +3168,9 @@ proc check_effective_target_sync_int_long { } {
             || [istarget i?86-*-*]
             || [istarget x86_64-*-*]
             || [istarget alpha*-*-*] 
+            || [istarget arm*-*-linux-gnueabi] 
             || [istarget bfin*-*linux*]
+            || [istarget hppa*-*linux*]
             || [istarget s390*-*-*] 
             || [istarget powerpc*-*-*]
             || [istarget sparc64-*-*]
@@ -2878,6 +3199,8 @@ proc check_effective_target_sync_char_short { } {
             || [istarget i?86-*-*]
             || [istarget x86_64-*-*]
             || [istarget alpha*-*-*] 
+            || [istarget arm*-*-linux-gnueabi] 
+            || [istarget hppa*-*linux*]
             || [istarget s390*-*-*] 
             || [istarget powerpc*-*-*]
             || [istarget sparc64-*-*]
@@ -2972,6 +3295,8 @@ proc is-effective-target { arg } {
     } else {
        switch $arg {
          "vmx_hw"         { set selected [check_vmx_hw_available] }
+         "vsx_hw"         { set selected [check_vsx_hw_available] }
+         "ppc_recip_hw"   { set selected [check_ppc_recip_hw_available] }
          "named_sections" { set selected [check_named_sections_available] }
          "gc_sections"    { set selected [check_gc_sections_available] }
          "cxa_atexit"     { set selected [check_cxa_atexit_available] }
@@ -2991,6 +3316,8 @@ proc is-effective-target-keyword { arg } {
        # These have different names for their check_* procs.
        switch $arg {
          "vmx_hw"         { return 1 }
+         "vsx_hw"         { return 1 }
+         "ppc_recip_hw"   { return 1 }
          "named_sections" { return 1 }
          "gc_sections"    { return 1 }
          "cxa_atexit"     { return 1 }
@@ -3184,6 +3511,16 @@ proc add_options_for_bind_pic_locally { flags } {
     return $flags
 }
 
+# Add to FLAGS the flags needed to enable 128-bit vectors.
+
+proc add_options_for_quad_vectors { flags } {
+    if [is-effective-target arm_neon_ok] {
+       return "$flags -mvectorize-with-neon-quad"
+    }
+
+    return $flags
+}
+
 # Return 1 if the target provides a full C99 runtime.
 
 proc check_effective_target_c99_runtime { } {
@@ -3214,12 +3551,15 @@ proc check_effective_target_4byte_wchar_t { } {
 # 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 1 if avx instructions can be compiled.
@@ -3233,6 +3573,17 @@ proc check_effective_target_avx { } {
     } "-O2 -mavx" ]
 }
 
+# Return 1 if sse instructions can be compiled.
+proc check_effective_target_sse { } {
+    return [check_no_compiler_messages sse object {
+       int main ()
+       {
+           __builtin_ia32_stmxcsr ();
+           return 0;
+       }
+    } "-O2 -msse" ]
+}
+
 # Return 1 if sse2 instructions can be compiled.
 proc check_effective_target_sse2 { } {
     return [check_no_compiler_messages sse2 object {
@@ -3245,6 +3596,19 @@ proc check_effective_target_sse2 { } {
     } "-O2 -msse2" ]
 }
 
+# Return 1 if F16C instructions can be compiled.
+
+proc check_effective_target_f16c { } {
+    return [check_no_compiler_messages f16c object {
+       #include "immintrin.h"
+       float
+       foo (unsigned short val)
+       {
+         return _cvtsh_ss (val);
+       }
+    } "-O2 -mf16c" ]
+}
+
 # Return 1 if C wchar_t type is compatible with char16_t.
 
 proc check_effective_target_wchar_t_char16_t_compatible { } {
@@ -3305,6 +3669,28 @@ proc check_effective_target_correct_iso_cpp_string_wchar_protos { } {
     }]
 }
 
+# Return 1 if GNU as is used.
+
+proc check_effective_target_gas { } {
+    global use_gas_saved
+    global tool
+
+    if {![info exists use_gas_saved]} {
+       # Check if the as used by gcc is GNU as.
+       set gcc_as [lindex [${tool}_target_compile "-print-prog-name=as" "" "none" ""] 0]
+       # Provide /dev/null as input, otherwise gas times out reading from
+       # stdin.
+       set status [remote_exec host "$gcc_as" "-v /dev/null"]
+       set as_output [lindex $status 1]
+       if { [ string first "GNU" $as_output ] >= 0 } {
+           set use_gas_saved 1
+       } else {
+           set use_gas_saved 0
+       }
+    }
+    return $use_gas_saved
+}
+
 # Return 1 if the compiler has been configure with link-time optimization
 # (LTO) support.
 
@@ -3313,6 +3699,15 @@ proc check_effective_target_lto { } {
     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 { } {
@@ -3332,3 +3727,12 @@ proc check_effective_target_c++ { } {
     }
  return 0
 }
+
+# Return 1 if expensive testcases should be run.
+
+proc check_effective_target_run_expensive_tests { } {
+    if { [getenv GCC_TEST_RUN_EXPENSIVE] != "" } {
+        return 1
+    }
+    return 0
+}