OSDN Git Service

Disable -mpreferred-stack-boundary options for Windows.
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / lib / target-supports.exp
index d525a5b..87b234d 100644 (file)
@@ -1,4 +1,4 @@
-#   Copyright (C) 1999, 2001, 2003, 2004, 2005, 2006, 2007
+#   Copyright (C) 1999, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
 #    Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # 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".
+# Assume by default that CONTENTS is C code.  
+# Otherwise, code should contain:
+# "// C++" for c++,
+# "! Fortran" for Fortran code,
+# "/* ObjC", for ObjC
+# and "// ObjC++" for ObjC++
+# 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} {
     global tool
+    verbose "check_compile tool: $tool for $basename" 
 
     if { [llength $args] > 0 } {
        set options [list "additional_flags=[lindex $args 0]"]
@@ -42,8 +49,17 @@ proc check_compile {basename type contents args} {
     switch -glob -- $contents {
        "*! Fortran*" { set src ${basename}[pid].f90 }
        "*// C++*" { set src ${basename}[pid].cc }
-       default { set src ${basename}[pid].c }
+       "*// ObjC++*" { set src ${basename}[pid].mm }
+       "*/* ObjC*" { set src ${basename}[pid].m }
+       default {
+           switch -- $tool {
+               "objc" { set src ${basename}[pid].m }
+               "obj-c++" { set src ${basename}[pid].mm }
+               default { set src ${basename}[pid].c }
+           }
+       }
     }
+
     set compile_type $type
     switch -glob $type {
        assembly { set output ${basename}[pid].s }
@@ -251,6 +267,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 }
 ###############################
 
@@ -338,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 { } {
@@ -371,7 +442,7 @@ proc check_gc_sections_available { } {
 
        # Check if the ld used by gcc supports --gc-sections.
        set gcc_spec [${tool}_target_compile "-dumpspecs" "" "none" ""]
-       regsub ".*\n\*linker:\[ \t\]*\n(\[^ \t\n\]*).*" "$gcc_spec" {\1} linker
+       regsub ".*\n\\*linker:\[ \t\]*\n(\[^ \t\n\]*).*" "$gcc_spec" {\1} linker
        set gcc_ld [lindex [${tool}_target_compile "-print-prog-name=$linker" "" "none" ""] 0]
        set ld_output [remote_exec host "$gcc_ld" "--help"]
        if { [ string first "--gc-sections" $ld_output ] >= 0 } {
@@ -452,8 +523,8 @@ proc check_profiling_available { test_what } {
        return 0
     }
 
-    # At present, there is no profiling support on NetWare.
-    if { [istarget *-*-netware*] } {
+    # cygwin does not support -p.
+    if { [istarget *-*-cygwin*] && [lindex $test_what 1] == "-p" } {
        return 0
     }
 
@@ -470,21 +541,29 @@ 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 powerpc-*-elf]
             || [istarget cris-*-*]
             || [istarget crisv32-*-*]
             || [istarget fido-*-elf]
             || [istarget h8300-*-*]
-            || [istarget m32c-*-elf]
+             || [istarget lm32-*-*]
+             || [istarget m32c-*-elf]
             || [istarget m68k-*-elf]
             || [istarget m68k-*-uclinux*]
+            || [istarget mep-*-elf]
             || [istarget mips*-*-elf*]
+            || [istarget moxie-*-elf*]
+            || [istarget rx-*-*]       
             || [istarget xstormy16-*]
             || [istarget xtensa*-*-elf]
+            || [istarget *-*-rtems*]
             || [istarget *-*-vxworks*] } {
            set profiling_available_saved 0
        } else {
@@ -495,6 +574,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
@@ -520,9 +610,25 @@ 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.
-#
-# This won't change for different subtargets so cache the result.
 
 proc check_effective_target_tls {} {
     return [check_no_compiler_messages tls assembly {
@@ -533,8 +639,6 @@ proc check_effective_target_tls {} {
 }
 
 # Return 1 if *native* thread local storage (TLS) is supported, 0 otherwise.
-#
-# This won't change for different subtargets so cache the result.
 
 proc check_effective_target_tls_native {} {
     # VxWorks uses emulated TLS machinery, but with non-standard helper
@@ -551,9 +655,24 @@ 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.
-#
-# This won't change for different subtargets so cache the result.
 
 proc check_effective_target_tls_runtime {} {
     return [check_runtime tls_runtime {
@@ -562,6 +681,29 @@ 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.
+
+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
 # code, 0 otherwise.
 
@@ -580,6 +722,25 @@ proc check_effective_target_pthread {} {
     } "-pthread"]
 }
 
+# Return 1 if compilation with -mpe-aligned-commons is error-free
+# for trivial code, 0 otherwise.
+
+proc check_effective_target_pe_aligned_commons {} {
+    if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
+       return [check_no_compiler_messages pe_aligned_commons object {
+           int foo;
+       } "-mpe-aligned-commons"]
+    }
+    return 0
+}
+
+# Return 1 if the target supports -static
+proc check_effective_target_static {} {
+    return [check_no_compiler_messages static executable {
+       int main (void) { return 0; }
+    } "-static"]
+}
+
 # Return 1 if the target supports -fstack-protector
 proc check_effective_target_fstack_protector {} {
     return [check_runtime fstack_protector {
@@ -634,6 +795,18 @@ proc check_effective_target_hard_float { } {
        }]
     }
 
+    # This proc is actually checking the availabilty of FPU
+    # support for doubles, so on the RX we must fail if the
+    # 64-bit double multilib has been selected.
+    if { [istarget rx-*-*] } {
+       return 0
+       # return [check_no_compiler_messages hard_float assembly {
+               #if defined __RX_64_BIT_DOUBLES__
+               #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; }
@@ -689,6 +862,15 @@ proc check_effective_target_mips16_attribute { } {
     } [add_options_for_mips16_attribute ""]]
 }
 
+# Return 1 if the target supports long double larger than double when
+# using the new ABI, 0 otherwise.
+
+proc check_effective_target_mips_newabi_large_long_double { } {
+    return [check_no_compiler_messages mips_newabi_large_long_double object {
+       int dummy[sizeof(long double) > sizeof(double) ? 1 : -1];
+    } "-mabi=64"]
+}
+
 # Return 1 if the current multilib does not generate PIC by default.
 
 proc check_effective_target_nonpic { } {
@@ -794,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.
 
@@ -818,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.
 
@@ -831,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;
@@ -841,6 +1076,88 @@ 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.
+
+proc check_vsx_hw_available { } {
+    return [check_cached_effective_target vsx_hw_available {
+       # Some simulators are known to not support VSX instructions.
+       # For now, disable on Darwin
+       if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
+           expr 0
+       } else {
+           set options "-mvsx"
+           check_runtime_nocache vsx_hw_available {
+               int main()
+               {
+               #ifdef __MACH__
+                 asm volatile ("xxlor vs0,vs0,vs0");
+               #else
+                 asm volatile ("xxlor 0,0,0");
+               #endif
+                 return 0;
+               }
+           } $options
+       }
+    }]
+}
+
 # Return 1 if the target supports executing AltiVec instructions, 0
 # otherwise.  Cache the result.
 
@@ -851,12 +1168,13 @@ proc check_vmx_hw_available { } {
            expr 0
        } else {
            # Most targets don't require special flags for this test case, but
-           # Darwin does.
+           # Darwin does.  Just to be sure, make sure VSX is not enabled for
+           # the altivec tests.
            if { [istarget *-*-darwin*]
                 || [istarget *-*-aix*] } {
-               set options "-maltivec"
+               set options "-maltivec -mno-vsx"
            } else {
-               set options ""
+               set options "-mno-vsx"
            }
            check_runtime_nocache vmx_hw_available {
                int main()
@@ -873,6 +1191,123 @@ 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.
+
+proc check_effective_target_cell_hw { } {
+    return [check_cached_effective_target cell_hw_available {
+       # Some simulators are known to not support VMX and PPU instructions.
+       if { [istarget powerpc-*-eabi*] } {
+           expr 0
+       } else {
+           # Most targets don't require special flags for this test
+           # case, but Darwin and AIX do.
+           if { [istarget *-*-darwin*]
+                || [istarget *-*-aix*] } {
+               set options "-maltivec -mcpu=cell"
+           } else {
+               set options "-mcpu=cell"
+           }
+           check_runtime_nocache cell_hw_available {
+               int main()
+               {
+               #ifdef __MACH__
+                 asm volatile ("vor v0,v0,v0");
+                  asm volatile ("lvlx v0,r0,r0");
+               #else
+                 asm volatile ("vor 0,0,0");
+                  asm volatile ("lvlx 0,0,0");
+               #endif
+                 return 0;
+               }
+           } $options
+       }
+    }]
+}
+
+# Return 1 if the target supports executing 64-bit instructions, 0
+# otherwise.  Cache the result.
+
+proc check_effective_target_powerpc64 { } {
+    global powerpc64_available_saved
+    global tool
+
+    if [info exists powerpc64_available_saved] {
+       verbose "check_effective_target_powerpc64 returning saved $powerpc64_available_saved" 2
+    } else {
+       set powerpc64_available_saved 0
+
+       # Some simulators are known to not support powerpc64 instructions.
+       if { [istarget powerpc-*-eabi*] || [istarget powerpc-ibm-aix*] } {
+           verbose "check_effective_target_powerpc64 returning 0" 2
+           return $powerpc64_available_saved
+       }
+
+       # Set up, compile, and execute a test program containing a 64-bit
+       # instruction.  Include the current process ID in the file
+       # names to prevent conflicts with invocations for multiple
+       # testsuites.
+       set src ppc[pid].c
+       set exe ppc[pid].x
+
+       set f [open $src "w"]
+       puts $f "int main() {"
+       puts $f "#ifdef __MACH__"
+       puts $f "  asm volatile (\"extsw r0,r0\");"
+       puts $f "#else"
+       puts $f "  asm volatile (\"extsw 0,0\");"
+       puts $f "#endif"
+       puts $f "  return 0; }"
+       close $f
+
+       set opts "additional_flags=-mcpu=G5"
+
+       verbose "check_effective_target_powerpc64 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_effective_target_powerpc64 testfile status is <$status>" 2
+
+           if { $status == "pass" } then {
+               set powerpc64_available_saved 1
+           }
+       } else {
+           verbose "check_effective_target_powerpc64 testfile compilation failed" 2
+       }
+    }
+
+    return $powerpc64_available_saved
+}
+
 # GCC 3.4.0 for powerpc64-*-linux* included an ABI fix for passing
 # complex float arguments.  This affects gfortran tests that call cabsf
 # in libm built by an earlier compiler.  Return 1 if libm uses the same
@@ -953,6 +1388,9 @@ proc check_cxa_atexit_available { } {
        if { [istarget "hppa*-*-hpux10*"] } {
            # HP-UX 10 doesn't have __cxa_atexit but subsequent test passes.
            expr 0
+       } elseif { [istarget "*-*-vxworks"] } {
+           # vxworks doesn't have __cxa_atexit but subsequent test passes.
+           expr 0
        } else {
            check_runtime_nocache cxa_atexit_available {
                // C++
@@ -989,6 +1427,25 @@ proc check_cxa_atexit_available { } {
     }]
 }
 
+proc check_effective_target_objc2 { } {
+    return [check_no_compiler_messages objc2 object {
+       #ifdef __OBJC2__
+       int dummy[1];
+       #else
+       #error
+       #endif 
+    }]
+}
+
+proc check_effective_target_next_runtime { } {
+    return [check_no_compiler_messages objc2 object {
+       #ifdef __NEXT_RUNTIME__
+       int dummy[1];
+       #else
+       #error
+       #endif 
+    }]
+}
 
 # Return 1 if we're generating 32-bit code using default options, 0
 # otherwise.
@@ -1048,6 +1505,18 @@ proc check_effective_target_lp64 { } {
     }]
 }
 
+# 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 long) == 8
+                 && sizeof (long) == 4 ? 1 : -1];
+    }]
+}
+
 # Return 1 if the target supports long double larger than double,
 # 0 otherwise.
 
@@ -1057,6 +1526,33 @@ proc check_effective_target_large_long_double { } {
     }]
 }
 
+# Return 1 if the target supports double larger than float,
+# 0 otherwise.
+
+proc check_effective_target_large_double { } {
+    return [check_no_compiler_messages large_double object {
+       int dummy[sizeof(double) > sizeof(float) ? 1 : -1];
+    }]
+}
+
+# Return 1 if the target supports double of 64 bits,
+# 0 otherwise.
+
+proc check_effective_target_double64 { } {
+    return [check_no_compiler_messages double64 object {
+       int dummy[sizeof(double) == 8 ? 1 : -1];
+    }]
+}
+
+# Return 1 if the target supports double of at least 64 bits,
+# 0 otherwise.
+
+proc check_effective_target_double64plus { } {
+    return [check_no_compiler_messages double64plus object {
+       int dummy[sizeof(double) >= 8 ? 1 : -1];
+    }]
+}
+
 # Return 1 if the target supports compiling fixed-point,
 # 0 otherwise.
 
@@ -1072,7 +1568,7 @@ proc check_effective_target_fixed_point { } {
 proc check_effective_target_dfp_nocache { } {
     verbose "check_effective_target_dfp_nocache: compiling source" 2
     set ret [check_no_compiler_messages_nocache dfp object {
-        _Decimal32 x; _Decimal64 y; _Decimal128 z;
+       float x __attribute__((mode(DD)));
     }]
     verbose "check_effective_target_dfp_nocache: returning $ret" 2
     return $ret
@@ -1080,7 +1576,8 @@ proc check_effective_target_dfp_nocache { } {
 
 proc check_effective_target_dfprt_nocache { } {
     return [check_runtime_nocache dfprt {
-       _Decimal32 x = 1.2df; _Decimal64 y = 2.3dd; _Decimal128 z;
+       typedef float d64 __attribute__((mode(DD)));
+       d64 x = 1.2df, y = 2.3dd, z;
        int main () { z = x + y; return 0; }
     }]
 }
@@ -1097,7 +1594,7 @@ proc check_effective_target_dfp { } {
 }
 
 # Return 1 if the target supports linking and executing Decimal Floating
-# Point, 0 otherwise.
+# Point, 0 otherwise.
 #
 # This won't change for different subtargets so cache the result.
 
@@ -1107,6 +1604,32 @@ proc check_effective_target_dfprt { } {
     }]
 }
 
+# Return 1 if the target supports compiling and assembling UCN, 0 otherwise.
+
+proc check_effective_target_ucn_nocache { } {
+    # -std=c99 is only valid for C
+    if [check_effective_target_c] {
+       set ucnopts "-std=c99"
+    }
+    append ucnopts " -fextended-identifiers"
+    verbose "check_effective_target_ucn_nocache: compiling source" 2
+    set ret [check_no_compiler_messages_nocache ucn object {
+       int \u00C0;
+    } $ucnopts]
+    verbose "check_effective_target_ucn_nocache: returning $ret" 2
+    return $ret
+}
+
+# Return 1 if the target supports compiling and assembling UCN, 0 otherwise.
+#
+# This won't change for different subtargets, so cache the result.
+
+proc check_effective_target_ucn { } {
+    return [check_cached_effective_target ucn {
+       check_effective_target_ucn_nocache
+    }]
+}
+
 # Return 1 if the target needs a command line argument to enable a SIMD
 # instruction set.
 
@@ -1133,7 +1656,8 @@ proc check_effective_target_vect_cmdline_needed { } {
        verbose "check_effective_target_vect_cmdline_needed: using cached result" 2
     } else {
        set et_vect_cmdline_needed_saved 1
-       if { [istarget ia64-*-*]
+       if { [istarget alpha*-*-*]
+            || [istarget ia64-*-*]
             || (([istarget x86_64-*-*] || [istarget i?86-*-*])
                 && [check_effective_target_lp64])
             || ([istarget powerpc*-*-*]
@@ -1168,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
        }
     }
@@ -1177,7 +1703,7 @@ proc check_effective_target_vect_int { } {
     return $et_vect_int_saved
 }
 
-# Return 1 if the target supports int->float conversion 
+# Return 1 if the target supports signed int->float conversion 
 #
 
 proc check_effective_target_vect_intfloat_cvt { } {
@@ -1199,8 +1725,44 @@ proc check_effective_target_vect_intfloat_cvt { } {
     return $et_vect_intfloat_cvt_saved
 }
 
+#Return 1 if we're supporting __int128 for target, 0 otherwise.
 
-# Return 1 if the target supports float->int conversion
+proc check_effective_target_int128 { } {
+    return [check_no_compiler_messages int128 object {
+       int dummy[
+       #ifndef __SIZEOF_INT128__
+       -1
+       #else
+       1
+       #endif
+       ];
+    }]
+}
+
+# Return 1 if the target supports unsigned int->float conversion 
+#
+
+proc check_effective_target_vect_uintfloat_cvt { } {
+    global et_vect_uintfloat_cvt_saved
+
+    if [info exists et_vect_uintfloat_cvt_saved] {
+        verbose "check_effective_target_vect_uintfloat_cvt: using cached result" 2
+    } else {
+        set et_vect_uintfloat_cvt_saved 0
+        if { [istarget i?86-*-*]
+             || ([istarget powerpc*-*-*]
+                 && ![istarget powerpc-*-linux*paired*])
+             || [istarget x86_64-*-*] } {
+           set et_vect_uintfloat_cvt_saved 1
+        }
+    }
+
+    verbose "check_effective_target_vect_uintfloat_cvt: returning $et_vect_uintfloat_cvt_saved" 2
+    return $et_vect_uintfloat_cvt_saved
+}
+
+
+# Return 1 if the target supports signed float->int conversion
 #
 
 proc check_effective_target_vect_floatint_cvt { } {
@@ -1222,6 +1784,26 @@ proc check_effective_target_vect_floatint_cvt { } {
     return $et_vect_floatint_cvt_saved
 }
 
+# Return 1 if the target supports unsigned float->int conversion
+#
+
+proc check_effective_target_vect_floatuint_cvt { } {
+    global et_vect_floatuint_cvt_saved
+
+    if [info exists et_vect_floatuint_cvt_saved] {
+        verbose "check_effective_target_vect_floatuint_cvt: using cached result" 2
+    } else {
+        set et_vect_floatuint_cvt_saved 0
+        if { ([istarget powerpc*-*-*]
+             && ![istarget powerpc-*-linux*paired*]) } {
+           set et_vect_floatuint_cvt_saved 1
+        }
+    }
+
+    verbose "check_effective_target_vect_floatuint_cvt: returning $et_vect_floatuint_cvt_saved" 2
+    return $et_vect_floatuint_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 {
@@ -1231,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.
@@ -1245,18 +1839,101 @@ proc check_effective_target_arm_vfp_ok { } {
     }
 }
 
-# Return 1 if this is an ARM target supporting -mfpu=neon
-# -mfloat-abi=softfp.  Some multilibs may be incompatible with these
+# Return 1 if this is an ARM target supporting -mfpu=vfp
+# -mfloat-abi=hard.  Some multilibs may be incompatible with these
 # options.
 
-proc check_effective_target_arm_neon_ok { } {
+proc check_effective_target_arm_hard_vfp_ok { } {
     if { [check_effective_target_arm32] } {
-        return [check_no_compiler_messages arm_neon_ok object {
-            int dummy;
-        } "-mfpu=neon -mfloat-abi=softfp"]
+       return [check_no_compiler_messages arm_hard_vfp_ok executable {
+           int main() { return 0;}
+       } "-mfpu=vfp -mfloat-abi=hard"]
     } else {
-        return 0
+       return 0
+    }
+}
+
+# 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
+# NEON, do not add -mfpu=neon.
+
+proc add_options_for_arm_neon { flags } {
+    if { ! [check_effective_target_arm_neon_ok] } {
+       return "$flags"
     }
+    global et_arm_neon_flags
+    return "$flags $et_arm_neon_flags"
+}
+
+# Return 1 if this is an ARM target supporting -mfpu=neon
+# -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.
+
+proc check_effective_target_arm_neon_ok_nocache { } {
+    global et_arm_neon_flags
+    set et_arm_neon_flags ""
+    if { [check_effective_target_arm32] } {
+       foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon" "-mfpu=neon -mfloat-abi=softfp"} {
+           if { [check_no_compiler_messages_nocache arm_neon_ok object {
+               #include "arm_neon.h"
+               int dummy;
+           } "$flags"] } {
+               set et_arm_neon_flags $flags
+               return 1
+           }
+       }
+    }
+
+    return 0
+}
+
+proc check_effective_target_arm_neon_ok { } {
+    return [check_cached_effective_target arm_neon_ok \
+               check_effective_target_arm_neon_ok_nocache]
+}
+
+# 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.
+
+proc add_options_for_arm_neon_fp16 { flags } {
+    if { ! [check_effective_target_arm_neon_fp16_ok] } {
+       return "$flags"
+    }
+    global et_arm_neon_fp16_flags
+    return "$flags $et_arm_neon_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.
+
+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
+           }
+       }
+    }
+
+    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]
 }
 
 # Return 1 is this is an ARM target where -mthumb causes Thumb-1 to be
@@ -1270,6 +1947,17 @@ proc check_effective_target_arm_thumb1_ok { } {
     } "-mthumb"]
 }
 
+# Return 1 is this is an ARM target where -mthumb causes Thumb-2 to be
+# used.
+
+proc check_effective_target_arm_thumb2_ok { } {
+    return [check_no_compiler_messages arm_thumb2_ok assembly {
+       #if !defined(__thumb2__)
+       #error FOO
+       #endif
+    } "-mthumb"]
+}
+
 # Return 1 if the target supports executing NEON instructions, 0
 # otherwise.  Cache the result.
 
@@ -1284,7 +1972,7 @@ proc check_effective_target_arm_neon_hw { } {
               : "0" (a), "w" (b));
          return (a != 1);
        }
-    } "-mfpu=neon -mfloat-abi=softfp"]
+    } [add_options_for_arm_neon ""]]
 }
 
 # Return 1 if this is a ARM target with NEON enabled.
