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]

Re: [patch] s390: Move predicates to predicates.md.


On Tue, Mar 22, 2005 at 03:00:08PM +0100, Adrian Straetling wrote:
> On Thu, Mar 17, 2005 at 05:58:00PM -0500, Kazu Hirata wrote:
> > Hi,
> > 
> > Attached is a patch to move predicates to predicates.md.
> > 
> > Built cc1 for s390-linux.  OK to apply?
> 
> Thanks for your patch. Unfortunately, bootstrap failed because most of the predicates actually have to be 'special_predicates' here. 
> We are currently working on a similar patch...

Hi,

here is now a working patch which moves predicates from s390.c to predicates.md.

Bootstrapped on s390-linux for 31/64bit

Adrian Strätling



2005-03-31  Adrian Strätling <straetling@de.ibm.com>

	* config/s390/s390-protos.h: Remove prototypes for predicate    
	functions. Add legitimate_branch_condition_p and
	legitimate_address_without_index_p.
	* config/s390/s390.c:     
	(SYMBOL_FLAG_ALIGN1, DISP_IN_RANGE): Move to s390.h.
	(s390_comparison, s390_alc_comparison, s390_slb_comparison,
	const0_operand, consttable_operand, larl_operand, s_operandw,
	shift_count_operand, bras_sym_operand,
	load_multiple_operation, store_multiple_operation,
	s390_plus_operand): Move to predicates.md.
	(check_mode): Replace by default behaviour of define_predicate.
	Add legitimate_branch_condition to test    
	s390_branch_condition_mask.
	Add legitimate_address_without_index_p to encapsulate     
	s390_decompose_address.
	* config/s390/s390.h (PREDICATE_CODES): Remove.
	* config/s390/s390.md: Include predicates.md.
	(predicates.md): New.


