diff mbox

convert v850 to constraints.md

Message ID 20110211181828.GR6247@codesourcery.com
State New
Headers show

Commit Message

Nathan Froyd Feb. 11, 2011, 6:18 p.m. UTC
As $SUBJECT suggests.

Tested with cross to v850-elf.  OK to commit, or wait for 4.7?

-Nathan

	* config/v850/constraints.md: New file.
	* config/v850/v850.md: Include it.
	* config/v850/predicates.md (reg_or_0_operand): Use
	constraint_satisfied_p.
	(special_symbolref_operand): Likewise.
	* config/v850/v850.h (CONSTANT_ADDRESS_P): Likewise.
	(GO_IF_LEGITIMATE_ADDRESS): Likewise.
	(REG_CLASS_FROM_LETTER, INT_7_BITS, INT_8_BITS): Delete.
	(CONST_OK_FOR_P, CONST_OK_FOR_LETTER_P): Delete.
	(EXTRA_CONSTRAINT): Delete.
	(CONST_OK_FOR_I, CONST_OK_FOR_J): Use CONST_OK_FOR_CONSTRAINT_P.
	(CONST_OK_FOR_K, CONST_OK_FOR_L, CONST_OK_FOR_M): Likewise.
	(CONST_OK_FOR_N, CONST_OK_FOR_O): Likewise.

Comments

Richard Henderson Feb. 11, 2011, 6:29 p.m. UTC | #1
On 02/11/2011 10:18 AM, Nathan Froyd wrote:
> +(define_constraint "L"
> +  "A valid constant for a movhi instruction."
> +  (and (match_code "const_int")
> +       (ior (match_test "(ival | 0x7fff0000) == 0x7fff0000")
> +	    (match_test "(ival | 0x7fff0000) + 0x10000 == 0"))))

Not a valid translation from the original.  This doesn't work
for 64-bit HWI.  C.f. the alpha L constraint, which is looking
for the exact same range of values.

> -    return CONST_DOUBLE_OK_FOR_G (op);
> +    return constraint_satisfied_p (op, CONSTRAINT_G);

You can use satisfies_constraint_G directly.  And elsewhere.



r~
Nathan Froyd Feb. 11, 2011, 6:38 p.m. UTC | #2
On Fri, Feb 11, 2011 at 10:29:51AM -0800, Richard Henderson wrote:
> On 02/11/2011 10:18 AM, Nathan Froyd wrote:
> > +(define_constraint "L"
> > +  "A valid constant for a movhi instruction."
> > +  (and (match_code "const_int")
> > +       (ior (match_test "(ival | 0x7fff0000) == 0x7fff0000")
> > +	    (match_test "(ival | 0x7fff0000) + 0x10000 == 0"))))
> 
> Not a valid translation from the original.  This doesn't work
> for 64-bit HWI.  C.f. the alpha L constraint, which is looking
> for the exact same range of values.

Hm, I was lazy and copied from LUI_OPERAND in mips.h.  I'll take a look
at Alpha's.

> > -    return CONST_DOUBLE_OK_FOR_G (op);
> > +    return constraint_satisfied_p (op, CONSTRAINT_G);
> 
> You can use satisfies_constraint_G directly.  And elsewhere.

I tried that, but met with a number of link errors because several files
do not include tm-constrs.h.  grepping for tm-constrs.h suggested that
it was only used in backend files, so I thought constraint_satisfied_p
would be better.  I'm happy to uses satisfies_constraint_foo if
twiddling target-independent files is OK.

-Nathan
Richard Henderson Feb. 11, 2011, 6:57 p.m. UTC | #3
On 02/11/2011 10:38 AM, Nathan Froyd wrote:
> On Fri, Feb 11, 2011 at 10:29:51AM -0800, Richard Henderson wrote:
>> On 02/11/2011 10:18 AM, Nathan Froyd wrote:
>>> +(define_constraint "L"
>>> +  "A valid constant for a movhi instruction."
>>> +  (and (match_code "const_int")
>>> +       (ior (match_test "(ival | 0x7fff0000) == 0x7fff0000")
>>> +	    (match_test "(ival | 0x7fff0000) + 0x10000 == 0"))))
>>
>> Not a valid translation from the original.  This doesn't work
>> for 64-bit HWI.  C.f. the alpha L constraint, which is looking
>> for the exact same range of values.
> 
> Hm, I was lazy and copied from LUI_OPERAND in mips.h.  I'll take a look
> at Alpha's.

Hm.  I looking more closely, I guess it does work.
It's clever, if a tad confusing.

