]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/testsuite/lib/target-supports.exp
Fix __atomic to not implement atomic loads with CAS.
[thirdparty/gcc.git] / gcc / testsuite / lib / target-supports.exp
index 6724a7fd214e91299f7b47563cff2d6e6611c3da..7a260085405c850ef4042faffc4ad71fdb25c830 100644 (file)
@@ -1,4 +1,4 @@
-#   Copyright (C) 1999-2016 Free Software Foundation, Inc.
+#   Copyright (C) 1999-2017 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
@@ -252,6 +252,20 @@ proc check_runtime {prop args} {
     }]
 }
 
+# Return 1 if GCC was configured with $pattern.
+proc check_configured_with { pattern } {
+    global tool
+
+    set gcc_output [${tool}_target_compile "-v" "" "none" ""]
+    if { [ regexp "Configured with: \[^\n\]*$pattern" $gcc_output ] } {
+        verbose "Matched: $pattern" 2
+        return 1
+    }
+
+    verbose "Failed to match: $pattern" 2
+    return 0
+}
+
 ###############################
 # proc check_weak_available { }
 ###############################
@@ -462,9 +476,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
-       set gcc_ld [lindex [${tool}_target_compile "-print-prog-name=$linker" "" "none" ""] 0]
+       set gcc_ld [lindex [${tool}_target_compile "-print-prog-name=ld" "" "none" ""] 0]
        set ld_output [remote_exec host "$gcc_ld" "--help"]
        if { [ string first "--gc-sections" $ld_output ] >= 0 } {
            set gc_sections_available_saved 1
@@ -533,7 +545,7 @@ proc check_profiling_available { test_what } {
     }
 
     if { $test_what == "-fauto-profile" } {
-       if { ! ([istarget x86_64-*-linux*] || [istarget i?86-*-linux*]) } {
+       if { !([istarget i?86-*-linux*] || [istarget x86_64-*-linux*]) } {
             verbose "autofdo only supported on linux"
             return 0
         }
@@ -765,7 +777,10 @@ proc check_effective_target_untyped_assembly {} {
 
 proc check_effective_target_alloca {} {
     if { [istarget nvptx-*-*] } {
-       return 0
+       return [check_no_compiler_messages alloca assembly {
+           void f (void*);
+           void g (int n) { f (__builtin_alloca (n)); }
+       }]
     }
     return 1
 }
@@ -1010,12 +1025,19 @@ proc check_effective_target_fstack_protector {} {
 }
 
 # Return 1 if compilation with -freorder-blocks-and-partition is error-free
-# for trivial code, 0 otherwise.
+# for trivial code, 0 otherwise.  As some targets (ARM for example) only
+# warn when -fprofile-use is also supplied we test that combination too.
 
 proc check_effective_target_freorder {} {
-    return [check_no_compiler_messages freorder object {
+    if { [check_no_compiler_messages freorder object {
        void foo (void) { }
     } "-freorder-blocks-and-partition"]
+    && [check_no_compiler_messages fprofile_use_freorder object {
+       void foo (void) { }
+    } "-fprofile-use -freorder-blocks-and-partition"] } {
+       return 1
+    }
+    return 0
 }
 
 # Return 1 if -fpic and -fPIC are supported, as in no warnings or errors
@@ -1521,7 +1543,7 @@ proc check_750cl_hw_available { } {
 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-*-*]) } {
+       if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
            expr 0
        } elseif { [istarget i?86-*-solaris2*] } {
            # The Solaris 2 kernel doesn't save and restore SSE registers
@@ -1545,7 +1567,7 @@ proc check_sse_os_support_available { } {
 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-*-*]) } {
+       if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
            expr 0
        } else {
            # Check that OS has AVX and SSE saving enabled.
@@ -1568,7 +1590,7 @@ proc check_avx_os_support_available { } {
 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-*-*]) } {
+       if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
            expr 0
        } else {
            check_runtime_nocache sse_hw_available {
@@ -1626,13 +1648,49 @@ proc check_mips_loongson_hw_available { } {
     }]
 }
 
+# Return 1 if the target supports executing MIPS MSA instructions, 0
+# otherwise.  Cache the result.
+
+proc check_mips_msa_hw_available { } {
+  return [check_cached_effective_target mips_msa_hw_available {
+    # If this is not the right target then we can skip the test.
+    if { !([istarget mips*-*-*]) } {
+      expr 0
+    } else {
+      check_runtime_nocache mips_msa_hw_available {
+       #if !defined(__mips_msa)
+       #error "MSA NOT AVAIL"
+       #else
+       #if !(((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2))
+       #error "MSA NOT AVAIL FOR ISA REV < 2"
+       #endif
+       #if !defined(__mips_hard_float)
+       #error "MSA HARD_FLOAT REQUIRED"
+       #endif
+       #if __mips_fpr != 64
+       #error "MSA 64-bit FPR REQUIRED"
+       #endif
+       #include <msa.h>
+
+       int main()
+       {
+         v8i16 v = __builtin_msa_ldi_h (0);
+         v[0] = 0;
+         return v[0];
+       }
+       #endif
+      } "-mmsa"
+    }
+  }]
+}
+
 # Return 1 if the target supports executing SSE2 instructions, 0
 # otherwise.  Cache the result.
 
 proc check_sse2_hw_available { } {
     return [check_cached_effective_target sse2_hw_available {
        # If this is not the right target then we can skip the test.
-       if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
+       if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
            expr 0
        } else {
            check_runtime_nocache sse2_hw_available {
@@ -1655,7 +1713,7 @@ proc check_sse2_hw_available { } {
 proc check_sse4_hw_available { } {
     return [check_cached_effective_target sse4_hw_available {
        # If this is not the right target then we can skip the test.
-       if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
+       if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
            expr 0
        } else {
            check_runtime_nocache sse4_hw_available {
@@ -1678,7 +1736,7 @@ proc check_sse4_hw_available { } {
 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-*-*]) } {
+       if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
            expr 0
        } else {
            check_runtime_nocache avx_hw_available {
@@ -1696,6 +1754,36 @@ proc check_avx_hw_available { } {
     }]
 }
 
+# Return 1 if the target supports executing AVX2 instructions, 0
+# otherwise.  Cache the result.
+
+proc check_avx2_hw_available { } {
+    return [check_cached_effective_target avx2_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 avx2_hw_available {
+               #include "cpuid.h"
+               int main ()
+               {
+                 unsigned int eax, ebx, ecx, edx;
+                 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)
+                     || ((ecx & bit_OSXSAVE) != bit_OSXSAVE))
+                   return 1;
+
+                 if (__get_cpuid_max (0, NULL) < 7)
+                   return 1;
+
+                 __cpuid_count (7, 0, eax, ebx, ecx, edx);
+
+                 return (ebx & bit_AVX2) != bit_AVX2;
+               }
+           } ""
+       }
+    }]
+}
+
 # Return 1 if the target supports running SSE executables, 0 otherwise.
 
 proc check_effective_target_sse_runtime { } {
@@ -1750,6 +1838,16 @@ proc check_effective_target_mips_loongson_runtime { } {
     return 0
 }
 
+# Return 1 if the target supports running MIPS MSA executables, 0 otherwise.
+
+proc check_effective_target_mips_msa_runtime { } {
+  if { [check_effective_target_mips_msa]
+       && [check_mips_msa_hw_available] } {
+    return 1
+  }
+  return 0
+}
+
 # Return 1 if the target supports running AVX executables, 0 otherwise.
 
 proc check_effective_target_avx_runtime { } {
@@ -1761,6 +1859,17 @@ proc check_effective_target_avx_runtime { } {
     return 0
 }
 
+# Return 1 if the target supports running AVX2 executables, 0 otherwise.
+
+proc check_effective_target_avx2_runtime { } {
+    if { [check_effective_target_avx2]
+        && [check_avx2_hw_available]
+        && [check_avx_os_support_available] } {
+       return 1
+    }
+    return 0
+}
+
 # Return 1 if we are compiling for 64-bit PowerPC but we do not use direct
 # move instructions for moves from GPR to FPR.
 
@@ -2439,43 +2548,43 @@ proc check_effective_target_has_q_floating_suffix { } {
 proc check_effective_target_float16 {} {
     return [check_no_compiler_messages_nocache float16 object {
         _Float16 x;
-    }]
+    } [add_options_for_float16 ""]]
 }
 
 proc check_effective_target_float32 {} {
     return [check_no_compiler_messages_nocache float32 object {
         _Float32 x;
-    }]
+    } [add_options_for_float32 ""]]
 }
 
 proc check_effective_target_float64 {} {
     return [check_no_compiler_messages_nocache float64 object {
         _Float64 x;
-    }]
+    } [add_options_for_float64 ""]]
 }
 
 proc check_effective_target_float128 {} {
     return [check_no_compiler_messages_nocache float128 object {
         _Float128 x;
-    }]
+    } [add_options_for_float128 ""]]
 }
 
 proc check_effective_target_float32x {} {
     return [check_no_compiler_messages_nocache float32x object {
         _Float32x x;
-    }]
+    } [add_options_for_float32x ""]]
 }
 
 proc check_effective_target_float64x {} {
     return [check_no_compiler_messages_nocache float64x object {
         _Float64x x;
-    }]
+    } [add_options_for_float64x ""]]
 }
 
 proc check_effective_target_float128x {} {
     return [check_no_compiler_messages_nocache float128x object {
         _Float128x x;
-    }]
+    } [add_options_for_float128x ""]]
 }
 
 # Likewise, but runtime support for any special options used as well
