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]

Use predicates.md for Xtensa


I committed this patch on mainline. I started with Kazu Hirata's scripts to create predicates.md but then rewrote most of the predicates in Lisp-style syntax. I also cleaned up the similar predicate functions for checking immediate ranges, and I moved the code for CONST_OK_FOR_LETTER_P and EXTRA_CONSTRAINT into functions in xtensa.c. These changes do not appear to cause any testsuite regressions for Xtensa.

2005-03-21 Bob Wilson <bob.wilson@acm.org>

	* config/xtensa/xtensa-protos.h: (xtensa_simm7, xtensa_uimm8,
	xtensa_uimm8x2, xtensa_uimm8x4, xtensa_ai4const, xtensa_lsi4x4,
	xtensa_b4const): Delete prototypes.
	(xtensa_simm8, xtensa_simm8x256, xtensa_simm12b, xtensa_b4constu,
	xtensa_mask_immediate, xtensa_mem_offset): Update prototypes.
	(xtensa_b4const_or_zero, xtensa_const_ok_for_letter_p,
	xtensa_extra_constraint): New prototypes.
	(add_operand, arith_operand, nonimmed_operand, mem_operand,
	mask_operand, extui_fldsz_operand, sext_operand, sext_fldsz_operand,
	lsbitnum_operand, branch_operand, ubranch_operand, call_insn_operand,
	move_operand, const_float_1_operand, fpmem_offset_operand,
	branch_operator, ubranch_operator, boolean_operator): Delete prototypes.
	* config/xtensa/xtensa.c (b4const_or_zero): Rename to ...
	(xtensa_b4const_or_zero): ...this.  Change return type to bool and
	argument type to HOST_WIDE_INT.
	(xtensa_simm8, xtensa_simm8x256, xtensa_simm12b,
	xtensa_mask_immediate): Likewise.
	(xtensa_uimm8, xtensa_uimm8x2, xtensa_uimm8x4, xtensa_b4const):
	Likewise.  Also make these functions static.
	(xtensa_simm7, xtensa_ai4const, xtensa_lsi4x4): Delete.
	(xtensa_const_ok_for_letter_p): New.
	(add_operand, arith_operand, nonimmed_operand, mem_operand,
	mask_operand, extui_fldsz_operand, sext_operand, sext_fldsz_operand,
	lsbitnum_operand, branch_operand, ubranch_operand, call_insn_operand,
	move_operand, const_float_1_operand, fpmem_offset_operand,
	branch_operator, ubranch_operator, boolean_operator): Move to
	predicates.md.
	(smalloffset_mem_p): Inline code from xtensa_lsi4x4.
	(xtensa_mem_offset): Change return type to bool.
	(xtensa_extra_constraint): New.
	(gen_int_relational): Update type of const_range_p function pointer.
	Use xtensa_b4const_or_zero.
	* config/xtensa/xtensa.h (CONST_OK_FOR_LETTER_P): Define to
	xtensa_const_ok_for_letter_p.  Update comments.
	(EXTRA_CONSTRAINT): Define to xtensa_extra_constraint.
	(PREDICATE_CODES): Delete.
	* config/xtensa/xtensa.md: Include predicates.md.
	* config/xtensa/predicates.md: New file.

Index: gcc/config/xtensa/xtensa-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/xtensa/xtensa-protos.h,v
retrieving revision 1.18
diff -u -p -r1.18 xtensa-protos.h
--- gcc/config/xtensa/xtensa-protos.h	19 Aug 2004 06:12:11 -0000	1.18
+++ gcc/config/xtensa/xtensa-protos.h	21 Mar 2005 17:20:05 -0000
@@ -1,5 +1,5 @@
 /* Prototypes of target machine for GNU compiler for Xtensa.
-   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
 
 This file is part of GCC.
@@ -23,45 +23,24 @@ Software Foundation, 59 Temple Place - S
 #define __XTENSA_PROTOS_H__
 
 /* Functions to test whether an immediate fits in a given field.  */
-extern int xtensa_simm7 (int);
-extern int xtensa_simm8 (int);
-extern int xtensa_simm8x256 (int);
-extern int xtensa_simm12b (int);
-extern int xtensa_uimm8 (int);
-extern int xtensa_uimm8x2 (int);
-extern int xtensa_uimm8x4 (int);
-extern int xtensa_ai4const (int);
-extern int xtensa_lsi4x4 (int);
-extern int xtensa_b4const (int);
-extern int xtensa_b4constu (int);
-extern int xtensa_tp7 (int);
+extern bool xtensa_simm8 (HOST_WIDE_INT);
+extern bool xtensa_simm8x256 (HOST_WIDE_INT);
+extern bool xtensa_simm12b (HOST_WIDE_INT);
+extern bool xtensa_b4const_or_zero (HOST_WIDE_INT);
+extern bool xtensa_b4constu (HOST_WIDE_INT);
+extern bool xtensa_mask_immediate (HOST_WIDE_INT);
+extern bool xtensa_const_ok_for_letter_p (HOST_WIDE_INT, int);
+extern bool xtensa_mem_offset (unsigned, enum machine_mode);
 
 /* Functions within xtensa.c that we reference.  */
 #ifdef RTX_CODE
 extern int xt_true_regnum (rtx);
