* config/frv/frv-protos.h: Add a prototype to
authorkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 4 Apr 2005 21:53:22 +0000 (21:53 +0000)
committerkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 4 Apr 2005 21:53:22 +0000 (21:53 +0000)
frv_legitimate_memory_operand and frv_const_unspec_p.
(frv_unspec): Move from frv.c.
* config/frv/frv.c (frv_unspec): Move to frv-protos.h.
(frv_const_unspec_p, frv_legitimate_memory_operand_): Export.
(ldd_address_operand, fdpic_fptr_operand, frv_load_operand,
gpr_or_fpr_operand, gpr_or_int12_operand,
gpr_fpr_or_int12_operand, fpr_or_int6_operand,
gpr_or_int10_operand, gpr_or_int_operand, int12_operand,
int6_operand, int5_operand, uint5_operand, uint4_operand,
uint1_operand, int_2word_operand, uint16_operand,
upper_int16_operand, integer_register_operand,
gpr_no_subreg_operand, fpr_operand, even_reg_operand,
odd_reg_operand, even_gpr_operand, odd_gpr_operand,
quad_fpr_operand, even_fpr_operand, odd_fpr_operand,
dbl_memory_one_insn_operand, dbl_memory_two_insn_operand,
move_destination_operand, movcc_fp_destination_operand,
frv_function_symbol_referenced_p, move_source_operand,
condexec_dest_operand, condexec_source_operand,
reg_or_0_operand, lr_operand, fdpic_operand, got12_operand,
const_unspec_operand, gpr_or_memory_operand,
gpr_or_memory_operand_with_scratch, fpr_or_memory_operand,
icc_operand, fcc_operand, cc_operand, icr_operand,
fcr_operand, cr_operand, call_operand, sibcall_operand,
symbolic_operand, relational_operator,
integer_relational_operator, float_relational_operator,
ccr_eqne_operator, minmax_operator,
condexec_si_binary_operator, condexec_si_media_operator,
condexec_si_divide_operator, condexec_si_unary_operator,
condexec_sf_conv_operator, condexec_sf_add_operator,
condexec_memory_operand, intop_compare_operator, acc_operand,
even_acc_operand, quad_acc_operand, accg_operand: Move to
predicates.md.
* config/frv/frv.h (PREDICATE_CODES): Remove.
* config/frv/frv.md: Include predicates.md.
* config/frv/predicates.md: New.

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

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

index f7e21e7..63fbd06 100644 (file)
@@ -3,6 +3,43 @@
        * config/frv/frv.h (PREDICATE_CODES): Add CONST to
        gpr_or_int12_operand.
 
+       * config/frv/frv-protos.h: Add a prototype to
+       frv_legitimate_memory_operand and frv_const_unspec_p.
+       (frv_unspec): Move from frv.c.
+       * config/frv/frv.c (frv_unspec): Move to frv-protos.h.
+       (frv_const_unspec_p, frv_legitimate_memory_operand_): Export.
+       (ldd_address_operand, fdpic_fptr_operand, frv_load_operand,
+       gpr_or_fpr_operand, gpr_or_int12_operand,
+       gpr_fpr_or_int12_operand, fpr_or_int6_operand,
+       gpr_or_int10_operand, gpr_or_int_operand, int12_operand,
+       int6_operand, int5_operand, uint5_operand, uint4_operand,
+       uint1_operand, int_2word_operand, uint16_operand,
+       upper_int16_operand, integer_register_operand,
+       gpr_no_subreg_operand, fpr_operand, even_reg_operand,
+       odd_reg_operand, even_gpr_operand, odd_gpr_operand,
+       quad_fpr_operand, even_fpr_operand, odd_fpr_operand,
+       dbl_memory_one_insn_operand, dbl_memory_two_insn_operand,
+       move_destination_operand, movcc_fp_destination_operand,
+       frv_function_symbol_referenced_p, move_source_operand,
+       condexec_dest_operand, condexec_source_operand,
+       reg_or_0_operand, lr_operand, fdpic_operand, got12_operand,
+       const_unspec_operand, gpr_or_memory_operand,
+       gpr_or_memory_operand_with_scratch, fpr_or_memory_operand,
+       icc_operand, fcc_operand, cc_operand, icr_operand,
+       fcr_operand, cr_operand, call_operand, sibcall_operand,
+       symbolic_operand, relational_operator,
+       integer_relational_operator, float_relational_operator,
+       ccr_eqne_operator, minmax_operator,
+       condexec_si_binary_operator, condexec_si_media_operator,
+       condexec_si_divide_operator, condexec_si_unary_operator,
+       condexec_sf_conv_operator, condexec_sf_add_operator,
+       condexec_memory_operand, intop_compare_operator, acc_operand,
+       even_acc_operand, quad_acc_operand, accg_operand: Move to
+       predicates.md.
+       * config/frv/frv.h (PREDICATE_CODES): Remove.
+       * config/frv/frv.md: Include predicates.md.
+       * config/frv/predicates.md: New.
+
 2004-04-04  Richard Sandiford  <rsandifo@redhat.com>
 
        PR target/19537
index 23bb792..89107a0 100644 (file)
@@ -205,5 +205,18 @@ extern rtx frv_matching_accg_for_acc       (rtx);
 extern void frv_expand_fdpic_call      (rtx *, bool, bool);
 extern rtx frv_gen_GPsym2reg           (rtx, rtx);
 extern void frv_output_dwarf_dtprel    (FILE *, int, rtx);
+extern int frv_legitimate_memory_operand (rtx, enum machine_mode, int);
+
+/* Information about a relocation unspec.  SYMBOL is the relocation symbol
+   (a SYMBOL_REF or LABEL_REF), RELOC is the type of relocation and OFFSET
+   is the constant addend.  */
+struct frv_unspec {
+  rtx symbol;
+  int reloc;
+  HOST_WIDE_INT offset;
+};
+
+extern bool frv_const_unspec_p (rtx, struct frv_unspec *);
+
 #endif
 
index b75826c..f867159 100644 (file)
@@ -123,15 +123,6 @@ static unsigned int frv_num_nops;
        REG < REGNO (X) + HARD_REGNO_NREGS (REGNO (X), GET_MODE (X));   \
        REG++)
 
-/* Information about a relocation unspec.  SYMBOL is the relocation symbol
-   (a SYMBOL_REF or LABEL_REF), RELOC is the type of relocation and OFFSET
-   is the constant addend.  */
-struct frv_unspec {
-  rtx symbol;
-  int reloc;
-  HOST_WIDE_INT offset;
-};
-
 /* Temporary register allocation support structure.  */
 typedef struct frv_tmp_reg_struct
   {
@@ -256,7 +247,6 @@ static bool frv_handle_option                       (size_t, const char *, int);
 static int frv_default_flags_for_cpu           (void);
 static int frv_string_begins_with              (tree, const char *);
 static FRV_INLINE bool frv_small_data_reloc_p  (rtx, int);
-static FRV_INLINE bool frv_const_unspec_p      (rtx, struct frv_unspec *);
 static void frv_print_operand_memory_reference_reg
                                                (FILE *, rtx);
 static void frv_print_operand_memory_reference (FILE *, rtx, int);
@@ -280,7 +270,6 @@ static void frv_frame_access_multi          (frv_frame_accessor_t*,
 static void frv_frame_access_standard_regs     (enum frv_stack_op,
                                                 frv_stack_t *);
 static struct machine_function *frv_init_machine_status                (void);
-static int frv_legitimate_memory_operand       (rtx, enum machine_mode, int);
 static rtx frv_int_to_acc                      (enum insn_code, int, rtx);
 static enum machine_mode frv_matching_accg_mode        (enum machine_mode);
 static rtx frv_read_argument                   (tree *);
@@ -468,7 +457,7 @@ frv_small_data_reloc_p (rtx symbol, int reloc)
 /* Return true if X is a valid relocation unspec.  If it is, fill in UNSPEC
    appropriately.  */
 
-static FRV_INLINE bool
+bool
 frv_const_unspec_p (rtx x, struct frv_unspec *unspec)
 {
   if (GET_CODE (x) == CONST)
@@ -3715,7 +3704,7 @@ frv_find_base_term (rtx x)
 /* Return 1 if operand is a valid FRV address.  CONDEXEC_P is true if
    the operand is used by a predicated instruction.  */
 
-static int
+int
 frv_legitimate_memory_operand (rtx op, enum machine_mode mode, int condexec_p)
 {
   return ((GET_MODE (op) == mode || mode == VOIDmode)
@@ -3805,1607 +3794,84 @@ frv_expand_fdpic_call (rtx *operands, bool ret_value, bool sibcall)
     c = gen_call_fdpicdi (picreg, const0_rtx, lr);
   emit_call_insn (c);
 }
-
-/* An address operand that may use a pair of registers, an addressing
-   mode that we reject in general.  */
-
-int
-ldd_address_operand (rtx x, enum machine_mode mode)
-{
-  if (GET_MODE (x) != mode && GET_MODE (x) != VOIDmode)
-    return FALSE;
-
-  return frv_legitimate_address_p (DImode, x, reload_completed, FALSE, TRUE);
-}
-
-int
-fdpic_fptr_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-  if (GET_CODE (op) != REG)
-    return FALSE;
-  if (REGNO (op) != FDPIC_FPTR_REGNO && REGNO (op) < FIRST_PSEUDO_REGISTER)
-    return FALSE;
-  return TRUE;
-}
 \f
-/* Return 1 is OP is a memory operand, or will be turned into one by
-   reload.  */
-
-int
-frv_load_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (reload_in_progress)
-    {
-      rtx tmp = op;
-      if (GET_CODE (tmp) == SUBREG)
-       tmp = SUBREG_REG (tmp);
-      if (GET_CODE (tmp) == REG
-         && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
-       op = reg_equiv_memory_loc[REGNO (tmp)];
-    }
-
-  return op && memory_operand (op, mode);
-}
-
-
-/* Return 1 if operand is a GPR register or a FPR register.  */
-
-int
-gpr_or_fpr_operand (rtx op, enum machine_mode mode)
-{
-  int regno;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) == SUBREG)
-    {
-      if (GET_CODE (SUBREG_REG (op)) != REG)
-       return register_operand (op, mode);
-
-      op = SUBREG_REG (op);
-    }
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  regno = REGNO (op);
-  if (GPR_P (regno) || FPR_P (regno) || regno >= FIRST_PSEUDO_REGISTER)
-    return TRUE;
-
-  return FALSE;
-}
-
-/* Return 1 if operand is a GPR register or 12 bit signed immediate.  */
+/* Look for a SYMBOL_REF of a function in an rtx.  We always want to
+   process these separately from any offsets, such that we add any
+   offsets to the function descriptor (the actual pointer), not to the
+   function address.  */
 
-int
-gpr_or_int12_operand (rtx op, enum machine_mode mode)
+static bool
+frv_function_symbol_referenced_p (rtx x)
 {
-  if (GET_CODE (op) == CONST_INT)
-    return IN_RANGE_P (INTVAL (op), -2048, 2047);
+  const char *format;
+  int length;
+  int j;
 
-  if (got12_operand (op, mode))
-    return true;
+  if (GET_CODE (x) == SYMBOL_REF)
+    return SYMBOL_REF_FUNCTION_P (x);
 
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
+  length = GET_RTX_LENGTH (GET_CODE (x));
+  format = GET_RTX_FORMAT (GET_CODE (x));
 
-  if (GET_CODE (op) == SUBREG)
+  for (j = 0; j < length; ++j)
     {
-      if (GET_CODE (SUBREG_REG (op)) != REG)
-       return register_operand (op, mode);
-
-      op = SUBREG_REG (op);
-    }
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  return GPR_OR_PSEUDO_P (REGNO (op));
-}
-
-/* Return 1 if operand is a GPR register, or a FPR register, or a 12 bit
-   signed immediate.  */
-
-int
-gpr_fpr_or_int12_operand (rtx op, enum machine_mode mode)
-{
-  int regno;
-
-  if (GET_CODE (op) == CONST_INT)
-    return IN_RANGE_P (INTVAL (op), -2048, 2047);
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
+      switch (format[j])
+       {
+       case 'e':
+         if (frv_function_symbol_referenced_p (XEXP (x, j)))
+           return TRUE;
+         break;
 
-  if (GET_CODE (op) == SUBREG)
-    {
-      if (GET_CODE (SUBREG_REG (op)) != REG)
-       return register_operand (op, mode);
+       case 'V':
+       case 'E':
+         if (XVEC (x, j) != 0)
+           {
+             int k;
+             for (k = 0; k < XVECLEN (x, j); ++k)
+               if (frv_function_symbol_referenced_p (XVECEXP (x, j, k)))
+                 return TRUE;
+           }
+         break;
 
-      op = SUBREG_REG (op);
+       default:
+         /* Nothing to do.  */
+         break;
+       }
     }
 
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  regno = REGNO (op);
-  if (GPR_P (regno) || FPR_P (regno) || regno >= FIRST_PSEUDO_REGISTER)
-    return TRUE;
-
   return FALSE;
 }
 
-/* Return 1 if operand is a register or 6 bit signed immediate.  */
-
-int
-fpr_or_int6_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == CONST_INT)
-    return IN_RANGE_P (INTVAL (op), -32, 31);
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) == SUBREG)
-    {
-      if (GET_CODE (SUBREG_REG (op)) != REG)
-       return register_operand (op, mode);
-
-      op = SUBREG_REG (op);
-    }
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  return FPR_OR_PSEUDO_P (REGNO (op));
-}
-
-/* Return 1 if operand is a register or 10 bit signed immediate.  */
-
-int
-gpr_or_int10_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == CONST_INT)
-    return IN_RANGE_P (INTVAL (op), -512, 511);
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) == SUBREG)
-    {
-      if (GET_CODE (SUBREG_REG (op)) != REG)
-       return register_operand (op, mode);
-
-      op = SUBREG_REG (op);
-    }
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  return GPR_OR_PSEUDO_P (REGNO (op));
-}
-
-/* Return 1 if operand is a register or an integer immediate.  */
-
-int
-gpr_or_int_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == CONST_INT)
-    return TRUE;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) == SUBREG)
-    {
-      if (GET_CODE (SUBREG_REG (op)) != REG)
-       return register_operand (op, mode);
-
-      op = SUBREG_REG (op);
-    }
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  return GPR_OR_PSEUDO_P (REGNO (op));
-}
-
-/* Return 1 if operand is a 12 bit signed immediate.  */
+/* Return true if the memory operand is one that can be conditionally
+   executed.  */
 
 int
