This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] convert mcore to constraints.md


As $SUBJECT suggests.

Tested with cross to mcore-elf.  OK to commit now, or wait until 4.7?

-Nathan

	* config/mcore/constraints.md: New file.
	* config/mcore/mcore.md: Include it.
	* config/mcore/mcore.c (reg_class_from_letter): Delete.
	* config/mcore/mcore.h (reg_class_from_letter): Delete.
	(REG_CLASS_FROM_LETTER): Delete.
	(CONST_OK_FOR_I, CONST_OK_FOR_J, CONST_OK_FOR_L): Use
	insn_const_int_ok_for_constraint.
	(CONST_OK_FOR_K, CONST_OK_FOR_M, CONST_OK_FOR_N): Likewise.
	(CONST_OK_FOR_O, CONST_OK_FOR_P): Likewise.
	(CONST_OK_FOR_LETTER_P, CONST_DOUBLE_OK_FOR_LETTER_P): Delete.
	(EXTRA_CONSTRAINT): Delete.

diff --git a/gcc/config/mcore/constraints.md b/gcc/config/mcore/constraints.md
new file mode 100644
index 0000000..dee9807
--- /dev/null
+++ b/gcc/config/mcore/constraints.md
@@ -0,0 +1,112 @@
+;; Constraint definitions for the Motorola MCore
+;; 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" "LRW_REGS"
+  "@internal")
+
+(define_register_constraint "b" "ONLYR1_REGS"
+  "@internal")
+
+(define_register_constraint "c" "C_REGS"
+  "@internal")
+
+(define_register_constraint "x" "ALL_REGS"
+  "@internal")
+
+;; Integer constraints.
+(define_constraint "I"
+  "An integer in the range 0 to 127."
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, 0, 127)")))
+
+(define_constraint "J"
+  "An integer in the range 1 to 32."
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, 1, 32)")))
+
+(define_constraint "K"
+  "A shift operand, an integer in the range 0 to 31."
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, 0, 31)")))
+
+(define_constraint "L"
+  "A negative arithmetic operand in the range -32 to -1."
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, -32, -1)")))
+
+(define_constraint "M"
+  "A constant loadable by bgeni."
+  (and (match_code "const_int")
+       (match_test "exact_log2 (ival) >= 0 && exact_log2 (ival) <= 30")))
+
+(define_constraint "N"
+  "A constant loadable by bmaskii, including -1."
+  (and (match_code "const_int")
+       (ior (match_test "ival == -1")
+	    (and (match_test "exact_log2 (ival + 1) >= 0")
+		 (match_test "exact_log2 (ival + 1) <= 30")))))
+
+(define_constraint "O"
+  "A constant allowed by cmov with two constants +/- 1 of each other."
+  (and (match_code "const_int")
+       (ior (match_test "insn_const_int_ok_for_constraint (ival, CONSTRAINT_I)")
+	    (match_test "insn_const_int_ok_for_constraint (ival, CONSTRAINT_M)")
+	    (match_test "insn_const_int_ok_for_constraint (ival, CONSTRAINT_N)")
+	    (match_test "insn_const_int_ok_for_constraint (ival - 1, CONSTRAINT_M)")
+	    (match_test "insn_const_int_ok_for_constraint (ival + 1, CONSTRAINT_N)"))))
+
+(define_constraint "P"
+  "A value that can be generated without an lrw instruction."
+  (and (match_code "const_int")
+       (match_test "mcore_const_ok_for_inline (ival)")))
+
+;; Floating-point constraints.
+(define_constraint "G"
+  "@internal"
+  (and (match_code "const_double")
+       (match_test "insn_const_int_ok_for_constraint (hval, CONSTRAINT_I)")
+       (match_test "insn_const_int_ok_for_constraint (ival, CONSTRAINT_I)")))
+
+;; Other constraints.
+(define_constraint "Q"
+  "The integer constant one."
+  (and (match_code "const_int")
+       (match_test "ival == 1")))
+
+(define_constraint "R"
+  "@internal"
+  (and (match_code "mem")
+       (match_test "GET_CODE (XEXP (op, 0)) == LABEL_REF")))
+
+(define_constraint "S"
+  "An integer constant with 0, 1, or 2 bits clear."
+  (and (match_code "const_int")
+       (match_test "mcore_num_zeros (ival) <= 2")))
+
+(define_constraint "T"
+  "An integer constant with 2 set bits."
+  (and (match_code "const_int")
+       (match_test "mcore_num_ones (ival) == 2")))
+
+(define_constraint "U"
+  "The integer constant zero."
+  (and (match_code "const_int")
+       (match_test "ival == 0")))
diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c
index 6227b17..8118276 100644
--- a/gcc/config/mcore/mcore.c
+++ b/gcc/config/mcore/mcore.c
@@ -61,19 +61,6 @@ const enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER] =
   GENERAL_REGS, C_REGS,       NO_REGS,      NO_REGS,
 };
 
