config.gcc: Match arm*-*-linux-* for ARM Linux/GNU.
[gcc.git] / gcc / testsuite / lib / target-supports.exp
index 8a0e36ff35f0d49471b600eb1f5b3b9225bca2c1..e932cc9e7ff413fd70bbc91798cf8bec76ba3625 100644 (file)
@@ -1,5 +1,5 @@
 #   Copyright (C) 1999, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-#   2011 Free Software Foundation, Inc.
+#   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
@@ -219,7 +219,6 @@ proc check_runtime {prop args} {
 # 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
@@ -230,25 +229,19 @@ proc check_weak_available { } {
 
     # 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] } {
-       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
     }
 
@@ -276,7 +269,7 @@ proc check_weak_available { } {
 # cannot be overridden.
 
 proc check_weak_override_available { } {
-    if { [istarget "*-*-mingw*"] } {
+    if { [istarget *-*-mingw*] } {
        return 0
     }
     return [check_weak_available]
@@ -291,14 +284,6 @@ proc check_weak_override_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 "
@@ -370,45 +355,16 @@ 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.
+# 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"]
-       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
+    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.
@@ -497,7 +453,9 @@ proc check_profiling_available { test_what } {
 
     # Tree profiling requires TLS runtime support.
     if { $test_what == "-fprofile-generate" } {
-       return [check_effective_target_tls_runtime]
+       if { ![check_effective_target_tls_runtime] } {
+           return 0
+       }
     }
 
     # Support for -p on solaris2 relies on mcrt1.o which comes with the
@@ -508,15 +466,6 @@ proc check_profiling_available { test_what } {
        return 0
     }
 
-    # Support for -p on irix relies on libprof1.a which doesn't appear to
-    # exist on any irix6 system currently posting testsuite results.
-    # 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*]
-         && ($test_what == "-p" || $test_what == "-pg") } {
-       return 0
-    }
-
     # We don't yet support profiling for MIPS16.
     if { [istarget mips*-*-*]
         && ![check_effective_target_nomips16]
@@ -567,9 +516,9 @@ proc check_profiling_available { test_what } {
             || [istarget powerpc-*-eabi*]
             || [istarget powerpc-*-elf]
             || [istarget rx-*-*]       
+            || [istarget tic6x-*-elf]
             || [istarget xstormy16-*]
             || [istarget xtensa*-*-elf]
-            || [istarget *-*-netware*]
             || [istarget *-*-rtems*]
             || [istarget *-*-vxworks*] } {
            set profiling_available_saved 0
@@ -620,16 +569,11 @@ 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 } {
-    # 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 *-*-osf*] } {
-       return "$flags -pthread"
-    }
-    # On Solaris 8 and 9, __tls_get_addr/___tls_get_addr only lives in
+    # On Solaris 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\]*] &&
+    if { [istarget *-*-solaris2.9*] &&
         [check_no_messages_and_pattern tls_native "!emutls" assembly {
             __thread int i;
             int f (void) { return i; }
@@ -655,8 +599,7 @@ proc check_effective_target_tls {} {
 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
     }
     
@@ -672,8 +615,7 @@ proc check_effective_target_tls_native {} {
 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
     }
     
@@ -693,12 +635,33 @@ proc check_effective_target_tls_runtime {} {
     } [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
     }
     
@@ -707,6 +670,14 @@ proc check_effective_target_function_sections {} {
     } "-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.
 
@@ -725,6 +696,21 @@ proc check_effective_target_fopenmp {} {
     } "-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.
 
@@ -893,6 +879,53 @@ proc check_effective_target_mips_newabi_large_long_double { } {
     } "-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 { } {
@@ -940,12 +973,7 @@ proc check_iconv_available { test_what } {
 # 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 1
 }
 
 # Return true if named sections are supported on this target.
@@ -956,6 +984,14 @@ proc check_named_sections_available { } {
     }]
 }
 
+# Return true if the "naked" function attribute is supported on this target.
+
+proc check_effective_target_naked_functions { } {
+    return [check_no_compiler_messages naked_functions assembly {
+       void f() __attribute__((naked));
+    }]
+}
+
 # Return 1 if the target supports Fortran real kinds larger than real(8),
 # 0 otherwise.
 #
@@ -987,6 +1023,28 @@ proc check_effective_target_fortran_real_16 { } {
     }]
 }
 
+
+# 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.
 #
@@ -1069,8 +1127,8 @@ proc check_sse_os_support_available { } {
            check_runtime_nocache sse_os_support_available {
                int main ()
                {
-                   __asm__ volatile ("movaps %xmm0,%xmm0");
-                   return 0;
+                 asm volatile ("movaps %xmm0,%xmm0");
+                 return 0;
                }
            } "-msse"
        } else {
@@ -1079,6 +1137,29 @@ proc check_sse_os_support_available { } {
     }]
 }
 
+# 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.
 
@@ -1175,7 +1256,8 @@ proc check_effective_target_sse2_runtime { } {
 
 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
@@ -1392,6 +1474,25 @@ proc check_effective_target_broken_cplxf_arg { } {
     }]
 }
 
+# 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; }
@@ -1422,7 +1523,7 @@ proc check_fork_available {} {
 # 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
      }
@@ -1434,10 +1535,10 @@ proc check_mkfifo_available {} {
 
 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 {
@@ -1507,6 +1608,28 @@ proc check_effective_target_ilp32 { } {
     }]
 }
 
+# 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.
 
@@ -1566,6 +1689,15 @@ proc check_effective_target_llp64 { } {
     }]
 }
 