-int12_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+condexec_memory_operand (rtx op, enum machine_mode mode)
 {
-  if (GET_CODE (op) != CONST_INT)
-    return FALSE;
-
-  return IN_RANGE_P (INTVAL (op), -2048, 2047);
-}
-
-/* Return 1 if operand is a 6 bit signed immediate.  */
+  enum machine_mode op_mode = GET_MODE (op);
+  rtx addr;
 
-int
-int6_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (GET_CODE (op) != CONST_INT)
+  if (mode != VOIDmode && op_mode != mode)
     return FALSE;
 
-  return IN_RANGE_P (INTVAL (op), -32, 31);
-}
-
-/* Return 1 if operand is a 5 bit signed immediate.  */
-
-int
-int5_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), -16, 15);
-}
-
-/* Return 1 if operand is a 5 bit unsigned immediate.  */
-
-int
-uint5_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), 0, 31);
-}
-
-/* Return 1 if operand is a 4 bit unsigned immediate.  */
-
-int
-uint4_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), 0, 15);
-}
-
-/* Return 1 if operand is a 1 bit unsigned immediate (0 or 1).  */
-
-int
-uint1_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), 0, 1);
-}
-
-/* Return 1 if operand is an integer constant that takes 2 instructions
-   to load up and can be split into sethi/setlo instructions..  */
-
-int
-int_2word_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  HOST_WIDE_INT value;
-  REAL_VALUE_TYPE rv;
-  long l;
-
-  switch (GET_CODE (op))
+  switch (op_mode)
     {
     default:
-      break;
-
-    case LABEL_REF:
-      if (TARGET_FDPIC)
-       return FALSE;
-      
-      return (flag_pic == 0);
-
-    case CONST:
-      if (flag_pic || TARGET_FDPIC)
-       return FALSE;
-
-      op = XEXP (op, 0);
-      if (GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
-       op = XEXP (op, 0);
-      return GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF;
-
-    case SYMBOL_REF:
-      if (TARGET_FDPIC)
-       return FALSE;
-      
-      /* small data references are already 1 word */
-      return (flag_pic == 0) && (! SYMBOL_REF_SMALL_P (op));
-
-    case CONST_INT:
-      return ! IN_RANGE_P (INTVAL (op), -32768, 32767);
+      return FALSE;
 
-    case CONST_DOUBLE:
-      if (GET_MODE (op) == SFmode)
-       {
-         REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
-         REAL_VALUE_TO_TARGET_SINGLE (rv, l);
-         value = l;
-         return ! IN_RANGE_P (value, -32768, 32767);
-       }
-      else if (GET_MODE (op) == VOIDmode)
-       {
-         value = CONST_DOUBLE_LOW (op);
-         return ! IN_RANGE_P (value, -32768, 32767);
-       }
+    case QImode:
+    case HImode:
+    case SImode:
+    case SFmode:
       break;
     }
 
-  return FALSE;
-}
-
-/* Return 1 if operand is a 16 bit unsigned immediate.  */
-
-int
-uint16_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (GET_CODE (op) != CONST_INT)
-    return FALSE;
-
-  return IN_RANGE_P (INTVAL (op), 0, 0xffff);
-}
-
-/* Return 1 if operand is an integer constant with the bottom 16 bits
-   clear.  */
-
-int
-upper_int16_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (GET_CODE (op) != CONST_INT)
-    return FALSE;
-
-  return ((INTVAL (op) & 0xffff) == 0);
-}
-
-/* Return true if operand is a GPR register.  */
-
-int
-integer_register_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) == SUBREG)
-    {
-      if (GET_CODE (SUBREG_REG (op)) != REG)
-       return register_operand (op, mode);
-
-      op = SUBREG_REG (op);
-    }
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  return GPR_OR_PSEUDO_P (REGNO (op));
-}
-
-/* Return true if operand is a GPR register.  Do not allow SUBREG's
-   here, in order to prevent a combine bug.  */
-
-int
-gpr_no_subreg_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) != REG)
+  if (GET_CODE (op) != MEM)
     return FALSE;
 
-  return GPR_OR_PSEUDO_P (REGNO (op));
+  addr = XEXP (op, 0);
+  return frv_legitimate_address_p (mode, addr, reload_completed, TRUE, FALSE);
 }
