diff mbox

[2/5,ARM] Add feature set definitions.

Message ID 55C8918B.10209@foss.arm.com
State New
Headers show

Commit Message

Matthew Wahab Aug. 10, 2015, 11:56 a.m. UTC
The ARM backend uses an unsigned long to record CPU feature flags and
there are currently 31 bits in use. This series of patches replaces the
single unsigned long with a representation based on an array of values.

This patch adds, but doesn't use, type arm_feature_set and macros
prefixed with ARM_FSET to represent and operate on feature sets.

Tested the series for arm-none-linux-gnueabihf with native bootstrap and
make check.

gcc/
2015-08-10  Matthew Wahab  <matthew.wahab@arm.com>

	* config/arm/arm-protos.h (FL_NONE): New.
	(FL_ANY): New.
	(arm_feature_set): New.
	(ARM_FSET_MAKE): New.
	(ARM_FSET_MAKE_CPU1): New.
	(ARM_FSET_MAKE_CPU2): New.
	(ARM_FSET_CPU1): New.
	(ARM_FSET_CPU2): New.
	(ARM_FSET_EMPTY): New.
	(ARM_FSET_ANY): New.
	(ARM_FSET_HAS_CPU1): New.
	(ARM_FSET_HAS_CPU2): New.
	(ARM_FSET_HAS_CPU): New.
	(ARM_FSET_ADD_CPU1): New.
	(ARM_FSET_ADD_CPU2): New.
	(ARM_FSET_DEL_CPU1): New.
	(ARM_FSET_DEL_CPU2): New.
	(ARM_FSET_UNION): New.
	(ARM_FSET_INTER): New.
	(ARM_FSET_XOR): New.
	(ARM_FSET_EXCLUDE): New.
	(AFM_FSET_IS_EMPTY): New.
	(ARM_FSET_CPU_SUBSET): New.

Comments

Ramana Radhakrishnan Aug. 10, 2015, 3:02 p.m. UTC | #1
On Mon, Aug 10, 2015 at 12:56:59PM +0100, Matthew Wahab wrote:
> The ARM backend uses an unsigned long to record CPU feature flags and
> there are currently 31 bits in use. This series of patches replaces the
> single unsigned long with a representation based on an array of values.
> 
> This patch adds, but doesn't use, type arm_feature_set and macros
> prefixed with ARM_FSET to represent and operate on feature sets.
> 
> Tested the series for arm-none-linux-gnueabihf with native bootstrap and
> make check.
> 
> gcc/
> 2015-08-10  Matthew Wahab  <matthew.wahab@arm.com>
> 
> 	* config/arm/arm-protos.h (FL_NONE): New.
> 	(FL_ANY): New.
> 	(arm_feature_set): New.
> 	(ARM_FSET_MAKE): New.
> 	(ARM_FSET_MAKE_CPU1): New.
> 	(ARM_FSET_MAKE_CPU2): New.
> 	(ARM_FSET_CPU1): New.
> 	(ARM_FSET_CPU2): New.
> 	(ARM_FSET_EMPTY): New.
> 	(ARM_FSET_ANY): New.
> 	(ARM_FSET_HAS_CPU1): New.
> 	(ARM_FSET_HAS_CPU2): New.
> 	(ARM_FSET_HAS_CPU): New.
> 	(ARM_FSET_ADD_CPU1): New.
> 	(ARM_FSET_ADD_CPU2): New.
> 	(ARM_FSET_DEL_CPU1): New.
> 	(ARM_FSET_DEL_CPU2): New.
> 	(ARM_FSET_UNION): New.
> 	(ARM_FSET_INTER): New.
> 	(ARM_FSET_XOR): New.
> 	(ARM_FSET_EXCLUDE): New.
> 	(AFM_FSET_IS_EMPTY): New.
> 	(ARM_FSET_CPU_SUBSET): New.
> 