diff -C3 -pN --exclude-from=/home/l144673/.Diff_excludes ../gcc-4.1/gcc/config/s390/predicates.md gcc/config/s390/predicates.md
*** ../gcc-4.1/gcc/config/s390/predicates.md	Thu Jan  1 01:00:00 1970
--- gcc/config/s390/predicates.md	Thu Mar 31 14:16:46 2005
***************
*** 0 ****
--- 1,383 ----
+ ;; Predicate definitions for S/390 / zSeries.
+ ;; 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.
+ 
+ ;; OP is the current operation.
+ ;; MODE is the current operation mode.
+ 
+ ;; operands --------------------------------------------------------------
+ 
+ ;; Return true if OP a (const_int 0) operand.
+ (define_predicate "const0_operand"
+   (and (match_code "const_int, const_double")
+        (match_test "op == CONST0_RTX (mode)")))
+ 
+ ;; Return true if OP is constant.
+ (define_special_predicate "consttable_operand"
+   (and (match_code "symbol_ref, label_ref, const, const_int, const_double")
+        (match_test "CONSTANT_P (op)")))
+ 
+ ;; Return true if OP is a valid S-type operand.
+ (define_predicate "s_operand"
+   (and (match_code "subreg, mem")
+        (match_operand 0 "general_operand"))
+ {
+   /* Just like memory_operand, allow (subreg (mem ...))
+      after reload.  */
+   if (reload_completed
+       && GET_CODE (op) == SUBREG
+       && GET_CODE (SUBREG_REG (op)) == MEM)
+     op = SUBREG_REG (op);
+ 
+   if (GET_CODE (op) != MEM)
+     return false;
+   if (!legitimate_address_without_index_p(op))
+     return false;
+ 
+   return true;
+ })
+ 
+ ;; Return true if OP is a valid operand for the BRAS instruction.
+ ;; allow SYMBOL_REFs && @PLT stubs
+ (define_special_predicate "bras_sym_operand"
+   (ior (match_code "symbol_ref")
+        (and (match_code "const")
+             (and (match_test "GET_CODE (XEXP (op, 0)) == UNSPEC")
+ 	         (match_test "XINT (XEXP (op, 0), 1) == UNSPEC_PLT")))))
+ 
+ ;; Return true if OP is a PLUS that is not a legitimate
+ ;; operand for the LA instruction.
+ 
+ (define_predicate "s390_plus_operand"
+   (and (match_code "plus")
+        (and (match_test "mode == Pmode")
+ 	    (match_test "!legitimate_la_operand_p(op)"))))
+ 
+ ;; Return true if OP is a valid shift count operand.
+ 
+ (define_predicate "shift_count_operand"
+   (match_code "reg, subreg, plus, const_int")
+ {
+   HOST_WIDE_INT offset = 0;
+ 
+   /* We can have an integer constant, an address register,
+      or a sum of the two.  Note that reload already checks
+      that any register present is an address register, so
+      we just check for any register here.  */
+   if (GET_CODE (op) == CONST_INT)
+     {
+       offset = INTVAL (op);
+       op = NULL_RTX;
+     }
+   if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
+     {
+       offset = INTVAL (XEXP (op, 1));
+       op = XEXP (op, 0);
+     }
+   while (op && GET_CODE (op) == SUBREG)
+     op = SUBREG_REG (op);
+   if (op && GET_CODE (op) != REG)
+     return false;
+ 
+   /* Unfortunately we have to reject constants that are invalid
+      for an address, or else reload will get confused.  */
+   if (!DISP_IN_RANGE (offset))
+     return false;
+ 
+   return true;
+ })
+ 
+ ;;  Return true if OP a valid operand for the LARL instruction.
+ 
+ (define_predicate "larl_operand"
+   (match_code "label_ref, symbol_ref, const, const_int, const_double")
+ {
+   /* Allow labels and local symbols.  */
+   if (GET_CODE (op) == LABEL_REF)
+     return true;
+   if (GET_CODE (op) == SYMBOL_REF)
+     return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
+ 	    && SYMBOL_REF_TLS_MODEL (op) == 0
+ 	    && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
+ 
+   /* Everything else must have a CONST, so strip it.  */
+   if (GET_CODE (op) != CONST)
+     return false;
+   op = XEXP (op, 0);
+ 
+   /* Allow adding *even* in-range constants.  */
+   if (GET_CODE (op) == PLUS)
+     {
+       if (GET_CODE (XEXP (op, 1)) != CONST_INT
+           || (INTVAL (XEXP (op, 1)) & 1) != 0)
+         return false;
+ #if HOST_BITS_PER_WIDE_INT > 32
+       if (INTVAL (XEXP (op, 1)) >= (HOST_WIDE_INT)1 << 32
+ 	  || INTVAL (XEXP (op, 1)) < -((HOST_WIDE_INT)1 << 32))
+         return false;
+ #endif
+       op = XEXP (op, 0);
+     }
+ 
+   /* Labels and local symbols allowed here as well.  */
+   if (GET_CODE (op) == LABEL_REF)
+     return true;
+   if (GET_CODE (op) == SYMBOL_REF)
+     return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
+ 	    && SYMBOL_REF_TLS_MODEL (op) == 0
+ 	    && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
+ 
+   /* Now we must have a @GOTENT offset or @PLT stub
+      or an @INDNTPOFF TLS offset.  */
+   if (GET_CODE (op) == UNSPEC
+       && XINT (op, 1) == UNSPEC_GOTENT)
+     return true;
+   if (GET_CODE (op) == UNSPEC
+       && XINT (op, 1) == UNSPEC_PLT)
+     return true;
+   if (GET_CODE (op) == UNSPEC
+       && XINT (op, 1) == UNSPEC_INDNTPOFF)
+     return true;
+ 
+   return false;
+ })
+ 
+ ;; operators --------------------------------------------------------------
+ 
+ ;; Return nonzero if OP is a valid comparison operator
+ ;; for a branch condition in mode MODE.
+ ;  COMPARISON_P checks rtx_class
+ (define_predicate "s390_comparison"
+   (and (match_code "eq,ne,lt,gt,le,ge,ltu,gtu,leu,geu,
+ 		    uneq,unlt,ungt,unle,unge,ltgt,
+ 		    unordered, ordered")
+        (match_test "COMPARISON_P(op)"))
+ {
+   if (GET_CODE (XEXP (op, 0)) != REG
+       || REGNO (XEXP (op, 0)) != CC_REGNUM
+       || XEXP (op, 1) != const0_rtx)
+     return false;
+ 
+   return legitimate_branch_condition_p(op);
+ })
+ 
+ ;; Return nonzero if OP is a valid comparison operator
+ ;; for an ALC condition in mode MODE.
+ 
+ (define_predicate "s390_alc_comparison"
+   (match_code "zero_extend, sign_extend, ltu, gtu, leu, geu")
+ {
+   while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND)
+     op = XEXP (op, 0);
+ 
+   if (!COMPARISON_P (op))
+     return false;
+ 
+   if (GET_CODE (XEXP (op, 0)) != REG
+       || REGNO (XEXP (op, 0)) != CC_REGNUM
+       || XEXP (op, 1) != const0_rtx)
+     return false;
+ 
+   switch (GET_MODE (XEXP (op, 0)))
+     {
+     case CCL1mode:
+       return GET_CODE (op) == LTU;
+ 
+     case CCL2mode:
+       return GET_CODE (op) == LEU;
+ 
+     case CCL3mode:
+       return GET_CODE (op) == GEU;
+ 
+     case CCUmode:
+       return GET_CODE (op) == GTU;
+ 
+     case CCURmode:
+       return GET_CODE (op) == LTU;
+ 
+     case CCSmode:
+       return GET_CODE (op) == UNGT;
+ 
+     case CCSRmode:
+       return GET_CODE (op) == UNLT;
+ 
+     default:
+       return false;
+     }
+ })
+ 
+ ;; Return nonzero if OP is a valid comparison operator
+ ;; for an SLB condition in mode MODE.
+ 
+ (define_predicate "s390_slb_comparison"
+   (match_code "zero_extend, sign_extend, ltu, gtu, leu, geu")
+ {
+   while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND)
+     op = XEXP (op, 0);
+ 
+   if (!COMPARISON_P (op))
+     return false;
+ 
+   if (GET_CODE (XEXP (op, 0)) != REG
+       || REGNO (XEXP (op, 0)) != CC_REGNUM
+       || XEXP (op, 1) != const0_rtx)
+     return false;
+ 
+   switch (GET_MODE (XEXP (op, 0)))
+     {
+     case CCL1mode:
+       return GET_CODE (op) == GEU;
+ 
+     case CCL2mode:
+       return GET_CODE (op) == GTU;
+ 
+     case CCL3mode:
+       return GET_CODE (op) == LTU;
+ 
+     case CCUmode:
+       return GET_CODE (op) == LEU;
+ 
+     case CCURmode:
+       return GET_CODE (op) == GEU;
+ 
+     case CCSmode:
+       return GET_CODE (op) == LE;
+ 
+     case CCSRmode:
+       return GET_CODE (op) == GE;
+ 
+     default:
+       return false;
+     }
+ })
+ 
+ ;; Return true if OP is a load multiple operation.  It is known to be a
+ ;; PARALLEL and the first section will be tested.
+ 
+ (define_special_predicate "load_multiple_operation"
+   (match_code "parallel")
+ {
+   enum machine_mode elt_mode;
+   int count = XVECLEN (op, 0);
+   unsigned int dest_regno;
+   rtx src_addr;
+   int i, off;
+ 
+   /* Perform a quick check so we don't blow up below.  */
+   if (count <= 1
+       || GET_CODE (XVECEXP (op, 0, 0)) != SET
+       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
+       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
+     return false;
+ 
+   dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
+   src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
+   elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0)));
+ 
+   /* Check, is base, or base + displacement.  */
+ 
+   if (GET_CODE (src_addr) == REG)
+     off = 0;
+   else if (GET_CODE (src_addr) == PLUS
+ 	   && GET_CODE (XEXP (src_addr, 0)) == REG
+ 	   && GET_CODE (XEXP (src_addr, 1)) == CONST_INT)
+     {
+       off = INTVAL (XEXP (src_addr, 1));
+       src_addr = XEXP (src_addr, 0);
+     }
+   else
+     return false;
+ 
+   for (i = 1; i < count; i++)
+     {
+       rtx elt = XVECEXP (op, 0, i);
+ 
+       if (GET_CODE (elt) != SET
+ 	  || GET_CODE (SET_DEST (elt)) != REG
+ 	  || GET_MODE (SET_DEST (elt)) != elt_mode
+ 	  || REGNO (SET_DEST (elt)) != dest_regno + i
+ 	  || GET_CODE (SET_SRC (elt)) != MEM
+ 	  || GET_MODE (SET_SRC (elt)) != elt_mode
+ 	  || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
+ 	  || ! 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))
+ 	     != off + i * GET_MODE_SIZE (elt_mode))
+ 	return false;
+     }
+ 
+   return true;
+ })
+ 
+ ;; Return true if OP is a store multiple operation.  It is known to be a
+ ;; PARALLEL and the first section will be tested.
+ 
+ (define_special_predicate "store_multiple_operation"
+   (match_code "parallel")
+ {
+   enum machine_mode elt_mode;
+   int count = XVECLEN (op, 0);
+   unsigned int src_regno;
+   rtx dest_addr;
+   int i, off;
+ 
+   /* Perform a quick check so we don't blow up below.  */
+   if (count <= 1
+       || GET_CODE (XVECEXP (op, 0, 0)) != SET
+       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
+       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
+     return false;
+ 
+   src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
+   dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
+   elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0)));
+ 
+   /* Check, is base, or base + displacement.  */
+ 
+   if (GET_CODE (dest_addr) == REG)
+     off = 0;
+   else if (GET_CODE (dest_addr) == PLUS
+ 	   && GET_CODE (XEXP (dest_addr, 0)) == REG
+ 	   && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT)
+     {
+       off = INTVAL (XEXP (dest_addr, 1));
+       dest_addr = XEXP (dest_addr, 0);
+     }
+   else
+     return false;
+ 
+   for (i = 1; i < count; i++)
+     {
+       rtx elt = XVECEXP (op, 0, i);
+ 
+       if (GET_CODE (elt) != SET
+ 	  || GET_CODE (SET_SRC (elt)) != REG
+ 	  || GET_MODE (SET_SRC (elt)) != elt_mode
+ 	  || REGNO (SET_SRC (elt)) != src_regno + i
+ 	  || GET_CODE (SET_DEST (elt)) != MEM
+ 	  || GET_MODE (SET_DEST (elt)) != elt_mode
+ 	  || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
+ 	  || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
+ 	  || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
+ 	  || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1))
+ 	     != off + i * GET_MODE_SIZE (elt_mode))
+ 	return false;
+     }
+   return true;
+ })
diff -C3 -pN --exclude-from=/home/l144673/.Diff_excludes ../gcc-4.1/gcc/config/s390/s390-protos.h gcc/config/s390/s390-protos.h
*** ../gcc-4.1/gcc/config/s390/s390-protos.h	Wed Mar 30 23:16:43 2005
--- gcc/config/s390/s390-protos.h	Thu Mar 31 14:16:46 2005
*************** extern void s390_conditional_register_us
*** 33,46 ****
  #ifdef RTX_CODE
  extern int s390_extra_constraint_str (rtx, int, const char *);
  extern int s390_const_ok_for_constraint_p (HOST_WIDE_INT, int, const char *);