+# Return 1 if long and int have different sizes,
+# 0 otherwise.
+
+proc check_effective_target_long_neq_int { } {
+    return [check_no_compiler_messages long_ne_int object {
+       int dummy[sizeof (int) != sizeof (long) ? 1 : -1];
+    }]
+}
+
 # Return 1 if the target supports long double larger than double,
 # 0 otherwise.
 
@@ -1708,10 +1840,12 @@ proc check_effective_target_vect_cmdline_needed { } {
        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
@@ -1765,7 +1899,9 @@ proc check_effective_target_vect_intfloat_cvt { } {
         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
         }
     }
@@ -1801,7 +1937,9 @@ proc check_effective_target_vect_uintfloat_cvt { } {
         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
         }
     }
@@ -1824,7 +1962,9 @@ proc check_effective_target_vect_floatint_cvt { } {
         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
         }
     }
@@ -1844,7 +1984,9 @@ proc check_effective_target_vect_floatuint_cvt { } {
     } 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
         }
     }
@@ -1862,6 +2004,24 @@ proc check_effective_target_arm32 { } {
     }]
 }
 
+# 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 {
@@ -1893,7 +2053,8 @@ proc check_effective_target_arm_vfp_ok { } {
 # options.
 
 proc check_effective_target_arm_hard_vfp_ok { } {
-    if { [check_effective_target_arm32] } {
+    if { [check_effective_target_arm32] 
+        && ! [check-flags [list "" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" }]] } {
        return [check_no_compiler_messages arm_hard_vfp_ok executable {
            int main() { return 0;}
        } "-mfpu=vfp -mfloat-abi=hard"]
@@ -1902,6 +2063,30 @@ proc check_effective_target_arm_hard_vfp_ok { } {
     }
 }
 
+# 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
@@ -1915,6 +2100,19 @@ proc add_options_for_arm_neon { flags } {
     return "$flags $et_arm_neon_flags"
 }
 
+# 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_neonv2 { flags } {
+    if { ! [check_effective_target_arm_neonv2_ok] } {
+       return "$flags"
+    }
+    global et_arm_neonv2_flags
+    return "$flags $et_arm_neonv2_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
@@ -1943,6 +2141,38 @@ proc check_effective_target_arm_neon_ok { } {
                check_effective_target_arm_neon_ok_nocache]
 }
 
+# Return 1 if this is an ARM target supporting -mfpu=neon-vfpv4
+# -mfloat-abi=softfp or equivalent options.  Some multilibs may be
+# incompatible with these options.  Also set et_arm_neonv2_flags to the
+# best options to add.
+
+proc check_effective_target_arm_neonv2_ok_nocache { } {
+    global et_arm_neonv2_flags
+    set et_arm_neonv2_flags ""
+    if { [check_effective_target_arm32] } {
+       foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-vfpv4" "-mfpu=neon-vfpv4 -mfloat-abi=softfp"} {
+           if { [check_no_compiler_messages_nocache arm_neonv2_ok object {
+               #include "arm_neon.h"
+               float32x2_t 
+               foo (float32x2_t a, float32x2_t b, float32x2_t c)
+                {
+                  return vfma_f32 (a, b, c);
+                }
+           } "$flags"] } {
+               set et_arm_neonv2_flags $flags
+               return 1
+           }
+       }
+    }
+
+    return 0
+}
+
+proc check_effective_target_arm_neonv2_ok { } {
+    return [check_cached_effective_target arm_neonv2_ok \
+               check_effective_target_arm_neonv2_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.
@@ -1996,6 +2226,68 @@ proc check_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 } */
+#       /* { dg-require-effective-target arm_arch_v5_multilib } */
+foreach { armfunc armflag armdef } { v4 "-march=armv4 -marm" __ARM_ARCH_4__
+                                    v4t "-march=armv4t" __ARM_ARCH_4T__
+                                    v5 "-march=armv5 -marm" __ARM_ARCH_5__
+                                    v5t "-march=armv5t" __ARM_ARCH_5T__
+                                    v5te "-march=armv5te" __ARM_ARCH_5TE__
+                                    v6 "-march=armv6" __ARM_ARCH_6__
+                                    v6k "-march=armv6k" __ARM_ARCH_6K__
+                                    v6t2 "-march=armv6t2" __ARM_ARCH_6T2__
+                                    v6z "-march=armv6z" __ARM_ARCH_6Z__
+                                    v6m "-march=armv6-m -mthumb" __ARM_ARCH_6M__
+                                    v7a "-march=armv7-a" __ARM_ARCH_7A__
+                                    v7r "-march=armv7-r" __ARM_ARCH_7R__
+                                    v7m "-march=armv7-m -mthumb" __ARM_ARCH_7M__
+                                    v7em "-march=armv7e-m -mthumb" __ARM_ARCH_7EM__ } {
+    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"
+       }
+
+       proc check_effective_target_arm_arch_FUNC_multilib { } {
+           return [check_runtime arm_arch_FUNC_multilib {
+               int
+               main (void)
+               {
+                   return 0;
+               }
+           } [add_options_for_arm_arch_FUNC ""]]
+        }
+    }]
+}
+
+# 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.
 
@@ -2018,6 +2310,43 @@ proc check_effective_target_arm_thumb2_ok { } {
     } "-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.
 
@@ -2035,6 +2364,21 @@ proc check_effective_target_arm_neon_hw { } {
     } [add_options_for_arm_neon ""]]
 }
 
