aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Shinwell <shinwell@codesourcery.com>2010-04-15 14:39:22 +0000
committerJulian Brown <jules@gcc.gnu.org>2010-04-15 14:39:22 +0000
commit28907f9a0a6452810467d7519f09873b5b7cd6be (patch)
tree3307259b566036b040ad6fb53a3da135d84fe218 /gcc
parent3f56ef8b604873d6ef72ef93a3a026128459d3bb (diff)
downloadgcc-28907f9a0a6452810467d7519f09873b5b7cd6be.zip
gcc-28907f9a0a6452810467d7519f09873b5b7cd6be.tar.gz
gcc-28907f9a0a6452810467d7519f09873b5b7cd6be.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/arm/arm.h11
-rw-r--r--gcc/config/arm/thumb2.md17
-rw-r--r--gcc/config/arm/vfp.md24
4 files changed, 40 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5b8b019..0b6da05 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 26ffaf8..ca430e9 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 69a5e06..3e2c3da 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 57c2192..02d527b 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,*")]
)