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