+proc check_effective_target_arm_neonv2_hw { } {
+    return [check_runtime arm_neon_hwv2_available {
+       #include "arm_neon.h"
+       int
+       main (void)
+       {
+         float32x2_t a, b, c;
+         asm ("vfma.f32 %P0, %P1, %P2"
+              : "=w" (a)
+              : "w" (b), "w" (c));
+         return 0;
+       }
+    } [add_options_for_arm_neonv2 ""]]
+}
+
 # Return 1 if this is a ARM target with NEON enabled.
 
 proc check_effective_target_arm_neon { } {
@@ -2051,6 +2395,24 @@ proc check_effective_target_arm_neon { } {
     }
 }
 
+proc check_effective_target_arm_neonv2 { } {
+    if { [check_effective_target_arm32] } {
+       return [check_no_compiler_messages arm_neon object {
+           #ifndef __ARM_NEON__
+           #error not NEON
+           #else
+           #ifndef __ARM_FEATURE_FMA
+           #error not NEONv2
+            #else
+           int dummy;
+           #endif
+           #endif
+       }]
+    } else {
+       return 0
+    }
+}
+
 # Return 1 if this a Loongson-2E or -2F target using an ABI that supports
 # the Loongson vector modes.
 
@@ -2075,6 +2437,19 @@ proc check_effective_target_arm_eabi { } {
     }]
 }
 
+# Return 1 if this is an ARM target that adheres to the hard-float variant of
+# the ABI for the ARM Architecture (e.g. -mfloat-abi=hard).
+
+proc check_effective_target_arm_hf_eabi { } {
+    return [check_no_compiler_messages arm_hf_eabi object {
+       #if !defined(__ARM_EABI__) || !defined(__ARM_PCS_VFP)
+       #error not hard-float EABI
+       #else
+       int dummy;
+       #endif
+    }]
+}
+
 # Return 1 if this is an ARM target supporting -mcpu=iwmmxt.
 # Some multilibs may be incompatible with this option.
 
