summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>2013-07-22 10:47:26 +0000
committerktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>2013-07-22 10:47:26 +0000
commit4369e6ad7ac12d5184c0c843a18b0d74a13cff07 (patch)
treef72bb2d49b5ba1af7f1591058fceda16849a74fb
parent4f3c15955dc66be54a2d3ec6f1a62575d47dfc43 (diff)
downloadgcc-4369e6ad7ac12d5184c0c843a18b0d74a13cff07.tar.gz
2013-07-22 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/predicates.md (shiftable_operator_strict_it): New predicate. * config/arm/thumb2.md (thumb_andsi_not_shiftsi_si): Disable cond_exec version for arm_restrict_it. (thumb2_smaxsi3): Convert to generate cond_exec. (thumb2_sminsi3): Likewise. (thumb32_umaxsi3): Likewise. (thumb2_uminsi3): Likewise. (thumb2_abssi2): Adjust constraints for arm_restrict_it. (thumb2_neg_abssi2): Likewise. (thumb2_mov_scc): Add alternative for 16-bit encoding. (thumb2_movsicc_insn): Adjust alternatives. (thumb2_mov_negscc): Disable for arm_restrict_it. (thumb2_mov_negscc_strict_it): New pattern. (thumb2_mov_notscc_strict_it): New pattern. (thumb2_mov_notscc): Disable for arm_restrict_it. (thumb2_ior_scc): Likewise. (thumb2_ior_scc_strict_it): New pattern. (thumb2_cond_move): Adjust for arm_restrict_it. (thumb2_cond_arith): Disable for arm_restrict_it. (thumb2_cond_arith_strict_it): New pattern. (thumb2_cond_sub): Adjust for arm_restrict_it. (thumb2_movcond): Likewise. (thumb2_extendqisi_v6): Disable cond_exec variant for arm_restrict_it. (thumb2_zero_extendhisi2_v6): Likewise. (thumb2_zero_extendqisi2_v6): Likewise. (orsi_notsi_si): Likewise. (orsi_not_shiftsi_si): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201122 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog31
-rw-r--r--gcc/config/arm/predicates.md4
-rw-r--r--gcc/config/arm/thumb2.md336
3 files changed, 281 insertions, 90 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 98cc565a3b3..b07b09a3cdc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,34 @@
+2013-07-22 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/predicates.md (shiftable_operator_strict_it):
+ New predicate.
+ * config/arm/thumb2.md (thumb_andsi_not_shiftsi_si):
+ Disable cond_exec version for arm_restrict_it.
+ (thumb2_smaxsi3): Convert to generate cond_exec.
+ (thumb2_sminsi3): Likewise.
+ (thumb32_umaxsi3): Likewise.
+ (thumb2_uminsi3): Likewise.
+ (thumb2_abssi2): Adjust constraints for arm_restrict_it.
+ (thumb2_neg_abssi2): Likewise.
+ (thumb2_mov_scc): Add alternative for 16-bit encoding.
+ (thumb2_movsicc_insn): Adjust alternatives.
+ (thumb2_mov_negscc): Disable for arm_restrict_it.
+ (thumb2_mov_negscc_strict_it): New pattern.
+ (thumb2_mov_notscc_strict_it): New pattern.
+ (thumb2_mov_notscc): Disable for arm_restrict_it.
+ (thumb2_ior_scc): Likewise.
+ (thumb2_ior_scc_strict_it): New pattern.
+ (thumb2_cond_move): Adjust for arm_restrict_it.
+ (thumb2_cond_arith): Disable for arm_restrict_it.
+ (thumb2_cond_arith_strict_it): New pattern.
+ (thumb2_cond_sub): Adjust for arm_restrict_it.
+ (thumb2_movcond): Likewise.
+ (thumb2_extendqisi_v6): Disable cond_exec variant for arm_restrict_it.
+ (thumb2_zero_extendhisi2_v6): Likewise.
+ (thumb2_zero_extendqisi2_v6): Likewise.
+ (orsi_notsi_si): Likewise.
+ (orsi_not_shiftsi_si): Likewise.
+
2013-07-22 Georg-Johann Lay <avr@gjlay.de>
* config/avr/avr.c (avr_out_xload): No SBIS around LPM so that
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index f4a4515fa39..29e1e5c8276 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -246,6 +246,10 @@
(and (match_code "plus,minus,ior,xor,and")
(match_test "mode == GET_MODE (op)")))
+(define_special_predicate "shiftable_operator_strict_it"
+ (and (match_code "plus,and")
+ (match_test "mode == GET_MODE (op)")))
+
;; True for logical binary operators.
(define_special_predicate "logical_binary_operator"
(and (match_code "ior,xor,and")
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index e36b4367699..8b184a80c2e 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -34,96 +34,91 @@
"TARGET_THUMB2"
"bic%?\\t%0, %1, %2%S4"
[(set_attr "predicable" "yes")
+ (set_attr "predicable_short_it" "no")
(set_attr "shift" "2")
(set_attr "type" "arlo_shift")]
)
+;; We use the '0' constraint for operand 1 because reload should
+;; be smart enough to generate an appropriate move for the r/r/r case.
(define_insn_and_split "*thumb2_smaxsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
- (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
+ [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
+ (smax:SI (match_operand:SI 1 "s_register_operand" "%0,0,0")
+ (match_operand:SI 2 "arm_rhs_operand" "r,Py,I")))
(clobber (reg:CC CC_REGNUM))]
- "TARGET_THUMB2"
- "#"
- ; cmp\\t%1, %2\;it\\tlt\;movlt\\t%0, %2
- ; cmp\\t%1, %2\;it\\tge\;movge\\t%0, %1
- ; cmp\\t%1, %2\;ite\\tge\;movge\\t%0, %1\;movlt\\t%0, %2
- "TARGET_THUMB2"
+ "TARGET_THUMB2"
+ "#"
+ ; cmp\\t%1, %2\;it\\tlt\;movlt\\t%0, %2
+ "TARGET_THUMB2 && reload_completed"
[(set (reg:CC CC_REGNUM)
(compare:CC (match_dup 1) (match_dup 2)))
- (set (match_dup 0)
- (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
- (match_dup 1)
- (match_dup 2)))]
+ (cond_exec (lt:SI (reg:CC CC_REGNUM) (const_int 0))
+ (set (match_dup 0)
+ (match_dup 2)))]
""
[(set_attr "conds" "clob")
- (set_attr "length" "10,10,14")]
+ (set_attr "enabled_for_depr_it" "yes,yes,no")
+ (set_attr "length" "6,6,10")]
)
(define_insn_and_split "*thumb2_sminsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
- (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
+ [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
+ (smin:SI (match_operand:SI 1 "s_register_operand" "%0,0,0")
+ (match_operand:SI 2 "arm_rhs_operand" "r,Py,I")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_THUMB2"
"#"
- ; cmp\\t%1, %2\;it\\tge\;movge\\t%0, %2
- ; cmp\\t%1, %2\;it\\tlt\;movlt\\t%0, %1
- ; cmp\\t%1, %2\;ite\\tlt\;movlt\\t%0, %1\;movge\\t%0, %2"
- "TARGET_THUMB2"
+ ; cmp\\t%1, %2\;it\\tge\;movge\\t%0, %2
+ "TARGET_THUMB2 && reload_completed"
[(set (reg:CC CC_REGNUM)
(compare:CC (match_dup 1) (match_dup 2)))
- (set (match_dup 0)
- (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
- (match_dup 1)
- (match_dup 2)))]
+ (cond_exec (ge:SI (reg:CC CC_REGNUM) (const_int 0))
+ (set (match_dup 0)
+ (match_dup 2)))]
""
[(set_attr "conds" "clob")
- (set_attr "length" "10,10,14")]
+ (set_attr "enabled_for_depr_it" "yes,yes,no")
+ (set_attr "length" "6,6,10")]
)
(define_insn_and_split "*thumb32_umaxsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
- (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
- (clobber (reg:CC CC_REGNUM))]
+ [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
+ (umax:SI (match_operand:SI 1 "s_register_operand" "%0,0,0")
+ (match_operand:SI 2 "arm_rhs_operand" "r,Py,I")))
+ (clobber (reg:CC CC_REGNUM))]
"TARGET_THUMB2"
"#"
- ; cmp\\t%1, %2\;it\\tcc\;movcc\\t%0, %2
- ; cmp\\t%1, %2\;it\\tcs\;movcs\\t%0, %1
- ; cmp\\t%1, %2\;ite\\tcs\;movcs\\t%0, %1\;movcc\\t%0, %2"
- "TARGET_THUMB2"
+ ; cmp\\t%1, %2\;it\\tcc\;movcc\\t%0, %2
+ "TARGET_THUMB2 && reload_completed"
[(set (reg:CC CC_REGNUM)
(compare:CC (match_dup 1) (match_dup 2)))
- (set (match_dup 0)
- (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
- (match_dup 1)
- (match_dup 2)))]
+ (cond_exec (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
+ (set (match_dup 0)
+ (match_dup 2)))]
""
[(set_attr "conds" "clob")
- (set_attr "length" "10,10,14")]
+ (set_attr "length" "6,6,10")
+ (set_attr "enabled_for_depr_it" "yes,yes,no")]
)
(define_insn_and_split "*thumb2_uminsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
- (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
+ [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
+ (umin:SI (match_operand:SI 1 "s_register_operand" "%0,0,0")
+ (match_operand:SI 2 "arm_rhs_operand" "r,Py,I")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_THUMB2"
"#"
- ; cmp\\t%1, %2\;it\\tcs\;movcs\\t%0, %2
- ; cmp\\t%1, %2\;it\\tcc\;movcc\\t%0, %1
- ; cmp\\t%1, %2\;ite\\tcc\;movcc\\t%0, %1\;movcs\\t%0, %2"
- "TARGET_THUMB2"
+ ; cmp\\t%1, %2\;it\\tcs\;movcs\\t%0, %2
+ "TARGET_THUMB2 && reload_completed"
[(set (reg:CC CC_REGNUM)
(compare:CC (match_dup 1) (match_dup 2)))
- (set (match_dup 0)
- (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
- (match_dup 1)
- (match_dup 2)))]
+ (cond_exec (geu:SI (reg:CC CC_REGNUM) (const_int 0))
+ (set (match_dup 0)
+ (match_dup 2)))]
""
[(set_attr "conds" "clob")
- (set_attr "length" "10,10,14")]
+ (set_attr "length" "6,6,10")
+ (set_attr "enabled_for_depr_it" "yes,yes,no")]
)
;; Thumb-2 does not have rsc, so use a clever trick with shifter operands.
@@ -152,17 +147,17 @@
)
(define_insn_and_split "*thumb2_abssi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
- (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
+ [(set (match_operand:SI 0 "s_register_operand" "=&r,l,r")
+ (abs:SI (match_operand:SI 1 "s_register_operand" "r,0,0")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_THUMB2"
"#"
- ; cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0
; eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
+ ; cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0
+ ; cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0
"&& reload_completed"
[(const_int 0)]
{
- /* if (which_alternative == 0) */
if (REGNO(operands[0]) == REGNO(operands[1]))
{
rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
@@ -199,25 +194,27 @@
}
DONE;
}
- [(set_attr "conds" "clob,*")
+ [(set_attr "conds" "*,clob,clob")
(set_attr "shift" "1")
- (set_attr "predicable" "no, yes")
+ (set_attr "predicable" "yes,no,no")
+ (set_attr "predicable_short_it" "no")
+ (set_attr "enabled_for_depr_it" "yes,yes,no")
(set_attr "ce_count" "2")
- (set_attr "length" "10,8")]
+ (set_attr "length" "8,6,10")]
)
(define_insn_and_split "*thumb2_neg_abssi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
- (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
+ [(set (match_operand:SI 0 "s_register_operand" "=&r,l,r")
+ (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "r,0,0"))))
(clobber (reg:CC CC_REGNUM))]
"TARGET_THUMB2"
"#"
+ ; eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
+ ; cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0
; cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0
- ; eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
"&& reload_completed"
[(const_int 0)]
{
- /* if (which_alternative == 0) */
if (REGNO(operands[0]) == REGNO(operands[1]))
{
rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
@@ -254,11 +251,13 @@
}
DONE;
}
- [(set_attr "conds" "clob,*")
+ [(set_attr "conds" "*,clob,clob")
(set_attr "shift" "1")
- (set_attr "predicable" "no, yes")
+ (set_attr "predicable" "yes,no,no")
+ (set_attr "enabled_for_depr_it" "yes,yes,no")
+ (set_attr "predicable_short_it" "no")
(set_attr "ce_count" "2")
- (set_attr "length" "10,8")]
+ (set_attr "length" "8,6,10")]
)
;; We have two alternatives here for memory loads (and similarly for stores)
@@ -340,7 +339,7 @@
)
(define_insn_and_split "*thumb2_mov_scc"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "=l,r")
(match_operator:SI 1 "arm_comparison_operator"
[(match_operand 2 "cc_register" "") (const_int 0)]))]
"TARGET_THUMB2"
@@ -352,14 +351,15 @@
(const_int 0)))]
""
[(set_attr "conds" "use")
- (set_attr "length" "10")]
+ (set_attr "enabled_for_depr_it" "yes,no")
+ (set_attr "length" "8,10")]
)
(define_insn_and_split "*thumb2_mov_negscc"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(neg:SI (match_operator:SI 1 "arm_comparison_operator"
[(match_operand 2 "cc_register" "") (const_int 0)])))]
- "TARGET_THUMB2"
+ "TARGET_THUMB2 && !arm_restrict_it"
"#" ; "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
"TARGET_THUMB2"
[(set (match_dup 0)
@@ -373,11 +373,39 @@
(set_attr "length" "10")]
)
+(define_insn_and_split "*thumb2_mov_negscc_strict_it"
+ [(set (match_operand:SI 0 "low_register_operand" "=l")
+ (neg:SI (match_operator:SI 1 "arm_comparison_operator"
+ [(match_operand 2 "cc_register" "") (const_int 0)])))]
+ "TARGET_THUMB2 && arm_restrict_it"
+ "#" ; ";mvn\\t%0, #0 ;it\\t%D1\;mov%D1\\t%0, #0\"
+ "&& reload_completed"
+ [(set (match_dup 0)
+ (match_dup 3))
+ (cond_exec (match_dup 4)
+ (set (match_dup 0)
+ (const_int 0)))]
+ {
+ operands[3] = GEN_INT (~0);
+ enum machine_mode mode = GET_MODE (operands[2]);
+ enum rtx_code rc = GET_CODE (operands[1]);
+
+ if (mode == CCFPmode || mode == CCFPEmode)
+ rc = reverse_condition_maybe_unordered (rc);
+ else
+ rc = reverse_condition (rc);
+ operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
+
+ }
+ [(set_attr "conds" "use")
+ (set_attr "length" "8")]
+)
+
(define_insn_and_split "*thumb2_mov_notscc"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(not:SI (match_operator:SI 1 "arm_comparison_operator"
[(match_operand 2 "cc_register" "") (const_int 0)])))]
- "TARGET_THUMB2"
+ "TARGET_THUMB2 && !arm_restrict_it"
"#" ; "ite\\t%D1\;mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
"TARGET_THUMB2"
[(set (match_dup 0)
@@ -392,13 +420,35 @@
(set_attr "length" "10")]
)
+(define_insn_and_split "*thumb2_mov_notscc_strict_it"
+ [(set (match_operand:SI 0 "low_register_operand" "=l")
+ (not:SI (match_operator:SI 1 "arm_comparison_operator"
+ [(match_operand 2 "cc_register" "") (const_int 0)])))]
+ "TARGET_THUMB2 && arm_restrict_it"
+ "#" ; "mvn %0, #0 ; it%d1 ; lsl%d1 %0, %0, #1"
+ "&& reload_completed"
+ [(set (match_dup 0)
+ (match_dup 3))
+ (cond_exec (match_dup 4)
+ (set (match_dup 0)
+ (ashift:SI (match_dup 0)
+ (const_int 1))))]
+ {
+ operands[3] = GEN_INT (~0);
+ operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
+ VOIDmode, operands[2], const0_rtx);
+ }
+ [(set_attr "conds" "use")
+ (set_attr "length" "8")]
+)
+
(define_insn_and_split "*thumb2_movsicc_insn"
- [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r,r,r,r,r,r,r,r,l")
+ [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r,r,r,r,r,r,r,r")
(if_then_else:SI
(match_operator 3 "arm_comparison_operator"
[(match_operand 4 "cc_register" "") (const_int 0)])
- (match_operand:SI 1 "arm_not_operand" "0 ,Py,0 ,0,rI,K,rI,rI,K ,K,r,lPy")
- (match_operand:SI 2 "arm_not_operand" "Py,0 ,rI,K,0 ,0,rI,K ,rI,K,r,lPy")))]
+ (match_operand:SI 1 "arm_not_operand" "0 ,lPy,0 ,0,rI,K,rI,rI,K ,K,r")
+ (match_operand:SI 2 "arm_not_operand" "lPy,0 ,rI,K,0 ,0,rI,K ,rI,K,r")))]
"TARGET_THUMB2"
"@
it\\t%D3\;mov%D3\\t%0, %2
@@ -411,14 +461,12 @@
#
#
#
- #
#"
; alt 6: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2
; alt 7: ite\\t%d3\;mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
; alt 8: ite\\t%d3\;mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
; alt 9: ite\\t%d3\;mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2
; alt 10: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2
- ; alt 11: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2"
"&& reload_completed"
[(const_int 0)]
{
@@ -449,8 +497,8 @@
operands[2])));
DONE;
}
- [(set_attr "length" "4,4,6,6,6,6,10,10,10,10,6,6")
- (set_attr "enabled_for_depr_it" "yes,yes,no,no,no,no,no,no,no,no,yes,yes")
+ [(set_attr "length" "4,4,6,6,6,6,10,10,10,10,6")
+ (set_attr "enabled_for_depr_it" "yes,yes,no,no,no,no,no,no,no,no,yes")
(set_attr "conds" "use")]
)
@@ -532,7 +580,7 @@
(ior:SI (match_operator:SI 1 "arm_comparison_operator"
[(match_operand 2 "cc_register" "") (const_int 0)])
(match_operand:SI 3 "s_register_operand" "0,?r")))]
- "TARGET_THUMB2"
+ "TARGET_THUMB2 && !arm_restrict_it"
"@
it\\t%d1\;orr%d1\\t%0, %3, #1
#"
@@ -557,6 +605,19 @@
(set_attr "length" "6,10")]
)
+(define_insn "*thumb2_ior_scc_strict_it"
+ [(set (match_operand:SI 0 "s_register_operand" "=l,l")
+ (ior:SI (match_operator:SI 2 "arm_comparison_operator"
+ [(match_operand 3 "cc_register" "") (const_int 0)])
+ (match_operand:SI 1 "s_register_operand" "0,?l")))]
+ "TARGET_THUMB2 && arm_restrict_it"
+ "@
+ it\\t%d2\;mov%d2\\t%0, #1\;it\\t%d2\;orr%d2\\t%0, %1
+ mov\\t%0, #1\;orr\\t%0, %1\;it\\t%D2\;mov%D2\\t%0, %1"
+ [(set_attr "conds" "use")
+ (set_attr "length" "8")]
+)
+
(define_insn "*thumb2_cond_move"
[(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
(if_then_else:SI (match_operator 3 "equality_operator"
@@ -584,13 +645,20 @@
output_asm_insn (\"it\\t%D4\", operands);
break;
case 2:
- output_asm_insn (\"ite\\t%D4\", operands);
+ if (arm_restrict_it)
+ output_asm_insn (\"it\\t%D4\", operands);
+ else
+ output_asm_insn (\"ite\\t%D4\", operands);
break;
default:
abort();
}
if (which_alternative != 0)
- output_asm_insn (\"mov%D4\\t%0, %1\", operands);
+ {
+ output_asm_insn (\"mov%D4\\t%0, %1\", operands);
+ if (arm_restrict_it && which_alternative == 2)
+ output_asm_insn (\"it\\t%d4\", operands);
+ }
if (which_alternative != 1)
output_asm_insn (\"mov%d4\\t%0, %2\", operands);
return \"\";
@@ -607,7 +675,7 @@
(match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
(match_operand:SI 1 "s_register_operand" "0,?r")]))
(clobber (reg:CC CC_REGNUM))]
- "TARGET_THUMB2"
+ "TARGET_THUMB2 && !arm_restrict_it"
"*
if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
return \"%i5\\t%0, %1, %2, lsr #31\";
@@ -636,9 +704,78 @@
(set_attr "length" "14")]
)
+(define_insn_and_split "*thumb2_cond_arith_strict_it"
+ [(set (match_operand:SI 0 "s_register_operand" "=l")
+ (match_operator:SI 5 "shiftable_operator_strict_it"
+ [(match_operator:SI 4 "arm_comparison_operator"
+ [(match_operand:SI 2 "s_register_operand" "r")
+ (match_operand:SI 3 "arm_rhs_operand" "rI")])
+ (match_operand:SI 1 "s_register_operand" "0")]))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_THUMB2 && arm_restrict_it"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ {
+ if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
+ {
+ /* %i5 %0, %1, %2, lsr #31 */
+ rtx shifted_op = gen_rtx_LSHIFTRT (SImode, operands[2], GEN_INT (31));
+ rtx op = NULL_RTX;
+
+ switch (GET_CODE (operands[5]))
+ {
+ case AND:
+ op = gen_rtx_AND (SImode, shifted_op, operands[1]);
+ break;
+ case PLUS:
+ op = gen_rtx_PLUS (SImode, shifted_op, operands[1]);
+ break;
+ default: gcc_unreachable ();
+ }
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], op));
+ DONE;
+ }
+
+ /* "cmp %2, %3" */
+ emit_insn (gen_rtx_SET (VOIDmode,
+ gen_rtx_REG (CCmode, CC_REGNUM),
+ gen_rtx_COMPARE (CCmode, operands[2], operands[3])));
+
+ if (GET_CODE (operands[5]) == AND)
+ {
+ /* %i5 %0, %1, #1
+ it%D4
+ mov%D4 %0, #0 */
+ enum rtx_code rc = reverse_condition (GET_CODE (operands[4]));
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], gen_rtx_AND (SImode, operands[1], GEN_INT (1))));
+ emit_insn (gen_rtx_COND_EXEC (VOIDmode,
+ gen_rtx_fmt_ee (rc, VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx),
+ gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
+ DONE;
+ }
+ else
+ {
+ /* it\\t%d4
+ %i5%d4\\t%0, %1, #1 */
+ emit_insn (gen_rtx_COND_EXEC (VOIDmode, gen_rtx_fmt_ee (GET_CODE (operands[4]),
+ VOIDmode,
+ gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx),
+ gen_rtx_SET(VOIDmode, operands[0],
+ gen_rtx_PLUS (SImode,
+ operands[1],
+ GEN_INT (1)))));
+ DONE;
+ }
+ FAIL;
+ }
+ [(set_attr "conds" "clob")
+ (set_attr "length" "12")]
+)
+
(define_insn "*thumb2_cond_sub"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
+ [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
+ (minus:SI (match_operand:SI 1 "s_register_operand" "0,?Ts")
(match_operator:SI 4 "arm_comparison_operator"
[(match_operand:SI 2 "s_register_operand" "r,r")
(match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
@@ -648,8 +785,16 @@
output_asm_insn (\"cmp\\t%2, %3\", operands);
if (which_alternative != 0)
{
- output_asm_insn (\"ite\\t%D4\", operands);
- output_asm_insn (\"mov%D4\\t%0, %1\", operands);
+ if (arm_restrict_it)
+ {
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ output_asm_insn (\"it\\t%d4\", operands);
+ }
+ else
+ {
+ output_asm_insn (\"ite\\t%D4\", operands);
+ output_asm_insn (\"mov%D4\\t%0, %1\", operands);
+ }
}
else
output_asm_insn (\"it\\t%d4\", operands);
@@ -728,13 +873,13 @@
)
(define_insn "*thumb2_movcond"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
+ [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts,Ts")
(if_then_else:SI
(match_operator 5 "arm_comparison_operator"
[(match_operand:SI 3 "s_register_operand" "r,r,r")
(match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
- (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
+ (match_operand:SI 1 "arm_rhs_operand" "0,TsI,?TsI")
+ (match_operand:SI 2 "arm_rhs_operand" "TsI,0,TsI")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_THUMB2"
"*
@@ -789,12 +934,18 @@
output_asm_insn (\"it\\t%d5\", operands);
break;
case 2:
- output_asm_insn (\"ite\\t%d5\", operands);
+ if (arm_restrict_it)
+ {
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ output_asm_insn (\"it\\t%D5\", operands);
+ }
+ else
+ output_asm_insn (\"ite\\t%d5\", operands);
break;
default:
abort();
}
- if (which_alternative != 0)
+ if (which_alternative != 0 && !(arm_restrict_it && which_alternative == 2))
output_asm_insn (\"mov%d5\\t%0, %1\", operands);
if (which_alternative != 1)
output_asm_insn (\"mov%D5\\t%0, %2\", operands);
@@ -817,6 +968,7 @@
ldr%(sb%)\\t%0, %1"
[(set_attr "type" "extend,load_byte")
(set_attr "predicable" "yes")
+ (set_attr "predicable_short_it" "no")
(set_attr "pool_range" "*,4094")
(set_attr "neg_pool_range" "*,250")]
)
@@ -830,6 +982,7 @@
ldr%(h%)\\t%0, %1"
[(set_attr "type" "extend,load_byte")
(set_attr "predicable" "yes")
+ (set_attr "predicable_short_it" "no")
(set_attr "pool_range" "*,4094")
(set_attr "neg_pool_range" "*,250")]
)
@@ -843,6 +996,7 @@
ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
[(set_attr "type" "extend,load_byte")
(set_attr "predicable" "yes")
+ (set_attr "predicable_short_it" "no")
(set_attr "pool_range" "*,4094")
(set_attr "neg_pool_range" "*,250")]
)
@@ -1167,7 +1321,8 @@
(match_operand:SI 1 "s_register_operand" "r")))]
"TARGET_THUMB2"
"orn%?\\t%0, %1, %2"
- [(set_attr "predicable" "yes")]
+ [(set_attr "predicable" "yes")
+ (set_attr "predicable_short_it" "no")]
)
(define_insn "*orsi_not_shiftsi_si"
@@ -1179,6 +1334,7 @@
"TARGET_THUMB2"
"orn%?\\t%0, %1, %2%S4"
[(set_attr "predicable" "yes")
+ (set_attr "predicable_short_it" "no")
(set_attr "shift" "2")
(set_attr "type" "arlo_shift")]
)