diff mbox

[mmix] convert to constraints.md

Message ID alpine.BSF.2.00.1209112146110.9003@dair.pair.com
State New
Headers show

Commit Message

Hans-Peter Nilsson Sept. 12, 2012, 1:54 a.m. UTC
On Fri, 31 Aug 2012, Hans-Peter Nilsson wrote:
> On Fri, 3 Aug 2012, Hans-Peter Nilsson wrote:
> Sorry, but I need more time to get
> test-results for a recent trunk revision to a state where
> testing patches makes sense.  I'll test the patch and commit
> that or a variant.  Thanks for your work.

Nathan, again thanks.  There are a few minor tweaks compared to your version:
- "U" is a define_address_constraint, not plain define_constraint.
- Keeping old layout of "mmix_reg_or_8bit_operand".  That looked like
  a spurious change and I prefer the ior construct to the if_then_else.
- Replacing undefined-constraint-"H" with "I" instead of removing it.
  It was either renamed early or a genuine typo.  Good catch.
- Carrying over old comments at "R" constraint.  Marking supposedly
  redundant constraints with FIXME:s.
- Removing the now-unused MMIX_REG_OK_STRICT macros.
- Using mmix_address_operand instead of address_operand in
  "mmix_symbolic_or_address_operand".
- Missing CL entry for mmix_emit_sp_add.  You thought nobody reads them? ;)

The redundant constraints and attempts to match const_double for
integer scalars is an artefact from olden times when large
integers (64 bits!) had to be modelled as const_doubles.
A clean-up for later.

Tested cross to mmix-knuth-mmixware and verified that the newlib libc and
libm, libgcc and libstdc++ were the same after this patch as before
(modulo a patch to fix "H"->"I" and the equivalent of the new
mmix_address_operand in mmix_symbolic_or_address_operand).

Committed.

	* config/mmix/mmix.h (MMIX_REG_OK_STRICT): Delete.
	(REG_CLASS_FROM_LETTER, CONST_OK_FOR_LETTER_P): Delete.
	(CONST_DOUBLE_OK_FOR_LETTER_P, EXTRA_CONSTRAINT): Delete.
	* config/mmix/mmix-protos.h (mmix_intval): Declare.
	(mmix_const_ok_for_letter_p, mmix_extra_constraint): Delete.
	(mmix_const_double_ok_for_letter_p): Delete.
	* config/mmix/constraints.md: New file.
	* config/mmix/mmix.md: Include it.
	(iordi3): Fix typo; use "I" instead of undefined "H" constraint.
	("*call_real"): Update comment about not using the "p" constraint.
	* config/mmix/predicates.md (mmix_reg_or_8bit_operand): Use
	satisfies_constraint_I.
	(mmix_address_operand): New predicate.
	(mmix_symbolic_or_address_operand): Use it instead of address_operand.
	* config/mmix/mmix.c: #include tm-constrs.h.
	(mmix_intval): Delete declaration.  Make non-static.
	(mmix_const_ok_for_letter_p, mmix_extra_constraint): Delete.
	(mmix_const_double_ok_for_letter_p): Delete.
	(mmix_legitimate_address_p): Use satisfies_constraint_I.
	(mmix_print_operand_address): Likewise.
	(mmix_emit_sp_add): Adjust to use insn_const_int_ok_for_constraint
	when matching "L" constraint.


brgds, H-P

Comments

Nathan Froyd Sept. 12, 2012, 8:56 a.m. UTC | #1
----- Original Message -----
> Nathan, again thanks.  There are a few minor tweaks compared to your
> version:

Thanks for fixing this up!

> - Keeping old layout of "mmix_reg_or_8bit_operand".  That looked like
>   a spurious change and I prefer the ior construct to the
>   if_then_else.

ISTR without this change, there were lots of assembly changes like:

    set rx, 6
    cmp rz, ry, rx

instead of the previous and better:

    cmp rz, ry, 6