@@ -2525,6 +2634,9 @@ proc check_effective_target_float128x_runtime {} {
 # _FloatN and _FloatNx types, 0 otherwise.
 
 proc check_effective_target_floatn_nx_runtime {} {
+    if { [istarget powerpc*-*-aix*] } {
+       return 0
+    }
     if { [istarget powerpc*-*-*] } {
        return [check_effective_target_base_quadfloat_support]
     }
@@ -2535,6 +2647,9 @@ proc check_effective_target_floatn_nx_runtime {} {
 # the function name.
 
 proc add_options_for_float16 { flags } {
+    if { [istarget arm*-*-*] } {
+       return "$flags -mfp16-format=ieee"
+    }
     return "$flags"
 }
 
@@ -2570,8 +2685,7 @@ proc check_effective_target___float128 { } {
        return [check_ppc_float128_sw_available]
     }
     if { [istarget ia64-*-*]
-        || [istarget i?86-*-*]
-        || [istarget x86_64-*-*] } {
+        || [istarget i?86-*-*] || [istarget x86_64-*-*] } {
        return 1
     }
     return 0
@@ -2646,6 +2760,26 @@ proc check_effective_target_dfprt { } {
     }]
 }
 
+proc check_effective_target_powerpc_popcntb_ok { } {
+    return [check_cached_effective_target powerpc_popcntb_ok {
+
+       # Disable on Darwin.
+       if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
+           expr 0
+       } else {
+           check_runtime_nocache powerpc_popcntb_ok {
+               volatile int r;
+               volatile int a = 0x12345678;
+               int main()
+               {
+                   asm volatile ("popcntb %0,%1" : "=r" (r) : "r" (a));
+                   return 0;
+               }
+           } "-mcpu=power5"
+       }
+    }]
+}
+
 # Return 1 if the target supports executing DFP hardware instructions,
 # 0 otherwise.  Cache the result.
 
@@ -2727,9 +2861,8 @@ proc check_effective_target_vect_cmdline_needed { } {
        set et_vect_cmdline_needed_saved 1
        if { [istarget alpha*-*-*]
             || [istarget ia64-*-*]
-            || (([istarget x86_64-*-*] || [istarget i?86-*-*])
-                && ([check_effective_target_x32]
-                    || [check_effective_target_lp64]))
+            || (([istarget i?86-*-*] || [istarget x86_64-*-*])
+                && ![is-effective-target ia32])
             || ([istarget powerpc*-*-*]
                 && ([check_effective_target_powerpc_spe]
                     || [check_effective_target_powerpc_altivec]))
@@ -2759,15 +2892,16 @@ proc check_effective_target_vect_int { } {
        set et_vect_int_saved($et_index) 0
        if { [istarget i?86-*-*] || [istarget x86_64-*-*]
              || ([istarget powerpc*-*-*]
-                  && ![istarget powerpc-*-linux*paired*])
-             || [istarget spu-*-*]
-             || [istarget sparc*-*-*]
-             || [istarget alpha*-*-*]
-             || [istarget ia64-*-*] 
-             || [istarget aarch64*-*-*]
-             || [check_effective_target_arm32]
-             || ([istarget mips*-*-*]
-                 && [et-is-effective-target mips_loongson]) } {
+                && ![istarget powerpc-*-linux*paired*])
+            || [istarget spu-*-*]
+            || [istarget sparc*-*-*]
+            || [istarget alpha*-*-*]
+            || [istarget ia64-*-*] 
+            || [istarget aarch64*-*-*]
+            || [check_effective_target_arm32]
+            || ([istarget mips*-*-*]
+                && ([et-is-effective-target mips_loongson]
+                    || [et-is-effective-target mips_msa])) } {
            set et_vect_int_saved($et_index) 1
        }
     }
@@ -2790,11 +2924,13 @@ proc check_effective_target_vect_intfloat_cvt { } {
     } else {
        set et_vect_intfloat_cvt_saved($et_index) 0
         if { [istarget i?86-*-*] || [istarget x86_64-*-*]
-              || ([istarget powerpc*-*-*]
-                   && ![istarget powerpc-*-linux*paired*])
-              || ([istarget arm*-*-*]
-                  && [check_effective_target_arm_neon_ok])} {
-          set et_vect_intfloat_cvt_saved($et_index) 1
+            || ([istarget powerpc*-*-*]
+                && ![istarget powerpc-*-linux*paired*])
+            || ([istarget arm*-*-*]
+                && [check_effective_target_arm_neon_ok])
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa]) } {
+           set et_vect_intfloat_cvt_saved($et_index) 1
         }
     }
 
@@ -2830,12 +2966,14 @@ proc check_effective_target_vect_uintfloat_cvt { } {
     } else {
        set et_vect_uintfloat_cvt_saved($et_index) 0
         if { [istarget i?86-*-*] || [istarget x86_64-*-*]
-             || ([istarget powerpc*-*-*]
-                 && ![istarget powerpc-*-linux*paired*])
-             || [istarget aarch64*-*-*]
-             || ([istarget arm*-*-*]
-                 && [check_effective_target_arm_neon_ok])} {
-          set et_vect_uintfloat_cvt_saved($et_index) 1
+            || ([istarget powerpc*-*-*]
+                && ![istarget powerpc-*-linux*paired*])
+            || [istarget aarch64*-*-*]
+            || ([istarget arm*-*-*]
+                && [check_effective_target_arm_neon_ok])
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa]) } {
+           set et_vect_uintfloat_cvt_saved($et_index) 1
         }
     }
 