>> You can use satisfies_constraint_G directly.  And elsewhere.
> 
> I tried that, but met with a number of link errors because several files
> do not include tm-constrs.h.  grepping for tm-constrs.h suggested that
> it was only used in backend files, so I thought constraint_satisfied_p
> would be better.  I'm happy to uses satisfies_constraint_foo if
> twiddling target-independent files is OK.

Oh?  Hum.  Well, I suppose leaving alone the instance that's in the
header file is best for now, though there are other instances within
backend files that ought to have been able to see the declarations...


r~
Nick Clifton Feb. 11, 2011, 7:35 p.m. UTC | #4
Hi Nathan,

> Tested with cross to v850-elf.  OK to commit, or wait for 4.7?

Please commit now.

Cheers
   Nick
diff mbox

Patch

diff --git a/gcc/config/v850/constraints.md b/gcc/config/v850/constraints.md
new file mode 100644
index 0000000..eecdab3
--- /dev/null
+++ b/gcc/config/v850/constraints.md
@@ -0,0 +1,108 @@ 
+;; Constraint definitions for V850.
+;; 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/>.
+
+(define_register_constraint "e" "EVEN_REGS"
+  "@internal")
+
+;; Integer constraints.
+(define_constraint "I"
+  "Integer constant 0."
+  (and (match_code "const_int")
+       (match_test "ival == 0")))
+
+(define_constraint "J"
+  "A signed 5-bit immediate."
+  (and (match_code "const_int")
+       (match_test "ival >= -16 && ival <= 15")))
+
+(define_constraint "K"
+  "A signed 16-bit immediate."
+  (and (match_code "const_int")
+       (match_test "ival >= -32768 && ival <= 32767")))
+
+(define_constraint "L"
+  "A valid constant for a movhi instruction."
+  (and (match_code "const_int")
+       (ior (match_test "(ival | 0x7fff0000) == 0x7fff0000")
+	    (match_test "(ival | 0x7fff0000) + 0x10000 == 0"))))
+
+(define_constraint "M"
+  "An unsigned 16-bit immediate."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 65535")))
+
+(define_constraint "N"
+  "An unsigned 5-bit immediate in shift instructions."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 31")))
+
+(define_constraint "O"
+  "A signed 9-bit immediate for word multiply instructions."
+  (and (match_code "const_int")
+       (match_test "ival >= -255 && ival <= 255")))
+
+(define_constraint "P"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "0")))
+
+;; Floating-point constraints.
+(define_constraint "G"
+  "A zero of some form."
+  (and (match_code "const_double")
+       (ior (match_test "GET_MODE_CLASS (mode) == MODE_FLOAT")
+	    (match_test "GET_MODE_CLASS (mode) == MODE_INT"))
+       (match_test "op == CONST0_RTX (mode)")))
+
+(define_constraint "H"
+  "@internal"
+  (and (match_code "const_double")
+       (match_test "0")))
+
+;;; Extra constraints.
+(define_constraint "Q"
+  "A memory address that does not contain a symbol address."
+  (and (match_code "mem")
+       (match_test "ep_memory_operand (op, mode, FALSE)")))
+
+(define_constraint "R"
+  "@internal"
+  (match_test "special_symbolref_operand (op, VOIDmode)"))
+
+(define_constraint "S"
+  "@internal"
+  (and (match_code "symbol_ref")
+       (match_test "!SYMBOL_REF_ZDA_P (op)")))
+
+(define_constraint "T"
+  "@internal"
+  (match_test "ep_memory_operand (op, mode, TRUE)"))
+
+(define_constraint "U"
+  "@internal"
+  (ior (and (match_code "symbol_ref")
+	    (match_test "SYMBOL_REF_ZDA_P (op)"))
+       (and (match_code "const")
+	    (match_test "GET_CODE (XEXP (op, 0)) == PLUS")
+	    (match_test "GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF")
+	    (match_test "SYMBOL_REF_ZDA_P (XEXP (XEXP (op, 0), 0))"))))
+
+(define_constraint "W"
+  "@internal"
+  (match_test "disp23_operand (op, VOIDmode)"))
diff --git a/gcc/config/v850/predicates.md b/gcc/config/v850/predicates.md
index a47453f..c991bb3 100644
--- a/gcc/config/v850/predicates.md
+++ b/gcc/config/v850/predicates.md
@@ -26,7 +26,7 @@ 
     return INTVAL (op) == 0;
 
   else if (GET_CODE (op) == CONST_DOUBLE)
-    return CONST_DOUBLE_OK_FOR_G (op);
+    return constraint_satisfied_p (op, CONSTRAINT_G);
 
   else
     return register_operand (op, mode);