-extern int add_operand (rtx, enum machine_mode);
-extern int arith_operand (rtx, enum machine_mode);
-extern int nonimmed_operand (rtx, enum machine_mode);
-extern int mem_operand (rtx, enum machine_mode);
 extern int xtensa_valid_move (enum machine_mode, rtx *);
-extern int mask_operand (rtx, enum machine_mode);
-extern int extui_fldsz_operand (rtx, enum machine_mode);
-extern int sext_operand (rtx, enum machine_mode);
-extern int sext_fldsz_operand (rtx, enum machine_mode);
-extern int lsbitnum_operand (rtx, enum machine_mode);
-extern int branch_operand (rtx, enum machine_mode);
-extern int ubranch_operand (rtx, enum machine_mode);
-extern int call_insn_operand (rtx, enum machine_mode);
-extern int move_operand (rtx, enum machine_mode);
 extern int smalloffset_mem_p (rtx);
 extern int constantpool_address_p (rtx);
 extern int constantpool_mem_p (rtx);
-extern int const_float_1_operand (rtx, enum machine_mode);
-extern int fpmem_offset_operand (rtx, enum machine_mode);
 extern void xtensa_extend_reg (rtx, rtx);
-extern int branch_operator (rtx, enum machine_mode);
-extern int ubranch_operator (rtx, enum machine_mode);
-extern int boolean_operator (rtx, enum machine_mode);
+extern bool xtensa_extra_constraint (rtx, int);
 extern void xtensa_expand_conditional_branch (rtx *, enum rtx_code);
 extern int xtensa_expand_conditional_move (rtx *, int);
 extern int xtensa_expand_scc (rtx *);
@@ -94,8 +73,6 @@ extern struct rtx_def *function_arg (CUM
 				     tree, int);
 #endif /* TREE_CODE */
 
-extern int xtensa_mask_immediate (int);
-extern int xtensa_mem_offset (unsigned, enum machine_mode);
 extern void xtensa_setup_frame_addresses (void);
 extern int xtensa_dbx_register_number (int);
 extern void override_options (void);
Index: gcc/config/xtensa/xtensa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/xtensa/xtensa.c,v
retrieving revision 1.70
diff -u -p -r1.70 xtensa.c
--- gcc/config/xtensa/xtensa.c	26 Aug 2004 17:08:10 -0000	1.70
+++ gcc/config/xtensa/xtensa.c	21 Mar 2005 17:20:06 -0000
@@ -1,5 +1,5 @@
 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
-   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
 
 This file is part of GCC.
@@ -192,7 +192,6 @@ enum reg_class xtensa_char_to_class[256]
   NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
 };
 
-static int b4const_or_zero (int);
 static enum internal_test map_test_to_internal_test (enum rtx_code);
 static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *);
 static rtx gen_float_relational (enum rtx_code, rtx, rtx);
@@ -270,13 +269,55 @@ struct gcc_target targetm = TARGET_INITI
  * Functions to test Xtensa immediate operand validity.
  */
 
-int
-xtensa_b4constu (int v)
+bool
+xtensa_simm8 (HOST_WIDE_INT v)
+{
+  return v >= -128 && v <= 127;
+}
+
+
+bool
+xtensa_simm8x256 (HOST_WIDE_INT v)
+{
+  return (v & 255) == 0 && (v >= -32768 && v <= 32512);
+}
+
+
+bool
+xtensa_simm12b (HOST_WIDE_INT v)
+{
+  return v >= -2048 && v <= 2047;
+}
+
+
+static bool
+xtensa_uimm8 (HOST_WIDE_INT v)
+{
+  return v >= 0 && v <= 255;
+}
+
+
+static bool
+xtensa_uimm8x2 (HOST_WIDE_INT v)
+{
+  return (v & 1) == 0 && (v >= 0 && v <= 510);
+}
+
+
+static bool
+xtensa_uimm8x4 (HOST_WIDE_INT v)
+{
+  return (v & 3) == 0 && (v >= 0 && v <= 1020);
+}
+
+
+static bool
+xtensa_b4const (HOST_WIDE_INT v)
 {
   switch (v)
     {
-    case 32768:
-    case 65536:
+    case -1:
+    case 1:
     case 2:
     case 3:
     case 4:
@@ -291,36 +332,28 @@ xtensa_b4constu (int v)
     case 64:
     case 128:
     case 256:
-      return 1;
+      return true;
     }
-  return 0;
+  return false;
 }
 
