+2011-02-14 Nathan Froyd <froydnj@codesourcery.com>
+
+ * 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.
+
2011-02-14 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR ada/41929
--- /dev/null
+;; 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")))
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). */
#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.
"nothing")
(include "predicates.md")
+(include "constraints.md")
;; -------------------------------------------------------------------------
;; Test and bit test