- extern int const0_operand (rtx, enum machine_mode);
- extern int consttable_operand (rtx, enum machine_mode);
- extern int larl_operand (rtx, enum machine_mode);
- extern int s_operand (rtx, enum machine_mode);
- extern int shift_count_operand (rtx, enum machine_mode);
- extern int bras_sym_operand (rtx, enum machine_mode);
- extern int load_multiple_operation (rtx, enum machine_mode);
- extern int store_multiple_operation (rtx, enum machine_mode);
  extern int s390_single_part (rtx, enum machine_mode, enum machine_mode, int);
  extern unsigned HOST_WIDE_INT s390_extract_part (rtx, enum machine_mode, int);
  extern bool s390_split_ok_p (rtx, rtx, enum machine_mode, int);
--- 33,38 ----
*************** extern int s390_match_ccmode (rtx, enum 
*** 51,59 ****
  extern enum machine_mode s390_tm_ccmode (rtx, rtx, int);
  extern enum machine_mode s390_select_ccmode (enum rtx_code, rtx, rtx);
  extern void s390_canonicalize_comparison (enum rtx_code *, rtx *, rtx *);
- extern int s390_comparison (rtx op, enum machine_mode mode);
- extern int s390_alc_comparison (rtx op, enum machine_mode mode);
- extern int s390_slb_comparison (rtx op, enum machine_mode mode);
  extern rtx s390_emit_compare (enum rtx_code, rtx, rtx);
  extern void s390_emit_jump (rtx, rtx);
  extern int symbolic_reference_mentioned_p (rtx);
--- 43,48 ----
*************** extern int legitimate_pic_operand_p (rtx
*** 64,69 ****
--- 53,60 ----
  extern int legitimate_constant_p (rtx);
  extern int legitimate_reload_constant_p (rtx);
  extern int legitimate_address_p (enum machine_mode, rtx, int);
+ extern bool legitimate_branch_condition_p(rtx);
+ extern bool legitimate_address_without_index_p(rtx);
  extern rtx legitimize_pic_address (rtx, rtx);
  extern rtx legitimize_address (rtx, rtx, enum machine_mode);
  extern rtx legitimize_reload_address (rtx, enum machine_mode, int, int);
diff -C3 -pN --exclude-from=/home/l144673/.Diff_excludes ../gcc-4.1/gcc/config/s390/s390.c gcc/config/s390/s390.c
*** ../gcc-4.1/gcc/config/s390/s390.c	Wed Mar 30 23:16:43 2005
--- gcc/config/s390/s390.c	Thu Mar 31 14:16:46 2005
*************** Software Foundation, 59 Temple Place - S
*** 52,60 ****
  #include "optabs.h"
  #include "tree-gimple.h"
  
- /* Machine-specific symbol_ref flags.  */
- #define SYMBOL_FLAG_ALIGN1	(SYMBOL_FLAG_MACH_DEP << 0)
- 
  
  static bool s390_assemble_integer (rtx, unsigned int, int);
  static void s390_encode_section_info (tree, rtx, int);
--- 52,57 ----
*************** struct machine_function GTY(())
*** 382,388 ****
  static int s390_match_ccmode_set (rtx, enum machine_mode);
  static int s390_branch_condition_mask (rtx);
  static const char *s390_branch_condition_mnemonic (rtx, int);
- static int check_mode (rtx, enum machine_mode *);
  static int s390_short_displacement (rtx);
  static int s390_decompose_address (rtx, struct s390_address *);
  static rtx get_thread_pointer (void);
--- 379,384 ----
*************** static int s390_function_arg_size (enum 
*** 413,422 ****
  static bool s390_function_arg_float (enum machine_mode, tree);
  static struct machine_function * s390_init_machine_status (void);
  
! /* Check whether integer displacement is in range.  */
! #define DISP_IN_RANGE(d) \
!   (TARGET_LONG_DISPLACEMENT? ((d) >= -524288 && (d) <= 524287) \
!                            : ((d) >= 0 && (d) <= 4095))
  
  /* Return true if SET either doesn't set the CC register, or else
     the source and destination have matching CC modes and that
--- 409,436 ----
  static bool s390_function_arg_float (enum machine_mode, tree);
  static struct machine_function * s390_init_machine_status (void);
  
! /* Return true if OP is a valid comparison operator for a branch condition */
! 
! bool
! legitimate_branch_condition_p(rtx op)
! {
!   return (s390_branch_condition_mask (op) >= 0);
! }
! 
! /* Return false if CODE is a valid address withou index */
! 
! bool
! legitimate_address_without_index_p(rtx op)
! {
!   struct s390_address addr;
! 
!   if (!s390_decompose_address (XEXP (op, 0), &addr))
!     return FALSE;
!   if (addr.indx)
!     return FALSE;
! 
!   return TRUE;
! }
  
  /* Return true if SET either doesn't set the CC register, or else
     the source and destination have matching CC modes and that
*************** s390_emit_jump (rtx target, rtx cond)
*** 791,912 ****
    emit_jump_insn (insn);
  }
  
- /* Return nonzero if OP is a valid comparison operator
-    for a branch condition in mode MODE.  */
- 
- int
- s390_comparison (rtx op, enum machine_mode mode)
- {
-   if (mode != VOIDmode && mode != GET_MODE (op))
-     return 0;
- 
-   if (!COMPARISON_P (op))
-     return 0;
- 
-   if (GET_CODE (XEXP (op, 0)) != REG
-       || REGNO (XEXP (op, 0)) != CC_REGNUM
-       || XEXP (op, 1) != const0_rtx)
-     return 0;
- 
-   return s390_branch_condition_mask (op) >= 0;
- }
- 
- /* Return nonzero if OP is a valid comparison operator
-    for an ALC condition in mode MODE.  */
- 
- int
- s390_alc_comparison (rtx op, enum machine_mode mode)
- {
-   if (mode != VOIDmode && mode != GET_MODE (op))
-     return 0;
- 
-   while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND)
-     op = XEXP (op, 0);
- 
-   if (!COMPARISON_P (op))
-     return 0;
- 
-   if (GET_CODE (XEXP (op, 0)) != REG
-       || REGNO (XEXP (op, 0)) != CC_REGNUM
-       || XEXP (op, 1) != const0_rtx)
-     return 0;
- 
-   switch (GET_MODE (XEXP (op, 0)))
-     {
-     case CCL1mode:
-       return GET_CODE (op) == LTU;
- 
-     case CCL2mode:
-       return GET_CODE (op) == LEU;
- 
-     case CCL3mode:
-       return GET_CODE (op) == GEU;
- 
-     case CCUmode:
-       return GET_CODE (op) == GTU;
- 
-     case CCURmode:
-       return GET_CODE (op) == LTU;
- 
-     case CCSmode:
-       return GET_CODE (op) == UNGT;
- 
-     case CCSRmode:
-       return GET_CODE (op) == UNLT;
- 
-     default:
-       return 0;
-     }
- }
- 
- /* Return nonzero if OP is a valid comparison operator
-    for an SLB condition in mode MODE.  */
- 
- int
- s390_slb_comparison (rtx op, enum machine_mode mode)
- {
-   if (mode != VOIDmode && mode != GET_MODE (op))
-     return 0;
- 
-   while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND)
-     op = XEXP (op, 0);
- 
-   if (!COMPARISON_P (op))
-     return 0;
- 
-   if (GET_CODE (XEXP (op, 0)) != REG
-       || REGNO (XEXP (op, 0)) != CC_REGNUM
-       || XEXP (op, 1) != const0_rtx)
-     return 0;
- 
-   switch (GET_MODE (XEXP (op, 0)))
-     {
-     case CCL1mode:
-       return GET_CODE (op) == GEU;
- 
-     case CCL2mode:
-       return GET_CODE (op) == GTU;
- 
-     case CCL3mode:
-       return GET_CODE (op) == LTU;
- 
-     case CCUmode:
-       return GET_CODE (op) == LEU;
- 
-     case CCURmode:
-       return GET_CODE (op) == GEU;
- 
-     case CCSmode:
-       return GET_CODE (op) == LE;
- 
-     case CCSRmode:
-       return GET_CODE (op) == GE;
- 
-     default:
-       return 0;
-     }
- }
- 
  /* Return branch condition mask to implement a branch
     specified by CODE.  Return -1 for invalid comparisons.  */
  
--- 805,810 ----
*************** s390_safe_attr_type (rtx insn)
*** 1508,1679 ****
      return TYPE_NONE;
  }
  