@@ -2858,11 +2996,13 @@ proc check_effective_target_vect_floatint_cvt { } {
     } else {
        set et_vect_floatint_cvt_saved($et_index) 0
         if { [istarget i?86-*-*] || [istarget x86_64-*-*]
-              || ([istarget powerpc*-*-*]
-                   && ![istarget powerpc-*-linux*paired*])
-              || ([istarget arm*-*-*]
-                  && [check_effective_target_arm_neon_ok])} {
-          set et_vect_floatint_cvt_saved($et_index) 1
+            || ([istarget powerpc*-*-*]
+                && ![istarget powerpc-*-linux*paired*])
+            || ([istarget arm*-*-*]
+                && [check_effective_target_arm_neon_ok])
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa]) } {
+           set et_vect_floatint_cvt_saved($et_index) 1
         }
     }
 
@@ -2886,7 +3026,9 @@ proc check_effective_target_vect_floatuint_cvt { } {
         if { ([istarget powerpc*-*-*]
              && ![istarget powerpc-*-linux*paired*])
            || ([istarget arm*-*-*]
-               && [check_effective_target_arm_neon_ok])} {
+               && [check_effective_target_arm_neon_ok])
+           || ([istarget mips*-*-*]
+               && [et-is-effective-target mips_msa]) } {
           set et_vect_floatuint_cvt_saved($et_index) 1
         }
     }
@@ -2908,14 +3050,13 @@ proc check_effective_target_vect_simd_clones { } {
        verbose "check_effective_target_vect_simd_clones: using cached result" 2
     } else {
        set et_vect_simd_clones_saved($et_index) 0
-       if { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
-           # On i?86/x86_64 #pragma omp declare simd builds a sse2, avx, avx2
-           # and avx512f clone.  Only the right clone for the specified arch
-           # will be chosen, but still we need to at least be able to assemble
-           # avx512f.
-           if { [check_effective_target_avx512f] } {
-               set et_vect_simd_clones_saved($et_index) 1
-           }
+       # On i?86/x86_64 #pragma omp declare simd builds a sse2, avx,
+       # avx2 and avx512f clone.  Only the right clone for the
+       # specified arch will be chosen, but still we need to at least
+       # be able to assemble avx512f.
+       if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
+             && [check_effective_target_avx512f]) } {
+           set et_vect_simd_clones_saved($et_index) 1
        }
     }
 
@@ -3215,6 +3356,28 @@ proc add_options_for_arm_v8_1a_neon { flags } {
     return "$flags $et_arm_v8_1a_neon_flags -march=armv8.1-a"
 }
 
+# Add the options needed for ARMv8.2 with the scalar FP16 extension.
+# Also adds the ARMv8 FP options for ARM and for AArch64.
+
+proc add_options_for_arm_v8_2a_fp16_scalar { flags } {
+    if { ! [check_effective_target_arm_v8_2a_fp16_scalar_ok] } {
+       return "$flags"
+    }
+    global et_arm_v8_2a_fp16_scalar_flags
+    return "$flags $et_arm_v8_2a_fp16_scalar_flags"
+}
+
+# Add the options needed for ARMv8.2 with the FP16 extension.  Also adds
+# the ARMv8 NEON options for ARM and for AArch64.
+
+proc add_options_for_arm_v8_2a_fp16_neon { flags } {
+    if { ! [check_effective_target_arm_v8_2a_fp16_neon_ok] } {
+       return "$flags"
+    }
+    global et_arm_v8_2a_fp16_neon_flags
+    return "$flags $et_arm_v8_2a_fp16_neon_flags"
+}
+
 proc add_options_for_arm_crc { flags } {
     if { ! [check_effective_target_arm_crc_ok] } {
         return "$flags"
@@ -3356,6 +3519,65 @@ proc add_options_for_arm_neon_fp16 { flags } {
     return "$flags $et_arm_neon_fp16_flags"
 }
 
+# Return 1 if this is an ARM target supporting the FP16 alternative
+# format.  Some multilibs may be incompatible with the options needed.  Also
+# set et_arm_neon_fp16_flags to the best options to add.
+
+proc check_effective_target_arm_fp16_alternative_ok_nocache { } {
+    global et_arm_neon_fp16_flags
+    set et_arm_neon_fp16_flags ""
+    if { [check_effective_target_arm32] } {
+       foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16"
+                      "-mfpu=neon-fp16 -mfloat-abi=softfp"} {
+           if { [check_no_compiler_messages_nocache \
+                     arm_fp16_alternative_ok object {
+               #if !defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+               #error __ARM_FP16_FORMAT_ALTERNATIVE not defined
+               #endif
+           } "$flags -mfp16-format=alternative"] } {
+               set et_arm_neon_fp16_flags "$flags -mfp16-format=alternative"
+               return 1
+           }
+       }
+    }
+
+    return 0
+}
+
+proc check_effective_target_arm_fp16_alternative_ok { } {
+    return [check_cached_effective_target arm_fp16_alternative_ok \
+               check_effective_target_arm_fp16_alternative_ok_nocache]
+}
+
+# Return 1 if this is an ARM target supports specifying the FP16 none
+# format.  Some multilibs may be incompatible with the options needed.
+
+proc check_effective_target_arm_fp16_none_ok_nocache { } {
+    if { [check_effective_target_arm32] } {
+       foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16"
+                      "-mfpu=neon-fp16 -mfloat-abi=softfp"} {
+           if { [check_no_compiler_messages_nocache \
+                     arm_fp16_none_ok object {
+               #if defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+               #error __ARM_FP16_FORMAT_ALTERNATIVE defined
+               #endif
+               #if defined (__ARM_FP16_FORMAT_IEEE)
+               #error __ARM_FP16_FORMAT_IEEE defined
+               #endif
+           } "$flags -mfp16-format=none"] } {
+               return 1
+           }
+       }
+    }
+
+    return 0
+}
+
+proc check_effective_target_arm_fp16_none_ok { } {
+    return [check_cached_effective_target arm_fp16_none_ok \
+               check_effective_target_arm_fp16_none_ok_nocache]
+}
+
 # Return 1 if this is an ARM target supporting -mfpu=neon-fp-armv8
 # -mfloat-abi=softfp or equivalent options.  Some multilibs may be
 # incompatible with these options.  Also set et_arm_v8_neon_flags to the
