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]

Committed, CRIS predicates.md. Some findings.


I chose to use lisp syntax instead of Kazu-sans script-generated
predicates.  Shorter, less redundant code, especially for the
trivial operator predicates.

1. While working on this I noticed that genpreds treats
(and (match_code "unspec,const_int") stuff) differently from
(and (ior (match_code "unspec") (match_code "const_int")) stuff),
in that mode-checks are omitted from the former but not the
latter construct.  This is a bug, but you're not likely to run
into it because the preferred way to describe predicates usually
doesn't need lots of match_codes listed, at least more than what
fits in 80 columns.

2. A nice feature would be if "helper" predicates; those only used
in other predicates, but not in the .md, could be emitted as
static functions.

3. Some feature to refer to the inner part of a predicate would
also be nice, something like
(match_operand 0 "memory_operand"
  (match_operand 1 "special_address_operand"))
so you wouldn't have to write the inner test as C or match_test.

4. I was also refreshed on that no other RTX than CONST_INT must
have VOIDmode (see also PR 20413).  This is not specific for
predicates however; genrecog also only treats CONST_INT as
special in this regard.  I suspect some other target also
generate CONST of VOIDmode.  I suggest having ENABLE_CHECKING
tests for this.

I intend to open PRs for the bug and the suggestions as some
kind of gcc-global FIXME, but I'm not going to implement them,
at least not for the time being.

No testsuite regressions and no code changes for cris-elf on the
toolchain libraries and the programs I use for benchmarking.  No
regressions for cris-linux on the gcc, objc and g++ testsuites
(the libstdc++ tests aren't finished, but I think I don't need
to see them).  The fortran testsuite seems to be largely failing
for all cross targets, but no changes there either.

	* config/cris/predicates.md: New file.
	* config/cris/cris-protos.h (cris_store_multiple_op_p)
	(cris_movem_load_rest_p): Declare.
	* config/cris/cris.c (cris_store_multiple_op): Return bool, not int.
	(cris_movem_load_rest_p): Ditto.  Globalize.
	(cris_bdap_operand, cris_bdap_biap_operand,
	cris_orthogonal_operator, cris_commutative_orth_op,
	cris_operand_extend_operator,
	cris_additive_operand_extend_operator, cris_extend_operator,
	cris_plus_or_bound_operator, cris_mem_op,
	cris_general_operand_or_symbol,
	cris_general_operand_or_gotless_symbol,
	cris_general_operand_or_plt_symbol, cris_mem_call_operand,
	cris_load_multiple_op): Remove predicate functions.
	(cris_symbol, cris_gotless_symbol) <case UNSPEC>: Return 0, don't
	abort, for UNSPECs other than CRIS_UNSPEC_PLT.
	* config/cris/cris.h (PREDICATE_CODES): Don't define.
	* config/cris/cris.md: Include predicates.md.
	("call", "call_value"): Generate CONSTs of Pmode, not VOIDmode.

