OSDN Git Service

config/m32r/m32r-protos.h: Remove the prototypes for
authornickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Mar 2005 18:05:54 +0000 (18:05 +0000)
committernickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Mar 2005 18:05:54 +0000 (18:05 +0000)
call_address_operand, symbolic_operand, seth_add3_operand,
cmp_int16_operand, uint16_operand, reg_or_int16_operand,
reg_or_uint16_operand, reg_or_cmp_int16_operand,
two_insn_const_operand, move_src_operand,
move_double_src_operand, move_dest_operand,
eqne_comparison_operator, signed_comparison_operator,
large_insn_p, conditional_move_operand, carry_compare_operand,
m32r_block_immediate_operand, extend_operand,
reg_or_eq_int16_operand, int8_operand, and
reg_or_zero_operand.
* config/m32r/m32r.c (call_address_operand, symbolic_operand,
seth_add3_operand, int8_operand, cmp_int16_operand,
uint16_operand, reg_or_int16_operand, reg_or_uint16_operand,
reg_or_eq_int16_operand, reg_or_cmp_int16_operand,
reg_or_zero_operand, two_insn_const_operand, move_src_operand,
move_double_src_operand, move_dest_operand,
eqne_comparison_operator, signed_comparison_operator,
extend_operand, small_insn_p, large_insn_p,
conditional_move_operand, carry_compare_operand,
m32r_block_immediate_operand): Move to predicates.md.
(MAX_MOVE_BYTES): Move to m32r.h.
* config/m32r/m32r.h (PREDICATE_CODES): Remove.
* config/m32r/m32r.md: Include predicates.md.
* config/m32r/predicates.md: New.

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

gcc/ChangeLog
gcc/config/m32r/m32r-protos.h
gcc/config/m32r/m32r.c
gcc/config/m32r/m32r.h
gcc/config/m32r/m32r.md
gcc/config/m32r/predicates.md [new file with mode: 0644]

index 2dc5a40..6adc260 100644 (file)
@@ -1,3 +1,31 @@
+2005-03-18  2005-03-18  Kazu Hirata  <kazu@cs.umass.edu>
+
+       * config/m32r/m32r-protos.h: Remove the prototypes for
+       call_address_operand, symbolic_operand, seth_add3_operand,
+       cmp_int16_operand, uint16_operand, reg_or_int16_operand,
+       reg_or_uint16_operand, reg_or_cmp_int16_operand,
+       two_insn_const_operand, move_src_operand,
+       move_double_src_operand, move_dest_operand,
+       eqne_comparison_operator, signed_comparison_operator,
+       large_insn_p, conditional_move_operand, carry_compare_operand,
+       m32r_block_immediate_operand, extend_operand,
+       reg_or_eq_int16_operand, int8_operand, and
+       reg_or_zero_operand.
+       * config/m32r/m32r.c (call_address_operand, symbolic_operand,
+       seth_add3_operand, int8_operand, cmp_int16_operand,
+       uint16_operand, reg_or_int16_operand, reg_or_uint16_operand,
+       reg_or_eq_int16_operand, reg_or_cmp_int16_operand,
+       reg_or_zero_operand, two_insn_const_operand, move_src_operand,
+       move_double_src_operand, move_dest_operand,
+       eqne_comparison_operator, signed_comparison_operator,
+       extend_operand, small_insn_p, large_insn_p,
+       conditional_move_operand, carry_compare_operand,
+       m32r_block_immediate_operand): Move to predicates.md.
+       (MAX_MOVE_BYTES): Move to m32r.h.
+       * config/m32r/m32r.h (PREDICATE_CODES): Remove.
+       * config/m32r/m32r.md: Include predicates.md.
+       * config/m32r/predicates.md: New.
+
 2005-03-18  Kazu Hirata  <kazu@cs.umass.edu>
 
        * hooks.c, hooks.h, intl.c, opts.h, prefix.c, tree-gimple.c,
