Patchwork convert h8300 to constraints.md

login
register
mail settings
Submitter Nathan Froyd
Date Feb. 15, 2011, 12:19 a.m.
Message ID <20110215001942.GM6247@codesourcery.com>
Download mbox | patch
Permalink /patch/83168/
State New
Headers show

Comments

Nathan Froyd - Feb. 15, 2011, 12:19 a.m.
As $SUBJECT suggests.

Tested with cross to h8300-elf (which doesn't totally build right now,
but the patch doesn't make things any worse).  OK to commit?

-Nathan

	* config/h8300/constraints.md: New file.
	* config/h8300/h8300.md: Include it.  Use satisfies_constraint_J,
	satisfies_constraint_L, and satisfies_constraint_N for peephole2s.
	(*tst_extzv_1_n, *tstsi_variable_bit_qi): Use satisfies_constraint_U.
	* config/h8300/predicates.md (bit_operand): Likewise.
	(incdec_operand): Use satisfies_constraint_M and
	satisfies_constraint_O.  Don't use C code block.
	* config/h8300/h8300-protos.h (h8300_reg_class_from_letter): Delete.
	* config/h8300/h8300.c (h8300_reg_class_from_letter): Delete.
	(compute_mov_length): Use satisfies_constraint_G.
	(fix_bit_operand): Use satisfies_constraint_U.
	* config/h8300/h8300.h (REG_CLASS_FROM_LETTER): Delete.
	(CONST_OK_FOR_I, CONST_OK_FOR_J, CONST_OK_FOR_L): Delete.
	(CONST_OK_FOR_M, CONST_OK_FOR_N, CONST_OK_FOR_O): Delete.
	(CONST_OK_FOR_Ppositive, CONST_OK_FOR_Pnegative): Delete.
	(CONST_OK_FOR_P, CONSTRAINT_LEN_FOR_P): Delete.
	(CONST_OK_FOR_CONSTRAINT_P, CONST_OK_FOR_LETTER_P): Delete.
	(CONST_DOUBLE_OK_FOR_LETTER_P): Delete.
	(OK_FOR_Q, OK_FOR_R, OK_FOR_S, OK_FOR_T, OK_FOR_U, OK_FOR_WU): Delete.
	(OK_FOR_W, CONSTRAINT_LEN_FOR_W, OK_FOR_Y2, OK_FOR_Y0): Delete.
	(OK_FOR_Y, CONSTRAINT_LEN_FOR_Y, OK_FOR_Z): Delete.
	(EXTRA_CONSTRAINT_STR, CONSTRAINT_LEN): Delete.
	(EXTRA_MEMORY_CONSTRAINT): Delete.
Anatoly Sokolov - April 1, 2011, 5:45 p.m.
Hi.

----- Original Message ----- 
From: "Nathan Froyd"
Sent: Tuesday, February 15, 2011 4:19 AM
Subject: [PATCH] convert h8300 to constraints.md

> 
> Tested with cross to h8300-elf (which doesn't totally build right now,
> but the patch doesn't make things any worse).  OK to commit?
> 

http://gcc.gnu.org/ml/gcc-patches/2011-02/msg00935.html

Anatoly.
Richard Henderson - April 1, 2011, 7:07 p.m.
On 02/14/2011 04:19 PM, Nathan Froyd wrote:
> +(define_constraint "WU"
> +  "@internal"
> +  (and (match_code "mem")
> +       (match_test "satisfies_constraint_U (op)")))

Based on

-#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
-  ((C) == 'W')

This one should be define_memory_constraint.

Otherwise ok.



r~

Patch

diff --git a/gcc/config/h8300/constraints.md b/gcc/config/h8300/constraints.md
new file mode 100644
index 0000000..2473f7e
--- /dev/null
+++ b/gcc/config/h8300/constraints.md
@@ -0,0 +1,214 @@ 
+;; Constraint definitions for Renesas H8/300.
+;; Copyright (C) 2011 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 3, 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 COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+;; Register constraints.
+(define_register_constraint "a" "MAC_REGS"
+  "@internal")
+
+(define_register_constraint "c" "COUNTER_REGS"
+  "@internal")
+
+;; Some patterns need to use er6 as a scratch register.  This is
+;; difficult to arrange since er6 is the frame pointer and usually can't
+;; be spilled.
+
+;; Such patterns should define two alternatives, one which allows only
+;; er6 and one which allows any general register.  The former
+;; alternative should have a 'd' constraint while the latter should be
+;; disparaged and use 'D'.
+
+;; Normally, 'd' maps to DESTINATION_REGS and 'D' maps to GENERAL_REGS.
+;; However, there are cases where they should be NO_REGS:
+
+;;   - 'd' should be NO_REGS when reloading a function that uses the
+;;     frame pointer.  In this case, DESTINATION_REGS won't contain any
+;;     spillable registers, so the first alternative can't be used.
+
+;;   - -fno-omit-frame-pointer means that the frame pointer will
+;;     always be in use.  It's therefore better to map 'd' to NO_REGS
+;;     before reload so that register allocator will pick the second
+;;     alternative.
+
+;;   - we would like 'D' to be be NO_REGS when the frame pointer isn't
+;;     live, but we the frame pointer may turn out to be needed after
+;;     we start reload, and then we may have already decided we don't
+;;     have a choice, so we can't do that.  Forcing the register
+;;     allocator to use er6 if possible might produce better code for
+;;     small functions: it's more efficient to save and restore er6 in
+;;     the prologue & epilogue than to do it in a define_split.
+;;     Hopefully disparaging 'D' will have a similar effect, without
+;;     forcing a reload failure if the frame pointer is found to be
+;;     needed too late.
+
+(define_register_constraint "d"
+  "(!flag_omit_frame_pointer && !reload_completed
+    ? NO_REGS
+    : (frame_pointer_needed && reload_in_progress
+       ? NO_REGS
+       : DESTINATION_REGS))"
+  "@internal")
+
+(define_register_constraint "D" "GENERAL_REGS"
+  "@internal")
+
+(define_register_constraint "f" "SOURCE_REGS"
+  "@internal")
+
+;; Integer constraints.
+(define_constraint "I"
+  "Integer zero."
+  (and (match_code "const_int")
+       (match_test "ival == 0")))
+
+(define_constraint "J"
+  "An integer with its low byte clear."
+  (and (match_code "const_int")
+       (match_test "(ival & 0xff) == 0")))
+
+(define_constraint "L"
+  "1, 2 or 4 on the H8300H or S; 1 or 2 otherwise."
+  (and (match_code "const_int")
+       (if_then_else (match_test "TARGET_H8300H || TARGET_H8300S")
+		     (match_test "ival == 1 || ival == 2 || ival == 4")
+		     (match_test "ival == 1 || ival == 2"))))
+
+(define_constraint "M"
+  "Integer 1 or 2."
+  (and (match_code "const_int")
+       (match_test "ival == 1 || ival == 2")))
+
+(define_constraint "N"
+  "-1, -2, or -4 on the H8300H or S; -1 or -2 otherwise."
+  (and (match_code "const_int")
+       (if_then_else (match_test "TARGET_H8300H || TARGET_H8300S")
+		     (match_test "ival == -1 || ival == -2 || ival == -4")
+		     (match_test "ival == -1 || ival == -2"))))
+
+(define_constraint "O"
+  "Integer -1 or -2."
+  (and (match_code "const_int")
+       (match_test "ival == -1 || ival == -2")))
+
+(define_constraint "P1>X"
+  "A positive, non-zero integer that fits in 1 bits."
+  (and (match_code "const_int")
+       (match_test "TARGET_H8300SX")
+       (match_test "IN_RANGE (ival, 1, (1 << 1) - 1)")))
+
+(define_constraint "P3>X"
+  "A positive, non-zero integer that fits in 3 bits."
+  (and (match_code "const_int")
+       (match_test "TARGET_H8300SX")
+       (match_test "IN_RANGE (ival, 1, (1 << 3) - 1)")))
+
+(define_constraint "P4>X"
+  "A positive, non-zero integer that fits in 4 bits."
+  (and (match_code "const_int")
+       (match_test "TARGET_H8300SX")
+       (match_test "IN_RANGE (ival, 1, (1 << 4) - 1)")))
+
+(define_constraint "P5>X"
+  "A positive, non-zero integer that fits in 5 bits."
+  (and (match_code "const_int")
+       (match_test "TARGET_H8300SX")
+       (match_test "IN_RANGE (ival, 1, (1 << 5) - 1)")))
+
+(define_constraint "P8>X"
+  "A positive, non-zero integer that fits in 8 bits."
+  (and (match_code "const_int")
+       (match_test "TARGET_H8300SX")
+       (match_test "IN_RANGE (ival, 1, (1 << 8) - 1)")))
+
+(define_constraint "P3<X"
+  "A negative, non-zero integer that fits in 3 bits."
+  (and (match_code "const_int")
+       (match_test "TARGET_H8300SX")
+       (match_test "IN_RANGE (ival, (-(1 << 3)) + 1, -1)")))
+
+;; Floating-point constraints.
+(define_constraint "G"
+  "Single-float zero."
+  (and (match_code "const_double")
+       (match_test "op == CONST0_RTX (SFmode)")))
+
+;; Extra constraints.
+(define_constraint "Q"
+  "@internal"
+  (and (match_test "TARGET_H8300SX")
+       (match_operand 0 "memory_operand")))
+
+(define_constraint "R"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "!h8300_shift_needs_scratch_p (ival, QImode)")))
+
+(define_constraint "S"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "!h8300_shift_needs_scratch_p (ival, HImode)")))
+
+(define_constraint "T"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "!h8300_shift_needs_scratch_p (ival, SImode)")))
+
+(define_constraint "U"
+  "An operand valid for a bset destination."
+  (ior (and (match_code "reg")
+	    (match_test "REG_OK_FOR_BASE_P (op)"))
+       (and (match_code "mem")
+	    (match_code "reg" "0")
+	    (match_test "REG_OK_FOR_BASE_P (XEXP (op, 0))"))
+       (and (match_code "mem")
+	    (match_code "symbol_ref" "0")
+	    (match_test "TARGET_H8300S"))
+       (and (match_code "mem")
+	    (match_code "const" "0")
+	    (match_code "plus" "00")
+	    (match_code "symbol_ref" "000")
+	    (match_code "const_int" "001")
+	    (ior (match_test "TARGET_H8300S")
+		 (match_test "SYMBOL_REF_FLAG (XEXP (XEXP (XEXP (op, 0), 0), 0))")))
+       (and (match_code "mem")
+	    (match_test "h8300_eightbit_constant_address_p (XEXP (op, 0))"))
+       (and (match_code "mem")
+	    (ior (match_test "TARGET_H8300S")
+		 (match_test "TARGET_H8300SX"))
+	    (match_code "const_int" "0"))))
+
+(define_constraint "WU"
+  "@internal"
+  (and (match_code "mem")
+       (match_test "satisfies_constraint_U (op)")))
+
+(define_constraint "Y0"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "exact_log2 (~ival & 0xff) != -1")))
+
+(define_constraint "Y2"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "exact_log2 (ival & 0xff) != -1")))
+
+(define_constraint "Z"
+  "@internal"
+  (and (match_test "TARGET_H8300SX")
+       (match_code "mem")
+       (match_test "CONSTANT_P (XEXP (op, 0))")))
diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h
index 1211c63..c7e96a3 100644
--- a/gcc/config/h8300/h8300-protos.h
+++ b/gcc/config/h8300/h8300-protos.h
@@ -109,7 +109,6 @@  extern int h8300_hard_regno_mode_ok (int, enum machine_mode);
 struct cpp_reader;
 extern void h8300_pr_interrupt (struct cpp_reader *);
 extern void h8300_pr_saveall (struct cpp_reader *);