@@ -1314,6 +2002,32 @@ proc check_effective_target_mips_loongson { } {
     }]
 }
 
+# Return 1 if this is an ARM target that adheres to the ABI for the ARM
+# Architecture.
+
+proc check_effective_target_arm_eabi { } {
+    return [check_no_compiler_messages arm_eabi object {
+       #ifndef __ARM_EABI__
+       #error not EABI
+       #else
+       int dummy;
+       #endif
+    }]
+}
+
+# Return 1 if this is an ARM target supporting -mcpu=iwmmxt.
+# Some multilibs may be incompatible with this option.
+
+proc check_effective_target_arm_iwmmxt_ok { } {
+    if { [check_effective_target_arm32] } {
+       return [check_no_compiler_messages arm_iwmmxt_ok object {
+           int dummy;
+       } "-mcpu=iwmmxt"]
+    } else {
+       return 0
+    }
+}
+
 # Return 1 if this is a PowerPC target with floating-point registers.
 
 proc check_effective_target_powerpc_fprs { } {
@@ -1369,6 +2083,52 @@ proc check_effective_target_powerpc_altivec_ok { } {
     }
 }
 
+# Return 1 if this is a PowerPC target supporting -mvsx
+
+proc check_effective_target_powerpc_vsx_ok { } {
+    if { ([istarget powerpc*-*-*]
+         && ![istarget powerpc-*-linux*paired*])
+        || [istarget rs6000-*-*] } {
+       # 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_vsx_ok object {
+           int main (void) {
+#ifdef __MACH__
+               asm volatile ("xxlor vs0,vs0,vs0");
+#else
+               asm volatile ("xxlor 0,0,0");
+#endif
+               return 0;
+           }
+       } "-mvsx"]
+    } else {
+       return 0
+    }
+}
+
+# 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 { } {
@@ -1379,6 +2139,23 @@ proc check_effective_target_powerpc_spu { } {
     }
 }
 
