h8300.md (adjust_length): New attribute.
authorVladimir Makarov <vmakarov@tofu.to.cygnus.com>
Mon, 22 Mar 1999 07:56:09 +0000 (07:56 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Mon, 22 Mar 1999 07:56:09 +0000 (07:56 +0000)
Mon Mar 22 10:44:33 1999  Vladimir Makarov  <vmakarov@tofu.to.cygnus.com>
* config/h8300/h8300.md (adjust_length): New attribute.
  (modhi3+1, andsi3+1, iorsi3+1, extzv+1, extzv+2): Change insn
  default value of attribute "adjust_length" onto "no".
* config/h8300/h8300.c (h8300_adjust_insn_length):  Use 0 if the
shift is negative.
* final.c (shorten_branches): Check insn length after its
  adjusting.

From-SVN: r25895

gcc/ChangeLog
gcc/config/h8300/h8300.c
gcc/config/h8300/h8300.md
gcc/final.c

index 6a11810ebd141c61d870e49cad9d2d47a84d9616..318f8a78d9fcef8ca47b96b97333c09ec1cc9a34 100644 (file)
@@ -1,3 +1,15 @@
+Mon Mar 22 10:44:33 1999  Vladimir Makarov  <vmakarov@tofu.to.cygnus.com>
+
+       * config/h8300/h8300.md (adjust_length): New attribute.
+       (modhi3+1, andsi3+1, iorsi3+1, extzv+1, extzv+2): Change insn
+       default value of attribute "adjust_length" onto "no".
+
+       * config/h8300/h8300.c (h8300_adjust_insn_length):  Use 0 if the
+       shift is negative.
+
+       * final.c (shorten_branches): Check insn length after its
+       adjusting.
+
 Sun Mar 21 17:33:48 1999  Jeffrey A Law  (law@cygnus.com)
 
        * i860.h (TARGET_SWITCHES): Add documentation for default case.
index fac3cbf1acc720a6da8391ac9ec4af7a0a29fe37..eb5d418aece3bacd15f0b49a362943dcbe754503 100644 (file)
@@ -3031,7 +3031,12 @@ h8300_adjust_insn_length (insn, length)
      rtx insn;
      int length;
 {
-  rtx pat = PATTERN (insn);
+  rtx pat;
+
+  if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO)
+    return 0;
+
+  pat = PATTERN (insn);
 
   /* Adjust length for reg->mem and mem->reg copies.  */
   if (GET_CODE (pat) == SET
@@ -3109,34 +3114,37 @@ h8300_adjust_insn_length (insn, length)
     {
       rtx src = SET_SRC (XVECEXP (pat, 0, 0));
       enum machine_mode mode = GET_MODE (src);
+      int shift;
 
       if (GET_CODE (XEXP (src, 1)) != CONST_INT)
        return 0;
 
+      shift = INTVAL (XEXP (src, 1));
+      /* According to ANSI, negative shift is undefined.  It is
+         considered to be zero in this case (see function
+         emit_a_shift above). */
+      if (shift < 0)
+       shift = 0;
+
       /* QImode shifts by small constants take one insn
         per shift.  So the adjustment is 20 (md length) -
         # shifts * 2.  */
-      if (mode == QImode && INTVAL (XEXP (src, 1)) <= 4)
-       return -(20 - INTVAL (XEXP (src, 1)) * 2);
+      if (mode == QImode && shift <= 4)
+       return -(20 - shift * 2);
 
       /* Similarly for HImode and SImode shifts by
         small constants on the H8/300H and H8/300S.  */
       if ((TARGET_H8300H || TARGET_H8300S)
-         && (mode == HImode || mode == SImode)
-         && INTVAL (XEXP (src, 1)) <= 4)
-       return -(20 - INTVAL (XEXP (src, 1)) * 2);
+         && (mode == HImode || mode == SImode) && shift <= 4)
+       return -(20 - shift * 2);
 
       /* HImode shifts by small constants for the H8/300.  */
-      if (mode == HImode
-         && INTVAL (XEXP (src, 1)) <= 4)
-       return -(20 - (INTVAL (XEXP (src, 1))
-                      * (GET_CODE (src) == ASHIFT ? 2 : 4)));
+      if (mode == HImode && shift <= 4)
+       return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 2 : 4)));
 
       /* SImode shifts by small constants for the H8/300.  */
-      if (mode == SImode
-         && INTVAL (XEXP (src, 1)) <= 2)
-       return -(20 - (INTVAL (XEXP (src, 1))
-                      * (GET_CODE (src) == ASHIFT ? 6 : 8)));
+      if (mode == SImode && shift <= 2)
+       return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 6 : 8)));
 
       /* XXX ??? Could check for more shift/rotate cases here.  */
     }
index d892cad9cb71d772d8d0f2c95b4c90a8e3f404ea..7e49af5ef75312825bf7a7abbf581c7479fd393f 100644 (file)
                                     (const_int 6)))]
        (const_int 200)))
 
+;; The necessity of instruction length adjustment.
+
+(define_attr "adjust_length" "yes,no"
+  (cond [(eq_attr "type" "branch") (const_string "no")]
+        (const_string "yes")))
+
 ;; Condition code settings.
 ;; none - insn does not affect cc
 ;; none_0hit - insn does not affect cc but it does modify operand 0
    and %X2,%X0
    bclr        %W2,%R0"
   [(set_attr "length" "2,4")
+   (set_attr "adjust_length" "no")
    (set_attr "cc" "set_znv,none_0hit")])
 
 (define_expand "andqi3"
    or  %X2,%X0
    bset        %V2,%R0"
   [(set_attr "length" "2,4")
+   (set_attr "adjust_length" "no")
    (set_attr "cc" "set_znv,none_0hit")])
 
 (define_expand "iorqi3"
    xor %X2,%X0
    bnot        %V2,%R0"
   [(set_attr "length" "2,4")
+   (set_attr "adjust_length" "no")
    (set_attr "cc" "set_znv,none_0hit")])
 
 (define_expand "xorqi3"
   ""
   "bld %Z2,%Y1\;%b4    #0,%R0\;bst     #0,%R0; bl1"
   [(set_attr "cc" "clobber")
-   (set_attr "length" "6")])
+   (set_attr "length" "6")
+   (set_attr "adjust_length" "no")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "bit_operand" "=Ur")
   ""
   "bld %Z2,%Y1\;%b5    %Z4,%Y3\;bst    #0,%R0; bl3"
   [(set_attr "cc" "clobber")
-   (set_attr "length" "6")])
+   (set_attr "length" "6")
+   (set_attr "adjust_length" "no")])
 
 \f
 ;; ----------------------------------------------
index e82d5e96d1e6d4f4a19d47a26837263af926dcb4..3cd2e0cb98927768679399514ecdc3f93722b86e 100644 (file)
@@ -1318,6 +1318,8 @@ shorten_branches (first)
       /* If needed, do any adjustment.  */
 #ifdef ADJUST_INSN_LENGTH
       ADJUST_INSN_LENGTH (insn, insn_lengths[uid]);
+      if (insn_lengths[uid] < 0)
+       fatal_insn ("Negative insn length", insn);
 #endif
     }