-extern enum reg_class  h8300_reg_class_from_letter (int);
 extern rtx             h8300_get_index (rtx, enum machine_mode mode, int *);
 extern unsigned int    h8300_insn_length_from_table (rtx, rtx *);
 extern const char *    output_h8sx_shift (rtx *, int, int);
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 834fc99..5031d67 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -41,6 +41,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "diagnostic-core.h"
 #include "c-family/c-pragma.h"	/* ??? */
 #include "tm_p.h"
+#include "tm-constrs.h"
 #include "ggc.h"
 #include "target.h"
 #include "target-def.h"
@@ -420,71 +421,6 @@  h8300_option_override (void)
     flag_strict_volatile_bitfields = 1;
 }
 
-/* Implement REG_CLASS_FROM_LETTER.
-
-   Some patterns need to use er6 as a scratch register.  This is
-   difficult to arrange since er6 is the frame pointer and usually
-   can't be spilled.
-
-   Such patterns should define two alternatives, one which allows only
-   er6 and one which allows any general register.  The former alternative
-   should have a 'd' constraint while the latter should be disparaged and
-   use 'D'.
-
-   Normally, 'd' maps to DESTINATION_REGS and 'D' maps to GENERAL_REGS.
-   However, there are cases where they should be NO_REGS:
-
-     - 'd' should be NO_REGS when reloading a function that uses the
-       frame pointer.  In this case, DESTINATION_REGS won't contain any
-       spillable registers, so the first alternative can't be used.
-
-     - -fno-omit-frame-pointer means that the frame pointer will
-       always be in use.  It's therefore better to map 'd' to NO_REGS
-       before reload so that register allocator will pick the second
-       alternative.
-
-     - we would like 'D' to be be NO_REGS when the frame pointer isn't
-       live, but we the frame pointer may turn out to be needed after
-       we start reload, and then we may have already decided we don't
-       have a choice, so we can't do that.  Forcing the register
-       allocator to use er6 if possible might produce better code for
-       small functions: it's more efficient to save and restore er6 in
-       the prologue & epilogue than to do it in a define_split.
-       Hopefully disparaging 'D' will have a similar effect, without
-       forcing a reload failure if the frame pointer is found to be
-       needed too late.  */
-
-enum reg_class
-h8300_reg_class_from_letter (int c)
-{
-  switch (c)
-    {
-    case 'a':
-      return MAC_REGS;
-
-    case 'c':
-      return COUNTER_REGS;
-
-    case 'd':
-      if (!flag_omit_frame_pointer && !reload_completed)
-	return NO_REGS;
-      if (frame_pointer_needed && reload_in_progress)
-	return NO_REGS;
-      return DESTINATION_REGS;
-
-    case 'D':
-      /* The meaning of a constraint shouldn't change dynamically, so
-	 we can't make this NO_REGS.  */
-      return GENERAL_REGS;
-
-    case 'f':
-      return SOURCE_REGS;
-
-    default:
-      return NO_REGS;
-    }
-}
-
 /* Return the byte register name for a register rtx X.  B should be 0
    if you want a lower byte register.  B should be 1 if you want an
    upper byte register.  */