-int
-xtensa_simm8x256 (int v)
-{
-  return (v & 255) == 0 && (v >= -32768 && v <= 32512);
-}
 
-int
-xtensa_ai4const (int v)
+bool
+xtensa_b4const_or_zero (HOST_WIDE_INT v)
 {
-  return (v == -1 || (v >= 1 && v <= 15));
+  if (v == 0)
+    return true;
+  return xtensa_b4const (v);
 }
 
-int
-xtensa_simm7 (int v)
-{
-  return v >= -32 && v <= 95;
-}
 
-int
-xtensa_b4const (int v)
+bool
+xtensa_b4constu (HOST_WIDE_INT v)
 {
   switch (v)
     {
-    case -1:
-    case 1:
+    case 32768:
+    case 65536:
     case 2:
     case 3:
     case 4:
@@ -335,51 +368,47 @@ xtensa_b4const (int v)
     case 64:
     case 128:
     case 256:
-      return 1;
+      return true;
     }
-  return 0;
+  return false;
 }
 
-int
-xtensa_simm8 (int v)
-{
-  return v >= -128 && v <= 127;
-}
-
-int
-xtensa_tp7 (int v)
-{
-  return (v >= 7 && v <= 22);
-}
 
-int
-xtensa_lsi4x4 (int v)
+bool
+xtensa_mask_immediate (HOST_WIDE_INT v)
 {
-  return (v & 3) == 0 && (v >= 0 && v <= 60);
-}
+#define MAX_MASK_SIZE 16
+  int mask_size;
 
-int
-xtensa_simm12b (int v)
-{
-  return v >= -2048 && v <= 2047;
-}
+  for (mask_size = 1; mask_size <= MAX_MASK_SIZE; mask_size++)
+    {
+      if ((v & 1) == 0)
+	return false;
+      v = v >> 1;
+      if (v == 0)
+	return true;
+    }
 
-int
-xtensa_uimm8 (int v)
-{
-  return v >= 0 && v <= 255;
+  return false;
 }
 
-int
-xtensa_uimm8x2 (int v)
-{
-  return (v & 1) == 0 && (v >= 0 && v <= 510);
-}
 
-int
-xtensa_uimm8x4 (int v)
+bool
+xtensa_const_ok_for_letter_p (HOST_WIDE_INT v, int c)
 {
-  return (v & 3) == 0 && (v >= 0 && v <= 1020);
+  switch (c)
+    {
+    case 'I': return xtensa_simm12b (v);
+    case 'J': return xtensa_simm8 (v);
+    case 'K': return (v == 0 || xtensa_b4const (v));
+    case 'L': return xtensa_b4constu (v);
+    case 'M': return (v >= -32 && v <= 95);
+    case 'N': return xtensa_simm8x256 (v);
+    case 'O': return (v == -1 || (v >= 1 && v <= 15));
+    case 'P': return xtensa_mask_immediate (v);
+    default: break;
+    }
+  return false;
 }
 
 
@@ -410,52 +439,6 @@ xt_true_regnum (rtx x)
 
 
 int
