From 8b5e132868da066eb8a8673286b796656b9ed127 Mon Sep 17 00:00:00 2001
From: Matthew Wahab <matthew.wahab@arm.com>
Date: Mon, 8 Jun 2015 14:11:13 +0100
Subject: [PATCH 3/4] Use feature sets.
Change-Id: I5a1b162102dd19b6376637218dc548502112cf4b
---
gcc/config/arm/arm-builtins.c | 4 +-
gcc/config/arm/arm-protos.h | 4 +-
gcc/config/arm/arm.c | 131 ++++++++++++++++++++++++------------------
3 files changed, 80 insertions(+), 59 deletions(-)
@@ -1074,10 +1074,10 @@ arm_init_neon_builtins (void)
#undef NUM_DREG_TYPES
#undef NUM_QREG_TYPES
-#define def_mbuiltin(MASK, NAME, TYPE, CODE) \
+#define def_mbuiltin(FLAG, NAME, TYPE, CODE) \
do \
{ \
- if ((MASK) & insn_flags) \
+ if (ARM_FSET_HAS_CPU1 (insn_flags, (FLAG))) \
{ \
tree bdecl; \
bdecl = add_builtin_function ((NAME), (TYPE), (CODE), \
@@ -515,11 +515,11 @@ typedef struct
/* The bits in this mask specify which
instructions we are allowed to generate. */
-extern unsigned long insn_flags;
+extern arm_feature_set insn_flags;
/* The bits in this mask specify which instruction scheduling options should
be used. */
-extern unsigned long tune_flags;
+extern arm_feature_set tune_flags;
/* Nonzero if this chip supports the ARM Architecture 3M extensions. */
extern int arm_arch3m;
@@ -105,6 +105,7 @@ static void arm_add_gc_roots (void);
static int arm_gen_constant (enum rtx_code, machine_mode, rtx,
HOST_WIDE_INT, rtx, rtx, int, int);
static unsigned bit_count (unsigned long);
+static unsigned feature_count (const arm_feature_set*);
static int arm_address_register_rtx_p (rtx, int);
static int arm_legitimate_index_p (machine_mode, rtx, RTX_CODE, int);
static bool is_called_in_ARM_mode (tree);
@@ -771,11 +772,11 @@ static int thumb_call_reg_needed;
/* The bits in this mask specify which
instructions we are allowed to generate. */
-unsigned long insn_flags = 0;
+arm_feature_set insn_flags = ARM_FSET_EMPTY;
/* The bits in this mask specify which instruction scheduling options should
be used. */
-unsigned long tune_flags = 0;
+arm_feature_set tune_flags = ARM_FSET_EMPTY;
/* The highest ARM architecture version supported by the
target. */
@@ -928,7 +929,7 @@ struct processors
enum processor_type core;
const char *arch;
enum base_architecture base_arch;
- const unsigned long flags;
+ const arm_feature_set flags;
const struct tune_params *const tune;
};
@@ -2197,10 +2198,10 @@ static const struct processors all_cores[] =
/* ARM Cores */
#define ARM_CORE(NAME, X, IDENT, ARCH, FLAGS, COSTS) \
{NAME, IDENT, #ARCH, BASE_ARCH_##ARCH, \
- FLAGS, &arm_##COSTS##_tune},
+ ARM_FSET_MAKE_CPU1 (FLAGS), &arm_##COSTS##_tune},
#include "arm-cores.def"
#undef ARM_CORE
- {NULL, arm_none, NULL, BASE_ARCH_0, 0, NULL}
+ {NULL, arm_none, NULL, BASE_ARCH_0, ARM_FSET_EMPTY, NULL}
};
static const struct processors all_architectures[] =
@@ -2210,10 +2211,10 @@ static const struct processors all_architectures[] =
from the core. */
#define ARM_ARCH(NAME, CORE, ARCH, FLAGS) \
- {NAME, CORE, #ARCH, BASE_ARCH_##ARCH, FLAGS, NULL},
+ {NAME, CORE, #ARCH, BASE_ARCH_##ARCH, ARM_FSET_MAKE_CPU1 (FLAGS), NULL},
#include "arm-arches.def"
#undef ARM_ARCH
- {NULL, arm_none, NULL, BASE_ARCH_0, 0, NULL}
+ {NULL, arm_none, NULL, BASE_ARCH_0, ARM_FSET_EMPTY, NULL}
};
@@ -2279,6 +2280,14 @@ bit_count (unsigned long value)
return count;
}
+/* Return the number of features in feature-set SET. */
+static unsigned
+feature_count (const arm_feature_set * set)
+{
+ return (bit_count (ARM_FSET_CPU1 (*set))
+ + bit_count (ARM_FSET_CPU2 (*set)));
+}
+
typedef struct
{
machine_mode mode;
@@ -2704,7 +2713,7 @@ arm_option_check_internal (struct gcc_options *opts)
/* Make sure that the processor choice does not conflict with any of the
other command line choices. */
- if (TARGET_ARM_P (flags) && !(insn_flags & FL_NOTM))
+ if (TARGET_ARM_P (flags) && !ARM_FSET_HAS_CPU1 (insn_flags, FL_NOTM))
error ("target CPU does not support ARM mode");
/* TARGET_BACKTRACE calls leaf_function_p, which causes a crash if done
@@ -2800,7 +2809,8 @@ static void
arm_option_override_internal (struct gcc_options *opts,
struct gcc_options *opts_set)
{
- if (TARGET_THUMB_P (opts->x_target_flags) && !(insn_flags & FL_THUMB))
+ if (TARGET_THUMB_P (opts->x_target_flags)
+ && !(ARM_FSET_HAS_CPU1 (insn_flags, FL_THUMB)))
{
warning (0, "target CPU does not support THUMB instructions");
opts->x_target_flags &= ~MASK_THUMB;
@@ -2887,8 +2897,13 @@ arm_option_override (void)
{
if (arm_selected_cpu)
{
+ const arm_feature_set tuning_flags = ARM_FSET_MAKE_CPU1 (FL_TUNE);
+ arm_feature_set selected_flags;
+ ARM_FSET_XOR (selected_flags, arm_selected_cpu->flags,
+ arm_selected_arch->flags);
+ ARM_FSET_EXCLUDE (selected_flags, selected_flags, tuning_flags);
/* Check for conflict between mcpu and march. */
- if ((arm_selected_cpu->flags ^ arm_selected_arch->flags) & ~FL_TUNE)
+ if (!ARM_FSET_IS_EMPTY (selected_flags))
{
warning (0, "switch -mcpu=%s conflicts with -march=%s switch",
arm_selected_cpu->name, arm_selected_arch->name);
@@ -2912,7 +2927,7 @@ arm_option_override (void)
if (!arm_selected_cpu)
{
const struct processors * sel;
- unsigned int sought;
+ arm_feature_set sought = ARM_FSET_EMPTY;;
arm_selected_cpu = &all_cores[TARGET_CPU_DEFAULT];
if (!arm_selected_cpu->name)
@@ -2932,26 +2947,27 @@ arm_option_override (void)
/* Now check to see if the user has specified some command line
switch that require certain abilities from the cpu. */
- sought = 0;
if (TARGET_INTERWORK || TARGET_THUMB)
{
- sought |= (FL_THUMB | FL_MODE32);
+ ARM_FSET_ADD_CPU1 (sought, FL_THUMB);
+ ARM_FSET_ADD_CPU1 (sought, FL_MODE32);
/* There are no ARM processors that support both APCS-26 and
interworking. Therefore we force FL_MODE26 to be removed
from insn_flags here (if it was set), so that the search
below will always be able to find a compatible processor. */
- insn_flags &= ~FL_MODE26;
+ ARM_FSET_DEL_CPU1 (insn_flags, FL_MODE26);
}
- if (sought != 0 && ((sought & insn_flags) != sought))
+ if (!ARM_FSET_IS_EMPTY (sought)
+ && !(ARM_FSET_CPU_SUBSET (sought, insn_flags)))
{
/* Try to locate a CPU type that supports all of the abilities
of the default CPU, plus the extra abilities requested by
the user. */
for (sel = all_cores; sel->name != NULL; sel++)
- if ((sel->flags & sought) == (sought | insn_flags))
+ if (ARM_FSET_CPU_SUBSET (sought, sel->flags))
break;
if (sel->name == NULL)
@@ -2971,19 +2987,23 @@ arm_option_override (void)
command line options we scan the array again looking
for a best match. */
for (sel = all_cores; sel->name != NULL; sel++)
- if ((sel->flags & sought) == sought)
- {
- unsigned count;
-
- count = bit_count (sel->flags & insn_flags);
-
- if (count >= current_bit_count)
- {
- best_fit = sel;
- current_bit_count = count;
- }
- }
+ {
+ arm_feature_set required = ARM_FSET_EMPTY;
+ ARM_FSET_UNION (required, sought, insn_flags);
+ if (ARM_FSET_CPU_SUBSET (required, sel->flags))
+ {
+ unsigned count;
+ arm_feature_set flags;
+ ARM_FSET_INTER (flags, sel->flags, insn_flags);
+ count = feature_count (&flags);
+ if (count >= current_bit_count)
+ {
+ best_fit = sel;
+ current_bit_count = count;
+ }
+ }
+ }
gcc_assert (best_fit);
sel = best_fit;
}
@@ -3011,7 +3031,8 @@ arm_option_override (void)
/* BPABI targets use linker tricks to allow interworking on cores
without thumb support. */
- if (TARGET_INTERWORK && !((insn_flags & FL_THUMB) || TARGET_BPABI))
+ if (TARGET_INTERWORK
+ && !(ARM_FSET_HAS_CPU1 (insn_flags, FL_THUMB) || TARGET_BPABI))
{
warning (0, "target CPU does not support interworking" );
target_flags &= ~MASK_INTERWORK;
@@ -3036,33 +3057,33 @@ arm_option_override (void)
warning (0, "passing floating point arguments in fp regs not yet supported");
/* Initialize boolean versions of the flags, for use in the arm.md file. */
- arm_arch3m = (insn_flags & FL_ARCH3M) != 0;
- arm_arch4 = (insn_flags & FL_ARCH4) != 0;
- arm_arch4t = arm_arch4 & ((insn_flags & FL_THUMB) != 0);
- arm_arch5 = (insn_flags & FL_ARCH5) != 0;
- arm_arch5e = (insn_flags & FL_ARCH5E) != 0;
- arm_arch6 = (insn_flags & FL_ARCH6) != 0;
- arm_arch6k = (insn_flags & FL_ARCH6K) != 0;
- arm_arch_notm = (insn_flags & FL_NOTM) != 0;
+ arm_arch3m = ARM_FSET_HAS_CPU1 (insn_flags, FL_ARCH3M);
+ arm_arch4 = ARM_FSET_HAS_CPU1 (insn_flags, FL_ARCH4);
+ arm_arch4t = arm_arch4 && (ARM_FSET_HAS_CPU1 (insn_flags, FL_THUMB));
+ arm_arch5 = ARM_FSET_HAS_CPU1 (insn_flags, FL_ARCH5);
+ arm_arch5e = ARM_FSET_HAS_CPU1 (insn_flags, FL_ARCH5E);
+ arm_arch6 = ARM_FSET_HAS_CPU1 (insn_flags, FL_ARCH6);
+ arm_arch6k = ARM_FSET_HAS_CPU1 (insn_flags, FL_ARCH6K);
+ arm_arch_notm = ARM_FSET_HAS_CPU1 (insn_flags, FL_NOTM);
arm_arch6m = arm_arch6 && !arm_arch_notm;
- arm_arch7 = (insn_flags & FL_ARCH7) != 0;
- arm_arch7em = (insn_flags & FL_ARCH7EM) != 0;
- arm_arch8 = (insn_flags & FL_ARCH8) != 0;
- arm_arch_thumb2 = (insn_flags & FL_THUMB2) != 0;
- arm_arch_xscale = (insn_flags & FL_XSCALE) != 0;
-
- arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
- arm_tune_strongarm = (tune_flags & FL_STRONG) != 0;
- arm_tune_wbuf = (tune_flags & FL_WBUF) != 0;
- arm_tune_xscale = (tune_flags & FL_XSCALE) != 0;
- arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0;
- arm_arch_iwmmxt2 = (insn_flags & FL_IWMMXT2) != 0;
- arm_arch_thumb_hwdiv = (insn_flags & FL_THUMB_DIV) != 0;
- arm_arch_arm_hwdiv = (insn_flags & FL_ARM_DIV) != 0;
- arm_arch_no_volatile_ce = (insn_flags & FL_NO_VOLATILE_CE) != 0;
+ arm_arch7 = ARM_FSET_HAS_CPU1 (insn_flags, FL_ARCH7);
+ arm_arch7em = ARM_FSET_HAS_CPU1 (insn_flags, FL_ARCH7EM);
+ arm_arch8 = ARM_FSET_HAS_CPU1 (insn_flags, FL_ARCH8);
+ arm_arch_thumb2 = ARM_FSET_HAS_CPU1 (insn_flags, FL_THUMB2);
+ arm_arch_xscale = ARM_FSET_HAS_CPU1 (insn_flags, FL_XSCALE);
+
+ arm_ld_sched = ARM_FSET_HAS_CPU1 (tune_flags, FL_LDSCHED);
+ arm_tune_strongarm = ARM_FSET_HAS_CPU1 (tune_flags, FL_STRONG);
+ arm_tune_wbuf = ARM_FSET_HAS_CPU1 (tune_flags, FL_WBUF);
+ arm_tune_xscale = ARM_FSET_HAS_CPU1 (tune_flags, FL_XSCALE);
+ arm_arch_iwmmxt = ARM_FSET_HAS_CPU1 (insn_flags, FL_IWMMXT);
+ arm_arch_iwmmxt2 = ARM_FSET_HAS_CPU1 (insn_flags, FL_IWMMXT2);
+ arm_arch_thumb_hwdiv = ARM_FSET_HAS_CPU1 (insn_flags, FL_THUMB_DIV);
+ arm_arch_arm_hwdiv = ARM_FSET_HAS_CPU1 (insn_flags, FL_ARM_DIV);
+ arm_arch_no_volatile_ce = ARM_FSET_HAS_CPU1 (insn_flags, FL_NO_VOLATILE_CE);
arm_tune_cortex_a9 = (arm_tune == cortexa9) != 0;
- arm_arch_crc = (insn_flags & FL_CRC32) != 0;
- arm_m_profile_small_mul = (insn_flags & FL_SMALLMUL) != 0;
+ arm_arch_crc = ARM_FSET_HAS_CPU1 (insn_flags, FL_CRC32);
+ arm_m_profile_small_mul = ARM_FSET_HAS_CPU1 (insn_flags, FL_SMALLMUL);
/* V5 code we generate is completely interworking capable, so we turn off
TARGET_INTERWORK here to avoid many tests later on. */
@@ -3154,7 +3175,7 @@ arm_option_override (void)
/* For arm2/3 there is no need to do any scheduling if we are doing
software floating-point. */
- if (TARGET_SOFT_FLOAT && (tune_flags & FL_MODE32) == 0)
+ if (TARGET_SOFT_FLOAT && !ARM_FSET_HAS_CPU1 (tune_flags, FL_MODE32))
flag_schedule_insns = flag_schedule_insns_after_reload = 0;
/* Use the cp15 method if it is available. */
--
1.9.1