diff options
author | olegendo <olegendo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-05-04 07:14:11 +0000 |
---|---|---|
committer | olegendo <olegendo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-05-04 07:14:11 +0000 |
commit | 121329865bb52656e6baacaac9ceaf278dbc3238 (patch) | |
tree | b83fc185cc0166a1c0a9e4730902267830baed4e | |
parent | 846521ce48938166d59dc1f4039ff6ed5566fe2b (diff) | |
download | gcc-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/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/sh/predicates.md | 12 | ||||
-rw-r--r-- | gcc/config/sh/sh-protos.h | 8 | ||||
-rw-r--r-- | gcc/config/sh/sh.h | 10 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 25 |
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. |