From 28907f9a0a6452810467d7519f09873b5b7cd6be Mon Sep 17 00:00:00 2001
From: Mark Shinwell <shinwell@codesourcery.com>
Date: Thu, 15 Apr 2010 14:39:22 +0000
Subject: [PATCH] thumb2.md (thumb2_movsi_insn): Split ldr and str alternatives
 according to use of high and low regs.

	gcc/
	* config/arm/thumb2.md (thumb2_movsi_insn): Split ldr and str
	alternatives according to use of high and low regs.
	* config/arm/vfp.md (thumb2_movsi_vfp): Likewise.
	* config/arm/arm.h (CONDITIONAL_REGISTER_USAGE): Use high regs when
	optimizing for size on Thumb-2.


Co-Authored-By: Julian Brown <julian@codesourcery.com>

From-SVN: r158378
---
 gcc/ChangeLog            |  9 +++++++++
 gcc/config/arm/arm.h     | 11 +++++------
 gcc/config/arm/thumb2.md | 17 ++++++++++++-----
 gcc/config/arm/vfp.md    | 24 ++++++++++++++----------
 4 files changed, 40 insertions(+), 21 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5b8b01927b34..0b6da050a437 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2010-04-15  Mark Shinwell  <shinwell@codesourcery.com>
+	    Julian Brown  <julian@codesourcery.com>
+
+	* config/arm/thumb2.md (thumb2_movsi_insn): Split ldr and str
+	alternatives according to use of high and low regs.
+	* config/arm/vfp.md (thumb2_movsi_vfp): Likewise.
+	* config/arm/arm.h (CONDITIONAL_REGISTER_USAGE): Use high regs when
+	optimizing for size on Thumb-2.
+
 2010-04-15  Thomas Schwinge  <tschwinge@gnu.org>
 
 	* config.gcc <i[34567]86-*-gnu*>: Handle softfp as for Linux.
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 26ffaf8dff80..ca430e94dd09 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -771,12 +771,11 @@ extern int arm_structure_size_boundary;
 	fixed_regs[regno] = call_used_regs[regno] = 1;		\
     }								\
 								\
-  if (TARGET_THUMB && optimize_size)				\
-    {								\
-      /* When optimizing for size, it's better not to use	\
-	 the HI regs, because of the overhead of stacking 	\
-	 them.  */						\
-      /* ??? Is this still true for thumb2?  */			\
+  if (TARGET_THUMB1 && optimize_size)				\
+    {                                                           \
+      /* When optimizing for size on Thumb-1, it's better not	\
+        to use the HI regs, because of the overhead of		\
+        stacking them.  */                                      \
       for (regno = FIRST_HI_REGNUM;				\
 	   regno <= LAST_HI_REGNUM; ++regno)			\
 	fixed_regs[regno] = call_used_regs[regno] = 1;		\
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index 69a5e0683b48..3e2c3daea3b3 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -223,9 +223,14 @@
    (set_attr "neg_pool_range" "*,*,*,0,*")]
 )
 
+;; We have two alternatives here for memory loads (and similarly for stores)
+;; to reflect the fact that the permissible constant pool ranges differ
+;; between ldr instructions taking low regs and ldr instructions taking high
+;; regs.  The high register alternatives are not taken into account when
+;; choosing register preferences in order to reflect their expense.
 (define_insn "*thumb2_movsi_insn"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
-	(match_operand:SI 1 "general_operand"	   "rk ,I,K,j,mi,rk"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,l ,*hk,m,*m")
+	(match_operand:SI 1 "general_operand"	   "rk ,I,K,j,mi,*mi,l,*hk"))]
   "TARGET_THUMB2 && ! TARGET_IWMMXT
    && !(TARGET_HARD_FLOAT && TARGET_VFP)
    && (   register_operand (operands[0], SImode)
@@ -236,11 +241,13 @@
    mvn%?\\t%0, #%B1
    movw%?\\t%0, %1
    ldr%?\\t%0, %1
+   ldr%?\\t%0, %1
+   str%?\\t%1, %0
    str%?\\t%1, %0"
-  [(set_attr "type" "*,*,*,*,load1,store1")
+  [(set_attr "type" "*,*,*,*,load1,load1,store1,store1")
    (set_attr "predicable" "yes")
-   (set_attr "pool_range" "*,*,*,*,4096,*")
-   (set_attr "neg_pool_range" "*,*,*,*,0,*")]
+   (set_attr "pool_range" "*,*,*,*,1020,4096,*,*")
+   (set_attr "neg_pool_range" "*,*,*,*,0,0,*,*")]
 )
 
 (define_insn "tls_load_dot_plus_four"
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index 57c2192d1e98..02d527b79c5d 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -86,9 +86,11 @@
    (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")]
 )
 
+;; See thumb2.md:thumb2_movsi_insn for an explanation of the split
+;; high/low register alternatives for loads and stores here.
 (define_insn "*thumb2_movsi_vfp"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m,*t,r, *t,*t, *Uv")
-      (match_operand:SI 1 "general_operand"	   "rk, I,K,j,mi,rk,r,*t,*t,*Uvi,*t"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r, l,*hk,m, *m,*t, r,*t,*t,  *Uv")
+	(match_operand:SI 1 "general_operand"	   "rk, I,K,j,mi,*mi,l,*hk, r,*t,*t,*Uvi,*t"))]
   "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT
    && (   s_register_operand (operands[0], SImode)
        || s_register_operand (operands[1], SImode))"
@@ -102,25 +104,27 @@
     case 3:
       return \"movw%?\\t%0, %1\";
     case 4:
-      return \"ldr%?\\t%0, %1\";
     case 5:
-      return \"str%?\\t%1, %0\";
+      return \"ldr%?\\t%0, %1\";
     case 6:
-      return \"fmsr%?\\t%0, %1\\t%@ int\";
     case 7:
-      return \"fmrs%?\\t%0, %1\\t%@ int\";
+      return \"str%?\\t%1, %0\";
     case 8:
+      return \"fmsr%?\\t%0, %1\\t%@ int\";
+    case 9:
+      return \"fmrs%?\\t%0, %1\\t%@ int\";
+    case 10:
       return \"fcpys%?\\t%0, %1\\t%@ int\";
-    case 9: case 10:
+    case 11: case 12:
       return output_move_vfp (operands);
     default:
       gcc_unreachable ();
     }
   "
   [(set_attr "predicable" "yes")
-   (set_attr "type" "*,*,*,*,load1,store1,r_2_f,f_2_r,fcpys,f_load,f_store")
-   (set_attr "pool_range"     "*,*,*,*,4096,*,*,*,*,1020,*")
-   (set_attr "neg_pool_range" "*,*,*,*,   0,*,*,*,*,1008,*")]
+   (set_attr "type" "*,*,*,*,load1,load1,store1,store1,r_2_f,f_2_r,fcpys,f_load,f_store")
+   (set_attr "pool_range"     "*,*,*,*,1020,4096,*,*,*,*,*,1020,*")
+   (set_attr "neg_pool_range" "*,*,*,*,   0,   0,*,*,*,*,*,1008,*")]
 )
 
 
-- 
GitLab