@@ -2192,7 +2567,7 @@ proc check_effective_target_powerpc_ppu_ok { } {
 # 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
@@ -2288,6 +2663,55 @@ proc check_effective_target_ultrasparc_hw { } {
     } "-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-V9 target.
+
+proc check_effective_target_sparc_v9 { } {
+    if { [istarget sparc*-*-*] } {
+       return [check_no_compiler_messages sparc_v9 object {
+           int main (void) {
+               asm volatile ("return %i7+8");
+               return 0;
+           }
+       }]
+    } else {
+       return 0
+    }
+}
+
+# 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 { } {
@@ -2313,27 +2737,6 @@ proc check_effective_target_vect_shift { } {
     return $et_vect_shift_saved
 }
 
-# Return 1 if the target supports hardware vector shift operation with
-# scalar shift argument.
-
-proc check_effective_target_vect_shift_scalar { } {
-    global et_vect_shift_scalar_saved
-
-    if [info exists et_vect_shift_scalar_saved] {
-        verbose "check_effective_target_vect_shift_scalar: using cached result" 2
-    } else {
-        set et_vect_shift_scalar_saved 0
-        if { [istarget x86_64-*-*]
-             || [istarget i?86-*-*] } {
-           set et_vect_shift_scalar_saved 1
-        }
-    }
-
-    verbose "check_effective_target_vect_shift_scalar: returning $et_vect_shift_scalar_saved" 2
-    return $et_vect_shift_scalar_saved
-}
-
-
 # Return 1 if the target supports hardware vector shift operation for char.
 
 proc check_effective_target_vect_shift_char { } {
@@ -2528,10 +2931,13 @@ proc check_effective_target_vect_perm { } {
         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
         }
     }
@@ -2551,7 +2957,8 @@ proc check_effective_target_vect_perm_byte { } {
         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
         }
@@ -2572,7 +2979,8 @@ proc check_effective_target_vect_perm_short { } {
         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
         }
@@ -2690,7 +3098,7 @@ proc check_effective_target_vect_widen_mult_qi_to_hi { } {
            set et_vect_widen_mult_qi_to_hi_saved 0
        }
         if { [istarget powerpc*-*-*]
-              || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
+              || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]) } {
             set et_vect_widen_mult_qi_to_hi_saved 1
         }
     }
@@ -2724,7 +3132,7 @@ proc check_effective_target_vect_widen_mult_hi_to_si { } {
              || [istarget ia64-*-*]
              || [istarget i?86-*-*]
              || [istarget x86_64-*-*]
-              || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
+              || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]) } {
             set et_vect_widen_mult_hi_to_si_saved 1
         }
     }
@@ -2745,7 +3153,7 @@ proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } {
     } else {
         set et_vect_widen_mult_qi_to_hi_pattern_saved 0
         if { [istarget powerpc*-*-*]
-              || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
+              || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]) } {
             set et_vect_widen_mult_qi_to_hi_pattern_saved 1
         }
     }
@@ -2770,7 +3178,7 @@ proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } {
               || [istarget ia64-*-*]
               || [istarget i?86-*-*]
               || [istarget x86_64-*-*]
-              || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
+              || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]) } {
             set et_vect_widen_mult_hi_to_si_pattern_saved 1
         }
     }
@@ -2778,6 +3186,26 @@ proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } {
     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.
 #
@@ -2880,7 +3308,8 @@ proc check_effective_target_vect_pack_trunc { } {
              || [istarget i?86-*-*]
              || [istarget x86_64-*-*]
              || [istarget spu-*-*]
-             || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
+             || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]
+                && [check_effective_target_arm_little_endian]) } {
             set et_vect_pack_trunc_saved 1
         }
     }
@@ -2905,7 +3334,8 @@ proc check_effective_target_vect_unpack { } {
              || [istarget x86_64-*-*] 
              || [istarget spu-*-*]
              || [istarget ia64-*-*]
-             || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
+             || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]
+                && [check_effective_target_arm_little_endian]) } {
             set et_vect_unpack_saved 1
         }
     }