@@ -129,8 +129,7 @@ 
 {
   if (GET_CODE (op) == CONST
       && GET_CODE (XEXP (op, 0)) == PLUS
-      && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
-      && CONST_OK_FOR_K (INTVAL (XEXP (XEXP (op, 0), 1))))
+      && constraint_satisfied_p (XEXP (XEXP (op, 0), 1), CONSTRAINT_K))
     op = XEXP (XEXP (op, 0), 0);
 
   if (GET_CODE (op) == SYMBOL_REF)
diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h
index afea278..3d8e944 100644
--- a/gcc/config/v850/v850.h
+++ b/gcc/config/v850/v850.h
@@ -357,11 +357,6 @@  enum reg_class
 #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.  */
-
-#define REG_CLASS_FROM_LETTER(C) \
-       (C == 'e' ? EVEN_REGS : (NO_REGS))
-
 /* Macros to check register numbers against specific register classes.  */
 
 /* These assume that REGNO is a hard or pseudo reg number.
@@ -384,62 +379,22 @@  enum reg_class
 #define CLASS_MAX_NREGS(CLASS, MODE)	\
   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
 
-/* 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 INT_7_BITS(VALUE) ((unsigned) (VALUE) + 0x40 < 0x80)
-#define INT_8_BITS(VALUE) ((unsigned) (VALUE) + 0x80 < 0x100)
-/* zero */
-#define CONST_OK_FOR_I(VALUE) ((VALUE) == 0)
-/* 5-bit signed immediate */
-#define CONST_OK_FOR_J(VALUE) ((unsigned) (VALUE) + 0x10 < 0x20)
-/* 16-bit signed immediate */
-#define CONST_OK_FOR_K(VALUE) ((unsigned) (VALUE) + 0x8000 < 0x10000)
-/* valid constant for movhi instruction.  */
-#define CONST_OK_FOR_L(VALUE) \
-  (((unsigned) ((int) (VALUE) >> 16) + 0x8000 < 0x10000) \
-   && CONST_OK_FOR_I ((VALUE & 0xffff)))
-/* 16-bit unsigned immediate */
-#define CONST_OK_FOR_M(VALUE) ((unsigned)(VALUE) < 0x10000)
-/* 5-bit unsigned immediate in shift instructions */
-#define CONST_OK_FOR_N(VALUE) ((unsigned) (VALUE) <= 31)
-/* 9-bit signed immediate for word multiply instruction.  */
-#define CONST_OK_FOR_O(VALUE) ((unsigned) (VALUE) + 0x100 < 0x200)
-
-#define CONST_OK_FOR_P(VALUE) 0
-
-#define CONST_OK_FOR_LETTER_P(VALUE, C)  \
-  ((C) == 'I' ? CONST_OK_FOR_I (VALUE) : \
-   (C) == 'J' ? CONST_OK_FOR_J (VALUE) : \
-   (C) == 'K' ? CONST_OK_FOR_K (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) : \
-   (C) == 'P' ? CONST_OK_FOR_P (VALUE) : \
-   0)
-
-/* Similar, but for floating constants, and defining letters G and H.
-   Here VALUE is the CONST_DOUBLE rtx itself. 
-     
-  `G' is a zero of some form.  */
+/* Convenience wrappers around insn_const_int_ok_for_constraint.  */
 
-#define CONST_DOUBLE_OK_FOR_G(VALUE)					\
-  ((GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT			\
-    && (VALUE) == CONST0_RTX (GET_MODE (VALUE)))			\
-   || (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_INT			\
-       && CONST_DOUBLE_LOW (VALUE) == 0					\
-       && CONST_DOUBLE_HIGH (VALUE) == 0))
-
-#define CONST_DOUBLE_OK_FOR_H(VALUE) 0
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)				\
-  ((C) == 'G'   ? CONST_DOUBLE_OK_FOR_G (VALUE)				\
-   : (C) == 'H' ? CONST_DOUBLE_OK_FOR_H (VALUE)				\
-   : 0)
+#define CONST_OK_FOR_I(VALUE) \
+  CONST_OK_FOR_CONSTRAINT_P (VALUE, 'I', "I")
+#define CONST_OK_FOR_J(VALUE) \
+  CONST_OK_FOR_CONSTRAINT_P (VALUE, 'J', "J")
+#define CONST_OK_FOR_K(VALUE) \
+  CONST_OK_FOR_CONSTRAINT_P (VALUE, 'K', "K")
+#define CONST_OK_FOR_L(VALUE) \
+  CONST_OK_FOR_CONSTRAINT_P (VALUE, 'L', "L")
+#define CONST_OK_FOR_M(VALUE) \
+  CONST_OK_FOR_CONSTRAINT_P (VALUE, 'M', "M")
+#define CONST_OK_FOR_N(VALUE) \
+  CONST_OK_FOR_CONSTRAINT_P (VALUE, 'N', "N")
+#define CONST_OK_FOR_O(VALUE) \
+  CONST_OK_FOR_CONSTRAINT_P (VALUE, 'O', "O")
 
 
 /* Stack layout; function entry, exit and calling.  */
