Patchwork convert m32c to constraints.md

login
register
mail settings
Submitter Nathan Froyd
Date Aug. 18, 2012, 2:06 a.m.
Message ID <1345255560-30678-1-git-send-email-froydnj@mozilla.com>
Download mbox | patch
Permalink /patch/178429/
State New
Headers show

Comments

Nathan Froyd - Aug. 18, 2012, 2:06 a.m.
As $SUBJECT suggests.

I haven't tested this.  It's possible my dejagnu installation is too old
and/or I have forgotten many subtleties for testing embedded targets,
but I could not make m32c-sim work and I didn't want to spend an
enormous amount of time making it work.

Nonetheless, I have compared assembly for libgcc and newlib on unpatched
and patched compilers and they are identical, so that is encouraging.

I suppose transferring the documentation from doc/md.texi to
constraints.md would be good.  I'd beg leaving that for a followup,
please.

m32c is the last machine (pending committal of the mmix constraints.md
patch) to be converted to constraints.md.  I suppose there is some
cleanup to come surrounding the constraints support; if anybody has bold
plans for what needs work, I'd be happy to hear them out.

OK to commit?

-Nathan

	* config/m32c/constraints.md: New file.
	* config/m32c/t-m32c (MD_FILES): Add constraints.
	* config/m32c/m32c-protos.h (m32c_const_ok_for_constraint_p): Delete.
	(m32c_extra_address_constraint, m32c_extra_memory_constraint): Delete.
	(m32c_reg_class_from_constraint): Delete.
	(m32c_extra_constraint_p, m32c_extra_constraint_p2): Delete.
	(m32c_matches_constraint_p): Declare.
	* config/m32c/m32c.h (CONSTRAINT_LEN): Delete.
	(REG_CLASS_FROM_CONSTRAINT): Delete.
	(CONST_OK_FOR_CONSTRAINT_P): Delete.
	(CONST_DOUBLE_OK_FOR_CONSTRAINT_P): Delete.
	(EXTRA_CONSTRAINT_STR): Delete.
	(EXTRA_MEMORY_CONSTRAINT, EXTRA_ADDRESS_CONSTRAINT): Delete.
	* config/m32c/m32c.c: Include tm-constrs.h
	(m32c_reg_class_from_constraint): Delete.
	(m32c_const_ok_for_constraint_p): Delete.
	(m32c_extra_constraint_p2): Rename to...
	(m32c_matches_constraint_p): ...this.  Make it return bool.  Tweak
	formatting.
	(m32c_extra_constraint_p): Delete.
	(m32c_extra_address_constraint, m32c_extra_memory_constraint): Delete.
	(m32c_split_move): Use satisfies_constraint_Ss.
	* config/m32c/predicates.md (memsym_operand): Use 
	satisfies_constraint_Si.
	(memimmed_operand): Use satisfies_constraint_Sp.
	(m32c_psi_scale, m32c_1bit8_operand): Use satisfies_constraint_Ilb.
	(m32c_1bit16_operand): Use satisfies_constraint_Ilw.
	(m32c_1mask8_operand): Use satisfies_constraint_ImB.
	(m32c_1mask16_operand): Use satisfies_constraint_Imw.

---
 gcc/config/m32c/constraints.md |  225 ++++++++++++++++++++++++++++
 gcc/config/m32c/m32c-protos.h  |    7 +-
 gcc/config/m32c/m32c.c         |  322 +++++++---------------------------------
 gcc/config/m32c/m32c.h         |   19 ---
 gcc/config/m32c/predicates.md  |   14 +-
 gcc/config/m32c/t-m32c         |    2 +-
 6 files changed, 286 insertions(+), 303 deletions(-)
 create mode 100644 gcc/config/m32c/constraints.md
DJ Delorie - Aug. 21, 2012, 2:25 a.m.
I ran the testsuite for you; no regressions.  Looks OK to me, please
apply.  Thanks!

Patch