+# Return 1 if this is a PowerPC SPE target.  The check includes options
+# specified by dg-options for this test, so don't cache the result.
+
+proc check_effective_target_powerpc_spe_nocache { } {
+    if { [istarget powerpc*-*-*] } {
+       return [check_no_compiler_messages_nocache powerpc_spe object {
+           #ifndef __SPE__
+           #error not SPE
+           #else
+           int dummy;
+           #endif
+       } [current_compiler_flags]]
+    } else {
+       return 0
+    }
+}
+
 # Return 1 if this is a PowerPC target with SPE enabled.
 
 proc check_effective_target_powerpc_spe { } {
@@ -1411,6 +2188,23 @@ proc check_effective_target_powerpc_altivec { } {
     }
 }
 
+# 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.
+
+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 {
+       return 0
+    }
+}
+
 # Return 1 if this is a SPU target with a toolchain that
 # supports automatic overlay generation.
 
@@ -1448,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
        }
     }
@@ -1516,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
        }
     }
@@ -1562,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
        }
     }
@@ -1608,6 +2415,91 @@ 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-*-*]
+            || [istarget i?86-*-*]
+            || [istarget x86_64-*-*] } {
+            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 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.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_vect_widen_sum_hi_to_si_pattern { } {
+    global et_vect_widen_sum_hi_to_si_pattern
+
+    if [info exists et_vect_widen_sum_hi_to_si_pattern_saved] {
+        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*-*-*] } {
+            set et_vect_widen_sum_hi_to_si_pattern_saved 1
+        }
+    }
+    verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern: returning $et_vect_widen_sum_hi_to_si_pattern_saved" 2
+    return $et_vect_widen_sum_hi_to_si_pattern_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
@@ -1830,7 +2722,9 @@ proc check_effective_target_vect_pack_trunc { } {
         set et_vect_pack_trunc_saved 0
         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
              || [istarget i?86-*-*]
-             || [istarget x86_64-*-*] } {
+             || [istarget x86_64-*-*]
+             || [istarget spu-*-*]
+             || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
             set et_vect_pack_trunc_saved 1
         }
     }
