Re: [PATCH][ARM] NEON DImode immediate constants

2012-04-30 Thread Andrew Stubbs

On 27/04/12 16:17, Richard Earnshaw wrote:

This is OK.


Thanks, now committed.


It would be good to merge all the target32 movdi variants into one
pattern and then use alternative enabling to deal with the different
valid alternatives.


Yes, I'll take a look.

Andrew


Re: [PATCH][ARM] NEON DImode immediate constants

2012-04-27 Thread Andrew Stubbs

Ping.

On 10/04/12 14:00, Andrew Stubbs wrote:

Ping.

On 30/03/12 12:15, Andrew Stubbs wrote:

On 28/02/12 16:20, Andrew Stubbs wrote:

Hi all,

This patch implements 64-bit immediate constant loads in NEON.

The current state is that you can load const_vector, but not const_int.
This is clearly not ideal. The result is a constant pool entry when it's
not necessary.

The patch disables the movdi_vfp patterns for loading DImode values, if
the operand is const_int and NEON is enabled, and extends the neon_mov
pattern to include DImode const_int, as well as the const_vector
operands. I've modified neon_valid_immediate only enough to accept
const_int input - the logic remains untouched.


That patch failed to bootstrap successfully, but this updated patch
bootstraps and tests with no regressions.

OK?

Andrew







Re: [PATCH][ARM] NEON DImode immediate constants

2012-04-27 Thread Richard Earnshaw
On 30/03/12 12:15, Andrew Stubbs wrote:
 On 28/02/12 16:20, Andrew Stubbs wrote:
 Hi all,

 This patch implements 64-bit immediate constant loads in NEON.

 The current state is that you can load const_vector, but not const_int.
 This is clearly not ideal. The result is a constant pool entry when it's
 not necessary.

 The patch disables the movdi_vfp patterns for loading DImode values, if
 the operand is const_int and NEON is enabled, and extends the neon_mov
 pattern to include DImode const_int, as well as the const_vector
 operands. I've modified neon_valid_immediate only enough to accept
 const_int input - the logic remains untouched.
 
 That patch failed to bootstrap successfully, but this updated patch 
 bootstraps and tests with no regressions.
 
 OK?

Sorry for the delay.

This is OK.

It would be good to merge all the target32 movdi variants into one
pattern and then use alternative enabling to deal with the different
valid alternatives.

R.
 
 Andrew
 
 
 neon-loadimm64.patch
 
 
 2012-03-27  Andrew Stubbs  a...@codesourcery.com
 
   gcc/
   * config/arm/arm.c (neon_valid_immediate): Allow const_int.
   (arm_print_operand): Add 'x' format.
   * config/arm/constraints.md (Dn): Allow const_int.
   * config/arm/neon.md (neon_movmode): Use VDX to allow DImode.
   Use 'x' format to print constants.
   * config/arm/predicates.md (imm_for_neon_mov_operand): Allow const_int.
   * config/arm/vfp.md (movdi_vfp): Disable for const_int when neon
   is enabled.
   (movdi_vfp_cortexa8): Likewise.
 
 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
 index 0bded8d..492ddde 100644
 --- a/gcc/config/arm/arm.c
 +++ b/gcc/config/arm/arm.c
 @@ -8873,11 +8873,25 @@ neon_valid_immediate (rtx op, enum machine_mode mode, 
 int inverse,
break; \
  }
  
 -  unsigned int i, elsize = 0, idx = 0, n_elts = CONST_VECTOR_NUNITS (op);
 -  unsigned int innersize = GET_MODE_SIZE (GET_MODE_INNER (mode));
 +  unsigned int i, elsize = 0, idx = 0, n_elts;
 +  unsigned int innersize;
unsigned char bytes[16];
int immtype = -1, matches;
unsigned int invmask = inverse ? 0xff : 0;
 +  bool vector = GET_CODE (op) == CONST_VECTOR;
 +
 +  if (vector)
 +{
 +  n_elts = CONST_VECTOR_NUNITS (op);
 +  innersize = GET_MODE_SIZE (GET_MODE_INNER (mode));
 +}
 +  else
 +{
 +  n_elts = 1;
 +  if (mode == VOIDmode)
 + mode = DImode;
 +  innersize = GET_MODE_SIZE (mode);
 +}
  
