From da5b1ec120cd4f8e68ff9f83f52a93f3a15bfb74 Mon Sep 17 00:00:00 2001 From: Oleg Endo Date: Wed, 4 May 2016 07:14:11 +0000 Subject: [PATCH] predicates (post_inc_mem, [...]): New predicates. 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 (*extendsi2_predec, *mov_load_predec, *mov_store_postinc): New patterns. From-SVN: r235859 --- gcc/ChangeLog | 11 +++++++++++ gcc/config/sh/predicates.md | 12 ++++++++++++ gcc/config/sh/sh-protos.h | 8 ++++++-- gcc/config/sh/sh.h | 10 ++++------ 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 + + * 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 (*extendsi2_predec, *mov_load_predec, + *mov_store_postinc): New patterns. + 2016-05-04 Marc Glisse * 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 "*extendsi2_predec" + [(set (match_operand:SI 0 "arith_reg_dest" "=z") + (sign_extend:SI (match_operand:QIHI 1 "pre_dec_mem" "<")))] + "TARGET_SH2A" + "mov. %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); }) +;; The pre-dec and post-inc mems must be captured by the '<' and '>' +;; constraints, otherwise wrong code might get generated. +(define_insn "*mov_load_predec" + [(set (match_operand:QIHISI 0 "arith_reg_dest" "=z") + (match_operand:QIHISI 1 "pre_dec_mem" "<"))] + "TARGET_SH2A" + "mov. %1,%0" + [(set_attr "type" "load")]) + +(define_insn "*mov_store_postinc" + [(set (match_operand:QIHISI 0 "post_inc_mem" "=>") + (match_operand:QIHISI 1 "arith_reg_operand" "z"))] + "TARGET_SH2A" + "mov. %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. -- 2.30.2