-
-/* Return true if operand is a FPR register.  */
-
-int
-fpr_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) == SUBREG)
-    {
-      if (GET_CODE (SUBREG_REG (op)) != REG)
-        return register_operand (op, mode);
-
-      op = SUBREG_REG (op);
-    }
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  return FPR_OR_PSEUDO_P (REGNO (op));
-}
-
-/* Return true if operand is an even GPR or FPR register.  */
-
-int
-even_reg_operand (rtx op, enum machine_mode mode)
-{
-  int regno;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) == SUBREG)
-    {
-      if (GET_CODE (SUBREG_REG (op)) != REG)
-        return register_operand (op, mode);
-
-      op = SUBREG_REG (op);
-    }
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  regno = REGNO (op);
-  if (regno >= FIRST_PSEUDO_REGISTER)
-    return TRUE;
-
-  if (GPR_P (regno))
-    return (((regno - GPR_FIRST) & 1) == 0);
-
-  if (FPR_P (regno))
-    return (((regno - FPR_FIRST) & 1) == 0);
-
-  return FALSE;
-}
-
-/* Return true if operand is an odd GPR register.  */
-
-int
-odd_reg_operand (rtx op, enum machine_mode mode)
-{
-  int regno;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) == SUBREG)
-    {
-      if (GET_CODE (SUBREG_REG (op)) != REG)
-        return register_operand (op, mode);
-
-      op = SUBREG_REG (op);
-    }
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  regno = REGNO (op);
-  /* Assume that reload will give us an even register.  */
-  if (regno >= FIRST_PSEUDO_REGISTER)
-    return FALSE;
-
-  if (GPR_P (regno))
-    return (((regno - GPR_FIRST) & 1) != 0);
-
-  if (FPR_P (regno))
-    return (((regno - FPR_FIRST) & 1) != 0);
-
-  return FALSE;
-}
-
-/* Return true if operand is an even GPR register.  */
-
-int
-even_gpr_operand (rtx op, enum machine_mode mode)
-{
-  int regno;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) == SUBREG)
-    {
-      if (GET_CODE (SUBREG_REG (op)) != REG)
-        return register_operand (op, mode);
-
-      op = SUBREG_REG (op);
-    }
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  regno = REGNO (op);
-  if (regno >= FIRST_PSEUDO_REGISTER)
-    return TRUE;
-
-  if (! GPR_P (regno))
-    return FALSE;
-
-  return (((regno - GPR_FIRST) & 1) == 0);
-}
-
-/* Return true if operand is an odd GPR register.  */
-
-int
-odd_gpr_operand (rtx op, enum machine_mode mode)
-{
-  int regno;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) == SUBREG)
-    {
-      if (GET_CODE (SUBREG_REG (op)) != REG)
-        return register_operand (op, mode);
-
-      op = SUBREG_REG (op);
-    }
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  regno = REGNO (op);
-  /* Assume that reload will give us an even register.  */
-  if (regno >= FIRST_PSEUDO_REGISTER)
-    return FALSE;
-
-  if (! GPR_P (regno))
-    return FALSE;
-
-  return (((regno - GPR_FIRST) & 1) != 0);
-}
-
-/* Return true if operand is a quad aligned FPR register.  */
-
-int
-quad_fpr_operand (rtx op, enum machine_mode mode)
-{
-  int regno;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) == SUBREG)
-    {
-      if (GET_CODE (SUBREG_REG (op)) != REG)
-        return register_operand (op, mode);
-
-      op = SUBREG_REG (op);
-    }
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  regno = REGNO (op);
-  if (regno >= FIRST_PSEUDO_REGISTER)
-    return TRUE;
-
-  if (! FPR_P (regno))
-    return FALSE;
-
-  return (((regno - FPR_FIRST) & 3) == 0);
-}
-
-/* Return true if operand is an even FPR register.  */
-
-int
-even_fpr_operand (rtx op, enum machine_mode mode)
-{
-  int regno;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) == SUBREG)
-    {
-      if (GET_CODE (SUBREG_REG (op)) != REG)
-        return register_operand (op, mode);
-
-      op = SUBREG_REG (op);
-    }
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  regno = REGNO (op);
-  if (regno >= FIRST_PSEUDO_REGISTER)
-    return TRUE;
-
-  if (! FPR_P (regno))
-    return FALSE;
-
-  return (((regno - FPR_FIRST) & 1) == 0);
-}
-
-/* Return true if operand is an odd FPR register.  */
-
-int
-odd_fpr_operand (rtx op, enum machine_mode mode)
-{
-  int regno;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) == SUBREG)
-    {
-      if (GET_CODE (SUBREG_REG (op)) != REG)
-        return register_operand (op, mode);
-
-      op = SUBREG_REG (op);
-    }
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  regno = REGNO (op);
-  /* Assume that reload will give us an even register.  */
-  if (regno >= FIRST_PSEUDO_REGISTER)
-    return FALSE;
-
-  if (! FPR_P (regno))
-    return FALSE;
-
-  return (((regno - FPR_FIRST) & 1) != 0);
-}
-
-/* Return true if operand is a 2 word memory address that can be loaded in one
-   instruction to load or store.  We assume the stack and frame pointers are
-   suitably aligned, and variables in the small data area.  FIXME -- at some we
-   should recognize other globals and statics. We can't assume that any old
-   pointer is aligned, given that arguments could be passed on an odd word on
-   the stack and the address taken and passed through to another function.  */
-
-int
-dbl_memory_one_insn_operand (rtx op, enum machine_mode mode)
-{
-  rtx addr;
-  rtx addr_reg;
-
-  if (! TARGET_DWORD)
-    return FALSE;
-
-  if (GET_CODE (op) != MEM)
-    return FALSE;
-
-  if (mode != VOIDmode && GET_MODE_SIZE (mode) != 2*UNITS_PER_WORD)
-    return FALSE;
-
-  addr = XEXP (op, 0);
-  if (GET_CODE (addr) == REG)
-    addr_reg = addr;
-
-  else if (GET_CODE (addr) == PLUS)
-    {
-      rtx addr0 = XEXP (addr, 0);
-      rtx addr1 = XEXP (addr, 1);
-
-      if (GET_CODE (addr0) != REG)
-       return FALSE;
-
-      if (got12_operand (addr1, VOIDmode))
-       return TRUE;
-
-      if (GET_CODE (addr1) != CONST_INT)
-       return FALSE;
-
-      if ((INTVAL (addr1) & 7) != 0)
-       return FALSE;
-
-      addr_reg = addr0;
-    }
-
-  else
-    return FALSE;
-
-  if (addr_reg == frame_pointer_rtx || addr_reg == stack_pointer_rtx)
-    return TRUE;
-
-  return FALSE;
-}
-
-/* Return true if operand is a 2 word memory address that needs to
-   use two instructions to load or store.  */
-
-int
-dbl_memory_two_insn_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) != MEM)
-    return FALSE;
-
-  if (mode != VOIDmode && GET_MODE_SIZE (mode) != 2*UNITS_PER_WORD)
-    return FALSE;
-
-  if (! TARGET_DWORD)
-    return TRUE;
-
-  return ! dbl_memory_one_insn_operand (op, mode);
-}
-
-/* Return true if operand is something that can be an output for a move
-   operation.  */
-
-int
-move_destination_operand (rtx op, enum machine_mode mode)
-{
-  rtx subreg;
-  enum rtx_code code;
-
-  switch (GET_CODE (op))
-    {
-    default:
-      break;
-
-    case SUBREG:
-      if (GET_MODE (op) != mode && mode != VOIDmode)
-        return FALSE;
-
-      subreg = SUBREG_REG (op);
-      code = GET_CODE (subreg);
-      if (code == MEM)
-       return frv_legitimate_address_p (mode, XEXP (subreg, 0),
-                                        reload_completed, FALSE, FALSE);
-
-      return (code == REG);
-
-    case REG:
-      if (GET_MODE (op) != mode && mode != VOIDmode)
-        return FALSE;
-
-      return TRUE;
-
-    case MEM:
-      return frv_legitimate_memory_operand (op, mode, FALSE);
-    }
-
-  return FALSE;
-}
-
-/* Return true if we the operand is a valid destination for a movcc_fp
-   instruction.  This means rejecting fcc_operands, since we need
-   scratch registers to write to them.  */
-
-int
-movcc_fp_destination_operand (rtx op, enum machine_mode mode)
-{
-  if (fcc_operand (op, mode))
-    return FALSE;
-
-  return move_destination_operand (op, mode);
-}
-
-/* Look for a SYMBOL_REF of a function in an rtx.  We always want to
-   process these separately from any offsets, such that we add any
-   offsets to the function descriptor (the actual pointer), not to the
-   function address.  */
-
-static bool
-frv_function_symbol_referenced_p (rtx x)
-{
-  const char *format;
-  int length;
-  int j;
-
-  if (GET_CODE (x) == SYMBOL_REF)
-    return SYMBOL_REF_FUNCTION_P (x);
-
-  length = GET_RTX_LENGTH (GET_CODE (x));
-  format = GET_RTX_FORMAT (GET_CODE (x));
-
-  for (j = 0; j < length; ++j)
-    {
-      switch (format[j])
-       {
-       case 'e':
-         if (frv_function_symbol_referenced_p (XEXP (x, j)))
-           return TRUE;
-         break;
-
-       case 'V':
-       case 'E':
-         if (XVEC (x, j) != 0)
-           {
-             int k;
-             for (k = 0; k < XVECLEN (x, j); ++k)
-               if (frv_function_symbol_referenced_p (XVECEXP (x, j, k)))
-                 return TRUE;
-           }
-         break;
-
-       default:
-         /* Nothing to do.  */
-         break;
-       }
-    }
-
-  return FALSE;
-}
-
-/* Return true if operand is something that can be an input for a move
-   operation.  */
-
-int
-move_source_operand (rtx op, enum machine_mode mode)
-{
-  rtx subreg;
-  enum rtx_code code;
-
-  switch (GET_CODE (op))
-    {
-    default:
-      break;
-
-    case CONST_INT:
-    case CONST_DOUBLE:
-      return immediate_operand (op, mode);
-
-    case SUBREG:
-      if (GET_MODE (op) != mode && mode != VOIDmode)
-        return FALSE;
-
-      subreg = SUBREG_REG (op);
-      code = GET_CODE (subreg);
-      if (code == MEM)
-       return frv_legitimate_address_p (mode, XEXP (subreg, 0),
-                                        reload_completed, FALSE, FALSE);
-
-      return (code == REG);
-
-    case REG:
-      if (GET_MODE (op) != mode && mode != VOIDmode)
-        return FALSE;
-
-      return TRUE;
-
-    case MEM:
-      return frv_legitimate_memory_operand (op, mode, FALSE);
-    }
-
-  return FALSE;
-}
-
-/* Return true if operand is something that can be an output for a conditional
-   move operation.  */
-
-int
-condexec_dest_operand (rtx op, enum machine_mode mode)
-{
-  rtx subreg;
-  enum rtx_code code;
-
-  switch (GET_CODE (op))
-    {
-    default:
-      break;
-
-    case SUBREG:
-      if (GET_MODE (op) != mode && mode != VOIDmode)
-        return FALSE;
-
-      subreg = SUBREG_REG (op);
-      code = GET_CODE (subreg);
-      if (code == MEM)
-       return frv_legitimate_address_p (mode, XEXP (subreg, 0),
-                                        reload_completed, TRUE, FALSE);
-
-      return (code == REG);
-
-    case REG:
-      if (GET_MODE (op) != mode && mode != VOIDmode)
-        return FALSE;
-
-      return TRUE;
-
-    case MEM:
-      return frv_legitimate_memory_operand (op, mode, TRUE);
-    }
-
-  return FALSE;
-}
-
-/* Return true if operand is something that can be an input for a conditional
-   move operation.  */
-
-int
-condexec_source_operand (rtx op, enum machine_mode mode)
-{
-  rtx subreg;
-  enum rtx_code code;
-
-  switch (GET_CODE (op))
-    {
-    default:
-      break;
-
-    case CONST_INT:
-    case CONST_DOUBLE:
-      return ZERO_P (op);
-
-    case SUBREG:
-      if (GET_MODE (op) != mode && mode != VOIDmode)
-        return FALSE;
-
-      subreg = SUBREG_REG (op);
-      code = GET_CODE (subreg);
-      if (code == MEM)
-       return frv_legitimate_address_p (mode, XEXP (subreg, 0),
-                                        reload_completed, TRUE, FALSE);
-
-      return (code == REG);
-
-    case REG:
-      if (GET_MODE (op) != mode && mode != VOIDmode)
-        return FALSE;
-
-      return TRUE;
-
-    case MEM:
-      return frv_legitimate_memory_operand (op, mode, TRUE);
-    }
-
-  return FALSE;
-}
-
-/* Return true if operand is a register of any flavor or a 0 of the
-   appropriate type.  */
-
-int
-reg_or_0_operand (rtx op, enum machine_mode mode)
-{
-  switch (GET_CODE (op))
-    {
-    default:
-      break;
-
-    case REG:
-    case SUBREG:
-      if (GET_MODE (op) != mode && mode != VOIDmode)
-       return FALSE;
-
-      return register_operand (op, mode);
-
-    case CONST_INT:
-    case CONST_DOUBLE:
-      return ZERO_P (op);
-    }
-
-  return FALSE;
-}
-
-/* Return true if operand is the link register.  */
-
-int
-lr_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (REGNO (op) != LR_REGNO && REGNO (op) < FIRST_PSEUDO_REGISTER)
-    return FALSE;
-
-  return TRUE;
-}
-
-/* Return true if operand is the uClinux PIC register.  */
-
-int
-fdpic_operand (rtx op, enum machine_mode mode)
-{
-  if (!TARGET_FDPIC)
-    return FALSE;
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (REGNO (op) != FDPIC_REGNO && REGNO (op) < FIRST_PSEUDO_REGISTER)
-    return FALSE;
-
-  return TRUE;
-}
-
-int
-got12_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  struct frv_unspec unspec;
-
-  if (frv_const_unspec_p (op, &unspec))
-    switch (unspec.reloc)
-      {
-      case R_FRV_GOT12:
-      case R_FRV_GOTOFF12:
-      case R_FRV_FUNCDESC_GOT12:
-      case R_FRV_FUNCDESC_GOTOFF12:
-      case R_FRV_GPREL12:
-      case R_FRV_TLSMOFF12:
-       return true;
-      }
-  return false;
-}
-
-/* Return true if OP is a valid const-unspec expression.  */
-
-int
-const_unspec_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  struct frv_unspec unspec;
-
-  return frv_const_unspec_p (op, &unspec);
-}
-
-/* Return true if operand is a gpr register or a valid memory operand.  */
-
-int
-gpr_or_memory_operand (rtx op, enum machine_mode mode)
-{
-  return (integer_register_operand (op, mode)
-         || frv_legitimate_memory_operand (op, mode, FALSE));
-}
-
-/* Return true if operand is a gpr register, a valid memory operand,
-   or a memory operand that can be made valid using an additional gpr
-   register.  */
-
-int
-gpr_or_memory_operand_with_scratch (rtx op, enum machine_mode mode)
-{
-  rtx addr;
-
-  if (gpr_or_memory_operand (op, mode))
-    return TRUE;
-
-  if (GET_CODE (op) != MEM)
-    return FALSE;
-
-  if (GET_MODE (op) != mode)
-    return FALSE;
-
-  addr = XEXP (op, 0);
-
-  if (GET_CODE (addr) != PLUS)
-    return FALSE;
-      
-  if (!integer_register_operand (XEXP (addr, 0), Pmode))
-    return FALSE;
-
-  if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
-    return FALSE;
-
-  return TRUE;
-}
-
-/* Return true if operand is a fpr register or a valid memory operation.  */
-
-int
-fpr_or_memory_operand (rtx op, enum machine_mode mode)
-{
-  return (fpr_operand (op, mode)
-         || frv_legitimate_memory_operand (op, mode, FALSE));
-}
-
-/* Return true if operand is an icc register.  */
-
-int
-icc_operand (rtx op, enum machine_mode mode)
-{
-  int regno;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  regno = REGNO (op);
-  return ICC_OR_PSEUDO_P (regno);
-}
-
-/* Return true if operand is an fcc register.  */
-
-int
-fcc_operand (rtx op, enum machine_mode mode)
-{
-  int regno;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  regno = REGNO (op);
-  return FCC_OR_PSEUDO_P (regno);
-}
-
-/* Return true if operand is either an fcc or icc register.  */
-
-int
-cc_operand (rtx op, enum machine_mode mode)
-{
-  int regno;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  regno = REGNO (op);
-  if (CC_OR_PSEUDO_P (regno))
-    return TRUE;
-
-  return FALSE;
-}
-
-/* Return true if operand is an integer CCR register.  */
-
-int
-icr_operand (rtx op, enum machine_mode mode)
-{
-  int regno;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  regno = REGNO (op);
-  return ICR_OR_PSEUDO_P (regno);
-}
-
-/* Return true if operand is an fcc register.  */
-
-int
-fcr_operand (rtx op, enum machine_mode mode)
-{
-  int regno;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  regno = REGNO (op);
-  return FCR_OR_PSEUDO_P (regno);
-}
-
-/* Return true if operand is either an fcc or icc register.  */
-
-int
-cr_operand (rtx op, enum machine_mode mode)
-{
-  int regno;
-
-  if (GET_MODE (op) != mode && mode != VOIDmode)
-    return FALSE;
-
-  if (GET_CODE (op) != REG)
-    return FALSE;
-
-  regno = REGNO (op);
-  if (CR_OR_PSEUDO_P (regno))
-    return TRUE;
-
-  return FALSE;
-}
-
-/* Return true if operand is a memory reference suitable for a call.  */
-
-int
-call_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_MODE (op) != mode && mode != VOIDmode && GET_CODE (op) != CONST_INT)
-    return FALSE;
-
-  if (GET_CODE (op) == SYMBOL_REF)
-    return !TARGET_LONG_CALLS || SYMBOL_REF_LOCAL_P (op);
-
-  /* Note this doesn't allow reg+reg or reg+imm12 addressing (which should
-     never occur anyway), but prevents reload from not handling the case
-     properly of a call through a pointer on a function that calls
-     vfork/setjmp, etc. due to the need to flush all of the registers to stack.  */
-  return gpr_or_int12_operand (op, mode);
-}
-
-/* Return true if operand is a memory reference suitable for a sibcall.  */
-
-int
-sibcall_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_MODE (op) != mode && mode != VOIDmode && GET_CODE (op) != CONST_INT)
-    return FALSE;
-
-  /* Note this doesn't allow reg+reg or reg+imm12 addressing (which should
-     never occur anyway), but prevents reload from not handling the case
-     properly of a call through a pointer on a function that calls
-     vfork/setjmp, etc. due to the need to flush all of the registers to stack.  */
-  return gpr_or_int12_operand (op, mode);
-}
-
-/* Returns 1 if OP is either a SYMBOL_REF or a constant.  */
-int
-symbolic_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  enum rtx_code c = GET_CODE (op);
-
-  if (c == CONST)
-    {
-      /* Allow (const:SI (plus:SI (symbol_ref) (const_int))).  */
-      return GET_MODE (op) == SImode
-       && GET_CODE (XEXP (op, 0)) == PLUS
-       && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
-       && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT;
-    }
-
-  return c == SYMBOL_REF || c == CONST_INT;
-}
-
-/* Return true if operator is a kind of relational operator.  */
-
-int
-relational_operator (rtx op, enum machine_mode mode)
-{
-  return (integer_relational_operator (op, mode)
-         || float_relational_operator (op, mode));
-}
-
-/* Return true if OP is a relational operator suitable for CCmode,
-   CC_UNSmode or CC_NZmode.  */
-
-int
-integer_relational_operator (rtx op, enum machine_mode mode)
-{
-  if (mode != VOIDmode && mode != GET_MODE (op))
-    return FALSE;
-
-  /* The allowable relations depend on the mode of the ICC register.  */
-  switch (GET_CODE (op))
-    {
-    default:
-      return FALSE;
-
-    case EQ:
-    case NE:
-    case LT:
-    case GE:
-      return (GET_MODE (XEXP (op, 0)) == CC_NZmode
-             || GET_MODE (XEXP (op, 0)) == CCmode);
-
-    case LE:
-    case GT:
-      return GET_MODE (XEXP (op, 0)) == CCmode;
-
-    case GTU:
-    case GEU:
-    case LTU:
-    case LEU:
-      return (GET_MODE (XEXP (op, 0)) == CC_NZmode
-             || GET_MODE (XEXP (op, 0)) == CC_UNSmode);
-    }
-}
-
-/* Return true if operator is a floating point relational operator.  */
-
-int
-float_relational_operator (rtx op, enum machine_mode mode)
-{
-  if (mode != VOIDmode && mode != GET_MODE (op))
-    return FALSE;
-
-  switch (GET_CODE (op))
-    {
-    default:
-      return FALSE;
-
-    case EQ: case NE:
-    case LE: case LT:
-    case GE: case GT:
-#if 0
-    case UEQ: case UNE:
-    case ULE: case ULT:
-    case UGE: case UGT:
-    case ORDERED:
-    case UNORDERED:
-#endif
-      return GET_MODE (XEXP (op, 0)) == CC_FPmode;
-    }
-}
-
-/* Return true if operator is EQ/NE of a conditional execution register.  */
-
-int
-ccr_eqne_operator (rtx op, enum machine_mode mode)
-{
-  enum machine_mode op_mode = GET_MODE (op);
-  rtx op0;
-  rtx op1;
-  int regno;
-
-  if (mode != VOIDmode && op_mode != mode)
-    return FALSE;
-
-  switch (GET_CODE (op))
-    {
-    default:
-      return FALSE;
-
-    case EQ:
-    case NE:
-      break;
-    }
-
-  op1 = XEXP (op, 1);
-  if (op1 != const0_rtx)
-    return FALSE;
-
-  op0 = XEXP (op, 0);
-  if (GET_CODE (op0) != REG)
-    return FALSE;
-
-  regno = REGNO (op0);
-  if (op_mode == CC_CCRmode && CR_OR_PSEUDO_P (regno))
-    return TRUE;
-
-  return FALSE;
-}
-
-/* Return true if operator is a minimum or maximum operator (both signed and
-   unsigned).  */
-
-int
-minmax_operator (rtx op, enum machine_mode mode)
-{
-  if (mode != VOIDmode && mode != GET_MODE (op))
-    return FALSE;
-
-  switch (GET_CODE (op))
-    {
-    default:
-      return FALSE;
-
-    case SMIN:
-    case SMAX:
-    case UMIN:
-    case UMAX:
-      break;
-    }
-
-  if (! integer_register_operand (XEXP (op, 0), mode))
-    return FALSE;
-
-  if (! gpr_or_int10_operand (XEXP (op, 1), mode))
-    return FALSE;
-
-  return TRUE;
-}
-
-/* Return true if operator is an integer binary operator that can executed
-   conditionally and takes 1 cycle.  */
-
-int
-condexec_si_binary_operator (rtx op, enum machine_mode mode)
-{
-  enum machine_mode op_mode = GET_MODE (op);
-
-  if (mode != VOIDmode && op_mode != mode)
-    return FALSE;
-
-  switch (GET_CODE (op))
-    {
-    default:
-      return FALSE;
-
-    case PLUS:
-    case MINUS:
-    case AND:
-    case IOR:
-    case XOR:
-    case ASHIFT:
-    case ASHIFTRT:
-    case LSHIFTRT:
-      return TRUE;
-    }
-}
-
-/* Return true if operator is an integer binary operator that can be
-   executed conditionally by a media instruction.  */
-
-int
-condexec_si_media_operator (rtx op, enum machine_mode mode)
-{
-  enum machine_mode op_mode = GET_MODE (op);
-
-  if (mode != VOIDmode && op_mode != mode)
-    return FALSE;
-
-  switch (GET_CODE (op))
-    {
-    default:
-      return FALSE;
-
-    case AND:
-    case IOR:
-    case XOR:
-      return TRUE;
-    }
-}
-
-/* Return true if operator is an integer division operator that can executed
-   conditionally.  */
-
-int
-condexec_si_divide_operator (rtx op, enum machine_mode mode)
-{
-  enum machine_mode op_mode = GET_MODE (op);
-
-  if (mode != VOIDmode && op_mode != mode)
-    return FALSE;
-
-  switch (GET_CODE (op))
-    {
-    default:
-      return FALSE;
-
-    case DIV:
-    case UDIV:
-      return TRUE;
-    }
-}
-
-/* Return true if operator is an integer unary operator that can executed
-   conditionally.  */
-
-int
-condexec_si_unary_operator (rtx op, enum machine_mode mode)
-{
-  enum machine_mode op_mode = GET_MODE (op);
-
-  if (mode != VOIDmode && op_mode != mode)
-    return FALSE;
-
-  switch (GET_CODE (op))
-    {
-    default:
-      return FALSE;
-
-    case NEG:
-    case NOT:
-      return TRUE;
-    }
-}
-
-/* Return true if operator is a conversion-type expression that can be
-   evaluated conditionally by floating-point instructions.  */
-
-int
-condexec_sf_conv_operator (rtx op, enum machine_mode mode)
-{
-  enum machine_mode op_mode = GET_MODE (op);
-
-  if (mode != VOIDmode && op_mode != mode)
-    return FALSE;
-
-  switch (GET_CODE (op))
-    {
-    default:
-      return FALSE;
-
-    case NEG:
-    case ABS:
-      return TRUE;
-    }
-}
-
-/* Return true if operator is an addition or subtraction expression.
-   Such expressions can be evaluated conditionally by floating-point
-   instructions.  */
-
-int
-condexec_sf_add_operator (rtx op, enum machine_mode mode)
-{
-  enum machine_mode op_mode = GET_MODE (op);
-
-  if (mode != VOIDmode && op_mode != mode)
-    return FALSE;
-
-  switch (GET_CODE (op))
-    {
-    default:
-      return FALSE;
-
-    case PLUS:
-    case MINUS:
-      return TRUE;
-    }
-}
-
-/* Return true if the memory operand is one that can be conditionally
-   executed.  */
-
-int
-condexec_memory_operand (rtx op, enum machine_mode mode)
-{
-  enum machine_mode op_mode = GET_MODE (op);
-  rtx addr;
-
-  if (mode != VOIDmode && op_mode != mode)
-    return FALSE;
-
-  switch (op_mode)
-    {
-    default:
-      return FALSE;
-
-    case QImode:
-    case HImode:
-    case SImode:
-    case SFmode:
-      break;
-    }
-
-  if (GET_CODE (op) != MEM)
-    return FALSE;
-
-  addr = XEXP (op, 0);
-  return frv_legitimate_address_p (mode, addr, reload_completed, TRUE, FALSE);
-}
-
-/* Return true if OP is an integer binary operator that can be combined
-   with a (set ... (compare:CC_NZ ...)) pattern.  */
-
-int
-intop_compare_operator (rtx op, enum machine_mode mode)
-{
-  if (mode != VOIDmode && GET_MODE (op) != mode)
-    return FALSE;
-
-  switch (GET_CODE (op))
-    {
-    default:
-      return FALSE;
-
-    case PLUS:
-    case MINUS:
-    case AND:
-    case IOR:
-    case XOR:
-    case ASHIFTRT:
-    case LSHIFTRT:
-      return GET_MODE (op) == SImode;
-    }
-}
-
-/* Return 1 if operand is a valid ACC register number.  */
-
-int
-acc_operand (rtx op, enum machine_mode mode)
-{
-  return ((mode == VOIDmode || mode == GET_MODE (op))
-         && REG_P (op) && ACC_P (REGNO (op))
-         && ((REGNO (op) - ACC_FIRST) & ~ACC_MASK) == 0);
-}
-
-/* Return 1 if operand is a valid even ACC register number.  */
-
-int
-even_acc_operand (rtx op, enum machine_mode mode)
-{
-  return acc_operand (op, mode) && ((REGNO (op) - ACC_FIRST) & 1) == 0;
-}
-
-/* Return 1 if operand is zero or four.  */
-
-int
-quad_acc_operand (rtx op, enum machine_mode mode)
-{
-  return acc_operand (op, mode) && ((REGNO (op) - ACC_FIRST) & 3) == 0;
-}
-
-/* Return 1 if operand is a valid ACCG register number.  */
-
-int
-accg_operand (rtx op, enum machine_mode mode)
-{
-  return ((mode == VOIDmode || mode == GET_MODE (op))
-         && REG_P (op) && ACCG_P (REGNO (op))
-         && ((REGNO (op) - ACCG_FIRST) & ~ACC_MASK) == 0);
-}
-
 \f
 /* Return true if the bare return instruction can be used outside of the
    epilog code.  For frv, we only do it if there was no stack allocation.  */