@@ -3540,24 +3762,26 @@ proc check_effective_target_arm_fp16_hw { } {
 # 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__
-                                    v8a "-march=armv8-a" __ARM_ARCH_8A__
-                                    v8_1a "-march=armv8.1a" __ARM_ARCH_8A__
-                                    v8m_base "-march=armv8-m.base -mthumb" __ARM_ARCH_8M_BASE__
-                                    v8m_main "-march=armv8-m.main -mthumb" __ARM_ARCH_8M_MAIN__ } {
+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 -mfloat-abi=soft" __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__
+       v8a "-march=armv8-a" __ARM_ARCH_8A__
+       v8_1a "-march=armv8.1a" __ARM_ARCH_8A__
+       v8_2a "-march=armv8.2a" __ARM_ARCH_8A__
+       v8m_base "-march=armv8-m.base -mthumb -mfloat-abi=soft" __ARM_ARCH_8M_BASE__
+       v8m_main "-march=armv8-m.main -mthumb" __ARM_ARCH_8M_MAIN__ } {
     eval [string map [list FUNC $armfunc FLAG $armflag DEF $armdef ] {
        proc check_effective_target_arm_arch_FUNC_ok { } {
            if { [ string match "*-marm*" "FLAG" ] &&
@@ -3607,6 +3831,12 @@ proc add_options_for_arm_arch_v7ve { flags } {
     return "$flags -march=armv7ve"
 }
 
+# Return 1 if GCC was configured with --with-mode=
+proc check_effective_target_default_mode { } {
+
+    return [check_configured_with "with-mode="]
+}
+
 # Return 1 if this is an ARM target where -marm causes ARM to be
 # used (not Thumb)
 
@@ -3726,6 +3956,19 @@ proc check_effective_target_arm_thumb1_cbz_ok {} {
     }
 }
 
+# Return 1 if this is an ARM target where ARMv8-M Security Extensions is
+# available.
+
+proc check_effective_target_arm_cmse_ok {} {
+    return [check_no_compiler_messages arm_cmse object {
+       int
+       foo (void)
+       {
+         asm ("bxns r0");
+       }
+    } "-mcmse"];
+}
+
 # Return 1 if this compilation turns on string_ops_prefer_neon on.
 
 proc check_effective_target_arm_tune_string_ops_prefer_neon { } {
@@ -3801,6 +4044,76 @@ proc check_effective_target_arm_v8_1a_neon_ok { } {
                check_effective_target_arm_v8_1a_neon_ok_nocache]
 }
 
+# Return 1 if the target supports ARMv8.2 scalar FP16 arithmetic
+# instructions, 0 otherwise.  The test is valid for ARM and for AArch64.
+# Record the command line options needed.
+
+proc check_effective_target_arm_v8_2a_fp16_scalar_ok_nocache { } {
+    global et_arm_v8_2a_fp16_scalar_flags
+    set et_arm_v8_2a_fp16_scalar_flags ""
+
+    if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
+       return 0;
+    }
+
+    # Iterate through sets of options to find the compiler flags that
+    # need to be added to the -march option.
+    foreach flags {"" "-mfpu=fp-armv8" "-mfloat-abi=softfp" \
+                      "-mfpu=fp-armv8 -mfloat-abi=softfp"} {
+       if { [check_no_compiler_messages_nocache \
+                 arm_v8_2a_fp16_scalar_ok object {
+           #if !defined (__ARM_FEATURE_FP16_SCALAR_ARITHMETIC)
+           #error "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC not defined"
+           #endif
+       } "$flags -march=armv8.2-a+fp16"] } {
+           set et_arm_v8_2a_fp16_scalar_flags "$flags -march=armv8.2-a+fp16"
+           return 1
+       }
+    }
+
+    return 0;
+}
+
+proc check_effective_target_arm_v8_2a_fp16_scalar_ok { } {
+    return [check_cached_effective_target arm_v8_2a_fp16_scalar_ok \
+               check_effective_target_arm_v8_2a_fp16_scalar_ok_nocache]
+}
+
+# Return 1 if the target supports ARMv8.2 Adv.SIMD FP16 arithmetic
+# instructions, 0 otherwise.  The test is valid for ARM and for AArch64.
+# Record the command line options needed.
+
+proc check_effective_target_arm_v8_2a_fp16_neon_ok_nocache { } {
+    global et_arm_v8_2a_fp16_neon_flags
+    set et_arm_v8_2a_fp16_neon_flags ""
+
+    if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
+       return 0;
+    }
+
+    # Iterate through sets of options to find the compiler flags that
+    # need to be added to the -march option.
+    foreach flags {"" "-mfpu=neon-fp-armv8" "-mfloat-abi=softfp" \
+                      "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} {
+       if { [check_no_compiler_messages_nocache \
+                 arm_v8_2a_fp16_neon_ok object {
+           #if !defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
+           #error "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC not defined"
+           #endif
+       } "$flags -march=armv8.2-a+fp16"] } {
+           set et_arm_v8_2a_fp16_neon_flags "$flags -march=armv8.2-a+fp16"
+           return 1
+       }
+    }
+
+    return 0;
+}
+
+proc check_effective_target_arm_v8_2a_fp16_neon_ok { } {
+    return [check_cached_effective_target arm_v8_2a_fp16_neon_ok \
+               check_effective_target_arm_v8_2a_fp16_neon_ok_nocache]
+}
+
 # Return 1 if the target supports executing ARMv8 NEON instructions, 0
 # otherwise.
 
@@ -3863,6 +4176,81 @@ proc check_effective_target_arm_v8_1a_neon_hw { } {
     } [add_options_for_arm_v8_1a_neon ""]]
 }
 
+# Return 1 if the target supports executing floating point instructions from
+# ARMv8.2 with the FP16 extension, 0 otherwise.  The test is valid for ARM and
+# for AArch64.
+
+proc check_effective_target_arm_v8_2a_fp16_scalar_hw { } {
+    if { ![check_effective_target_arm_v8_2a_fp16_scalar_ok] } {
+       return 0;
+    }
+    return [check_runtime arm_v8_2a_fp16_scalar_hw_available {
+       int
+       main (void)
+       {
+         __fp16 a = 1.0;
+         __fp16 result;
+
+         #ifdef __ARM_ARCH_ISA_A64
+
+         asm ("fabs %h0, %h1"
+              : "=w"(result)
+              : "w"(a)
+              : /* No clobbers.  */);
+
+         #else
+
+         asm ("vabs.f16 %0, %1"
+              : "=w"(result)
+              : "w"(a)
+              : /* No clobbers.  */);
+
+         #endif
+
+         return (result == 1.0) ? 0 : 1;
+       }
+    } [add_options_for_arm_v8_2a_fp16_scalar ""]]
+}
+
+# Return 1 if the target supports executing Adv.SIMD instructions from ARMv8.2
+# with the FP16 extension, 0 otherwise.  The test is valid for ARM and for
+# AArch64.
+
+proc check_effective_target_arm_v8_2a_fp16_neon_hw { } {
+    if { ![check_effective_target_arm_v8_2a_fp16_neon_ok] } {
+       return 0;
+    }
+    return [check_runtime arm_v8_2a_fp16_neon_hw_available {
+       int
+       main (void)
+       {
+         #ifdef __ARM_ARCH_ISA_A64
+
+         __Float16x4_t a = {1.0, -1.0, 1.0, -1.0};
+         __Float16x4_t result;
+
+         asm ("fabs %0.4h, %1.4h"
+              : "=w"(result)
+              : "w"(a)
+              : /* No clobbers.  */);
+
+         #else
+
+         __simd64_float16_t a = {1.0, -1.0, 1.0, -1.0};
+         __simd64_float16_t result;
+
+         asm ("vabs.f16 %P0, %P1"
+              : "=w"(result)
+              : "w"(a)
+              : /* No clobbers.  */);
+
+         #endif
+
+         return (result[0] == 1.0) ? 0 : 1;
+       }
+    } [add_options_for_arm_v8_2a_fp16_neon ""]]
+}
+
 # Return 1 if this is a ARM target with NEON enabled.
 
 proc check_effective_target_arm_neon { } {
@@ -3925,6 +4313,15 @@ proc add_options_for_mpaired_single { flags } {
     return "$flags -mpaired-single"
 }
 
+# Add the options needed for MIPS SIMD Architecture.
+
+proc add_options_for_mips_msa { flags } {
+  if { ! [check_effective_target_mips_msa] } {
+    return "$flags"
+  }
+  return "$flags -mmsa"
+}
+
 # Return 1 if this a Loongson-2E or -2F target using an ABI that supports
 # the Loongson vector modes.
 
@@ -3945,6 +4342,37 @@ proc check_effective_target_mips_nanlegacy { } {
     } "-mnan=legacy"]
 }
 
+# Return 1 if an MSA program can be compiled to object
+
+proc check_effective_target_mips_msa { } {
+  if ![check_effective_target_nomips16] {
+    return 0
+  }
+  return [check_no_compiler_messages msa object {
+    #if !defined(__mips_msa)
+    #error "MSA NOT AVAIL"
+    #else
+    #if !(((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2))
+    #error "MSA NOT AVAIL FOR ISA REV < 2"
+    #endif
+    #if !defined(__mips_hard_float)
+    #error "MSA HARD_FLOAT REQUIRED"
+    #endif
+    #if __mips_fpr != 64
+    #error "MSA 64-bit FPR REQUIRED"
+    #endif
+    #include <msa.h>
+
+    int main()
+    {
+      v8i16 v = __builtin_msa_ldi_h (1);
+
+      return v[0];
+    }
+    #endif
+  } "-mmsa" ]
+}
+
 # Return 1 if this is an ARM target that adheres to the ABI for the ARM
 # Architecture.
 