@@ -1853,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
         }
     }
@@ -1893,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
        }
     }
@@ -1901,6 +2798,27 @@ proc check_effective_target_vect_no_align { } {
     return $et_vect_no_align_saved
 }
 
+# Return 1 if the target supports a vector misalign access, 0 otherwise.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_vect_hw_misalign { } {
+    global et_vect_hw_misalign_saved
+
+    if [info exists et_vect_hw_misalign_saved] {
+        verbose "check_effective_target_vect_hw_misalign: using cached result" 2
+    } else {
+        set et_vect_hw_misalign_saved 0
+       if { ([istarget x86_64-*-*] 
+            || [istarget i?86-*-*]) } {
+          set et_vect_hw_misalign_saved 1
+       }
+    }
+    verbose "check_effective_target_vect_hw_misalign: returning $et_vect_hw_misalign_saved" 2
+    return $et_vect_hw_misalign_saved
+}
+
+
 # Return 1 if arrays are aligned to the vector alignment
 # boundary, 0 otherwise.
 #
@@ -2007,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 { } {
@@ -2061,7 +2998,11 @@ proc check_effective_target_vect_short_mult { } {
        if { [istarget ia64-*-*]
             || [istarget spu-*-*]
             || [istarget i?86-*-*]
-            || [istarget x86_64-*-*] } {
+            || [istarget x86_64-*-*]
+            || [istarget powerpc*-*-*]
+            || [check_effective_target_arm32]
+            || ([istarget mips*-*-*]
+                && [check_effective_target_mips_loongson]) } {
           set et_vect_short_mult_saved 1
        }
     }
@@ -2101,7 +3042,10 @@ 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 i?86-*-*]
+             || [istarget x86_64-*-*]
+             || [istarget spu-*-*] } {
            set et_vect_extract_even_odd_saved 1
         }
     }