index 1cd416d..9961758 100644 (file)
@@ -2758,104 +2758,6 @@ do {                                                                    \
 \f
 /* Miscellaneous Parameters.  */
 
-/* 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.  Here is an example of two entries in the list for a
-   typical RISC machine:
-
-        #define PREDICATE_CODES \
-          {"gen_reg_rtx_operand", {SUBREG, REG}},  \
-          {"reg_or_short_cint_operand", {SUBREG, REG, CONST_INT}},
-
-   Defining this macro does not affect the generated code (however, incorrect
-   definitions that omit an rtl code that may be matched by the predicate can
-   cause the compiler to malfunction).  Instead, it allows the table built by
-   `genrecog' to be more compact and efficient, thus speeding up the compiler.
-   The most important predicates to include in the list specified by this macro
-   are thoses used in the most insn patterns.  */
-#define PREDICATE_CODES                                                        \
-  { "integer_register_operand",                { REG, SUBREG }},               \
-  { "frv_load_operand",                        { REG, SUBREG, MEM }},          \
-  { "gpr_no_subreg_operand",           { REG }},                       \
-  { "gpr_or_fpr_operand",              { REG, SUBREG }},               \
-  { "gpr_or_int12_operand",            { REG, SUBREG, CONST_INT, CONST }},     \
-  { "gpr_fpr_or_int12_operand",                { REG, SUBREG, CONST_INT }},    \
-  { "gpr_or_int10_operand",            { REG, SUBREG, CONST_INT }},    \
-  { "gpr_or_int_operand",              { REG, SUBREG, CONST_INT }},    \
-  { "move_source_operand",             { REG, SUBREG, CONST_INT, MEM,  \
-                                         CONST_DOUBLE, CONST,          \
-                                         SYMBOL_REF, LABEL_REF }},     \
-  { "move_destination_operand",                { REG, SUBREG, MEM }},          \
-  { "movcc_fp_destination_operand",    { REG, SUBREG, MEM }},          \
-  { "condexec_source_operand",         { REG, SUBREG, CONST_INT, MEM,  \
-                                         CONST_DOUBLE }},              \
-  { "condexec_dest_operand",           { REG, SUBREG, MEM }},          \
-  { "reg_or_0_operand",                        { REG, SUBREG, CONST_INT }},    \
-  { "lr_operand",                      { REG }},                       \
-  { "gpr_or_memory_operand",           { REG, SUBREG, MEM }},          \
-  { "gpr_or_memory_operand_with_scratch", { REG, SUBREG, MEM }},       \
-  { "fpr_or_memory_operand",           { REG, SUBREG, MEM }},          \
-  { "int12_operand",                   { CONST_INT }},                 \
-  { "int_2word_operand",               { CONST_INT, CONST_DOUBLE,      \
-                                         SYMBOL_REF, LABEL_REF, CONST }}, \
-  { "fdpic_operand",                   { REG }},                       \
-  { "fdpic_fptr_operand",              { REG }},                       \
-  { "ldd_address_operand",             { REG, SUBREG, PLUS }},         \
-  { "got12_operand",                   { CONST }},                     \
-  { "const_unspec_operand",            { CONST }},                     \
-  { "icc_operand",                     { REG }},                       \
-  { "fcc_operand",                     { REG }},                       \
-  { "cc_operand",                      { REG }},                       \
-  { "icr_operand",                     { REG }},                       \
-  { "fcr_operand",                     { REG }},                       \
-  { "cr_operand",                      { REG }},                       \
-  { "fpr_operand",                     { REG, SUBREG }},               \
-  { "even_reg_operand",                        { REG, SUBREG }},               \
-  { "odd_reg_operand",                 { REG, SUBREG }},               \
-  { "even_gpr_operand",                        { REG, SUBREG }},               \
-  { "odd_gpr_operand",                 { REG, SUBREG }},               \
-  { "quad_fpr_operand",                        { REG, SUBREG }},               \
-  { "even_fpr_operand",                        { REG, SUBREG }},               \
-  { "odd_fpr_operand",                 { REG, SUBREG }},               \
-  { "dbl_memory_one_insn_operand",     { MEM }},                       \
-  { "dbl_memory_two_insn_operand",     { MEM }},                       \
-  { "call_operand",                    { REG, SUBREG, CONST_INT,       \
-                                         CONST, SYMBOL_REF }},         \
-  { "sibcall_operand",                 { REG, SUBREG, CONST_INT,       \
-                                         CONST }},                     \
-  { "upper_int16_operand",             { CONST_INT }},                 \
-  { "uint16_operand",                  { CONST_INT }},                 \
-  { "symbolic_operand",                 { SYMBOL_REF, CONST_INT }},     \
-  { "relational_operator",             { EQ, NE, LE, LT, GE, GT,       \
-                                         LEU, LTU, GEU, GTU }},        \
-  { "integer_relational_operator",     { EQ, NE, LE, LT, GE, GT,       \
-                                         LEU, LTU, GEU, GTU }},        \
-  { "float_relational_operator",       { EQ, NE, LE, LT, GE, GT }},    \
-  { "ccr_eqne_operator",               { EQ, NE }},                    \
-  { "minmax_operator",                 { SMIN, SMAX, UMIN, UMAX }},    \
-  { "condexec_si_binary_operator",     { PLUS, MINUS, AND, IOR, XOR,   \
-                                         ASHIFT, ASHIFTRT, LSHIFTRT }}, \
-  { "condexec_si_media_operator",      { AND, IOR, XOR }},             \
-  { "condexec_si_divide_operator",     { DIV, UDIV }},                 \
-  { "condexec_si_unary_operator",      { NOT, NEG }},                  \
-  { "condexec_sf_add_operator",                { PLUS, MINUS }},               \
-  { "condexec_sf_conv_operator",       { ABS, NEG }},                  \
-  { "intop_compare_operator",          { PLUS, MINUS, AND, IOR, XOR,   \
-                                         ASHIFT, ASHIFTRT, LSHIFTRT }}, \
-  { "fpr_or_int6_operand",             { REG, SUBREG, CONST_INT }},    \
-  { "int6_operand",                    { CONST_INT }},                 \
-  { "int5_operand",                    { CONST_INT }},                 \
-  { "uint5_operand",                   { CONST_INT }},                 \
-  { "uint4_operand",                   { CONST_INT }},                 \
-  { "uint1_operand",                   { CONST_INT }},                 \
-  { "acc_operand",                     { REG, SUBREG }},               \
-  { "even_acc_operand",                        { REG, SUBREG }},               \
-  { "quad_acc_operand",                        { REG, SUBREG }},               \
-  { "accg_operand",                    { REG, SUBREG }},
-
 /* An alias for a machine mode name.  This is the machine mode that elements of
    a jump-table should have.  */
 #define CASE_VECTOR_MODE SImode
index a81bc8b..3770b79 100644 (file)
 ;; )
 ;;
 