@@ -3992,7 +4420,7 @@ proc check_effective_target_arm_prefer_ldrd_strd { } {
     }
 
     return [check_no_messages_and_pattern arm_prefer_ldrd_strd "strd\tr" assembly {
-        void foo (int *p) { p[0] = 1; p[1] = 0;}
+        void foo (void) { __asm__ ("" ::: "r4", "r5"); }
     }  "-O2 -mthumb" ]
 }
 
@@ -4453,13 +4881,14 @@ proc check_effective_target_vect_shift { } {
     } else {
        set et_vect_shift_saved($et_index) 0
        if { ([istarget powerpc*-*-*]
-             && ![istarget powerpc-*-linux*paired*])
+             && ![istarget powerpc-*-linux*paired*])
             || [istarget ia64-*-*]
             || [istarget i?86-*-*] || [istarget x86_64-*-*]
             || [istarget aarch64*-*-*]
             || [check_effective_target_arm32]
             || ([istarget mips*-*-*]
-               && [et-is-effective-target mips_loongson]) } {
+                && ([et-is-effective-target mips_msa]
+                    || [et-is-effective-target mips_loongson])) } {
           set et_vect_shift_saved($et_index) 1
        }
     }
@@ -4522,7 +4951,9 @@ proc check_effective_target_vect_shift_char { } {
        set et_vect_shift_char_saved($et_index) 0
        if { ([istarget powerpc*-*-*]
              && ![istarget powerpc-*-linux*paired*])
-            || [check_effective_target_arm32] } {
+            || [check_effective_target_arm32]
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa]) } {
           set et_vect_shift_char_saved($et_index) 1
        }
     }
@@ -4543,7 +4974,9 @@ proc check_effective_target_vect_long { } {
               && [check_effective_target_ilp32])
         || [check_effective_target_arm32]
         || ([istarget sparc*-*-*] && [check_effective_target_ilp32])
-        || [istarget aarch64*-*-*] } {
+        || [istarget aarch64*-*-*]
+        || ([istarget mips*-*-*]
+             && [et-is-effective-target mips_msa]) } {
        set answer 1
     } else {
        set answer 0
@@ -4566,14 +4999,16 @@ proc check_effective_target_vect_float { } {
     } else {
        set et_vect_float_saved($et_index) 0
        if { [istarget i?86-*-*] || [istarget x86_64-*-*]
-             || [istarget powerpc*-*-*]
-             || [istarget spu-*-*]
-             || [istarget mips-sde-elf]
-             || [istarget mipsisa64*-*-*]
-             || [istarget ia64-*-*]
-             || [istarget aarch64*-*-*]
-             || [check_effective_target_arm32] } {
-          set et_vect_float_saved($et_index) 1
+            || [istarget powerpc*-*-*]
+            || [istarget spu-*-*]
+            || [istarget mips-sde-elf]
+            || [istarget mipsisa64*-*-*]
+            || [istarget ia64-*-*]
+            || [istarget aarch64*-*-*]
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa])
+            || [check_effective_target_arm32] } {
+           set et_vect_float_saved($et_index) 1
        }
     }
 
@@ -4594,21 +5029,18 @@ proc check_effective_target_vect_double { } {
        verbose "check_effective_target_vect_double: using cached result" 2
     } else {
        set et_vect_double_saved($et_index) 0
-       if { [istarget i?86-*-*] || [istarget x86_64-*-*]
-            || [istarget aarch64*-*-*] } {
-          if { [check_no_compiler_messages vect_double assembly {
-                #ifdef __tune_atom__
-                # error No double vectorizer support.
-                #endif
-               }] } {
-               set et_vect_double_saved($et_index) 1
-           } else {
-               set et_vect_double_saved($et_index) 0
-           }
-       } elseif { [istarget spu-*-*] } {
-          set et_vect_double_saved($et_index) 1
-       } elseif { [istarget powerpc*-*-*] && [check_vsx_hw_available] } {
-          set et_vect_double_saved($et_index) 1
+       if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
+             && [check_no_compiler_messages vect_double assembly {
+                 #ifdef __tune_atom__
+                 # error No double vectorizer support.
+                 #endif
+             }])
+            || [istarget aarch64*-*-*]
+            || [istarget spu-*-*]
+            || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa]) } {
+           set et_vect_double_saved($et_index) 1
        }
     }
 
@@ -4629,7 +5061,9 @@ proc check_effective_target_vect_long_long { } {
         verbose "check_effective_target_vect_long_long: using cached result" 2
     } else {
        set et_vect_long_long_saved($et_index) 0
-       if { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
+       if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa]) } {
           set et_vect_long_long_saved($et_index) 1
         }
     }
@@ -4728,7 +5162,8 @@ proc check_effective_target_vect_perm { } {
              || [istarget spu-*-*]
             || [istarget i?86-*-*] || [istarget x86_64-*-*]
             || ([istarget mips*-*-*]
-                && [et-is-effective-target mpaired_single]) } {
+                && ([et-is-effective-target mpaired_single]
+                    || [et-is-effective-target mips_msa])) } {
            set et_vect_perm_saved($et_index) 1
         }
     }
@@ -4755,7 +5190,9 @@ proc check_effective_target_vect_perm_byte { } {
             || ([istarget aarch64*-*-*]
                 && [is-effective-target aarch64_little_endian])
             || [istarget powerpc*-*-*]
-             || [istarget spu-*-*] } {
+            || [istarget spu-*-*]
+            || ([istarget mips-*.*]
+                && [et-is-effective-target mips_msa]) } {
            set et_vect_perm_byte_saved($et_index) 1
         }
     }
@@ -4782,7 +5219,9 @@ proc check_effective_target_vect_perm_short { } {
             || ([istarget aarch64*-*-*]
                 && [is-effective-target aarch64_little_endian])
             || [istarget powerpc*-*-*]
-             || [istarget spu-*-*] } {
+            || [istarget spu-*-*]
+            || ([istarget mips*-*-*]
+                 && [et-is-effective-target mips_msa]) } {
            set et_vect_perm_short_saved($et_index) 1
         }
     }
@@ -4953,12 +5392,12 @@ proc check_effective_target_vect_widen_mult_hi_to_si { } {
          set et_vect_widen_mult_hi_to_si_saved($et_index) 0
         }
         if { [istarget powerpc*-*-*]
-             || [istarget spu-*-*]
-             || [istarget ia64-*-*]
-             || [istarget aarch64*-*-*]
-             || [istarget i?86-*-*] || [istarget x86_64-*-*]
-             || ([istarget arm*-*-*]
-                 && [check_effective_target_arm_neon_ok]) } {
+            || [istarget spu-*-*]
+            || [istarget ia64-*-*]
+            || [istarget aarch64*-*-*]
+            || [istarget i?86-*-*] || [istarget x86_64-*-*]
+            || ([istarget arm*-*-*]
+                && [check_effective_target_arm_neon_ok]) } {
            set et_vect_widen_mult_hi_to_si_saved($et_index) 1
         }
     }