-add_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == CONST_INT)
-    return (xtensa_simm8 (INTVAL (op)) || xtensa_simm8x256 (INTVAL (op)));
-
-  return register_operand (op, mode);
-}
-
-
-int
-arith_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == CONST_INT)
-    return xtensa_simm8 (INTVAL (op));
-
-  return register_operand (op, mode);
-}
-
-
-int
-nonimmed_operand (rtx op, enum machine_mode mode)
-{
-  /* We cannot use the standard nonimmediate_operand() predicate because
-     it includes constant pool memory operands.  */
-
-  if (memory_operand (op, mode))
-    return !constantpool_address_p (XEXP (op, 0));
-
-  return register_operand (op, mode);
-}
-
-
-int
-mem_operand (rtx op, enum machine_mode mode)
-{
-  /* We cannot use the standard memory_operand() predicate because
-     it includes constant pool memory operands.  */
-
-  if (memory_operand (op, mode))
-    return !constantpool_address_p (XEXP (op, 0));
-
-  return FALSE;
-}
-
-
-int
 xtensa_valid_move (enum machine_mode mode, rtx *operands)
 {
   /* Either the destination or source must be a register, and the
@@ -485,165 +468,6 @@ xtensa_valid_move (enum machine_mode mod
 
 
 int
-mask_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == CONST_INT)
-    return xtensa_mask_immediate (INTVAL (op));
-
-  return register_operand (op, mode);
-}
-
-
-int
-extui_fldsz_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return ((GET_CODE (op) == CONST_INT)
-	  && xtensa_mask_immediate ((1 << INTVAL (op)) - 1));
-}
-
-
-int
-sext_operand (rtx op, enum machine_mode mode)
-{
-  if (TARGET_SEXT)
-    return nonimmed_operand (op, mode);
-  return mem_operand (op, mode);
-}
-
-
-int
-sext_fldsz_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return ((GET_CODE (op) == CONST_INT) && xtensa_tp7 (INTVAL (op) - 1));
-}
-
-
-int
-lsbitnum_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (GET_CODE (op) == CONST_INT)
-    {
-      return (BITS_BIG_ENDIAN
-	      ? (INTVAL (op) == BITS_PER_WORD-1)
-	      : (INTVAL (op) == 0));
-    }
-  return FALSE;
-}
-
-
-static int
-b4const_or_zero (int v)
-{
-  if (v == 0)
-    return TRUE;
-  return xtensa_b4const (v);
-}
-
-
-int
-branch_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == CONST_INT)
-    return b4const_or_zero (INTVAL (op));
-
-  return register_operand (op, mode);
-}
-
-
-int
-ubranch_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == CONST_INT)
-    return xtensa_b4constu (INTVAL (op));
-
-  return register_operand (op, mode);
-}
-
-
-int
-call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if ((GET_CODE (op) == REG)
-      && (op != arg_pointer_rtx)
-      && ((REGNO (op) < FRAME_POINTER_REGNUM)
-	  || (REGNO (op) > LAST_VIRTUAL_REGISTER)))
-    return TRUE;
-
-  if (CONSTANT_ADDRESS_P (op))
-    {
-      /* Direct calls only allowed to static functions with PIC.  */
-      if (flag_pic)
-	{
-	  tree callee, callee_sec, caller_sec;
-
-	  if (GET_CODE (op) != SYMBOL_REF
-	      || !SYMBOL_REF_LOCAL_P (op) || SYMBOL_REF_EXTERNAL_P (op))
-	    return FALSE;
-
-	  /* Don't attempt a direct call if the callee is known to be in
-	     a different section, since there's a good chance it will be
-	     out of range.  */
-
-	  if (flag_function_sections
-	      || DECL_ONE_ONLY (current_function_decl))
-	    return FALSE;
-	  caller_sec = DECL_SECTION_NAME (current_function_decl);
-	  callee = SYMBOL_REF_DECL (op);
-	  if (callee)
-	    {
-	      if (DECL_ONE_ONLY (callee))
-		return FALSE;
-	      callee_sec = DECL_SECTION_NAME (callee);
-	      if (((caller_sec == NULL_TREE) ^ (callee_sec == NULL_TREE))
-		  || (caller_sec != NULL_TREE
-		      && strcmp (TREE_STRING_POINTER (caller_sec),
-				 TREE_STRING_POINTER (callee_sec)) != 0))
-		return FALSE;
-	    }
-	  else if (caller_sec != NULL_TREE)
-	    return FALSE;
-	}
-      return TRUE;
-    }
-
-  return FALSE;
-}
-
-
-int
-move_operand (rtx op, enum machine_mode mode)
-{
-  if (register_operand (op, mode)
-      || memory_operand (op, mode))
-    return TRUE;
-
-  switch (mode)
-    {
-    case DFmode:
-    case SFmode:
-      return TARGET_CONST16 && CONSTANT_P (op);
-
-    case DImode:
-    case SImode:
-      if (TARGET_CONST16)
-	return CONSTANT_P (op);
-      /* Fall through.  */
-
-    case HImode:
-    case QImode:
-      if (GET_CODE (op) == CONST_INT && xtensa_simm12b (INTVAL (op)))
-	return TRUE;
-      break;
-
-    default:
-      break;
-    }
-
-  return FALSE;
-}
-
-
-int
 smalloffset_mem_p (rtx op)
 {
   if (GET_CODE (op) == MEM)
@@ -654,11 +478,14 @@ smalloffset_mem_p (rtx op)
       if (GET_CODE (addr) == PLUS)
 	{
 	  rtx offset = XEXP (addr, 0);
+	  HOST_WIDE_INT val;
 	  if (GET_CODE (offset) != CONST_INT)
 	    offset = XEXP (addr, 1);
 	  if (GET_CODE (offset) != CONST_INT)
 	    return FALSE;
-	  return xtensa_lsi4x4 (INTVAL (offset));
+
+	  val = INTVAL (offset);
+	  return (val & 3) == 0 && (val >= 0 && val <= 60);
 	}
     }
   return FALSE;
