From 04b6000c8295a88c4e6a53f6226ad92657e588fb Mon Sep 17 00:00:00 2001 From: Vladimir Makarov Date: Mon, 22 Mar 1999 07:56:09 +0000 Subject: [PATCH] h8300.md (adjust_length): New attribute. Mon Mar 22 10:44:33 1999 Vladimir Makarov * 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 | 12 ++++++++++++ gcc/config/h8300/h8300.c | 36 ++++++++++++++++++++++-------------- gcc/config/h8300/h8300.md | 15 +++++++++++++-- gcc/final.c | 2 ++ 4 files changed, 49 insertions(+), 16 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6a11810ebd1..318f8a78d9f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +Mon Mar 22 10:44:33 1999 Vladimir Makarov + + * 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. diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index fac3cbf1acc..eb5d418aece 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -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. */ } diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index d892cad9cb7..7e49af5ef75 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -81,6 +81,12 @@ (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 @@ -983,6 +989,7 @@ 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" @@ -1087,6 +1094,7 @@ 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" @@ -1173,6 +1181,7 @@ 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" @@ -2226,7 +2235,8 @@ "" "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") @@ -2240,7 +2250,8 @@ "" "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")]) ;; ---------------------------------------------- diff --git a/gcc/final.c b/gcc/final.c index e82d5e96d1e..3cd2e0cb989 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -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 }