@@ -5008,12 +5447,12 @@ proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } {
     } else {
        set et_vect_widen_mult_hi_to_si_pattern_saved($et_index) 0
         if { [istarget powerpc*-*-*]
-              || [istarget spu-*-*]
-              || [istarget ia64-*-*]
-              || [istarget i?86-*-*] || [istarget x86_64-*-*]
-              || ([istarget arm*-*-*]
-                 && [check_effective_target_arm_neon_ok]
-                 && [check_effective_target_arm_little_endian]) } {
+            || [istarget spu-*-*]
+            || [istarget ia64-*-*]
+            || [istarget i?86-*-*] || [istarget x86_64-*-*]
+            || ([istarget arm*-*-*]
+                && [check_effective_target_arm_neon_ok]
+                && [check_effective_target_arm_little_endian]) } {
            set et_vect_widen_mult_hi_to_si_pattern_saved($et_index) 1
         }
     }
@@ -5081,7 +5520,9 @@ proc check_effective_target_vect_sdot_qi { } {
         verbose "check_effective_target_vect_sdot_qi: using cached result" 2
     } else {
        set et_vect_sdot_qi_saved($et_index) 0
-        if { [istarget ia64-*-*] } {
+       if { [istarget ia64-*-*]
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa]) } {
             set et_vect_udot_qi_saved 1
         }
     }
@@ -5104,7 +5545,9 @@ proc check_effective_target_vect_udot_qi { } {
     } else {
        set et_vect_udot_qi_saved($et_index) 0
         if { [istarget powerpc*-*-*]
-             || [istarget ia64-*-*] } {
+            || [istarget ia64-*-*]
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa]) } {
            set et_vect_udot_qi_saved($et_index) 1
         }
     }
@@ -5128,7 +5571,9 @@ proc check_effective_target_vect_sdot_hi { } {
        set et_vect_sdot_hi_saved($et_index) 0
         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
             || [istarget ia64-*-*]
-            || [istarget i?86-*-*] || [istarget x86_64-*-*] } {
+            || [istarget i?86-*-*] || [istarget x86_64-*-*]
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa]) } {
            set et_vect_sdot_hi_saved($et_index) 1
         }
     }
@@ -5150,7 +5595,9 @@ proc check_effective_target_vect_udot_hi { } {
         verbose "check_effective_target_vect_udot_hi: using cached result" 2
     } else {
        set et_vect_udot_hi_saved($et_index) 0
-        if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) } {
+       if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa]) } {
            set et_vect_udot_hi_saved($et_index) 1
         }
     }
@@ -5172,7 +5619,7 @@ proc check_effective_target_vect_usad_char { } {
         verbose "check_effective_target_vect_usad_char: using cached result" 2
     } else {
        set et_vect_usad_char_saved($et_index) 0
-        if { ([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
+        if { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
            set et_vect_usad_char_saved($et_index) 1
         }
     }
@@ -5200,7 +5647,9 @@ proc check_effective_target_vect_pack_trunc { } {
              || [istarget aarch64*-*-*]
              || [istarget spu-*-*]
              || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]
-                && [check_effective_target_arm_little_endian]) } {
+                && [check_effective_target_arm_little_endian])
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa]) } {
            set et_vect_pack_trunc_saved($et_index) 1
         }
     }
@@ -5227,6 +5676,8 @@ proc check_effective_target_vect_unpack { } {
              || [istarget spu-*-*]
              || [istarget ia64-*-*]
              || [istarget aarch64*-*-*]
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa])
              || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]
                 && [check_effective_target_arm_little_endian]) } {
            set et_vect_unpack_saved($et_index) 1
@@ -5297,9 +5748,13 @@ proc check_effective_target_vect_hw_misalign { } {
        set et_vect_hw_misalign_saved($et_index) 0
        if { [istarget i?86-*-*] || [istarget x86_64-*-*]
             || ([istarget powerpc*-*-*] && [check_p8vector_hw_available])
-            || [istarget aarch64*-*-*] } {
+            || [istarget aarch64*-*-*]
+            || ([istarget mips*-*-*] && [et-is-effective-target mips_msa]) } {
          set et_vect_hw_misalign_saved($et_index) 1
        }
+       if { [istarget arm*-*-*] } {
+           set et_vect_hw_misalign_saved($et_index) [check_effective_target_arm_vect_no_misalign]
+       }
     }
     verbose "check_effective_target_vect_hw_misalign:\
             returning $et_vect_hw_misalign_saved($et_index)" 2
@@ -5312,16 +5767,13 @@ proc check_effective_target_vect_hw_misalign { } {
 
 proc check_effective_target_vect_aligned_arrays { } {
     set et_vect_aligned_arrays 0
-    if { ([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
-       if { ([is-effective-target lp64]
-             && ( ![check_avx_available]
-                || [check_prefer_avx128])) } {
-            set et_vect_aligned_arrays 1
-       }
-    }
-    if [istarget spu-*-*] {
+    if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
+         && !([is-effective-target ia32]
+              || ([check_avx_available] && ![check_prefer_avx128])))
+        || [istarget spu-*-*] } {
        set et_vect_aligned_arrays 1
     }
+
     verbose "check_effective_target_vect_aligned_arrays:\
             returning $et_vect_aligned_arrays" 2
     return $et_vect_aligned_arrays
@@ -5468,6 +5920,8 @@ proc check_effective_target_vect_condition { } {
             || [istarget ia64-*-*]
             || [istarget i?86-*-*] || [istarget x86_64-*-*]
             || [istarget spu-*-*]
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa])
             || ([istarget arm*-*-*]
                 && [check_effective_target_arm_neon_ok]) } {
           set et_vect_cond_saved($et_index) 1
@@ -5492,7 +5946,9 @@ proc check_effective_target_vect_cond_mixed { } {
        set et_vect_cond_mixed_saved($et_index) 0
        if { [istarget i?86-*-*] || [istarget x86_64-*-*]
             || [istarget aarch64*-*-*]
-            || [istarget powerpc*-*-*] } {
+            || [istarget powerpc*-*-*] 
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa]) } {
           set et_vect_cond_mixed_saved($et_index) 1
        }
     }
@@ -5515,8 +5971,10 @@ proc check_effective_target_vect_char_mult { } {
        if { [istarget aarch64*-*-*]
             || [istarget ia64-*-*]
             || [istarget i?86-*-*] || [istarget x86_64-*-*]
-             || [check_effective_target_arm32]
-            || [check_effective_target_powerpc_altivec] } {
+            || [check_effective_target_arm32]
+            || [check_effective_target_powerpc_altivec]
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa]) } {
           set et_vect_char_mult_saved($et_index) 1
        }
     }
@@ -5543,7 +6001,8 @@ proc check_effective_target_vect_short_mult { } {
             || [istarget aarch64*-*-*]
             || [check_effective_target_arm32]
             || ([istarget mips*-*-*]
-                && [et-is-effective-target mips_loongson]) } {
+                && ([et-is-effective-target mips_msa]
+                    || [et-is-effective-target mips_loongson])) } {
           set et_vect_short_mult_saved($et_index) 1
        }
     }
@@ -5568,6 +6027,8 @@ proc check_effective_target_vect_int_mult { } {
             || [istarget i?86-*-*] || [istarget x86_64-*-*]
             || [istarget ia64-*-*]
             || [istarget aarch64*-*-*]
+            || ([istarget mips*-*-*]
+                && [et-is-effective-target mips_msa])
             || [check_effective_target_arm32] } {
           set et_vect_int_mult_saved($et_index) 1
        }
@@ -5596,7 +6057,8 @@ proc check_effective_target_vect_extract_even_odd { } {
              || [istarget ia64-*-*]
              || [istarget spu-*-*]
             || ([istarget mips*-*-*]
-                && [et-is-effective-target mpaired_single]) } {
+                && ([et-is-effective-target mips_msa]
+                    || [et-is-effective-target mpaired_single])) } {
            set et_vect_extract_even_odd_saved($et_index) 1
         }
     }