(apologies if the assembly syntax isn't correct; hopefully the intent is clear)

but if you double-checked that the assembly didn't change after your changes, maybe something else that you tweaked fixed this.

> - Replacing undefined-constraint-"H" with "I" instead of removing it.
>   It was either renamed early or a genuine typo.  Good catch.

Hard not to see it; the gen* machinery complains about undefined constraints. :)

-Nathan
diff mbox

Patch

Index: gcc/config/mmix/mmix.h
===================================================================
--- gcc/config/mmix/mmix.h	(revision 190682)
+++ gcc/config/mmix/mmix.h	(working copy)
@@ -72,12 +72,6 @@  along with GCC; see the file COPYING3.
    untouched by the epilogue".  */
 #define MMIX_EH_RETURN_STACKADJ_REGNUM MMIX_STATIC_CHAIN_REGNUM

-#ifdef REG_OK_STRICT
-# define MMIX_REG_OK_STRICT 1
-#else
-# define MMIX_REG_OK_STRICT 0
-#endif
-
 #define MMIX_FUNCTION_ARG_SIZE(MODE, TYPE) \
  ((MODE) != BLKmode ? GET_MODE_SIZE (MODE) : int_size_in_bytes (TYPE))

@@ -439,11 +433,6 @@  enum reg_class

 #define INDEX_REG_CLASS GENERAL_REGS

-#define REG_CLASS_FROM_LETTER(CHAR)		\
- ((CHAR) == 'x' ? SYSTEM_REGS			\
-  : (CHAR) == 'y' ? REMAINDER_REG		\
-  : (CHAR) == 'z' ? HIMULT_REG : NO_REGS)
-
 #define REGNO_OK_FOR_BASE_P(REGNO)				\
  ((REGNO) <= MMIX_LAST_GENERAL_REGISTER				\
   || (REGNO) == MMIX_ARG_POINTER_REGNUM				\
@@ -460,16 +449,6 @@  enum reg_class

 #define CLASS_MAX_NREGS(CLASS, MODE) HARD_REGNO_NREGS (CLASS, MODE)

-#define CONST_OK_FOR_LETTER_P(VALUE, C)	\
- mmix_const_ok_for_letter_p (VALUE, C)
-
-#define EXTRA_CONSTRAINT(VALUE, C)	\
- mmix_extra_constraint (VALUE, C, MMIX_REG_OK_STRICT)
-
-/* Do we need anything serious here?  Yes, any FLOT constant.  */
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)			\
- mmix_const_double_ok_for_letter_p (VALUE, C)
-

 /* Node: Frame Layout */

Index: gcc/config/mmix/predicates.md
===================================================================
--- gcc/config/mmix/predicates.md	(revision 190682)
+++ gcc/config/mmix/predicates.md	(working copy)
@@ -118,7 +118,7 @@  (define_predicate "mmix_symbolic_or_addr
 	return 1;
       /* Fall through.  */
     default:
-      return address_operand (op, mode);
+      return mmix_address_operand (op, mode);
     }
 })