--- /dev/null	2004-02-23 22:02:56.000000000 +0100
+++ predicates.md	2005-04-20 04:53:28.000000000 +0200
@@ -0,0 +1,170 @@
+;; Operand and operator predicates for the GCC CRIS port.
+;; 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.
+
+
+;; Operator predicates.
+
+(define_predicate "cris_orthogonal_operator"
+  (match_code "plus, minus, ior, and, umin"))
+
+(define_predicate "cris_commutative_orth_op"
+  (match_code "plus, ior, and, umin"))
+
+;; By the name, you might think we should include MULT.  We don't because
+;; it doesn't accept the same addressing modes as the others (only
+;; registers) and there's also the problem of handling TARGET_MUL_BUG.
+
+(define_predicate "cris_operand_extend_operator"
+  (match_code "plus, minus, umin"))
+
+(define_predicate "cris_additive_operand_extend_operator"
+  (match_code "plus, minus"))
+
+(define_predicate "cris_extend_operator"
+  (match_code "zero_extend, sign_extend"))
+
+(define_predicate "cris_plus_or_bound_operator"
+  (match_code "plus, umin"))
+
+;; Used as an operator to get a handle on a already-known-valid MEM rtx:es
+;; (no need to validate the address), where some address expression parts
+;; have their own match_operand.
+
+(define_predicate "cris_mem_op"
+  (match_code "mem"))
+
+(define_predicate "cris_load_multiple_op"
+  (and (match_code "parallel")
+       (match_test "cris_movem_load_rest_p (op, 0)")))
+
+(define_predicate "cris_store_multiple_op"
+  (and (match_code "parallel")
+       (match_test "cris_store_multiple_op_p (op)")))
+
+
+;; Operand helper predicates.
+
+(define_predicate "cris_bdap_const_operand"
+  (and (match_code "label_ref, symbol_ref, const_int, const_double, const")
+       (not (and (match_test "flag_pic")
+		 (match_test "cris_symbol (op)")))))
+
+(define_predicate "cris_simple_address_operand"
+  (ior (match_operand:SI 0 "register_operand")
+       (and (match_code "post_inc")
+	    (match_test "register_operand (XEXP (op, 0), Pmode)"))))
+
+(define_predicate "cris_simple_operand"
+  (ior (match_operand 0 "register_operand")
+       (and (match_code "mem")
+	    (match_test "cris_simple_address_operand (XEXP (op, 0),
+						      Pmode)"))))
+
+;; The caller needs to use :SI.
+(define_predicate "cris_bdap_sign_extend_operand"
+  (and (match_code "sign_extend")
+       (and (match_test "MEM_P (XEXP (op, 0))")
+	    (match_test "cris_simple_address_operand (XEXP (XEXP (op, 0), 0),
+						      Pmode)"))))
+
+;; FIXME: Should not have to test for 1.
+(define_predicate "cris_scale_int_operand"
+  (and (match_code "const_int")
+       (ior (ior (match_test "op == GEN_INT (4)")
+		 (match_test "op == const2_rtx"))
+	    (match_test "op == const1_rtx"))))
+
+;; FIXME: Should be able to assume (reg int).
+(define_predicate "cris_biap_mult_operand"
+  (and (match_code "mult")
+       (ior (and (match_test "register_operand (XEXP (op, 0), Pmode)")
+		 (match_test "cris_scale_int_operand (XEXP (op, 1), Pmode)"))
+	    (and (match_test "cris_scale_int_operand (XEXP (op, 0), Pmode)")
+		 (match_test "register_operand (XEXP (op, 1), Pmode)")))))
+
+
+;; Operand predicates.
+
+;; This checks a part of an address, the one that is not a plain register
+;; for an addressing mode using BDAP.
+;; Allowed operands are either:
+;; a) a register
+;; b) a CONST operand (but not a symbol when generating PIC)
+;; c) a [r] or [r+] in SImode, or sign-extend from HI or QI.
+
+(define_predicate "cris_bdap_operand"
+  (ior (match_operand 0 "cris_bdap_const_operand")
+       (ior (match_operand:SI 0 "cris_simple_operand")
+	    (match_operand:SI 0 "cris_bdap_sign_extend_operand"))))
+
+;; This is similar to cris_bdap_operand:
+;; It checks a part of an address, the one that is not a plain register
+;; for an addressing mode using BDAP or BIAP.
+;; Allowed operands are either:
+;; a) a register
+;; b) a CONST operand (but not a symbol when generating PIC)
+;; c) a mult of (1, 2 or 4) and a register
+;; d) a [r] or [r+] in SImode, or sign-extend from HI or QI.  */
+
+(define_predicate "cris_bdap_biap_operand"
+  (ior (match_operand 0 "cris_bdap_operand")
+       (match_operand 0 "cris_biap_mult_operand")))
+
+;; Since a PIC symbol without a GOT entry is not a general_operand, we
+;; have to have a predicate that matches it.  We use this in the expanded
+;; "movsi" anonymous pattern.
+;; FIXME: Can s/special_// when PR 20413 is fixed.
+
+(define_special_predicate "cris_general_operand_or_gotless_symbol"
+  (ior (match_operand 0 "general_operand")
+       (and (match_code "const, symbol_ref, label_ref, unspec")
+	    (match_test "cris_gotless_symbol (op)"))))
+
+;; Since with -fPIC, not all symbols are valid PIC symbols or indeed
+;; general_operands, we have to have a predicate that matches it for the
+;; "movsi" expander.
+;; FIXME: Can s/special_// when PR 20413 is fixed.
+
+(define_special_predicate "cris_general_operand_or_symbol"
+  (ior (match_operand 0 "general_operand")
+       (and (match_code "const, symbol_ref, label_ref")
+	    (match_test "cris_symbol (op)"))))
+
+;; Since a PLT symbol is not a general_operand, we have to have a
+;; predicate that matches it when we need it.  We use this in the expanded
+;; "call" and "call_value" anonymous patterns.
+
+(define_predicate "cris_general_operand_or_plt_symbol"
+  (ior (match_operand 0 "general_operand")
+       (and (match_code "const")
+	    (and (match_test "GET_CODE (XEXP (op, 0)) == UNSPEC")
+		 (not (match_test "TARGET_AVOID_GOTPLT"))))))
+
+;; This matches a (MEM (general_operand)) or
+;; (MEM (cris_general_operand_or_symbol)).  The second one isn't a valid
+;; memory_operand, so we need this predicate to recognize call
+;; destinations before we change them to a PLT operand (by wrapping in
+;; UNSPEC CRIS_UNSPEC_PLT).
+
+(define_predicate "cris_mem_call_operand"
+  (and (match_code "mem")
+       (ior (match_operand 0 "memory_operand")
+	    (match_test "cris_general_operand_or_symbol (XEXP (op, 0),
+							 Pmode)"))))
? predicates.md
Index: cris-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/cris/cris-protos.h,v
retrieving revision 1.18
diff -p -c -r1.18 cris-protos.h
*** cris-protos.h	13 Apr 2005 18:34:22 -0000	1.18
--- cris-protos.h	20 Apr 2005 09:07:19 -0000
*************** extern int cris_legitimate_pic_operand (
*** 41,46 ****
--- 41,48 ----
  extern int cris_gotless_symbol (rtx);
  extern int cris_got_symbol (rtx);
  extern int cris_symbol (rtx);
+ extern bool cris_store_multiple_op_p (rtx);
+ extern bool cris_movem_load_rest_p (rtx, int);
  extern void cris_asm_output_symbol_ref (FILE *, rtx);
  extern bool cris_output_addr_const_extra (FILE *, rtx);
  extern int cris_cfun_uses_pic_table (void);
Index: cris.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/cris/cris.c,v
retrieving revision 1.71
diff -p -c -r1.71 cris.c
*** cris.c	13 Apr 2005 18:34:22 -0000	1.71
--- cris.c	20 Apr 2005 09:07:21 -0000
*************** static void cris_operand_lossage (const 
*** 120,127 ****
  
  static int cris_reg_saved_in_regsave_area  (unsigned int, bool);
  
- static int cris_movem_load_rest_p (rtx, int);
- 
  static void cris_asm_output_mi_thunk
    (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
  
--- 120,125 ----
*************** int cris_cpu_version = CRIS_DEFAULT_CPU_
*** 205,484 ****
  
  struct gcc_target targetm = TARGET_INITIALIZER;
  
- /* Predicate functions.  */
- 
- /* This checks a part of an address, the one that is not a plain register
-    for an addressing mode using BDAP.
-    Allowed operands is either:
-    a) a register
-    b) a CONST operand (but not a symbol when generating PIC)
-    c) a [r] or [r+] in SImode, or sign-extend from HI or QI.  */
- 
- int
- cris_bdap_operand (rtx op, enum machine_mode mode)
- {
-   register enum rtx_code code = GET_CODE (op);
- 
-   if (mode != SImode && (mode != VOIDmode || GET_MODE (op) != VOIDmode))
-     return 0;
- 
-   /* Just return whether this is a simple register or constant.  */
-   if (register_operand (op, mode)
-       || (CONSTANT_P (op) && !(flag_pic && cris_symbol (op))))
-     return 1;
- 
-   /* Is it a [r] or possibly a [r+]?  */
-   if (code == MEM)
-     {
-       rtx tem = XEXP (op, 0);
- 
-       if (mode == SImode
- 	  && (register_operand (tem, SImode)
- 	      || (GET_CODE (tem) == POST_INC
- 		  && register_operand (XEXP (tem, 0), SImode))))
- 	return 1;
-       else
- 	return 0;
-     }
- 
-   /* Perhaps a sign-extended mem: [r].(b|w) or [r+].(b|w)?  */
-   if (code == SIGN_EXTEND)
-     {
-       rtx tem = XEXP (op, 0);
- 
-       if (GET_CODE (tem) != MEM)
- 	return 0;
- 
-       tem = XEXP (tem, 0);
-       if (mode == SImode
- 	  && (register_operand (tem, SImode)
- 	      || (GET_CODE (tem) == POST_INC
- 		  && register_operand (XEXP (tem, 0), SImode))))
- 	return 1;
-       else
- 	return 0;
-     }
- 
-   return 0;
- }
- 
- /* This is similar to cris_bdap_operand:
-    It checks a part of an address, the one that is not a plain register
-    for an addressing mode using BDAP *or* BIAP.
-    Allowed operands is either:
-    a) a register
-    b) a CONST operand (but not a symbol when generating PIC)
-    c) a mult of (1, 2 or 4) and a register
-    d) a [r] or [r+] in SImode, or sign-extend from HI or QI.  */
- 
- int
- cris_bdap_biap_operand (rtx op, enum machine_mode mode)
- {
-   register enum rtx_code code = GET_CODE (op);
-   rtx reg;
-   rtx val;
- 
-   /* Check for bdap operand.  */
-   if (cris_bdap_operand (op, mode))
-     return 1;
- 
-   if (mode != SImode && (mode != VOIDmode || GET_MODE (op) != VOIDmode))
-     return 0;
- 
-   /* Check that we're looking at a BIAP operand.  */
-   if (code != MULT)
-     return 0;
- 
-   /* Canonicalize register and multiplicand.  */
-   if (GET_CODE (XEXP (op, 0)) == CONST_INT)
-     {
-       val = XEXP (op, 0);
-       reg = XEXP (op, 1);
-     }
-   else
-     {
-       val = XEXP (op, 1);
-       reg = XEXP (op, 0);
-     }
- 
-   /* Check that the operands are correct after canonicalization.  */
-   if (! register_operand (reg, SImode) || GET_CODE (val) != CONST_INT)
-     return 0;
- 
-   /* Check that the multiplicand has a valid value.  */
-   if ((code == MULT
-        && (INTVAL (val) == 1 || INTVAL (val) == 2 || INTVAL (val) == 4)))
-     return 1;
- 
-   return 0;
- }
- 
- /* Check if MODE is same as mode for X, and X is PLUS, MINUS, IOR or
-    AND or UMIN.  */
- 
- int
- cris_orthogonal_operator (rtx x, enum machine_mode mode)
- {
-   enum rtx_code code = GET_CODE (x);
- 
-   if (mode == VOIDmode)
-     mode = GET_MODE (x);
- 
-   return (GET_MODE (x) == mode
- 	  && (code == PLUS || code == MINUS
- 	      || code == IOR || code == AND || code == UMIN));
- }
- 
- /* Check if MODE is same as mode for X, and X is PLUS, IOR or AND or
-    UMIN.  */
- 
- int
- cris_commutative_orth_op (rtx x, enum machine_mode mode)
- {
-   enum rtx_code code = GET_CODE (x);
- 
-   if (mode == VOIDmode)
-     mode = GET_MODE (x);
- 
-   return (GET_MODE (x) == mode &&
- 	  (code == PLUS
- 	   || code == IOR || code == AND || code == UMIN));
- }
- 
- /* Check if MODE is same as mode for X, and X is PLUS or MINUS or UMIN.
-    By the name, you might think we should include MULT.  We don't because
-    it doesn't accept the same addressing modes as the others (ony
-    registers) and there's also the problem of handling TARGET_MUL_BUG.  */
- 
- int
- cris_operand_extend_operator (rtx x, enum machine_mode mode)
- {
-   enum rtx_code code = GET_CODE (x);
- 
-   if (mode == VOIDmode)
-     mode = GET_MODE (x);
- 
-   return (GET_MODE (x) == mode
- 	  && (code == PLUS || code == MINUS || code == UMIN));
- }
- 
- /* Check if MODE is same as mode for X, and X is PLUS or MINUS.  */
- 
- int
- cris_additive_operand_extend_operator (rtx x, enum machine_mode mode)
- {
-   enum rtx_code code = GET_CODE (x);
- 
-   if (mode == VOIDmode)
-     mode = GET_MODE (x);
- 
-   return (GET_MODE (x) == mode
- 	  && (code == PLUS || code == MINUS));
- }
- 
- /* Check to see if MODE is same as mode for X, and X is SIGN_EXTEND or
-    ZERO_EXTEND.  */
- 
- int
- cris_extend_operator (rtx x, enum machine_mode mode)
- {
-   enum rtx_code code = GET_CODE (x);
- 
-   if (mode == VOIDmode)
-     mode = GET_MODE (x);
- 
-   return
-     (GET_MODE (x) == mode && (code == SIGN_EXTEND || code == ZERO_EXTEND));
- }
- 
- /* Check to see if MODE is same as mode for X, and X is PLUS or BOUND.  */
- 
- int
- cris_plus_or_bound_operator (rtx x, enum machine_mode mode)
- {
-   enum rtx_code code = GET_CODE (x);
- 
-   if (mode == VOIDmode)
-     mode = GET_MODE (x);
- 
-   return
-     (GET_MODE (x) == mode && (code == UMIN || code == PLUS));
- }
- 
- /* Used as an operator to get a handle on a already-known-valid MEM rtx:es
-    (no need to validate the address), where some address expression parts
-    have their own match_operand.  */
- 
- int
- cris_mem_op (rtx x, enum machine_mode mode)
- {
-   if (mode == VOIDmode)
-     mode = GET_MODE (x);
- 
-   return GET_MODE (x) == mode && GET_CODE (x) == MEM;
- }
- 
- /* Since with -fPIC, not all symbols are valid PIC symbols or indeed
-    general_operands, we have to have a predicate that matches it for the
-    "movsi" expander.  */
- 
- int
- cris_general_operand_or_symbol (rtx op, enum machine_mode mode)
- {
-   return general_operand (op, mode)
-     || (CONSTANT_P (op) && cris_symbol (op));
- }
- 
- /* Since a PIC symbol without a GOT entry is not a general_operand, we
-    have to have a predicate that matches it.  We use this in the expanded
-    "movsi" anonymous pattern.  */
- 
- int
- cris_general_operand_or_gotless_symbol (rtx op, enum machine_mode mode)
- {
-   return general_operand (op, mode)
-     || (GET_CODE (op) == UNSPEC && XINT (op, 1) == CRIS_UNSPEC_GOT)
-     || (CONSTANT_P (op) && cris_gotless_symbol (op));
- }
- 
- /* Since a PLT symbol is not a general_operand, we have to have a
-    predicate that matches it when we need it.  We use this in the expanded
-    "call" and "call_value" anonymous patterns.  */
- 
- int
- cris_general_operand_or_plt_symbol (rtx op, enum machine_mode mode)
- {
-   return general_operand (op, mode)
-     || (GET_CODE (op) == CONST
- 	&& GET_CODE (XEXP (op, 0)) == UNSPEC
- 	&& !TARGET_AVOID_GOTPLT);
- }
- 
- /* This matches a (MEM (general_operand)) or
-    (MEM (cris_general_operand_or_symbol)).  The second one isn't a valid
-    memory_operand, so we need this predicate to recognize call
-    destinations before we change them to a PLT operand (by wrapping in
-    UNSPEC CRIS_UNSPEC_PLT).  */
- 
- int
- cris_mem_call_operand (rtx op, enum machine_mode mode)
- {
-   rtx xmem;
- 
-   if (GET_CODE (op) != MEM)
-     return 0;
- 
-   if (memory_operand (op, mode))
-     return 1;
- 
-   xmem = XEXP (op, 0);
- 
-   return cris_general_operand_or_symbol (xmem, GET_MODE (op));
- }
- 
  /* Helper for cris_load_multiple_op and cris_ret_movem_op.  */
  
! static int
  cris_movem_load_rest_p (rtx op, int offs)
  {
    unsigned int reg_count = XVECLEN (op, 0) - offs;
--- 203,211 ----
  
  struct gcc_target targetm = TARGET_INITIALIZER;
  
  /* Helper for cris_load_multiple_op and cris_ret_movem_op.  */
  
! bool
  cris_movem_load_rest_p (rtx op, int offs)
  {
    unsigned int reg_count = XVECLEN (op, 0) - offs;
*************** cris_movem_load_rest_p (rtx op, int offs
*** 495,501 ****
        || GET_CODE (XVECEXP (op, 0, offs)) != SET
        || GET_CODE (SET_DEST (XVECEXP (op, 0, offs))) != REG
        || GET_CODE (SET_SRC (XVECEXP (op, 0, offs))) != MEM)
!     return 0;
  
    /* Check a possible post-inc indicator.  */
    if (GET_CODE (SET_SRC (XVECEXP (op, 0, offs + 1))) == PLUS)
--- 222,228 ----
        || GET_CODE (XVECEXP (op, 0, offs)) != SET
        || GET_CODE (SET_DEST (XVECEXP (op, 0, offs))) != REG
        || GET_CODE (SET_SRC (XVECEXP (op, 0, offs))) != MEM)
!     return false;
  
    /* Check a possible post-inc indicator.  */
    if (GET_CODE (SET_SRC (XVECEXP (op, 0, offs + 1))) == PLUS)
*************** cris_movem_load_rest_p (rtx op, int offs
*** 511,517 ****
  	  || REGNO (reg) != REGNO (SET_DEST (XVECEXP (op, 0, offs + 1)))
  	  || GET_CODE (inc) != CONST_INT
  	  || INTVAL (inc) != (HOST_WIDE_INT) reg_count * 4)
! 	return 0;
        i = offs + 2;
      }
    else
--- 238,244 ----
  	  || REGNO (reg) != REGNO (SET_DEST (XVECEXP (op, 0, offs + 1)))
  	  || GET_CODE (inc) != CONST_INT
  	  || INTVAL (inc) != (HOST_WIDE_INT) reg_count * 4)
! 	return false;
        i = offs + 2;
      }
    else
*************** cris_movem_load_rest_p (rtx op, int offs
*** 531,537 ****
        || GET_CODE (SET_SRC (elt)) != MEM
        || GET_MODE (SET_SRC (elt)) != SImode
        || !memory_address_p (SImode, src_addr))
!     return 0;
  
    for (setno = 1; i < XVECLEN (op, 0); setno++, i++)
      {
--- 258,264 ----
        || GET_CODE (SET_SRC (elt)) != MEM
        || GET_MODE (SET_SRC (elt)) != SImode
        || !memory_address_p (SImode, src_addr))
!     return false;
  
    for (setno = 1; i < XVECLEN (op, 0); setno++, i++)
      {
*************** cris_movem_load_rest_p (rtx op, int offs
*** 548,571 ****
  	  || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
  	  || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
  	  || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != setno * 4)
! 	return 0;
      }
  
!   return 1;
! }
! 
! /* Predicate for the parallel contents in a movem from-memory.  */
! 
! int
! cris_load_multiple_op (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
! {
!   return cris_movem_load_rest_p (op, 0);
  }
  
! /* Predicate for the parallel contents in a movem to-memory.  */
  
! int
! cris_store_multiple_op (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
  {
    int reg_count = XVECLEN (op, 0);
    rtx dest;
--- 275,291 ----
  	  || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
  	  || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
  	  || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != setno * 4)
! 	return false;
      }
  
!   return true;
  }
  
! /* Worker function for predicate for the parallel contents in a movem
!    to-memory.  */
  
! bool
! cris_store_multiple_op_p (rtx op)
  {
    int reg_count = XVECLEN (op, 0);
    rtx dest;
*************** cris_store_multiple_op (rtx op, enum mac
*** 581,598 ****
    /* Perform a quick check so we don't blow up below.  FIXME: Adjust for
       other than (MEM reg) and (MEM (PLUS reg const)).  */
    if (reg_count <= 1)
!     return 0;
  
    elt = XVECEXP (op, 0, 0);
  
    if (GET_CODE (elt) != SET)
!     return  0;
  
    dest = SET_DEST (elt);
  
    if (GET_CODE (SET_SRC (elt)) != REG
        || GET_CODE (dest) != MEM)
!     return 0;
  
    dest_addr = XEXP (dest, 0);
  
--- 301,318 ----
    /* Perform a quick check so we don't blow up below.  FIXME: Adjust for
       other than (MEM reg) and (MEM (PLUS reg const)).  */
    if (reg_count <= 1)
!     return false;
  
    elt = XVECEXP (op, 0, 0);
  
    if (GET_CODE (elt) != SET)
!     return  false;
  
    dest = SET_DEST (elt);
  
    if (GET_CODE (SET_SRC (elt)) != REG
        || GET_CODE (dest) != MEM)
!     return false;
  
    dest_addr = XEXP (dest, 0);
  
*************** cris_store_multiple_op (rtx op, enum mac
*** 620,626 ****
  		   && REGNO (XEXP (dest_addr, 0)) == REGNO (reg)
  		   && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT
  		   && INTVAL (XEXP (dest_addr, 1)) == INTVAL (inc))))
! 	return 0;
  
        i = 2;
      }
--- 340,346 ----
  		   && REGNO (XEXP (dest_addr, 0)) == REGNO (reg)
  		   && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT
  		   && INTVAL (XEXP (dest_addr, 1)) == INTVAL (inc))))