index 2ea6a59..0f72bd7 100644 (file)
@@ -1,5 +1,5 @@
 /* Prototypes for m32r.c functions used in the md file & elsewhere.
-   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
 
    This file is part of GCC.
@@ -58,35 +58,13 @@ extern rtx    m32r_return_addr (int);
 extern rtx    m32r_function_symbol (const char *);
 
 #ifdef HAVE_MACHINE_MODES
-extern int    call_address_operand (rtx, Mmode);
 extern int    call_operand (rtx, Mmode);
-extern int    symbolic_operand (rtx, Mmode);
 extern int    small_data_operand (rtx, Mmode);
 extern int    addr24_operand (rtx, Mmode);
 extern int    addr32_operand (rtx, Mmode);
 extern int    call26_operand (rtx, Mmode);
-extern int    seth_add3_operand (rtx, Mmode);
-extern int    cmp_int16_operand (rtx, Mmode);
-extern int    uint16_operand (rtx, Mmode);
-extern int    reg_or_int16_operand (rtx, Mmode);
-extern int    reg_or_uint16_operand (rtx, Mmode);
-extern int    reg_or_cmp_int16_operand (rtx, Mmode);
-extern int    two_insn_const_operand (rtx, Mmode);
-extern int    move_src_operand (rtx, Mmode);
-extern int    move_double_src_operand (rtx, Mmode);
-extern int    move_dest_operand (rtx, Mmode);
-extern int    eqne_comparison_operator (rtx, Mmode);
-extern int    signed_comparison_operator (rtx, Mmode);
 extern int    memreg_operand (rtx, Mmode);
 extern int    small_insn_p (rtx, Mmode);
-extern int    large_insn_p (rtx, Mmode);
-extern int    conditional_move_operand (rtx, Mmode);
-extern int    carry_compare_operand (rtx, Mmode);
-extern int    m32r_block_immediate_operand (rtx, Mmode);
-extern int    extend_operand (rtx, Mmode);
-extern int    reg_or_eq_int16_operand (rtx, Mmode);
-extern int    int8_operand (rtx, Mmode);
-extern int    reg_or_zero_operand (rtx, Mmode);
 
 #endif /* HAVE_MACHINE_MODES */
 
index 170c4c6..dd86186 100644 (file)
@@ -1,6 +1,6 @@
 /* Subroutines used for code generation on the Renesas M32R cpu.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-   Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+   2005 Free Software Foundation, Inc.
 
    This file is part of GCC.
 
@@ -472,17 +472,6 @@ m32r_init_expanders (void)
      to make it easy to experiment.  */
 }
 \f
-/* Acceptable arguments to the call insn.  */
-
-int
-call_address_operand (rtx op, enum machine_mode mode)
-{
-  return symbolic_operand (op, mode);
-
-/* Constants and values in registers are not OK, because
-   the m32r BL instruction can only support PC relative branching.  */ 
-}
-
 int
 call_operand (rtx op, enum machine_mode mode)
 {
@@ -492,23 +481,6 @@ call_operand (rtx op, enum machine_mode mode)
   return call_address_operand (op, mode);
 }
 
-/* Returns 1 if OP is a symbol reference.  */
-
-int
-symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  switch (GET_CODE (op))
-    {
-    case SYMBOL_REF:
-    case LABEL_REF:
-    case CONST :
-      return 1;
-
-    default:
-      return 0;
-    }
-}
-
 /* Return 1 if OP is a reference to an object in .sdata/.sbss.  */
 
 int
@@ -604,256 +576,6 @@ call26_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
   return TARGET_CALL26;
 }
 
