diff options
author | Richard Earnshaw <rearnsha@arm.com> | 2009-06-13 12:49:25 +0000 |
---|---|---|
committer | Richard Earnshaw <rearnsha@gcc.gnu.org> | 2009-06-13 12:49:25 +0000 |
commit | 81beb0316c9ec1b53f038de4721929d444f5e406 (patch) | |
tree | 9462413f39917293691b2f80a1691fc920688266 /gcc/config/arm | |
parent | 98f6c6001353550dbafae02051371d2bef236b99 (diff) | |
download | gcc-81beb0316c9ec1b53f038de4721929d444f5e406.zip gcc-81beb0316c9ec1b53f038de4721929d444f5e406.tar.gz gcc-81beb0316c9ec1b53f038de4721929d444f5e406.tar.bz2 |
re PR target/40327 (Use fewer instructions to add some constants to register)
PR target/40327
* arm/constraints.md (Pa, Pb): New constraints.
* arm/arm.md (thumb1_addsi3): Support more complex additions. Add a
split pattern to deal with them.
From-SVN: r148452
Diffstat (limited to 'gcc/config/arm')
-rw-r--r-- | gcc/config/arm/arm.md | 29 | ||||
-rw-r--r-- | gcc/config/arm/constraints.md | 13 |
2 files changed, 36 insertions, 6 deletions
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 5f3a5e0..40e41c5 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -640,10 +640,10 @@ ;; register. Trying to reload it will always fail catastrophically, ;; so never allow those alternatives to match if reloading is needed. -(define_insn "*thumb1_addsi3" - [(set (match_operand:SI 0 "register_operand" "=l,l,l,*rk,*hk,l,!k") - (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k") - (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,!M,!O")))] +(define_insn_and_split "*thumb1_addsi3" + [(set (match_operand:SI 0 "register_operand" "=l,l,l,*rk,*hk,l,!k,l,l") + (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k,0,l") + (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,!M,!O,Pa,Pb")))] "TARGET_THUMB1" "* static const char * const asms[] = @@ -654,7 +654,9 @@ \"add\\t%0, %0, %2\", \"add\\t%0, %0, %2\", \"add\\t%0, %1, %2\", - \"add\\t%0, %1, %2\" + \"add\\t%0, %1, %2\", + \"#\", + \"#\" }; if ((which_alternative == 2 || which_alternative == 6) && GET_CODE (operands[2]) == CONST_INT @@ -662,7 +664,22 @@ return \"sub\\t%0, %1, #%n2\"; return asms[which_alternative]; " - [(set_attr "length" "2")] + "&& reload_completed && CONST_INT_P (operands[2]) + && operands[1] != stack_pointer_rtx + && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255)" + [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2))) + (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))] + { + HOST_WIDE_INT offset = INTVAL (operands[2]); + if (offset > 255) + offset = 255; + else if (offset < -255) + offset = -255; + + operands[3] = GEN_INT (offset); + operands[2] = GEN_INT (INTVAL (operands[2]) - offset); + } + [(set_attr "length" "2,2,2,2,2,2,2,4,4")] ) ;; Reloading and elimination of the frame pointer can diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md index 6cefa4e..f71599e 100644 --- a/gcc/config/arm/constraints.md +++ b/gcc/config/arm/constraints.md @@ -30,6 +30,7 @@ ;; The following multi-letter normal constraints have been used: ;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv +;; in Thumb-1 state: Pa, Pb ;; The following memory constraints have been used: ;; in ARM/Thumb-2 state: Q, Ut, Uv, Uy, Un, Um, Us @@ -129,6 +130,18 @@ (match_test "TARGET_THUMB1 && ival >= -508 && ival <= 508 && ((ival & 3) == 0)"))) +(define_constraint "Pa" + "@internal In Thumb-1 state a constant in the range -510 to +510" + (and (match_code "const_int") + (match_test "TARGET_THUMB1 && ival >= -510 && ival <= 510 + && (ival > 255 || ival < -255)"))) + +(define_constraint "Pb" + "@internal In Thumb-1 state a constant in the range -262 to +262" + (and (match_code "const_int") + (match_test "TARGET_THUMB1 && ival >= -262 && ival <= 262 + && (ival > 255 || ival < -255)"))) + (define_constraint "G" "In ARM/Thumb-2 state a valid FPA immediate constant." (and (match_code "const_double") |