-/* Provide reg_class from a letter such as appears in the machine
-   description.  */
-const enum reg_class reg_class_from_letter[] =
-{
-  /* a */ LRW_REGS, /* b */ ONLYR1_REGS, /* c */ C_REGS,  /* d */ NO_REGS,
-  /* e */ NO_REGS, /* f */ NO_REGS, /* g */ NO_REGS, /* h */ NO_REGS,
-  /* i */ NO_REGS, /* j */ NO_REGS, /* k */ NO_REGS, /* l */ NO_REGS,
-  /* m */ NO_REGS, /* n */ NO_REGS, /* o */ NO_REGS, /* p */ NO_REGS,
-  /* q */ NO_REGS, /* r */ GENERAL_REGS, /* s */ NO_REGS, /* t */ NO_REGS,
-  /* u */ NO_REGS, /* v */ NO_REGS, /* w */ NO_REGS, /* x */ ALL_REGS,
-  /* y */ NO_REGS, /* z */ NO_REGS
-};
-
 struct mcore_frame
 {
   int arg_size;			/* Stdarg spills (bytes).  */
diff --git a/gcc/config/mcore/mcore.h b/gcc/config/mcore/mcore.h
index 3f76e18..54c12ef 100644
--- a/gcc/config/mcore/mcore.h
+++ b/gcc/config/mcore/mcore.h
@@ -374,82 +374,23 @@ extern const enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
 #define INDEX_REG_CLASS  NO_REGS
 #define BASE_REG_CLASS	 GENERAL_REGS
 
-/* Get reg_class from a letter such as appears in the machine 
-   description.  */
-extern const enum reg_class reg_class_from_letter[];
-
-#define REG_CLASS_FROM_LETTER(C) \
-   (ISLOWER (C) ? reg_class_from_letter[(C) - 'a'] : NO_REGS)
-
-/* The letters I, J, K, L, M, N, O, and 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.
-	I: loadable by movi (0..127)
-	J: arithmetic operand 1..32
-	K: shift operand 0..31
-	L: negative arithmetic operand -1..-32
-	M: powers of two, constants loadable by bgeni
-	N: powers of two minus 1, constants loadable by bmaski, including -1
-        O: allowed by cmov with two constants +/- 1 of each other
-        P: values we will generate 'inline' -- without an 'lrw'
-
-   Others defined for use after reload
-        Q: constant 1
-	R: a label
-        S: 0/1/2 cleared bits out of 32	[for bclri's]
-        T: 2 set bits out of 32	[for bseti's]
-        U: constant 0
-        xxxS: 1 cleared bit out of 32 (complement of power of 2). for bclri
-        xxxT: 2 cleared bits out of 32. for pairs of bclris.  */
-#define CONST_OK_FOR_I(VALUE) (((HOST_WIDE_INT)(VALUE)) >= 0 && ((HOST_WIDE_INT)(VALUE)) <= 0x7f)
-#define CONST_OK_FOR_J(VALUE) (((HOST_WIDE_INT)(VALUE)) >  0 && ((HOST_WIDE_INT)(VALUE)) <= 32)
-#define CONST_OK_FOR_L(VALUE) (((HOST_WIDE_INT)(VALUE)) <  0 && ((HOST_WIDE_INT)(VALUE)) >= -32)
-#define CONST_OK_FOR_K(VALUE) (((HOST_WIDE_INT)(VALUE)) >= 0 && ((HOST_WIDE_INT)(VALUE)) <= 31)
-#define CONST_OK_FOR_M(VALUE) (exact_log2 (VALUE) >= 0 && exact_log2 (VALUE) <= 30)
-#define CONST_OK_FOR_N(VALUE) (((HOST_WIDE_INT)(VALUE)) == -1 || (exact_log2 ((VALUE) + 1) >= 0 && exact_log2 ((VALUE) + 1) <= 30))
-#define CONST_OK_FOR_O(VALUE) (CONST_OK_FOR_I(VALUE) || \
-                               CONST_OK_FOR_M(VALUE) || \
-                               CONST_OK_FOR_N(VALUE) || \
-                               CONST_OK_FOR_M((HOST_WIDE_INT)(VALUE) - 1) || \
-                               CONST_OK_FOR_N((HOST_WIDE_INT)(VALUE) + 1))
-
-#define CONST_OK_FOR_P(VALUE) (mcore_const_ok_for_inline (VALUE)) 
-
-#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) == 'K' ? CONST_OK_FOR_K (VALUE)   \
-    : (C) == 'M' ? CONST_OK_FOR_M (VALUE)   \
-    : (C) == 'N' ? CONST_OK_FOR_N (VALUE)   \
-    : (C) == 'P' ? CONST_OK_FOR_P (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.  */
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
-   ((C) == 'G' ? CONST_OK_FOR_I (CONST_DOUBLE_HIGH (VALUE)) \
-	      && CONST_OK_FOR_I (CONST_DOUBLE_LOW (VALUE))  \
-    : 0)
-
-/* Letters in the range `Q' through `U' in a register constraint string
-   may be defined in a machine-dependent fashion to stand for arbitrary
-   operand types.  */
-#define EXTRA_CONSTRAINT(OP, C)				\
-  ((C) == 'R' ? (GET_CODE (OP) == MEM			\
-		 && GET_CODE (XEXP (OP, 0)) == LABEL_REF) \
-   : (C) == 'S' ? (GET_CODE (OP) == CONST_INT \
-                   && mcore_num_zeros (INTVAL (OP)) <= 2) \
-   : (C) == 'T' ? (GET_CODE (OP) == CONST_INT \
-                   && mcore_num_ones (INTVAL (OP)) == 2) \
-   : (C) == 'Q' ? (GET_CODE (OP) == CONST_INT \
-                   && INTVAL(OP) == 1) \
-   : (C) == 'U' ? (GET_CODE (OP) == CONST_INT \
-                   && INTVAL(OP) == 0) \
-   : 0)
+/* Convenience wrappers around insn_const_int_ok_for_constraint.  */
+#define CONST_OK_FOR_I(VALUE) \
+  insn_const_int_ok_for_constraint (VALUE, CONSTRAINT_I)
+#define CONST_OK_FOR_J(VALUE) \
+  insn_const_int_ok_for_constraint (VALUE, CONSTRAINT_J)
+#define CONST_OK_FOR_L(VALUE) \
+  insn_const_int_ok_for_constraint (VALUE, CONSTRAINT_L)
+#define CONST_OK_FOR_K(VALUE) \
+  insn_const_int_ok_for_constraint (VALUE, CONSTRAINT_K)
+#define CONST_OK_FOR_M(VALUE) \
+  insn_const_int_ok_for_constraint (VALUE, CONSTRAINT_M)
+#define CONST_OK_FOR_N(VALUE) \
+  insn_const_int_ok_for_constraint (VALUE, CONSTRAINT_N)
+#define CONST_OK_FOR_O(VALUE) \
+  insn_const_int_ok_for_constraint (VALUE, CONSTRAINT_O)
+#define CONST_OK_FOR_P(VALUE) \
+  insn_const_int_ok_for_constraint (VALUE, CONSTRAINT_P)
 
 /* Given an rtx X being reloaded into a reg required to be
    in class CLASS, return the class of reg to actually use.
diff --git a/gcc/config/mcore/mcore.md b/gcc/config/mcore/mcore.md
index 532181d..c56a0c6 100644
--- a/gcc/config/mcore/mcore.md
+++ b/gcc/config/mcore/mcore.md
@@ -54,6 +54,7 @@
 			 "nothing")
 
 (include "predicates.md")
+(include "constraints.md")
 
 ;; -------------------------------------------------------------------------
 ;; Test and bit test


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]