-/* Returns 1 if OP is an acceptable operand for seth/add3.  */
-
-int
-seth_add3_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (flag_pic)
-    return 0;
-
-  if (GET_CODE (op) == SYMBOL_REF
-      || GET_CODE (op) == LABEL_REF)
-    return 1;
-
-  if (GET_CODE (op) == CONST
-      && GET_CODE (XEXP (op, 0)) == PLUS
-      && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
-      && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
-      && INT16_P (INTVAL (XEXP (XEXP (op, 0), 1))))
-    return 1;
-
-  return 0;
-}
-
-/* Return true if OP is a signed 8 bit immediate value.  */
-
-int
-int8_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (GET_CODE (op) != CONST_INT)
-    return 0;
-  return INT8_P (INTVAL (op));
-}
-
-/* Return true if OP is a signed 16 bit immediate value
-   useful in comparisons.  */
-
-int
-cmp_int16_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (GET_CODE (op) != CONST_INT)
-    return 0;
-  return CMP_INT16_P (INTVAL (op));
-}
-
-/* Return true if OP is an unsigned 16 bit immediate value.  */
-
-int
-uint16_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (GET_CODE (op) != CONST_INT)
-    return 0;
-  return UINT16_P (INTVAL (op));
-}
-
-/* Return true if OP is a register or signed 16 bit value.  */
-
-int
-reg_or_int16_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
-    return register_operand (op, mode);
-  if (GET_CODE (op) != CONST_INT)
-    return 0;
-  return INT16_P (INTVAL (op));
-}
-
-/* Return true if OP is a register or an unsigned 16 bit value.  */
-
-int
-reg_or_uint16_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
-    return register_operand (op, mode);
-  if (GET_CODE (op) != CONST_INT)
-    return 0;
-  return UINT16_P (INTVAL (op));
-}
-
-/* Return true if OP is a register or an integer value that can be
-   used is SEQ/SNE.  We can use either XOR of the value or ADD of
-   the negative of the value for the constant.  Don't allow 0,
-   because that is special cased.  */
-
-int
-reg_or_eq_int16_operand (rtx op, enum machine_mode mode)
-{
-  HOST_WIDE_INT value;
-
-  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
-    return register_operand (op, mode);
-
-  if (GET_CODE (op) != CONST_INT)
-    return 0;
-
-  value = INTVAL (op);
-  return (value != 0) && (UINT16_P (value) || CMP_INT16_P (-value));
-}
-
-/* Return true if OP is a register or signed 16 bit value for compares.  */
-
-int
-reg_or_cmp_int16_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
-    return register_operand (op, mode);
-  if (GET_CODE (op) != CONST_INT)
-    return 0;
-  return CMP_INT16_P (INTVAL (op));
-}
-
-/* Return true if OP is a register or the constant 0.  */
-
-int
-reg_or_zero_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
-    return register_operand (op, mode);
-
-  if (GET_CODE (op) != CONST_INT)
-    return 0;
-
-  return INTVAL (op) == 0;
-}
-
-/* Return true if OP is a const_int requiring two instructions to load.  */
-
-int
-two_insn_const_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (GET_CODE (op) != CONST_INT)
-    return 0;
-  if (INT16_P (INTVAL (op))
-      || UINT24_P (INTVAL (op))
-      || UPPER16_P (INTVAL (op)))
-    return 0;
-  return 1;
-}
-
-/* Return true if OP is an acceptable argument for a single word
-   move source.  */
-
-int
-move_src_operand (rtx op, enum machine_mode mode)
-{
-  switch (GET_CODE (op))
-    {
-    case LABEL_REF :
-    case SYMBOL_REF :
-    case CONST :
-      return addr24_operand (op, mode);
-    case CONST_INT :
-      /* ??? We allow more cse opportunities if we only allow constants
-        loadable with one insn, and split the rest into two.  The instances
-        where this would help should be rare and the current way is
-        simpler.  */
-      if (HOST_BITS_PER_WIDE_INT > 32)
-       {
-         HOST_WIDE_INT rest = INTVAL (op) >> 31;
-         return (rest == 0 || rest == -1);
-       }
-      else
-       return 1;
-    case CONST_DOUBLE :
-      if (mode == SFmode)
-       return 1;
-      else if (mode == SImode)
-       {
-         /* Large unsigned constants are represented as const_double's.  */
-         unsigned HOST_WIDE_INT low, high;
-
-         low = CONST_DOUBLE_LOW (op);
-         high = CONST_DOUBLE_HIGH (op);
-         return high == 0 && low <= (unsigned) 0xffffffff;
-       }
-      else
-       return 0;
-    case REG :
-      return register_operand (op, mode);
-    case SUBREG :
-      /* (subreg (mem ...) ...) can occur here if the inner part was once a
-        pseudo-reg and is now a stack slot.  */
-      if (GET_CODE (SUBREG_REG (op)) == MEM)
-       return address_operand (XEXP (SUBREG_REG (op), 0), mode);
-      else
-       return register_operand (op, mode);
-    case MEM :
-      if (GET_CODE (XEXP (op, 0)) == PRE_INC
-         || GET_CODE (XEXP (op, 0)) == PRE_DEC)
-       return 0;               /* loads can't do pre-{inc,dec} */
-      return address_operand (XEXP (op, 0), mode);
-    default :
-      return 0;
-    }
-}
-
-/* Return true if OP is an acceptable argument for a double word
-   move source.  */
-
-int
-move_double_src_operand (rtx op, enum machine_mode mode)
-{
-  switch (GET_CODE (op))
-    {
-    case CONST_INT :
-    case CONST_DOUBLE :
-      return 1;
-    case REG :
-      return register_operand (op, mode);
-    case SUBREG :
-      /* (subreg (mem ...) ...) can occur here if the inner part was once a
-        pseudo-reg and is now a stack slot.  */
-      if (GET_CODE (SUBREG_REG (op)) == MEM)
-       return move_double_src_operand (SUBREG_REG (op), mode);
-      else
-       return register_operand (op, mode);
-    case MEM :
-      /* Disallow auto inc/dec for now.  */
-      if (GET_CODE (XEXP (op, 0)) == PRE_DEC
-         || GET_CODE (XEXP (op, 0)) == PRE_INC)
-       return 0;
-      return address_operand (XEXP (op, 0), mode);
-    default :
-      return 0;
-    }
-}
-
-/* Return true if OP is an acceptable argument for a move destination.  */
-
-int
-move_dest_operand (rtx op, enum machine_mode mode)
-{
-  switch (GET_CODE (op))
-    {
-    case REG :
-      return register_operand (op, mode);
-    case SUBREG :
-      /* (subreg (mem ...) ...) can occur here if the inner part was once a
-        pseudo-reg and is now a stack slot.  */
-      if (GET_CODE (SUBREG_REG (op)) == MEM)
-       return address_operand (XEXP (SUBREG_REG (op), 0), mode);
-      else
-       return register_operand (op, mode);
-    case MEM :
-      if (GET_CODE (XEXP (op, 0)) == POST_INC)
-       return 0;               /* stores can't do post inc */
-      return address_operand (XEXP (op, 0), mode);
-    default :
-      return 0;
-    }
-}
-
 /* Return 1 if OP is a DImode const we want to handle inline.
    This must match the code in the movdi pattern.
    It is used by the 'G' CONST_DOUBLE_OK_FOR_LETTER.  */
