-/* Copyright (C) 2007-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2020 Free Software Foundation, Inc.
This file is part of GCC.
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "c-family/c-common.h"
+#include "memmodel.h"
#include "tm_p.h"
#include "c-family/c-pragma.h"
#include "stringpool.h"
-/* Output C specific EABI object attributes. These can not be done in
+/* Output C specific EABI object attributes. These cannot be done in
arm.c because they require information from the C frontend. */
static void
def_or_undef_macro (pfile, "__ARM_FEATURE_QRDMX", TARGET_NEON_RDMA);
- if (TARGET_CRC32)
- builtin_define ("__ARM_FEATURE_CRC32");
-
+ def_or_undef_macro (pfile, "__ARM_FEATURE_CRC32", TARGET_CRC32);
+ def_or_undef_macro (pfile, "__ARM_FEATURE_DOTPROD", TARGET_DOTPROD);
+ def_or_undef_macro (pfile, "__ARM_FEATURE_COMPLEX", TARGET_COMPLEX);
def_or_undef_macro (pfile, "__ARM_32BIT_STATE", TARGET_32BIT);
+ cpp_undef (pfile, "__ARM_FEATURE_CMSE");
+ if (arm_arch8 && !arm_arch_notm)
+ {
+ if (arm_arch_cmse && use_cmse)
+ builtin_define_with_int_value ("__ARM_FEATURE_CMSE", 3);
+ else
+ builtin_define ("__ARM_FEATURE_CMSE");
+ }
+
+ cpp_undef (pfile, "__ARM_FEATURE_LDREX");
if (TARGET_ARM_FEATURE_LDREX)
builtin_define_with_int_value ("__ARM_FEATURE_LDREX",
TARGET_ARM_FEATURE_LDREX);
- else
- cpp_undef (pfile, "__ARM_FEATURE_LDREX");
def_or_undef_macro (pfile, "__ARM_FEATURE_CLZ",
((TARGET_ARM_ARCH >= 5 && !TARGET_THUMB)
|| TARGET_ARM_ARCH_ISA_THUMB >=2));
+ def_or_undef_macro (pfile, "__ARM_FEATURE_NUMERIC_MAXMIN",
+ TARGET_ARM_ARCH >= 8 && TARGET_NEON && TARGET_VFP5);
+
def_or_undef_macro (pfile, "__ARM_FEATURE_SIMD32", TARGET_INT_SIMD);
builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM",
flag_short_enums ? 1 : 4);
builtin_define_type_sizeof ("__ARM_SIZEOF_WCHAR_T", wchar_type_node);
+
+ cpp_undef (pfile, "__ARM_ARCH_PROFILE");
if (TARGET_ARM_ARCH_PROFILE)
builtin_define_with_int_value ("__ARM_ARCH_PROFILE",
TARGET_ARM_ARCH_PROFILE);
consistency with armcc. */
builtin_define ("__arm__");
if (TARGET_ARM_ARCH)
- builtin_define_with_int_value ("__ARM_ARCH", TARGET_ARM_ARCH);
+ {
+ cpp_undef (pfile, "__ARM_ARCH");
+ builtin_define_with_int_value ("__ARM_ARCH", TARGET_ARM_ARCH);
+ }
if (arm_arch_notm)
builtin_define ("__ARM_ARCH_ISA_ARM");
builtin_define ("__APCS_32__");
+ def_or_undef_macro (pfile, "__GCC_ASM_FLAG_OUTPUTS__", !TARGET_THUMB1);
+
def_or_undef_macro (pfile, "__thumb__", TARGET_THUMB);
def_or_undef_macro (pfile, "__thumb2__", TARGET_THUMB2);
if (TARGET_BIG_END)
else
def_or_undef_macro (pfile, "__THUMBEL__", TARGET_THUMB);
+ cpp_undef (pfile, "__ARM_ARCH_ISA_THUMB");
if (TARGET_ARM_ARCH_ISA_THUMB)
builtin_define_with_int_value ("__ARM_ARCH_ISA_THUMB",
TARGET_ARM_ARCH_ISA_THUMB);
if (TARGET_SOFT_FLOAT)
builtin_define ("__SOFTFP__");
- def_or_undef_macro (pfile, "__VFP_FP__", TARGET_VFP);
+ builtin_define ("__VFP_FP__");
+ cpp_undef (pfile, "__ARM_FP");
if (TARGET_ARM_FP)
builtin_define_with_int_value ("__ARM_FP", TARGET_ARM_FP);
- else
- cpp_undef (pfile, "__ARM_FP");
- if (arm_fp16_format == ARM_FP16_FORMAT_IEEE)
- builtin_define ("__ARM_FP16_FORMAT_IEEE");
- if (arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
- builtin_define ("__ARM_FP16_FORMAT_ALTERNATIVE");
+ def_or_undef_macro (pfile, "__ARM_FP16_FORMAT_IEEE",
+ arm_fp16_format == ARM_FP16_FORMAT_IEEE);
+ def_or_undef_macro (pfile, "__ARM_FP16_FORMAT_ALTERNATIVE",
+ arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE);
+ def_or_undef_macro (pfile, "__ARM_FP16_ARGS",
+ arm_fp16_format != ARM_FP16_FORMAT_NONE);
+
+ def_or_undef_macro (pfile, "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC",
+ TARGET_VFP_FP16INST);
+ def_or_undef_macro (pfile, "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC",
+ TARGET_NEON_FP16INST);
+ def_or_undef_macro (pfile, "__ARM_FEATURE_FP16_FML", TARGET_FP16FML);
def_or_undef_macro (pfile, "__ARM_FEATURE_FMA", TARGET_FMA);
def_or_undef_macro (pfile, "__ARM_NEON__", TARGET_NEON);
def_or_undef_macro (pfile, "__ARM_NEON", TARGET_NEON);
+ cpp_undef (pfile, "__ARM_NEON_FP");
if (TARGET_NEON_FP)
builtin_define_with_int_value ("__ARM_NEON_FP", TARGET_NEON_FP);
- else
- cpp_undef (pfile, "__ARM_NEON_FP");
/* Add a define for interworking. Needed when building libgcc.a. */
if (arm_cpp_interwork)
if (arm_arch_iwmmxt2)
builtin_define ("__IWMMXT2__");
/* ARMv6KZ was originally identified as the misspelled __ARM_ARCH_6ZK__. To
- preserve the existing behaviour, the misspelled feature macro must still be
+ preserve the existing behavior, the misspelled feature macro must still be
defined. */
if (arm_arch6kz)
builtin_define ("__ARM_ARCH_6ZK__");
builtin_define ("__ARM_EABI__");
}
+ def_or_undef_macro (pfile, "__FDPIC__", TARGET_FDPIC);
+
def_or_undef_macro (pfile, "__ARM_ARCH_EXT_IDIV__", TARGET_IDIV);
def_or_undef_macro (pfile, "__ARM_FEATURE_IDIV", TARGET_IDIV);
def_or_undef_macro (pfile, "__ARM_ASM_SYNTAX_UNIFIED__", inline_asm_unified);
+
+ cpp_undef (pfile, "__ARM_FEATURE_COPROC");
+ if (TARGET_32BIT && arm_arch4 && !(arm_arch8 && arm_arch_notm))
+ {
+ int coproc_level = 0x1;
+
+ if (arm_arch5t)
+ coproc_level |= 0x2;
+ if (arm_arch5te)
+ coproc_level |= 0x4;
+ if (arm_arch6)
+ coproc_level |= 0x8;
+
+ builtin_define_with_int_value ("__ARM_FEATURE_COPROC", coproc_level);
+ }
}
void
/* Hook to validate the current #pragma GCC target and set the arch custom
mode state. If ARGS is NULL, then POP_TARGET is used to reset
the options. */
+
static bool
arm_pragma_target_parse (tree args, tree pop_target)
{
- tree prev_tree = build_target_option_node (&global_options);
+ tree prev_tree = target_option_current_node;
tree cur_tree;
struct cl_target_option *prev_opt;
struct cl_target_option *cur_opt;
TREE_TARGET_OPTION (prev_tree));
return false;
}
- }
- target_option_current_node = cur_tree;
- arm_reset_previous_fndecl ();
+ /* handle_pragma_pop_options and handle_pragma_reset_options will set
+ target_option_current_node, but not handle_pragma_target. */
+ target_option_current_node = cur_tree;
+ arm_configure_build_target (&arm_active_target,
+ TREE_TARGET_OPTION (cur_tree),
+ &global_options_set, false);
+ }
- /* Figure out the previous mode. */
- prev_opt = TREE_TARGET_OPTION (prev_tree);
- cur_opt = TREE_TARGET_OPTION (cur_tree);
+ /* Update macros if target_node changes. The global state will be restored
+ by arm_set_current_function. */
+ prev_opt = TREE_TARGET_OPTION (prev_tree);
+ cur_opt = TREE_TARGET_OPTION (cur_tree);
gcc_assert (prev_opt);
gcc_assert (cur_opt);
/* Don't warn for macros that have context sensitive values depending on
other attributes.
- See warn_of_redefinition, Reset after cpp_create_definition. */
+ See warn_of_redefinition, reset after cpp_create_definition. */
tree acond_macro = get_identifier ("__ARM_NEON_FP");
C_CPP_HASHNODE (acond_macro)->flags |= NODE_CONDITIONAL ;
arm_cpu_builtins (parse_in);
cpp_opts->warn_unused_macros = saved_warn_unused_macros;
+
+ /* Make sure that target_reinit is called for next function, since
+ TREE_TARGET_OPTION might change with the #pragma even if there is
+ no target attribute attached to the function. */
+ arm_reset_previous_fndecl ();
+
+ /* If going to the default mode, we restore the initial states.
+ if cur_tree is a new target, states will be saved/restored on a per
+ function basis in arm_set_current_function. */
+ if (cur_tree == target_option_default_node)
+ save_restore_target_globals (cur_tree);
}
return true;