@@ -5623,8 +6085,9 @@ proc check_effective_target_vect_interleave { } {
              || [istarget ia64-*-*]
              || [istarget spu-*-*]
             || ([istarget mips*-*-*]
-                && [et-is-effective-target mpaired_single]) } {
-          set et_vect_interleave_saved($et_index) 1
+                && ([et-is-effective-target mpaired_single]
+                    || [et-is-effective-target mips_msa])) } {
+           set et_vect_interleave_saved($et_index) 1
         }
     }
 
@@ -5670,14 +6133,11 @@ proc check_effective_target_vect_multiple_sizes { } {
     global et_index
 
     set et_vect_multiple_sizes_saved($et_index) 0
-    if { ([istarget aarch64*-*-*]
-         || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok])) } {
-       set et_vect_multiple_sizes_saved($et_index) 1
-    }
-    if { ([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
-      if { ([check_avx_available] && ![check_prefer_avx128]) } {
+    if { [istarget aarch64*-*-*]
+        || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok])
+        || (([istarget i?86-*-*] || [istarget x86_64-*-*])
+            && ([check_avx_available] && ![check_prefer_avx128])) } {
        set et_vect_multiple_sizes_saved($et_index) 1
-      }
     }
 
     verbose "check_effective_target_vect_multiple_sizes:\
@@ -5721,7 +6181,8 @@ proc check_effective_target_vect_call_copysignf { } {
     } else {
        set et_vect_call_copysignf_saved($et_index) 0
        if { [istarget i?86-*-*] || [istarget x86_64-*-*]
-            || [istarget powerpc*-*-*] } {
+            || [istarget powerpc*-*-*]
+            || [istarget aarch64*-*-*] } {
           set et_vect_call_copysignf_saved($et_index) 1
        }
     }
@@ -5740,7 +6201,7 @@ proc check_effective_target_sqrt_insn { } {
        verbose "check_effective_target_hw_sqrt: using cached result" 2
     } else {
        set et_sqrt_insn_saved 0
-       if { [istarget x86_64-*-*]
+       if { [istarget i?86-*-*] || [istarget x86_64-*-*]
             || [istarget powerpc*-*-*]
             || [istarget aarch64*-*-*]
             || ([istarget arm*-*-*] && [check_effective_target_arm_vfp_ok]) } {
@@ -5778,8 +6239,8 @@ proc check_effective_target_vect_call_sqrtf { } {
 
 proc check_effective_target_vect_call_lrint { } {
     set et_vect_call_lrint 0
-    if { ([istarget i?86-*-*] || [istarget x86_64-*-*])
-        && [check_effective_target_ilp32] } {
+    if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
+         && [check_effective_target_ilp32]) } {
        set et_vect_call_lrint 1
     }
 
@@ -6053,10 +6514,7 @@ proc check_effective_target_section_anchors { } {
 # 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
-    } elseif { [istarget spu-*-*] } {
+    if { [istarget spu-*-*] } {
        return 1
     } else {
        return 0
@@ -6065,23 +6523,10 @@ proc check_effective_target_sync_int_128 { } {
 
 # Return 1 if the target supports atomic operations on "int_128" values
 # and can execute them.
+# This requires support for both compare-and-swap and true atomic loads.
 
 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;
-               }
-           } ""
-       }]
-    } elseif { [istarget spu-*-*] } {
+    if { [istarget spu-*-*] } {
        return 1
     } else {
        return 0
@@ -6094,7 +6539,7 @@ proc check_effective_target_sync_int_128_runtime { } {
 # Note: 32bit s390 targets require -mzarch in dg-options.
 
 proc check_effective_target_sync_long_long { } {
-    if { [istarget x86_64-*-*] || [istarget i?86-*-*])
+    if { [istarget i?86-*-*] || [istarget x86_64-*-*])
         || [istarget aarch64*-*-*]
         || [istarget arm*-*-*]
         || [istarget alpha*-*-*]
@@ -6113,46 +6558,43 @@ proc check_effective_target_sync_long_long { } {
 # 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 aarch64*-*-*] } {
-       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);
+    if { (([istarget x86_64-*-*] || [istarget i?86-*-*])
+         && [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;
+                 }
+             } ""
+         }])
+        || [istarget aarch64*-*-*]
+        || ([istarget arm*-*-linux-*]
+            && [check_runtime sync_longlong_runtime {
+                #include <stdlib.h>
+                int main ()
+                {
+                    long long l1;
 
-             /* Just check for native; checking for kernel fallback is tricky.  */
-             asm volatile ("ldrexd r0,r1, [%0]" : : "r" (&l1) : "r0", "r1");
+                    if (sizeof (long long) != 8)
+                    exit (1);
 
-             exit (0);
-           }
-       } "" ]
-    } elseif { [istarget alpha*-*-*] } {
-       return 1
-    } elseif { ([istarget sparc*-*-*]
-                && [check_effective_target_lp64]
-                && [check_effective_target_ultrasparc_hw]) } {
-       return 1
-    } elseif { [istarget spu-*-*] } {
-       return 1
-    } elseif { [istarget powerpc*-*-*] && [check_effective_target_lp64] } {
+                    /* Just check for native;
+                       checking for kernel fallback is tricky.  */
+                    asm volatile ("ldrexd r0,r1, [%0]"
+                                  : : "r" (&l1) : "r0", "r1");
+                    exit (0);
+                }
+            } "" ])
+        || [istarget alpha*-*-*]
+        || ([istarget sparc*-*-*]
+            && [check_effective_target_lp64]
+            && [check_effective_target_ultrasparc_hw])
+        || [istarget spu-*-*]
+        || ([istarget powerpc*-*-*] && [check_effective_target_lp64]) } {
        return 1
     } else {
        return 0
@@ -6174,18 +6616,15 @@ proc check_effective_target_bswap { } {
             || [istarget m68k-*-*]
             || [istarget powerpc*-*-*]
             || [istarget rs6000-*-*]
-            || [istarget s390*-*-*] } {
-           set et_bswap_saved 1
-       } else {
-           if { [istarget arm*-*-*]
+            || [istarget s390*-*-*]
+            || ([istarget arm*-*-*]
                 && [check_no_compiler_messages_nocache arm_v6_or_later object {
                     #if __ARM_ARCH < 6
                     #error not armv6 or later
                     #endif
                     int i;
-                } ""] } {
+                } ""]) } {
                set et_bswap_saved 1
-           }
        }
     }
 
@@ -6355,6 +6794,17 @@ proc check_effective_target_newlib {} {
     }]
 }
 
