+2003-06-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * 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 <roger@eyesopen.com>
Richard Henderson <rth@redhat.com>
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);
/* 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[])
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];
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;
+}
\f
/* Fix the operands of a gen_xxx so that it could become a bit
operating insn. */
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)
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. */
;; 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
(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
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"
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"
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"
(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"
(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"
(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")])
\f
;; -----------------------------------------------------------------
""
"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")
""
"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")])
\f
;; -----------------------------------------------------------------
;; COMBINE PATTERNS