@@ -2811,7 +2747,7 @@  compute_mov_length (rtx *operands)
 	      if (REG_P (src))
 		return 4;
 
-	      if (CONST_DOUBLE_OK_FOR_LETTER_P (src, 'G'))
+	      if (satisfies_constraint_G (src))
 		return 4;
 
 	      return 8;
@@ -2931,7 +2867,7 @@  compute_mov_length (rtx *operands)
 	      if (REG_P (src))
 		return 2;
 
-	      if (CONST_DOUBLE_OK_FOR_LETTER_P (src, 'G'))
+	      if (satisfies_constraint_G (src))
 		return 2;
 
 	      return 6;
@@ -5170,7 +5106,7 @@  fix_bit_operand (rtx *operands, enum rtx_code code)
     {
       /* OK to have a memory dest.  */
       if (GET_CODE (operands[0]) == MEM
-	  && !OK_FOR_U (operands[0]))
+	  && !satisfies_constraint_U (operands[0]))
 	{
 	  rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
 				 copy_to_mode_reg (Pmode,
@@ -5180,7 +5116,7 @@  fix_bit_operand (rtx *operands, enum rtx_code code)
 	}
 
       if (GET_CODE (operands[1]) == MEM
-	  && !OK_FOR_U (operands[1]))
+	  && !satisfies_constraint_U (operands[1]))
 	{
 	  rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
 				 copy_to_mode_reg (Pmode,
diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h
index 589b70f..a9e581a 100644
--- a/gcc/config/h8300/h8300.h
+++ b/gcc/config/h8300/h8300.h
@@ -374,76 +374,6 @@  enum reg_class {
 #define INDEX_REG_CLASS (TARGET_H8300SX ? GENERAL_REGS : NO_REGS)
 #define BASE_REG_CLASS  GENERAL_REGS
 
-/* Get reg_class from a letter such as appears in the machine description.
-
-   'a' is the MAC register.  */
-
-#define REG_CLASS_FROM_LETTER(C) (h8300_reg_class_from_letter (C))
-
-/* The letters I, J, K, L, M, N, O, P in a register constraint string
-   can be used to stand for particular ranges of immediate operands.
-   This macro defines what the ranges are.
-   C is the letter, and VALUE is a constant value.
-   Return 1 if VALUE is in the range specified by C.  */
-
-#define CONST_OK_FOR_I(VALUE) ((VALUE) == 0)
-#define CONST_OK_FOR_J(VALUE) (((VALUE) & 0xff) == 0)
-#define CONST_OK_FOR_L(VALUE)				\
-  (TARGET_H8300H || TARGET_H8300S			\
-   ? (VALUE) == 1 || (VALUE) == 2 || (VALUE) == 4	\
-   : (VALUE) == 1 || (VALUE) == 2)
-#define CONST_OK_FOR_M(VALUE)				\
-  ((VALUE) == 1 || (VALUE) == 2)
-#define CONST_OK_FOR_N(VALUE)				\
-  (TARGET_H8300H || TARGET_H8300S			\
-   ? (VALUE) == -1 || (VALUE) == -2 || (VALUE) == -4	\
-   : (VALUE) == -1 || (VALUE) == -2)
-#define CONST_OK_FOR_O(VALUE)				\
-  ((VALUE) == -1 || (VALUE) == -2)
-
-/* Multi-letter constraints for constant are always started with P
-   (just because it was the only letter in the range left.  New
-   constraints for constants should be added here.  */
-#define CONST_OK_FOR_Ppositive(VALUE, NBITS)		\
-  ((VALUE) > 0 && (VALUE) < (1 << (NBITS)))
-#define CONST_OK_FOR_Pnegative(VALUE, NBITS)		\
-  ((VALUE) < 0 && (VALUE) > -(1 << (NBITS)))
-#define CONST_OK_FOR_P(VALUE, STR) \
-  ((STR)[1] >= '1' && (STR)[1] <= '9' && (STR)[2] == '<' 	\
-   ? (((STR)[3] == '0' || ((STR)[3] == 'X' && TARGET_H8300SX))	\
-      && CONST_OK_FOR_Pnegative ((VALUE), (STR)[1] - '0'))	\
-   : ((STR)[1] >= '1' && (STR)[1] <= '9' && (STR)[2] == '>')	\
-   ? (((STR)[3] == '0' || ((STR)[3] == 'X' && TARGET_H8300SX))	\
-      && CONST_OK_FOR_Ppositive ((VALUE), (STR)[1] - '0'))	\
-   : 0)
-#define CONSTRAINT_LEN_FOR_P(STR) \
-  ((((STR)[1] >= '1' && (STR)[1] <= '9')			\
-    && ((STR)[2] == '<' || (STR)[2] == '>')			\
-    && ((STR)[3] == 'X' || (STR)[3] == '0')) ? 4		\
-   : 0)
-
-#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR)	\
-  ((C) == 'P' ? CONST_OK_FOR_P ((VALUE), (STR))		\
-   : CONST_OK_FOR_LETTER_P ((VALUE), (C)))
-  
-#define CONST_OK_FOR_LETTER_P(VALUE, C)		\
-  ((C) == 'I' ? CONST_OK_FOR_I (VALUE) :	\
-   (C) == 'J' ? CONST_OK_FOR_J (VALUE) :	\
-   (C) == 'L' ? CONST_OK_FOR_L (VALUE) :	\
-   (C) == 'M' ? CONST_OK_FOR_M (VALUE) :	\
-   (C) == 'N' ? CONST_OK_FOR_N (VALUE) :	\
-   (C) == 'O' ? CONST_OK_FOR_O (VALUE) :	\
-   0)
-
-/* Similar, but for floating constants, and defining letters G and H.
-   Here VALUE is the CONST_DOUBLE rtx itself.
-
-  `G' is a floating-point zero.  */
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)	\
-  ((C) == 'G' ? (VALUE) == CONST0_RTX (SFmode)	\
-   : 0)
-
 /* Return the maximum number of consecutive registers
    needed to represent mode MODE in a register of class CLASS.  */
 
@@ -685,122 +615,6 @@  struct cum_arg
 
 #endif
 
-/* Extra constraints.  */
-
-#define OK_FOR_Q(OP)					\
-  (TARGET_H8300SX && memory_operand ((OP), VOIDmode))
-
-#define OK_FOR_R(OP)					\
-  (GET_CODE (OP) == CONST_INT				\
-   ? !h8300_shift_needs_scratch_p (INTVAL (OP), QImode)	\
-   : 0)
-
-#define OK_FOR_S(OP)					\
-  (GET_CODE (OP) == CONST_INT				\
-   ? !h8300_shift_needs_scratch_p (INTVAL (OP), HImode)	\
-   : 0)
-
-#define OK_FOR_T(OP)					\
-  (GET_CODE (OP) == CONST_INT				\
-   ? !h8300_shift_needs_scratch_p (INTVAL (OP), SImode)	\
-   : 0)
-
-/* 'U' if valid for a bset destination;
-   i.e. a register, register indirect, or the eightbit memory region
-   (a SYMBOL_REF with an SYMBOL_REF_FLAG set).
-
-   On the H8S 'U' can also be a 16bit or 32bit absolute.  */
-#define OK_FOR_U(OP)							\
-  ((GET_CODE (OP) == REG && REG_OK_FOR_BASE_P (OP))			\
-   || (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG		\
-       && REG_OK_FOR_BASE_P (XEXP (OP, 0)))				\
-   || (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF	\
-       && TARGET_H8300S)						\
-   || (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == CONST		\
-       && GET_CODE (XEXP (XEXP (OP, 0), 0)) == PLUS			\
-       && GET_CODE (XEXP (XEXP (XEXP (OP, 0), 0), 0)) == SYMBOL_REF	\
-       && GET_CODE (XEXP (XEXP (XEXP (OP, 0), 0), 1)) == CONST_INT	\
-       && (TARGET_H8300S						\
-	   || SYMBOL_REF_FLAG (XEXP (XEXP (XEXP (OP, 0), 0), 0))))	\
-   || (GET_CODE (OP) == MEM						\
-       && h8300_eightbit_constant_address_p (XEXP (OP, 0)))		\
-   || (GET_CODE (OP) == MEM && (TARGET_H8300S || TARGET_H8300SX)	\
-       && GET_CODE (XEXP (OP, 0)) == CONST_INT))
-
-/* Multi-letter constraints starting with W are to be used for
-   operands that require a memory operand, i.e,. that are never used
-   along with register constraints (see EXTRA_MEMORY_CONSTRAINTS).  */
-
-#define OK_FOR_WU(OP)					\
-  (GET_CODE (OP) == MEM && OK_FOR_U (OP))
-
-#define OK_FOR_W(OP, STR)				\
-  ((STR)[1] == 'U' ? OK_FOR_WU (OP)			\
-   : 0)
-
-#define CONSTRAINT_LEN_FOR_W(STR)			\
-  ((STR)[1] == 'U' ? 2					\
-   : 0)
-
-/* Multi-letter constraints starting with Y are to be used for operands
-   that are constant immediates and have single 1 or 0 in their binary
-   representation.  */
-
-#define OK_FOR_Y2(OP)                                   \
-  ((GET_CODE (OP) == CONST_INT) && (exact_log2 (INTVAL (OP) & 0xff) != -1))
-
-#define OK_FOR_Y0(OP)                                   \
-  ((GET_CODE (OP) == CONST_INT) && (exact_log2 (~INTVAL (OP) & 0xff) != -1))
-
-#define OK_FOR_Y(OP, STR)                               \
-  ((STR)[1] == '2' ? OK_FOR_Y2 (OP)                     \
-   : (STR)[1] == '0' ? OK_FOR_Y0 (OP)	\
-   : 0)
-
-#define CONSTRAINT_LEN_FOR_Y(STR)			\
-  ((STR)[1] == '2' ? 2                                  \
-   : (STR)[1] == '0' ? 2		\
-   : 0)
-
-#define OK_FOR_Z(OP)					\
-  (TARGET_H8300SX					\
-   && GET_CODE (OP) == MEM				\
-   && CONSTANT_P (XEXP ((OP), 0)))
-
-#define EXTRA_CONSTRAINT_STR(OP, C, STR)	\
-  ((C) == 'Q' ? OK_FOR_Q (OP) :			\
-   (C) == 'R' ? OK_FOR_R (OP) :			\
-   (C) == 'S' ? OK_FOR_S (OP) :			\
-   (C) == 'T' ? OK_FOR_T (OP) :			\
-   (C) == 'U' ? OK_FOR_U (OP) :			\
-   (C) == 'W' ? OK_FOR_W ((OP), (STR)) :	\
-   (C) == 'Y' ? OK_FOR_Y ((OP), (STR)) :	\
-   (C) == 'Z' ? OK_FOR_Z (OP) :			\
-   0)
-
-#define CONSTRAINT_LEN(C, STR) \
-  ((C) == 'P' ? CONSTRAINT_LEN_FOR_P (STR)	\
-   : (C) == 'W' ? CONSTRAINT_LEN_FOR_W (STR)	\
-   : (C) == 'Y' ? CONSTRAINT_LEN_FOR_Y (STR)	\
-   : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
-
-/* Experiments suggest that it's better not add 'Q' or 'U' here.  No
-   patterns need it for correctness (no patterns use 'Q' and 'U'
-   without also providing a register alternative).  And defining it
-   will mean that a spilled pseudo could be replaced by its frame
-   location in several consecutive insns.
-
-   Instead, it seems to be better to force pseudos to be reloaded
-   into registers and then use peepholes to recombine insns when
-   beneficial.
-
-   Unfortunately, for WU (unlike plain U, that matches regs as well),
-   we must require a memory address.  In fact, all multi-letter
-   constraints started with W are supposed to have this property, so
-   we just test for W here.  */
-#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
-  ((C) == 'W')
-
 
 /* Go to LABEL if ADDR (a legitimate address expression)
    has an effect that depends on the machine mode it is used for.
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index 21ab391..4797460 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -177,6 +177,7 @@ 
 	      (const_int 14)))])
 
 (include "predicates.md")
+(include "constraints.md")
 
 ;; ----------------------------------------------------------------------
 ;; MOVE INSTRUCTIONS
@@ -995,7 +996,7 @@ 
    btst\\t%Z1,%Y0
    #"
   "&& reload_completed
-   && !OK_FOR_U (operands[0])"
+   && !satisfies_constraint_U (operands[0])"
   [(set (match_dup 2)
 	(match_dup 0))
    (parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
@@ -1065,7 +1066,7 @@ 
    btst\\t%w1,%X0
    #"
   "&& reload_completed
-   && !OK_FOR_U (operands[0])"
+   && !satisfies_constraint_U (operands[0])"
   [(set (match_dup 2)
 	(match_dup 0))
    (parallel [(set (cc0) (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
@@ -4867,9 +4868,9 @@ 
 		 (match_operand:HI 2 "register_operand" "")))]
   "REG_P (operands[0]) && REG_P (operands[2])
    && REGNO (operands[0]) != REGNO (operands[2])
-   && (CONST_OK_FOR_J (INTVAL (operands[1]))
-       || CONST_OK_FOR_L (INTVAL (operands[1]))
-       || CONST_OK_FOR_N (INTVAL (operands[1])))"
+   && (satisfies_constraint_J (operands[1])
+       || satisfies_constraint_L (operands[1])
+       || satisfies_constraint_N (operands[1]))"
   [(set (match_dup 0)
 	(match_dup 2))
    (set (match_dup 0)
@@ -4897,8 +4898,8 @@ 
   "(TARGET_H8300H || TARGET_H8300S)
    && REG_P (operands[0]) && REG_P (operands[2])
    && REGNO (operands[0]) != REGNO (operands[2])
-   && (CONST_OK_FOR_L (INTVAL (operands[1]))
-       || CONST_OK_FOR_N (INTVAL (operands[1])))"
+   && (satisfies_constraint_L (operands[1])
+       || satisfies_constraint_N (operands[1]))"
   [(set (match_dup 0)
 	(match_dup 2))
    (set (match_dup 0)
@@ -4926,8 +4927,8 @@ 
   "(TARGET_H8300H || TARGET_H8300S)
    && REG_P (operands[0]) && REG_P (operands[1])
    && REGNO (operands[0]) != REGNO (operands[1])
-   && !CONST_OK_FOR_L (INTVAL (operands[2]))
-   && !CONST_OK_FOR_N (INTVAL (operands[2]))
+   && !satisfies_constraint_L (operands[2])
+   && !satisfies_constraint_N (operands[2])
    && ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2])
        || (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2])
        || INTVAL (operands[2]) == 0xffff
diff --git a/gcc/config/h8300/predicates.md b/gcc/config/h8300/predicates.md
index 895698b..ac25ffa 100644
--- a/gcc/config/h8300/predicates.md
+++ b/gcc/config/h8300/predicates.md
@@ -326,7 +326,7 @@ 
 {
   /* We can accept any nonimmediate operand, except that MEM operands must
      be limited to those that use addresses valid for the 'U' constraint.  */
-  if (!nonimmediate_operand (op, mode) && !OK_FOR_U (op))
+  if (!nonimmediate_operand (op, mode) && !satisfies_constraint_U (op))
     return 0;
 
   /* H8SX accepts pretty much anything here.  */
@@ -344,7 +344,7 @@ 
   if (GET_CODE (op) == SUBREG)
     return 1;
   return (GET_CODE (op) == MEM
-	  && OK_FOR_U (op));
+	  && satisfies_constraint_U (op));
 })
 
 ;; Return nonzero if OP is a MEM suitable for bit manipulation insns.
@@ -353,7 +353,7 @@ 
   (match_code "mem")
 {
   return (GET_CODE (op) == MEM
-	  && OK_FOR_U (op));
+	  && satisfies_constraint_U (op));
 })
 
 ;; Return nonzero if OP is indirect register or constant memory
@@ -416,12 +416,9 @@ 
 ;; Return nonzero if X is a constant suitable for inc/dec.
 
 (define_predicate "incdec_operand"
-  (match_code "const_int")
-{
-  return (GET_CODE (op) == CONST_INT
-	  && (CONST_OK_FOR_M (INTVAL (op))
-	      || CONST_OK_FOR_O (INTVAL (op))));
-})
+  (and (match_code "const_int")
+       (ior (match_test "satisfies_constraint_M (op)")
+	    (match_test "satisfies_constraint_O (op)"))))
 
 ;; Recognize valid operators for bit instructions.