@@ -704,46 +531,6 @@ constantpool_mem_p (rtx op)
 }
 
 
-/* Accept the floating point constant 1 in the appropriate mode.  */
-
-int
-const_float_1_operand (rtx op, enum machine_mode mode)
-{
-  REAL_VALUE_TYPE d;
-  static REAL_VALUE_TYPE onedf;
-  static REAL_VALUE_TYPE onesf;
-  static int one_initialized;
-
-  if ((GET_CODE (op) != CONST_DOUBLE)
-      || (mode != GET_MODE (op))
-      || (mode != DFmode && mode != SFmode))
-    return FALSE;
-
-  REAL_VALUE_FROM_CONST_DOUBLE (d, op);
-
-  if (! one_initialized)
-    {
-      onedf = REAL_VALUE_ATOF ("1.0", DFmode);
-      onesf = REAL_VALUE_ATOF ("1.0", SFmode);
-      one_initialized = TRUE;
-    }
-
-  if (mode == DFmode)
-    return REAL_VALUES_EQUAL (d, onedf);
-  else
-    return REAL_VALUES_EQUAL (d, onesf);
-}
-
-
-int
-fpmem_offset_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (GET_CODE (op) == CONST_INT)
-    return xtensa_mem_offset (INTVAL (op), SFmode);
-  return 0;
-}
-
-
 void
 xtensa_extend_reg (rtx dst, rtx src)
 {
@@ -759,82 +546,7 @@ xtensa_extend_reg (rtx dst, rtx src)
 }
 
 