diff --git a/gcc/config/m32c/constraints.md b/gcc/config/m32c/constraints.md
new file mode 100644
index 0000000..da7dda4
--- /dev/null
+++ b/gcc/config/m32c/constraints.md
@@ -0,0 +1,225 @@ 
+;; m32c constraints
+;; Copyright (C) 2012 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/>.
+
+(define_register_constraint "Rsp" "SP_REGS"
+  "@internal")
+
+(define_register_constraint "Rfb" "FB_REGS"
+  "@internal")
+
+(define_register_constraint "Rsb" "SB_REGS"
+  "@internal")
+
+(define_register_constraint "Rcr" "TARGET_A16 ? CR_REGS : NO_REGS"
+  "@internal")
+
+(define_register_constraint "Rcl" "TARGET_A24 ? CR_REGS : NO_REGS"
+  "@internal")
+
+(define_register_constraint "R0w" "R0_REGS"
+  "@internal")
+
+(define_register_constraint "R1w" "R1_REGS"
+  "@internal")
+
+(define_register_constraint "R2w" "R2_REGS"
+  "@internal")
+
+(define_register_constraint "R3w" "R3_REGS"
+  "@internal")
+
+(define_register_constraint "R02" "R02_REGS"
+  "@internal")
+
+(define_register_constraint "R13" "R13_REGS"
+  "@internal")
+
+(define_register_constraint "R03" "R03_REGS"
+  "@internal")
+
+(define_register_constraint "Rdi" "DI_REGS"
+  "@internal")
+
+(define_register_constraint "Rhl" "HL_REGS"
+  "@internal")
+
+(define_register_constraint "R23" "R23_REGS"
+  "@internal")
+
+(define_register_constraint "Ra0" "A0_REGS"
+  "@internal")
+
+(define_register_constraint "Ra1" "A1_REGS"
+  "@internal")
+
+(define_register_constraint "Raa" "A_REGS"
+  "@internal")
+
+(define_register_constraint "Raw" "TARGET_A16 ? A_REGS : NO_REGS"
+  "@internal")
+
+(define_register_constraint "Ral" "TARGET_A24 ? A_REGS : NO_REGS"
+  "@internal")
+
+(define_register_constraint "Rqi" "QI_REGS"
+  "@internal")
+
+(define_register_constraint "Rad" "AD_REGS"
+  "@internal")
+
+(define_register_constraint "Rsi" "SI_REGS"
+  "@internal")
+
+(define_register_constraint "Rhi" "HI_REGS"
+  "@internal")
+
+(define_register_constraint "Rhc" "HC_REGS"
+  "@internal")
+
+(define_register_constraint "Rra" "RA_REGS"
+  "@internal")
+
+(define_register_constraint "Rfl" "FLG_REGS"
+  "@internal")
+
+(define_register_constraint "Rmm" "fixed_regs[MEM0_REGNO] ? NO_REGS : MEM_REGS"
+  "@internal")
+
+(define_register_constraint "Rpi" "TARGET_A16 ? HI_REGS : RA_REGS"
+  "@internal")
+
+;;; For integer constant constraints:
+;;; s=signed u=unsigned n=nonzero m=minus l=log2able,
+;;; [sun] bits [SUN] bytes, p=pointer size
+;;; I[-0-9][0-9] matches that number
+
+(define_constraint "Is3"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, -8, 7)")))
+
+(define_constraint "IS1"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, -128, 127)")))
+
+(define_constraint "IS2"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, -32768, 32767)")))
+
+(define_constraint "IU2"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, 0, 65535)")))
+
+(define_constraint "IU3"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, 0, 0x00ffffff)")))
+
+(define_constraint "In4"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, -8, 8) && ival")))
+
+(define_constraint "In5"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, -16, 16) && ival")))
+
+(define_constraint "In6"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, -32, 32) && ival")))
+
+(define_constraint "IM2"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, -65536, -1)")))
+
+(define_constraint "Ilb"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (exact_log2 (ival), 0, 7)")))
+
+(define_constraint "Imb"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (exact_log2 ((ival ^ 0xff) & 0xff), 0, 7)")))
+
+(define_constraint "ImB"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (exact_log2 ((ival ^ 0xffff) & 0xffff), 0, 7)")))
+
+(define_constraint "Ilw"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (exact_log2 (ival), 0, 15)")))
+
+(define_constraint "Imw"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (exact_log2 ((ival ^ 0xffff) & 0xffff), 0, 15)")))
+
+(define_constraint "I00"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "ival == 0")))
+
+(define_memory_constraint "SF"
+  "@internal"
+  (match_test "m32c_matches_constraint_p (op, CONSTRAINT_SF)"))
+
+(define_memory_constraint "Sd"
+  "@internal"
+  (match_test "m32c_matches_constraint_p (op, CONSTRAINT_Sd)"))
+
+(define_memory_constraint "Sa"
+  "@internal"
+  (match_test "m32c_matches_constraint_p (op, CONSTRAINT_Sa)"))
+
+(define_memory_constraint "Si"
+  "@internal"
+  (match_test "m32c_matches_constraint_p (op, CONSTRAINT_Si)"))
+
+(define_memory_constraint "Ss"
+  "@internal"
+  (match_test "m32c_matches_constraint_p (op, CONSTRAINT_Ss)"))
+
+(define_memory_constraint "Sf"
+  "@internal"
+  (match_test "m32c_matches_constraint_p (op, CONSTRAINT_Sf)"))
+
+(define_memory_constraint "Sb"
+  "@internal"
+  (match_test "m32c_matches_constraint_p (op, CONSTRAINT_Sb)"))
+
+(define_memory_constraint "Sp"
+  "@internal"
+  (match_test "m32c_matches_constraint_p (op, CONSTRAINT_Sp)"))
+
+(define_memory_constraint "S1"
+  "@internal"
+  (match_test "m32c_matches_constraint_p (op, CONSTRAINT_S1)"))
+
+(define_constraint "Rpa"
+  "@internal"
+  (match_test "m32c_matches_constraint_p (op, CONSTRAINT_Rpa)"))
diff --git a/gcc/config/m32c/m32c-protos.h b/gcc/config/m32c/m32c-protos.h
index 9c247dc..1f70da1 100644
--- a/gcc/config/m32c/m32c-protos.h
+++ b/gcc/config/m32c/m32c-protos.h
@@ -20,21 +20,17 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 void m32c_conditional_register_usage (void);
-int  m32c_const_ok_for_constraint_p (HOST_WIDE_INT, char, const char *);
 unsigned int m32c_dwarf_frame_regnum (int);
 int  m32c_eh_return_data_regno (int);
 void m32c_emit_epilogue (void);
 void m32c_emit_prologue (void);
 int  m32c_epilogue_uses (int);
-int  m32c_extra_address_constraint (char, const char *);
-int  m32c_extra_memory_constraint (char, const char *);
 int  m32c_function_arg_regno_p (int);
 void m32c_init_expanders (void);
 int  m32c_initial_elimination_offset (int, int);
 void m32c_output_reg_pop (FILE *, int);
 void m32c_output_reg_push (FILE *, int);
 unsigned int  m32c_push_rounding (int);
-int  m32c_reg_class_from_constraint (char, const char *);
 void m32c_register_pragmas (void);
 void m32c_note_pragma_address (const char *, unsigned);
 int  m32c_regno_ok_for_base_p (int);
@@ -53,8 +49,7 @@  int  m32c_expand_movmemhi (rtx *);
 int  m32c_expand_movstr (rtx *);
 void m32c_expand_neg_mulpsi3 (rtx *);
 int  m32c_expand_setmemhi (rtx *);
-int  m32c_extra_constraint_p (rtx, char, const char *);
-int  m32c_extra_constraint_p2 (rtx, char, const char *);
+bool m32c_matches_constraint_p (rtx, int);
 int  m32c_hard_regno_nregs (int, enum machine_mode);
 int  m32c_hard_regno_ok (int, enum machine_mode);
 bool m32c_illegal_subreg_p (rtx);
diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c
index 878be09..2379178 100644
--- a/gcc/config/m32c/m32c.c
+++ b/gcc/config/m32c/m32c.c
@@ -48,6 +48,7 @@ 
 #include "langhooks.h"
 #include "gimple.h"
 #include "df.h"
+#include "tm-constrs.h"
 
 /* Prototypes */
 
@@ -629,94 +630,6 @@  m32c_regno_reg_class (int regno)
     }
 }
 
-/* Implements REG_CLASS_FROM_CONSTRAINT.  Note that some constraints only match
-   for certain chip families.  */
-int
-m32c_reg_class_from_constraint (char c ATTRIBUTE_UNUSED, const char *s)
-{
-  if (memcmp (s, "Rsp", 3) == 0)
-    return SP_REGS;
-  if (memcmp (s, "Rfb", 3) == 0)
-    return FB_REGS;
-  if (memcmp (s, "Rsb", 3) == 0)
-    return SB_REGS;
-  if (memcmp (s, "Rcr", 3) == 0)
-    return TARGET_A16 ? CR_REGS : NO_REGS;
-  if (memcmp (s, "Rcl", 3) == 0)
-    return TARGET_A24 ? CR_REGS : NO_REGS;
-  if (memcmp (s, "R0w", 3) == 0)
-    return R0_REGS;
-  if (memcmp (s, "R1w", 3) == 0)
-    return R1_REGS;
-  if (memcmp (s, "R2w", 3) == 0)
-    return R2_REGS;
-  if (memcmp (s, "R3w", 3) == 0)
-    return R3_REGS;
-  if (memcmp (s, "R02", 3) == 0)
-    return R02_REGS;
-  if (memcmp (s, "R13", 3) == 0)
-    return R13_REGS;
-  if (memcmp (s, "R03", 3) == 0)
-    return R03_REGS;
-  if (memcmp (s, "Rdi", 3) == 0)
-    return DI_REGS;
-  if (memcmp (s, "Rhl", 3) == 0)
-    return HL_REGS;
-  if (memcmp (s, "R23", 3) == 0)
-    return R23_REGS;
-  if (memcmp (s, "Ra0", 3) == 0)
-    return A0_REGS;
-  if (memcmp (s, "Ra1", 3) == 0)
-    return A1_REGS;
-  if (memcmp (s, "Raa", 3) == 0)
-    return A_REGS;
-  if (memcmp (s, "Raw", 3) == 0)
-    return TARGET_A16 ? A_REGS : NO_REGS;
-  if (memcmp (s, "Ral", 3) == 0)
-    return TARGET_A24 ? A_REGS : NO_REGS;
-  if (memcmp (s, "Rqi", 3) == 0)
-    return QI_REGS;
-  if (memcmp (s, "Rad", 3) == 0)
-    return AD_REGS;
-  if (memcmp (s, "Rsi", 3) == 0)
-    return SI_REGS;
-  if (memcmp (s, "Rhi", 3) == 0)
-    return HI_REGS;
-  if (memcmp (s, "Rhc", 3) == 0)
-    return HC_REGS;
-  if (memcmp (s, "Rra", 3) == 0)
-    return RA_REGS;
-  if (memcmp (s, "Rfl", 3) == 0)
-    return FLG_REGS;
-  if (memcmp (s, "Rmm", 3) == 0)
-    {
-      if (fixed_regs[MEM0_REGNO])
-	return NO_REGS;
-      return MEM_REGS;
-    }
-
-  /* PSImode registers - i.e. whatever can hold a pointer.  */
-  if (memcmp (s, "Rpi", 3) == 0)
-    {
-      if (TARGET_A16)
-	return HI_REGS;
-      else
-	return RA_REGS; /* r2r0 and r3r1 can hold pointers.  */
-    }
-
-  /* We handle this one as an EXTRA_CONSTRAINT.  */
-  if (memcmp (s, "Rpa", 3) == 0)
-    return NO_REGS;
-
-  if (*s == 'R')
-    {
-      fprintf(stderr, "unrecognized R constraint: %.3s\n", s);
-      gcc_unreachable();
-    }
-
-  return NO_REGS;
-}
-
 /* Implements REGNO_OK_FOR_BASE_P.  */
 int
 m32c_regno_ok_for_base_p (int regno)
@@ -926,141 +839,57 @@  m32c_cannot_change_mode_class (enum machine_mode from,
 			       && (REGNO (rtx) == AP_REGNO \
 				   || REGNO (rtx) >= FIRST_PSEUDO_REGISTER))
 
-/* Implements CONST_OK_FOR_CONSTRAINT_P.  Currently, all constant
-   constraints start with 'I', with the next two characters indicating
-   the type and size of the range allowed.  */
-int
-m32c_const_ok_for_constraint_p (HOST_WIDE_INT value,
-				char c ATTRIBUTE_UNUSED, const char *str)
-{
-  /* s=signed u=unsigned n=nonzero m=minus l=log2able,
-     [sun] bits [SUN] bytes, p=pointer size
-     I[-0-9][0-9] matches that number */
-  if (memcmp (str, "Is3", 3) == 0)
-    {
-      return (-8 <= value && value <= 7);
-    }
-  if (memcmp (str, "IS1", 3) == 0)
-    {
-      return (-128 <= value && value <= 127);
-    }
-  if (memcmp (str, "IS2", 3) == 0)
-    {
-      return (-32768 <= value && value <= 32767);
-    }
-  if (memcmp (str, "IU2", 3) == 0)
-    {
-      return (0 <= value && value <= 65535);
-    }
-  if (memcmp (str, "IU3", 3) == 0)
-    {
-      return (0 <= value && value <= 0x00ffffff);
-    }
-  if (memcmp (str, "In4", 3) == 0)
-    {
-      return (-8 <= value && value && value <= 8);
-    }
-  if (memcmp (str, "In5", 3) == 0)
-    {
-      return (-16 <= value && value && value <= 16);
-    }
-  if (memcmp (str, "In6", 3) == 0)
-    {
-      return (-32 <= value && value && value <= 32);
-    }
-  if (memcmp (str, "IM2", 3) == 0)
-    {
-      return (-65536 <= value && value && value <= -1);
-    }
-  if (memcmp (str, "Ilb", 3) == 0)
-    {
-      int b = exact_log2 (value);
-      return (b >= 0 && b <= 7);
-    }
-  if (memcmp (str, "Imb", 3) == 0)
-    {
-      int b = exact_log2 ((value ^ 0xff) & 0xff);
-      return (b >= 0 && b <= 7);
-    }
-  if (memcmp (str, "ImB", 3) == 0)
-    {
-      int b = exact_log2 ((value ^ 0xffff) & 0xffff);
-      return (b >= 0 && b <= 7);
-    }
-  if (memcmp (str, "Ilw", 3) == 0)
-    {
-      int b = exact_log2 (value);
-      return (b >= 0 && b <= 15);
-    }
-  if (memcmp (str, "Imw", 3) == 0)
-    {
-      int b = exact_log2 ((value ^ 0xffff) & 0xffff);
-      return (b >= 0 && b <= 15);
-    }
-  if (memcmp (str, "I00", 3) == 0)
-    {
-      return (value == 0);
-    }
-  return 0;
-}
-
 #define A0_OR_PSEUDO(x) (IS_REG(x, A0_REGNO) || REGNO (x) >= FIRST_PSEUDO_REGISTER)
 
 /* Implements EXTRA_CONSTRAINT_STR (see next function too).  'S' is
    for memory constraints, plus "Rpa" for PARALLEL rtx's we use for
    call return values.  */
-int
-m32c_extra_constraint_p2 (rtx value, char c ATTRIBUTE_UNUSED, const char *str)
+bool
+m32c_matches_constraint_p (rtx value, int constraint)
 {
   encode_pattern (value);
 
-  if (far_addr_space_p (value))
-    {
-      if (memcmp (str, "SF", 2) == 0)
-	{
-	  return (   (RTX_IS ("mr")
-		      && A0_OR_PSEUDO (patternr[1])
-		      && GET_MODE (patternr[1]) == SImode)
-		     || (RTX_IS ("m+^Sri")
-			 && A0_OR_PSEUDO (patternr[4])
-			 && GET_MODE (patternr[4]) == HImode)
-		     || (RTX_IS ("m+^Srs")
-			 && A0_OR_PSEUDO (patternr[4])
-			 && GET_MODE (patternr[4]) == HImode)
-		     || (RTX_IS ("m+^S+ris")
-			 && A0_OR_PSEUDO (patternr[5])
-			 && GET_MODE (patternr[5]) == HImode)
-		     || RTX_IS ("ms")
-		     );
-	}
-      return 0;
-    }
-
-  if (memcmp (str, "Sd", 2) == 0)
+  switch (constraint) {
+  case CONSTRAINT_SF:
+    return (far_addr_space_p (value)
+	    && ((RTX_IS ("mr")
+		 && A0_OR_PSEUDO (patternr[1])
+		 && GET_MODE (patternr[1]) == SImode)
+		|| (RTX_IS ("m+^Sri")
+		    && A0_OR_PSEUDO (patternr[4])
+		    && GET_MODE (patternr[4]) == HImode)
+		|| (RTX_IS ("m+^Srs")
+		    && A0_OR_PSEUDO (patternr[4])
+		    && GET_MODE (patternr[4]) == HImode)
+		|| (RTX_IS ("m+^S+ris")
+		    && A0_OR_PSEUDO (patternr[5])
+		    && GET_MODE (patternr[5]) == HImode)
+		|| RTX_IS ("ms")));
+  case CONSTRAINT_Sd:    
     {
       /* This is the common "src/dest" address */
       rtx r;
       if (GET_CODE (value) == MEM && CONSTANT_P (XEXP (value, 0)))
-	return 1;
+	return true;
       if (RTX_IS ("ms") || RTX_IS ("m+si"))
-	return 1;
+	return true;
       if (RTX_IS ("m++rii"))
 	{
 	  if (REGNO (patternr[3]) == FB_REGNO
 	      && INTVAL (patternr[4]) == 0)
-	    return 1;
+	    return true;
 	}
       if (RTX_IS ("mr"))
 	r = patternr[1];
       else if (RTX_IS ("m+ri") || RTX_IS ("m+rs") || RTX_IS ("m+r+si"))
 	r = patternr[2];
       else
-	return 0;
+	return false;
       if (REGNO (r) == SP_REGNO)
-	return 0;
+	return false;
       return m32c_legitimate_address_p (GET_MODE (value), XEXP (value, 0), 1);
     }
-  else if (memcmp (str, "Sa", 2) == 0)
+  case CONSTRAINT_Sa:
     {
       rtx r;
       if (RTX_IS ("mr"))
@@ -1068,81 +897,34 @@  m32c_extra_constraint_p2 (rtx value, char c ATTRIBUTE_UNUSED, const char *str)
       else if (RTX_IS ("m+ri"))
 	r = patternr[2];
       else
-	return 0;
+	return false;
       return (IS_REG (r, A0_REGNO) || IS_REG (r, A1_REGNO));
     }
-  else if (memcmp (str, "Si", 2) == 0)
-    {
-      return (RTX_IS ("mi") || RTX_IS ("ms") || RTX_IS ("m+si"));
-    }
-  else if (memcmp (str, "Ss", 2) == 0)
-    {
-      return ((RTX_IS ("mr")
-	       && (IS_REG (patternr[1], SP_REGNO)))
-	      || (RTX_IS ("m+ri") && (IS_REG (patternr[2], SP_REGNO))));
-    }
-  else if (memcmp (str, "Sf", 2) == 0)
-    {
-      return ((RTX_IS ("mr")
-	       && (IS_REG (patternr[1], FB_REGNO)))
-	      || (RTX_IS ("m+ri") && (IS_REG (patternr[2], FB_REGNO))));
-    }
-  else if (memcmp (str, "Sb", 2) == 0)
-    {
-      return ((RTX_IS ("mr")
-	       && (IS_REG (patternr[1], SB_REGNO)))
-	      || (RTX_IS ("m+ri") && (IS_REG (patternr[2], SB_REGNO))));
-    }
-  else if (memcmp (str, "Sp", 2) == 0)
-    {
-      /* Absolute addresses 0..0x1fff used for bit addressing (I/O ports) */
-      return (RTX_IS ("mi")
-	      && !(INTVAL (patternr[1]) & ~0x1fff));
-    }
-  else if (memcmp (str, "S1", 2) == 0)
-    {
-      return r1h_operand (value, QImode);
-    }
-  else if (memcmp (str, "SF", 2) == 0)
-    {
-      return 0;
-    }
-
-  gcc_assert (str[0] != 'S');
-
-  if (memcmp (str, "Rpa", 2) == 0)
+  case CONSTRAINT_Si:
+    return (RTX_IS ("mi") || RTX_IS ("ms") || RTX_IS ("m+si"));
+  case CONSTRAINT_Ss:
+    return ((RTX_IS ("mr")
+	     && (IS_REG (patternr[1], SP_REGNO)))
+	    || (RTX_IS ("m+ri") && (IS_REG (patternr[2], SP_REGNO))));
+  case CONSTRAINT_Sf:
+    return ((RTX_IS ("mr")
+	     && (IS_REG (patternr[1], FB_REGNO)))
+	    || (RTX_IS ("m+ri") && (IS_REG (patternr[2], FB_REGNO))));
+  case CONSTRAINT_Sb:
+    return ((RTX_IS ("mr")
+	     && (IS_REG (patternr[1], SB_REGNO)))
+	    || (RTX_IS ("m+ri") && (IS_REG (patternr[2], SB_REGNO))));
+  case CONSTRAINT_Sp:
+    /* Absolute addresses 0..0x1fff used for bit addressing (I/O ports) */
+    return (RTX_IS ("mi")
+	    && !(INTVAL (patternr[1]) & ~0x1fff));
+  case CONSTRAINT_S1:
+    return r1h_operand (value, QImode);
+  case CONSTRAINT_Rpa:
     return GET_CODE (value) == PARALLEL;
-
-  return 0;
-}
-
-/* This is for when we're debugging the above.  */
-int
-m32c_extra_constraint_p (rtx value, char c, const char *str)
-{
-  int rv = m32c_extra_constraint_p2 (value, c, str);
-#if DEBUG0
-  fprintf (stderr, "\nconstraint %.*s: %d\n", CONSTRAINT_LEN (c, str), str,
-	   rv);
-  debug_rtx (value);
-#endif
-  return rv;
-}
-
-/* Implements EXTRA_MEMORY_CONSTRAINT.  Currently, we only use strings
-   starting with 'S'.  */
-int
-m32c_extra_memory_constraint (char c, const char *str ATTRIBUTE_UNUSED)
-{
-  return c == 'S';
-}
-
-/* Implements EXTRA_ADDRESS_CONSTRAINT.  We reserve 'A' strings for these,
-   but don't currently define any.  */
-int
-m32c_extra_address_constraint (char c, const char *str ATTRIBUTE_UNUSED)
-{
-  return c == 'A';
+  default:
+    return false;
+  }
 }
 
 /* STACK AND CALLING */
@@ -3667,7 +3449,7 @@  m32c_split_move (rtx * operands, enum machine_mode mode, int split_all)
      point, so it's safe to set it to 3 even with define_insn.  */
   /* None of the chips can move SI operands to sp-relative addresses,
      so we always split those.  */
-  if (m32c_extra_constraint_p (operands[0], 'S', "Ss"))
+  if (satisfies_constraint_Ss (operands[0]))
     split_all = 3;
 
   if (TARGET_A16
diff --git a/gcc/config/m32c/m32c.h b/gcc/config/m32c/m32c.h
index 00f8a2c..1efbd36 100644
--- a/gcc/config/m32c/m32c.h
+++ b/gcc/config/m32c/m32c.h
@@ -405,15 +405,6 @@  enum reg_class
    A - addresses (currently unused)
 */
 
-#define CONSTRAINT_LEN(CHAR,STR) \
-	((CHAR) == 'I' ? 3 \
-	 : (CHAR) == 'R' ? 3 \
-	 : (CHAR) == 'S' ? 2 \
-	 : (CHAR) == 'A' ? 2 \
-	 : DEFAULT_CONSTRAINT_LEN(CHAR,STR))
-#define REG_CLASS_FROM_CONSTRAINT(CHAR,STR) \
-	(enum reg_class) m32c_reg_class_from_constraint (CHAR, STR)
-
 #define REGNO_OK_FOR_BASE_P(NUM) m32c_regno_ok_for_base_p (NUM)
 #define REGNO_OK_FOR_INDEX_P(NUM) 0
 
@@ -427,16 +418,6 @@  enum reg_class
 
 #define CANNOT_CHANGE_MODE_CLASS(F,T,C) m32c_cannot_change_mode_class(F,T,C)
 
-#define CONST_OK_FOR_CONSTRAINT_P(VALUE,C,STR) \
-	m32c_const_ok_for_constraint_p (VALUE, C, STR)
-#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(VALUE,C,STR) 0
-#define EXTRA_CONSTRAINT_STR(VALUE,C,STR) \
-	m32c_extra_constraint_p (VALUE, C, STR)
-#define EXTRA_MEMORY_CONSTRAINT(C,STR) \
-	m32c_extra_memory_constraint (C, STR)
-#define EXTRA_ADDRESS_CONSTRAINT(C,STR) \
-	m32c_extra_address_constraint (C, STR)
-
 /* STACK AND CALLING */
 
 /* Frame Layout */
diff --git a/gcc/config/m32c/predicates.md b/gcc/config/m32c/predicates.md
index 9293baa..9045cb5 100644
--- a/gcc/config/m32c/predicates.md
+++ b/gcc/config/m32c/predicates.md
@@ -183,12 +183,12 @@ 
 ; TRUE for memory operands that are not indexed
 (define_predicate "memsym_operand"
   (and (match_operand 0 "memory_operand" "")
-       (match_test "m32c_extra_constraint_p (op, 'S', \"Si\")")))
+       (match_test "satisfies_constraint_Si (op)")))
 
 ; TRUE for memory operands with small integer addresses
 (define_predicate "memimmed_operand"
   (and (match_operand 0 "memory_operand" "")
-       (match_test "m32c_extra_constraint_p (op, 'S', \"Sp\")")))
+       (match_test "satisfies_constraint_Sp (op)")))
 
 ; TRUE for r1h.  This is complicated since r1h isn't a register GCC
 ; normally knows about.