+(include "predicates.md")
 \f
 ;; ::::::::::::::::::::
 ;; ::
diff --git a/gcc/config/frv/predicates.md b/gcc/config/frv/predicates.md
new file mode 100644 (file)
index 0000000..656b695
--- /dev/null
@@ -0,0 +1,1550 @@
+;; Predicate definitions for Frv.
+;; 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 operand is a GPR register.
+
+(define_predicate "integer_register_operand"
+  (match_code "reg,subreg")
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return GPR_OR_PSEUDO_P (REGNO (op));
+})
+
+;; Return 1 is OP is a memory operand, or will be turned into one by
+;; reload.
+
+(define_predicate "frv_load_operand"
+  (match_code "reg,subreg,mem")
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (reload_in_progress)
+    {
+      rtx tmp = op;
+      if (GET_CODE (tmp) == SUBREG)
+       tmp = SUBREG_REG (tmp);
+      if (GET_CODE (tmp) == REG
+         && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
+       op = reg_equiv_memory_loc[REGNO (tmp)];
+    }
+
+  return op && memory_operand (op, mode);
+})
+
+;; Return true if operand is a GPR register.  Do not allow SUBREG's
+;; here, in order to prevent a combine bug.
+
+(define_predicate "gpr_no_subreg_operand"
+  (match_code "reg")
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return GPR_OR_PSEUDO_P (REGNO (op));
+})
+
+;; Return 1 if operand is a GPR register or a FPR register.
+
+(define_predicate "gpr_or_fpr_operand"
+  (match_code "reg,subreg")
+{
+  int regno;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  regno = REGNO (op);
+  if (GPR_P (regno) || FPR_P (regno) || regno >= FIRST_PSEUDO_REGISTER)
+    return TRUE;
+
+  return FALSE;
+})
+
+;; Return 1 if operand is a GPR register or 12 bit signed immediate.
+
+(define_predicate "gpr_or_int12_operand"
+  (match_code "reg,subreg,const_int,const")
+{
+  if (GET_CODE (op) == CONST_INT)
+    return IN_RANGE_P (INTVAL (op), -2048, 2047);
+
+  if (got12_operand (op, mode))
+    return true;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return GPR_OR_PSEUDO_P (REGNO (op));
+})
+
+;; Return 1 if operand is a GPR register, or a FPR register, or a 12
+;; bit signed immediate.
+
+(define_predicate "gpr_fpr_or_int12_operand"
+  (match_code "reg,subreg,const_int")
+{
+  int regno;
+
+  if (GET_CODE (op) == CONST_INT)
+    return IN_RANGE_P (INTVAL (op), -2048, 2047);
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  regno = REGNO (op);
+  if (GPR_P (regno) || FPR_P (regno) || regno >= FIRST_PSEUDO_REGISTER)
+    return TRUE;
+
+  return FALSE;
+})
+
+;; Return 1 if operand is a register or 10 bit signed immediate.
+
+(define_predicate "gpr_or_int10_operand"
+  (match_code "reg,subreg,const_int")
+{
+  if (GET_CODE (op) == CONST_INT)
+    return IN_RANGE_P (INTVAL (op), -512, 511);
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return GPR_OR_PSEUDO_P (REGNO (op));
+})
+
+;; Return 1 if operand is a register or an integer immediate.
+
+(define_predicate "gpr_or_int_operand"
+  (match_code "reg,subreg,const_int")
+{
+  if (GET_CODE (op) == CONST_INT)
+    return TRUE;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return GPR_OR_PSEUDO_P (REGNO (op));
+})
+
+;; Return true if operand is something that can be an input for a move
+;; operation.
+
+(define_predicate "move_source_operand"
+  (match_code "reg,subreg,const_int,mem,const_double,const,symbol_ref,label_ref")
+{
+  rtx subreg;
+  enum rtx_code code;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case CONST_INT:
+    case CONST_DOUBLE:
+      return immediate_operand (op, mode);
+
+    case SUBREG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+        return FALSE;
+
+      subreg = SUBREG_REG (op);
+      code = GET_CODE (subreg);
+      if (code == MEM)
+       return frv_legitimate_address_p (mode, XEXP (subreg, 0),
+                                        reload_completed, FALSE, FALSE);
+
+      return (code == REG);
+
+    case REG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+        return FALSE;
+
+      return TRUE;
+
+    case MEM:
+      return frv_legitimate_memory_operand (op, mode, FALSE);
+    }
+
+  return FALSE;
+})
+
+;; Return true if operand is something that can be an output for a
+;; move operation.
+
+(define_predicate "move_destination_operand"
+  (match_code "reg,subreg,mem")
+{
+  rtx subreg;
+  enum rtx_code code;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case SUBREG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+        return FALSE;
+
+      subreg = SUBREG_REG (op);
+      code = GET_CODE (subreg);
+      if (code == MEM)
+       return frv_legitimate_address_p (mode, XEXP (subreg, 0),
+                                        reload_completed, FALSE, FALSE);
+
+      return (code == REG);
+
+    case REG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+        return FALSE;
+
+      return TRUE;
+
+    case MEM:
+      return frv_legitimate_memory_operand (op, mode, FALSE);
+    }
+
+  return FALSE;
+})
+
+;; Return true if we the operand is a valid destination for a movcc_fp
+;; instruction.  This means rejecting fcc_operands, since we need
+;; scratch registers to write to them.
+
+(define_predicate "movcc_fp_destination_operand"
+  (match_code "reg,subreg,mem")
+{
+  if (fcc_operand (op, mode))
+    return FALSE;
+
+  return move_destination_operand (op, mode);
+})
+
+;; Return true if operand is something that can be an input for a
+;; conditional move operation.
+
+(define_predicate "condexec_source_operand"
+  (match_code "reg,subreg,const_int,mem,const_double")
+{
+  rtx subreg;
+  enum rtx_code code;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case CONST_INT:
+    case CONST_DOUBLE:
+      return ZERO_P (op);
+
+    case SUBREG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+        return FALSE;
+
+      subreg = SUBREG_REG (op);
+      code = GET_CODE (subreg);
+      if (code == MEM)
+       return frv_legitimate_address_p (mode, XEXP (subreg, 0),
+                                        reload_completed, TRUE, FALSE);
+
+      return (code == REG);
+
+    case REG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+        return FALSE;
+
+      return TRUE;
+
+    case MEM:
+      return frv_legitimate_memory_operand (op, mode, TRUE);
+    }
+
+  return FALSE;
+})
+
+;; Return true if operand is something that can be an output for a
+;; conditional move operation.
+
+(define_predicate "condexec_dest_operand"
+  (match_code "reg,subreg,mem")
+{
+  rtx subreg;
+  enum rtx_code code;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case SUBREG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+        return FALSE;
+
+      subreg = SUBREG_REG (op);
+      code = GET_CODE (subreg);
+      if (code == MEM)
+       return frv_legitimate_address_p (mode, XEXP (subreg, 0),
+                                        reload_completed, TRUE, FALSE);
+
+      return (code == REG);
+
+    case REG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+        return FALSE;
+
+      return TRUE;
+
+    case MEM:
+      return frv_legitimate_memory_operand (op, mode, TRUE);
+    }
+
+  return FALSE;
+})
+
+;; Return true if operand is a register of any flavor or a 0 of the
+;; appropriate type.
+
+(define_predicate "reg_or_0_operand"
+  (match_code "reg,subreg,const_int")
+{
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case REG:
+    case SUBREG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+       return FALSE;
+
+      return register_operand (op, mode);
+
+    case CONST_INT:
+    case CONST_DOUBLE:
+      return ZERO_P (op);
+    }
+
+  return FALSE;
+})
+
+;; Return true if operand is the link register.
+
+(define_predicate "lr_operand"
+  (match_code "reg")
+{
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (REGNO (op) != LR_REGNO && REGNO (op) < FIRST_PSEUDO_REGISTER)
+    return FALSE;
+
+  return TRUE;
+})
+
+;; Return true if operand is a gpr register or a valid memory operand.
+
+(define_predicate "gpr_or_memory_operand"
+  (match_code "reg,subreg,mem")
+{
+  return (integer_register_operand (op, mode)
+         || frv_legitimate_memory_operand (op, mode, FALSE));
+})
+
+;; Return true if operand is a gpr register, a valid memory operand,
+;; or a memory operand that can be made valid using an additional gpr
+;; register.
+
+(define_predicate "gpr_or_memory_operand_with_scratch"
+  (match_code "reg,subreg,mem")
+{
+  rtx addr;
+
+  if (gpr_or_memory_operand (op, mode))
+    return TRUE;
+
+  if (GET_CODE (op) != MEM)
+    return FALSE;
+
+  if (GET_MODE (op) != mode)
+    return FALSE;
+
+  addr = XEXP (op, 0);
+
+  if (GET_CODE (addr) != PLUS)
+    return FALSE;
+      
+  if (!integer_register_operand (XEXP (addr, 0), Pmode))
+    return FALSE;
+
+  if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
+    return FALSE;
+
+  return TRUE;
+})
+
+;; Return true if operand is a fpr register or a valid memory
+;; operation.
+
+(define_predicate "fpr_or_memory_operand"
+  (match_code "reg,subreg,mem")
+{
+  return (fpr_operand (op, mode)
+         || frv_legitimate_memory_operand (op, mode, FALSE));
+})
+
+;; Return 1 if operand is a 12 bit signed immediate.
+
+(define_predicate "int12_operand"
+  (match_code "const_int")
+{
+  if (GET_CODE (op) != CONST_INT)
+    return FALSE;
+
+  return IN_RANGE_P (INTVAL (op), -2048, 2047);
+})
+
+;; Return 1 if operand is an integer constant that takes 2
+;; instructions to load up and can be split into sethi/setlo
+;; instructions..
+
+(define_predicate "int_2word_operand"
+  (match_code "const_int,const_double,symbol_ref,label_ref,const")
+{
+  HOST_WIDE_INT value;
+  REAL_VALUE_TYPE rv;
+  long l;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case LABEL_REF:
+      if (TARGET_FDPIC)
+       return FALSE;
+      
+      return (flag_pic == 0);
+
+    case CONST:
+      if (flag_pic || TARGET_FDPIC)
+       return FALSE;
+
+      op = XEXP (op, 0);
+      if (GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
+       op = XEXP (op, 0);
+      return GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF;
+
+    case SYMBOL_REF:
+      if (TARGET_FDPIC)
+       return FALSE;
+      
+      /* small data references are already 1 word */
+      return (flag_pic == 0) && (! SYMBOL_REF_SMALL_P (op));
+
+    case CONST_INT:
+      return ! IN_RANGE_P (INTVAL (op), -32768, 32767);
+
+    case CONST_DOUBLE:
+      if (GET_MODE (op) == SFmode)
+       {
+         REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
+         REAL_VALUE_TO_TARGET_SINGLE (rv, l);
+         value = l;
+         return ! IN_RANGE_P (value, -32768, 32767);
+       }
+      else if (GET_MODE (op) == VOIDmode)
+       {
+         value = CONST_DOUBLE_LOW (op);
+         return ! IN_RANGE_P (value, -32768, 32767);
+       }
+      break;
+    }
+
+  return FALSE;
+})
+
+;; Return true if operand is the uClinux PIC register.
+
+(define_predicate "fdpic_operand"
+  (match_code "reg")
+{
+  if (!TARGET_FDPIC)
+    return FALSE;
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (REGNO (op) != FDPIC_REGNO && REGNO (op) < FIRST_PSEUDO_REGISTER)
+    return FALSE;
+
+  return TRUE;
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "fdpic_fptr_operand"
+  (match_code "reg")
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+  if (GET_CODE (op) != REG)
+    return FALSE;
+  if (REGNO (op) != FDPIC_FPTR_REGNO && REGNO (op) < FIRST_PSEUDO_REGISTER)
+    return FALSE;
+  return TRUE;
+})
+
+;; An address operand that may use a pair of registers, an addressing
+;; mode that we reject in general.
+
+(define_predicate "ldd_address_operand"
+  (match_code "reg,subreg,plus")
+{
+  if (GET_MODE (op) != mode && GET_MODE (op) != VOIDmode)
+    return FALSE;
+
+  return frv_legitimate_address_p (DImode, op, reload_completed, FALSE, TRUE);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "got12_operand"
+  (match_code "const")
+{
+  struct frv_unspec unspec;
+
+  if (frv_const_unspec_p (op, &unspec))
+    switch (unspec.reloc)
+      {
+      case R_FRV_GOT12:
+      case R_FRV_GOTOFF12:
+      case R_FRV_FUNCDESC_GOT12:
+      case R_FRV_FUNCDESC_GOTOFF12:
+      case R_FRV_GPREL12:
+      case R_FRV_TLSMOFF12:
+       return true;
+      }
+  return false;
+})
+
+;; Return true if OP is a valid const-unspec expression.
+
+(define_predicate "const_unspec_operand"
+  (match_code "const")
+{
+  struct frv_unspec unspec;
+
+  return frv_const_unspec_p (op, &unspec);
+})
+
+;; Return true if operand is an icc register.
+
+(define_predicate "icc_operand"
+  (match_code "reg")
+{
+  int regno;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  regno = REGNO (op);
+  return ICC_OR_PSEUDO_P (regno);
+})
+
+;; Return true if operand is an fcc register.
+
+(define_predicate "fcc_operand"
+  (match_code "reg")
+{
+  int regno;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  regno = REGNO (op);
+  return FCC_OR_PSEUDO_P (regno);
+})
+
+;; Return true if operand is either an fcc or icc register.
+
+(define_predicate "cc_operand"
+  (match_code "reg")
+{
+  int regno;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  regno = REGNO (op);
+  if (CC_OR_PSEUDO_P (regno))
+    return TRUE;
+
+  return FALSE;
+})
+
+;; Return true if operand is an integer CCR register.
+
+(define_predicate "icr_operand"
+  (match_code "reg")
+{
+  int regno;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  regno = REGNO (op);
+  return ICR_OR_PSEUDO_P (regno);
+})
+
+;; Return true if operand is an fcc register.
+
+(define_predicate "fcr_operand"
+  (match_code "reg")
+{
+  int regno;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  regno = REGNO (op);
+  return FCR_OR_PSEUDO_P (regno);
+})
+
+;; Return true if operand is either an fcc or icc register.
+
+(define_predicate "cr_operand"
+  (match_code "reg")
+{
+  int regno;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  regno = REGNO (op);
+  if (CR_OR_PSEUDO_P (regno))
+    return TRUE;
+
+  return FALSE;
+})
+
+;; Return true if operand is a FPR register.
+
+(define_predicate "fpr_operand"
+  (match_code "reg,subreg")
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+        return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return FPR_OR_PSEUDO_P (REGNO (op));
+})
+
+;; Return true if operand is an even GPR or FPR register.
+
+(define_predicate "even_reg_operand"
+  (match_code "reg,subreg")
+{
+  int regno;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+        return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  regno = REGNO (op);
+  if (regno >= FIRST_PSEUDO_REGISTER)
+    return TRUE;
+
+  if (GPR_P (regno))
+    return (((regno - GPR_FIRST) & 1) == 0);
+
+  if (FPR_P (regno))
+    return (((regno - FPR_FIRST) & 1) == 0);
+
+  return FALSE;
+})
+
+;; Return true if operand is an odd GPR register.
+
+(define_predicate "odd_reg_operand"
+  (match_code "reg,subreg")
+{
+  int regno;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+        return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  regno = REGNO (op);
+  /* Assume that reload will give us an even register.  */
+  if (regno >= FIRST_PSEUDO_REGISTER)
+    return FALSE;
+
+  if (GPR_P (regno))
+    return (((regno - GPR_FIRST) & 1) != 0);
+
+  if (FPR_P (regno))
+    return (((regno - FPR_FIRST) & 1) != 0);
+
+  return FALSE;
+})
+
+;; Return true if operand is an even GPR register.
+
+(define_predicate "even_gpr_operand"
+  (match_code "reg,subreg")
+{
+  int regno;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+        return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  regno = REGNO (op);
+  if (regno >= FIRST_PSEUDO_REGISTER)
+    return TRUE;
+
+  if (! GPR_P (regno))
+    return FALSE;
+
+  return (((regno - GPR_FIRST) & 1) == 0);
+})
+
+;; Return true if operand is an odd GPR register.
+
+(define_predicate "odd_gpr_operand"
+  (match_code "reg,subreg")
+{
+  int regno;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+        return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  regno = REGNO (op);
+  /* Assume that reload will give us an even register.  */
+  if (regno >= FIRST_PSEUDO_REGISTER)
+    return FALSE;
+
+  if (! GPR_P (regno))
+    return FALSE;
+
+  return (((regno - GPR_FIRST) & 1) != 0);
+})
+
+;; Return true if operand is a quad aligned FPR register.
+
+(define_predicate "quad_fpr_operand"
+  (match_code "reg,subreg")
+{
+  int regno;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+        return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  regno = REGNO (op);
+  if (regno >= FIRST_PSEUDO_REGISTER)
+    return TRUE;
+
+  if (! FPR_P (regno))
+    return FALSE;
+
+  return (((regno - FPR_FIRST) & 3) == 0);
+})
+
+;; Return true if operand is an even FPR register.
+
+(define_predicate "even_fpr_operand"
+  (match_code "reg,subreg")
+{
+  int regno;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+        return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  regno = REGNO (op);
+  if (regno >= FIRST_PSEUDO_REGISTER)
+    return TRUE;
+
+  if (! FPR_P (regno))
+    return FALSE;
+
+  return (((regno - FPR_FIRST) & 1) == 0);
+})
+
+;; Return true if operand is an odd FPR register.
+
+(define_predicate "odd_fpr_operand"
+  (match_code "reg,subreg")
+{
+  int regno;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+        return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  regno = REGNO (op);
+  /* Assume that reload will give us an even register.  */
+  if (regno >= FIRST_PSEUDO_REGISTER)
+    return FALSE;
+
+  if (! FPR_P (regno))
+    return FALSE;
+
+  return (((regno - FPR_FIRST) & 1) != 0);
+})
+
+;; Return true if operand is a 2 word memory address that can be
+;; loaded in one instruction to load or store.  We assume the stack
+;; and frame pointers are suitably aligned, and variables in the small
+;; data area.  FIXME -- at some we should recognize other globals and
+;; statics. We can't assume that any old pointer is aligned, given
+;; that arguments could be passed on an odd word on the stack and the
+;; address taken and passed through to another function.
+
+(define_predicate "dbl_memory_one_insn_operand"
+  (match_code "mem")
+{
+  rtx addr;
+  rtx addr_reg;
+
+  if (! TARGET_DWORD)
+    return FALSE;
+
+  if (GET_CODE (op) != MEM)
+    return FALSE;
+
+  if (mode != VOIDmode && GET_MODE_SIZE (mode) != 2*UNITS_PER_WORD)
+    return FALSE;
+
+  addr = XEXP (op, 0);
+  if (GET_CODE (addr) == REG)
+    addr_reg = addr;
+
+  else if (GET_CODE (addr) == PLUS)
+    {
+      rtx addr0 = XEXP (addr, 0);
+      rtx addr1 = XEXP (addr, 1);
+
+      if (GET_CODE (addr0) != REG)
+       return FALSE;
+
+      if (got12_operand (addr1, VOIDmode))
+       return TRUE;
+
+      if (GET_CODE (addr1) != CONST_INT)
+       return FALSE;
+
+      if ((INTVAL (addr1) & 7) != 0)
+       return FALSE;
+
+      addr_reg = addr0;
+    }
+
+  else
+    return FALSE;
+
+  if (addr_reg == frame_pointer_rtx || addr_reg == stack_pointer_rtx)
+    return TRUE;
+
+  return FALSE;
+})
+
+;; Return true if operand is a 2 word memory address that needs to use
+;; two instructions to load or store.
+
+(define_predicate "dbl_memory_two_insn_operand"
+  (match_code "mem")
+{
+  if (GET_CODE (op) != MEM)
+    return FALSE;
+
+  if (mode != VOIDmode && GET_MODE_SIZE (mode) != 2*UNITS_PER_WORD)
+    return FALSE;
+
+  if (! TARGET_DWORD)
+    return TRUE;
+
+  return ! dbl_memory_one_insn_operand (op, mode);
+})
+
+;; Return true if operand is a memory reference suitable for a call.
+
+(define_predicate "call_operand"
+  (match_code "reg,subreg,const_int,const,symbol_ref")
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode && GET_CODE (op) != CONST_INT)
+    return FALSE;
+
+  if (GET_CODE (op) == SYMBOL_REF)
+    return !TARGET_LONG_CALLS || SYMBOL_REF_LOCAL_P (op);
+
+  /* Note this doesn't allow reg+reg or reg+imm12 addressing (which should
+     never occur anyway), but prevents reload from not handling the case
+     properly of a call through a pointer on a function that calls
+     vfork/setjmp, etc. due to the need to flush all of the registers to stack.  */
+  return gpr_or_int12_operand (op, mode);
+})
+
+;; Return true if operand is a memory reference suitable for a
+;; sibcall.
+
+(define_predicate "sibcall_operand"
+  (match_code "reg,subreg,const_int,const")
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode && GET_CODE (op) != CONST_INT)
+    return FALSE;
+
+  /* Note this doesn't allow reg+reg or reg+imm12 addressing (which should
+     never occur anyway), but prevents reload from not handling the case
+     properly of a call through a pointer on a function that calls
+     vfork/setjmp, etc. due to the need to flush all of the registers to stack.  */
+  return gpr_or_int12_operand (op, mode);
+})
+
+;; Return 1 if operand is an integer constant with the bottom 16 bits
+;; clear.
+
+(define_predicate "upper_int16_operand"
+  (match_code "const_int")
+{
+  if (GET_CODE (op) != CONST_INT)
+    return FALSE;
+
+  return ((INTVAL (op) & 0xffff) == 0);
+})
+
+;; Return 1 if operand is a 16 bit unsigned immediate.
+
+(define_predicate "uint16_operand"
+  (match_code "const_int")
+{
+  if (GET_CODE (op) != CONST_INT)
+    return FALSE;
+
+  return IN_RANGE_P (INTVAL (op), 0, 0xffff);
+})
+
+;; Returns 1 if OP is either a SYMBOL_REF or a constant.
+
+(define_predicate "symbolic_operand"
+  (match_code "symbol_ref,const_int")
+{
+  enum rtx_code c = GET_CODE (op);
+
+  if (c == CONST)
+    {
+      /* Allow (const:SI (plus:SI (symbol_ref) (const_int))).  */
+      return GET_MODE (op) == SImode
+       && GET_CODE (XEXP (op, 0)) == PLUS
+       && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
+       && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT;
+    }
+
+  return c == SYMBOL_REF || c == CONST_INT;
+})
+
+;; Return true if operator is a kind of relational operator.
+
+(define_predicate "relational_operator"
+  (match_code "eq,ne,le,lt,ge,gt,leu,ltu,geu,gtu")
+{
+  return (integer_relational_operator (op, mode)
+         || float_relational_operator (op, mode));
+})
+
+;; Return true if OP is a relational operator suitable for CCmode,
+;; CC_UNSmode or CC_NZmode.
+
+(define_predicate "integer_relational_operator"
+  (match_code "eq,ne,le,lt,ge,gt,leu,ltu,geu,gtu")
+{
+  if (mode != VOIDmode && mode != GET_MODE (op))
+    return FALSE;
+
+  /* The allowable relations depend on the mode of the ICC register.  */
+  switch (GET_CODE (op))
+    {
+    default:
+      return FALSE;
+
+    case EQ:
+    case NE:
+    case LT:
+    case GE:
+      return (GET_MODE (XEXP (op, 0)) == CC_NZmode
+             || GET_MODE (XEXP (op, 0)) == CCmode);
+
+    case LE:
+    case GT:
+      return GET_MODE (XEXP (op, 0)) == CCmode;
+
+    case GTU:
+    case GEU:
+    case LTU:
+    case LEU:
+      return (GET_MODE (XEXP (op, 0)) == CC_NZmode
+             || GET_MODE (XEXP (op, 0)) == CC_UNSmode);
+    }
+})
+
+;; Return true if operator is a floating point relational operator.
+
+(define_predicate "float_relational_operator"
+  (match_code "eq,ne,le,lt,ge,gt")
+{
+  if (mode != VOIDmode && mode != GET_MODE (op))
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      return FALSE;
+
+    case EQ: case NE:
+    case LE: case LT:
+    case GE: case GT:
+#if 0
+    case UEQ: case UNE:
+    case ULE: case ULT:
+    case UGE: case UGT:
+    case ORDERED:
+    case UNORDERED:
+#endif
+      return GET_MODE (XEXP (op, 0)) == CC_FPmode;
+    }
+})
+
+;; Return true if operator is EQ/NE of a conditional execution
+;; register.
+
+(define_predicate "ccr_eqne_operator"
+  (match_code "eq,ne")
+{
+  enum machine_mode op_mode = GET_MODE (op);
+  rtx op0;
+  rtx op1;
+  int regno;
+
+  if (mode != VOIDmode && op_mode != mode)
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      return FALSE;
+
+    case EQ:
+    case NE:
+      break;
+    }
+
+  op1 = XEXP (op, 1);
+  if (op1 != const0_rtx)
+    return FALSE;
+
+  op0 = XEXP (op, 0);
+  if (GET_CODE (op0) != REG)
+    return FALSE;
+
+  regno = REGNO (op0);
+  if (op_mode == CC_CCRmode && CR_OR_PSEUDO_P (regno))
+    return TRUE;
+
+  return FALSE;
+})
+
+;; Return true if operator is a minimum or maximum operator (both
+;; signed and unsigned).
+
+(define_predicate "minmax_operator"
+  (match_code "smin,smax,umin,umax")
+{
+  if (mode != VOIDmode && mode != GET_MODE (op))
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      return FALSE;
+
+    case SMIN:
+    case SMAX:
+    case UMIN:
+    case UMAX:
+      break;
+    }
+
+  if (! integer_register_operand (XEXP (op, 0), mode))
+    return FALSE;
+
+  if (! gpr_or_int10_operand (XEXP (op, 1), mode))
+    return FALSE;
+
+  return TRUE;
+})
+
+;; Return true if operator is an integer binary operator that can
+;; executed conditionally and takes 1 cycle.
+
+(define_predicate "condexec_si_binary_operator"
+  (match_code "plus,minus,and,ior,xor,ashift,ashiftrt,lshiftrt")
+{
+  enum machine_mode op_mode = GET_MODE (op);
+
+  if (mode != VOIDmode && op_mode != mode)
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      return FALSE;
+
+    case PLUS:
+    case MINUS:
+    case AND:
+    case IOR:
+    case XOR:
+    case ASHIFT:
+    case ASHIFTRT:
+    case LSHIFTRT:
+      return TRUE;
+    }
+})
+
+;; Return true if operator is an integer binary operator that can be
+;; executed conditionally by a media instruction.
+
+(define_predicate "condexec_si_media_operator"
+  (match_code "and,ior,xor")
+{
+  enum machine_mode op_mode = GET_MODE (op);
+
+  if (mode != VOIDmode && op_mode != mode)
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      return FALSE;
+
+    case AND:
+    case IOR:
+    case XOR:
+      return TRUE;
+    }
+})
+
+;; Return true if operator is an integer division operator that can
+;; executed conditionally.
+
+(define_predicate "condexec_si_divide_operator"
+  (match_code "div,udiv")
+{
+  enum machine_mode op_mode = GET_MODE (op);
+
+  if (mode != VOIDmode && op_mode != mode)
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      return FALSE;
+
+    case DIV:
+    case UDIV:
+      return TRUE;
+    }
+})
+
+;; Return true if operator is an integer unary operator that can
+;; executed conditionally.
+
+(define_predicate "condexec_si_unary_operator"
+  (match_code "not,neg")
+{
+  enum machine_mode op_mode = GET_MODE (op);
+
+  if (mode != VOIDmode && op_mode != mode)
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      return FALSE;
+
+    case NEG:
+    case NOT:
+      return TRUE;
+    }
+})
+
+;; Return true if operator is an addition or subtraction
+;; expression. Such expressions can be evaluated conditionally by
+;; floating-point instructions.
+
+(define_predicate "condexec_sf_add_operator"
+  (match_code "plus,minus")
+{
+  enum machine_mode op_mode = GET_MODE (op);
+
+  if (mode != VOIDmode && op_mode != mode)
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      return FALSE;
+
+    case PLUS:
+    case MINUS:
+      return TRUE;
+    }
+})
+
+;; Return true if operator is a conversion-type expression that can be
+;; evaluated conditionally by floating-point instructions.
+
+(define_predicate "condexec_sf_conv_operator"
+  (match_code "abs,neg")
+{
+  enum machine_mode op_mode = GET_MODE (op);
+
+  if (mode != VOIDmode && op_mode != mode)
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      return FALSE;
+
+    case NEG:
+    case ABS:
+      return TRUE;
+    }
+})
+
+;; Return true if OP is an integer binary operator that can be
+;; combined with a (set ... (compare:CC_NZ ...)) pattern.
+
+(define_predicate "intop_compare_operator"
+  (match_code "plus,minus,and,ior,xor,ashift,ashiftrt,lshiftrt")
+{
+  if (mode != VOIDmode && GET_MODE (op) != mode)
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      return FALSE;
+
+    case PLUS:
+    case MINUS:
+    case AND:
+    case IOR:
+    case XOR:
+    case ASHIFTRT:
+    case LSHIFTRT:
+      return GET_MODE (op) == SImode;
+    }
+})
+
+;; Return 1 if operand is a register or 6 bit signed immediate.
+
+(define_predicate "fpr_or_int6_operand"
+  (match_code "reg,subreg,const_int")
+{
+  if (GET_CODE (op) == CONST_INT)
+    return IN_RANGE_P (INTVAL (op), -32, 31);
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return FPR_OR_PSEUDO_P (REGNO (op));
+})
+
+;; Return 1 if operand is a 6 bit signed immediate.
+
+(define_predicate "int6_operand"
+  (match_code "const_int")
+{
+  if (GET_CODE (op) != CONST_INT)
+    return FALSE;
+
+  return IN_RANGE_P (INTVAL (op), -32, 31);
+})
+
+;; Return 1 if operand is a 5 bit signed immediate.
+
+(define_predicate "int5_operand"
+  (match_code "const_int")
+{
+  return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), -16, 15);
+})
+
+;; Return 1 if operand is a 5 bit unsigned immediate.
+
+(define_predicate "uint5_operand"
+  (match_code "const_int")
+{
+  return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), 0, 31);
+})
+
+;; Return 1 if operand is a 4 bit unsigned immediate.
+
+(define_predicate "uint4_operand"
+  (match_code "const_int")
+{
+  return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), 0, 15);
+})
+
+;; Return 1 if operand is a 1 bit unsigned immediate (0 or 1).
+
+(define_predicate "uint1_operand"
+  (match_code "const_int")
+{
+  return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), 0, 1);
+})
+
+;; Return 1 if operand is a valid ACC register number.
+
+(define_predicate "acc_operand"
+  (match_code "reg,subreg")
+{
+  return ((mode == VOIDmode || mode == GET_MODE (op))
+         && REG_P (op) && ACC_P (REGNO (op))
+         && ((REGNO (op) - ACC_FIRST) & ~ACC_MASK) == 0);
+})
+
+;; Return 1 if operand is a valid even ACC register number.
+
+(define_predicate "even_acc_operand"
+  (match_code "reg,subreg")
+{
+  return acc_operand (op, mode) && ((REGNO (op) - ACC_FIRST) & 1) == 0;
+})
+
+;; Return 1 if operand is zero or four.
+
+(define_predicate "quad_acc_operand"
+  (match_code "reg,subreg")
+{
+  return acc_operand (op, mode) && ((REGNO (op) - ACC_FIRST) & 3) == 0;
+})
+
+;; Return 1 if operand is a valid ACCG register number.
+
+(define_predicate "accg_operand"
+  (match_code "reg,subreg")
+{
+  return ((mode == VOIDmode || mode == GET_MODE (op))
+         && REG_P (op) && ACCG_P (REGNO (op))
+         && ((REGNO (op) - ACCG_FIRST) & ~ACC_MASK) == 0);
+})