- /* Return true if OP a (const_int 0) operand.
-    OP is the current operation.
-    MODE is the current operation mode.  */
- 
- int
- const0_operand (register rtx op, enum machine_mode mode)
- {
-   return op == CONST0_RTX (mode);
- }
- 
- /* Return true if OP is constant.
-    OP is the current operation.
-    MODE is the current operation mode.  */
- 
- int
- consttable_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
- {
-   return CONSTANT_P (op);
- }
- 
- /* Return true if the mode of operand OP matches MODE.
-    If MODE is set to VOIDmode, set it to the mode of OP.  */
- 
- static int
- check_mode (register rtx op, enum machine_mode *mode)
- {
-   if (*mode == VOIDmode)
-       *mode = GET_MODE (op);
-   else
-   {
-     if (GET_MODE (op) != VOIDmode && GET_MODE (op) != *mode)
-        return 0;
-   }
-   return 1;
- }
- 
- /* Return true if OP a valid operand for the LARL instruction.
-    OP is the current operation.
-    MODE is the current operation mode.  */
- 
- int
- larl_operand (register rtx op, enum machine_mode mode)
- {
-   if (! check_mode (op, &mode))
-     return 0;
- 
-   /* Allow labels and local symbols.  */
-   if (GET_CODE (op) == LABEL_REF)
-     return 1;
-   if (GET_CODE (op) == SYMBOL_REF)
-     return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
- 	    && SYMBOL_REF_TLS_MODEL (op) == 0
- 	    && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
- 
-   /* Everything else must have a CONST, so strip it.  */
-   if (GET_CODE (op) != CONST)
-     return 0;
-   op = XEXP (op, 0);
- 
-   /* Allow adding *even* in-range constants.  */
-   if (GET_CODE (op) == PLUS)
-     {
-       if (GET_CODE (XEXP (op, 1)) != CONST_INT
-           || (INTVAL (XEXP (op, 1)) & 1) != 0)
-         return 0;
- #if HOST_BITS_PER_WIDE_INT > 32
-       if (INTVAL (XEXP (op, 1)) >= (HOST_WIDE_INT)1 << 32
- 	  || INTVAL (XEXP (op, 1)) < -((HOST_WIDE_INT)1 << 32))
-         return 0;
- #endif
-       op = XEXP (op, 0);
-     }
- 
-   /* Labels and local symbols allowed here as well.  */
-   if (GET_CODE (op) == LABEL_REF)
-     return 1;
-   if (GET_CODE (op) == SYMBOL_REF)
-     return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
- 	    && SYMBOL_REF_TLS_MODEL (op) == 0
- 	    && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
- 
-   /* Now we must have a @GOTENT offset or @PLT stub
-      or an @INDNTPOFF TLS offset.  */
-   if (GET_CODE (op) == UNSPEC
-       && XINT (op, 1) == UNSPEC_GOTENT)
-     return 1;
-   if (GET_CODE (op) == UNSPEC
-       && XINT (op, 1) == UNSPEC_PLT)
-     return 1;
-   if (GET_CODE (op) == UNSPEC
-       && XINT (op, 1) == UNSPEC_INDNTPOFF)
-     return 1;
- 
-   return 0;
- }
- 
- /* Return true if OP is a valid S-type operand.
-    OP is the current operation.
-    MODE is the current operation mode.  */
- 
- int
- s_operand (rtx op, enum machine_mode mode)
- {
-   struct s390_address addr;
- 
-   /* Call general_operand first, so that we don't have to
-      check for many special cases.  */
-   if (!general_operand (op, mode))
-     return 0;
- 
-   /* Just like memory_operand, allow (subreg (mem ...))
-      after reload.  */
-   if (reload_completed
-       && GET_CODE (op) == SUBREG
-       && GET_CODE (SUBREG_REG (op)) == MEM)
-     op = SUBREG_REG (op);
- 
-   if (GET_CODE (op) != MEM)
-     return 0;
-   if (!s390_decompose_address (XEXP (op, 0), &addr))
-     return 0;
-   if (addr.indx)
-     return 0;
- 
-   return 1;
- }
- 
- /* Return true if OP a valid shift count operand.
-    OP is the current operation.
-    MODE is the current operation mode.  */
- 
- int
- shift_count_operand (rtx op, enum machine_mode mode)
- {
-   HOST_WIDE_INT offset = 0;
- 
-   if (! check_mode (op, &mode))
-     return 0;
- 
-   /* We can have an integer constant, an address register,
-      or a sum of the two.  Note that reload already checks
-      that any register present is an address register, so
-      we just check for any register here.  */
-   if (GET_CODE (op) == CONST_INT)
-     {
-       offset = INTVAL (op);
-       op = NULL_RTX;
-     }
-   if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
-     {
-       offset = INTVAL (XEXP (op, 1));
-       op = XEXP (op, 0);
-     }
-   while (op && GET_CODE (op) == SUBREG)
-     op = SUBREG_REG (op);
-   if (op && GET_CODE (op) != REG)
-     return 0;
- 
-   /* Unfortunately we have to reject constants that are invalid
-      for an address, or else reload will get confused.  */
-   if (!DISP_IN_RANGE (offset))
-     return 0;
- 
-   return 1;
- }
- 
  /* Return true if DISP is a valid short displacement.  */
  
  static int
