summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorolegendo <olegendo@138bc75d-0d04-0410-961f-82ee72b054a4>2016-05-04 07:14:11 +0000
committerolegendo <olegendo@138bc75d-0d04-0410-961f-82ee72b054a4>2016-05-04 07:14:11 +0000
commit121329865bb52656e6baacaac9ceaf278dbc3238 (patch)
treeb83fc185cc0166a1c0a9e4730902267830baed4e
parent846521ce48938166d59dc1f4039ff6ed5566fe2b (diff)
downloadgcc-121329865bb52656e6baacaac9ceaf278dbc3238.tar.gz
gcc/
* config/sh/predicates (post_inc_mem, pre_dec_mem): New predicates. * config/sh/sh-protos.h (sh_find_set_of_reg): Return null result if result.set_rtx is null instead of aborting. * config/sh/sh.h (USE_LOAD_POST_INCREMENT, USE_STORE_PRE_DECREMENT): Always enable. (USE_LOAD_PRE_DECREMENT, USE_STORE_POST_INCREMENT): Enable for SH2A. * config/sh/sh.md (*extend<mode>si2_predec, *mov<mode>_load_predec, *mov<mode>_store_postinc): New patterns. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235859 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/sh/predicates.md12
-rw-r--r--gcc/config/sh/sh-protos.h8
-rw-r--r--gcc/config/sh/sh.h10
-rw-r--r--gcc/config/sh/sh.md25
5 files changed, 58 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6461fc196b7..272b1ed1cc2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2016-05-04 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/predicates (post_inc_mem, pre_dec_mem): New predicates.
+ * config/sh/sh-protos.h (sh_find_set_of_reg): Return null result if
+ result.set_rtx is null instead of aborting.
+ * config/sh/sh.h (USE_LOAD_POST_INCREMENT, USE_STORE_PRE_DECREMENT):
+ Always enable.
+ (USE_LOAD_PRE_DECREMENT, USE_STORE_POST_INCREMENT): Enable for SH2A.
+ * config/sh/sh.md (*extend<mode>si2_predec, *mov<mode>_load_predec,
+ *mov<mode>_store_postinc): New patterns.
+
2016-05-04 Marc Glisse <marc.glisse@inria.fr>
* match.pd ((A | B) & (A | C)): Generalize to BIT_XOR_EXPR. Mark
diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index 3e69d88f64b..b582637642a 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -230,6 +230,18 @@
(match_test "sh_disp_addr_displacement (op)
<= sh_max_mov_insn_displacement (GET_MODE (op), false)")))
+;; Returns true if OP is a post-increment addressing mode memory reference.
+(define_predicate "post_inc_mem"
+ (and (match_code "mem")
+ (match_code "post_inc" "0")
+ (match_code "reg" "00")))
+
+;; Returns true if OP is a pre-decrement addressing mode memory reference.
+(define_predicate "pre_dec_mem"
+ (and (match_code "mem")
+ (match_code "pre_dec" "0")
+ (match_code "reg" "00")))
+
;; Returns 1 if the operand can be used in an SH2A movu.{b|w} insn.
(define_predicate "zero_extend_movu_operand"
(and (ior (match_operand 0 "displacement_mem_operand")
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index ea7e847300d..c47e2eade15 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -224,8 +224,12 @@ sh_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc,
}
}
- if (result.set_src != NULL)
- gcc_assert (result.insn != NULL && result.set_rtx != NULL);
+ /* If the searched reg is found inside a (mem (post_inc:SI (reg))), set_of
+ will return NULL and set_rtx will be NULL.
+ In this case report a 'not found'. result.insn will always be non-null
+ at this point, so no need to check it. */
+ if (result.set_src != NULL && result.set_rtx == NULL)
+ result.set_src = NULL;
return result;
}
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 60c625028c1..16b4a8e6900 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -1307,12 +1307,10 @@ struct sh_args {
#define HAVE_POST_INCREMENT TARGET_SH1
#define HAVE_PRE_DECREMENT TARGET_SH1
-#define USE_LOAD_POST_INCREMENT(mode) ((mode == SImode || mode == DImode) \
- ? 0 : TARGET_SH1)
-#define USE_LOAD_PRE_DECREMENT(mode) 0
-#define USE_STORE_POST_INCREMENT(mode) 0
-#define USE_STORE_PRE_DECREMENT(mode) ((mode == SImode || mode == DImode) \
- ? 0 : TARGET_SH1)
+#define USE_LOAD_POST_INCREMENT(mode) TARGET_SH1
+#define USE_LOAD_PRE_DECREMENT(mode) TARGET_SH2A
+#define USE_STORE_POST_INCREMENT(mode) TARGET_SH2A
+#define USE_STORE_PRE_DECREMENT(mode) TARGET_SH1
/* If a memory clear move would take CLEAR_RATIO or more simple
move-instruction pairs, we will do a setmem instead. */
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 2d9502b7aa7..2a8fbc8df9b 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -4820,6 +4820,15 @@
[(set_attr "type" "load")
(set_attr "length" "2,2,4")])
+;; The pre-dec and post-inc mems must be captured by the '<' and '>'
+;; constraints, otherwise wrong code might get generated.
+(define_insn "*extend<mode>si2_predec"
+ [(set (match_operand:SI 0 "arith_reg_dest" "=z")
+ (sign_extend:SI (match_operand:QIHI 1 "pre_dec_mem" "<")))]
+ "TARGET_SH2A"
+ "mov.<bw> %1,%0"
+ [(set_attr "type" "load")])
+
;; The *_snd patterns will take care of other QImode/HImode addressing
;; modes than displacement addressing. They must be defined _after_ the
;; displacement addressing patterns. Otherwise the displacement addressing
@@ -5261,6 +5270,22 @@
prepare_move_operands (operands, <MODE>mode);
})
+;; The pre-dec and post-inc mems must be captured by the '<' and '>'
+;; constraints, otherwise wrong code might get generated.
+(define_insn "*mov<mode>_load_predec"
+ [(set (match_operand:QIHISI 0 "arith_reg_dest" "=z")
+ (match_operand:QIHISI 1 "pre_dec_mem" "<"))]
+ "TARGET_SH2A"
+ "mov.<bwl> %1,%0"
+ [(set_attr "type" "load")])
+
+(define_insn "*mov<mode>_store_postinc"
+ [(set (match_operand:QIHISI 0 "post_inc_mem" "=>")
+ (match_operand:QIHISI 1 "arith_reg_operand" "z"))]
+ "TARGET_SH2A"
+ "mov.<bwl> %1,%0"
+ [(set_attr "type" "store")])
+
;; Specifying the displacement addressing load / store patterns separately
;; before the generic movqi / movhi pattern allows controlling the order
;; in which load / store insns are selected in a more fine grained way.