@@ -152,4 +152,12 @@  (define_predicate "mmix_reg_or_8bit_oper
   (ior
    (match_operand 0 "register_operand")
    (and (match_code "const_int")
-	(match_test "CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')"))))
+	(match_test "satisfies_constraint_I (op)"))))
+
+;; True if this is a memory address, possibly strictly.
+;; See also comment above the "*call_real" pattern.
+
+(define_predicate "mmix_address_operand"
+  (if_then_else (match_test "reload_in_progress || reload_completed")
+    (match_test "strict_memory_address_p (Pmode, op)")
+    (match_test "memory_address_p (Pmode, op)")))
Index: gcc/config/mmix/mmix-protos.h
===================================================================
--- gcc/config/mmix/mmix-protos.h	(revision 190682)
+++ gcc/config/mmix/mmix-protos.h	(working copy)
@@ -40,6 +40,7 @@  extern void mmix_asm_output_reg_push (FI
 extern void mmix_asm_output_reg_pop (FILE *, int);
 extern void mmix_asm_output_skip (FILE *, int);
 extern void mmix_asm_output_align (FILE *, int);
+extern HOST_WIDEST_INT mmix_intval (const_rtx);
 extern int mmix_shiftable_wyde_value (unsigned HOST_WIDEST_INT);
 extern void mmix_output_register_setting (FILE *, int, HOST_WIDEST_INT, int);
 extern int mmix_opposite_regno (int, int);
@@ -59,9 +60,6 @@  extern void mmix_asm_output_addr_diff_el
 extern void mmix_asm_output_addr_vec_elt (FILE *, int);
 extern enum reg_class mmix_secondary_reload_class
   (enum reg_class, enum machine_mode, rtx, int);
-extern int mmix_const_ok_for_letter_p (HOST_WIDE_INT, int);
-extern int mmix_const_double_ok_for_letter_p (rtx, int);
-extern int mmix_extra_constraint (rtx, int, int);
 extern rtx mmix_dynamic_chain_address (rtx);
 extern rtx mmix_return_addr_rtx (int, rtx);
 extern rtx mmix_eh_return_stackadj_rtx (void);
Index: gcc/config/mmix/constraints.md
===================================================================
--- gcc/config/mmix/constraints.md	(revision 0)
+++ gcc/config/mmix/constraints.md	(revision 0)
@@ -0,0 +1,112 @@ 
+;; MMIX 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 "x" "SYSTEM_REGS"
+  "@internal")
+
+(define_register_constraint "y" "REMAINDER_REG"
+  "@internal")
+
+(define_register_constraint "z" "HIMULT_REG"
+  "@internal")
+
+(define_constraint "I"
+  "A 8-bit unsigned integer"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, 0, 255)")))
+
+(define_constraint "J"
+  "A 16-bit unsigned integer."
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, 0, 65535)")))
+
+(define_constraint "K"
+  "An integer between -255 and 0."
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, -255, 0)")))
+
+(define_constraint "L"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "mmix_shiftable_wyde_value (ival)")))
+
+(define_constraint "M"
+  "The value 0."
+  (and (match_code "const_int")
+       (match_test "ival == 0")))
+
+(define_constraint "N"
+  "@internal"
+  (and (match_code "const_int")
+       (match_test "mmix_shiftable_wyde_value (~ival)")))
+
+(define_constraint "O"
+  "The value 3, 5, 9, or 17."
+  (and (match_code "const_int")
+       (ior (match_test "ival == 3")
+	    (match_test "ival == 5")
+	    (match_test "ival == 9")
+	    (match_test "ival == 17"))))
+
+;; FIXME: M (or G) is redundant.
+
+(define_constraint "G"
+  "Floating-point zero."
+  (and (match_code "const_double")
+       (match_test "op == CONST0_RTX (mode)")))
+
+;; R asks whether x is to be loaded with GETA or something else.  Right
+;; now, only a SYMBOL_REF and LABEL_REF can fit for
+;; TARGET_BASE_ADDRESSES.
+;;
+;; Only constant symbolic addresses apply.  With TARGET_BASE_ADDRESSES,
+;; we just allow straight LABEL_REF or SYMBOL_REFs with SYMBOL_REF_FLAG
+;; set right now; only function addresses and code labels.  If we change
+;; to let SYMBOL_REF_FLAG be set on other symbols, we have to check
+;; inside CONST expressions.  When TARGET_BASE_ADDRESSES is not in
+;; effect, a "raw" constant check together with mmix_constant_address_p
+;; is all that's needed; we want all constant addresses to be loaded
+;; with GETA then.
+
+(define_constraint "R"
+  "@internal"
+  (and (not (match_code "const_int,const_double"))
+       (match_test "mmix_constant_address_p (op)")
+       (ior (match_test "!TARGET_BASE_ADDRESSES")
+	    (match_code "LABEL_REF")
+	    (and (match_code "SYMBOL_REF")
+		 (match_test "SYMBOL_REF_FLAG (op)")))))
+
+;; FIXME: L (or S) is redundant.
+
+(define_constraint "S"
+  "@internal"
+  (and (match_code "const_int,const_double")
+       (match_test "mmix_shiftable_wyde_value (mmix_intval (op))")))
+
+;; FIXME: N (or T) is redundant.
+
+(define_constraint "T"
+  "@internal"
+  (and (match_code "const_int,const_double")
+       (match_test "mmix_shiftable_wyde_value (~mmix_intval (op))")))
+
+(define_address_constraint "U"
+  "@internal"
+  (match_operand 0 "mmix_address_operand"))
Index: gcc/config/mmix/mmix.md
===================================================================
--- gcc/config/mmix/mmix.md	(revision 190682)
+++ gcc/config/mmix/mmix.md	(working copy)
@@ -43,6 +43,7 @@  (define_constants
 ;; Operand and operator predicates.

 (include "predicates.md")
+(include "constraints.md")

 ;; FIXME: Can we remove the reg-to-reg for smaller modes?  Shouldn't they
 ;; be synthesized ok?
@@ -274,7 +275,7 @@  (define_insn "anddi3"
 (define_insn "iordi3"
   [(set (match_operand:DI 0 "register_operand" "=r,r")
 	(ior:DI (match_operand:DI 1 "register_operand" "%r,0")
-		(match_operand:DI 2 "mmix_reg_or_constant_operand" "rH,LS")))]
+		(match_operand:DI 2 "mmix_reg_or_constant_operand" "rI,LS")))]
   ""
   "@
    OR %0,%1,%2