> From fd51de4ebdbeff478716cf0a4329fd38cd861403 Mon Sep 17 00:00:00 2001
> From: Matthew Wahab <matthew.wahab@arm.com>
> Date: Thu, 4 Jun 2015 15:35:25 +0100
> Subject: [PATCH 2/5] Add feature set definitions.
> 
> Change-Id: I5f89b46ea57e35f477ec4751fea3cb6ee8fce251
> ---
>  gcc/config/arm/arm-protos.h | 105 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 105 insertions(+)
> 
> diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
> index cef9eec..610c73e 100644
> --- a/gcc/config/arm/arm-protos.h
> +++ b/gcc/config/arm/arm-protos.h
> @@ -346,6 +346,8 @@ extern bool arm_is_constant_pool_ref (rtx);
>  /* Flags used to identify the presence of processor capabilities.  */
>  
>  /* Bit values used to identify processor capabilities.  */
> +#define FL_NONE	      (0)	      /* No flags.  */
> +#define FL_ANY	      (0xffffffff)    /* All flags.  */
>  #define FL_CO_PROC    (1 << 0)        /* Has external co-processor bus */
>  #define FL_ARCH3M     (1 << 1)        /* Extended multiply */
>  #define FL_MODE26     (1 << 2)        /* 26-bit mode support */
> @@ -413,6 +415,109 @@ extern bool arm_is_constant_pool_ref (rtx);
>  #define FL_FOR_ARCH7EM  (FL_FOR_ARCH7M | FL_ARCH7EM)
>  #define FL_FOR_ARCH8A	(FL_FOR_ARCH7VE | FL_ARCH8)
>  
> +/* There are too many feature bits to fit in a single word so the set of cpu and
> +   fpu capabilities is a structure.  A feature set is created and manipulated
> +   with the ARM_FSET macros.  */
> +
> +typedef struct
> +{
> +  unsigned long cpu[2];
> +} arm_feature_set;
> +
> +
> +/* Initialize a feature set.  */
> +
> +#define ARM_FSET_MAKE(CPU1,CPU2) { { (CPU1), (CPU2) } }
> +
> +#define ARM_FSET_MAKE_CPU1(CPU1) ARM_FSET_MAKE ((CPU1), (FL_NONE))
> +#define ARM_FSET_MAKE_CPU2(CPU2) ARM_FSET_MAKE ((FL_NONE), (CPU2))
> +
> +/* Accessors.  */
> +
> +#define ARM_FSET_CPU1(S) ((S).cpu[0])
> +#define ARM_FSET_CPU2(S) ((S).cpu[1])
> +
> +/* Useful combinations.  */
> +
> +#define ARM_FSET_EMPTY ARM_FSET_MAKE (FL_NONE, FL_NONE)
> +#define ARM_FSET_ANY ARM_FSET_MAKE (FL_ANY, FL_ANY)
> +
> +/* Tests for a specific CPU feature.  */
> +
> +#define ARM_FSET_HAS_CPU1(A, F)  \
> +  (((A).cpu[0] & ((unsigned long)(F))) == ((unsigned long)(F)))
> +#define ARM_FSET_HAS_CPU2(A, F)  \
> +  (((A).cpu[1] & ((unsigned long)(F))) == ((unsigned long)(F)))
> +#define ARM_FSET_HAS_CPU(A, F1, F2)				\
> +  (ARM_FSET_HAS_CPU1 ((A), (F1)) && ARM_FSET_HAS_CPU2 ((A), (F2)))
> +
> +/* Add a feature to a feature set.  */
> +
> +#define ARM_FSET_ADD_CPU1(DST, F)		\
> +  do {						\
> +    (DST).cpu[0] |= (F);			\
> +  } while (0)
> +
> +#define ARM_FSET_ADD_CPU2(DST, F)		\
> +  do {						\
> +    (DST).cpu[1] |= (F);			\
> +  } while (0)
> +
> +/* Remove a feature from a feature set.  */
> +
> +#define ARM_FSET_DEL_CPU1(DST, F)		\
> +  do {						\
> +    (DST).cpu[0] &= ~(F);			\
> +  } while (0)
> +
> +#define ARM_FSET_DEL_CPU2(DST, F)		\
> +  do {						\
> +    (DST).cpu[1] &= ~(F);			\
> +  } while (0)
> +
> +/* Union of feature sets.  */
> +
> +#define ARM_FSET_UNION(DST,F1,F2)		\
> +  do {						\
> +    (DST).cpu[0] = (F1).cpu[0] | (F2).cpu[0];	\
> +    (DST).cpu[1] = (F1).cpu[1] | (F2).cpu[1];	\
> +  } while (0)
> +
> +/* Intersection of feature sets.  */
> +
> +#define ARM_FSET_INTER(DST,F1,F2)		\
> +  do {						\
> +    (DST).cpu[0] = (F1).cpu[0] & (F2).cpu[0];	\
> +    (DST).cpu[1] = (F1).cpu[1] & (F2).cpu[1];	\
> +  } while (0)
> +
> +/* Exclusive disjunction.  */
> +
> +#define ARM_FSET_XOR(DST,F1,F2)				\
> +  do {							\
> +    (DST).cpu[0] = (F1).cpu[0] ^ (F2).cpu[0];		\
> +    (DST).cpu[1] = (F1).cpu[1] ^ (F2).cpu[1];		\
> +  } while (0)
> +
> +/* Difference of feature sets: F1 excluding the elements of F2.  */
> +
> +#define ARM_FSET_EXCLUDE(DST,F1,F2)		\
> +  do {						\
> +    (DST).cpu[0] = (F1).cpu[0] & ~(F2).cpu[0];	\
> +    (DST).cpu[1] = (F1).cpu[1] & ~(F2).cpu[1];	\
> +  } while (0)
> +
> +/* Test for an empty feature set.  */
> +
> +#define ARM_FSET_IS_EMPTY(A)		\
> +  (!((A).cpu[0]) && !((A).cpu[1]))
> +
> +/* Tests whether the cpu features of A are a subset of B.  */
> +
> +#define ARM_FSET_CPU_SUBSET(A,B)					\
> +  ((((A).cpu[0] & (B).cpu[0]) == (A).cpu[0])				\
> +   && (((A).cpu[1] & (B).cpu[1]) == (A).cpu[1]))
> +
>  /* The bits in this mask specify which
>     instructions we are allowed to generate.  */
>  extern unsigned long insn_flags;
> -- 
> 1.9.1
> 


