From caf7f21af63ee8f8de2b352d69b93878e5e86dab Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Thu, 26 Jun 2003 13:04:09 +0000 Subject: [PATCH] h8300-protos.h: Change emit_a_rotate to output_a_rotate. * config/h8300/h8300-protos.h: Change emit_a_rotate to output_a_rotate. Add a prototype for compute_a_rotate_length. * config/h8300/h8300.c (emit_a_rotate): Change to output_a_rotate. (compute_a_rotate_length): New. (h8300_adjust_insn_length): Remove. * config/h8300/h8300.h (ADJUST_INSN_LENGTH): Remove. * config/h8300/h8300.md (adjust_length): Remove. (*rotlqi3_1): Use output_a_rotate and compute_a_rotate_length. (*rotlhi3_1): Likewise. (*rotlsi3_1): Likewise. From-SVN: r68528 --- gcc/ChangeLog | 14 ++++ gcc/config/h8300/h8300-protos.h | 3 +- gcc/config/h8300/h8300.c | 130 +++++++++++++------------------- gcc/config/h8300/h8300.h | 3 - gcc/config/h8300/h8300.md | 38 ++++------ 5 files changed, 82 insertions(+), 106 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0bf71eaa547..9844d81a60d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2003-06-26 Kazu Hirata + + * config/h8300/h8300-protos.h: Change emit_a_rotate to + output_a_rotate. Add a prototype for compute_a_rotate_length. + * config/h8300/h8300.c (emit_a_rotate): Change to + output_a_rotate. + (compute_a_rotate_length): New. + (h8300_adjust_insn_length): Remove. + * config/h8300/h8300.h (ADJUST_INSN_LENGTH): Remove. + * config/h8300/h8300.md (adjust_length): Remove. + (*rotlqi3_1): Use output_a_rotate and compute_a_rotate_length. + (*rotlhi3_1): Likewise. + (*rotlsi3_1): Likewise. + 2003-06-26 Roger Sayle Richard Henderson diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h index e7ddff8f1c3..d99f0dca0b9 100644 --- a/gcc/config/h8300/h8300-protos.h +++ b/gcc/config/h8300/h8300-protos.h @@ -33,7 +33,8 @@ extern int compute_plussi_cc (rtx *); extern const char *output_a_shift (rtx *); extern unsigned int compute_a_shift_length (rtx, rtx *); extern int compute_a_shift_cc (rtx, rtx *); -extern const char *emit_a_rotate (enum rtx_code, rtx *); +extern const char *output_a_rotate (enum rtx_code, rtx *); +extern unsigned int compute_a_rotate_length (rtx *); extern const char *output_simode_bld (int, rtx[]); extern void print_operand_address (FILE *, rtx); extern void print_operand (FILE *, rtx, int); diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index edb7820d128..54703c2452c 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -3822,7 +3822,7 @@ compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands) /* A rotation by a non-constant will cause a loop to be generated, in which a rotation by one bit is used. A rotation by a constant, including the one in the loop, will be taken care of by - emit_a_rotate () at the insn emit time. */ + output_a_rotate () at the insn emit time. */ int expand_a_rotate (enum rtx_code code, rtx operands[]) @@ -3877,10 +3877,10 @@ expand_a_rotate (enum rtx_code code, rtx operands[]) return 1; } -/* Emit rotate insns. */ +/* Output rotate insns. */ const char * -emit_a_rotate (enum rtx_code code, rtx *operands) +output_a_rotate (enum rtx_code code, rtx *operands) { rtx dst = operands[0]; rtx rotate_amount = operands[2]; @@ -3985,6 +3985,55 @@ emit_a_rotate (enum rtx_code code, rtx *operands) return ""; } + +unsigned int +compute_a_rotate_length (rtx *operands) +{ + rtx src = operands[1]; + enum machine_mode mode = GET_MODE (src); + int amount; + unsigned int length = 0; + + if (GET_CODE (XEXP (src, 1)) != CONST_INT) + return 0; + + amount = INTVAL (XEXP (src, 1)); + + /* Clean up AMOUNT. */ + if (amount < 0) + amount = 0; + if ((unsigned int) amount > GET_MODE_BITSIZE (mode)) + amount = GET_MODE_BITSIZE (mode); + + /* Determine the faster direction. After this phase, amount + will be at most a half of GET_MODE_BITSIZE (mode). */ + if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2) + /* Flip the direction. */ + amount = GET_MODE_BITSIZE (mode) - amount; + + /* See if a byte swap (in HImode) or a word swap (in SImode) can + boost up the rotation. */ + if ((mode == HImode && TARGET_H8300 && amount >= 5) + || (mode == HImode && TARGET_H8300H && amount >= 6) + || (mode == HImode && TARGET_H8300S && amount == 8) + || (mode == SImode && TARGET_H8300H && amount >= 10) + || (mode == SImode && TARGET_H8300S && amount >= 13)) + { + /* Adjust AMOUNT and flip the direction. */ + amount = GET_MODE_BITSIZE (mode) / 2 - amount; + length += 6; + } + + /* We use 2-bit rotations on the H8S. */ + if (TARGET_H8300S) + amount = amount / 2 + amount % 2; + + /* The H8/300 uses three insns to rotate one bit, taking 6 + length. */ + length += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2); + + return length; +} /* Fix the operands of a gen_xxx so that it could become a bit operating insn. */ @@ -4299,81 +4348,6 @@ output_simode_bld (int bild, rtx operands[]) return ""; } -/* Given INSN and its current length LENGTH, return the adjustment - (in bytes) to correctly compute INSN's length. - - We use this to get the lengths of various memory references correct. */ - -int -h8300_adjust_insn_length (rtx insn, int length ATTRIBUTE_UNUSED) -{ - rtx pat = PATTERN (insn); - - /* We must filter these out before calling get_attr_adjust_length. */ - if (GET_CODE (pat) == USE - || GET_CODE (pat) == CLOBBER - || GET_CODE (pat) == SEQUENCE - || GET_CODE (pat) == ADDR_VEC - || GET_CODE (pat) == ADDR_DIFF_VEC) - return 0; - - if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO) - return 0; - - /* Rotations need various adjustments. */ - if (GET_CODE (pat) == SET - && (GET_CODE (SET_SRC (pat)) == ROTATE - || GET_CODE (SET_SRC (pat)) == ROTATERT)) - { - rtx src = SET_SRC (pat); - enum machine_mode mode = GET_MODE (src); - int amount; - int states = 0; - - if (GET_CODE (XEXP (src, 1)) != CONST_INT) - return 0; - - amount = INTVAL (XEXP (src, 1)); - - /* Clean up AMOUNT. */ - if (amount < 0) - amount = 0; - if ((unsigned int) amount > GET_MODE_BITSIZE (mode)) - amount = GET_MODE_BITSIZE (mode); - - /* Determine the faster direction. After this phase, amount - will be at most a half of GET_MODE_BITSIZE (mode). */ - if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2) - /* Flip the direction. */ - amount = GET_MODE_BITSIZE (mode) - amount; - - /* See if a byte swap (in HImode) or a word swap (in SImode) can - boost up the rotation. */ - if ((mode == HImode && TARGET_H8300 && amount >= 5) - || (mode == HImode && TARGET_H8300H && amount >= 6) - || (mode == HImode && TARGET_H8300S && amount == 8) - || (mode == SImode && TARGET_H8300H && amount >= 10) - || (mode == SImode && TARGET_H8300S && amount >= 13)) - { - /* Adjust AMOUNT and flip the direction. */ - amount = GET_MODE_BITSIZE (mode) / 2 - amount; - states += 6; - } - - /* We use 2-bit rotations on the H8S. */ - if (TARGET_H8300S) - amount = amount / 2 + amount % 2; - - /* The H8/300 uses three insns to rotate one bit, taking 6 - states. */ - states += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2); - - return -(20 - states); - } - - return 0; -} - #ifndef OBJECT_FORMAT_ELF static void h8300_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED) diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h index 0bbeb2c1081..c04e531e725 100644 --- a/gcc/config/h8300/h8300.h +++ b/gcc/config/h8300/h8300.h @@ -1002,9 +1002,6 @@ struct cum_arg so give the MEM rtx a byte's mode. */ #define FUNCTION_MODE QImode -#define ADJUST_INSN_LENGTH(INSN, LENGTH) \ - LENGTH += h8300_adjust_insn_length (INSN, LENGTH); - #define BRANCH_COST 0 /* Tell final.c how to eliminate redundant test instructions. */ diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index 1b81c53287b..ad1d348a761 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -22,11 +22,9 @@ ;; the Free Software Foundation, 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. -;; Some of the extend instructions accept a general_operand_src, which -;; allows all the normal memory addressing modes. The length computations -;; don't take this into account. The lengths in the MD file should be -;; "worst case" and then be adjusted to their correct values by -;; h8300_adjust_insn_length. +;; We compute exact length on each instruction for most of the time. +;; In some case, most notably bit operations that may involve memory +;; operands, the lengths in this file are "worst case". ;; On the H8/300H and H8S, adds/subs operate on the 32bit "er" ;; registers. Right now GCC doesn't expose the "e" half to the @@ -90,12 +88,6 @@ (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 @@ -1180,7 +1172,6 @@ and %X2,%X0 bclr %W2,%R0" [(set_attr "length" "2,8") - (set_attr "adjust_length" "no") (set_attr "cc" "set_znv,none_0hit")]) (define_expand "andqi3" @@ -1281,7 +1272,6 @@ or\\t%X2,%X0 bset\\t%V2,%R0" [(set_attr "length" "2,8") - (set_attr "adjust_length" "no") (set_attr "cc" "set_znv,none_0hit")]) (define_expand "iorqi3" @@ -1323,7 +1313,6 @@ xor\\t%X2,%X0 bnot\\t%V2,%R0" [(set_attr "length" "2,8") - (set_attr "adjust_length" "no") (set_attr "cc" "set_znv,none_0hit")]) (define_expand "xorqi3" @@ -2441,8 +2430,9 @@ (rotate:QI (match_operand:QI 1 "register_operand" "0") (match_operand:QI 2 "immediate_operand" "")))] "" - "* return emit_a_rotate (ROTATE, operands);" - [(set_attr "length" "20") + "* return output_a_rotate (ROTATE, operands);" + [(set (attr "length") + (symbol_ref "compute_a_rotate_length (operands)")) (set_attr "cc" "clobber")]) (define_expand "rotlhi3" @@ -2457,8 +2447,9 @@ (rotate:HI (match_operand:HI 1 "register_operand" "0") (match_operand:QI 2 "immediate_operand" "")))] "" - "* return emit_a_rotate (ROTATE, operands);" - [(set_attr "length" "20") + "* return output_a_rotate (ROTATE, operands);" + [(set (attr "length") + (symbol_ref "compute_a_rotate_length (operands)")) (set_attr "cc" "clobber")]) (define_expand "rotlsi3" @@ -2473,8 +2464,9 @@ (rotate:SI (match_operand:SI 1 "register_operand" "0") (match_operand:QI 2 "immediate_operand" "")))] "TARGET_H8300H || TARGET_H8300S" - "* return emit_a_rotate (ROTATE, operands);" - [(set_attr "length" "20") + "* return output_a_rotate (ROTATE, operands);" + [(set (attr "length") + (symbol_ref "compute_a_rotate_length (operands)")) (set_attr "cc" "clobber")]) ;; ----------------------------------------------------------------- @@ -2633,8 +2625,7 @@ "" "bld %Z2,%Y1\;b%c4 #0,%R0\;bst #0,%R0; bl1" [(set_attr "cc" "clobber") - (set_attr "length" "6") - (set_attr "adjust_length" "no")]) + (set_attr "length" "6")]) (define_insn "" [(set (match_operand:HI 0 "bit_operand" "=Ur") @@ -2648,8 +2639,7 @@ "" "bld %Z2,%Y1\;b%c5 %Z4,%Y3\;bst #0,%R0; bl3" [(set_attr "cc" "clobber") - (set_attr "length" "6") - (set_attr "adjust_length" "no")]) + (set_attr "length" "6")]) ;; ----------------------------------------------------------------- ;; COMBINE PATTERNS