Re: [PATCH][ARM] Improve use of conditional execution in thumb mode.

2012-03-21 Thread Andrew Stubbs

On 19/03/12 14:48, Richard Earnshaw wrote:

OK.


Committed.

Andrew


Re: [PATCH][ARM] Improve use of conditional execution in thumb mode.

2012-03-19 Thread Andrew Stubbs

Ping.

On 08/03/12 15:48, Andrew Stubbs wrote:

On 17/02/12 15:30, Andrew Stubbs wrote:

I've got a full test run going again.

OK for 4.8, again?


The test run revealed some bugs handling MINUS.

This update has been tested and passes a bootstrap and test with no
regressions. Indeed, it has actually corrected a failure in
gcc.target/arm/combine-movs.c.

OK?

Andrew




Re: [PATCH][ARM] Improve use of conditional execution in thumb mode.

2012-03-19 Thread Richard Earnshaw
On 08/03/12 15:48, Andrew Stubbs wrote:
 On 17/02/12 15:30, Andrew Stubbs wrote:
 I've got a full test run going again.

 OK for 4.8, again?
 
 The test run revealed some bugs handling MINUS.
 
 This update has been tested and passes a bootstrap and test with no 
 regressions. Indeed, it has actually corrected a failure in 
 gcc.target/arm/combine-movs.c.
 
 OK?
 

OK.

R.



Re: [PATCH][ARM] Improve use of conditional execution in thumb mode.

2012-03-08 Thread Andrew Stubbs

On 17/02/12 15:30, Andrew Stubbs wrote:

I've got a full test run going again.

OK for 4.8, again?


The test run revealed some bugs handling MINUS.

This update has been tested and passes a bootstrap and test with no 
regressions. Indeed, it has actually corrected a failure in 
gcc.target/arm/combine-movs.c.


OK?

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

	gcc/
	* config/arm/arm.c (thumb2_reorg): Add complete support
	for 16-bit instructions.
	* config/arm/thumb2.md: Delete obsolete flag-clobbering peepholes.

	gcc/testsuite/
	* gcc.target/arm/thumb-16bit-ops.c: New file.
	* gcc.target/arm/thumb-ifcvt.c: New file.

