s390: Rearrange temporary moves for use of CRJ
authorRichard Henderson <rth@redhat.com>
Fri, 10 Aug 2012 02:12:56 +0000 (19:12 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Fri, 10 Aug 2012 02:12:56 +0000 (19:12 -0700)
* config/s390/s390.c (s390_expand_cs_hqi): Copy val to a temp before
performing the compare for the restart loop.

From-SVN: r190280

gcc/ChangeLog
gcc/config/s390/s390.c

index e978842929e346babb495033a56fb44a6ad0e26c..9e4e8720dc478218409ec6b2304f1ea2b5369129 100644 (file)
@@ -1,3 +1,8 @@
+2012-08-09  Richard Henderson  <rth@redhat.com>
+
+       * config/s390/s390.c (s390_expand_cs_hqi): Copy val to a temp before
+       performing the compare for the restart loop.
+
 2012-08-09  DJ Delorie  <dj@redhat.com>
 
        * config/rl78/rl78.c (rl78_alloc_physical_registers): Check for
index 5297ff3ff8dfe9a8f46a2d5427c1ecee031ae50b..0ae77a29c0c40d8ca4d81f9ce3d67edd97e52931 100644 (file)
@@ -4821,7 +4821,7 @@ s390_expand_cs_hqi (enum machine_mode mode, rtx btarget, rtx vtarget, rtx mem,
                    rtx cmp, rtx new_rtx, bool is_weak)
 {
   struct alignment_context ac;
-  rtx cmpv, newv, val, resv, cc, seq0, seq1, seq2, seq3;
+  rtx cmpv, newv, val, cc, seq0, seq1, seq2, seq3;
   rtx res = gen_reg_rtx (SImode);
   rtx csloop = NULL, csend = NULL;
 
@@ -4868,14 +4868,18 @@ s390_expand_cs_hqi (enum machine_mode mode, rtx btarget, rtx vtarget, rtx mem,
     emit_insn (gen_cstorecc4 (btarget, cc, XEXP (cc, 0), XEXP (cc, 1)));
   else
     {
+      rtx tmp;
+
       /* Jump to end if we're done (likely?).  */
       s390_emit_jump (csend, cc);
 
-      /* Check for changes outside mode, and loop internal if so.  */
-      resv = expand_simple_binop (SImode, AND, res, ac.modemaski,
-                                 NULL_RTX, 1, OPTAB_DIRECT);
-      cc = s390_emit_compare (NE, resv, val);
-      emit_move_insn (val, resv);
+      /* Check for changes outside mode, and loop internal if so.
+        Arrange the moves so that the compare is adjacent to the
+        branch so that we can generate CRJ.  */
+      tmp = copy_to_reg (val);
+      force_expand_binop (SImode, and_optab, res, ac.modemaski, val,
+                         1, OPTAB_DIRECT);
+      cc = s390_emit_compare (NE, val, tmp);
       s390_emit_jump (csloop, cc);
 
       /* Failed.  */