@@ -893,28 +615,6 @@ easy_df_const (rtx op)
   return 0;
 }
 
-/* Return 1 if OP is an EQ or NE comparison operator.  */
-
-int
-eqne_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  enum rtx_code code = GET_CODE (op);
-
-  return (code == EQ || code == NE);
-}
-
-/* Return 1 if OP is a signed comparison operator.  */
-
-int
-signed_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  enum rtx_code code = GET_CODE (op);
-
-  return (COMPARISON_P (op)
-         && (code == EQ || code == NE
-             || code == LT || code == LE || code == GT || code == GE));
-}
-
 /* Return 1 if OP is (mem (reg ...)).
    This is used in insn length calcs.  */
 
@@ -924,58 +624,6 @@ memreg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
   return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == REG;
 }
 
-/* Return true if OP is an acceptable input argument for a zero/sign extend
-   operation.  */
-
-int
-extend_operand (rtx op, enum machine_mode mode)
-{
-  rtx addr;
-
-  switch (GET_CODE (op))
-    {
-    case REG :
-    case SUBREG :
-      return register_operand (op, mode);
-
-    case MEM :
-      addr = XEXP (op, 0);
-      if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
-       return 0;               /* loads can't do pre inc/pre dec */
-
-      return address_operand (addr, mode);
-
-    default :
-      return 0;
-    }
-}
-
-/* Return nonzero if the operand is an insn that is a small insn.
-   Allow const_int 0 as well, which is a placeholder for NOP slots.  */
-
-int
-small_insn_p (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
-    return 1;
-
-  if (! INSN_P (op))
-    return 0;
-
-  return get_attr_length (op) == 2;
-}
-
-/* Return nonzero if the operand is an insn that is a large insn.  */
-
-int
-large_insn_p (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (! INSN_P (op))
-    return 0;
-
-  return get_attr_length (op) != 2;
-}
-
 /* Return nonzero if TYPE must be passed by indirect reference.  */
 
 static bool
@@ -2424,59 +2072,6 @@ zero_and_one (rtx operand1, rtx operand2)
        ||((INTVAL (operand1) == 1) && (INTVAL (operand2) == 0)));
 }
 