-int
-branch_operator (rtx x, enum machine_mode mode)
-{
-  if (GET_MODE (x) != mode)
-    return FALSE;
-
-  switch (GET_CODE (x))
-    {
-    case EQ:
-    case NE:
-    case LT:
-    case GE:
-      return TRUE;
-    default:
-      break;
-    }
-  return FALSE;
-}
-
-
-int
-ubranch_operator (rtx x, enum machine_mode mode)
-{
-  if (GET_MODE (x) != mode)
-    return FALSE;
-
-  switch (GET_CODE (x))
-    {
-    case LTU:
-    case GEU:
-      return TRUE;
-    default:
-      break;
-    }
-  return FALSE;
-}
-
-
-int
-boolean_operator (rtx x, enum machine_mode mode)
-{
-  if (GET_MODE (x) != mode)
-    return FALSE;
-
-  switch (GET_CODE (x))
-    {
-    case EQ:
-    case NE:
-      return TRUE;
-    default:
-      break;
-    }
-  return FALSE;
-}
-
-
-int
-xtensa_mask_immediate (int v)
-{
-#define MAX_MASK_SIZE 16
-  int mask_size;
-
-  for (mask_size = 1; mask_size <= MAX_MASK_SIZE; mask_size++)
-    {
-      if ((v & 1) == 0)
-	return FALSE;
-      v = v >> 1;
-      if (v == 0)
-	return TRUE;
-    }
-
-  return FALSE;
-}
-
-
-int
+bool
 xtensa_mem_offset (unsigned v, enum machine_mode mode)
 {
   switch (mode)
@@ -865,6 +577,26 @@ xtensa_mem_offset (unsigned v, enum mach
 }
 
 
+bool
+xtensa_extra_constraint (rtx op, int c)
+{
+  /* Allow pseudo registers during reload.  */
+  if (GET_CODE (op) != MEM)
+    return (c >= 'R' && c <= 'U'
+	    && reload_in_progress && GET_CODE (op) == REG
+	    && REGNO (op) >= FIRST_PSEUDO_REGISTER);
+
+  switch (c)
+    {
+    case 'R': return smalloffset_mem_p (op);
+    case 'T': return !TARGET_CONST16 && constantpool_mem_p (op);
+    case 'U': return !constantpool_mem_p (op);
+    default: break;
+    }
+  return false;
+}
+
+
 /* Make normal rtx_code into something we can index from an array.  */
 
 static enum internal_test
@@ -903,7 +635,7 @@ gen_int_relational (enum rtx_code test_c
   struct cmp_info
   {
     enum rtx_code test_code;	/* test code to use in insn */
-    int (*const_range_p) (int);	/* predicate function to check range */
+    bool (*const_range_p) (HOST_WIDE_INT); /* range check function */
     int const_add;		/* constant to add (convert LE -> LT) */
     int reverse_regs;		/* reverse registers in test */
     int invert_const;		/* != 0 if invert value if cmp1 is constant */
@@ -913,13 +645,13 @@ gen_int_relational (enum rtx_code test_c
 
   static struct cmp_info info[ (int)ITEST_MAX ] = {
 
-    { EQ,	b4const_or_zero,	0, 0, 0, 0, 0 },	/* EQ  */
-    { NE,	b4const_or_zero,	0, 0, 0, 0, 0 },	/* NE  */
+    { EQ,	xtensa_b4const_or_zero,	0, 0, 0, 0, 0 },	/* EQ  */
+    { NE,	xtensa_b4const_or_zero,	0, 0, 0, 0, 0 },	/* NE  */
 
-    { LT,	b4const_or_zero,	1, 1, 1, 0, 0 },	/* GT  */
-    { GE,	b4const_or_zero,	0, 0, 0, 0, 0 },	/* GE  */
-    { LT,	b4const_or_zero,	0, 0, 0, 0, 0 },	/* LT  */
-    { GE,	b4const_or_zero,	1, 1, 1, 0, 0 },	/* LE  */
+    { LT,	xtensa_b4const_or_zero,	1, 1, 1, 0, 0 },	/* GT  */
+    { GE,	xtensa_b4const_or_zero,	0, 0, 0, 0, 0 },	/* GE  */
+    { LT,	xtensa_b4const_or_zero,	0, 0, 0, 0, 0 },	/* LT  */
+    { GE,	xtensa_b4const_or_zero,	1, 1, 1, 0, 0 },	/* LE  */
 
     { LTU,	xtensa_b4constu,	1, 1, 1, 0, 1 },	/* GTU */
     { GEU,	xtensa_b4constu,	0, 0, 0, 0, 1 },	/* GEU */
Index: gcc/config/xtensa/xtensa.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/xtensa/xtensa.h,v
retrieving revision 1.63
diff -u -p -r1.63 xtensa.h
--- gcc/config/xtensa/xtensa.h	12 Mar 2005 00:34:07 -0000	1.63
+++ gcc/config/xtensa/xtensa.h	21 Mar 2005 17:20:06 -0000
@@ -545,29 +545,16 @@ extern enum reg_class xtensa_char_to_cla
 
    For Xtensa:
 
-   I = 12-bit signed immediate for movi
-   J = 8-bit signed immediate for addi
+   I = 12-bit signed immediate for MOVI
+   J = 8-bit signed immediate for ADDI
    K = 4-bit value in (b4const U {0})
    L = 4-bit value in b4constu
-   M = 7-bit value in simm7
-   N = 8-bit unsigned immediate shifted left by 8 bits for addmi
-   O = 4-bit value in ai4const
-   P = valid immediate mask value for extui */
-
-#define CONST_OK_FOR_LETTER_P(VALUE, C)					\
-  ((C) == 'I' ? (xtensa_simm12b (VALUE))				\
-   : (C) == 'J' ? (xtensa_simm8 (VALUE))				\
-   : (C) == 'K' ? (((VALUE) == 0) || xtensa_b4const (VALUE))		\
-   : (C) == 'L' ? (xtensa_b4constu (VALUE))				\
-   : (C) == 'M' ? (xtensa_simm7 (VALUE))				\
-   : (C) == 'N' ? (xtensa_simm8x256 (VALUE))				\
-   : (C) == 'O' ? (xtensa_ai4const (VALUE))				\
-   : (C) == 'P' ? (xtensa_mask_immediate (VALUE))			\
-   : FALSE)
+   M = 7-bit immediate value for MOVI.N
+   N = 8-bit unsigned immediate shifted left by 8 bits for ADDMI
+   O = 4-bit immediate for ADDI.N
+   P = valid immediate mask value for EXTUI */
 
-
-/* Similar, but for floating constants, and defining letters G and H.
-   Here VALUE is the CONST_DOUBLE rtx itself.  */
+#define CONST_OK_FOR_LETTER_P  xtensa_const_ok_for_letter_p
 #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) (0)
 
 
@@ -591,15 +578,7 @@ extern enum reg_class xtensa_char_to_cla
    address will be checked anyway because of the code in
    GO_IF_LEGITIMATE_ADDRESS.  */
 
-#define EXTRA_CONSTRAINT(OP, CODE)					\
-  ((GET_CODE (OP) != MEM) ?						\
-       ((CODE) >= 'R' && (CODE) <= 'U'					\
-	&& reload_in_progress && GET_CODE (OP) == REG			\
-        && REGNO (OP) >= FIRST_PSEUDO_REGISTER)				\
-   : ((CODE) == 'R') ? smalloffset_mem_p (OP)				\
-   : ((CODE) == 'T') ? !TARGET_CONST16 && constantpool_mem_p (OP)	\
-   : ((CODE) == 'U') ? !constantpool_mem_p (OP)				\
-   : FALSE)
+#define EXTRA_CONSTRAINT  xtensa_extra_constraint
 
 #define PREFERRED_RELOAD_CLASS(X, CLASS)				\
   xtensa_preferred_reload_class (X, CLASS, 0)
@@ -1149,37 +1128,6 @@ typedef struct xtensa_args
 
 #define BRANCH_COST 3
 
-/* Optionally define this if you have added predicates to
-   'MACHINE.c'.  This macro is called within an initializer of an
-   array of structures.  The first field in the structure is the
-   name of a predicate and the second field is an array of rtl
-   codes.  For each predicate, list all rtl codes that can be in
-   expressions matched by the predicate.  The list should have a
-   trailing comma.  */
-
-#define PREDICATE_CODES							\
-  {"add_operand",		{ REG, CONST_INT, SUBREG }},		\
-  {"arith_operand",		{ REG, CONST_INT, SUBREG }},		\
-  {"nonimmed_operand",		{ REG, SUBREG, MEM }},			\
-  {"mem_operand",		{ MEM }},				\
-  {"mask_operand",		{ REG, CONST_INT, SUBREG }},		\
-  {"extui_fldsz_operand",	{ CONST_INT }},				\
-  {"sext_fldsz_operand",	{ CONST_INT }},				\
-  {"lsbitnum_operand",		{ CONST_INT }},				\
-  {"fpmem_offset_operand",	{ CONST_INT }},				\
-  {"sext_operand",		{ REG, SUBREG, MEM }},			\
-  {"branch_operand",		{ REG, CONST_INT, SUBREG }},		\
-  {"ubranch_operand",		{ REG, CONST_INT, SUBREG }},		\
-  {"call_insn_operand",		{ CONST_INT, CONST, SYMBOL_REF, REG }},	\
-  {"move_operand",		{ REG, SUBREG, MEM, CONST_INT, CONST_DOUBLE, \
-				  CONST, SYMBOL_REF, LABEL_REF }},	\
-  {"const_float_1_operand",	{ CONST_DOUBLE }},			\
-  {"branch_operator",		{ EQ, NE, LT, GE }},			\
-  {"ubranch_operator",		{ LTU, GEU }},				\
-  {"boolean_operator",		{ EQ, NE }},
-
-/* Control the assembler format that we output.  */
-
 /* How to refer to registers in assembler output.
    This sequence is indexed by compiler's hard-register-number (see above).  */
 #define REGISTER_NAMES							\
Index: gcc/config/xtensa/xtensa.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/xtensa/xtensa.md,v
retrieving revision 1.22
diff -u -p -r1.22 xtensa.md
--- gcc/config/xtensa/xtensa.md	19 Aug 2004 06:12:12 -0000	1.22
+++ gcc/config/xtensa/xtensa.md	21 Mar 2005 17:20:06 -0000
@@ -88,7 +88,12 @@
 			 (eq_attr "type" "fconv")
 			 "nothing")
 
+;; Include predicate definitions
+
+(include "predicates.md")
+
+
 ;; Addition.
 
 (define_expand "adddi3"
--- /dev/null	2005-03-17 08:46:35.771167648 -0800
+++ gcc/config/xtensa/predicates.md	2005-03-21 09:40:49.178422587 -0800
@@ -0,0 +1,157 @@
+;; Predicate definitions for Xtensa.
+;; Copyright (C) 2005 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 2, 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 COPYING.  If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+(define_predicate "add_operand"
+  (ior (and (match_code "const_int")
+	    (match_test "xtensa_simm8 (INTVAL (op))
+			 || xtensa_simm8x256 (INTVAL (op))"))
+       (match_operand 0 "register_operand")))
+
+(define_predicate "arith_operand"
+  (ior (and (match_code "const_int")
+	    (match_test "xtensa_simm8 (INTVAL (op))"))
+       (match_operand 0 "register_operand")))
+
+;; Non-immediate operand excluding the constant pool.
+(define_predicate "nonimmed_operand"
+  (ior (and (match_operand 0 "memory_operand")
+	    (match_test "!constantpool_address_p (XEXP (op, 0))"))
+       (match_operand 0 "register_operand")))
+
+;; Memory operand excluding the constant pool.
+(define_predicate "mem_operand"
+  (and (match_operand 0 "memory_operand")
+       (match_test "!constantpool_address_p (XEXP (op, 0))")))
+
+(define_predicate "mask_operand"
+  (ior (and (match_code "const_int")
+	    (match_test "xtensa_mask_immediate (INTVAL (op))"))
+       (match_operand 0 "register_operand")))
+
+(define_predicate "extui_fldsz_operand"
+  (and (match_code "const_int")
+       (match_test "xtensa_mask_immediate ((1 << INTVAL (op)) - 1)")))
+
+(define_predicate "sext_operand"
+  (if_then_else (match_test "TARGET_SEXT")
+		(match_operand 0 "nonimmed_operand")
+		(match_operand 0 "mem_operand")))
+
+(define_predicate "sext_fldsz_operand"
+  (and (match_code "const_int")
+       (match_test "INTVAL (op) >= 8 && INTVAL (op) <= 23")))
+
+(define_predicate "lsbitnum_operand"
+  (and (match_code "const_int")
+       (match_test "BITS_BIG_ENDIAN
+		    ? (INTVAL (op) == BITS_PER_WORD - 1)
+		    : (INTVAL (op) == 0)")))
+
+(define_predicate "branch_operand"
+  (ior (and (match_code "const_int")
+	    (match_test "xtensa_b4const_or_zero (INTVAL (op))"))
+       (match_operand 0 "register_operand")))
+
+(define_predicate "ubranch_operand"
+  (ior (and (match_code "const_int")
+	    (match_test "xtensa_b4constu (INTVAL (op))"))
+       (match_operand 0 "register_operand")))
+
+(define_predicate "call_insn_operand"
+  (match_code "const_int,const,symbol_ref,reg")
+{
+  if ((GET_CODE (op) == REG)
+      && (op != arg_pointer_rtx)
+      && ((REGNO (op) < FRAME_POINTER_REGNUM)
+	  || (REGNO (op) > LAST_VIRTUAL_REGISTER)))
+    return true;
+
+  if (CONSTANT_ADDRESS_P (op))
+    {
+      /* Direct calls only allowed to static functions with PIC.  */
+      if (flag_pic)
+	{
+	  tree callee, callee_sec, caller_sec;
+
+	  if (GET_CODE (op) != SYMBOL_REF
+	      || !SYMBOL_REF_LOCAL_P (op) || SYMBOL_REF_EXTERNAL_P (op))
+	    return false;
+
+	  /* Don't attempt a direct call if the callee is known to be in
+	     a different section, since there's a good chance it will be
+	     out of range.  */
+
+	  if (flag_function_sections
+	      || DECL_ONE_ONLY (current_function_decl))
+	    return false;
+	  caller_sec = DECL_SECTION_NAME (current_function_decl);
+	  callee = SYMBOL_REF_DECL (op);
+	  if (callee)
+	    {
+	      if (DECL_ONE_ONLY (callee))
+		return false;
+	      callee_sec = DECL_SECTION_NAME (callee);
+	      if (((caller_sec == NULL_TREE) ^ (callee_sec == NULL_TREE))
+		  || (caller_sec != NULL_TREE
+		      && strcmp (TREE_STRING_POINTER (caller_sec),
+				 TREE_STRING_POINTER (callee_sec)) != 0))
+		return false;
+	    }
+	  else if (caller_sec != NULL_TREE)
+	    return false;
+	}
+      return true;
+    }
+
+  return false;
+})
+
+(define_predicate "move_operand"
+  (ior
+     (ior (match_operand 0 "register_operand")
+	  (match_operand 0 "memory_operand"))
+     (ior (and (match_code "const_int")
+	       (match_test "GET_MODE_CLASS (mode) == MODE_INT
+			    && xtensa_simm12b (INTVAL (op))"))
+	  (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
+	       (match_test "TARGET_CONST16 && CONSTANT_P (op)
+			    && GET_MODE_SIZE (mode) % UNITS_PER_WORD == 0")))))
+
+;; Accept the floating point constant 1 in the appropriate mode.
+(define_predicate "const_float_1_operand"
+  (match_code "const_double")
+{
+  REAL_VALUE_TYPE d;
+  REAL_VALUE_FROM_CONST_DOUBLE (d, op);
+  return REAL_VALUES_EQUAL (d, dconst1);
+})
+
+(define_predicate "fpmem_offset_operand"
+  (and (match_code "const_int")
+       (match_test "xtensa_mem_offset (INTVAL (op), SFmode)")))
+
+(define_predicate "branch_operator"
+  (match_code "eq,ne,lt,ge"))
+
+(define_predicate "ubranch_operator"
+  (match_code "ltu,geu"))
+
+(define_predicate "boolean_operator"
+  (match_code "eq,ne"))

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