--- 1406,1411 ----
*************** s390_address_cost (rtx addr)
*** 2112,2138 ****
    return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
  }
  
- /* Return true if OP is a valid operand for the BRAS instruction.
-    OP is the current operation.
-    MODE is the current operation mode.  */
- 
- int
- bras_sym_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
- {
-   register enum rtx_code code = GET_CODE (op);
- 
-   /* Allow SYMBOL_REFs.  */
-   if (code == SYMBOL_REF)
-     return 1;
- 
-   /* Allow @PLT stubs.  */
-   if (code == CONST
-       && GET_CODE (XEXP (op, 0)) == UNSPEC
-       && XINT (XEXP (op, 0), 1) == UNSPEC_PLT)
-     return 1;
-   return 0;
- }
- 
  /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
     otherwise return 0.  */
  
--- 1844,1849 ----
*************** tls_symbolic_operand (register rtx op)
*** 2144,2269 ****
    return SYMBOL_REF_TLS_MODEL (op);
  }
  
- /* Return true if OP is a load multiple operation.  It is known to be a
-    PARALLEL and the first section will be tested.
-    OP is the current operation.
-    MODE is the current operation mode.  */
- 
- int
- load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
- {
-   enum machine_mode elt_mode;
-   int count = XVECLEN (op, 0);
-   unsigned int dest_regno;
-   rtx src_addr;
-   int i, off;
- 
- 
-   /* Perform a quick check so we don't blow up below.  */
-   if (count <= 1
-       || GET_CODE (XVECEXP (op, 0, 0)) != SET
-       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
-       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
-     return 0;
- 
-   dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
-   src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
-   elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0)));
- 
-   /* Check, is base, or base + displacement.  */
- 
-   if (GET_CODE (src_addr) == REG)
-     off = 0;
-   else if (GET_CODE (src_addr) == PLUS
- 	   && GET_CODE (XEXP (src_addr, 0)) == REG
- 	   && GET_CODE (XEXP (src_addr, 1)) == CONST_INT)
-     {
-       off = INTVAL (XEXP (src_addr, 1));
-       src_addr = XEXP (src_addr, 0);
-     }
-   else
-     return 0;
- 
-   for (i = 1; i < count; i++)
-     {
-       rtx elt = XVECEXP (op, 0, i);
- 
-       if (GET_CODE (elt) != SET
- 	  || GET_CODE (SET_DEST (elt)) != REG
- 	  || GET_MODE (SET_DEST (elt)) != elt_mode
- 	  || REGNO (SET_DEST (elt)) != dest_regno + i
- 	  || GET_CODE (SET_SRC (elt)) != MEM
- 	  || GET_MODE (SET_SRC (elt)) != elt_mode
- 	  || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
- 	  || ! 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))
- 	     != off + i * GET_MODE_SIZE (elt_mode))
- 	return 0;
-     }
- 
-   return 1;
- }
- 
- /* Return true if OP is a store multiple operation.  It is known to be a
-    PARALLEL and the first section will be tested.
-    OP is the current operation.
-    MODE is the current operation mode.  */
- 
- int
- store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
- {
-   enum machine_mode elt_mode;
-   int count = XVECLEN (op, 0);
-   unsigned int src_regno;
-   rtx dest_addr;
-   int i, off;
- 
-   /* Perform a quick check so we don't blow up below.  */
-   if (count <= 1
-       || GET_CODE (XVECEXP (op, 0, 0)) != SET
-       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
-       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
-     return 0;
- 
-   src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
-   dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
-   elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0)));
- 
-   /* Check, is base, or base + displacement.  */
- 
-   if (GET_CODE (dest_addr) == REG)
-     off = 0;
-   else if (GET_CODE (dest_addr) == PLUS
- 	   && GET_CODE (XEXP (dest_addr, 0)) == REG
- 	   && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT)
-     {
-       off = INTVAL (XEXP (dest_addr, 1));
-       dest_addr = XEXP (dest_addr, 0);
-     }
-   else
-     return 0;
- 
-   for (i = 1; i < count; i++)
-     {
-       rtx elt = XVECEXP (op, 0, i);
- 
-       if (GET_CODE (elt) != SET
- 	  || GET_CODE (SET_SRC (elt)) != REG
- 	  || GET_MODE (SET_SRC (elt)) != elt_mode
- 	  || REGNO (SET_SRC (elt)) != src_regno + i
- 	  || GET_CODE (SET_DEST (elt)) != MEM
- 	  || GET_MODE (SET_DEST (elt)) != elt_mode
- 	  || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
- 	  || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
- 	  || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
- 	  || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1))
- 	     != off + i * GET_MODE_SIZE (elt_mode))
- 	return 0;
-     }
-   return 1;
- }
- 
  /* Split DImode access register reference REG (on 64-bit) into its constituent
     low and high parts, and store them into LO and HI.  Note that gen_lowpart/
     gen_highpart cannot be used as they assume all registers are word-sized,
--- 1855,1860 ----
*************** s390_secondary_output_reload_class (enum
*** 2570,2595 ****
    return NO_REGS;
  }
  
- /* Return true if OP is a PLUS that is not a legitimate
-    operand for the LA instruction.
-    OP is the current operation.
-    MODE is the current operation mode.  */
- 
- int
- s390_plus_operand (register rtx op, enum machine_mode mode)
- {
-   if (!check_mode (op, &mode) || mode != Pmode)
-     return FALSE;
- 
-   if (GET_CODE (op) != PLUS)
-     return FALSE;
- 
-   if (legitimate_la_operand_p (op))
-     return FALSE;
- 
-   return TRUE;
- }
- 
  /* Generate code to load SRC, which is PLUS that is not a
     legitimate operand for the LA instruction, into TARGET.
     SCRATCH may be used as scratch register.  */