OK.

Ramana
diff mbox

Patch

From fd51de4ebdbeff478716cf0a4329fd38cd861403 Mon Sep 17 00:00:00 2001
From: Matthew Wahab <matthew.wahab@arm.com>
Date: Thu, 4 Jun 2015 15:35:25 +0100
Subject: [PATCH 2/5] Add feature set definitions.

Change-Id: I5f89b46ea57e35f477ec4751fea3cb6ee8fce251
---
 gcc/config/arm/arm-protos.h | 105 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 105 insertions(+)

diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index cef9eec..610c73e 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -346,6 +346,8 @@  extern bool arm_is_constant_pool_ref (rtx);
 /* Flags used to identify the presence of processor capabilities.  */
 
 /* Bit values used to identify processor capabilities.  */
+#define FL_NONE	      (0)	      /* No flags.  */
+#define FL_ANY	      (0xffffffff)    /* All flags.  */
 #define FL_CO_PROC    (1 << 0)        /* Has external co-processor bus */
 #define FL_ARCH3M     (1 << 1)        /* Extended multiply */
 #define FL_MODE26     (1 << 2)        /* 26-bit mode support */
@@ -413,6 +415,109 @@  extern bool arm_is_constant_pool_ref (rtx);
 #define FL_FOR_ARCH7EM  (FL_FOR_ARCH7M | FL_ARCH7EM)
 #define FL_FOR_ARCH8A	(FL_FOR_ARCH7VE | FL_ARCH8)
 
