summaryrefslogtreecommitdiff
path: root/gcc/config/sh/sh.md
diff options
context:
space:
mode:
authorolegendo <olegendo@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-30 06:48:40 +0000
committerolegendo <olegendo@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-30 06:48:40 +0000
commitf938598f39cbec5d166d339acdee70c1878acb50 (patch)
tree8d8f4b5e5400b7783c9e99e0a72b0f26226488f6 /gcc/config/sh/sh.md
parent1f215533890bcb4224ab7a60a33fd7b903c68c71 (diff)
downloadgcc-f938598f39cbec5d166d339acdee70c1878acb50.tar.gz
PR target/39423
* config/gcc/sh/sh.md (*movsi_index_disp, *movhi_index_disp): New insns. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189954 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/sh/sh.md')
-rw-r--r--gcc/config/sh/sh.md126
1 files changed, 126 insertions, 0 deletions
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 6382238383d..ec9ff03ff7a 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -5103,6 +5103,132 @@ label:
"TARGET_SH1"
"sett")
+
+;; Use the combine pass to transform sequences such as
+;; mov r5,r0
+;; add #1,r0
+;; shll2 r0
+;; mov.l @(r0,r4),r0
+;; into
+;; shll2 r5
+;; add r4,r5
+;; mov.l @(4,r5),r0
+;;
+;; See also PR 39423.
+;; FIXME: Fold copy pasted patterns somehow.
+;; FIXME: Combine never tries this kind of patterns for DImode.
+(define_insn_and_split "*movsi_index_disp"
+ [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+ (mem:SI
+ (plus:SI
+ (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand" "r")
+ (match_operand:SI 2 "const_int_operand"))
+ (match_operand:SI 3 "arith_reg_operand" "r"))
+ (match_operand:SI 4 "const_int_operand"))))]
+ "TARGET_SH1 && sh_legitimate_index_p (SImode, operands[4], TARGET_SH2A, true)
+ && exact_log2 (INTVAL (operands[2])) > 0"
+ "#"
+ "&& can_create_pseudo_p ()"
+ [(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
+ (set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
+ (set (match_dup 0) (mem:SI (plus:SI (match_dup 6) (match_dup 4))))]
+{
+ operands[5] = gen_reg_rtx (SImode);
+ operands[6] = gen_reg_rtx (SImode);
+ operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
+})
+
+(define_insn_and_split "*movhi_index_disp"
+ [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+ (sign_extend:SI
+ (mem:HI
+ (plus:SI
+ (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand" "r")
+ (match_operand:SI 2 "const_int_operand"))
+ (match_operand:SI 3 "arith_reg_operand" "r"))
+ (match_operand:SI 4 "const_int_operand")))))]
+ "TARGET_SH1 && sh_legitimate_index_p (HImode, operands[4], TARGET_SH2A, true)
+ && exact_log2 (INTVAL (operands[2])) > 0"
+ "#"
+ "&& can_create_pseudo_p ()"
+ [(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
+ (set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
+ (set (match_dup 0)
+ (sign_extend:SI (mem:HI (plus:SI (match_dup 6) (match_dup 4)))))]
+{
+ operands[5] = gen_reg_rtx (SImode);
+ operands[6] = gen_reg_rtx (SImode);
+ operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
+})
+
+(define_insn_and_split "*movhi_index_disp"
+ [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+ (zero_extend:SI
+ (mem:HI
+ (plus:SI
+ (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand" "r")
+ (match_operand:SI 2 "const_int_operand"))
+ (match_operand:SI 3 "arith_reg_operand" "r"))
+ (match_operand:SI 4 "const_int_operand")))))]
+ "TARGET_SH1 && sh_legitimate_index_p (HImode, operands[4], TARGET_SH2A, true)
+ && exact_log2 (INTVAL (operands[2])) > 0"
+ "#"
+ "&& can_create_pseudo_p ()"
+ [(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
+ (set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
+ (set (match_dup 7)
+ (sign_extend:SI (mem:HI (plus:SI (match_dup 6) (match_dup 4)))))
+ (set (match_dup 0) (zero_extend:SI (match_dup 8)))]
+{
+ operands[5] = gen_reg_rtx (SImode);
+ operands[6] = gen_reg_rtx (SImode);
+ operands[7] = gen_reg_rtx (SImode);
+ operands[8] = gen_lowpart (HImode, operands[7]);
+ operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
+})
+
+(define_insn_and_split "*movsi_index_disp"
+ [(set (mem:SI
+ (plus:SI
+ (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand" "r")
+ (match_operand:SI 2 "const_int_operand"))
+ (match_operand:SI 3 "arith_reg_operand" "r"))
+ (match_operand:SI 4 "const_int_operand")))
+ (match_operand:SI 0 "arith_reg_operand" "r"))]
+ "TARGET_SH1 && sh_legitimate_index_p (SImode, operands[4], TARGET_SH2A, true)
+ && exact_log2 (INTVAL (operands[2])) > 0"
+ "#"
+ "&& can_create_pseudo_p ()"
+ [(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
+ (set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
+ (set (mem:SI (plus:SI (match_dup 6) (match_dup 4))) (match_dup 0))]
+{
+ operands[5] = gen_reg_rtx (SImode);
+ operands[6] = gen_reg_rtx (SImode);
+ operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
+})
+
+(define_insn_and_split "*movhi_index_disp"
+ [(set (mem:HI
+ (plus:SI
+ (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand" "r")
+ (match_operand:SI 2 "const_int_operand"))
+ (match_operand:SI 3 "arith_reg_operand" "r"))
+ (match_operand:SI 4 "const_int_operand")))
+ (match_operand:HI 0 "arith_reg_operand" "r"))]
+ "TARGET_SH1 && sh_legitimate_index_p (HImode, operands[4], TARGET_SH2A, true)
+ && exact_log2 (INTVAL (operands[2])) > 0"
+ "#"
+ "&& can_create_pseudo_p ()"
+ [(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
+ (set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
+ (set (mem:HI (plus:SI (match_dup 6) (match_dup 4))) (match_dup 0))]
+{
+ operands[5] = gen_reg_rtx (SImode);
+ operands[6] = gen_reg_rtx (SImode);
+ operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
+})
+
;; Define additional pop for SH1 and SH2 so it does not get
;; placed in the delay slot.
(define_insn "*movsi_pop"