@@ -2988,9 +3418,14 @@ proc check_effective_target_vect_aligned_arrays { } {
        verbose "check_effective_target_vect_aligned_arrays: using cached result" 2
     } else {
        set et_vect_aligned_arrays_saved 0
-        if { (([istarget x86_64-*-*]
-              || [istarget i?86-*-*]) && [is-effective-target lp64])
-              || [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
        }
     }
@@ -3040,6 +3475,26 @@ proc check_effective_target_natural_alignment_64 { } {
     return $et_natural_alignment_64_saved
 }
 
+# Return 1 if all vector types are naturally aligned (aligned to their
+# type-size), 0 otherwise.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_vect_natural_alignment { } {
+    global et_vect_natural_alignment
+
+    if [info exists et_vect_natural_alignment_saved] {
+        verbose "check_effective_target_vect_natural_alignment: using cached result" 2
+    } else {
+        set et_vect_natural_alignment_saved 1
+        if { [check_effective_target_arm_eabi] } {
+            set et_vect_natural_alignment_saved 0
+        }
+    }
+    verbose "check_effective_target_vect_natural_alignment: returning $et_vect_natural_alignment_saved" 2
+    return $et_vect_natural_alignment_saved
+}
+
 # Return 1 if vector alignment (for types of size 32 bit or less) is reachable, 0 otherwise.
 #
 # This won't change for different subtargets so cache the result.
@@ -3091,7 +3546,8 @@ proc check_effective_target_vect_element_align { } {
        verbose "check_effective_target_vect_element_align: using cached result" 2
     } else {
        set et_vect_element_align 0
-       if { [istarget arm*-*-*]
+       if { ([istarget arm*-*-*]
+             && ![check_effective_target_arm_vect_no_misalign])
             || [check_effective_target_vect_hw_misalign] } {
           set et_vect_element_align 1
        }
@@ -3114,7 +3570,8 @@ 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
        }
     }
@@ -3123,6 +3580,27 @@ proc check_effective_target_vect_condition { } {
     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 { } {
@@ -3134,7 +3612,8 @@ proc check_effective_target_vect_char_mult { } {
        set et_vect_char_mult_saved 0
        if { [istarget ia64-*-*]
             || [istarget i?86-*-*]
-            || [istarget x86_64-*-*] } {
+            || [istarget x86_64-*-*]
+            || [check_effective_target_arm32] } {
           set et_vect_char_mult_saved 1
        }
     }
@@ -3201,11 +3680,14 @@ proc check_effective_target_vect_extract_even_odd { } {
     } 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 ia64-*-*]
-             || [istarget spu-*-*] } {
-           set et_vect_extract_even_odd_saved 1
+             || [istarget spu-*-*]
+            || ([istarget mips*-*-*]
+                && [check_effective_target_mpaired_single]) } {
+           set et_vect_extract_even_odd_saved 1
         }
     }
 
@@ -3223,10 +3705,13 @@ 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 ia64-*-*]
-             || [istarget spu-*-*] } {
+             || [istarget spu-*-*]
+            || ([istarget mips*-*-*]
+                && [check_effective_target_mpaired_single]) } {
            set et_vect_interleave_saved 1
         }
     }
@@ -3261,6 +3746,95 @@ foreach N {2 3 4 8} {
     }]
 }
 
+# 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_ok]) } {
+       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_vect64_saved 0
+        if { ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]) } {
+           set et_vect64_saved 1
+        }
+    }
+
+    verbose "check_effective_target_vect64: returning $et_vect64_saved" 2
+    return $et_vect64_saved
+}
+
+# Return 1 if the target supports vector copysignf calls.
+
+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_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_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
 
 proc check_effective_target_section_anchors { } {
@@ -3280,6 +3854,105 @@ proc check_effective_target_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*-*-*]
+        || ([istarget sparc*-*-*] && [check_effective_target_lp64]) } {
+       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-*] } {
+       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
+    } elseif { ([istarget sparc*-*-*]
+                && [check_effective_target_lp64]
+                && [check_effective_target_ultrasparc_hw]) } {
+       return 1
+    } elseif { [istarget powerpc*-*-*] && [check_effective_target_lp64] } {
+       return 1
+    } else {
+       return 0
+    }
+}
+
 # Return 1 if the target supports atomic operations on "int" and "long".
 
 proc check_effective_target_sync_int_long { } {
@@ -3295,14 +3968,14 @@ proc check_effective_target_sync_int_long { } {
             || [istarget i?86-*-*]
             || [istarget x86_64-*-*]
             || [istarget alpha*-*-*] 
-            || [istarget arm*-*-linux-gnueabi
+            || [istarget arm*-*-linux-*
             || [istarget bfin*-*linux*]
             || [istarget hppa*-*linux*]
             || [istarget s390*-*-*] 
             || [istarget powerpc*-*-*]
-            || [istarget sparc64-*-*]
-            || [istarget sparcv9-*-*]
-            || [istarget mips*-*-*] } {
+            || [istarget crisv32-*-*] || [istarget cris-*-*]
+            || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9])
+            || [check_effective_target_mips_llsc] } {
            set et_sync_int_long_saved 1
         }
     }
