OSDN Git Service

* config/ia64/ia64.c (emit_insn_group_barriers): Stop if ar.lc
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 20 Aug 2000 19:03:03 +0000 (19:03 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 20 Aug 2000 19:03:03 +0000 (19:03 +0000)
        assigned before a loop.

        * config/ia64/ia64.md (ashlsi3): Zero extend the shift count.
        (ashrsi3, lshrsi3): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@35823 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.md

index 3a3bc0a..d5467b5 100644 (file)
@@ -1,3 +1,11 @@
+2000-08-20  Richard Henderson  <rth@cygnus.com>
+
+       * config/ia64/ia64.c (emit_insn_group_barriers): Stop if ar.lc
+       assigned before a loop.
+
+       * config/ia64/ia64.md (ashlsi3): Zero extend the shift count.
+       (ashrsi3, lshrsi3): Likewise.
+
 2000-08-20  Gabriel Dos Reis  <gdr@codesourcery.com>
 
        * c-lang.c: #include diagnostic.h
index 3088a82..f0ad8ba 100644 (file)
@@ -3934,6 +3934,21 @@ emit_insn_group_barriers (insns)
       switch (GET_CODE (insn))
        {
        case NOTE:
+         /* For very small loops we can wind up with extra stop bits
+            inside the loop because of not putting a stop after the
+            assignment to ar.lc before the loop label.  */
+         /* ??? Ideally we'd do this for any register used in the first
+            insn group that's been written recently.  */
+          if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
+           {
+             need_barrier = rws_access_regno (AR_LC_REGNUM, flags, 0);
+             if (need_barrier)
+               {
+                 emit_insn_after (gen_insn_group_barrier (), insn);
+                 memset (rws_sum, 0, sizeof(rws_sum));
+                 prev_insn = NULL_RTX;
+               }
+           }
          break;
 
        case CALL_INSN:
index e0173e6..3afddea 100644 (file)
 ;; ::
 ;; ::::::::::::::::::::
 
-(define_insn "ashlsi3"
+(define_expand "ashlsi3"
+  [(set (match_operand:SI 0 "register_operand" "")
+       (ashift:SI (match_operand:SI 1 "register_operand" "")
+                  (match_operand:SI 2 "reg_or_5bit_operand" "")))]
+  ""
+  "
+{
+  if (GET_CODE (operands[2]) != CONST_INT)
+    {
+      /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED?  Now
+        we've got to get rid of stray bits outside the SImode register.  */
+      rtx subshift = gen_reg_rtx (DImode);
+      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
+      operands[2] = subshift;
+    }
+}")
+
+(define_insn "*ashlsi3_internal"
   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
        (ashift:SI (match_operand:SI 1 "register_operand" "r,r,r")
-                  (match_operand:SI 2 "reg_or_5bit_operand" "R,n,r")))]
+                  (match_operand:DI 2 "reg_or_5bit_operand" "R,n,r")))]
   ""
   "@
    shladd %0 = %1, %2, r0
                         GEN_INT (32 - INTVAL (operands[2])), operands[2]));
   else
     {
+      rtx subshift = gen_reg_rtx (DImode);
       emit_insn (gen_extendsidi2 (subtarget, operands[1]));
-      emit_insn (gen_ashrdi3 (subtarget, subtarget,
-                             gen_lowpart (DImode, operands[2])));
+      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
+      emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
     }
   emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
   DONE;
                          GEN_INT (32 - INTVAL (operands[2])), operands[2]));
   else
     {
+      rtx subshift = gen_reg_rtx (DImode);
       emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
-      emit_insn (gen_lshrdi3 (subtarget, subtarget,
-                             gen_lowpart (DImode, operands[2])));
+      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
+      emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
     }
   emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
   DONE;