! 	return false;
  
        i = 2;
      }
*************** cris_store_multiple_op (rtx op, enum mac
*** 637,643 ****
        || REGNO (SET_SRC (elt)) != (unsigned int) regno
        || GET_CODE (SET_DEST (elt)) != MEM
        || GET_MODE (SET_DEST (elt)) != SImode)
!     return 0;
  
    if (REG_P (dest_addr))
      {
--- 357,363 ----
        || REGNO (SET_SRC (elt)) != (unsigned int) regno
        || GET_CODE (SET_DEST (elt)) != MEM
        || GET_MODE (SET_DEST (elt)) != SImode)
!     return false;
  
    if (REG_P (dest_addr))
      {
*************** cris_store_multiple_op (rtx op, enum mac
*** 652,658 ****
        offset = INTVAL (XEXP (dest_addr, 1));
      }
    else
!     return 0;
  
    for (setno = 1; i < XVECLEN (op, 0); setno++, i++)
      {
--- 372,378 ----
        offset = INTVAL (XEXP (dest_addr, 1));
      }
    else
!     return false;
  
    for (setno = 1; i < XVECLEN (op, 0); setno++, i++)
      {
*************** cris_store_multiple_op (rtx op, enum mac
*** 669,678 ****
  	  || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_base)
  	  || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
  	  || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != setno * 4 + offset)
! 	return 0;
      }
  