-/* Return nonzero if the operand is suitable for use in a conditional move sequence.  */
-
-int
-conditional_move_operand (rtx operand, enum machine_mode mode)
-{
-  /* Only defined for simple integers so far...  */
-  if (mode != SImode && mode != HImode && mode != QImode)
-    return FALSE;
-
-  /* At the moment we can handle moving registers and loading constants.  */
-  /* To be added: Addition/subtraction/bitops/multiplication of registers.  */
-
-  switch (GET_CODE (operand))
-    {
-    case REG:
-      return 1;
-
-    case CONST_INT:
-      return INT8_P (INTVAL (operand));
-
-    default:
-#if 0
-      fprintf (stderr, "Test for cond move op of type: %s\n",
-              GET_RTX_NAME (GET_CODE (operand)));
-#endif
-      return 0;
-    }
-}
-
-/* Return true if the code is a test of the carry bit.  */
-
-int
-carry_compare_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  rtx x;
-
-  if (GET_MODE (op) != CCmode && GET_MODE (op) != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) != NE && GET_CODE (op) != EQ)
-    return FALSE;
-
-  x = XEXP (op, 0);
-  if (GET_CODE (x) != REG || REGNO (x) != CARRY_REGNUM)
-    return FALSE;
-
-  x = XEXP (op, 1);
-  if (GET_CODE (x) != CONST_INT || INTVAL (x) != 0)
-    return FALSE;
-
-  return TRUE;
-}
-
 /* Generate the correct assembler code to handle the conditional loading of a
    value into a register.  It is known that the operands satisfy the
    conditional_move_operand() function above.  The destination is operand[0].
@@ -2583,13 +2178,6 @@ block_move_call (rtx dest_reg, rtx src_reg, rtx bytes_rtx)
                     TYPE_MODE (sizetype));
 }
 
-/* The maximum number of bytes to copy using pairs of load/store instructions.
-   If a block is larger than this then a loop will be generated to copy
-   MAX_MOVE_BYTES chunks at a time.  The value of 32 is a semi-arbitrary choice.
-   A customer uses Dhrystome as their benchmark, and Dhrystone has a 31 byte
-   string copy in it.  */
-#define MAX_MOVE_BYTES 32
-
 /* Expand string/block move operations.
 
    operands[0] is the pointer to the destination.
@@ -2836,20 +2424,6 @@ m32r_output_block_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
     }
 }
 
-/* Return true if op is an integer constant, less than or equal to
-   MAX_MOVE_BYTES.  */
-
-int
-m32r_block_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (GET_CODE (op) != CONST_INT
-      || INTVAL (op) > MAX_MOVE_BYTES
-      || INTVAL (op) <= 0)
-    return 0;
-
-  return 1;
-}
-
 /* Return true if using NEW_REG in place of OLD_REG is ok.  */
 
 int
index 2ebda2a..82c1564 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler, Renesas M32R cpu.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-   Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+   2005 Free Software Foundation, Inc.
 
    This file is part of GCC.
 
@@ -1740,38 +1740,9 @@ enum m32r_function_type
 
 #define M32R_INTERRUPT_P(TYPE) ((TYPE) == M32R_FUNCTION_INTERRUPT)
 
-/* Define this if you have defined special-purpose predicates in the
-   file `MACHINE.c'.  This macro is called within an initializer of an
-   array of structures.  The first field in the structure is the name
-   of a predicate and the second field is an array of rtl codes.  For
-   each predicate, list all rtl codes that can be in expressions
-   matched by the predicate.  The list should have a trailing comma.  */
-
-#define PREDICATE_CODES                                                        \
-{ "reg_or_zero_operand",        { REG, SUBREG, CONST_INT }},            \
-{ "conditional_move_operand",  { REG, SUBREG, CONST_INT }},            \
-{ "carry_compare_operand",     { EQ, NE }},                            \
-{ "eqne_comparison_operator",  { EQ, NE }},                            \
-{ "signed_comparison_operator", { EQ, NE, LT, LE, GT, GE }},           \
-{ "move_dest_operand",         { REG, SUBREG, MEM }},                  \
-{ "move_src_operand",          { REG, SUBREG, MEM, CONST_INT,          \
-                                 CONST_DOUBLE, LABEL_REF, CONST,       \
-                                 SYMBOL_REF }},                        \
-{ "move_double_src_operand",   { REG, SUBREG, MEM, CONST_INT,          \
-                                 CONST_DOUBLE }},                      \
-{ "two_insn_const_operand",    { CONST_INT }},                         \
-{ "symbolic_operand",          { SYMBOL_REF, LABEL_REF, CONST }},      \
-{ "int8_operand",              { CONST_INT }},                         \
-{ "uint16_operand",            { CONST_INT }},                         \
-{ "reg_or_int16_operand",      { REG, SUBREG, CONST_INT }},            \
-{ "reg_or_uint16_operand",     { REG, SUBREG, CONST_INT }},            \
-{ "reg_or_cmp_int16_operand",  { REG, SUBREG, CONST_INT }},            \
-{ "reg_or_eq_int16_operand",   { REG, SUBREG, CONST_INT }},            \
-{ "cmp_int16_operand",         { CONST_INT }},                         \
-{ "call_address_operand",      { SYMBOL_REF, LABEL_REF, CONST }},      \
-{ "extend_operand",            { REG, SUBREG, MEM }},                  \
-{ "small_insn_p",              { INSN, CALL_INSN, JUMP_INSN }},        \
-{ "m32r_block_immediate_operand",{ CONST_INT }},                       \
-{ "large_insn_p",              { INSN, CALL_INSN, JUMP_INSN }},        \
-{ "seth_add3_operand",         { SYMBOL_REF, LABEL_REF, CONST }},
-
+/* The maximum number of bytes to copy using pairs of load/store instructions.
+   If a block is larger than this then a loop will be generated to copy
+   MAX_MOVE_BYTES chunks at a time.  The value of 32 is a semi-arbitrary choice.
+   A customer uses Dhrystome as their benchmark, and Dhrystone has a 31 byte
+   string copy in it.  */
+#define MAX_MOVE_BYTES 32
index 80c579d..6b79970 100644 (file)
   "long_IF,long_E,memory*2")
 
 \f
