This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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.
;;