!   return 1;
  }
  
  /* The CONDITIONAL_REGISTER_USAGE worker.  */
--- 389,398 ----
  	  || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_base)
  	  || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
  	  || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != setno * 4 + offset)
! 	return false;
      }
  
!   return true;
  }
  
  /* The CONDITIONAL_REGISTER_USAGE worker.  */
*************** cris_symbol (rtx x)
*** 2176,2182 ****
        return 1;
  
      case UNSPEC:
!       if (XINT (x, 1) == CRIS_UNSPEC_GOT)
  	return 0;
        /* A PLT reference.  */
        ASSERT_PLT_UNSPEC (x);
--- 1896,1902 ----
        return 1;
  
      case UNSPEC:
!       if (XINT (x, 1) == CRIS_UNSPEC_GOT || XINT (x, 1) != CRIS_UNSPEC_PLT)
  	return 0;
        /* A PLT reference.  */
        ASSERT_PLT_UNSPEC (x);
*************** cris_gotless_symbol (rtx x)
*** 2218,2223 ****
--- 1938,1945 ----
      case UNSPEC:
        if (XINT (x, 1) == CRIS_UNSPEC_GOT)
  	return 1;
+       if (XINT (x, 1) != CRIS_UNSPEC_PLT)
+ 	return 0;
        ASSERT_PLT_UNSPEC (x);
        return 1;
  