+/* There are too many feature bits to fit in a single word so the set of cpu and
+   fpu capabilities is a structure.  A feature set is created and manipulated
+   with the ARM_FSET macros.  */
+
+typedef struct
+{
+  unsigned long cpu[2];
+} arm_feature_set;
+
+
+/* Initialize a feature set.  */
+
+#define ARM_FSET_MAKE(CPU1,CPU2) { { (CPU1), (CPU2) } }
+
+#define ARM_FSET_MAKE_CPU1(CPU1) ARM_FSET_MAKE ((CPU1), (FL_NONE))
+#define ARM_FSET_MAKE_CPU2(CPU2) ARM_FSET_MAKE ((FL_NONE), (CPU2))
+
+/* Accessors.  */
+
+#define ARM_FSET_CPU1(S) ((S).cpu[0])
+#define ARM_FSET_CPU2(S) ((S).cpu[1])
+
+/* Useful combinations.  */
+
+#define ARM_FSET_EMPTY ARM_FSET_MAKE (FL_NONE, FL_NONE)
+#define ARM_FSET_ANY ARM_FSET_MAKE (FL_ANY, FL_ANY)
+
+/* Tests for a specific CPU feature.  */
+
+#define ARM_FSET_HAS_CPU1(A, F)  \
+  (((A).cpu[0] & ((unsigned long)(F))) == ((unsigned long)(F)))
+#define ARM_FSET_HAS_CPU2(A, F)  \
+  (((A).cpu[1] & ((unsigned long)(F))) == ((unsigned long)(F)))
+#define ARM_FSET_HAS_CPU(A, F1, F2)				\
+  (ARM_FSET_HAS_CPU1 ((A), (F1)) && ARM_FSET_HAS_CPU2 ((A), (F2)))
+
+/* Add a feature to a feature set.  */
+
+#define ARM_FSET_ADD_CPU1(DST, F)		\
+  do {						\
+    (DST).cpu[0] |= (F);			\
+  } while (0)
+
+#define ARM_FSET_ADD_CPU2(DST, F)		\
+  do {						\
+    (DST).cpu[1] |= (F);			\
+  } while (0)
+
+/* Remove a feature from a feature set.  */
+
+#define ARM_FSET_DEL_CPU1(DST, F)		\
+  do {						\
+    (DST).cpu[0] &= ~(F);			\
+  } while (0)
+
+#define ARM_FSET_DEL_CPU2(DST, F)		\
+  do {						\
+    (DST).cpu[1] &= ~(F);			\
+  } while (0)
+
+/* Union of feature sets.  */
+
+#define ARM_FSET_UNION(DST,F1,F2)		\
+  do {						\
+    (DST).cpu[0] = (F1).cpu[0] | (F2).cpu[0];	\
+    (DST).cpu[1] = (F1).cpu[1] | (F2).cpu[1];	\
+  } while (0)
+
+/* Intersection of feature sets.  */
+
+#define ARM_FSET_INTER(DST,F1,F2)		\
+  do {						\
+    (DST).cpu[0] = (F1).cpu[0] & (F2).cpu[0];	\
+    (DST).cpu[1] = (F1).cpu[1] & (F2).cpu[1];	\
+  } while (0)
+
+/* Exclusive disjunction.  */
+
+#define ARM_FSET_XOR(DST,F1,F2)				\
+  do {							\
+    (DST).cpu[0] = (F1).cpu[0] ^ (F2).cpu[0];		\
+    (DST).cpu[1] = (F1).cpu[1] ^ (F2).cpu[1];		\
+  } while (0)
+
+/* Difference of feature sets: F1 excluding the elements of F2.  */
+
+#define ARM_FSET_EXCLUDE(DST,F1,F2)		\
+  do {						\
+    (DST).cpu[0] = (F1).cpu[0] & ~(F2).cpu[0];	\
+    (DST).cpu[1] = (F1).cpu[1] & ~(F2).cpu[1];	\
+  } while (0)
+
+/* Test for an empty feature set.  */
+
+#define ARM_FSET_IS_EMPTY(A)		\
+  (!((A).cpu[0]) && !((A).cpu[1]))
+
+/* Tests whether the cpu features of A are a subset of B.  */
+
+#define ARM_FSET_CPU_SUBSET(A,B)					\
+  ((((A).cpu[0] & (B).cpu[0]) == (A).cpu[0])				\
+   && (((A).cpu[1] & (B).cpu[1]) == (A).cpu[1]))
+
 /* The bits in this mask specify which
    instructions we are allowed to generate.  */
 extern unsigned long insn_flags;
-- 
1.9.1