@@ -274,22 +274,22 @@ 
 ; TRUE for constants we can multiply pointers by
 (define_predicate "m32c_psi_scale"
   (and (match_operand 0 "const_int_operand")
-       (match_test "m32c_const_ok_for_constraint_p(INTVAL(op), 'I', \"Ilb\")")))
+       (match_test "satisfies_constraint_Ilb (op)")))
 
 ; TRUE for one bit set (bit) or clear (mask) out of N bits.
 
 (define_predicate "m32c_1bit8_operand"
   (and (match_operand 0 "const_int_operand")
-       (match_test "m32c_const_ok_for_constraint_p(INTVAL(op), 'I', \"Ilb\")")))
+       (match_test "satisfies_constraint_Ilb (op)")))
 
 (define_predicate "m32c_1bit16_operand"
   (and (match_operand 0 "const_int_operand")
-       (match_test "m32c_const_ok_for_constraint_p(INTVAL(op), 'I', \"Ilw\")")))
+       (match_test "satisfies_constraint_Ilw (op)")))
 
 (define_predicate "m32c_1mask8_operand"
   (and (match_operand 0 "const_int_operand")
-       (match_test "m32c_const_ok_for_constraint_p(INTVAL(op), 'I', \"ImB\")")))
+       (match_test "satisfies_constraint_ImB (op)")))
 
 (define_predicate "m32c_1mask16_operand"
   (and (match_operand 0 "const_int_operand")
-       (match_test "m32c_const_ok_for_constraint_p(INTVAL(op), 'I', \"Imw\")")))
+       (match_test "satisfies_constraint_Imw (op)")))
diff --git a/gcc/config/m32c/t-m32c b/gcc/config/m32c/t-m32c
index 1e4ed6b..d5f1bf4 100644
--- a/gcc/config/m32c/t-m32c
+++ b/gcc/config/m32c/t-m32c
@@ -23,7 +23,7 @@ 
 
 md_file = md
 
-MD_FILES = m32c predicates addsub bitops blkmov cond jump minmax mov muldiv prologue shift
+MD_FILES = m32c constraints predicates addsub bitops blkmov cond jump minmax mov muldiv prologue shift
 
 # Doing it this way lets the gen* programs report the right line numbers.