+(include "predicates.md")
+  
 ;; Expand prologue as RTL
 (define_expand "prologue"
   [(const_int 1)]
diff --git a/gcc/config/m32r/predicates.md b/gcc/config/m32r/predicates.md
new file mode 100644 (file)
index 0000000..d8561d6
--- /dev/null
@@ -0,0 +1,442 @@
+;; Predicate definitions for Renesas M32R.
+;; Copyright (C) 2005 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING.  If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;; Return true if OP is a register or the constant 0.
+
+(define_predicate "reg_or_zero_operand"
+  (match_code "reg,subreg,const_int")
+{
+  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
+    return register_operand (op, mode);
+
+  if (GET_CODE (op) != CONST_INT)
+    return 0;
+
+  return INTVAL (op) == 0;
+})
+
+;; Return nonzero if the operand is suitable for use in a conditional
+;; move sequence.
+
+(define_predicate "conditional_move_operand"
+  (match_code "reg,subreg,const_int")
+{
+  /* Only defined for simple integers so far...  */
+  if (mode != SImode && mode != HImode && mode != QImode)
+    return FALSE;
+
+  /* At the moment we can handle moving registers and loading constants.  */
+  /* To be added: Addition/subtraction/bitops/multiplication of registers.  */
+
+  switch (GET_CODE (op))
+    {
+    case REG:
+      return 1;
+
+    case CONST_INT:
+      return INT8_P (INTVAL (op));
+
+    default:
+#if 0
+      fprintf (stderr, "Test for cond move op of type: %s\n",
+              GET_RTX_NAME (GET_CODE (op)));
+#endif
+      return 0;
+    }
+})
+
+;; Return true if the code is a test of the carry bit.
+
+(define_predicate "carry_compare_operand"
+  (match_code "eq,ne")
+{
+  rtx x;
+
+  if (GET_MODE (op) != CCmode && GET_MODE (op) != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) != NE && GET_CODE (op) != EQ)
+    return FALSE;
+
+  x = XEXP (op, 0);
+  if (GET_CODE (x) != REG || REGNO (x) != CARRY_REGNUM)
+    return FALSE;
+
+  x = XEXP (op, 1);
+  if (GET_CODE (x) != CONST_INT || INTVAL (x) != 0)
+    return FALSE;
+
+  return TRUE;
+})
+
+;; Return 1 if OP is an EQ or NE comparison operator.
+
+(define_predicate "eqne_comparison_operator"
+  (match_code "eq,ne")
+{
+  enum rtx_code code = GET_CODE (op);
+
+  return (code == EQ || code == NE);
+})
+
+;; Return 1 if OP is a signed comparison operator.
+
+(define_predicate "signed_comparison_operator"
+  (match_code "eq,ne,lt,le,gt,ge")
+{
+  enum rtx_code code = GET_CODE (op);
+
+  return (COMPARISON_P (op)
+         && (code == EQ || code == NE
+             || code == LT || code == LE || code == GT || code == GE));
+})
+
+;; Return true if OP is an acceptable argument for a move destination.
+
+(define_predicate "move_dest_operand"
+  (match_code "reg,subreg,mem")
+{
+  switch (GET_CODE (op))
+    {
+    case REG :
+      return register_operand (op, mode);
+    case SUBREG :
+      /* (subreg (mem ...) ...) can occur here if the inner part was once a
+        pseudo-reg and is now a stack slot.  */
+      if (GET_CODE (SUBREG_REG (op)) == MEM)
+       return address_operand (XEXP (SUBREG_REG (op), 0), mode);
+      else
+       return register_operand (op, mode);
+    case MEM :
+      if (GET_CODE (XEXP (op, 0)) == POST_INC)
+       return 0;               /* stores can't do post inc */
+      return address_operand (XEXP (op, 0), mode);
+    default :
+      return 0;
+    }
+})
+
+;; Return true if OP is an acceptable argument for a single word move
+;; source.
+
+(define_predicate "move_src_operand"
+  (match_code "reg,subreg,mem,const_int,const_double,label_ref,const,symbol_ref")
+{
+  switch (GET_CODE (op))
+    {
+    case LABEL_REF :
+    case SYMBOL_REF :
+    case CONST :
+      return addr24_operand (op, mode);
+    case CONST_INT :
+      /* ??? We allow more cse opportunities if we only allow constants
+        loadable with one insn, and split the rest into two.  The instances
+        where this would help should be rare and the current way is
+        simpler.  */
+      if (HOST_BITS_PER_WIDE_INT > 32)
+       {
+         HOST_WIDE_INT rest = INTVAL (op) >> 31;
+         return (rest == 0 || rest == -1);
+       }
+      else
+       return 1;
+    case CONST_DOUBLE :
+      if (mode == SFmode)
+       return 1;
+      else if (mode == SImode)
+       {
+         /* Large unsigned constants are represented as const_double's.  */
+         unsigned HOST_WIDE_INT low, high;
+
+         low = CONST_DOUBLE_LOW (op);
+         high = CONST_DOUBLE_HIGH (op);
+         return high == 0 && low <= (unsigned) 0xffffffff;
+       }
+      else
+       return 0;
+    case REG :
+      return register_operand (op, mode);
+    case SUBREG :
+      /* (subreg (mem ...) ...) can occur here if the inner part was once a
+        pseudo-reg and is now a stack slot.  */
+      if (GET_CODE (SUBREG_REG (op)) == MEM)
+       return address_operand (XEXP (SUBREG_REG (op), 0), mode);
+      else
+       return register_operand (op, mode);
+    case MEM :
+      if (GET_CODE (XEXP (op, 0)) == PRE_INC
+         || GET_CODE (XEXP (op, 0)) == PRE_DEC)
+       return 0;               /* loads can't do pre-{inc,dec} */
+      return address_operand (XEXP (op, 0), mode);
+    default :
+      return 0;
+    }
+})
+
+;; Return true if OP is an acceptable argument for a double word move
+;; source.
+
+(define_predicate "move_double_src_operand"
+  (match_code "reg,subreg,mem,const_int,const_double")
+{
+  switch (GET_CODE (op))
+    {
+    case CONST_INT :
+    case CONST_DOUBLE :
+      return 1;
+    case REG :
+      return register_operand (op, mode);
+    case SUBREG :
+      /* (subreg (mem ...) ...) can occur here if the inner part was once a
+        pseudo-reg and is now a stack slot.  */
+      if (GET_CODE (SUBREG_REG (op)) == MEM)
+       return move_double_src_operand (SUBREG_REG (op), mode);
+      else
+       return register_operand (op, mode);
+    case MEM :
+      /* Disallow auto inc/dec for now.  */
+      if (GET_CODE (XEXP (op, 0)) == PRE_DEC
+         || GET_CODE (XEXP (op, 0)) == PRE_INC)
+       return 0;
+      return address_operand (XEXP (op, 0), mode);
+    default :
+      return 0;
+    }
+})
+
+;; Return true if OP is a const_int requiring two instructions to
+;; load.
+
+(define_predicate "two_insn_const_operand"
+  (match_code "const_int")
+{
+  if (GET_CODE (op) != CONST_INT)
+    return 0;
+  if (INT16_P (INTVAL (op))
+      || UINT24_P (INTVAL (op))
+      || UPPER16_P (INTVAL (op)))
+    return 0;
+  return 1;
+})
+
+;; Returns 1 if OP is a symbol reference.
+
+(define_predicate "symbolic_operand"
+  (match_code "symbol_ref,label_ref,const")
+{
+  switch (GET_CODE (op))
+    {
+    case SYMBOL_REF:
+    case LABEL_REF:
+    case CONST :
+      return 1;
+
+    default:
+      return 0;
+    }
+})
+
+;; Return true if OP is a signed 8 bit immediate value.
+
+(define_predicate "int8_operand"
+  (match_code "const_int")
+{
+  if (GET_CODE (op) != CONST_INT)
+    return 0;
+  return INT8_P (INTVAL (op));
+})
+
+;; Return true if OP is an unsigned 16 bit immediate value.
+
+(define_predicate "uint16_operand"
+  (match_code "const_int")
+{
+  if (GET_CODE (op) != CONST_INT)
+    return 0;
+  return UINT16_P (INTVAL (op));
+})
+
+;; Return true if OP is a register or signed 16 bit value.
+
+(define_predicate "reg_or_int16_operand"
+  (match_code "reg,subreg,const_int")
+{
+  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
+    return register_operand (op, mode);
+  if (GET_CODE (op) != CONST_INT)
+    return 0;
+  return INT16_P (INTVAL (op));
+})
+
+;; Return true if OP is a register or an unsigned 16 bit value.
+
+(define_predicate "reg_or_uint16_operand"
+  (match_code "reg,subreg,const_int")
+{
+  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
+    return register_operand (op, mode);
+  if (GET_CODE (op) != CONST_INT)
+    return 0;
+  return UINT16_P (INTVAL (op));
+})
+
+;; Return true if OP is a register or signed 16 bit value for
+;; compares.
+
+(define_predicate "reg_or_cmp_int16_operand"
+  (match_code "reg,subreg,const_int")
+{
+  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
+    return register_operand (op, mode);
+  if (GET_CODE (op) != CONST_INT)
+    return 0;
+  return CMP_INT16_P (INTVAL (op));
+})
+
+;; Return true if OP is a register or an integer value that can be
+;; used is SEQ/SNE.  We can use either XOR of the value or ADD of the
+;; negative of the value for the constant.  Don't allow 0, because
+;; that is special cased.
+
+(define_predicate "reg_or_eq_int16_operand"
+  (match_code "reg,subreg,const_int")
+{
+  HOST_WIDE_INT value;
+
+  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
+    return register_operand (op, mode);
+
+  if (GET_CODE (op) != CONST_INT)
+    return 0;
+
+  value = INTVAL (op);
+  return (value != 0) && (UINT16_P (value) || CMP_INT16_P (-value));
+})
+
+;; Return true if OP is a signed 16 bit immediate value useful in
+;; comparisons.
+
+(define_predicate "cmp_int16_operand"
+  (match_code "const_int")
+{
+  if (GET_CODE (op) != CONST_INT)
+    return 0;
+  return CMP_INT16_P (INTVAL (op));
+})
+
+;; Acceptable arguments to the call insn.
+
+(define_predicate "call_address_operand"
+  (match_code "symbol_ref,label_ref,const")
+{
+  return symbolic_operand (op, mode);
+
+/* Constants and values in registers are not OK, because
+   the m32r BL instruction can only support PC relative branching.  */
+})
+
+;; Return true if OP is an acceptable input argument for a zero/sign
+;; extend operation.
+
+(define_predicate "extend_operand"
+  (match_code "reg,subreg,mem")
+{
+  rtx addr;
+
+  switch (GET_CODE (op))
+    {
+    case REG :
+    case SUBREG :
+      return register_operand (op, mode);
+
+    case MEM :
+      addr = XEXP (op, 0);
+      if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
+       return 0;               /* loads can't do pre inc/pre dec */
+
+      return address_operand (addr, mode);
+
+    default :
+      return 0;
+    }
+})
+
+;; Return nonzero if the operand is an insn that is a small
+;; insn. Allow const_int 0 as well, which is a placeholder for NOP
+;; slots.
+
+(define_predicate "small_insn_p"
+  (match_code "insn,call_insn,jump_insn")
+{
+  if (GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
+    return 1;
+
+  if (! INSN_P (op))
+    return 0;
+
+  return get_attr_length (op) == 2;
+})
+
+;; Return true if op is an integer constant, less than or equal to
+;; MAX_MOVE_BYTES.
+
+(define_predicate "m32r_block_immediate_operand"
+  (match_code "const_int")
+{
+  if (GET_CODE (op) != CONST_INT
+      || INTVAL (op) > MAX_MOVE_BYTES
+      || INTVAL (op) <= 0)
+    return 0;
+
+  return 1;
+})
+
+;; Return nonzero if the operand is an insn that is a large insn.
+
+(define_predicate "large_insn_p"
+  (match_code "insn,call_insn,jump_insn")
+{
+  if (! INSN_P (op))
+    return 0;
+
+  return get_attr_length (op) != 2;
+})
+
+;; Returns 1 if OP is an acceptable operand for seth/add3.
+
+(define_predicate "seth_add3_operand"
+  (match_code "symbol_ref,label_ref,const")
+{
+  if (flag_pic)
+    return 0;
+
+  if (GET_CODE (op) == SYMBOL_REF
+      || GET_CODE (op) == LABEL_REF)
+    return 1;
+
+  if (GET_CODE (op) == CONST
+      && GET_CODE (XEXP (op, 0)) == PLUS
+      && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
+      && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
+      && INT16_P (INTVAL (XEXP (XEXP (op, 0), 1))))
+    return 1;
+
+  return 0;
+})