Index: cris.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/cris/cris.h,v
retrieving revision 1.89
diff -p -c -r1.89 cris.h
*** cris.h	13 Apr 2005 18:34:23 -0000	1.89
--- cris.h	20 Apr 2005 09:07:22 -0000
*************** struct cum_args {int regs;};
*** 1616,1659 ****
  
  /* Node: Misc */
  
- /* FIXME: Check this one more time.  */
- #define PREDICATE_CODES					\
-  {"cris_orthogonal_operator",				\
-   {PLUS, MINUS, IOR, AND, UMIN}},			\
-  {"cris_commutative_orth_op",				\
-   {PLUS, IOR, AND, UMIN}},				\
-  {"cris_operand_extend_operator",			\
-   {PLUS, MINUS, UMIN}},					\
-  {"cris_additive_operand_extend_operator",		\
-   {PLUS, MINUS}},					\
-  {"cris_extend_operator",				\
-   {ZERO_EXTEND, SIGN_EXTEND}},				\
-  {"cris_plus_or_bound_operator",			\
-   {PLUS, UMIN}},					\
-  {"cris_mem_op",					\
-   {MEM}},						\
-  {"cris_load_multiple_op",				\
-   {PARALLEL}},						\
-  {"cris_store_multiple_op",				\
-   {PARALLEL}},						\
-  {"cris_bdap_operand",					\
-   {SUBREG, REG, LABEL_REF, SYMBOL_REF, MEM, CONST_INT,	\
-    CONST_DOUBLE, CONST, SIGN_EXTEND}},			\
-  {"cris_bdap_biap_operand",				\
-   {SUBREG, REG, LABEL_REF, SYMBOL_REF, MEM, CONST_INT,	\
-    CONST_DOUBLE, CONST, SIGN_EXTEND, MULT}},		\
-  {"cris_general_operand_or_gotless_symbol",		\
-   {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,		\
-    LABEL_REF, SUBREG, REG, MEM, UNSPEC}},		\
-  {"cris_general_operand_or_symbol",			\
-   {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,		\
-    LABEL_REF, SUBREG, REG, MEM}},			\
-  {"cris_general_operand_or_plt_symbol",			\
-   {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,		\
-    LABEL_REF, SUBREG, REG, MEM}},			\
-  {"cris_mem_call_operand",				\
-   {MEM}},
- 
  /* A combination of the bound (umin) insn together with a
     sign-extended add via the table to PC seems optimal.
     If the table overflows, the assembler will take care of it.
--- 1616,1621 ----
Index: cris.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/cris/cris.md,v
retrieving revision 1.30
diff -p -c -r1.30 cris.md
*** cris.md	14 Apr 2005 15:01:32 -0000	1.30
--- cris.md	20 Apr 2005 09:07:24 -0000
***************
*** 141,146 ****
--- 141,150 ----
  (define_delay (eq_attr "slottable" "has_slot")
    [(eq_attr "slottable" "yes") (nil) (nil)])
  
+ ;; Operand and operator predicates.
+ 
+ (include "predicates.md")
+ 
  ;; Test insns.
  
  ;; DImode
***************
*** 3944,3950 ****
  	       for the symbol cause bad recombinatorial effects?  */
  	    op0 = force_reg (Pmode,
  			     gen_rtx_CONST
! 			     (VOIDmode,
  			      gen_rtx_UNSPEC (VOIDmode,
  					      gen_rtvec (1, op0),
  					      CRIS_UNSPEC_PLT)));
--- 3948,3954 ----
  	       for the symbol cause bad recombinatorial effects?  */
  	    op0 = force_reg (Pmode,
  			     gen_rtx_CONST
! 			     (Pmode,
  			      gen_rtx_UNSPEC (VOIDmode,
  					      gen_rtvec (1, op0),
  					      CRIS_UNSPEC_PLT)));
***************
*** 4009,4015 ****
  	       for the symbol cause bad recombinatorial effects?  */
  	    op1 = force_reg (Pmode,
  			     gen_rtx_CONST
! 			     (VOIDmode,
  			      gen_rtx_UNSPEC (VOIDmode,
  					      gen_rtvec (1, op1),
  					      CRIS_UNSPEC_PLT)));
--- 4013,4019 ----
  	       for the symbol cause bad recombinatorial effects?  */
  	    op1 = force_reg (Pmode,
  			     gen_rtx_CONST
! 			     (Pmode,
  			      gen_rtx_UNSPEC (VOIDmode,
  					      gen_rtvec (1, op1),
  					      CRIS_UNSPEC_PLT)));

brgds, H-P


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