@@ -2122,7 +3066,8 @@ proc check_effective_target_vect_extract_even_odd_wide { } {
         set et_vect_extract_even_odd_wide_saved 0 
         if { [istarget powerpc*-*-*] 
              || [istarget i?86-*-*]
-             || [istarget x86_64-*-*] } {
+             || [istarget x86_64-*-*]
+             || [istarget spu-*-*] } {
            set et_vect_extract_even_odd_wide_saved 1
         }
     }
@@ -2142,7 +3087,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
         }
     }
@@ -2197,7 +3143,8 @@ proc check_effective_target_section_anchors { } {
         verbose "check_effective_target_section_anchors: using cached result" 2
     } else {
         set et_section_anchors_saved 0
-        if { [istarget powerpc*-*-*] } {
+        if { [istarget powerpc*-*-*]
+             || [istarget arm*-*-*] } {
            set et_section_anchors_saved 1
         }
     }
@@ -2221,6 +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-*-*]
@@ -2249,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-*-*]
@@ -2343,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] }
@@ -2362,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 }
@@ -2389,7 +3345,8 @@ proc check_effective_target_string_merging { } {
 }
 
 # Return 1 if target has the basic signed and unsigned types in
-# <stdint.h>, 0 otherwise.
+# <stdint.h>, 0 otherwise.  This will be obsolete when GCC ensures a
+# working <stdint.h> for all targets.
 
 proc check_effective_target_stdint_types { } {
     return [check_no_compiler_messages stdint_types assembly {
@@ -2399,6 +3356,19 @@ proc check_effective_target_stdint_types { } {
     }]
 }
 
+# Return 1 if target has the basic signed and unsigned types in
+# <inttypes.h>, 0 otherwise.  This is for tests that GCC's notions of
+# these types agree with those in the header, as some systems have
+# only <inttypes.h>.
+
+proc check_effective_target_inttypes_types { } {
+    return [check_no_compiler_messages inttypes_types assembly {
+       #include <inttypes.h>
+       int8_t a; int16_t b; int32_t c; int64_t d;
+       uint8_t e; uint16_t f; uint32_t g; uint64_t h;
+    }]
+}
+
 # Return 1 if programs are intended to be run on a simulator
 # (i.e. slowly) rather than hardware (i.e. fast).
 
@@ -2508,6 +3478,49 @@ proc add_options_for_c99_runtime { flags } {
     return $flags
 }
 
+# Add to FLAGS all the target-specific flags needed to enable
+# full IEEE compliance mode.
+
+proc add_options_for_ieee { flags } {
+    if { [istarget "alpha*-*-*"]
+         || [istarget "sh*-*-*"] } {
+       return "$flags -mieee"
+    }
+    return $flags
+}
+
+# Add to FLAGS the flags needed to enable functions to bind locally
+# when using pic/PIC passes in the testsuite.
+
+proc add_options_for_bind_pic_locally { flags } {
+    if {[check_no_compiler_messages using_pic2 assembly {
+        #if __PIC__ != 2
+        #error FOO
+        #endif
+    }]} {
+       return "$flags -fPIE"
+    }
+    if {[check_no_compiler_messages using_pic1 assembly {
+        #if __PIC__ != 1
+        #error FOO
+        #endif
+    }]} {
+       return "$flags -fpie"
+    }
+
+    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 { } {
@@ -2538,10 +3551,188 @@ 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.
+
+proc check_effective_target_avx { } {
+    return [check_no_compiler_messages avx object {
+       void _mm256_zeroall (void)
+       {
+          __builtin_ia32_vzeroall ();
+       }
+    } "-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 {
+       typedef long long __m128i __attribute__ ((__vector_size__ (16)));
+       
+       __m128i _mm_srli_si128 (__m128i __A, int __N)
+       {
+           return (__m128i)__builtin_ia32_psrldqi128 (__A, 8);
+       }
+    } "-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 { } {
+    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 <math.h>
+       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 {
+       typedef float d64 __attribute__((mode(DD)));
+       d64 x, y, z;
+       void foo (void) { z = x + y; }
+    }]
+}
+
+# Return 1 if string.h and wchar.h headers provide C++ requires overloads
+# for strchr etc. functions.
+
+proc check_effective_target_correct_iso_cpp_string_wchar_protos { } {
+    return [check_no_compiler_messages correct_iso_cpp_string_wchar_protos assembly {
+       #include <string.h>
+       #include <wchar.h>
+       #if !defined(__cplusplus) \
+           || !defined(__CORRECT_ISO_CPP_STRING_H_PROTO) \
+           || !defined(__CORRECT_ISO_CPP_WCHAR_H_PROTO)
+       ISO C++ correct string.h and wchar.h protos not supported.
+       #else
+       int i;
+       #endif
+    }]
+}
+
+# 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.
+
+proc check_effective_target_lto { } {
+    global ENABLE_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 { } {
+ global tool
+    if [string match $tool "gcc"] {
+   return 1
+    }
+ return 0
+}
+
+# Return 1 if the language for the compiler under test is C++.
+
+proc check_effective_target_c++ { } {
+ global tool
+    if [string match $tool "g++"] {
+   return 1
+    }
+ 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
 }