---
 gcc/config/arm/arm.c   |  157 ---
 gcc/config/arm/thumb2.md   |  107 -
 gcc/testsuite/gcc.target/arm/thumb-16bit-ops.c |  196 
 gcc/testsuite/gcc.target/arm/thumb-ifcvt.c |   19 ++
 4 files changed, 344 insertions(+), 135 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arm/thumb-16bit-ops.c
 create mode 100644 gcc/testsuite/gcc.target/arm/thumb-ifcvt.c

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 0bded8d..44f99c1 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -13246,47 +13246,148 @@ thumb2_reorg (void)
   FOR_BB_INSNS_REVERSE (bb, insn)
 	{
 	  if (NONJUMP_INSN_P (insn)
-	   !REGNO_REG_SET_P (live, CC_REGNUM))
+	   !REGNO_REG_SET_P (live, CC_REGNUM)
+	   GET_CODE (PATTERN (insn)) == SET)
 	{
+	  enum {SKIP, CONV, SWAP_CONV} action = SKIP;
 	  rtx pat = PATTERN (insn);
-	  if (GET_CODE (pat) == SET
-		   low_register_operand (XEXP (pat, 0), SImode)
-		   thumb_16bit_operator (XEXP (pat, 1), SImode)
-		   low_register_operand (XEXP (XEXP (pat, 1), 0), SImode)
-		   low_register_operand (XEXP (XEXP (pat, 1), 1), SImode))
+	  rtx dst = XEXP (pat, 0);
+	  rtx src = XEXP (pat, 1);
+	  rtx op0 = NULL_RTX, op1 = NULL_RTX;
+
+	  if (!OBJECT_P (src))
+		  op0 = XEXP (src, 0);
+
+	  if (BINARY_P (src))
+		  op1 = XEXP (src, 1);
+
+	  if (low_register_operand (dst, SImode))
 		{
-		  rtx dst = XEXP (pat, 0);
-		  rtx src = XEXP (pat, 1);
-		  rtx op0 = XEXP (src, 0);
-		  rtx op1 = (GET_RTX_CLASS (GET_CODE (src)) == RTX_COMM_ARITH
-			 ? XEXP (src, 1) : NULL);
-
-		  if (rtx_equal_p (dst, op0)
-		  || GET_CODE (src) == PLUS || GET_CODE (src) == MINUS)
+		  switch (GET_CODE (src))
 		{
-		  rtx ccreg = gen_rtx_REG (CCmode, CC_REGNUM);
-		  rtx clobber = gen_rtx_CLOBBER (VOIDmode, ccreg);
-		  rtvec vec = gen_rtvec (2, pat, clobber);
+		case PLUS:
+		  if (low_register_operand (op0, SImode))
+			{
+			  /* ADDS Rd,Rn,Rm  */
+			  if (low_register_operand (op1, SImode))
+			action = CONV;
+			  /* ADDS Rdn,#imm8  */
+			  /* SUBS Rdn,#imm8  */
+			  else if (rtx_equal_p (dst, op0)
+CONST_INT_P (op1)
+IN_RANGE (INTVAL (op1), -255, 255))
+			action = CONV;
+			  /* ADDS Rd,Rn,#imm3  */
+			  /* SUBS Rd,Rn,#imm3  */
+			  else if (CONST_INT_P (op1)
+IN_RANGE (INTVAL (op1), -7, 7))
+			action = CONV;
+			}
+		  break;
+
+		case MINUS:
+		  /* RSBS Rd,Rn,#0  
+			 Not handled here: see NEG below.  */
+		  /* SUBS Rd,Rn,#imm3
+			 SUBS Rdn,#imm8
+			 Not handled here: see PLUS above.  */
+		  /* SUBS Rd,Rn,Rm  */
+		  if (low_register_operand (op0, SImode)
+			   low_register_operand (op1, SImode))
+			action = CONV;
+		  break;
+
+		case MULT:
+		  /* MULS Rdm,Rn,Rdm
+			 As an exception to the rule, this is only used
+			 when optimizing for size since MULS is slow on all
+			 known implementations.  We do not even want to use
+			 MULS in cold code, if optimizing for speed, so we
+			 test the global flag here.  */
+		  if (!optimize_size)
+			break;
+		  /* else fall through.  */
+		case AND:
+		case IOR:
+		case XOR:
+		  /* ANDS Rdn,Rm  */
+		  if (rtx_equal_p (dst, op0)
+			   low_register_operand (op1, SImode))
+			action = CONV;
+		  else if (rtx_equal_p (dst, op1)
+			low_register_operand (op0, SImode))
+			action = SWAP_CONV;
+		  break;
+
+		case ASHIFTRT:
+		case ASHIFT:
+		case LSHIFTRT:
+		  /* ASRS Rdn,Rm */
+		  /* LSRS Rdn,Rm */
+		  /* LSLS Rdn,Rm */
+		  if (rtx_equal_p (dst, op0)
+			   low_register_operand (op1, SImode))
+			action = CONV;
+		  /* ASRS Rd,Rm,#imm5 */
+		  /* LSRS Rd,Rm,#imm5 */
+		  /* LSLS Rd,Rm,#imm5 */
+		  else if (low_register_operand (op0, SImode)
+			CONST_INT_P (op1)
+			IN_RANGE (INTVAL (op1), 0, 31))
+			action = CONV;
+		  break;
+
+		case ROTATERT:
+		  /* RORS Rdn,Rm  */
+		  if (rtx_equal_p (dst, op0)
+			   low_register_operand (op1, SImode))
+			action = CONV;
+		  break;
 
-		  PATTERN (insn) = gen_rtx_PARALLEL (VOIDmode, vec);
-		  INSN_CODE (insn) = -1;
+		case NOT:
+		case NEG:
+		  /* 

Re: [PATCH][ARM] Improve use of conditional execution in thumb mode.

2012-02-17 Thread Andrew Stubbs

On 14/02/12 18:00, Andrew Stubbs wrote:

On Tue 14 Feb 2012 17:35:36 GMT, Richard Earnshaw wrote:

Bernds checked in a patch last year (or maybe even before that) to make
the selection of flags clobbered insns run very late (certainly after
condexec had run), so I'm not sure why you're not seeing this.


Hm, you mentioned some peepholes. Try removing them


Hmmm, it seems you're right. The machine reorg pass now takes care of
this. Well ... that was easy!

Here's a patch to remove the obsolete peepholes. I've confirmed it works
with the testcase.


Testing revealed that the new thumb_reorg code was not as thorough as 
the old peepholes at converting insns to 16-bit encodings.


This updated patch rewrites thumb_reorg to fix up all the missing cases, 
and adds a testcase to make sure it's all good. The parts that were in 
the old patch are unchanged.


I did initially try to insert the new cases into the old code, but the 
if conditions got way out of hand, and/or I ended up duplicating the 
active code. I've therefore recast the code to make it more scalable, 
but it boils down to the exact same thing.


I've got a full test run going again.

OK for 4.8, again?

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

	gcc/
	* config/arm/arm.c (thumb2_reorg): Add complete support
	for 16-bit instructions.
	* config/arm/thumb2.md: Delete obsolete flag-clobbering peepholes.

	gcc/testsuite/
	* gcc.target/arm/thumb-16bit-ops.c: New file.
	* gcc.target/arm/thumb-ifcvt.c: New file.

---
 gcc/config/arm/arm.c   |  132 +++
 gcc/config/arm/thumb2.md   |  107 
 gcc/testsuite/gcc.target/arm/thumb-16bit-ops.c |  164 
 gcc/testsuite/gcc.target/arm/thumb-ifcvt.c |   19 +++
 4 files changed, 286 insertions(+), 136 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arm/thumb-16bit-ops.c
 create mode 100644 gcc/testsuite/gcc.target/arm/thumb-ifcvt.c

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 0bded8d..c3a19e4 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -13246,47 +13246,121 @@ thumb2_reorg (void)
   FOR_BB_INSNS_REVERSE (bb, insn)
 	{
 	  if (NONJUMP_INSN_P (insn)
-	   !REGNO_REG_SET_P (live, CC_REGNUM))
+	   !REGNO_REG_SET_P (live, CC_REGNUM)
+	   GET_CODE (PATTERN (insn)) == SET)
 	{
+	  enum {SKIP, CONV, SWAP_CONV} action = SKIP;
 	  rtx pat = PATTERN (insn);
-	  if (GET_CODE (pat) == SET
-		   low_register_operand (XEXP (pat, 0), SImode)
-		   thumb_16bit_operator (XEXP (pat, 1), SImode)
-		   low_register_operand (XEXP (XEXP (pat, 1), 0), SImode)
-		   low_register_operand (XEXP (XEXP (pat, 1), 1), SImode))
+	  rtx dst = XEXP (pat, 0);
+	  rtx src = XEXP (pat, 1);
+	  rtx op0 = NULL_RTX, op1 = NULL_RTX;
+
+	  if (!OBJECT_P (src))
+		  op0 = XEXP (src, 0);
+
+	  if (BINARY_P (src))
+		  op1 = XEXP (src, 1);
+
+	  if (low_register_operand (dst, SImode))
 		{
-		  rtx dst = XEXP (pat, 0);
-		  rtx src = XEXP (pat, 1);
-		  rtx op0 = XEXP (src, 0);
-		  rtx op1 = (GET_RTX_CLASS (GET_CODE (src)) == RTX_COMM_ARITH
-			 ? XEXP (src, 1) : NULL);
-
-		  if (rtx_equal_p (dst, op0)
-		  || GET_CODE (src) == PLUS || GET_CODE (src) == MINUS)
+		  switch (GET_CODE (src))
 		{
-		  rtx ccreg = gen_rtx_REG (CCmode, CC_REGNUM);
-		  rtx clobber = gen_rtx_CLOBBER (VOIDmode, ccreg);
-		  rtvec vec = gen_rtvec (2, pat, clobber);
-
-		  PATTERN (insn) = gen_rtx_PARALLEL (VOIDmode, vec);
-		  INSN_CODE (insn) = -1;
+		case PLUS:
+		case MINUS:
+		  if (low_register_operand (op0, SImode))
+			{
+			  /* ADDS Rd,Rn,Rm  */
+			  if (low_register_operand (op1, SImode))
+			action = CONV;
+			  /* ADDS Rdn,#imm8  */
+			  else if (rtx_equal_p (dst, op0)
+CONST_INT_P (op1)
+IN_RANGE (INTVAL (op1), 0, 255))
+			action = CONV;
+			  /* ADDS Rd,Rn,#imm3  */
+			  else if (CONST_INT_P (op1)
+IN_RANGE (INTVAL (op1), 0, 7))
+			action = CONV;
+			}
+		  break;
+		case MULT:
+		  /* MULS Rdm,Rn,Rdm
+			 As an exception to the rule, this is only used
+			 when optimizing for size since MULS is slow on all
+			 known implementations.  */
+		  if (!optimize_function_for_size_p (cfun))
+			break;
+		  /* else fall through.  */
+		case AND:
+		case IOR:
+		case XOR:
+		  /* ANDS Rdn,Rm  */
+		  if (rtx_equal_p (dst, op0)
+			   low_register_operand (op1, SImode))
+			action = CONV;
+		  else if (rtx_equal_p (dst, op1)
+			low_register_operand (op0, SImode))
+			action = SWAP_CONV;
+		  break;
+		case ASHIFTRT:
+		case ASHIFT:
+		case LSHIFTRT:
+		  /* ASRS Rdn,Rm */
+		  if (rtx_equal_p (dst, op0)
+			   low_register_operand (op1, SImode))
+			action = CONV;
+		  /* ASRS Rd,Rm,#imm5 */
+		  else if (low_register_operand (op0, SImode)
+			CONST_INT_P (op1)
+			IN_RANGE