+# Some newlib versions don't provide a frexpl and instead depend
+# on frexp to implement long double conversions in their printf-like
+# functions.  This leads to broken results.  Detect such versions here.
+
+proc check_effective_target_newlib_broken_long_double_io {} {
+  if { [is-effective-target newlib] && ![is-effective-target frexpl] } {
+       return 1
+  }
+  return 0
+}
+
 # Return true if this is NOT a Bionic target.
 
 proc check_effective_target_non_bionic {} {
@@ -6864,7 +7314,7 @@ proc check_effective_target_avx512f { } {
 # Return 1 if avx instructions can be compiled.
 
 proc check_effective_target_avx { } {
-    if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
+    if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
        return 0
     }
     return [check_no_compiler_messages avx object {
@@ -6970,6 +7420,21 @@ proc check_effective_target_pow10 { } {
     } "-lm" ]
 }
 
+# Return 1 if frexpl function exists.
+
+proc check_effective_target_frexpl { } {
+    return [check_runtime frexpl {
+       #include <math.h>
+       int main () {
+       long double x;
+       int y;
+       x = frexpl (5.0, &y);
+       return 0;
+       }
+    } "-lm" ]
+}
+
+
 # Return 1 if issignaling function exists.
 proc check_effective_target_issignaling {} {
     return [check_runtime issignaling {
@@ -7286,6 +7751,9 @@ proc check_vect_support_and_set_flags { } {
        }
        if { [check_effective_target_mips_loongson] } {
            lappend EFFECTIVE_TARGETS mips_loongson
+       }
+       if { [check_effective_target_mips_msa] } {
+           lappend EFFECTIVE_TARGETS mips_msa
         }
        return [llength $EFFECTIVE_TARGETS]
     } elseif [istarget sparc*-*-*] {
@@ -7417,6 +7885,24 @@ proc check_effective_target_aarch64_large { } {
     }
 }
 
+
+# Return 1 if this is a reduced AVR Tiny core.  Such cores have different
+# register set, instruction set, addressing capabilities and ABI.
+
+proc check_effective_target_avr_tiny { } {
+    if { [istarget avr*-*-*] } {
+        return [check_no_compiler_messages avr_tiny object {
+            #ifdef __AVR_TINY__
+            int dummy;
+            #else
+            #error target not a reduced AVR Tiny core
+            #endif
+        }]
+    } else {
+        return 0
+    }
+}
+
 # Return 1 if <fenv.h> is available with all the standard IEEE
 # exceptions and floating-point exceptions are raised by arithmetic
 # operations.  (If the target requires special options for "inexact"
@@ -7457,7 +7943,7 @@ proc check_effective_target_fenv_exceptions {} {
 proc check_effective_target_tiny {} {
     global et_target_tiny_saved
 
-    if [info exists et_target_tine_saved] {
+    if [info exists et_target_tiny_saved] {
       verbose "check_effective_target_tiny: using cached result" 2
     } else {
        set et_target_tiny_saved 0
@@ -7465,6 +7951,10 @@ proc check_effective_target_tiny {} {
              && [check_effective_target_aarch64_tiny] } {
          set et_target_tiny_saved 1
        }
+       if { [istarget avr-*-*]
+             && [check_effective_target_avr_tiny] } {
+         set et_target_tiny_saved 1
+       }
     }
 
     return $et_target_tiny_saved
@@ -7509,7 +7999,7 @@ proc check_effective_target_pie_copyreloc { } {
     global tool
     global GCC_UNDER_TEST
 
-    if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
+    if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
        return 0
     }
 
@@ -7561,7 +8051,7 @@ proc check_effective_target_got32x_reloc { } {
     global tool
     global GCC_UNDER_TEST
 
-    if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
+    if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
        return 0
     }
 
@@ -7612,7 +8102,7 @@ proc check_effective_target_tls_get_addr_via_got { } {
     global tool
     global GCC_UNDER_TEST
 
-    if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
+    if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
        return 0
     }
 
@@ -7706,3 +8196,130 @@ proc check_effective_target_profile_update_atomic {} {
        int main (void) { return 0; }
     } "-fprofile-update=atomic -fprofile-generate"]
 }
+
+#For versions of ARM architectures that have hardware div insn,
+#disable the divmod transform
+
+proc check_effective_target_arm_divmod_simode { } {
+    return [check_no_compiler_messages arm_divmod assembly {
+       #ifdef __ARM_ARCH_EXT_IDIV__
+       #error has div insn
+       #endif
+       int i;
+    }]
+}
+
+# Return 1 if target supports divmod hardware insn or divmod libcall.
+
+proc check_effective_target_divmod { } {
+    #TODO: Add checks for all targets that have either hardware divmod insn
+    # or define libfunc for divmod.
+    if { [istarget arm*-*-*]
+        || [istarget i?86-*-*] || [istarget x86_64-*-*] } {
+       return 1
+    }
+    return 0
+}
+
+# Return 1 if target supports divmod for SImode. The reason for
+# separating this from check_effective_target_divmod is that
+# some versions of ARM architecture define div instruction
+# only for simode, and for these archs, we do not want to enable
+# divmod transform for simode.
+
+proc check_effective_target_divmod_simode { } {
+    if { [istarget arm*-*-*] } {
+       return [check_effective_target_arm_divmod_simode]
+    }
+
+    return [check_effective_target_divmod]
+}
+
+# Return 1 if store merging optimization is applicable for target.
+# Store merging is not profitable for targets like the avr which
+# can load/store only one byte at a time. Use int size as a proxy
+# for the number of bytes the target can write, and skip for targets
+# with a smallish (< 32) size.
+
+proc check_effective_target_store_merge { } {
+    if { [is-effective-target non_strict_align ] && [is-effective-target int32plus] } {
+       return 1
+    }
+
+    return 0
+}
+
+# Return 1 if the target supports coprocessor instructions: cdp, ldc, stc, mcr and
+# mrc.
+proc check_effective_target_arm_coproc1_ok_nocache { } {
+    if { ![istarget arm*-*-*] } {
+       return 0
+    }
+    return [check_no_compiler_messages_nocache arm_coproc1_ok assembly {
+       #if (__thumb__ && !__thumb2__) || __ARM_ARCH < 4
+       #error FOO
+       #endif
+    }]
+}
+
+proc check_effective_target_arm_coproc1_ok { } {
+    return [check_cached_effective_target arm_coproc1_ok \
+               check_effective_target_arm_coproc1_ok_nocache]
+}
+
+# Return 1 if the target supports all coprocessor instructions checked by
+# check_effective_target_arm_coproc1_ok in addition to the following: cdp2,
+# ldc2, ldc2l, stc2, stc2l, mcr2 and mrc2.
+proc check_effective_target_arm_coproc2_ok_nocache { } {
+    if { ![check_effective_target_arm_coproc1_ok] } {
+       return 0
+    }
+    return [check_no_compiler_messages_nocache arm_coproc2_ok assembly {
+       #if __ARM_ARCH < 5
+       #error FOO
+       #endif
+    }]
+}
+
+proc check_effective_target_arm_coproc2_ok { } {
+    return [check_cached_effective_target arm_coproc2_ok \
+               check_effective_target_arm_coproc2_ok_nocache]
+}
+
+# Return 1 if the target supports all coprocessor instructions checked by
+# check_effective_target_arm_coproc2_ok in addition the following: mcrr and
+# mrrc.
+proc check_effective_target_arm_coproc3_ok_nocache { } {
+    if { ![check_effective_target_arm_coproc2_ok] } {
+       return 0
+    }
+    return [check_no_compiler_messages_nocache arm_coproc3_ok assembly {
+       #if __ARM_ARCH < 6 && !defined (__ARM_ARCH_5TE__)
+       #error FOO
+       #endif
+    }]
+}
+
+proc check_effective_target_arm_coproc3_ok { } {
+    return [check_cached_effective_target arm_coproc3_ok \
+               check_effective_target_arm_coproc3_ok_nocache]
+}
+
+# Return 1 if the target supports all coprocessor instructions checked by
+# check_effective_target_arm_coproc3_ok in addition the following: mcrr2 and
+# mrcc2.
+proc check_effective_target_arm_coproc4_ok_nocache { } {
+    if { ![check_effective_target_arm_coproc3_ok] } {
+       return 0
+    }
+    return [check_no_compiler_messages_nocache arm_coproc4_ok assembly {
+       #if __ARM_ARCH < 6
+       #error FOO
+       #endif
+    }]
+}
+
+proc check_effective_target_arm_coproc4_ok { } {
+    return [check_cached_effective_target arm_coproc4_ok \
+               check_effective_target_arm_coproc4_ok_nocache]
+}