@@ -1037,6 +1038,7 @@  (define_expand "call_value"
 ;; first ("p") alternative by adding ? in the first operand
 ;; might do the trick.  We define 'U' as a synonym to 'p', but without the
 ;; caveats (and very small advantages) of 'p'.
+;; As of r190682 still so: newlib/libc/stdlib/dtoa.c ICEs if "p" is used.
 (define_insn "*call_real"
   [(call (mem:QI
 	  (match_operand:DI 0 "mmix_symbolic_or_address_operand" "s,rU"))
Index: gcc/config/mmix/mmix.c
===================================================================
--- gcc/config/mmix/mmix.c	(revision 190682)
+++ gcc/config/mmix/mmix.c	(working copy)
@@ -44,6 +44,7 @@  along with GCC; see the file COPYING3.
 #include "target.h"
 #include "target-def.h"
 #include "df.h"
+#include "tm-constrs.h"

 /* First some local helper definitions.  */
 #define MMIX_FIRST_GLOBAL_REGNUM 32
@@ -118,7 +119,6 @@  static void mmix_output_shiftvalue_op_fr
   (FILE *, const char *, HOST_WIDEST_INT);
 static void mmix_output_shifted_value (FILE *, HOST_WIDEST_INT);
 static void mmix_output_condition (FILE *, const_rtx, int);
-static HOST_WIDEST_INT mmix_intval (const_rtx);
 static void mmix_output_octa (FILE *, HOST_WIDEST_INT, int);
 static bool mmix_assemble_integer (rtx, unsigned int, int);
 static struct machine_function *mmix_init_machine_status (void);
@@ -459,87 +459,6 @@  mmix_secondary_reload_class (enum reg_cl
   return NO_REGS;
 }

-/* CONST_OK_FOR_LETTER_P.  */
-
-int
-mmix_const_ok_for_letter_p (HOST_WIDE_INT value, int c)
-{
-  return
-    (c == 'I' ? value >= 0 && value <= 255
-     : c == 'J' ? value >= 0 && value <= 65535
-     : c == 'K' ? value <= 0 && value >= -255
-     : c == 'L' ? mmix_shiftable_wyde_value (value)
-     : c == 'M' ? value == 0
-     : c == 'N' ? mmix_shiftable_wyde_value (~value)
-     : c == 'O' ? (value == 3 || value == 5 || value == 9
-		   || value == 17)
-     : 0);
-}
-
-/* CONST_DOUBLE_OK_FOR_LETTER_P.  */
-
-int
-mmix_const_double_ok_for_letter_p (rtx value, int c)
-{
-  return
-    (c == 'G' ? value == CONST0_RTX (GET_MODE (value))
-     : 0);
-}
-
-/* EXTRA_CONSTRAINT.
-   We need this since our constants are not always expressible as
-   CONST_INT:s, but rather often as CONST_DOUBLE:s.  */
-
-int
-mmix_extra_constraint (rtx x, int c, int strict)
-{
-  HOST_WIDEST_INT value;
-
-  /* When checking for an address, we need to handle strict vs. non-strict
-     register checks.  Don't use address_operand, but instead its
-     equivalent (its callee, which it is just a wrapper for),
-     memory_operand_p and the strict-equivalent strict_memory_address_p.  */
-  if (c == 'U')
-    return
-      strict
-      ? strict_memory_address_p (Pmode, x)
-      : memory_address_p (Pmode, x);
-
-  /* R asks whether x is to be loaded with GETA or something else.  Right
-     now, only a SYMBOL_REF and LABEL_REF can fit for
-     TARGET_BASE_ADDRESSES.
-
-     Only constant symbolic addresses apply.  With TARGET_BASE_ADDRESSES,
-     we just allow straight LABEL_REF or SYMBOL_REFs with SYMBOL_REF_FLAG
-     set right now; only function addresses and code labels.  If we change
-     to let SYMBOL_REF_FLAG be set on other symbols, we have to check
-     inside CONST expressions.  When TARGET_BASE_ADDRESSES is not in
-     effect, a "raw" constant check together with mmix_constant_address_p
-     is all that's needed; we want all constant addresses to be loaded
-     with GETA then.  */
-  if (c == 'R')
-    return
-      GET_CODE (x) != CONST_INT && GET_CODE (x) != CONST_DOUBLE
-      && mmix_constant_address_p (x)
-      && (! TARGET_BASE_ADDRESSES
-	  || (GET_CODE (x) == LABEL_REF
-	      || (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FLAG (x))));
-
-  if (GET_CODE (x) != CONST_DOUBLE || GET_MODE (x) != VOIDmode)
-    return 0;
-
-  value = mmix_intval (x);
-
-  /* We used to map Q->J, R->K, S->L, T->N, U->O, but we don't have to any
-     more ('U' taken for address_operand, 'R' similarly).  Some letters map
-     outside of CONST_INT, though; we still use 'S' and 'T'.  */
-  if (c == 'S')
-    return mmix_shiftable_wyde_value (value);
-  else if (c == 'T')
-    return mmix_shiftable_wyde_value (~value);
-  return 0;
-}
-
 /* DYNAMIC_CHAIN_ADDRESS.  */

 rtx
@@ -1161,8 +1080,7 @@  mmix_legitimate_address_p (enum machine_
 	return 1;

       /* (mem (plus (reg) (0..255?))) */
-      if (GET_CODE (x2) == CONST_INT
-	  && CONST_OK_FOR_LETTER_P (INTVAL (x2), 'I'))
+      if (satisfies_constraint_I (x2))
 	return 1;

       return 0;
@@ -1843,8 +1761,7 @@  mmix_print_operand_address (FILE *stream
 		       reg_names[MMIX_OUTPUT_REGNO (REGNO (x2))]);
 	      return;
 	    }
-	  else if (GET_CODE (x2) == CONST_INT
-		   && CONST_OK_FOR_LETTER_P (INTVAL (x2), 'I'))
+	  else if (satisfies_constraint_I (x2))
 	    {
 	      output_addr_const (stream, x2);
 	      return;
@@ -2529,7 +2446,7 @@  mmix_emit_sp_add (HOST_WIDE_INT offset)
     {
       /* Positive adjustments are in the epilogue only.  Don't mark them
 	 as "frame-related" for unwind info.  */
-      if (CONST_OK_FOR_LETTER_P (offset, 'L'))
+      if (insn_const_int_ok_for_constraint (offset, CONSTRAINT_L))
 	emit_insn (gen_adddi3 (stack_pointer_rtx,
 			       stack_pointer_rtx,
 			       GEN_INT (offset)));
@@ -2754,7 +2671,7 @@  mmix_output_condition (FILE *stream, con

 /* Return the bit-value for a const_int or const_double.  */

-static HOST_WIDEST_INT
+HOST_WIDEST_INT
 mmix_intval (const_rtx x)
 {
   unsigned HOST_WIDEST_INT retval;