--- 2161,2166 ----
diff -C3 -pN --exclude-from=/home/l144673/.Diff_excludes ../gcc-4.1/gcc/config/s390/s390.h gcc/config/s390/s390.h
*** ../gcc-4.1/gcc/config/s390/s390.h	Wed Mar 30 23:16:43 2005
--- gcc/config/s390/s390.h	Thu Mar 31 14:16:46 2005
*************** do {									\
*** 1043,1068 ****
  
  /* Miscellaneous parameters.  */
  
- /* Define the codes that are matched by predicates in aux-output.c.  */
- #define PREDICATE_CODES							\
-   {"s_operand",       { SUBREG, MEM }},					\
-   {"shift_count_operand", { REG, SUBREG, PLUS, CONST_INT }},		\
-   {"bras_sym_operand",{ SYMBOL_REF, CONST }},				\
-   {"larl_operand",    { SYMBOL_REF, CONST, CONST_INT, CONST_DOUBLE }},	\
-   {"load_multiple_operation", {PARALLEL}},			        \
-   {"store_multiple_operation", {PARALLEL}},			        \
-   {"const0_operand",  { CONST_INT, CONST_DOUBLE }},			\
-   {"consttable_operand", { SYMBOL_REF, LABEL_REF, CONST, 		\
- 			   CONST_INT, CONST_DOUBLE }},			\
-   {"s390_plus_operand", { PLUS }},					\
-   {"s390_comparison",     { EQ, NE, LT, GT, LE, GE, LTU, GTU, LEU, GEU,	\
- 			    UNEQ, UNLT, UNGT, UNLE, UNGE, LTGT,		\
- 			    UNORDERED, ORDERED }},			\
-   {"s390_alc_comparison", { ZERO_EXTEND, SIGN_EXTEND, 			\
- 			    LTU, GTU, LEU, GEU }},			\
-   {"s390_slb_comparison", { ZERO_EXTEND, SIGN_EXTEND,			\
- 			    LTU, GTU, LEU, GEU }},
- 
  /* Specify the machine mode that this machine uses for the index in the
     tablejump instruction.  */
  #define CASE_VECTOR_MODE (TARGET_64BIT ? DImode : SImode)
--- 1043,1048 ----
*************** do {									\
*** 1083,1086 ****
--- 1063,1074 ----
     indexing purposes) so give the MEM rtx a byte's mode.  */
  #define FUNCTION_MODE QImode
  
+ /* Machine-specific symbol_ref flags.  */
+ #define SYMBOL_FLAG_ALIGN1	(SYMBOL_FLAG_MACH_DEP << 0)
+ 
+ /* Check whether integer displacement is in range.  */
+ #define DISP_IN_RANGE(d) \
+   (TARGET_LONG_DISPLACEMENT? ((d) >= -524288 && (d) <= 524287) \
+                            : ((d) >= 0 && (d) <= 4095))
+ 
  #endif
diff -C3 -pN --exclude-from=/home/l144673/.Diff_excludes ../gcc-4.1/gcc/config/s390/s390.md gcc/config/s390/s390.md
*** ../gcc-4.1/gcc/config/s390/s390.md	Thu Mar 31 13:46:35 2005
--- gcc/config/s390/s390.md	Thu Mar 31 14:16:46 2005
***************
*** 228,233 ****
--- 228,236 ----
  ;; Pipeline description for z990. 
  (include "2084.md")
  
+ ;; Predicates
+ (include "predicates.md")
+ 
  ;;
  ;;- Compare instructions.
  ;;


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