Home | History | Annotate | Line # | Download | only in arm
      1  1.1  mrg /* Copyright (C) 2007-2022 Free Software Foundation, Inc.
      2  1.1  mrg 
      3  1.1  mrg    This file is part of GCC.
      4  1.1  mrg 
      5  1.1  mrg    GCC is free software; you can redistribute it and/or modify it under
      6  1.1  mrg    the terms of the GNU General Public License as published by the Free
      7  1.1  mrg    Software Foundation; either version 3, or (at your option) any later
      8  1.1  mrg    version.
      9  1.1  mrg 
     10  1.1  mrg    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     11  1.1  mrg    WARRANTY; without even the implied warranty of MERCHANTABILITY or
     12  1.1  mrg    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     13  1.1  mrg    for more details.
     14  1.1  mrg 
     15  1.1  mrg    You should have received a copy of the GNU General Public License
     16  1.1  mrg    along with GCC; see the file COPYING3.  If not see
     17  1.1  mrg    <http://www.gnu.org/licenses/>.  */
     18  1.1  mrg 
     19  1.1  mrg #define IN_TARGET_CODE 1
     20  1.1  mrg 
     21  1.1  mrg #include "config.h"
     22  1.1  mrg #include "system.h"
     23  1.1  mrg #include "coretypes.h"
     24  1.1  mrg #include "target.h"
     25  1.1  mrg #include "c-family/c-common.h"
     26  1.1  mrg #include "memmodel.h"
     27  1.1  mrg #include "tm_p.h"
     28  1.1  mrg #include "c-family/c-pragma.h"
     29  1.1  mrg #include "stringpool.h"
     30  1.1  mrg #include "arm-builtins.h"
     31  1.1  mrg #include "arm-protos.h"
     32  1.1  mrg 
     33  1.1  mrg tree
     34  1.1  mrg arm_resolve_cde_builtin (location_t loc, tree fndecl, void *arglist)
     35  1.1  mrg {
     36  1.1  mrg   vec<tree, va_gc> *params = static_cast<vec<tree, va_gc> *> (arglist);
     37  1.1  mrg   unsigned param_num = params ? params->length() : 0;
     38  1.1  mrg   unsigned num_args = list_length (TYPE_ARG_TYPES (TREE_TYPE (fndecl))) - 1;
     39  1.1  mrg   /* Ensure this function has the correct number of arguments.
     40  1.1  mrg      This won't happen when using the intrinsics defined by the ACLE, since
     41  1.1  mrg      they're exposed to the user via a wrapper in the arm_cde.h header that has
     42  1.1  mrg      the correct number of arguments ... hence the compiler would already catch
     43  1.1  mrg      an incorrect number of arguments there.
     44  1.1  mrg 
     45  1.1  mrg      It is still possible to get here if the user tries to call the __bulitin_*
     46  1.1  mrg      functions directly.  We could print some error message in this function,
     47  1.1  mrg      but instead we leave it to the rest of the code to catch this problem in
     48  1.1  mrg      the same way that other __builtin_* functions catch it.
     49  1.1  mrg 
     50  1.1  mrg      This does mean an odd error message, but it's consistent with the rest of
     51  1.1  mrg      the builtins.  */
     52  1.1  mrg   if (param_num != num_args)
     53  1.1  mrg     return NULL_TREE;
     54  1.1  mrg 
     55  1.1  mrg   tree to_return = NULL_TREE;
     56  1.1  mrg   /* Take the functions return type since that's the same type as the arguments
     57  1.1  mrg      this function needs (the types of the builtin function all come from the
     58  1.1  mrg      machine mode of the RTL pattern, and they're all the same and calculated
     59  1.1  mrg      in the same way).  */
     60  1.1  mrg   tree pattern_type = TREE_TYPE (TREE_TYPE (fndecl));
     61  1.1  mrg 
     62  1.1  mrg   unsigned i;
     63  1.1  mrg   /* Hard coding the number of parameters we don't want to cast at the end of
     64  1.1  mrg      the builtin.  This is the  easiest approach for the CDE intrinsics, and
     65  1.1  mrg      introducing a parameter to store in the builtins.def macros seems overkill
     66  1.1  mrg      when they're only relevant here.  */
     67  1.1  mrg   unsigned end_args = arm_cde_end_args (fndecl);
     68  1.1  mrg   unsigned cast_param_end = param_num - end_args;
     69  1.1  mrg   /* For the vcx1q patterns that don't need any casts.  */
     70  1.1  mrg   if (cast_param_end == 1)
     71  1.1  mrg     return NULL_TREE;
     72  1.1  mrg 
     73  1.1  mrg   /* In order to check all arguments rather than complaining on the first
     74  1.1  mrg      invalid one we record whether *any* arguments are invalid using this
     75  1.1  mrg      boolean variable.  */
     76  1.1  mrg   bool invalid = false;
     77  1.1  mrg   for (i = 1; i < cast_param_end; i++)
     78  1.1  mrg     {
     79  1.1  mrg       tree this_param = (*params)[i];
     80  1.1  mrg       if (TREE_CODE (this_param) == ERROR_MARK)
     81  1.1  mrg 	{
     82  1.1  mrg 	  invalid = true;
     83  1.1  mrg 	  continue;
     84  1.1  mrg 	}
     85  1.1  mrg       tree param_type = TREE_TYPE (this_param);
     86  1.1  mrg 
     87  1.1  mrg       /* Return value is cast to type that second argument originally was.
     88  1.1  mrg 	 All non-constant arguments are cast to the return type calculated from
     89  1.1  mrg 	 the RTL pattern.
     90  1.1  mrg 
     91  1.1  mrg 	 Set the return type to an unqualified version of the type of the first
     92  1.1  mrg 	 parameter.  The first parameter since that is how the intrinsics are
     93  1.1  mrg 	 defined -- to always return the same type as the first polymorphic
     94  1.1  mrg 	 argument.  Unqualified version of the type since we don't want passing
     95  1.1  mrg 	 a constant parameter to mean that the return value of the builtin is
     96  1.1  mrg 	 also constant.  */
     97  1.1  mrg       if (i == 1)
     98  1.1  mrg 	to_return = build_qualified_type (param_type, 0 MEM_STAT_INFO);
     99  1.1  mrg 
    100  1.1  mrg       /* The only requirement of these intrinsics on the type of the variable
    101  1.1  mrg 	 is that it's 128 bits wide.  All other types are valid and we simply
    102  1.1  mrg 	 VIEW_CONVERT_EXPR them to the type of the underlying builtin.  */
    103  1.1  mrg       tree type_size = TYPE_SIZE (param_type);
    104  1.1  mrg       if (! tree_fits_shwi_p (type_size)
    105  1.1  mrg 	  || tree_to_shwi (type_size) != 128)
    106  1.1  mrg 	{
    107  1.1  mrg 	  error_at (loc,
    108  1.1  mrg 		    "argument %u to function %qE is of type %qT which is not "
    109  1.1  mrg 		    "known to be 128 bits wide",
    110  1.1  mrg 		    i + 1, fndecl, param_type);
    111  1.1  mrg 	  invalid = true;
    112  1.1  mrg 	  continue;
    113  1.1  mrg 	}
    114  1.1  mrg 
    115  1.1  mrg       /* Only convert the argument if we actually need to.  */
    116  1.1  mrg       if (! check_base_type (pattern_type, param_type))
    117  1.1  mrg 	(*params)[i] = build1 (VIEW_CONVERT_EXPR, pattern_type, this_param);
    118  1.1  mrg     }
    119  1.1  mrg   if (invalid)
    120  1.1  mrg     return NULL_TREE;
    121  1.1  mrg 
    122  1.1  mrg   /* We know it's safe to call this since this builtin is here to implement an
    123  1.1  mrg      ACLE function, and those functions are only for C/C++.  */
    124  1.1  mrg   tree call_expr = build_function_call_vec (loc, vNULL, fndecl, params,
    125  1.1  mrg 					    NULL, fndecl);
    126  1.1  mrg 
    127  1.1  mrg   gcc_assert (to_return != NULL_TREE);
    128  1.1  mrg   if (! check_base_type (to_return, pattern_type))
    129  1.1  mrg     return build1 (VIEW_CONVERT_EXPR, to_return, call_expr);
    130  1.1  mrg   return call_expr;
    131  1.1  mrg }
    132  1.1  mrg 
    133  1.1  mrg /* Implement "#pragma GCC arm".  */
    134  1.1  mrg static void
    135  1.1  mrg arm_pragma_arm (cpp_reader *)
    136  1.1  mrg {
    137  1.1  mrg   tree x;
    138  1.1  mrg   if (pragma_lex (&x) != CPP_STRING)
    139  1.1  mrg     {
    140  1.1  mrg       error ("%<#pragma GCC arm%> requires a string parameter");
    141  1.1  mrg       return;
    142  1.1  mrg     }
    143  1.1  mrg 
    144  1.1  mrg   const char *name = TREE_STRING_POINTER (x);
    145  1.1  mrg   if (strcmp (name, "arm_mve_types.h") == 0)
    146  1.1  mrg     arm_mve::handle_arm_mve_types_h ();
    147  1.1  mrg   else
    148  1.1  mrg     error ("unknown %<#pragma GCC arm%> option %qs", name);
    149  1.1  mrg }
    150  1.1  mrg 
    151  1.1  mrg /* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN.  This is currently only
    152  1.1  mrg    used for the MVE related builtins for the CDE extension.
    153  1.1  mrg    Here we ensure the type of arguments is such that the size is correct, and
    154  1.1  mrg    then return a tree that describes the same function call but with the
    155  1.1  mrg    relevant types cast as necessary.  */
    156  1.1  mrg tree
    157  1.1  mrg arm_resolve_overloaded_builtin (location_t loc, tree fndecl, void *arglist)
    158  1.1  mrg {
    159  1.1  mrg   if (arm_describe_resolver (fndecl) == arm_cde_resolver)
    160  1.1  mrg     return arm_resolve_cde_builtin (loc, fndecl, arglist);
    161  1.1  mrg   return NULL_TREE;
    162  1.1  mrg }
    163  1.1  mrg 
    164  1.1  mrg /* Output C specific EABI object attributes.  These cannot be done in
    165  1.1  mrg    arm.cc because they require information from the C frontend.  */
    166  1.1  mrg 
    167  1.1  mrg static void
    168  1.1  mrg arm_output_c_attributes (void)
    169  1.1  mrg {
    170  1.1  mrg   int wchar_size = (int)(TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT);
    171  1.1  mrg   arm_emit_eabi_attribute ("Tag_ABI_PCS_wchar_t", 18, wchar_size);
    172  1.1  mrg }
    173  1.1  mrg 
    174  1.1  mrg 
    175  1.1  mrg /* Setup so that common code calls arm_output_c_attributes.  */
    176  1.1  mrg 
    177  1.1  mrg void
    178  1.1  mrg arm_lang_object_attributes_init (void)
    179  1.1  mrg {
    180  1.1  mrg   arm_lang_output_object_attributes_hook = arm_output_c_attributes;
    181  1.1  mrg }
    182  1.1  mrg 
    183  1.1  mrg #define builtin_define(TXT) cpp_define (pfile, TXT)
    184  1.1  mrg #define builtin_assert(TXT) cpp_assert (pfile, TXT)
    185  1.1  mrg 
    186  1.1  mrg /* Define or undefine macros based on the current target.  If the user does
    187  1.1  mrg    #pragma GCC target, we need to adjust the macros dynamically.  */
    188  1.1  mrg 
    189  1.1  mrg static void
    190  1.1  mrg def_or_undef_macro(struct cpp_reader* pfile, const char *name, bool def_p)
    191  1.1  mrg {
    192  1.1  mrg   if (def_p)
    193  1.1  mrg     cpp_define (pfile, name);
    194  1.1  mrg   else
    195  1.1  mrg     cpp_undef (pfile, name);
    196  1.1  mrg }
    197  1.1  mrg 
    198  1.1  mrg static void
    199  1.1  mrg arm_cpu_builtins (struct cpp_reader* pfile)
    200  1.1  mrg {
    201  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_DSP", TARGET_DSP_MULTIPLY);
    202  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_QBIT", TARGET_ARM_QBIT);
    203  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_SAT", TARGET_ARM_SAT);
    204  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_CRYPTO", TARGET_CRYPTO);
    205  1.1  mrg 
    206  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_UNALIGNED", unaligned_access);
    207  1.1  mrg 
    208  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_QRDMX", TARGET_NEON_RDMA);
    209  1.1  mrg 
    210  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_CRC32", TARGET_CRC32);
    211  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_DOTPROD", TARGET_DOTPROD);
    212  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_COMPLEX", TARGET_COMPLEX);
    213  1.1  mrg   def_or_undef_macro (pfile, "__ARM_32BIT_STATE", TARGET_32BIT);
    214  1.1  mrg 
    215  1.1  mrg   cpp_undef (pfile, "__ARM_FEATURE_MVE");
    216  1.1  mrg   if (TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT)
    217  1.1  mrg     {
    218  1.1  mrg       builtin_define_with_int_value ("__ARM_FEATURE_MVE", 3);
    219  1.1  mrg     }
    220  1.1  mrg   else if (TARGET_HAVE_MVE)
    221  1.1  mrg     {
    222  1.1  mrg       builtin_define_with_int_value ("__ARM_FEATURE_MVE", 1);
    223  1.1  mrg     }
    224  1.1  mrg 
    225  1.1  mrg   cpp_undef (pfile, "__ARM_FEATURE_CMSE");
    226  1.1  mrg   if (arm_arch8 && !arm_arch_notm)
    227  1.1  mrg     {
    228  1.1  mrg       if (arm_arch_cmse && use_cmse)
    229  1.1  mrg 	builtin_define_with_int_value ("__ARM_FEATURE_CMSE", 3);
    230  1.1  mrg       else
    231  1.1  mrg 	builtin_define ("__ARM_FEATURE_CMSE");
    232  1.1  mrg     }
    233  1.1  mrg 
    234  1.1  mrg   cpp_undef (pfile, "__ARM_FEATURE_LDREX");
    235  1.1  mrg   if (TARGET_ARM_FEATURE_LDREX)
    236  1.1  mrg     builtin_define_with_int_value ("__ARM_FEATURE_LDREX",
    237  1.1  mrg 				   TARGET_ARM_FEATURE_LDREX);
    238  1.1  mrg 
    239  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_CLZ",
    240  1.1  mrg 		      ((TARGET_ARM_ARCH >= 5 && !TARGET_THUMB)
    241  1.1  mrg 		       || TARGET_ARM_ARCH_ISA_THUMB >=2));
    242  1.1  mrg 
    243  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_NUMERIC_MAXMIN",
    244  1.1  mrg 		      TARGET_ARM_ARCH >= 8 && TARGET_NEON && TARGET_VFP5);
    245  1.1  mrg 
    246  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_SIMD32", TARGET_INT_SIMD);
    247  1.1  mrg 
    248  1.1  mrg   builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM",
    249  1.1  mrg 				 flag_short_enums ? 1 : 4);
    250  1.1  mrg   builtin_define_type_sizeof ("__ARM_SIZEOF_WCHAR_T", wchar_type_node);
    251  1.1  mrg 
    252  1.1  mrg   cpp_undef (pfile, "__ARM_ARCH_PROFILE");
    253  1.1  mrg   if (TARGET_ARM_ARCH_PROFILE)
    254  1.1  mrg     builtin_define_with_int_value ("__ARM_ARCH_PROFILE",
    255  1.1  mrg 				   TARGET_ARM_ARCH_PROFILE);
    256  1.1  mrg 
    257  1.1  mrg   /* Define __arm__ even when in thumb mode, for
    258  1.1  mrg      consistency with armcc.  */
    259  1.1  mrg   builtin_define ("__arm__");
    260  1.1  mrg   if (TARGET_ARM_ARCH)
    261  1.1  mrg     {
    262  1.1  mrg       cpp_undef (pfile, "__ARM_ARCH");
    263  1.1  mrg       builtin_define_with_int_value ("__ARM_ARCH", TARGET_ARM_ARCH);
    264  1.1  mrg     }
    265  1.1  mrg   if (arm_arch_notm)
    266  1.1  mrg     builtin_define ("__ARM_ARCH_ISA_ARM");
    267  1.1  mrg   builtin_define ("__APCS_32__");
    268  1.1  mrg 
    269  1.1  mrg   def_or_undef_macro (pfile, "__GCC_ASM_FLAG_OUTPUTS__", !TARGET_THUMB1);
    270  1.1  mrg 
    271  1.1  mrg   def_or_undef_macro (pfile, "__thumb__", TARGET_THUMB);
    272  1.1  mrg   def_or_undef_macro (pfile, "__thumb2__", TARGET_THUMB2);
    273  1.1  mrg   if (TARGET_BIG_END)
    274  1.1  mrg     def_or_undef_macro (pfile, "__THUMBEB__", TARGET_THUMB);
    275  1.1  mrg   else
    276  1.1  mrg     def_or_undef_macro (pfile, "__THUMBEL__", TARGET_THUMB);
    277  1.1  mrg 
    278  1.1  mrg   cpp_undef (pfile, "__ARM_ARCH_ISA_THUMB");
    279  1.1  mrg   if (TARGET_ARM_ARCH_ISA_THUMB)
    280  1.1  mrg     builtin_define_with_int_value ("__ARM_ARCH_ISA_THUMB",
    281  1.1  mrg 				   TARGET_ARM_ARCH_ISA_THUMB);
    282  1.1  mrg 
    283  1.1  mrg   if (TARGET_BIG_END)
    284  1.1  mrg     {
    285  1.1  mrg       builtin_define ("__ARMEB__");
    286  1.1  mrg       builtin_define ("__ARM_BIG_ENDIAN");
    287  1.1  mrg     }
    288  1.1  mrg   else
    289  1.1  mrg     {
    290  1.1  mrg       builtin_define ("__ARMEL__");
    291  1.1  mrg     }
    292  1.1  mrg 
    293  1.1  mrg   if (TARGET_SOFT_FLOAT)
    294  1.1  mrg     builtin_define ("__SOFTFP__");
    295  1.1  mrg 
    296  1.1  mrg   builtin_define ("__VFP_FP__");
    297  1.1  mrg 
    298  1.1  mrg   cpp_undef (pfile, "__ARM_FP");
    299  1.1  mrg   if (TARGET_ARM_FP)
    300  1.1  mrg     builtin_define_with_int_value ("__ARM_FP", TARGET_ARM_FP);
    301  1.1  mrg 
    302  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FP16_FORMAT_IEEE",
    303  1.1  mrg 		      arm_fp16_format == ARM_FP16_FORMAT_IEEE);
    304  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FP16_FORMAT_ALTERNATIVE",
    305  1.1  mrg 		      arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE);
    306  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FP16_ARGS",
    307  1.1  mrg 		      arm_fp16_format != ARM_FP16_FORMAT_NONE);
    308  1.1  mrg 
    309  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC",
    310  1.1  mrg 		      TARGET_VFP_FP16INST);
    311  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC",
    312  1.1  mrg 		      TARGET_NEON_FP16INST);
    313  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_FP16_FML", TARGET_FP16FML);
    314  1.1  mrg 
    315  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_FMA", TARGET_FMA);
    316  1.1  mrg   def_or_undef_macro (pfile, "__ARM_NEON__", TARGET_NEON);
    317  1.1  mrg   def_or_undef_macro (pfile, "__ARM_NEON", TARGET_NEON);
    318  1.1  mrg 
    319  1.1  mrg   cpp_undef (pfile, "__ARM_NEON_FP");
    320  1.1  mrg   if (TARGET_NEON_FP)
    321  1.1  mrg     builtin_define_with_int_value ("__ARM_NEON_FP", TARGET_NEON_FP);
    322  1.1  mrg 
    323  1.1  mrg   /* Add a define for interworking. Needed when building libgcc.a.  */
    324  1.1  mrg   if (arm_cpp_interwork)
    325  1.1  mrg     builtin_define ("__THUMB_INTERWORK__");
    326  1.1  mrg 
    327  1.1  mrg   builtin_define (arm_arch_name);
    328  1.1  mrg   if (arm_arch_xscale)
    329  1.1  mrg     builtin_define ("__XSCALE__");
    330  1.1  mrg   if (arm_arch_iwmmxt)
    331  1.1  mrg     {
    332  1.1  mrg       builtin_define ("__IWMMXT__");
    333  1.1  mrg       builtin_define ("__ARM_WMMX");
    334  1.1  mrg     }
    335  1.1  mrg   if (arm_arch_iwmmxt2)
    336  1.1  mrg     builtin_define ("__IWMMXT2__");
    337  1.1  mrg   /* ARMv6KZ was originally identified as the misspelled __ARM_ARCH_6ZK__.  To
    338  1.1  mrg      preserve the existing behavior, the misspelled feature macro must still be
    339  1.1  mrg      defined.  */
    340  1.1  mrg   if (arm_arch6kz)
    341  1.1  mrg     builtin_define ("__ARM_ARCH_6ZK__");
    342  1.1  mrg   if (TARGET_AAPCS_BASED)
    343  1.1  mrg     {
    344  1.1  mrg       if (arm_pcs_default == ARM_PCS_AAPCS_VFP)
    345  1.1  mrg 	builtin_define ("__ARM_PCS_VFP");
    346  1.1  mrg       else if (arm_pcs_default == ARM_PCS_AAPCS)
    347  1.1  mrg 	builtin_define ("__ARM_PCS");
    348  1.1  mrg       builtin_define ("__ARM_EABI__");
    349  1.1  mrg     }
    350  1.1  mrg 
    351  1.1  mrg   def_or_undef_macro (pfile, "__FDPIC__", TARGET_FDPIC);
    352  1.1  mrg 
    353  1.1  mrg   def_or_undef_macro (pfile, "__ARM_ARCH_EXT_IDIV__", TARGET_IDIV);
    354  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_IDIV", TARGET_IDIV);
    355  1.1  mrg 
    356  1.1  mrg   def_or_undef_macro (pfile, "__ARM_ASM_SYNTAX_UNIFIED__", inline_asm_unified);
    357  1.1  mrg 
    358  1.1  mrg   cpp_undef (pfile, "__ARM_FEATURE_COPROC");
    359  1.1  mrg   if (TARGET_32BIT && arm_arch4 && !(arm_arch8 && arm_arch_notm))
    360  1.1  mrg     {
    361  1.1  mrg       int coproc_level = 0x1;
    362  1.1  mrg 
    363  1.1  mrg       if (arm_arch5t)
    364  1.1  mrg 	coproc_level |= 0x2;
    365  1.1  mrg       if (arm_arch5te)
    366  1.1  mrg 	coproc_level |= 0x4;
    367  1.1  mrg       if (arm_arch6)
    368  1.1  mrg 	coproc_level |= 0x8;
    369  1.1  mrg 
    370  1.1  mrg       builtin_define_with_int_value ("__ARM_FEATURE_COPROC", coproc_level);
    371  1.1  mrg     }
    372  1.1  mrg 
    373  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_CDE", TARGET_CDE);
    374  1.1  mrg   cpp_undef (pfile, "__ARM_FEATURE_CDE_COPROC");
    375  1.1  mrg   if (TARGET_CDE)
    376  1.1  mrg     builtin_define_with_int_value ("__ARM_FEATURE_CDE_COPROC",
    377  1.1  mrg 				   arm_arch_cde_coproc);
    378  1.1  mrg 
    379  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_MATMUL_INT8", TARGET_I8MM);
    380  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_BF16_SCALAR_ARITHMETIC",
    381  1.1  mrg 		      TARGET_BF16_FP);
    382  1.1  mrg   def_or_undef_macro (pfile, "__ARM_FEATURE_BF16_VECTOR_ARITHMETIC",
    383  1.1  mrg 		      TARGET_BF16_SIMD);
    384  1.1  mrg   def_or_undef_macro (pfile, "__ARM_BF16_FORMAT_ALTERNATIVE",
    385  1.1  mrg 		      TARGET_BF16_FP || TARGET_BF16_SIMD);
    386  1.1  mrg }
    387  1.1  mrg 
    388  1.1  mrg void
    389  1.1  mrg arm_cpu_cpp_builtins (struct cpp_reader * pfile)
    390  1.1  mrg {
    391  1.1  mrg   builtin_assert ("cpu=arm");
    392  1.1  mrg   builtin_assert ("machine=arm");
    393  1.1  mrg 
    394  1.1  mrg   arm_cpu_builtins (pfile);
    395  1.1  mrg }
    396  1.1  mrg 
    397  1.1  mrg /* Hook to validate the current #pragma GCC target and set the arch custom
    398  1.1  mrg    mode state.  If ARGS is NULL, then POP_TARGET is used to reset
    399  1.1  mrg    the options.  */
    400  1.1  mrg 
    401  1.1  mrg static bool
    402  1.1  mrg arm_pragma_target_parse (tree args, tree pop_target)
    403  1.1  mrg {
    404  1.1  mrg   tree prev_tree = target_option_current_node;
    405  1.1  mrg   tree cur_tree;
    406  1.1  mrg   struct cl_target_option *prev_opt;
    407  1.1  mrg   struct cl_target_option *cur_opt;
    408  1.1  mrg 
    409  1.1  mrg   if (! args)
    410  1.1  mrg     {
    411  1.1  mrg       cur_tree = ((pop_target) ? pop_target : target_option_default_node);
    412  1.1  mrg       cl_target_option_restore (&global_options, &global_options_set,
    413  1.1  mrg 				TREE_TARGET_OPTION (cur_tree));
    414  1.1  mrg     }
    415  1.1  mrg   else
    416  1.1  mrg     {
    417  1.1  mrg       cur_tree = arm_valid_target_attribute_tree (args, &global_options,
    418  1.1  mrg 						  &global_options_set);
    419  1.1  mrg       if (cur_tree == NULL_TREE)
    420  1.1  mrg 	{
    421  1.1  mrg 	  cl_target_option_restore (&global_options, &global_options_set,
    422  1.1  mrg 				    TREE_TARGET_OPTION (prev_tree));
    423  1.1  mrg 	  return false;
    424  1.1  mrg 	}
    425  1.1  mrg 
    426  1.1  mrg       /* handle_pragma_pop_options and handle_pragma_reset_options will set
    427  1.1  mrg        target_option_current_node, but not handle_pragma_target.  */
    428  1.1  mrg       target_option_current_node = cur_tree;
    429  1.1  mrg       arm_configure_build_target (&arm_active_target,
    430  1.1  mrg 				  TREE_TARGET_OPTION (cur_tree), false);
    431  1.1  mrg       arm_option_reconfigure_globals ();
    432  1.1  mrg     }
    433  1.1  mrg 
    434  1.1  mrg   /* Update macros if target_node changes. The global state will be restored
    435  1.1  mrg      by arm_set_current_function.  */
    436  1.1  mrg   prev_opt = TREE_TARGET_OPTION (prev_tree);
    437  1.1  mrg   cur_opt  = TREE_TARGET_OPTION (cur_tree);
    438  1.1  mrg 
    439  1.1  mrg   gcc_assert (prev_opt);
    440  1.1  mrg   gcc_assert (cur_opt);
    441  1.1  mrg 
    442  1.1  mrg   if (cur_opt != prev_opt)
    443  1.1  mrg     {
    444  1.1  mrg       /* For the definitions, ensure all newly defined macros are considered
    445  1.1  mrg 	 as used for -Wunused-macros.  There is no point warning about the
    446  1.1  mrg 	 compiler predefined macros.  */
    447  1.1  mrg       cpp_options *cpp_opts = cpp_get_options (parse_in);
    448  1.1  mrg       unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros;
    449  1.1  mrg 
    450  1.1  mrg       cpp_opts->warn_unused_macros = 0;
    451  1.1  mrg 
    452  1.1  mrg       /* Update macros.  */
    453  1.1  mrg       gcc_assert (cur_opt->x_target_flags == target_flags);
    454  1.1  mrg 
    455  1.1  mrg       /* Don't warn for macros that have context sensitive values depending on
    456  1.1  mrg 	 other attributes.
    457  1.1  mrg 	 See warn_of_redefinition, reset after cpp_create_definition.  */
    458  1.1  mrg       tree acond_macro = get_identifier ("__ARM_NEON_FP");
    459  1.1  mrg       C_CPP_HASHNODE (acond_macro)->flags |= NODE_CONDITIONAL ;
    460  1.1  mrg 
    461  1.1  mrg       acond_macro = get_identifier ("__ARM_FP");
    462  1.1  mrg       C_CPP_HASHNODE (acond_macro)->flags |= NODE_CONDITIONAL;
    463  1.1  mrg 
    464  1.1  mrg       acond_macro = get_identifier ("__ARM_FEATURE_LDREX");
    465  1.1  mrg       C_CPP_HASHNODE (acond_macro)->flags |= NODE_CONDITIONAL;
    466  1.1  mrg 
    467  1.1  mrg       cpp_force_token_locations (parse_in, BUILTINS_LOCATION);
    468  1.1  mrg       arm_cpu_builtins (parse_in);
    469  1.1  mrg       cpp_stop_forcing_token_locations (parse_in);
    470  1.1  mrg 
    471  1.1  mrg       cpp_opts->warn_unused_macros = saved_warn_unused_macros;
    472  1.1  mrg 
    473  1.1  mrg       /* Make sure that target_reinit is called for next function, since
    474  1.1  mrg 	 TREE_TARGET_OPTION might change with the #pragma even if there is
    475  1.1  mrg 	 no target attribute attached to the function.  */
    476  1.1  mrg       arm_reset_previous_fndecl ();
    477  1.1  mrg 
    478  1.1  mrg       /* If going to the default mode, we restore the initial states.
    479  1.1  mrg 	 if cur_tree is a new target, states will be saved/restored on a per
    480  1.1  mrg 	 function basis in arm_set_current_function.  */
    481  1.1  mrg       if (cur_tree == target_option_default_node)
    482  1.1  mrg 	save_restore_target_globals (cur_tree);
    483  1.1  mrg     }
    484  1.1  mrg 
    485  1.1  mrg   return true;
    486  1.1  mrg }
    487  1.1  mrg 
    488  1.1  mrg /* Register target pragmas.  We need to add the hook for parsing #pragma GCC
    489  1.1  mrg    option here rather than in arm.cc since it will pull in various preprocessor
    490  1.1  mrg    functions, and those are not present in languages like fortran without a
    491  1.1  mrg    preprocessor.  */
    492  1.1  mrg 
    493  1.1  mrg void
    494  1.1  mrg arm_register_target_pragmas (void)
    495  1.1  mrg {
    496  1.1  mrg   /* Update pragma hook to allow parsing #pragma GCC target.  */
    497  1.1  mrg   targetm.target_option.pragma_parse = arm_pragma_target_parse;
    498  1.1  mrg   targetm.resolve_overloaded_builtin = arm_resolve_overloaded_builtin;
    499  1.1  mrg 
    500  1.1  mrg   c_register_pragma ("GCC", "arm", arm_pragma_arm);
    501  1.1  mrg 
    502  1.1  mrg #ifdef REGISTER_SUBTARGET_PRAGMAS
    503  1.1  mrg   REGISTER_SUBTARGET_PRAGMAS ();
    504  1.1  mrg #endif
    505  1.1  mrg }
    506