/* Vectors of float constants.  */
if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
 @@ -8913,7 +8927,7 @@ neon_valid_immediate (rtx op, enum machine_mode mode, 
 int inverse,
/* Splat vector constant out into a byte vector.  */
for (i = 0; i  n_elts; i++)
  {
 -  rtx el = CONST_VECTOR_ELT (op, i);
 +  rtx el = vector ? CONST_VECTOR_ELT (op, i) : op;
unsigned HOST_WIDE_INT elpart;
unsigned int part, parts;
  
 @@ -17230,6 +17244,19 @@ arm_print_operand (FILE *stream, rtx x, int code)
   }
return;
  
 +/* An integer that we want to print in HEX.  */
 +case 'x':
 +  switch (GET_CODE (x))
 + {
 + case CONST_INT:
 +   fprintf (stream, # HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
 +   break;
 +
 + default:
 +   output_operand_lossage (Unsupported operand for code '%c', code);
 + }
 +  return;
 +
  case 'B':
if (GET_CODE (x) == CONST_INT)
   {
 diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
 index 7d0269a..68979c1 100644
 --- a/gcc/config/arm/constraints.md
 +++ b/gcc/config/arm/constraints.md
 @@ -255,9 +255,9 @@
  
  (define_constraint Dn
   @internal
 -  In ARM/Thumb-2 state a const_vector which can be loaded with a Neon vmov
 -  immediate instruction.
 - (and (match_code const_vector)
 +  In ARM/Thumb-2 state a const_vector or const_int which can be loaded with a
 +  Neon vmov immediate instruction.
 + (and (match_code const_vector,const_int)
(match_test TARGET_32BIT
   imm_for_neon_mov_operand (op, GET_MODE (op)
  
 diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
 index d7caa37..3c88568 100644
 --- a/gcc/config/arm/neon.md
 +++ b/gcc/config/arm/neon.md
 @@ -152,9 +152,9 @@
  (define_attr vqh_mnem vadd,vmin,vmax (const_string vadd))
  
  (define_insn *neon_movmode
 -  [(set (match_operand:VD 0 nonimmediate_operand
 +  [(set (match_operand:VDX 0 nonimmediate_operand
 =w,Uv,w, w,  ?r,?w,?r,?r, ?Us)
 - (match_operand:VD 1 general_operand
 + (match_operand:VDX 1 general_operand
  w,w, Dn,Uvi, w, r, r, Usi,r))]
TARGET_NEON
  (register_operand (operands[0], MODEmode)
 @@ -173,7 +173,7 @@
if (width == 0)
  return vmov.f32\t%P0, %1  @ mode;
else
 -sprintf (templ, vmov.i%d\t%%P0, %%1  @ mode, width);
 +sprintf (templ, vmov.i%d\t%%P0, %%x1  @ mode, width);
  
return templ;
  }
 diff --git 

Re: [PATCH][ARM] NEON DImode immediate constants

2012-04-10 Thread Andrew Stubbs

Ping.

On 30/03/12 12:15, Andrew Stubbs wrote:

On 28/02/12 16:20, Andrew Stubbs wrote:

Hi all,

This patch implements 64-bit immediate constant loads in NEON.

The current state is that you can load const_vector, but not const_int.
This is clearly not ideal. The result is a constant pool entry when it's
not necessary.

The patch disables the movdi_vfp patterns for loading DImode values, if
the operand is const_int and NEON is enabled, and extends the neon_mov
pattern to include DImode const_int, as well as the const_vector
operands. I've modified neon_valid_immediate only enough to accept
const_int input - the logic remains untouched.


That patch failed to bootstrap successfully, but this updated patch
bootstraps and tests with no regressions.

OK?

Andrew




Re: [PATCH][ARM] NEON DImode immediate constants

2012-03-30 Thread Andrew Stubbs

On 28/02/12 16:20, Andrew Stubbs wrote:

Hi all,

This patch implements 64-bit immediate constant loads in NEON.

The current state is that you can load const_vector, but not const_int.
This is clearly not ideal. The result is a constant pool entry when it's
not necessary.

The patch disables the movdi_vfp patterns for loading DImode values, if
the operand is const_int and NEON is enabled, and extends the neon_mov
pattern to include DImode const_int, as well as the const_vector
operands. I've modified neon_valid_immediate only enough to accept
const_int input - the logic remains untouched.


That patch failed to bootstrap successfully, but this updated patch 
bootstraps and tests with no regressions.


OK?

Andrew
2012-03-27  Andrew Stubbs  a...@codesourcery.com

	gcc/
	* config/arm/arm.c (neon_valid_immediate): Allow const_int.
	(arm_print_operand): Add 'x' format.
	* config/arm/constraints.md (Dn): Allow const_int.
	* config/arm/neon.md (neon_movmode): Use VDX to allow DImode.
	Use 'x' format to print constants.
	* config/arm/predicates.md (imm_for_neon_mov_operand): Allow const_int.
	* config/arm/vfp.md (movdi_vfp): Disable for const_int when neon
	is enabled.
	(movdi_vfp_cortexa8): Likewise.

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 0bded8d..492ddde 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -8873,11 +8873,25 @@ neon_valid_immediate (rtx op, enum machine_mode mode, int inverse,
   break;	\
 }
 
-  unsigned int i, elsize = 0, idx = 0, n_elts = CONST_VECTOR_NUNITS (op);
-  unsigned int innersize = GET_MODE_SIZE (GET_MODE_INNER (mode));
+  unsigned int i, elsize = 0, idx = 0, n_elts;
+  unsigned int innersize;
   unsigned char bytes[16];
   int immtype = -1, matches;
   unsigned int invmask = inverse ? 0xff : 0;
+  bool vector = GET_CODE (op) == CONST_VECTOR;
+
+  if (vector)
+{
+  n_elts = CONST_VECTOR_NUNITS (op);
+  innersize = GET_MODE_SIZE (GET_MODE_INNER (mode));
+}
+  else
+{
+  n_elts = 1;
+  if (mode == VOIDmode)
+	mode = DImode;
+  innersize = GET_MODE_SIZE (mode);
+}
 
   /* Vectors of float constants.  */
   if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
@@ -8913,7 +8927,7 @@ neon_valid_immediate (rtx op, enum machine_mode mode, int inverse,
   /* Splat vector constant out into a byte vector.  */
   for (i = 0; i  n_elts; i++)
 {
-  rtx el = CONST_VECTOR_ELT (op, i);
+  rtx el = vector ? CONST_VECTOR_ELT (op, i) : op;
   unsigned HOST_WIDE_INT elpart;
   unsigned int part, parts;
 
@@ -17230,6 +17244,19 @@ arm_print_operand (FILE *stream, rtx x, int code)
 	}
   return;
 
+/* An integer that we want to print in HEX.  */
+case 'x':
+  switch (GET_CODE (x))
+	{
+	case CONST_INT:
+	  fprintf (stream, # HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
+	  break;
+
+	default:
+	  output_operand_lossage (Unsupported operand for code '%c', code);
+	}
+  return;
+
 case 'B':
   if (GET_CODE (x) == CONST_INT)
 	{
diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
index 7d0269a..68979c1 100644
--- a/gcc/config/arm/constraints.md
+++ b/gcc/config/arm/constraints.md
@@ -255,9 +255,9 @@
 
 (define_constraint Dn
  @internal
-  In ARM/Thumb-2 state a const_vector which can be loaded with a Neon vmov
-  immediate instruction.
- (and (match_code const_vector)
+  In ARM/Thumb-2 state a const_vector or const_int which can be loaded with a
+  Neon vmov immediate instruction.
+ (and (match_code const_vector,const_int)
   (match_test TARGET_32BIT
 		imm_for_neon_mov_operand (op, GET_MODE (op)
 
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index d7caa37..3c88568 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -152,9 +152,9 @@
 (define_attr vqh_mnem vadd,vmin,vmax (const_string vadd))
 
 (define_insn *neon_movmode
-  [(set (match_operand:VD 0 nonimmediate_operand
+  [(set (match_operand:VDX 0 nonimmediate_operand
 	  =w,Uv,w, w,  ?r,?w,?r,?r, ?Us)
-	(match_operand:VD 1 general_operand
+	(match_operand:VDX 1 general_operand
 	   w,w, Dn,Uvi, w, r, r, Usi,r))]
   TARGET_NEON
 (register_operand (operands[0], MODEmode)
@@ -173,7 +173,7 @@
   if (width == 0)
 return vmov.f32\t%P0, %1  @ mode;
   else
-sprintf (templ, vmov.i%d\t%%P0, %%1  @ mode, width);
+sprintf (templ, vmov.i%d\t%%P0, %%x1  @ mode, width);
 
   return templ;
 }
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index b535335..8a8a1f1 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -630,7 +630,7 @@
 })
 
 (define_predicate imm_for_neon_mov_operand
-  (match_code const_vector)
+  (match_code const_vector,const_int)
 {
   return neon_immediate_valid_for_move (op, mode, NULL, NULL);
 })
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index 6530570..2061414 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -138,7 +138,9 @@

[PATCH][ARM] NEON DImode immediate constants

2012-02-28 Thread Andrew Stubbs

Hi all,

This patch implements 64-bit immediate constant loads in NEON.

The current state is that you can load const_vector, but not const_int. 
This is clearly not ideal. The result is a constant pool entry when it's 
not necessary.


The patch disables the movdi_vfp patterns for loading DImode values, if 
the operand is const_int and NEON is enabled, and extends the neon_mov 
pattern to include DImode const_int, as well as the const_vector 
operands. I've modified neon_valid_immediate only enough to accept 
const_int input - the logic remains untouched.


OK for 4.8?

Andrew
2012-02-28  Andrew Stubbs  a...@codesourcery.com

	gcc/
	* config/arm/arm.c (neon_valid_immediate): Allow const_int.
	* config/arm/constraints.md (Dn): Allow const_int.
	* config/arm/neon.md (neon_movmode): Use VDX to allow DImode.
	* config/arm/predicates.md (imm_for_neon_mov_operand): Allow const_int.
	* config/arm/vfp.md (movdi_vfp): Disable for const_int when neon
	is enabled.
	(movdi_vfp_cortexa8): Likewise.

---
 gcc/config/arm/arm.c  |   20 +---
 gcc/config/arm/constraints.md |6 +++---
 gcc/config/arm/neon.md|4 ++--
 gcc/config/arm/predicates.md  |2 +-
 gcc/config/arm/vfp.md |6 --
 5 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 0bded8d..ea2a256 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -8873,11 +8873,25 @@ neon_valid_immediate (rtx op, enum machine_mode mode, int inverse,
   break;	\
 }
 
-  unsigned int i, elsize = 0, idx = 0, n_elts = CONST_VECTOR_NUNITS (op);
-  unsigned int innersize = GET_MODE_SIZE (GET_MODE_INNER (mode));
+  unsigned int i, elsize = 0, idx = 0, n_elts;
+  unsigned int innersize;
   unsigned char bytes[16];
   int immtype = -1, matches;
   unsigned int invmask = inverse ? 0xff : 0;
+  bool vector = GET_CODE (op) == CONST_VECTOR;
+
+  if (vector)
+{
+  n_elts = CONST_VECTOR_NUNITS (op);
+  innersize = GET_MODE_SIZE (GET_MODE_INNER (mode));
+}
+  else
+{
+  n_elts = 1;
+  if (mode == VOIDmode)
+	mode = DImode;
+  innersize = GET_MODE_SIZE (mode);
+}
 
   /* Vectors of float constants.  */
   if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
@@ -8913,7 +8927,7 @@ neon_valid_immediate (rtx op, enum machine_mode mode, int inverse,
   /* Splat vector constant out into a byte vector.  */
   for (i = 0; i  n_elts; i++)
 {
-  rtx el = CONST_VECTOR_ELT (op, i);
+  rtx el = vector ? CONST_VECTOR_ELT (op, i) : op;
   unsigned HOST_WIDE_INT elpart;
   unsigned int part, parts;
 
diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
index 7d0269a..68979c1 100644
--- a/gcc/config/arm/constraints.md
+++ b/gcc/config/arm/constraints.md
@@ -255,9 +255,9 @@
 
 (define_constraint Dn
  @internal
-  In ARM/Thumb-2 state a const_vector which can be loaded with a Neon vmov
-  immediate instruction.
- (and (match_code const_vector)
+  In ARM/Thumb-2 state a const_vector or const_int which can be loaded with a
+  Neon vmov immediate instruction.
+ (and (match_code const_vector,const_int)
   (match_test TARGET_32BIT
 		imm_for_neon_mov_operand (op, GET_MODE (op)
 
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index d7caa37..757be01 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -152,9 +152,9 @@
 (define_attr vqh_mnem vadd,vmin,vmax (const_string vadd))
 
 (define_insn *neon_movmode
-  [(set (match_operand:VD 0 nonimmediate_operand
+  [(set (match_operand:VDX 0 nonimmediate_operand
 	  =w,Uv,w, w,  ?r,?w,?r,?r, ?Us)
-	(match_operand:VD 1 general_operand
+	(match_operand:VDX 1 general_operand
 	   w,w, Dn,Uvi, w, r, r, Usi,r))]
   TARGET_NEON
 (register_operand (operands[0], MODEmode)
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index b535335..8a8a1f1 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -630,7 +630,7 @@
 })
 
 (define_predicate imm_for_neon_mov_operand
-  (match_code const_vector)
+  (match_code const_vector,const_int)
 {
   return neon_immediate_valid_for_move (op, mode, NULL, NULL);
 })
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index 6530570..2cc4104 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -138,7 +138,8 @@
(match_operand:DI 1 di_operand  r,rDa,Db,Dc,mi,mi,r,r,w,w,Uvi,w))]
   TARGET_32BIT  TARGET_HARD_FLOAT  TARGET_VFP  arm_tune != cortexa8
 (   register_operand (operands[0], DImode)
-   || register_operand (operands[1], DImode))
+   || register_operand (operands[1], DImode))
+(!TARGET_NEON || !CONST_INT_P (operands[1]))
   *
   switch (which_alternative)
 {
@@ -187,7 +188,8 @@
(match_operand:DI 1 di_operand  r,rDa,Db,Dc,mi,mi,r,r,w,w,Uvi,w))]
   TARGET_32BIT  TARGET_HARD_FLOAT  TARGET_VFP  arm_tune == cortexa8
  (   register_operand (operands[0], DImode)
-||