@@ -623,9 +578,7 @@  struct cum_arg { int nbytes; int anonymous_args; };
 /* ??? This seems too exclusive.  May get better code by accepting more
    possibilities here, in particular, should accept ZDA_NAME SYMBOL_REFs.  */
 
-#define CONSTANT_ADDRESS_P(X)   \
-  (GET_CODE (X) == CONST_INT				\
-   && CONST_OK_FOR_K (INTVAL (X)))
+#define CONSTANT_ADDRESS_P(X) constraint_satisfied_p (X, CONSTRAINT_K)
 
 /* Maximum number of registers that can appear in a valid memory address.  */
 
@@ -666,39 +619,6 @@  struct cum_arg { int nbytes; int anonymous_args; };
 
 #endif
 
-/* A C expression that defines the optional machine-dependent
-   constraint letters that can be used to segregate specific types of
-   operands, usually memory references, for the target machine.
-   Normally this macro will not be defined.  If it is required for a
-   particular target machine, it should return 1 if VALUE corresponds
-   to the operand type represented by the constraint letter C.  If C
-   is not defined as an extra constraint, the value returned should
-   be 0 regardless of VALUE.
-
-   For example, on the ROMP, load instructions cannot have their
-   output in r0 if the memory reference contains a symbolic address.
-   Constraint letter `Q' is defined as representing a memory address
-   that does *not* contain a symbolic address.  An alternative is
-   specified with a `Q' constraint on the input and `r' on the
-   output.  The next alternative specifies `m' on the input and a
-   register class that does not include r0 on the output.  */
-
-#define EXTRA_CONSTRAINT(OP, C)						\
- ((C) == 'Q'   ? ep_memory_operand (OP, GET_MODE (OP), FALSE)		\
-  : (C) == 'R' ? special_symbolref_operand (OP, VOIDmode)		\
-  : (C) == 'S' ? (GET_CODE (OP) == SYMBOL_REF				\
-		  && !SYMBOL_REF_ZDA_P (OP))				\
-  : (C) == 'T' ? ep_memory_operand (OP, GET_MODE (OP), TRUE)		\
-  : (C) == 'U' ? ((GET_CODE (OP) == SYMBOL_REF				\
-		   && SYMBOL_REF_ZDA_P (OP))				\
-		  || (GET_CODE (OP) == CONST				\
-		      && GET_CODE (XEXP (OP, 0)) == PLUS		\
-		      && GET_CODE (XEXP (XEXP (OP, 0), 0)) == SYMBOL_REF\
-		      && SYMBOL_REF_ZDA_P (XEXP (XEXP (OP, 0), 0))))	\
-  : (C) == 'W' ? (GET_CODE (OP) == CONST_INT                            \
-		  && ((unsigned)(INTVAL (OP)) >= 0x8000)               \
-		  && ((unsigned)(INTVAL (OP)) < 0x400000))              \
-  : 0)
 
 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
    that is a valid memory address for an instruction.
@@ -738,7 +658,7 @@  do {									\
      goto ADDR;								\
   if (GET_CODE (X) == PLUS						\
       && RTX_OK_FOR_BASE_P (XEXP (X, 0)) 				\
-      && (GET_CODE (XEXP (X,1)) == CONST_INT && CONST_OK_FOR_K (INTVAL(XEXP (X,1)) + GET_MODE_NUNITS(MODE) * UNITS_PER_WORD)) \
+      && constraint_satisfied_p (XEXP (X,1), CONSTRAINT_K)		\
       && ((MODE == QImode || INTVAL (XEXP (X, 1)) % 2 == 0)		\
 	   && CONST_OK_FOR_K (INTVAL (XEXP (X, 1)) 			\
                               + (GET_MODE_NUNITS (MODE) * UNITS_PER_WORD)))) \
diff --git a/gcc/config/v850/v850.md b/gcc/config/v850/v850.md
index 26bc583..88e42c6 100644
--- a/gcc/config/v850/v850.md
+++ b/gcc/config/v850/v850.md
@@ -100,6 +100,7 @@ 
 			 "nothing")
 
 (include "predicates.md")
+(include "constraints.md")
 
 ;; ----------------------------------------------------------------------
 ;; MOVE INSTRUCTIONS