@@ -3326,13 +3999,13 @@ proc check_effective_target_sync_char_short { } {
             || [istarget i?86-*-*]
             || [istarget x86_64-*-*]
             || [istarget alpha*-*-*] 
-            || [istarget arm*-*-linux-gnueabi
+            || [istarget arm*-*-linux-*
             || [istarget hppa*-*linux*]
             || [istarget s390*-*-*] 
             || [istarget powerpc*-*-*]
-            || [istarget sparc64-*-*]
-            || [istarget sparcv9-*-*]
-            || [istarget mips*-*-*] } {
+            || [istarget crisv32-*-*] || [istarget cris-*-*]
+            || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9])
+            || [check_effective_target_mips_llsc] } {
            set et_sync_char_short_saved 1
         }
     }
@@ -3572,16 +4245,25 @@ proc check_effective_target_fd_truncate { } {
          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);
        }
     }
 
@@ -3599,9 +4281,6 @@ proc add_options_for_c99_runtime { flags } {
     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"
     }
@@ -3612,11 +4291,11 @@ proc add_options_for_c99_runtime { flags } {
 # 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-*-*"] } {
+    if { [istarget rx-*-*] } {
        return "$flags -mnofpu"
     }
     return $flags
@@ -3644,11 +4323,11 @@ proc add_options_for_bind_pic_locally { flags } {
     return $flags
 }
 
-# Add to FLAGS the flags needed to enable 128-bit vectors.
+# Add to FLAGS the flags needed to enable 64-bit vectors.
 
-proc add_options_for_quad_vectors { flags } {
+proc add_options_for_double_vectors { flags } {
     if [is-effective-target arm_neon_ok] {
-       return "$flags -mvectorize-with-neon-quad"
+       return "$flags -mvectorize-with-neon-double"
     }
 
     return $flags
@@ -3695,6 +4374,39 @@ proc check_effective_target_automatic_stack_alignment  { } {
     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 { } {
@@ -3824,6 +4536,26 @@ proc check_effective_target_gas { } {
     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.
 
@@ -3861,6 +4593,31 @@ 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++1y { } {
+    if ![check_effective_target_c++] {
+       return 0
+    }
+    return [check-flags { { } { } { -std=c++1y -std=gnu++1y } }]
+}
+
+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 -std=c++1y -std=gnu++1y } }]
+}
+
 # Return 1 if expensive testcases should be run.
 
 proc check_effective_target_run_expensive_tests { } {
@@ -3886,21 +4643,21 @@ proc check_vect_support_and_set_flags { } {
     global DEFAULT_VECTCFLAGS
     global dg-do-what-default
 
-    if  [istarget "powerpc-*paired*"]  {
+    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*-*-*"] {
+    } 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]  {
+        if [check_vsx_hw_available] {
             lappend DEFAULT_VECTCFLAGS "-mvsx" "-mno-allow-movmisalign"
         }
 
@@ -3913,16 +4670,16 @@ proc check_vect_support_and_set_flags { } {
             }
             set dg-do-what-default compile
         }
-    } elseif { [istarget  "spu-*-*"] } {
+    } elseif { [istarget spu-*-*] } {
         set dg-do-what-default run
-    } elseif { [istarget "i?86-*-*"] || [istarget "x86_64-*-*"] } {
+    } 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*-*-*"]
+    } elseif { [istarget mips*-*-*]
                && ([check_effective_target_mpaired_single]
                     || [check_effective_target_mips_loongson])
                && [check_effective_target_nomips16] } {
@@ -3930,14 +4687,14 @@ proc check_vect_support_and_set_flags { } {
             lappend DEFAULT_VECTCFLAGS "-mpaired-single"
         }
         set dg-do-what-default run
-    } elseif [istarget "sparc*-*-*"] {
+    } 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*-*-*"] {
+    } 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
@@ -3950,7 +4707,7 @@ proc check_vect_support_and_set_flags { } {
         } else {
             set dg-do-what-default compile
         }
-    } elseif [istarget "ia64-*-*"] {
+    } 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 ""]
@@ -3978,3 +4735,11 @@ proc check_effective_target_non_strict_align {} {
        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>
+    }]
+}