predicates (post_inc_mem, [...]): New predicates.
authorOleg Endo <olegendo@gcc.gnu.org>
Wed, 4 May 2016 07:14:11 +0000 (07:14 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Wed, 4 May 2016 07:14:11 +0000 (07:14 +0000)
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.

From-SVN: r235859

gcc/ChangeLog
gcc/config/sh/predicates.md
gcc/config/sh/sh-protos.h
gcc/config/sh/sh.h
gcc/config/sh/sh.md

index 6461fc196b79b7a25474b1e808a2c6d5d05a0591..272b1ed1cc2bdedf7dc06dc8b84bc74dbc793447 100644 (file)
@@ -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
index 3e69d88f64bbe6390532bf9948888744483aa7e4..b582637642a6e1ea3f1738606c0bfa69c3547a83 100644 (file)
        (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")
index ea7e847300ded8fea39963f8efd3d4a0fc7ab4fc..c47e2eade1534134c27e9feae98cbbbbd34bed6a 100644 (file)
@@ -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;
 }
index 60c625028c1da07daa69cc0922562dad1a2d9920..16b4a8e69007478454143a7c3da957fcdd06deae 100644 (file)
@@ -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.  */
index 2d9502b7aa7488aa5e4166d07b466152e7ea66a0..2a8fbc8df9b954d282cf8fd82a25dfe3d83714ea 100644 (file)
   [(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
   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.