combine.c revision 52284
118334Speter/* Optimize by combining instructions for GNU compiler.
250397Sobrien   Copyright (C) 1987, 88, 92-98, 1999 Free Software Foundation, Inc.
318334Speter
418334SpeterThis file is part of GNU CC.
518334Speter
618334SpeterGNU CC is free software; you can redistribute it and/or modify
718334Speterit under the terms of the GNU General Public License as published by
818334Speterthe Free Software Foundation; either version 2, or (at your option)
918334Speterany later version.
1018334Speter
1118334SpeterGNU CC is distributed in the hope that it will be useful,
1218334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of
1318334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1418334SpeterGNU General Public License for more details.
1518334Speter
1618334SpeterYou should have received a copy of the GNU General Public License
1718334Speteralong with GNU CC; see the file COPYING.  If not, write to
1818334Speterthe Free Software Foundation, 59 Temple Place - Suite 330,
1918334SpeterBoston, MA 02111-1307, USA.  */
2018334Speter
2118334Speter
2218334Speter/* This module is essentially the "combiner" phase of the U. of Arizona
2318334Speter   Portable Optimizer, but redone to work on our list-structured
2418334Speter   representation for RTL instead of their string representation.
2518334Speter
2618334Speter   The LOG_LINKS of each insn identify the most recent assignment
2718334Speter   to each REG used in the insn.  It is a list of previous insns,
2818334Speter   each of which contains a SET for a REG that is used in this insn
2918334Speter   and not used or set in between.  LOG_LINKs never cross basic blocks.
3018334Speter   They were set up by the preceding pass (lifetime analysis).
3118334Speter
3218334Speter   We try to combine each pair of insns joined by a logical link.
3318334Speter   We also try to combine triples of insns A, B and C when
3418334Speter   C has a link back to B and B has a link back to A.
3518334Speter
3618334Speter   LOG_LINKS does not have links for use of the CC0.  They don't
3718334Speter   need to, because the insn that sets the CC0 is always immediately
3818334Speter   before the insn that tests it.  So we always regard a branch
3918334Speter   insn as having a logical link to the preceding insn.  The same is true
4018334Speter   for an insn explicitly using CC0.
4118334Speter
4218334Speter   We check (with use_crosses_set_p) to avoid combining in such a way
4318334Speter   as to move a computation to a place where its value would be different.
4418334Speter
4518334Speter   Combination is done by mathematically substituting the previous
4618334Speter   insn(s) values for the regs they set into the expressions in
4718334Speter   the later insns that refer to these regs.  If the result is a valid insn
4818334Speter   for our target machine, according to the machine description,
4918334Speter   we install it, delete the earlier insns, and update the data flow
5018334Speter   information (LOG_LINKS and REG_NOTES) for what we did.
5118334Speter
5218334Speter   There are a few exceptions where the dataflow information created by
5318334Speter   flow.c aren't completely updated:
5418334Speter
5518334Speter   - reg_live_length is not updated
5618334Speter   - reg_n_refs is not adjusted in the rare case when a register is
5718334Speter     no longer required in a computation
5818334Speter   - there are extremely rare cases (see distribute_regnotes) when a
5918334Speter     REG_DEAD note is lost
6018334Speter   - a LOG_LINKS entry that refers to an insn with multiple SETs may be
6118334Speter     removed because there is no way to know which register it was
6218334Speter     linking
6318334Speter
6418334Speter   To simplify substitution, we combine only when the earlier insn(s)
6518334Speter   consist of only a single assignment.  To simplify updating afterward,
6618334Speter   we never combine when a subroutine call appears in the middle.
6718334Speter
6818334Speter   Since we do not represent assignments to CC0 explicitly except when that
6918334Speter   is all an insn does, there is no LOG_LINKS entry in an insn that uses
7018334Speter   the condition code for the insn that set the condition code.
7118334Speter   Fortunately, these two insns must be consecutive.
7218334Speter   Therefore, every JUMP_INSN is taken to have an implicit logical link
7318334Speter   to the preceding insn.  This is not quite right, since non-jumps can
7418334Speter   also use the condition code; but in practice such insns would not
7518334Speter   combine anyway.  */
7618334Speter
7718334Speter#include "config.h"
7850397Sobrien#include "system.h"
7952284Sobrien#include "rtl.h" /* stdio.h must precede rtl.h for FFS.  */
8018334Speter#include "flags.h"
8118334Speter#include "regs.h"
8218334Speter#include "hard-reg-set.h"
8318334Speter#include "basic-block.h"
8418334Speter#include "insn-config.h"
8550397Sobrien/* Include expr.h after insn-config.h so we get HAVE_conditional_move. */
8650397Sobrien#include "expr.h"
8718334Speter#include "insn-flags.h"
8818334Speter#include "insn-codes.h"
8918334Speter#include "insn-attr.h"
9018334Speter#include "recog.h"
9118334Speter#include "real.h"
9250397Sobrien#include "toplev.h"
9318334Speter
9418334Speter/* It is not safe to use ordinary gen_lowpart in combine.
9518334Speter   Use gen_lowpart_for_combine instead.  See comments there.  */
9618334Speter#define gen_lowpart dont_use_gen_lowpart_you_dummy
9718334Speter
9818334Speter/* Number of attempts to combine instructions in this function.  */
9918334Speter
10018334Speterstatic int combine_attempts;
10118334Speter
10218334Speter/* Number of attempts that got as far as substitution in this function.  */
10318334Speter
10418334Speterstatic int combine_merges;
10518334Speter
10618334Speter/* Number of instructions combined with added SETs in this function.  */
10718334Speter
10818334Speterstatic int combine_extras;
10918334Speter
11018334Speter/* Number of instructions combined in this function.  */
11118334Speter
11218334Speterstatic int combine_successes;
11318334Speter
11418334Speter/* Totals over entire compilation.  */
11518334Speter
11618334Speterstatic int total_attempts, total_merges, total_extras, total_successes;
11718334Speter
11818334Speter/* Define a default value for REVERSIBLE_CC_MODE.
11918334Speter   We can never assume that a condition code mode is safe to reverse unless
12018334Speter   the md tells us so.  */
12118334Speter#ifndef REVERSIBLE_CC_MODE
12218334Speter#define REVERSIBLE_CC_MODE(MODE) 0
12318334Speter#endif
12418334Speter
12518334Speter/* Vector mapping INSN_UIDs to cuids.
12618334Speter   The cuids are like uids but increase monotonically always.
12718334Speter   Combine always uses cuids so that it can compare them.
12818334Speter   But actually renumbering the uids, which we used to do,
12918334Speter   proves to be a bad idea because it makes it hard to compare
13018334Speter   the dumps produced by earlier passes with those from later passes.  */
13118334Speter
13218334Speterstatic int *uid_cuid;
13318334Speterstatic int max_uid_cuid;
13418334Speter
13518334Speter/* Get the cuid of an insn.  */
13618334Speter
13750397Sobrien#define INSN_CUID(INSN) \
13850397Sobrien(INSN_UID (INSN) > max_uid_cuid ? insn_cuid (INSN) : uid_cuid[INSN_UID (INSN)])
13918334Speter
14018334Speter/* Maximum register number, which is the size of the tables below.  */
14118334Speter
14218334Speterstatic int combine_max_regno;
14318334Speter
14418334Speter/* Record last point of death of (hard or pseudo) register n.  */
14518334Speter
14618334Speterstatic rtx *reg_last_death;
14718334Speter
14818334Speter/* Record last point of modification of (hard or pseudo) register n.  */
14918334Speter
15018334Speterstatic rtx *reg_last_set;
15118334Speter
15218334Speter/* Record the cuid of the last insn that invalidated memory
15318334Speter   (anything that writes memory, and subroutine calls, but not pushes).  */
15418334Speter
15518334Speterstatic int mem_last_set;
15618334Speter
15718334Speter/* Record the cuid of the last CALL_INSN
15818334Speter   so we can tell whether a potential combination crosses any calls.  */
15918334Speter
16018334Speterstatic int last_call_cuid;
16118334Speter
16218334Speter/* When `subst' is called, this is the insn that is being modified
16318334Speter   (by combining in a previous insn).  The PATTERN of this insn
16418334Speter   is still the old pattern partially modified and it should not be
16518334Speter   looked at, but this may be used to examine the successors of the insn
16618334Speter   to judge whether a simplification is valid.  */
16718334Speter
16818334Speterstatic rtx subst_insn;
16918334Speter
17018334Speter/* This is an insn that belongs before subst_insn, but is not currently
17118334Speter   on the insn chain.  */
17218334Speter
17318334Speterstatic rtx subst_prev_insn;
17418334Speter
17518334Speter/* This is the lowest CUID that `subst' is currently dealing with.
17618334Speter   get_last_value will not return a value if the register was set at or
17718334Speter   after this CUID.  If not for this mechanism, we could get confused if
17818334Speter   I2 or I1 in try_combine were an insn that used the old value of a register
17918334Speter   to obtain a new value.  In that case, we might erroneously get the
18018334Speter   new value of the register when we wanted the old one.  */
18118334Speter
18218334Speterstatic int subst_low_cuid;
18318334Speter
18418334Speter/* This contains any hard registers that are used in newpat; reg_dead_at_p
18518334Speter   must consider all these registers to be always live.  */
18618334Speter
18718334Speterstatic HARD_REG_SET newpat_used_regs;
18818334Speter
18918334Speter/* This is an insn to which a LOG_LINKS entry has been added.  If this
19018334Speter   insn is the earlier than I2 or I3, combine should rescan starting at
19118334Speter   that location.  */
19218334Speter
19318334Speterstatic rtx added_links_insn;
19418334Speter
19518334Speter/* Basic block number of the block in which we are performing combines.  */
19618334Speterstatic int this_basic_block;
19718334Speter
19818334Speter/* The next group of arrays allows the recording of the last value assigned
19918334Speter   to (hard or pseudo) register n.  We use this information to see if a
20018334Speter   operation being processed is redundant given a prior operation performed
20118334Speter   on the register.  For example, an `and' with a constant is redundant if
20218334Speter   all the zero bits are already known to be turned off.
20318334Speter
20418334Speter   We use an approach similar to that used by cse, but change it in the
20518334Speter   following ways:
20618334Speter
20718334Speter   (1) We do not want to reinitialize at each label.
20818334Speter   (2) It is useful, but not critical, to know the actual value assigned
20918334Speter       to a register.  Often just its form is helpful.
21018334Speter
21118334Speter   Therefore, we maintain the following arrays:
21218334Speter
21318334Speter   reg_last_set_value		the last value assigned
21418334Speter   reg_last_set_label		records the value of label_tick when the
21518334Speter				register was assigned
21618334Speter   reg_last_set_table_tick	records the value of label_tick when a
21718334Speter				value using the register is assigned
21818334Speter   reg_last_set_invalid		set to non-zero when it is not valid
21918334Speter				to use the value of this register in some
22018334Speter				register's value
22118334Speter
22218334Speter   To understand the usage of these tables, it is important to understand
22318334Speter   the distinction between the value in reg_last_set_value being valid
22418334Speter   and the register being validly contained in some other expression in the
22518334Speter   table.
22618334Speter
22718334Speter   Entry I in reg_last_set_value is valid if it is non-zero, and either
22818334Speter   reg_n_sets[i] is 1 or reg_last_set_label[i] == label_tick.
22918334Speter
23018334Speter   Register I may validly appear in any expression returned for the value
23118334Speter   of another register if reg_n_sets[i] is 1.  It may also appear in the
23218334Speter   value for register J if reg_last_set_label[i] < reg_last_set_label[j] or
23318334Speter   reg_last_set_invalid[j] is zero.
23418334Speter
23518334Speter   If an expression is found in the table containing a register which may
23618334Speter   not validly appear in an expression, the register is replaced by
23718334Speter   something that won't match, (clobber (const_int 0)).
23818334Speter
23918334Speter   reg_last_set_invalid[i] is set non-zero when register I is being assigned
24018334Speter   to and reg_last_set_table_tick[i] == label_tick.  */
24118334Speter
24250397Sobrien/* Record last value assigned to (hard or pseudo) register n.  */
24318334Speter
24418334Speterstatic rtx *reg_last_set_value;
24518334Speter
24618334Speter/* Record the value of label_tick when the value for register n is placed in
24718334Speter   reg_last_set_value[n].  */
24818334Speter
24918334Speterstatic int *reg_last_set_label;
25018334Speter
25118334Speter/* Record the value of label_tick when an expression involving register n
25250397Sobrien   is placed in reg_last_set_value.  */
25318334Speter
25418334Speterstatic int *reg_last_set_table_tick;
25518334Speter
25618334Speter/* Set non-zero if references to register n in expressions should not be
25718334Speter   used.  */
25818334Speter
25918334Speterstatic char *reg_last_set_invalid;
26018334Speter
26150397Sobrien/* Incremented for each label.  */
26218334Speter
26318334Speterstatic int label_tick;
26418334Speter
26518334Speter/* Some registers that are set more than once and used in more than one
26618334Speter   basic block are nevertheless always set in similar ways.  For example,
26718334Speter   a QImode register may be loaded from memory in two places on a machine
26818334Speter   where byte loads zero extend.
26918334Speter
27018334Speter   We record in the following array what we know about the nonzero
27118334Speter   bits of a register, specifically which bits are known to be zero.
27218334Speter
27318334Speter   If an entry is zero, it means that we don't know anything special.  */
27418334Speter
27518334Speterstatic unsigned HOST_WIDE_INT *reg_nonzero_bits;
27618334Speter
27718334Speter/* Mode used to compute significance in reg_nonzero_bits.  It is the largest
27818334Speter   integer mode that can fit in HOST_BITS_PER_WIDE_INT.  */
27918334Speter
28018334Speterstatic enum machine_mode nonzero_bits_mode;
28118334Speter
28218334Speter/* Nonzero if we know that a register has some leading bits that are always
28318334Speter   equal to the sign bit.  */
28418334Speter
28518334Speterstatic char *reg_sign_bit_copies;
28618334Speter
28718334Speter/* Nonzero when reg_nonzero_bits and reg_sign_bit_copies can be safely used.
28818334Speter   It is zero while computing them and after combine has completed.  This
28918334Speter   former test prevents propagating values based on previously set values,
29018334Speter   which can be incorrect if a variable is modified in a loop.  */
29118334Speter
29218334Speterstatic int nonzero_sign_valid;
29318334Speter
29418334Speter/* These arrays are maintained in parallel with reg_last_set_value
29518334Speter   and are used to store the mode in which the register was last set,
29618334Speter   the bits that were known to be zero when it was last set, and the
29718334Speter   number of sign bits copies it was known to have when it was last set.  */
29818334Speter
29918334Speterstatic enum machine_mode *reg_last_set_mode;
30018334Speterstatic unsigned HOST_WIDE_INT *reg_last_set_nonzero_bits;
30118334Speterstatic char *reg_last_set_sign_bit_copies;
30218334Speter
30318334Speter/* Record one modification to rtl structure
30418334Speter   to be undone by storing old_contents into *where.
30518334Speter   is_int is 1 if the contents are an int.  */
30618334Speter
30718334Speterstruct undo
30818334Speter{
30950397Sobrien  struct undo *next;
31018334Speter  int is_int;
31118334Speter  union {rtx r; int i;} old_contents;
31218334Speter  union {rtx *r; int *i;} where;
31318334Speter};
31418334Speter
31518334Speter/* Record a bunch of changes to be undone, up to MAX_UNDO of them.
31618334Speter   num_undo says how many are currently recorded.
31718334Speter
31818334Speter   storage is nonzero if we must undo the allocation of new storage.
31918334Speter   The value of storage is what to pass to obfree.
32018334Speter
32118334Speter   other_insn is nonzero if we have modified some other insn in the process
32250397Sobrien   of working on subst_insn.  It must be verified too.
32318334Speter
32450397Sobrien   previous_undos is the value of undobuf.undos when we started processing
32550397Sobrien   this substitution.  This will prevent gen_rtx_combine from re-used a piece
32650397Sobrien   from the previous expression.  Doing so can produce circular rtl
32750397Sobrien   structures.  */
32818334Speter
32918334Speterstruct undobuf
33018334Speter{
33118334Speter  char *storage;
33250397Sobrien  struct undo *undos;
33350397Sobrien  struct undo *frees;
33450397Sobrien  struct undo *previous_undos;
33518334Speter  rtx other_insn;
33618334Speter};
33718334Speter
33818334Speterstatic struct undobuf undobuf;
33918334Speter
34018334Speter/* Substitute NEWVAL, an rtx expression, into INTO, a place in some
34118334Speter   insn.  The substitution can be undone by undo_all.  If INTO is already
34218334Speter   set to NEWVAL, do not record this change.  Because computing NEWVAL might
34318334Speter   also call SUBST, we have to compute it before we put anything into
34418334Speter   the undo table.  */
34518334Speter
34618334Speter#define SUBST(INTO, NEWVAL)  \
34750397Sobrien do { rtx _new = (NEWVAL);					\
34850397Sobrien      struct undo *_buf;					\
34950397Sobrien								\
35050397Sobrien      if (undobuf.frees)					\
35150397Sobrien	_buf = undobuf.frees, undobuf.frees = _buf->next;	\
35250397Sobrien      else							\
35350397Sobrien	_buf = (struct undo *) xmalloc (sizeof (struct undo));	\
35450397Sobrien								\
35550397Sobrien      _buf->is_int = 0;						\
35650397Sobrien      _buf->where.r = &INTO;					\
35750397Sobrien      _buf->old_contents.r = INTO;				\
35850397Sobrien      INTO = _new;						\
35950397Sobrien      if (_buf->old_contents.r == INTO)				\
36050397Sobrien	_buf->next = undobuf.frees, undobuf.frees = _buf;	\
36150397Sobrien      else							\
36250397Sobrien	_buf->next = undobuf.undos, undobuf.undos = _buf;	\
36318334Speter    } while (0)
36418334Speter
36550397Sobrien/* Similar to SUBST, but NEWVAL is an int expression.  Note that substitution
36650397Sobrien   for the value of a HOST_WIDE_INT value (including CONST_INT) is
36750397Sobrien   not safe.  */
36818334Speter
36918334Speter#define SUBST_INT(INTO, NEWVAL)  \
37050397Sobrien do { struct undo *_buf;					\
37150397Sobrien								\
37250397Sobrien      if (undobuf.frees)					\
37350397Sobrien	_buf = undobuf.frees, undobuf.frees = _buf->next;	\
37450397Sobrien      else							\
37550397Sobrien	_buf = (struct undo *) xmalloc (sizeof (struct undo));	\
37650397Sobrien								\
37750397Sobrien      _buf->is_int = 1;						\
37850397Sobrien      _buf->where.i = (int *) &INTO;				\
37950397Sobrien      _buf->old_contents.i = INTO;				\
38050397Sobrien      INTO = NEWVAL;						\
38150397Sobrien      if (_buf->old_contents.i == INTO)				\
38250397Sobrien	_buf->next = undobuf.frees, undobuf.frees = _buf;	\
38350397Sobrien      else							\
38450397Sobrien	_buf->next = undobuf.undos, undobuf.undos = _buf;	\
38518334Speter     } while (0)
38618334Speter
38718334Speter/* Number of times the pseudo being substituted for
38818334Speter   was found and replaced.  */
38918334Speter
39018334Speterstatic int n_occurrences;
39118334Speter
39250397Sobrienstatic void init_reg_last_arrays	PROTO((void));
39350397Sobrienstatic void setup_incoming_promotions   PROTO((void));
39418334Speterstatic void set_nonzero_bits_and_sign_copies  PROTO((rtx, rtx));
39518334Speterstatic int can_combine_p	PROTO((rtx, rtx, rtx, rtx, rtx *, rtx *));
39650397Sobrienstatic int sets_function_arg_p	PROTO((rtx));
39718334Speterstatic int combinable_i3pat	PROTO((rtx, rtx *, rtx, rtx, int, rtx *));
39818334Speterstatic rtx try_combine		PROTO((rtx, rtx, rtx));
39918334Speterstatic void undo_all		PROTO((void));
40018334Speterstatic rtx *find_split_point	PROTO((rtx *, rtx));
40118334Speterstatic rtx subst		PROTO((rtx, rtx, rtx, int, int));
40218334Speterstatic rtx simplify_rtx		PROTO((rtx, enum machine_mode, int, int));
40318334Speterstatic rtx simplify_if_then_else  PROTO((rtx));
40418334Speterstatic rtx simplify_set		PROTO((rtx));
40518334Speterstatic rtx simplify_logical	PROTO((rtx, int));
40618334Speterstatic rtx expand_compound_operation  PROTO((rtx));
40718334Speterstatic rtx expand_field_assignment  PROTO((rtx));
40818334Speterstatic rtx make_extraction	PROTO((enum machine_mode, rtx, int, rtx, int,
40918334Speter				       int, int, int));
41018334Speterstatic rtx extract_left_shift	PROTO((rtx, int));
41118334Speterstatic rtx make_compound_operation  PROTO((rtx, enum rtx_code));
41218334Speterstatic int get_pos_from_mask	PROTO((unsigned HOST_WIDE_INT, int *));
41318334Speterstatic rtx force_to_mode	PROTO((rtx, enum machine_mode,
41418334Speter				       unsigned HOST_WIDE_INT, rtx, int));
41518334Speterstatic rtx if_then_else_cond	PROTO((rtx, rtx *, rtx *));
41618334Speterstatic rtx known_cond		PROTO((rtx, enum rtx_code, rtx, rtx));
41750397Sobrienstatic int rtx_equal_for_field_assignment_p PROTO((rtx, rtx));
41818334Speterstatic rtx make_field_assignment  PROTO((rtx));
41918334Speterstatic rtx apply_distributive_law  PROTO((rtx));
42018334Speterstatic rtx simplify_and_const_int  PROTO((rtx, enum machine_mode, rtx,
42118334Speter					  unsigned HOST_WIDE_INT));
42218334Speterstatic unsigned HOST_WIDE_INT nonzero_bits  PROTO((rtx, enum machine_mode));
42318334Speterstatic int num_sign_bit_copies  PROTO((rtx, enum machine_mode));
42418334Speterstatic int merge_outer_ops	PROTO((enum rtx_code *, HOST_WIDE_INT *,
42518334Speter				       enum rtx_code, HOST_WIDE_INT,
42618334Speter				       enum machine_mode, int *));
42718334Speterstatic rtx simplify_shift_const	PROTO((rtx, enum rtx_code, enum machine_mode,
42818334Speter				       rtx, int));
42952284Sobrienstatic int recog_for_combine	PROTO((rtx *, rtx, rtx *));
43018334Speterstatic rtx gen_lowpart_for_combine  PROTO((enum machine_mode, rtx));
43118334Speterstatic rtx gen_rtx_combine PVPROTO((enum rtx_code code, enum machine_mode mode,
43218334Speter				  ...));
43318334Speterstatic rtx gen_binary		PROTO((enum rtx_code, enum machine_mode,
43418334Speter				       rtx, rtx));
43518334Speterstatic rtx gen_unary		PROTO((enum rtx_code, enum machine_mode,
43618334Speter				       enum machine_mode, rtx));
43718334Speterstatic enum rtx_code simplify_comparison  PROTO((enum rtx_code, rtx *, rtx *));
43818334Speterstatic int reversible_comparison_p  PROTO((rtx));
43918334Speterstatic void update_table_tick	PROTO((rtx));
44018334Speterstatic void record_value_for_reg  PROTO((rtx, rtx, rtx));
44118334Speterstatic void record_dead_and_set_regs_1  PROTO((rtx, rtx));
44218334Speterstatic void record_dead_and_set_regs  PROTO((rtx));
44350397Sobrienstatic int get_last_value_validate  PROTO((rtx *, rtx, int, int));
44418334Speterstatic rtx get_last_value	PROTO((rtx));
44518334Speterstatic int use_crosses_set_p	PROTO((rtx, int));
44618334Speterstatic void reg_dead_at_p_1	PROTO((rtx, rtx));
44718334Speterstatic int reg_dead_at_p	PROTO((rtx, rtx));
44850397Sobrienstatic void move_deaths		PROTO((rtx, rtx, int, rtx, rtx *));
44918334Speterstatic int reg_bitfield_target_p  PROTO((rtx, rtx));
45018334Speterstatic void distribute_notes	PROTO((rtx, rtx, rtx, rtx, rtx, rtx));
45118334Speterstatic void distribute_links	PROTO((rtx));
45218334Speterstatic void mark_used_regs_combine PROTO((rtx));
45350397Sobrienstatic int insn_cuid		PROTO((rtx));
45418334Speter
45518334Speter/* Main entry point for combiner.  F is the first insn of the function.
45618334Speter   NREGS is the first unused pseudo-reg number.  */
45718334Speter
45818334Spetervoid
45918334Spetercombine_instructions (f, nregs)
46018334Speter     rtx f;
46118334Speter     int nregs;
46218334Speter{
46350397Sobrien  register rtx insn, next;
46450397Sobrien#ifdef HAVE_cc0
46550397Sobrien  register rtx prev;
46650397Sobrien#endif
46718334Speter  register int i;
46818334Speter  register rtx links, nextlinks;
46918334Speter
47018334Speter  combine_attempts = 0;
47118334Speter  combine_merges = 0;
47218334Speter  combine_extras = 0;
47318334Speter  combine_successes = 0;
47450397Sobrien  undobuf.undos = undobuf.previous_undos = 0;
47518334Speter
47618334Speter  combine_max_regno = nregs;
47718334Speter
47818334Speter  reg_nonzero_bits
47918334Speter    = (unsigned HOST_WIDE_INT *) alloca (nregs * sizeof (HOST_WIDE_INT));
48018334Speter  reg_sign_bit_copies = (char *) alloca (nregs * sizeof (char));
48118334Speter
48218334Speter  bzero ((char *) reg_nonzero_bits, nregs * sizeof (HOST_WIDE_INT));
48318334Speter  bzero (reg_sign_bit_copies, nregs * sizeof (char));
48418334Speter
48518334Speter  reg_last_death = (rtx *) alloca (nregs * sizeof (rtx));
48618334Speter  reg_last_set = (rtx *) alloca (nregs * sizeof (rtx));
48718334Speter  reg_last_set_value = (rtx *) alloca (nregs * sizeof (rtx));
48818334Speter  reg_last_set_table_tick = (int *) alloca (nregs * sizeof (int));
48918334Speter  reg_last_set_label = (int *) alloca (nregs * sizeof (int));
49018334Speter  reg_last_set_invalid = (char *) alloca (nregs * sizeof (char));
49118334Speter  reg_last_set_mode
49218334Speter    = (enum machine_mode *) alloca (nregs * sizeof (enum machine_mode));
49318334Speter  reg_last_set_nonzero_bits
49418334Speter    = (unsigned HOST_WIDE_INT *) alloca (nregs * sizeof (HOST_WIDE_INT));
49518334Speter  reg_last_set_sign_bit_copies
49618334Speter    = (char *) alloca (nregs * sizeof (char));
49718334Speter
49818334Speter  init_reg_last_arrays ();
49918334Speter
50018334Speter  init_recog_no_volatile ();
50118334Speter
50218334Speter  /* Compute maximum uid value so uid_cuid can be allocated.  */
50318334Speter
50418334Speter  for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
50518334Speter    if (INSN_UID (insn) > i)
50618334Speter      i = INSN_UID (insn);
50718334Speter
50818334Speter  uid_cuid = (int *) alloca ((i + 1) * sizeof (int));
50918334Speter  max_uid_cuid = i;
51018334Speter
51118334Speter  nonzero_bits_mode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
51218334Speter
51318334Speter  /* Don't use reg_nonzero_bits when computing it.  This can cause problems
51418334Speter     when, for example, we have j <<= 1 in a loop.  */
51518334Speter
51618334Speter  nonzero_sign_valid = 0;
51718334Speter
51818334Speter  /* Compute the mapping from uids to cuids.
51918334Speter     Cuids are numbers assigned to insns, like uids,
52018334Speter     except that cuids increase monotonically through the code.
52118334Speter
52218334Speter     Scan all SETs and see if we can deduce anything about what
52318334Speter     bits are known to be zero for some registers and how many copies
52418334Speter     of the sign bit are known to exist for those registers.
52518334Speter
52618334Speter     Also set any known values so that we can use it while searching
52718334Speter     for what bits are known to be set.  */
52818334Speter
52918334Speter  label_tick = 1;
53018334Speter
53118334Speter  /* We need to initialize it here, because record_dead_and_set_regs may call
53218334Speter     get_last_value.  */
53318334Speter  subst_prev_insn = NULL_RTX;
53418334Speter
53518334Speter  setup_incoming_promotions ();
53618334Speter
53718334Speter  for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
53818334Speter    {
53918334Speter      uid_cuid[INSN_UID (insn)] = ++i;
54018334Speter      subst_low_cuid = i;
54118334Speter      subst_insn = insn;
54218334Speter
54318334Speter      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
54418334Speter	{
54518334Speter	  note_stores (PATTERN (insn), set_nonzero_bits_and_sign_copies);
54618334Speter	  record_dead_and_set_regs (insn);
54750397Sobrien
54850397Sobrien#ifdef AUTO_INC_DEC
54950397Sobrien	  for (links = REG_NOTES (insn); links; links = XEXP (links, 1))
55050397Sobrien	    if (REG_NOTE_KIND (links) == REG_INC)
55150397Sobrien	      set_nonzero_bits_and_sign_copies (XEXP (links, 0), NULL_RTX);
55250397Sobrien#endif
55318334Speter	}
55418334Speter
55518334Speter      if (GET_CODE (insn) == CODE_LABEL)
55618334Speter	label_tick++;
55718334Speter    }
55818334Speter
55918334Speter  nonzero_sign_valid = 1;
56018334Speter
56118334Speter  /* Now scan all the insns in forward order.  */
56218334Speter
56318334Speter  this_basic_block = -1;
56418334Speter  label_tick = 1;
56518334Speter  last_call_cuid = 0;
56618334Speter  mem_last_set = 0;
56718334Speter  init_reg_last_arrays ();
56818334Speter  setup_incoming_promotions ();
56918334Speter
57018334Speter  for (insn = f; insn; insn = next ? next : NEXT_INSN (insn))
57118334Speter    {
57218334Speter      next = 0;
57318334Speter
57418334Speter      /* If INSN starts a new basic block, update our basic block number.  */
57518334Speter      if (this_basic_block + 1 < n_basic_blocks
57652284Sobrien	  && BLOCK_HEAD (this_basic_block + 1) == insn)
57718334Speter	this_basic_block++;
57818334Speter
57918334Speter      if (GET_CODE (insn) == CODE_LABEL)
58018334Speter	label_tick++;
58118334Speter
58218334Speter      else if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
58318334Speter	{
58418334Speter	  /* Try this insn with each insn it links back to.  */
58518334Speter
58618334Speter	  for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
58718334Speter	    if ((next = try_combine (insn, XEXP (links, 0), NULL_RTX)) != 0)
58818334Speter	      goto retry;
58918334Speter
59018334Speter	  /* Try each sequence of three linked insns ending with this one.  */
59118334Speter
59218334Speter	  for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
59318334Speter	    for (nextlinks = LOG_LINKS (XEXP (links, 0)); nextlinks;
59418334Speter		 nextlinks = XEXP (nextlinks, 1))
59518334Speter	      if ((next = try_combine (insn, XEXP (links, 0),
59618334Speter				       XEXP (nextlinks, 0))) != 0)
59718334Speter		goto retry;
59818334Speter
59918334Speter#ifdef HAVE_cc0
60018334Speter	  /* Try to combine a jump insn that uses CC0
60118334Speter	     with a preceding insn that sets CC0, and maybe with its
60218334Speter	     logical predecessor as well.
60318334Speter	     This is how we make decrement-and-branch insns.
60418334Speter	     We need this special code because data flow connections
60518334Speter	     via CC0 do not get entered in LOG_LINKS.  */
60618334Speter
60718334Speter	  if (GET_CODE (insn) == JUMP_INSN
60818334Speter	      && (prev = prev_nonnote_insn (insn)) != 0
60918334Speter	      && GET_CODE (prev) == INSN
61018334Speter	      && sets_cc0_p (PATTERN (prev)))
61118334Speter	    {
61218334Speter	      if ((next = try_combine (insn, prev, NULL_RTX)) != 0)
61318334Speter		goto retry;
61418334Speter
61518334Speter	      for (nextlinks = LOG_LINKS (prev); nextlinks;
61618334Speter		   nextlinks = XEXP (nextlinks, 1))
61718334Speter		if ((next = try_combine (insn, prev,
61818334Speter					 XEXP (nextlinks, 0))) != 0)
61918334Speter		  goto retry;
62018334Speter	    }
62118334Speter
62218334Speter	  /* Do the same for an insn that explicitly references CC0.  */
62318334Speter	  if (GET_CODE (insn) == INSN
62418334Speter	      && (prev = prev_nonnote_insn (insn)) != 0
62518334Speter	      && GET_CODE (prev) == INSN
62618334Speter	      && sets_cc0_p (PATTERN (prev))
62718334Speter	      && GET_CODE (PATTERN (insn)) == SET
62818334Speter	      && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (insn))))
62918334Speter	    {
63018334Speter	      if ((next = try_combine (insn, prev, NULL_RTX)) != 0)
63118334Speter		goto retry;
63218334Speter
63318334Speter	      for (nextlinks = LOG_LINKS (prev); nextlinks;
63418334Speter		   nextlinks = XEXP (nextlinks, 1))
63518334Speter		if ((next = try_combine (insn, prev,
63618334Speter					 XEXP (nextlinks, 0))) != 0)
63718334Speter		  goto retry;
63818334Speter	    }
63918334Speter
64018334Speter	  /* Finally, see if any of the insns that this insn links to
64118334Speter	     explicitly references CC0.  If so, try this insn, that insn,
64218334Speter	     and its predecessor if it sets CC0.  */
64318334Speter	  for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
64418334Speter	    if (GET_CODE (XEXP (links, 0)) == INSN
64518334Speter		&& GET_CODE (PATTERN (XEXP (links, 0))) == SET
64618334Speter		&& reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (XEXP (links, 0))))
64718334Speter		&& (prev = prev_nonnote_insn (XEXP (links, 0))) != 0
64818334Speter		&& GET_CODE (prev) == INSN
64918334Speter		&& sets_cc0_p (PATTERN (prev))
65018334Speter		&& (next = try_combine (insn, XEXP (links, 0), prev)) != 0)
65118334Speter	      goto retry;
65218334Speter#endif
65318334Speter
65418334Speter	  /* Try combining an insn with two different insns whose results it
65518334Speter	     uses.  */
65618334Speter	  for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
65718334Speter	    for (nextlinks = XEXP (links, 1); nextlinks;
65818334Speter		 nextlinks = XEXP (nextlinks, 1))
65918334Speter	      if ((next = try_combine (insn, XEXP (links, 0),
66018334Speter				       XEXP (nextlinks, 0))) != 0)
66118334Speter		goto retry;
66218334Speter
66318334Speter	  if (GET_CODE (insn) != NOTE)
66418334Speter	    record_dead_and_set_regs (insn);
66518334Speter
66618334Speter	retry:
66718334Speter	  ;
66818334Speter	}
66918334Speter    }
67018334Speter
67118334Speter  total_attempts += combine_attempts;
67218334Speter  total_merges += combine_merges;
67318334Speter  total_extras += combine_extras;
67418334Speter  total_successes += combine_successes;
67518334Speter
67618334Speter  nonzero_sign_valid = 0;
67752284Sobrien
67852284Sobrien  /* Make recognizer allow volatile MEMs again.  */
67952284Sobrien  init_recog ();
68018334Speter}
68118334Speter
68218334Speter/* Wipe the reg_last_xxx arrays in preparation for another pass.  */
68318334Speter
68418334Speterstatic void
68518334Speterinit_reg_last_arrays ()
68618334Speter{
68718334Speter  int nregs = combine_max_regno;
68818334Speter
68918334Speter  bzero ((char *) reg_last_death, nregs * sizeof (rtx));
69018334Speter  bzero ((char *) reg_last_set, nregs * sizeof (rtx));
69118334Speter  bzero ((char *) reg_last_set_value, nregs * sizeof (rtx));
69218334Speter  bzero ((char *) reg_last_set_table_tick, nregs * sizeof (int));
69318334Speter  bzero ((char *) reg_last_set_label, nregs * sizeof (int));
69418334Speter  bzero (reg_last_set_invalid, nregs * sizeof (char));
69518334Speter  bzero ((char *) reg_last_set_mode, nregs * sizeof (enum machine_mode));
69618334Speter  bzero ((char *) reg_last_set_nonzero_bits, nregs * sizeof (HOST_WIDE_INT));
69718334Speter  bzero (reg_last_set_sign_bit_copies, nregs * sizeof (char));
69818334Speter}
69918334Speter
70018334Speter/* Set up any promoted values for incoming argument registers.  */
70118334Speter
70218334Speterstatic void
70318334Spetersetup_incoming_promotions ()
70418334Speter{
70518334Speter#ifdef PROMOTE_FUNCTION_ARGS
70618334Speter  int regno;
70718334Speter  rtx reg;
70818334Speter  enum machine_mode mode;
70918334Speter  int unsignedp;
71018334Speter  rtx first = get_insns ();
71118334Speter
71218334Speter  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
71318334Speter    if (FUNCTION_ARG_REGNO_P (regno)
71418334Speter	&& (reg = promoted_input_arg (regno, &mode, &unsignedp)) != 0)
71550397Sobrien      {
71650397Sobrien	record_value_for_reg
71750397Sobrien	  (reg, first, gen_rtx_fmt_e ((unsignedp ? ZERO_EXTEND
71850397Sobrien				       : SIGN_EXTEND),
71950397Sobrien				      GET_MODE (reg),
72050397Sobrien				      gen_rtx_CLOBBER (mode, const0_rtx)));
72150397Sobrien      }
72218334Speter#endif
72318334Speter}
72418334Speter
72550397Sobrien/* Called via note_stores.  If X is a pseudo that is narrower than
72650397Sobrien   HOST_BITS_PER_WIDE_INT and is being set, record what bits are known zero.
72718334Speter
72818334Speter   If we are setting only a portion of X and we can't figure out what
72918334Speter   portion, assume all bits will be used since we don't know what will
73018334Speter   be happening.
73118334Speter
73218334Speter   Similarly, set how many bits of X are known to be copies of the sign bit
73318334Speter   at all locations in the function.  This is the smallest number implied
73418334Speter   by any set of X.  */
73518334Speter
73618334Speterstatic void
73718334Speterset_nonzero_bits_and_sign_copies (x, set)
73818334Speter     rtx x;
73918334Speter     rtx set;
74018334Speter{
74118334Speter  int num;
74218334Speter
74318334Speter  if (GET_CODE (x) == REG
74418334Speter      && REGNO (x) >= FIRST_PSEUDO_REGISTER
74518334Speter      /* If this register is undefined at the start of the file, we can't
74618334Speter	 say what its contents were.  */
74752284Sobrien      && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, REGNO (x))
74818334Speter      && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
74918334Speter    {
75050397Sobrien      if (set == 0 || GET_CODE (set) == CLOBBER)
75118334Speter	{
75218334Speter	  reg_nonzero_bits[REGNO (x)] = GET_MODE_MASK (GET_MODE (x));
75350397Sobrien	  reg_sign_bit_copies[REGNO (x)] = 1;
75418334Speter	  return;
75518334Speter	}
75618334Speter
75718334Speter      /* If this is a complex assignment, see if we can convert it into a
75818334Speter	 simple assignment.  */
75918334Speter      set = expand_field_assignment (set);
76018334Speter
76118334Speter      /* If this is a simple assignment, or we have a paradoxical SUBREG,
76218334Speter	 set what we know about X.  */
76318334Speter
76418334Speter      if (SET_DEST (set) == x
76518334Speter	  || (GET_CODE (SET_DEST (set)) == SUBREG
76618334Speter	      && (GET_MODE_SIZE (GET_MODE (SET_DEST (set)))
76718334Speter		  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (set)))))
76818334Speter	      && SUBREG_REG (SET_DEST (set)) == x))
76918334Speter	{
77018334Speter	  rtx src = SET_SRC (set);
77118334Speter
77218334Speter#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
77318334Speter	  /* If X is narrower than a word and SRC is a non-negative
77418334Speter	     constant that would appear negative in the mode of X,
77518334Speter	     sign-extend it for use in reg_nonzero_bits because some
77618334Speter	     machines (maybe most) will actually do the sign-extension
77718334Speter	     and this is the conservative approach.
77818334Speter
77918334Speter	     ??? For 2.5, try to tighten up the MD files in this regard
78018334Speter	     instead of this kludge.  */
78118334Speter
78218334Speter	  if (GET_MODE_BITSIZE (GET_MODE (x)) < BITS_PER_WORD
78318334Speter	      && GET_CODE (src) == CONST_INT
78418334Speter	      && INTVAL (src) > 0
78518334Speter	      && 0 != (INTVAL (src)
78618334Speter		       & ((HOST_WIDE_INT) 1
78718334Speter			  << (GET_MODE_BITSIZE (GET_MODE (x)) - 1))))
78818334Speter	    src = GEN_INT (INTVAL (src)
78918334Speter			   | ((HOST_WIDE_INT) (-1)
79018334Speter			      << GET_MODE_BITSIZE (GET_MODE (x))));
79118334Speter#endif
79218334Speter
79318334Speter	  reg_nonzero_bits[REGNO (x)]
79418334Speter	    |= nonzero_bits (src, nonzero_bits_mode);
79518334Speter	  num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
79618334Speter	  if (reg_sign_bit_copies[REGNO (x)] == 0
79718334Speter	      || reg_sign_bit_copies[REGNO (x)] > num)
79818334Speter	    reg_sign_bit_copies[REGNO (x)] = num;
79918334Speter	}
80018334Speter      else
80118334Speter	{
80218334Speter	  reg_nonzero_bits[REGNO (x)] = GET_MODE_MASK (GET_MODE (x));
80350397Sobrien	  reg_sign_bit_copies[REGNO (x)] = 1;
80418334Speter	}
80518334Speter    }
80618334Speter}
80718334Speter
80818334Speter/* See if INSN can be combined into I3.  PRED and SUCC are optionally
80918334Speter   insns that were previously combined into I3 or that will be combined
81018334Speter   into the merger of INSN and I3.
81118334Speter
81218334Speter   Return 0 if the combination is not allowed for any reason.
81318334Speter
81418334Speter   If the combination is allowed, *PDEST will be set to the single
81518334Speter   destination of INSN and *PSRC to the single source, and this function
81618334Speter   will return 1.  */
81718334Speter
81818334Speterstatic int
81918334Spetercan_combine_p (insn, i3, pred, succ, pdest, psrc)
82018334Speter     rtx insn;
82118334Speter     rtx i3;
82252284Sobrien     rtx pred ATTRIBUTE_UNUSED;
82352284Sobrien     rtx succ;
82418334Speter     rtx *pdest, *psrc;
82518334Speter{
82618334Speter  int i;
82718334Speter  rtx set = 0, src, dest;
82850397Sobrien  rtx p;
82950397Sobrien#ifdef AUTO_INC_DEC
83050397Sobrien  rtx link;
83150397Sobrien#endif
83218334Speter  int all_adjacent = (succ ? (next_active_insn (insn) == succ
83318334Speter			      && next_active_insn (succ) == i3)
83418334Speter		      : next_active_insn (insn) == i3);
83518334Speter
83618334Speter  /* Can combine only if previous insn is a SET of a REG, a SUBREG or CC0.
83718334Speter     or a PARALLEL consisting of such a SET and CLOBBERs.
83818334Speter
83918334Speter     If INSN has CLOBBER parallel parts, ignore them for our processing.
84018334Speter     By definition, these happen during the execution of the insn.  When it
84118334Speter     is merged with another insn, all bets are off.  If they are, in fact,
84218334Speter     needed and aren't also supplied in I3, they may be added by
84318334Speter     recog_for_combine.  Otherwise, it won't match.
84418334Speter
84518334Speter     We can also ignore a SET whose SET_DEST is mentioned in a REG_UNUSED
84618334Speter     note.
84718334Speter
84818334Speter     Get the source and destination of INSN.  If more than one, can't
84918334Speter     combine.  */
85018334Speter
85118334Speter  if (GET_CODE (PATTERN (insn)) == SET)
85218334Speter    set = PATTERN (insn);
85318334Speter  else if (GET_CODE (PATTERN (insn)) == PARALLEL
85418334Speter	   && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
85518334Speter    {
85618334Speter      for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
85718334Speter	{
85818334Speter	  rtx elt = XVECEXP (PATTERN (insn), 0, i);
85918334Speter
86018334Speter	  switch (GET_CODE (elt))
86118334Speter	    {
86250397Sobrien	    /* This is important to combine floating point insns
86350397Sobrien	       for the SH4 port.  */
86450397Sobrien	    case USE:
86550397Sobrien	      /* Combining an isolated USE doesn't make sense.
86650397Sobrien		 We depend here on combinable_i3_pat to reject them.  */
86750397Sobrien	      /* The code below this loop only verifies that the inputs of
86850397Sobrien		 the SET in INSN do not change.  We call reg_set_between_p
86950397Sobrien		 to verify that the REG in the USE does not change betweeen
87050397Sobrien		 I3 and INSN.
87150397Sobrien		 If the USE in INSN was for a pseudo register, the matching
87250397Sobrien		 insn pattern will likely match any register; combining this
87350397Sobrien		 with any other USE would only be safe if we knew that the
87450397Sobrien		 used registers have identical values, or if there was
87550397Sobrien		 something to tell them apart, e.g. different modes.  For
87650397Sobrien		 now, we forgo such compilcated tests and simply disallow
87750397Sobrien		 combining of USES of pseudo registers with any other USE.  */
87850397Sobrien	      if (GET_CODE (XEXP (elt, 0)) == REG
87950397Sobrien		  && GET_CODE (PATTERN (i3)) == PARALLEL)
88050397Sobrien		{
88150397Sobrien		  rtx i3pat = PATTERN (i3);
88250397Sobrien		  int i = XVECLEN (i3pat, 0) - 1;
88350397Sobrien		  int regno = REGNO (XEXP (elt, 0));
88450397Sobrien		  do
88550397Sobrien		    {
88650397Sobrien		      rtx i3elt = XVECEXP (i3pat, 0, i);
88750397Sobrien		      if (GET_CODE (i3elt) == USE
88850397Sobrien			  && GET_CODE (XEXP (i3elt, 0)) == REG
88950397Sobrien			  && (REGNO (XEXP (i3elt, 0)) == regno
89050397Sobrien			      ? reg_set_between_p (XEXP (elt, 0),
89150397Sobrien						   PREV_INSN (insn), i3)
89250397Sobrien			      : regno >= FIRST_PSEUDO_REGISTER))
89350397Sobrien			return 0;
89450397Sobrien		    }
89550397Sobrien		  while (--i >= 0);
89650397Sobrien		}
89750397Sobrien	      break;
89850397Sobrien
89918334Speter	      /* We can ignore CLOBBERs.  */
90018334Speter	    case CLOBBER:
90118334Speter	      break;
90218334Speter
90318334Speter	    case SET:
90418334Speter	      /* Ignore SETs whose result isn't used but not those that
90518334Speter		 have side-effects.  */
90618334Speter	      if (find_reg_note (insn, REG_UNUSED, SET_DEST (elt))
90718334Speter		  && ! side_effects_p (elt))
90818334Speter		break;
90918334Speter
91018334Speter	      /* If we have already found a SET, this is a second one and
91118334Speter		 so we cannot combine with this insn.  */
91218334Speter	      if (set)
91318334Speter		return 0;
91418334Speter
91518334Speter	      set = elt;
91618334Speter	      break;
91718334Speter
91818334Speter	    default:
91918334Speter	      /* Anything else means we can't combine.  */
92018334Speter	      return 0;
92118334Speter	    }
92218334Speter	}
92318334Speter
92418334Speter      if (set == 0
92518334Speter	  /* If SET_SRC is an ASM_OPERANDS we can't throw away these CLOBBERs,
92618334Speter	     so don't do anything with it.  */
92718334Speter	  || GET_CODE (SET_SRC (set)) == ASM_OPERANDS)
92818334Speter	return 0;
92918334Speter    }
93018334Speter  else
93118334Speter    return 0;
93218334Speter
93318334Speter  if (set == 0)
93418334Speter    return 0;
93518334Speter
93618334Speter  set = expand_field_assignment (set);
93718334Speter  src = SET_SRC (set), dest = SET_DEST (set);
93818334Speter
93918334Speter  /* Don't eliminate a store in the stack pointer.  */
94018334Speter  if (dest == stack_pointer_rtx
94118334Speter      /* If we couldn't eliminate a field assignment, we can't combine.  */
94218334Speter      || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == STRICT_LOW_PART
94318334Speter      /* Don't combine with an insn that sets a register to itself if it has
94418334Speter	 a REG_EQUAL note.  This may be part of a REG_NO_CONFLICT sequence.  */
94518334Speter      || (rtx_equal_p (src, dest) && find_reg_note (insn, REG_EQUAL, NULL_RTX))
94618334Speter      /* Can't merge a function call.  */
94718334Speter      || GET_CODE (src) == CALL
94818334Speter      /* Don't eliminate a function call argument.  */
94918334Speter      || (GET_CODE (i3) == CALL_INSN
95018334Speter	  && (find_reg_fusage (i3, USE, dest)
95118334Speter	      || (GET_CODE (dest) == REG
95218334Speter		  && REGNO (dest) < FIRST_PSEUDO_REGISTER
95318334Speter		  && global_regs[REGNO (dest)])))
95418334Speter      /* Don't substitute into an incremented register.  */
95518334Speter      || FIND_REG_INC_NOTE (i3, dest)
95618334Speter      || (succ && FIND_REG_INC_NOTE (succ, dest))
95752284Sobrien#if 0
95818334Speter      /* Don't combine the end of a libcall into anything.  */
95952284Sobrien      /* ??? This gives worse code, and appears to be unnecessary, since no
96052284Sobrien	 pass after flow uses REG_LIBCALL/REG_RETVAL notes.  Local-alloc does
96152284Sobrien	 use REG_RETVAL notes for noconflict blocks, but other code here
96252284Sobrien	 makes sure that those insns don't disappear.  */
96318334Speter      || find_reg_note (insn, REG_RETVAL, NULL_RTX)
96452284Sobrien#endif
96518334Speter      /* Make sure that DEST is not used after SUCC but before I3.  */
96618334Speter      || (succ && ! all_adjacent
96718334Speter	  && reg_used_between_p (dest, succ, i3))
96818334Speter      /* Make sure that the value that is to be substituted for the register
96918334Speter	 does not use any registers whose values alter in between.  However,
97018334Speter	 If the insns are adjacent, a use can't cross a set even though we
97118334Speter	 think it might (this can happen for a sequence of insns each setting
97218334Speter	 the same destination; reg_last_set of that register might point to
97318334Speter	 a NOTE).  If INSN has a REG_EQUIV note, the register is always
97418334Speter	 equivalent to the memory so the substitution is valid even if there
97518334Speter	 are intervening stores.  Also, don't move a volatile asm or
97618334Speter	 UNSPEC_VOLATILE across any other insns.  */
97718334Speter      || (! all_adjacent
97818334Speter	  && (((GET_CODE (src) != MEM
97918334Speter		|| ! find_reg_note (insn, REG_EQUIV, src))
98018334Speter	       && use_crosses_set_p (src, INSN_CUID (insn)))
98118334Speter	      || (GET_CODE (src) == ASM_OPERANDS && MEM_VOLATILE_P (src))
98218334Speter	      || GET_CODE (src) == UNSPEC_VOLATILE))
98318334Speter      /* If there is a REG_NO_CONFLICT note for DEST in I3 or SUCC, we get
98418334Speter	 better register allocation by not doing the combine.  */
98518334Speter      || find_reg_note (i3, REG_NO_CONFLICT, dest)
98618334Speter      || (succ && find_reg_note (succ, REG_NO_CONFLICT, dest))
98718334Speter      /* Don't combine across a CALL_INSN, because that would possibly
98818334Speter	 change whether the life span of some REGs crosses calls or not,
98918334Speter	 and it is a pain to update that information.
99018334Speter	 Exception: if source is a constant, moving it later can't hurt.
99118334Speter	 Accept that special case, because it helps -fforce-addr a lot.  */
99218334Speter      || (INSN_CUID (insn) < last_call_cuid && ! CONSTANT_P (src)))
99318334Speter    return 0;
99418334Speter
99518334Speter  /* DEST must either be a REG or CC0.  */
99618334Speter  if (GET_CODE (dest) == REG)
99718334Speter    {
99818334Speter      /* If register alignment is being enforced for multi-word items in all
99918334Speter	 cases except for parameters, it is possible to have a register copy
100018334Speter	 insn referencing a hard register that is not allowed to contain the
100118334Speter	 mode being copied and which would not be valid as an operand of most
100218334Speter	 insns.  Eliminate this problem by not combining with such an insn.
100318334Speter
100418334Speter	 Also, on some machines we don't want to extend the life of a hard
100550397Sobrien	 register.
100618334Speter
100750397Sobrien	 This is the same test done in can_combine except that we don't test
100850397Sobrien	 if SRC is a CALL operation to permit a hard register with
100950397Sobrien	 SMALL_REGISTER_CLASSES, and that we have to take all_adjacent
101050397Sobrien	 into account.  */
101150397Sobrien
101218334Speter      if (GET_CODE (src) == REG
101318334Speter	  && ((REGNO (dest) < FIRST_PSEUDO_REGISTER
101418334Speter	       && ! HARD_REGNO_MODE_OK (REGNO (dest), GET_MODE (dest)))
101518334Speter	      /* Don't extend the life of a hard register unless it is
101618334Speter		 user variable (if we have few registers) or it can't
101718334Speter		 fit into the desired register (meaning something special
101850397Sobrien		 is going on).
101950397Sobrien		 Also avoid substituting a return register into I3, because
102050397Sobrien		 reload can't handle a conflict with constraints of other
102150397Sobrien		 inputs.  */
102218334Speter	      || (REGNO (src) < FIRST_PSEUDO_REGISTER
102318334Speter		  && (! HARD_REGNO_MODE_OK (REGNO (src), GET_MODE (src))
102450397Sobrien		      || (SMALL_REGISTER_CLASSES
102550397Sobrien			  && ((! all_adjacent && ! REG_USERVAR_P (src))
102650397Sobrien			      || (FUNCTION_VALUE_REGNO_P (REGNO (src))
102750397Sobrien				  && ! REG_USERVAR_P (src))))))))
102818334Speter	return 0;
102918334Speter    }
103018334Speter  else if (GET_CODE (dest) != CC0)
103118334Speter    return 0;
103218334Speter
103318334Speter  /* Don't substitute for a register intended as a clobberable operand.
103418334Speter     Similarly, don't substitute an expression containing a register that
103518334Speter     will be clobbered in I3.  */
103618334Speter  if (GET_CODE (PATTERN (i3)) == PARALLEL)
103718334Speter    for (i = XVECLEN (PATTERN (i3), 0) - 1; i >= 0; i--)
103818334Speter      if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER
103918334Speter	  && (reg_overlap_mentioned_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0),
104018334Speter				       src)
104118334Speter	      || rtx_equal_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0), dest)))
104218334Speter	return 0;
104318334Speter
104418334Speter  /* If INSN contains anything volatile, or is an `asm' (whether volatile
104550397Sobrien     or not), reject, unless nothing volatile comes between it and I3 */
104618334Speter
104718334Speter  if (GET_CODE (src) == ASM_OPERANDS || volatile_refs_p (src))
104850397Sobrien    {
104950397Sobrien      /* Make sure succ doesn't contain a volatile reference.  */
105050397Sobrien      if (succ != 0 && volatile_refs_p (PATTERN (succ)))
105150397Sobrien        return 0;
105250397Sobrien
105350397Sobrien      for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p))
105450397Sobrien        if (GET_RTX_CLASS (GET_CODE (p)) == 'i'
105550397Sobrien  	  && p != succ && volatile_refs_p (PATTERN (p)))
105650397Sobrien  	return 0;
105750397Sobrien    }
105818334Speter
105950397Sobrien  /* If INSN is an asm, and DEST is a hard register, reject, since it has
106050397Sobrien     to be an explicit register variable, and was chosen for a reason.  */
106150397Sobrien
106250397Sobrien  if (GET_CODE (src) == ASM_OPERANDS
106350397Sobrien      && GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER)
106450397Sobrien    return 0;
106550397Sobrien
106618334Speter  /* If there are any volatile insns between INSN and I3, reject, because
106718334Speter     they might affect machine state.  */
106818334Speter
106918334Speter  for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p))
107018334Speter    if (GET_RTX_CLASS (GET_CODE (p)) == 'i'
107118334Speter	&& p != succ && volatile_insn_p (PATTERN (p)))
107218334Speter      return 0;
107318334Speter
107418334Speter  /* If INSN or I2 contains an autoincrement or autodecrement,
107518334Speter     make sure that register is not used between there and I3,
107618334Speter     and not already used in I3 either.
107718334Speter     Also insist that I3 not be a jump; if it were one
107818334Speter     and the incremented register were spilled, we would lose.  */
107918334Speter
108018334Speter#ifdef AUTO_INC_DEC
108118334Speter  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
108218334Speter    if (REG_NOTE_KIND (link) == REG_INC
108318334Speter	&& (GET_CODE (i3) == JUMP_INSN
108418334Speter	    || reg_used_between_p (XEXP (link, 0), insn, i3)
108518334Speter	    || reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i3))))
108618334Speter      return 0;
108718334Speter#endif
108818334Speter
108918334Speter#ifdef HAVE_cc0
109018334Speter  /* Don't combine an insn that follows a CC0-setting insn.
109118334Speter     An insn that uses CC0 must not be separated from the one that sets it.
109218334Speter     We do, however, allow I2 to follow a CC0-setting insn if that insn
109318334Speter     is passed as I1; in that case it will be deleted also.
109418334Speter     We also allow combining in this case if all the insns are adjacent
109518334Speter     because that would leave the two CC0 insns adjacent as well.
109618334Speter     It would be more logical to test whether CC0 occurs inside I1 or I2,
109718334Speter     but that would be much slower, and this ought to be equivalent.  */
109818334Speter
109918334Speter  p = prev_nonnote_insn (insn);
110018334Speter  if (p && p != pred && GET_CODE (p) == INSN && sets_cc0_p (PATTERN (p))
110118334Speter      && ! all_adjacent)
110218334Speter    return 0;
110318334Speter#endif
110418334Speter
110518334Speter  /* If we get here, we have passed all the tests and the combination is
110618334Speter     to be allowed.  */
110718334Speter
110818334Speter  *pdest = dest;
110918334Speter  *psrc = src;
111018334Speter
111118334Speter  return 1;
111218334Speter}
111318334Speter
111450397Sobrien/* Check if PAT is an insn - or a part of it - used to set up an
111550397Sobrien   argument for a function in a hard register.  */
111650397Sobrien
111750397Sobrienstatic int
111850397Sobriensets_function_arg_p (pat)
111950397Sobrien     rtx pat;
112050397Sobrien{
112150397Sobrien  int i;
112250397Sobrien  rtx inner_dest;
112350397Sobrien
112450397Sobrien  switch (GET_CODE (pat))
112550397Sobrien    {
112650397Sobrien    case INSN:
112750397Sobrien      return sets_function_arg_p (PATTERN (pat));
112850397Sobrien
112950397Sobrien    case PARALLEL:
113050397Sobrien      for (i = XVECLEN (pat, 0); --i >= 0;)
113150397Sobrien	if (sets_function_arg_p (XVECEXP (pat, 0, i)))
113250397Sobrien	  return 1;
113350397Sobrien
113450397Sobrien      break;
113550397Sobrien
113650397Sobrien    case SET:
113750397Sobrien      inner_dest = SET_DEST (pat);
113850397Sobrien      while (GET_CODE (inner_dest) == STRICT_LOW_PART
113950397Sobrien	     || GET_CODE (inner_dest) == SUBREG
114050397Sobrien	     || GET_CODE (inner_dest) == ZERO_EXTRACT)
114150397Sobrien	inner_dest = XEXP (inner_dest, 0);
114250397Sobrien
114350397Sobrien      return (GET_CODE (inner_dest) == REG
114450397Sobrien	      && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER
114550397Sobrien	      && FUNCTION_ARG_REGNO_P (REGNO (inner_dest)));
114650397Sobrien
114750397Sobrien    default:
114850397Sobrien      break;
114950397Sobrien    }
115050397Sobrien
115150397Sobrien  return 0;
115250397Sobrien}
115350397Sobrien
115418334Speter/* LOC is the location within I3 that contains its pattern or the component
115518334Speter   of a PARALLEL of the pattern.  We validate that it is valid for combining.
115618334Speter
115718334Speter   One problem is if I3 modifies its output, as opposed to replacing it
115818334Speter   entirely, we can't allow the output to contain I2DEST or I1DEST as doing
115918334Speter   so would produce an insn that is not equivalent to the original insns.
116018334Speter
116118334Speter   Consider:
116218334Speter
116318334Speter         (set (reg:DI 101) (reg:DI 100))
116418334Speter	 (set (subreg:SI (reg:DI 101) 0) <foo>)
116518334Speter
116618334Speter   This is NOT equivalent to:
116718334Speter
116818334Speter         (parallel [(set (subreg:SI (reg:DI 100) 0) <foo>)
116918334Speter	 	    (set (reg:DI 101) (reg:DI 100))])
117018334Speter
117118334Speter   Not only does this modify 100 (in which case it might still be valid
117218334Speter   if 100 were dead in I2), it sets 101 to the ORIGINAL value of 100.
117318334Speter
117418334Speter   We can also run into a problem if I2 sets a register that I1
117518334Speter   uses and I1 gets directly substituted into I3 (not via I2).  In that
117618334Speter   case, we would be getting the wrong value of I2DEST into I3, so we
117718334Speter   must reject the combination.  This case occurs when I2 and I1 both
117818334Speter   feed into I3, rather than when I1 feeds into I2, which feeds into I3.
117918334Speter   If I1_NOT_IN_SRC is non-zero, it means that finding I1 in the source
118018334Speter   of a SET must prevent combination from occurring.
118118334Speter
118250397Sobrien   On machines where SMALL_REGISTER_CLASSES is non-zero, we don't combine
118318334Speter   if the destination of a SET is a hard register that isn't a user
118418334Speter   variable.
118518334Speter
118618334Speter   Before doing the above check, we first try to expand a field assignment
118718334Speter   into a set of logical operations.
118818334Speter
118918334Speter   If PI3_DEST_KILLED is non-zero, it is a pointer to a location in which
119018334Speter   we place a register that is both set and used within I3.  If more than one
119118334Speter   such register is detected, we fail.
119218334Speter
119318334Speter   Return 1 if the combination is valid, zero otherwise.  */
119418334Speter
119518334Speterstatic int
119618334Spetercombinable_i3pat (i3, loc, i2dest, i1dest, i1_not_in_src, pi3dest_killed)
119718334Speter     rtx i3;
119818334Speter     rtx *loc;
119918334Speter     rtx i2dest;
120018334Speter     rtx i1dest;
120118334Speter     int i1_not_in_src;
120218334Speter     rtx *pi3dest_killed;
120318334Speter{
120418334Speter  rtx x = *loc;
120518334Speter
120618334Speter  if (GET_CODE (x) == SET)
120718334Speter    {
120818334Speter      rtx set = expand_field_assignment (x);
120918334Speter      rtx dest = SET_DEST (set);
121018334Speter      rtx src = SET_SRC (set);
121150397Sobrien      rtx inner_dest = dest;
121250397Sobrien
121350397Sobrien#if 0
121450397Sobrien      rtx inner_src = src;
121550397Sobrien#endif
121618334Speter
121718334Speter      SUBST (*loc, set);
121818334Speter
121918334Speter      while (GET_CODE (inner_dest) == STRICT_LOW_PART
122018334Speter	     || GET_CODE (inner_dest) == SUBREG
122118334Speter	     || GET_CODE (inner_dest) == ZERO_EXTRACT)
122218334Speter	inner_dest = XEXP (inner_dest, 0);
122318334Speter
122418334Speter  /* We probably don't need this any more now that LIMIT_RELOAD_CLASS
122518334Speter     was added.  */
122618334Speter#if 0
122718334Speter      while (GET_CODE (inner_src) == STRICT_LOW_PART
122818334Speter	     || GET_CODE (inner_src) == SUBREG
122918334Speter	     || GET_CODE (inner_src) == ZERO_EXTRACT)
123018334Speter	inner_src = XEXP (inner_src, 0);
123118334Speter
123218334Speter      /* If it is better that two different modes keep two different pseudos,
123318334Speter	 avoid combining them.  This avoids producing the following pattern
123418334Speter	 on a 386:
123518334Speter	  (set (subreg:SI (reg/v:QI 21) 0)
123618334Speter	       (lshiftrt:SI (reg/v:SI 20)
123718334Speter	           (const_int 24)))
123818334Speter	 If that were made, reload could not handle the pair of
123918334Speter	 reg 20/21, since it would try to get any GENERAL_REGS
124018334Speter	 but some of them don't handle QImode.  */
124118334Speter
124218334Speter      if (rtx_equal_p (inner_src, i2dest)
124318334Speter	  && GET_CODE (inner_dest) == REG
124418334Speter	  && ! MODES_TIEABLE_P (GET_MODE (i2dest), GET_MODE (inner_dest)))
124518334Speter	return 0;
124618334Speter#endif
124718334Speter
124818334Speter      /* Check for the case where I3 modifies its output, as
124918334Speter	 discussed above.  */
125018334Speter      if ((inner_dest != dest
125118334Speter	   && (reg_overlap_mentioned_p (i2dest, inner_dest)
125218334Speter	       || (i1dest && reg_overlap_mentioned_p (i1dest, inner_dest))))
125350397Sobrien
125418334Speter	  /* This is the same test done in can_combine_p except that we
125518334Speter	     allow a hard register with SMALL_REGISTER_CLASSES if SRC is a
125650397Sobrien	     CALL operation. Moreover, we can't test all_adjacent; we don't
125750397Sobrien	     have to, since this instruction will stay in place, thus we are
125850397Sobrien	     not considering increasing the lifetime of INNER_DEST.
125950397Sobrien
126050397Sobrien	     Also, if this insn sets a function argument, combining it with
126150397Sobrien	     something that might need a spill could clobber a previous
126250397Sobrien	     function argument; the all_adjacent test in can_combine_p also
126350397Sobrien	     checks this; here, we do a more specific test for this case.  */
126450397Sobrien
126518334Speter	  || (GET_CODE (inner_dest) == REG
126618334Speter	      && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER
126718334Speter	      && (! HARD_REGNO_MODE_OK (REGNO (inner_dest),
126818334Speter					GET_MODE (inner_dest))
126950397Sobrien		 || (SMALL_REGISTER_CLASSES && GET_CODE (src) != CALL
127050397Sobrien		     && ! REG_USERVAR_P (inner_dest)
127150397Sobrien		     && (FUNCTION_VALUE_REGNO_P (REGNO (inner_dest))
127250397Sobrien			 || (FUNCTION_ARG_REGNO_P (REGNO (inner_dest))
127350397Sobrien			     && i3 != 0
127450397Sobrien			     && sets_function_arg_p (prev_nonnote_insn (i3)))))))
127518334Speter	  || (i1_not_in_src && reg_overlap_mentioned_p (i1dest, src)))
127618334Speter	return 0;
127718334Speter
127818334Speter      /* If DEST is used in I3, it is being killed in this insn,
127918334Speter	 so record that for later.
128018334Speter	 Never add REG_DEAD notes for the FRAME_POINTER_REGNUM or the
128118334Speter	 STACK_POINTER_REGNUM, since these are always considered to be
128218334Speter	 live.  Similarly for ARG_POINTER_REGNUM if it is fixed.  */
128318334Speter      if (pi3dest_killed && GET_CODE (dest) == REG
128418334Speter	  && reg_referenced_p (dest, PATTERN (i3))
128518334Speter	  && REGNO (dest) != FRAME_POINTER_REGNUM
128618334Speter#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
128718334Speter	  && REGNO (dest) != HARD_FRAME_POINTER_REGNUM
128818334Speter#endif
128918334Speter#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
129018334Speter	  && (REGNO (dest) != ARG_POINTER_REGNUM
129118334Speter	      || ! fixed_regs [REGNO (dest)])
129218334Speter#endif
129318334Speter	  && REGNO (dest) != STACK_POINTER_REGNUM)
129418334Speter	{
129518334Speter	  if (*pi3dest_killed)
129618334Speter	    return 0;
129718334Speter
129818334Speter	  *pi3dest_killed = dest;
129918334Speter	}
130018334Speter    }
130118334Speter
130218334Speter  else if (GET_CODE (x) == PARALLEL)
130318334Speter    {
130418334Speter      int i;
130518334Speter
130618334Speter      for (i = 0; i < XVECLEN (x, 0); i++)
130718334Speter	if (! combinable_i3pat (i3, &XVECEXP (x, 0, i), i2dest, i1dest,
130818334Speter				i1_not_in_src, pi3dest_killed))
130918334Speter	  return 0;
131018334Speter    }
131118334Speter
131218334Speter  return 1;
131318334Speter}
131418334Speter
131518334Speter/* Try to combine the insns I1 and I2 into I3.
131618334Speter   Here I1 and I2 appear earlier than I3.
131718334Speter   I1 can be zero; then we combine just I2 into I3.
131818334Speter
131918334Speter   It we are combining three insns and the resulting insn is not recognized,
132018334Speter   try splitting it into two insns.  If that happens, I2 and I3 are retained
132118334Speter   and I1 is pseudo-deleted by turning it into a NOTE.  Otherwise, I1 and I2
132218334Speter   are pseudo-deleted.
132318334Speter
132418334Speter   Return 0 if the combination does not work.  Then nothing is changed.
132518334Speter   If we did the combination, return the insn at which combine should
132618334Speter   resume scanning.  */
132718334Speter
132818334Speterstatic rtx
132918334Spetertry_combine (i3, i2, i1)
133018334Speter     register rtx i3, i2, i1;
133118334Speter{
133218334Speter  /* New patterns for I3 and I3, respectively.  */
133318334Speter  rtx newpat, newi2pat = 0;
133418334Speter  /* Indicates need to preserve SET in I1 or I2 in I3 if it is not dead.  */
133518334Speter  int added_sets_1, added_sets_2;
133618334Speter  /* Total number of SETs to put into I3.  */
133718334Speter  int total_sets;
133818334Speter  /* Nonzero is I2's body now appears in I3.  */
133918334Speter  int i2_is_used;
134018334Speter  /* INSN_CODEs for new I3, new I2, and user of condition code.  */
134118334Speter  int insn_code_number, i2_code_number, other_code_number;
134218334Speter  /* Contains I3 if the destination of I3 is used in its source, which means
134318334Speter     that the old life of I3 is being killed.  If that usage is placed into
134418334Speter     I2 and not in I3, a REG_DEAD note must be made.  */
134518334Speter  rtx i3dest_killed = 0;
134618334Speter  /* SET_DEST and SET_SRC of I2 and I1.  */
134718334Speter  rtx i2dest, i2src, i1dest = 0, i1src = 0;
134818334Speter  /* PATTERN (I2), or a copy of it in certain cases.  */
134918334Speter  rtx i2pat;
135018334Speter  /* Indicates if I2DEST or I1DEST is in I2SRC or I1_SRC.  */
135118334Speter  int i2dest_in_i2src = 0, i1dest_in_i1src = 0, i2dest_in_i1src = 0;
135218334Speter  int i1_feeds_i3 = 0;
135318334Speter  /* Notes that must be added to REG_NOTES in I3 and I2.  */
135418334Speter  rtx new_i3_notes, new_i2_notes;
135518334Speter  /* Notes that we substituted I3 into I2 instead of the normal case.  */
135618334Speter  int i3_subst_into_i2 = 0;
135718334Speter  /* Notes that I1, I2 or I3 is a MULT operation.  */
135818334Speter  int have_mult = 0;
135918334Speter
136018334Speter  int maxreg;
136118334Speter  rtx temp;
136218334Speter  register rtx link;
136318334Speter  int i;
136418334Speter
136518334Speter  /* If any of I1, I2, and I3 isn't really an insn, we can't do anything.
136618334Speter     This can occur when flow deletes an insn that it has merged into an
136718334Speter     auto-increment address.  We also can't do anything if I3 has a
136818334Speter     REG_LIBCALL note since we don't want to disrupt the contiguity of a
136918334Speter     libcall.  */
137018334Speter
137118334Speter  if (GET_RTX_CLASS (GET_CODE (i3)) != 'i'
137218334Speter      || GET_RTX_CLASS (GET_CODE (i2)) != 'i'
137318334Speter      || (i1 && GET_RTX_CLASS (GET_CODE (i1)) != 'i')
137452284Sobrien#if 0
137552284Sobrien      /* ??? This gives worse code, and appears to be unnecessary, since no
137652284Sobrien	 pass after flow uses REG_LIBCALL/REG_RETVAL notes.  */
137752284Sobrien      || find_reg_note (i3, REG_LIBCALL, NULL_RTX)
137852284Sobrien#endif
137952284Sobrien)
138018334Speter    return 0;
138118334Speter
138218334Speter  combine_attempts++;
138318334Speter
138450397Sobrien  undobuf.undos = undobuf.previous_undos = 0;
138518334Speter  undobuf.other_insn = 0;
138618334Speter
138718334Speter  /* Save the current high-water-mark so we can free storage if we didn't
138818334Speter     accept this combination.  */
138918334Speter  undobuf.storage = (char *) oballoc (0);
139018334Speter
139118334Speter  /* Reset the hard register usage information.  */
139218334Speter  CLEAR_HARD_REG_SET (newpat_used_regs);
139318334Speter
139418334Speter  /* If I1 and I2 both feed I3, they can be in any order.  To simplify the
139518334Speter     code below, set I1 to be the earlier of the two insns.  */
139618334Speter  if (i1 && INSN_CUID (i1) > INSN_CUID (i2))
139718334Speter    temp = i1, i1 = i2, i2 = temp;
139818334Speter
139918334Speter  added_links_insn = 0;
140018334Speter
140118334Speter  /* First check for one important special-case that the code below will
140218334Speter     not handle.  Namely, the case where I1 is zero, I2 has multiple sets,
140318334Speter     and I3 is a SET whose SET_SRC is a SET_DEST in I2.  In that case,
140418334Speter     we may be able to replace that destination with the destination of I3.
140518334Speter     This occurs in the common code where we compute both a quotient and
140618334Speter     remainder into a structure, in which case we want to do the computation
140718334Speter     directly into the structure to avoid register-register copies.
140818334Speter
140918334Speter     We make very conservative checks below and only try to handle the
141018334Speter     most common cases of this.  For example, we only handle the case
141118334Speter     where I2 and I3 are adjacent to avoid making difficult register
141218334Speter     usage tests.  */
141318334Speter
141418334Speter  if (i1 == 0 && GET_CODE (i3) == INSN && GET_CODE (PATTERN (i3)) == SET
141518334Speter      && GET_CODE (SET_SRC (PATTERN (i3))) == REG
141618334Speter      && REGNO (SET_SRC (PATTERN (i3))) >= FIRST_PSEUDO_REGISTER
141750397Sobrien      && (! SMALL_REGISTER_CLASSES
141850397Sobrien	  || (GET_CODE (SET_DEST (PATTERN (i3))) != REG
141950397Sobrien	      || REGNO (SET_DEST (PATTERN (i3))) >= FIRST_PSEUDO_REGISTER
142050397Sobrien	      || REG_USERVAR_P (SET_DEST (PATTERN (i3)))))
142118334Speter      && find_reg_note (i3, REG_DEAD, SET_SRC (PATTERN (i3)))
142218334Speter      && GET_CODE (PATTERN (i2)) == PARALLEL
142318334Speter      && ! side_effects_p (SET_DEST (PATTERN (i3)))
142418334Speter      /* If the dest of I3 is a ZERO_EXTRACT or STRICT_LOW_PART, the code
142518334Speter	 below would need to check what is inside (and reg_overlap_mentioned_p
142618334Speter	 doesn't support those codes anyway).  Don't allow those destinations;
142718334Speter	 the resulting insn isn't likely to be recognized anyway.  */
142818334Speter      && GET_CODE (SET_DEST (PATTERN (i3))) != ZERO_EXTRACT
142918334Speter      && GET_CODE (SET_DEST (PATTERN (i3))) != STRICT_LOW_PART
143018334Speter      && ! reg_overlap_mentioned_p (SET_SRC (PATTERN (i3)),
143118334Speter				    SET_DEST (PATTERN (i3)))
143218334Speter      && next_real_insn (i2) == i3)
143318334Speter    {
143418334Speter      rtx p2 = PATTERN (i2);
143518334Speter
143618334Speter      /* Make sure that the destination of I3,
143718334Speter	 which we are going to substitute into one output of I2,
143818334Speter	 is not used within another output of I2.  We must avoid making this:
143918334Speter	 (parallel [(set (mem (reg 69)) ...)
144018334Speter		    (set (reg 69) ...)])
144118334Speter	 which is not well-defined as to order of actions.
144218334Speter	 (Besides, reload can't handle output reloads for this.)
144318334Speter
144418334Speter	 The problem can also happen if the dest of I3 is a memory ref,
144518334Speter	 if another dest in I2 is an indirect memory ref.  */
144618334Speter      for (i = 0; i < XVECLEN (p2, 0); i++)
144750397Sobrien	if ((GET_CODE (XVECEXP (p2, 0, i)) == SET
144850397Sobrien	     || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER)
144918334Speter	    && reg_overlap_mentioned_p (SET_DEST (PATTERN (i3)),
145018334Speter					SET_DEST (XVECEXP (p2, 0, i))))
145118334Speter	  break;
145218334Speter
145318334Speter      if (i == XVECLEN (p2, 0))
145418334Speter	for (i = 0; i < XVECLEN (p2, 0); i++)
145518334Speter	  if (SET_DEST (XVECEXP (p2, 0, i)) == SET_SRC (PATTERN (i3)))
145618334Speter	    {
145718334Speter	      combine_merges++;
145818334Speter
145918334Speter	      subst_insn = i3;
146018334Speter	      subst_low_cuid = INSN_CUID (i2);
146118334Speter
146218334Speter	      added_sets_2 = added_sets_1 = 0;
146318334Speter	      i2dest = SET_SRC (PATTERN (i3));
146418334Speter
146518334Speter	      /* Replace the dest in I2 with our dest and make the resulting
146618334Speter		 insn the new pattern for I3.  Then skip to where we
146718334Speter		 validate the pattern.  Everything was set up above.  */
146818334Speter	      SUBST (SET_DEST (XVECEXP (p2, 0, i)),
146918334Speter		     SET_DEST (PATTERN (i3)));
147018334Speter
147118334Speter	      newpat = p2;
147218334Speter	      i3_subst_into_i2 = 1;
147318334Speter	      goto validate_replacement;
147418334Speter	    }
147518334Speter    }
147618334Speter
147718334Speter#ifndef HAVE_cc0
147818334Speter  /* If we have no I1 and I2 looks like:
147918334Speter	(parallel [(set (reg:CC X) (compare:CC OP (const_int 0)))
148018334Speter		   (set Y OP)])
148118334Speter     make up a dummy I1 that is
148218334Speter	(set Y OP)
148318334Speter     and change I2 to be
148418334Speter        (set (reg:CC X) (compare:CC Y (const_int 0)))
148518334Speter
148618334Speter     (We can ignore any trailing CLOBBERs.)
148718334Speter
148818334Speter     This undoes a previous combination and allows us to match a branch-and-
148918334Speter     decrement insn.  */
149018334Speter
149118334Speter  if (i1 == 0 && GET_CODE (PATTERN (i2)) == PARALLEL
149218334Speter      && XVECLEN (PATTERN (i2), 0) >= 2
149318334Speter      && GET_CODE (XVECEXP (PATTERN (i2), 0, 0)) == SET
149418334Speter      && (GET_MODE_CLASS (GET_MODE (SET_DEST (XVECEXP (PATTERN (i2), 0, 0))))
149518334Speter	  == MODE_CC)
149618334Speter      && GET_CODE (SET_SRC (XVECEXP (PATTERN (i2), 0, 0))) == COMPARE
149718334Speter      && XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 1) == const0_rtx
149818334Speter      && GET_CODE (XVECEXP (PATTERN (i2), 0, 1)) == SET
149918334Speter      && GET_CODE (SET_DEST (XVECEXP (PATTERN (i2), 0, 1))) == REG
150018334Speter      && rtx_equal_p (XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 0),
150118334Speter		      SET_SRC (XVECEXP (PATTERN (i2), 0, 1))))
150218334Speter    {
150318334Speter      for (i =  XVECLEN (PATTERN (i2), 0) - 1; i >= 2; i--)
150418334Speter	if (GET_CODE (XVECEXP (PATTERN (i2), 0, i)) != CLOBBER)
150518334Speter	  break;
150618334Speter
150718334Speter      if (i == 1)
150818334Speter	{
150918334Speter	  /* We make I1 with the same INSN_UID as I2.  This gives it
151018334Speter	     the same INSN_CUID for value tracking.  Our fake I1 will
151118334Speter	     never appear in the insn stream so giving it the same INSN_UID
151218334Speter	     as I2 will not cause a problem.  */
151318334Speter
151418334Speter	  subst_prev_insn = i1
151550397Sobrien	    = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2,
151650397Sobrien			    XVECEXP (PATTERN (i2), 0, 1), -1, NULL_RTX,
151750397Sobrien			    NULL_RTX);
151818334Speter
151918334Speter	  SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0));
152018334Speter	  SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),
152118334Speter		 SET_DEST (PATTERN (i1)));
152218334Speter	}
152318334Speter    }
152418334Speter#endif
152518334Speter
152618334Speter  /* Verify that I2 and I1 are valid for combining.  */
152718334Speter  if (! can_combine_p (i2, i3, i1, NULL_RTX, &i2dest, &i2src)
152818334Speter      || (i1 && ! can_combine_p (i1, i3, NULL_RTX, i2, &i1dest, &i1src)))
152918334Speter    {
153018334Speter      undo_all ();
153118334Speter      return 0;
153218334Speter    }
153318334Speter
153418334Speter  /* Record whether I2DEST is used in I2SRC and similarly for the other
153518334Speter     cases.  Knowing this will help in register status updating below.  */
153618334Speter  i2dest_in_i2src = reg_overlap_mentioned_p (i2dest, i2src);
153718334Speter  i1dest_in_i1src = i1 && reg_overlap_mentioned_p (i1dest, i1src);
153818334Speter  i2dest_in_i1src = i1 && reg_overlap_mentioned_p (i2dest, i1src);
153918334Speter
154018334Speter  /* See if I1 directly feeds into I3.  It does if I1DEST is not used
154118334Speter     in I2SRC.  */
154218334Speter  i1_feeds_i3 = i1 && ! reg_overlap_mentioned_p (i1dest, i2src);
154318334Speter
154418334Speter  /* Ensure that I3's pattern can be the destination of combines.  */
154518334Speter  if (! combinable_i3pat (i3, &PATTERN (i3), i2dest, i1dest,
154618334Speter			  i1 && i2dest_in_i1src && i1_feeds_i3,
154718334Speter			  &i3dest_killed))
154818334Speter    {
154918334Speter      undo_all ();
155018334Speter      return 0;
155118334Speter    }
155218334Speter
155318334Speter  /* See if any of the insns is a MULT operation.  Unless one is, we will
155418334Speter     reject a combination that is, since it must be slower.  Be conservative
155518334Speter     here.  */
155618334Speter  if (GET_CODE (i2src) == MULT
155718334Speter      || (i1 != 0 && GET_CODE (i1src) == MULT)
155818334Speter      || (GET_CODE (PATTERN (i3)) == SET
155918334Speter	  && GET_CODE (SET_SRC (PATTERN (i3))) == MULT))
156018334Speter    have_mult = 1;
156118334Speter
156218334Speter  /* If I3 has an inc, then give up if I1 or I2 uses the reg that is inc'd.
156318334Speter     We used to do this EXCEPT in one case: I3 has a post-inc in an
156418334Speter     output operand.  However, that exception can give rise to insns like
156518334Speter     	mov r3,(r3)+
156618334Speter     which is a famous insn on the PDP-11 where the value of r3 used as the
156718334Speter     source was model-dependent.  Avoid this sort of thing.  */
156818334Speter
156918334Speter#if 0
157018334Speter  if (!(GET_CODE (PATTERN (i3)) == SET
157118334Speter	&& GET_CODE (SET_SRC (PATTERN (i3))) == REG
157218334Speter	&& GET_CODE (SET_DEST (PATTERN (i3))) == MEM
157318334Speter	&& (GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_INC
157418334Speter	    || GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_DEC)))
157518334Speter    /* It's not the exception.  */
157618334Speter#endif
157718334Speter#ifdef AUTO_INC_DEC
157818334Speter    for (link = REG_NOTES (i3); link; link = XEXP (link, 1))
157918334Speter      if (REG_NOTE_KIND (link) == REG_INC
158018334Speter	  && (reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i2))
158118334Speter	      || (i1 != 0
158218334Speter		  && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i1)))))
158318334Speter	{
158418334Speter	  undo_all ();
158518334Speter	  return 0;
158618334Speter	}
158718334Speter#endif
158818334Speter
158918334Speter  /* See if the SETs in I1 or I2 need to be kept around in the merged
159018334Speter     instruction: whenever the value set there is still needed past I3.
159118334Speter     For the SETs in I2, this is easy: we see if I2DEST dies or is set in I3.
159218334Speter
159318334Speter     For the SET in I1, we have two cases:  If I1 and I2 independently
159418334Speter     feed into I3, the set in I1 needs to be kept around if I1DEST dies
159518334Speter     or is set in I3.  Otherwise (if I1 feeds I2 which feeds I3), the set
159618334Speter     in I1 needs to be kept around unless I1DEST dies or is set in either
159718334Speter     I2 or I3.  We can distinguish these cases by seeing if I2SRC mentions
159818334Speter     I1DEST.  If so, we know I1 feeds into I2.  */
159918334Speter
160018334Speter  added_sets_2 = ! dead_or_set_p (i3, i2dest);
160118334Speter
160218334Speter  added_sets_1
160318334Speter    = i1 && ! (i1_feeds_i3 ? dead_or_set_p (i3, i1dest)
160418334Speter	       : (dead_or_set_p (i3, i1dest) || dead_or_set_p (i2, i1dest)));
160518334Speter
160618334Speter  /* If the set in I2 needs to be kept around, we must make a copy of
160718334Speter     PATTERN (I2), so that when we substitute I1SRC for I1DEST in
160818334Speter     PATTERN (I2), we are only substituting for the original I1DEST, not into
160918334Speter     an already-substituted copy.  This also prevents making self-referential
161018334Speter     rtx.  If I2 is a PARALLEL, we just need the piece that assigns I2SRC to
161118334Speter     I2DEST.  */
161218334Speter
161318334Speter  i2pat = (GET_CODE (PATTERN (i2)) == PARALLEL
161450397Sobrien	   ? gen_rtx_SET (VOIDmode, i2dest, i2src)
161518334Speter	   : PATTERN (i2));
161618334Speter
161718334Speter  if (added_sets_2)
161818334Speter    i2pat = copy_rtx (i2pat);
161918334Speter
162018334Speter  combine_merges++;
162118334Speter
162218334Speter  /* Substitute in the latest insn for the regs set by the earlier ones.  */
162318334Speter
162418334Speter  maxreg = max_reg_num ();
162518334Speter
162618334Speter  subst_insn = i3;
162718334Speter
162818334Speter  /* It is possible that the source of I2 or I1 may be performing an
162918334Speter     unneeded operation, such as a ZERO_EXTEND of something that is known
163018334Speter     to have the high part zero.  Handle that case by letting subst look at
163118334Speter     the innermost one of them.
163218334Speter
163318334Speter     Another way to do this would be to have a function that tries to
163418334Speter     simplify a single insn instead of merging two or more insns.  We don't
163518334Speter     do this because of the potential of infinite loops and because
163618334Speter     of the potential extra memory required.  However, doing it the way
163718334Speter     we are is a bit of a kludge and doesn't catch all cases.
163818334Speter
163918334Speter     But only do this if -fexpensive-optimizations since it slows things down
164018334Speter     and doesn't usually win.  */
164118334Speter
164218334Speter  if (flag_expensive_optimizations)
164318334Speter    {
164418334Speter      /* Pass pc_rtx so no substitutions are done, just simplifications.
164518334Speter	 The cases that we are interested in here do not involve the few
164618334Speter	 cases were is_replaced is checked.  */
164718334Speter      if (i1)
164818334Speter	{
164918334Speter	  subst_low_cuid = INSN_CUID (i1);
165018334Speter	  i1src = subst (i1src, pc_rtx, pc_rtx, 0, 0);
165118334Speter	}
165218334Speter      else
165318334Speter	{
165418334Speter	  subst_low_cuid = INSN_CUID (i2);
165518334Speter	  i2src = subst (i2src, pc_rtx, pc_rtx, 0, 0);
165618334Speter	}
165718334Speter
165850397Sobrien      undobuf.previous_undos = undobuf.undos;
165918334Speter    }
166018334Speter
166118334Speter#ifndef HAVE_cc0
166218334Speter  /* Many machines that don't use CC0 have insns that can both perform an
166318334Speter     arithmetic operation and set the condition code.  These operations will
166418334Speter     be represented as a PARALLEL with the first element of the vector
166518334Speter     being a COMPARE of an arithmetic operation with the constant zero.
166618334Speter     The second element of the vector will set some pseudo to the result
166718334Speter     of the same arithmetic operation.  If we simplify the COMPARE, we won't
166818334Speter     match such a pattern and so will generate an extra insn.   Here we test
166918334Speter     for this case, where both the comparison and the operation result are
167018334Speter     needed, and make the PARALLEL by just replacing I2DEST in I3SRC with
167118334Speter     I2SRC.  Later we will make the PARALLEL that contains I2.  */
167218334Speter
167318334Speter  if (i1 == 0 && added_sets_2 && GET_CODE (PATTERN (i3)) == SET
167418334Speter      && GET_CODE (SET_SRC (PATTERN (i3))) == COMPARE
167518334Speter      && XEXP (SET_SRC (PATTERN (i3)), 1) == const0_rtx
167618334Speter      && rtx_equal_p (XEXP (SET_SRC (PATTERN (i3)), 0), i2dest))
167718334Speter    {
167850397Sobrien#ifdef EXTRA_CC_MODES
167918334Speter      rtx *cc_use;
168018334Speter      enum machine_mode compare_mode;
168150397Sobrien#endif
168218334Speter
168318334Speter      newpat = PATTERN (i3);
168418334Speter      SUBST (XEXP (SET_SRC (newpat), 0), i2src);
168518334Speter
168618334Speter      i2_is_used = 1;
168718334Speter
168818334Speter#ifdef EXTRA_CC_MODES
168918334Speter      /* See if a COMPARE with the operand we substituted in should be done
169018334Speter	 with the mode that is currently being used.  If not, do the same
169118334Speter	 processing we do in `subst' for a SET; namely, if the destination
169218334Speter	 is used only once, try to replace it with a register of the proper
169318334Speter	 mode and also replace the COMPARE.  */
169418334Speter      if (undobuf.other_insn == 0
169518334Speter	  && (cc_use = find_single_use (SET_DEST (newpat), i3,
169618334Speter					&undobuf.other_insn))
169718334Speter	  && ((compare_mode = SELECT_CC_MODE (GET_CODE (*cc_use),
169818334Speter					      i2src, const0_rtx))
169918334Speter	      != GET_MODE (SET_DEST (newpat))))
170018334Speter	{
170118334Speter	  int regno = REGNO (SET_DEST (newpat));
170250397Sobrien	  rtx new_dest = gen_rtx_REG (compare_mode, regno);
170318334Speter
170418334Speter	  if (regno < FIRST_PSEUDO_REGISTER
170550397Sobrien	      || (REG_N_SETS (regno) == 1 && ! added_sets_2
170618334Speter		  && ! REG_USERVAR_P (SET_DEST (newpat))))
170718334Speter	    {
170818334Speter	      if (regno >= FIRST_PSEUDO_REGISTER)
170918334Speter		SUBST (regno_reg_rtx[regno], new_dest);
171018334Speter
171118334Speter	      SUBST (SET_DEST (newpat), new_dest);
171218334Speter	      SUBST (XEXP (*cc_use, 0), new_dest);
171318334Speter	      SUBST (SET_SRC (newpat),
171418334Speter		     gen_rtx_combine (COMPARE, compare_mode,
171518334Speter				      i2src, const0_rtx));
171618334Speter	    }
171718334Speter	  else
171818334Speter	    undobuf.other_insn = 0;
171918334Speter	}
172018334Speter#endif
172118334Speter    }
172218334Speter  else
172318334Speter#endif
172418334Speter    {
172518334Speter      n_occurrences = 0;		/* `subst' counts here */
172618334Speter
172718334Speter      /* If I1 feeds into I2 (not into I3) and I1DEST is in I1SRC, we
172818334Speter	 need to make a unique copy of I2SRC each time we substitute it
172918334Speter	 to avoid self-referential rtl.  */
173018334Speter
173118334Speter      subst_low_cuid = INSN_CUID (i2);
173218334Speter      newpat = subst (PATTERN (i3), i2dest, i2src, 0,
173318334Speter		      ! i1_feeds_i3 && i1dest_in_i1src);
173450397Sobrien      undobuf.previous_undos = undobuf.undos;
173518334Speter
173618334Speter      /* Record whether i2's body now appears within i3's body.  */
173718334Speter      i2_is_used = n_occurrences;
173818334Speter    }
173918334Speter
174018334Speter  /* If we already got a failure, don't try to do more.  Otherwise,
174118334Speter     try to substitute in I1 if we have it.  */
174218334Speter
174318334Speter  if (i1 && GET_CODE (newpat) != CLOBBER)
174418334Speter    {
174518334Speter      /* Before we can do this substitution, we must redo the test done
174618334Speter	 above (see detailed comments there) that ensures  that I1DEST
174750397Sobrien	 isn't mentioned in any SETs in NEWPAT that are field assignments.  */
174818334Speter
174918334Speter      if (! combinable_i3pat (NULL_RTX, &newpat, i1dest, NULL_RTX,
175018334Speter			      0, NULL_PTR))
175118334Speter	{
175218334Speter	  undo_all ();
175318334Speter	  return 0;
175418334Speter	}
175518334Speter
175618334Speter      n_occurrences = 0;
175718334Speter      subst_low_cuid = INSN_CUID (i1);
175818334Speter      newpat = subst (newpat, i1dest, i1src, 0, 0);
175950397Sobrien      undobuf.previous_undos = undobuf.undos;
176018334Speter    }
176118334Speter
176218334Speter  /* Fail if an autoincrement side-effect has been duplicated.  Be careful
176318334Speter     to count all the ways that I2SRC and I1SRC can be used.  */
176418334Speter  if ((FIND_REG_INC_NOTE (i2, NULL_RTX) != 0
176518334Speter       && i2_is_used + added_sets_2 > 1)
176618334Speter      || (i1 != 0 && FIND_REG_INC_NOTE (i1, NULL_RTX) != 0
176718334Speter	  && (n_occurrences + added_sets_1 + (added_sets_2 && ! i1_feeds_i3)
176818334Speter	      > 1))
176918334Speter      /* Fail if we tried to make a new register (we used to abort, but there's
177018334Speter	 really no reason to).  */
177118334Speter      || max_reg_num () != maxreg
177218334Speter      /* Fail if we couldn't do something and have a CLOBBER.  */
177318334Speter      || GET_CODE (newpat) == CLOBBER
177418334Speter      /* Fail if this new pattern is a MULT and we didn't have one before
177518334Speter	 at the outer level.  */
177618334Speter      || (GET_CODE (newpat) == SET && GET_CODE (SET_SRC (newpat)) == MULT
177718334Speter	  && ! have_mult))
177818334Speter    {
177918334Speter      undo_all ();
178018334Speter      return 0;
178118334Speter    }
178218334Speter
178318334Speter  /* If the actions of the earlier insns must be kept
178418334Speter     in addition to substituting them into the latest one,
178518334Speter     we must make a new PARALLEL for the latest insn
178618334Speter     to hold additional the SETs.  */
178718334Speter
178818334Speter  if (added_sets_1 || added_sets_2)
178918334Speter    {
179018334Speter      combine_extras++;
179118334Speter
179218334Speter      if (GET_CODE (newpat) == PARALLEL)
179318334Speter	{
179418334Speter	  rtvec old = XVEC (newpat, 0);
179518334Speter	  total_sets = XVECLEN (newpat, 0) + added_sets_1 + added_sets_2;
179650397Sobrien	  newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets));
179750397Sobrien	  bcopy ((char *) &old->elem[0], (char *) XVEC (newpat, 0)->elem,
179818334Speter		 sizeof (old->elem[0]) * old->num_elem);
179918334Speter	}
180018334Speter      else
180118334Speter	{
180218334Speter	  rtx old = newpat;
180318334Speter	  total_sets = 1 + added_sets_1 + added_sets_2;
180450397Sobrien	  newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets));
180518334Speter	  XVECEXP (newpat, 0, 0) = old;
180618334Speter	}
180718334Speter
180818334Speter     if (added_sets_1)
180918334Speter       XVECEXP (newpat, 0, --total_sets)
181018334Speter	 = (GET_CODE (PATTERN (i1)) == PARALLEL
181150397Sobrien	    ? gen_rtx_SET (VOIDmode, i1dest, i1src) : PATTERN (i1));
181218334Speter
181318334Speter     if (added_sets_2)
181418334Speter	{
181518334Speter	  /* If there is no I1, use I2's body as is.  We used to also not do
181618334Speter	     the subst call below if I2 was substituted into I3,
181718334Speter	     but that could lose a simplification.  */
181818334Speter	  if (i1 == 0)
181918334Speter	    XVECEXP (newpat, 0, --total_sets) = i2pat;
182018334Speter	  else
182118334Speter	    /* See comment where i2pat is assigned.  */
182218334Speter	    XVECEXP (newpat, 0, --total_sets)
182318334Speter	      = subst (i2pat, i1dest, i1src, 0, 0);
182418334Speter	}
182518334Speter    }
182618334Speter
182718334Speter  /* We come here when we are replacing a destination in I2 with the
182818334Speter     destination of I3.  */
182918334Speter validate_replacement:
183018334Speter
183118334Speter  /* Note which hard regs this insn has as inputs.  */
183218334Speter  mark_used_regs_combine (newpat);
183318334Speter
183418334Speter  /* Is the result of combination a valid instruction?  */
183552284Sobrien  insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
183618334Speter
183718334Speter  /* If the result isn't valid, see if it is a PARALLEL of two SETs where
183818334Speter     the second SET's destination is a register that is unused.  In that case,
183918334Speter     we just need the first SET.   This can occur when simplifying a divmod
184018334Speter     insn.  We *must* test for this case here because the code below that
184118334Speter     splits two independent SETs doesn't handle this case correctly when it
184218334Speter     updates the register status.  Also check the case where the first
184318334Speter     SET's destination is unused.  That would not cause incorrect code, but
184418334Speter     does cause an unneeded insn to remain.  */
184518334Speter
184618334Speter  if (insn_code_number < 0 && GET_CODE (newpat) == PARALLEL
184718334Speter      && XVECLEN (newpat, 0) == 2
184818334Speter      && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
184918334Speter      && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
185018334Speter      && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == REG
185118334Speter      && find_reg_note (i3, REG_UNUSED, SET_DEST (XVECEXP (newpat, 0, 1)))
185218334Speter      && ! side_effects_p (SET_SRC (XVECEXP (newpat, 0, 1)))
185318334Speter      && asm_noperands (newpat) < 0)
185418334Speter    {
185518334Speter      newpat = XVECEXP (newpat, 0, 0);
185652284Sobrien      insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
185718334Speter    }
185818334Speter
185918334Speter  else if (insn_code_number < 0 && GET_CODE (newpat) == PARALLEL
186018334Speter	   && XVECLEN (newpat, 0) == 2
186118334Speter	   && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
186218334Speter	   && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
186318334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) == REG
186418334Speter	   && find_reg_note (i3, REG_UNUSED, SET_DEST (XVECEXP (newpat, 0, 0)))
186518334Speter	   && ! side_effects_p (SET_SRC (XVECEXP (newpat, 0, 0)))
186618334Speter	   && asm_noperands (newpat) < 0)
186718334Speter    {
186818334Speter      newpat = XVECEXP (newpat, 0, 1);
186952284Sobrien      insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
187018334Speter    }
187118334Speter
187218334Speter  /* If we were combining three insns and the result is a simple SET
187318334Speter     with no ASM_OPERANDS that wasn't recognized, try to split it into two
187418334Speter     insns.  There are two ways to do this.  It can be split using a
187518334Speter     machine-specific method (like when you have an addition of a large
187618334Speter     constant) or by combine in the function find_split_point.  */
187718334Speter
187818334Speter  if (i1 && insn_code_number < 0 && GET_CODE (newpat) == SET
187918334Speter      && asm_noperands (newpat) < 0)
188018334Speter    {
188118334Speter      rtx m_split, *split;
188218334Speter      rtx ni2dest = i2dest;
188318334Speter
188418334Speter      /* See if the MD file can split NEWPAT.  If it can't, see if letting it
188518334Speter	 use I2DEST as a scratch register will help.  In the latter case,
188618334Speter	 convert I2DEST to the mode of the source of NEWPAT if we can.  */
188718334Speter
188818334Speter      m_split = split_insns (newpat, i3);
188918334Speter
189018334Speter      /* We can only use I2DEST as a scratch reg if it doesn't overlap any
189118334Speter	 inputs of NEWPAT.  */
189218334Speter
189318334Speter      /* ??? If I2DEST is not safe, and I1DEST exists, then it would be
189418334Speter	 possible to try that as a scratch reg.  This would require adding
189518334Speter	 more code to make it work though.  */
189618334Speter
189718334Speter      if (m_split == 0 && ! reg_overlap_mentioned_p (ni2dest, newpat))
189818334Speter	{
189918334Speter	  /* If I2DEST is a hard register or the only use of a pseudo,
190018334Speter	     we can change its mode.  */
190118334Speter	  if (GET_MODE (SET_DEST (newpat)) != GET_MODE (i2dest)
190218334Speter	      && GET_MODE (SET_DEST (newpat)) != VOIDmode
190318334Speter	      && GET_CODE (i2dest) == REG
190418334Speter	      && (REGNO (i2dest) < FIRST_PSEUDO_REGISTER
190550397Sobrien		  || (REG_N_SETS (REGNO (i2dest)) == 1 && ! added_sets_2
190618334Speter		      && ! REG_USERVAR_P (i2dest))))
190750397Sobrien	    ni2dest = gen_rtx_REG (GET_MODE (SET_DEST (newpat)),
190818334Speter			       REGNO (i2dest));
190918334Speter
191050397Sobrien	  m_split = split_insns
191150397Sobrien	    (gen_rtx_PARALLEL (VOIDmode,
191250397Sobrien			       gen_rtvec (2, newpat,
191350397Sobrien					  gen_rtx_CLOBBER (VOIDmode,
191450397Sobrien							   ni2dest))),
191550397Sobrien	     i3);
191618334Speter	}
191718334Speter
191818334Speter      if (m_split && GET_CODE (m_split) == SEQUENCE
191918334Speter	  && XVECLEN (m_split, 0) == 2
192018334Speter	  && (next_real_insn (i2) == i3
192118334Speter	      || ! use_crosses_set_p (PATTERN (XVECEXP (m_split, 0, 0)),
192218334Speter				      INSN_CUID (i2))))
192318334Speter	{
192418334Speter	  rtx i2set, i3set;
192518334Speter	  rtx newi3pat = PATTERN (XVECEXP (m_split, 0, 1));
192618334Speter	  newi2pat = PATTERN (XVECEXP (m_split, 0, 0));
192718334Speter
192818334Speter	  i3set = single_set (XVECEXP (m_split, 0, 1));
192918334Speter	  i2set = single_set (XVECEXP (m_split, 0, 0));
193018334Speter
193118334Speter	  /* In case we changed the mode of I2DEST, replace it in the
193218334Speter	     pseudo-register table here.  We can't do it above in case this
193318334Speter	     code doesn't get executed and we do a split the other way.  */
193418334Speter
193518334Speter	  if (REGNO (i2dest) >= FIRST_PSEUDO_REGISTER)
193618334Speter	    SUBST (regno_reg_rtx[REGNO (i2dest)], ni2dest);
193718334Speter
193852284Sobrien	  i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
193918334Speter
194018334Speter	  /* If I2 or I3 has multiple SETs, we won't know how to track
194150397Sobrien	     register status, so don't use these insns.  If I2's destination
194250397Sobrien	     is used between I2 and I3, we also can't use these insns.  */
194318334Speter
194450397Sobrien	  if (i2_code_number >= 0 && i2set && i3set
194550397Sobrien	      && (next_real_insn (i2) == i3
194650397Sobrien		  || ! reg_used_between_p (SET_DEST (i2set), i2, i3)))
194752284Sobrien	    insn_code_number = recog_for_combine (&newi3pat, i3,
194852284Sobrien						  &new_i3_notes);
194918334Speter	  if (insn_code_number >= 0)
195018334Speter	    newpat = newi3pat;
195118334Speter
195218334Speter	  /* It is possible that both insns now set the destination of I3.
195318334Speter	     If so, we must show an extra use of it.  */
195418334Speter
195550397Sobrien	  if (insn_code_number >= 0)
195650397Sobrien	    {
195750397Sobrien	      rtx new_i3_dest = SET_DEST (i3set);
195850397Sobrien	      rtx new_i2_dest = SET_DEST (i2set);
195950397Sobrien
196050397Sobrien	      while (GET_CODE (new_i3_dest) == ZERO_EXTRACT
196150397Sobrien		     || GET_CODE (new_i3_dest) == STRICT_LOW_PART
196250397Sobrien		     || GET_CODE (new_i3_dest) == SUBREG)
196350397Sobrien		new_i3_dest = XEXP (new_i3_dest, 0);
196450397Sobrien
196550397Sobrien	      while (GET_CODE (new_i2_dest) == ZERO_EXTRACT
196650397Sobrien		     || GET_CODE (new_i2_dest) == STRICT_LOW_PART
196750397Sobrien		     || GET_CODE (new_i2_dest) == SUBREG)
196850397Sobrien		new_i2_dest = XEXP (new_i2_dest, 0);
196950397Sobrien
197050397Sobrien	      if (GET_CODE (new_i3_dest) == REG
197150397Sobrien		  && GET_CODE (new_i2_dest) == REG
197250397Sobrien		  && REGNO (new_i3_dest) == REGNO (new_i2_dest))
197350397Sobrien		REG_N_SETS (REGNO (new_i2_dest))++;
197450397Sobrien	    }
197518334Speter	}
197618334Speter
197718334Speter      /* If we can split it and use I2DEST, go ahead and see if that
197818334Speter	 helps things be recognized.  Verify that none of the registers
197918334Speter	 are set between I2 and I3.  */
198018334Speter      if (insn_code_number < 0 && (split = find_split_point (&newpat, i3)) != 0
198118334Speter#ifdef HAVE_cc0
198218334Speter	  && GET_CODE (i2dest) == REG
198318334Speter#endif
198418334Speter	  /* We need I2DEST in the proper mode.  If it is a hard register
198518334Speter	     or the only use of a pseudo, we can change its mode.  */
198618334Speter	  && (GET_MODE (*split) == GET_MODE (i2dest)
198718334Speter	      || GET_MODE (*split) == VOIDmode
198818334Speter	      || REGNO (i2dest) < FIRST_PSEUDO_REGISTER
198950397Sobrien	      || (REG_N_SETS (REGNO (i2dest)) == 1 && ! added_sets_2
199018334Speter		  && ! REG_USERVAR_P (i2dest)))
199118334Speter	  && (next_real_insn (i2) == i3
199218334Speter	      || ! use_crosses_set_p (*split, INSN_CUID (i2)))
199318334Speter	  /* We can't overwrite I2DEST if its value is still used by
199418334Speter	     NEWPAT.  */
199518334Speter	  && ! reg_referenced_p (i2dest, newpat))
199618334Speter	{
199718334Speter	  rtx newdest = i2dest;
199818334Speter	  enum rtx_code split_code = GET_CODE (*split);
199918334Speter	  enum machine_mode split_mode = GET_MODE (*split);
200018334Speter
200118334Speter	  /* Get NEWDEST as a register in the proper mode.  We have already
200218334Speter	     validated that we can do this.  */
200318334Speter	  if (GET_MODE (i2dest) != split_mode && split_mode != VOIDmode)
200418334Speter	    {
200550397Sobrien	      newdest = gen_rtx_REG (split_mode, REGNO (i2dest));
200618334Speter
200718334Speter	      if (REGNO (i2dest) >= FIRST_PSEUDO_REGISTER)
200818334Speter		SUBST (regno_reg_rtx[REGNO (i2dest)], newdest);
200918334Speter	    }
201018334Speter
201118334Speter	  /* If *SPLIT is a (mult FOO (const_int pow2)), convert it to
201218334Speter	     an ASHIFT.  This can occur if it was inside a PLUS and hence
201318334Speter	     appeared to be a memory address.  This is a kludge.  */
201418334Speter	  if (split_code == MULT
201518334Speter	      && GET_CODE (XEXP (*split, 1)) == CONST_INT
201618334Speter	      && (i = exact_log2 (INTVAL (XEXP (*split, 1)))) >= 0)
201718334Speter	    {
201818334Speter	      SUBST (*split, gen_rtx_combine (ASHIFT, split_mode,
201918334Speter					      XEXP (*split, 0), GEN_INT (i)));
202018334Speter	      /* Update split_code because we may not have a multiply
202118334Speter		 anymore.  */
202218334Speter	      split_code = GET_CODE (*split);
202318334Speter	    }
202418334Speter
202518334Speter#ifdef INSN_SCHEDULING
202618334Speter	  /* If *SPLIT is a paradoxical SUBREG, when we split it, it should
202718334Speter	     be written as a ZERO_EXTEND.  */
202818334Speter	  if (split_code == SUBREG && GET_CODE (SUBREG_REG (*split)) == MEM)
202918334Speter	    SUBST (*split, gen_rtx_combine (ZERO_EXTEND, split_mode,
203018334Speter					    XEXP (*split, 0)));
203118334Speter#endif
203218334Speter
203318334Speter	  newi2pat = gen_rtx_combine (SET, VOIDmode, newdest, *split);
203418334Speter	  SUBST (*split, newdest);
203552284Sobrien	  i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
203618334Speter
203718334Speter	  /* If the split point was a MULT and we didn't have one before,
203818334Speter	     don't use one now.  */
203918334Speter	  if (i2_code_number >= 0 && ! (split_code == MULT && ! have_mult))
204052284Sobrien	    insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
204118334Speter	}
204218334Speter    }
204318334Speter
204418334Speter  /* Check for a case where we loaded from memory in a narrow mode and
204518334Speter     then sign extended it, but we need both registers.  In that case,
204618334Speter     we have a PARALLEL with both loads from the same memory location.
204718334Speter     We can split this into a load from memory followed by a register-register
204818334Speter     copy.  This saves at least one insn, more if register allocation can
204918334Speter     eliminate the copy.
205018334Speter
205118334Speter     We cannot do this if the destination of the second assignment is
205218334Speter     a register that we have already assumed is zero-extended.  Similarly
205318334Speter     for a SUBREG of such a register.  */
205418334Speter
205518334Speter  else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0
205618334Speter	   && GET_CODE (newpat) == PARALLEL
205718334Speter	   && XVECLEN (newpat, 0) == 2
205818334Speter	   && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
205918334Speter	   && GET_CODE (SET_SRC (XVECEXP (newpat, 0, 0))) == SIGN_EXTEND
206018334Speter	   && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
206118334Speter	   && rtx_equal_p (SET_SRC (XVECEXP (newpat, 0, 1)),
206218334Speter			   XEXP (SET_SRC (XVECEXP (newpat, 0, 0)), 0))
206318334Speter	   && ! use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)),
206418334Speter				   INSN_CUID (i2))
206518334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT
206618334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
206718334Speter	   && ! (temp = SET_DEST (XVECEXP (newpat, 0, 1)),
206818334Speter		 (GET_CODE (temp) == REG
206918334Speter		  && reg_nonzero_bits[REGNO (temp)] != 0
207018334Speter		  && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
207118334Speter		  && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
207218334Speter		  && (reg_nonzero_bits[REGNO (temp)]
207318334Speter		      != GET_MODE_MASK (word_mode))))
207418334Speter	   && ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == SUBREG
207518334Speter		 && (temp = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1))),
207618334Speter		     (GET_CODE (temp) == REG
207718334Speter		      && reg_nonzero_bits[REGNO (temp)] != 0
207818334Speter		      && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
207918334Speter		      && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
208018334Speter		      && (reg_nonzero_bits[REGNO (temp)]
208118334Speter			  != GET_MODE_MASK (word_mode)))))
208218334Speter	   && ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1)),
208318334Speter					 SET_SRC (XVECEXP (newpat, 0, 1)))
208418334Speter	   && ! find_reg_note (i3, REG_UNUSED,
208518334Speter			       SET_DEST (XVECEXP (newpat, 0, 0))))
208618334Speter    {
208718334Speter      rtx ni2dest;
208818334Speter
208918334Speter      newi2pat = XVECEXP (newpat, 0, 0);
209018334Speter      ni2dest = SET_DEST (XVECEXP (newpat, 0, 0));
209118334Speter      newpat = XVECEXP (newpat, 0, 1);
209218334Speter      SUBST (SET_SRC (newpat),
209318334Speter	     gen_lowpart_for_combine (GET_MODE (SET_SRC (newpat)), ni2dest));
209452284Sobrien      i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
209518334Speter
209618334Speter      if (i2_code_number >= 0)
209752284Sobrien	insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
209818334Speter
209918334Speter      if (insn_code_number >= 0)
210018334Speter	{
210118334Speter	  rtx insn;
210218334Speter	  rtx link;
210318334Speter
210418334Speter	  /* If we will be able to accept this, we have made a change to the
210518334Speter	     destination of I3.  This can invalidate a LOG_LINKS pointing
210618334Speter	     to I3.  No other part of combine.c makes such a transformation.
210718334Speter
210818334Speter	     The new I3 will have a destination that was previously the
210918334Speter	     destination of I1 or I2 and which was used in i2 or I3.  Call
211018334Speter	     distribute_links to make a LOG_LINK from the next use of
211118334Speter	     that destination.  */
211218334Speter
211318334Speter	  PATTERN (i3) = newpat;
211450397Sobrien	  distribute_links (gen_rtx_INSN_LIST (VOIDmode, i3, NULL_RTX));
211518334Speter
211618334Speter	  /* I3 now uses what used to be its destination and which is
211718334Speter	     now I2's destination.  That means we need a LOG_LINK from
211818334Speter	     I3 to I2.  But we used to have one, so we still will.
211918334Speter
212018334Speter	     However, some later insn might be using I2's dest and have
212118334Speter	     a LOG_LINK pointing at I3.  We must remove this link.
212218334Speter	     The simplest way to remove the link is to point it at I1,
212318334Speter	     which we know will be a NOTE.  */
212418334Speter
212518334Speter	  for (insn = NEXT_INSN (i3);
212618334Speter	       insn && (this_basic_block == n_basic_blocks - 1
212752284Sobrien			|| insn != BLOCK_HEAD (this_basic_block + 1));
212818334Speter	       insn = NEXT_INSN (insn))
212918334Speter	    {
213018334Speter	      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
213118334Speter		  && reg_referenced_p (ni2dest, PATTERN (insn)))
213218334Speter		{
213318334Speter		  for (link = LOG_LINKS (insn); link;
213418334Speter		       link = XEXP (link, 1))
213518334Speter		    if (XEXP (link, 0) == i3)
213618334Speter		      XEXP (link, 0) = i1;
213718334Speter
213818334Speter		  break;
213918334Speter		}
214018334Speter	    }
214118334Speter	}
214218334Speter    }
214318334Speter
214418334Speter  /* Similarly, check for a case where we have a PARALLEL of two independent
214518334Speter     SETs but we started with three insns.  In this case, we can do the sets
214618334Speter     as two separate insns.  This case occurs when some SET allows two
214718334Speter     other insns to combine, but the destination of that SET is still live.  */
214818334Speter
214918334Speter  else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0
215018334Speter	   && GET_CODE (newpat) == PARALLEL
215118334Speter	   && XVECLEN (newpat, 0) == 2
215218334Speter	   && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
215318334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != ZERO_EXTRACT
215418334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != STRICT_LOW_PART
215518334Speter	   && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
215618334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT
215718334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
215818334Speter	   && ! use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)),
215918334Speter				   INSN_CUID (i2))
216018334Speter	   /* Don't pass sets with (USE (MEM ...)) dests to the following.  */
216118334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != USE
216218334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != USE
216318334Speter	   && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 1)),
216418334Speter				  XVECEXP (newpat, 0, 0))
216518334Speter	   && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 0)),
216618334Speter				  XVECEXP (newpat, 0, 1)))
216718334Speter    {
216850397Sobrien      /* Normally, it doesn't matter which of the two is done first,
216950397Sobrien	 but it does if one references cc0.  In that case, it has to
217050397Sobrien	 be first.  */
217150397Sobrien#ifdef HAVE_cc0
217250397Sobrien      if (reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0)))
217350397Sobrien	{
217450397Sobrien	  newi2pat = XVECEXP (newpat, 0, 0);
217550397Sobrien	  newpat = XVECEXP (newpat, 0, 1);
217650397Sobrien	}
217750397Sobrien      else
217850397Sobrien#endif
217950397Sobrien	{
218050397Sobrien	  newi2pat = XVECEXP (newpat, 0, 1);
218150397Sobrien	  newpat = XVECEXP (newpat, 0, 0);
218250397Sobrien	}
218318334Speter
218452284Sobrien      i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
218518334Speter
218618334Speter      if (i2_code_number >= 0)
218752284Sobrien	insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
218818334Speter    }
218918334Speter
219018334Speter  /* If it still isn't recognized, fail and change things back the way they
219118334Speter     were.  */
219218334Speter  if ((insn_code_number < 0
219318334Speter       /* Is the result a reasonable ASM_OPERANDS?  */
219418334Speter       && (! check_asm_operands (newpat) || added_sets_1 || added_sets_2)))
219518334Speter    {
219618334Speter      undo_all ();
219718334Speter      return 0;
219818334Speter    }
219918334Speter
220018334Speter  /* If we had to change another insn, make sure it is valid also.  */
220118334Speter  if (undobuf.other_insn)
220218334Speter    {
220318334Speter      rtx other_pat = PATTERN (undobuf.other_insn);
220418334Speter      rtx new_other_notes;
220518334Speter      rtx note, next;
220618334Speter
220718334Speter      CLEAR_HARD_REG_SET (newpat_used_regs);
220818334Speter
220952284Sobrien      other_code_number = recog_for_combine (&other_pat, undobuf.other_insn,
221052284Sobrien					     &new_other_notes);
221118334Speter
221218334Speter      if (other_code_number < 0 && ! check_asm_operands (other_pat))
221318334Speter	{
221418334Speter	  undo_all ();
221518334Speter	  return 0;
221618334Speter	}
221718334Speter
221818334Speter      PATTERN (undobuf.other_insn) = other_pat;
221918334Speter
222018334Speter      /* If any of the notes in OTHER_INSN were REG_UNUSED, ensure that they
222118334Speter	 are still valid.  Then add any non-duplicate notes added by
222218334Speter	 recog_for_combine.  */
222318334Speter      for (note = REG_NOTES (undobuf.other_insn); note; note = next)
222418334Speter	{
222518334Speter	  next = XEXP (note, 1);
222618334Speter
222718334Speter	  if (REG_NOTE_KIND (note) == REG_UNUSED
222818334Speter	      && ! reg_set_p (XEXP (note, 0), PATTERN (undobuf.other_insn)))
222918334Speter	    {
223018334Speter	      if (GET_CODE (XEXP (note, 0)) == REG)
223150397Sobrien		REG_N_DEATHS (REGNO (XEXP (note, 0)))--;
223218334Speter
223318334Speter	      remove_note (undobuf.other_insn, note);
223418334Speter	    }
223518334Speter	}
223618334Speter
223718334Speter      for (note = new_other_notes; note; note = XEXP (note, 1))
223818334Speter	if (GET_CODE (XEXP (note, 0)) == REG)
223950397Sobrien	  REG_N_DEATHS (REGNO (XEXP (note, 0)))++;
224018334Speter
224118334Speter      distribute_notes (new_other_notes, undobuf.other_insn,
224218334Speter			undobuf.other_insn, NULL_RTX, NULL_RTX, NULL_RTX);
224318334Speter    }
224418334Speter
224518334Speter  /* We now know that we can do this combination.  Merge the insns and
224618334Speter     update the status of registers and LOG_LINKS.  */
224718334Speter
224818334Speter  {
224918334Speter    rtx i3notes, i2notes, i1notes = 0;
225018334Speter    rtx i3links, i2links, i1links = 0;
225118334Speter    rtx midnotes = 0;
225218334Speter    register int regno;
225350397Sobrien    /* Compute which registers we expect to eliminate.  newi2pat may be setting
225450397Sobrien       either i3dest or i2dest, so we must check it.  Also, i1dest may be the
225550397Sobrien       same as i3dest, in which case newi2pat may be setting i1dest.  */
225650397Sobrien    rtx elim_i2 = ((newi2pat && reg_set_p (i2dest, newi2pat))
225750397Sobrien		   || i2dest_in_i2src || i2dest_in_i1src
225818334Speter		   ? 0 : i2dest);
225950397Sobrien    rtx elim_i1 = (i1 == 0 || i1dest_in_i1src
226050397Sobrien		   || (newi2pat && reg_set_p (i1dest, newi2pat))
226150397Sobrien		   ? 0 : i1dest);
226218334Speter
226318334Speter    /* Get the old REG_NOTES and LOG_LINKS from all our insns and
226418334Speter       clear them.  */
226518334Speter    i3notes = REG_NOTES (i3), i3links = LOG_LINKS (i3);
226618334Speter    i2notes = REG_NOTES (i2), i2links = LOG_LINKS (i2);
226718334Speter    if (i1)
226818334Speter      i1notes = REG_NOTES (i1), i1links = LOG_LINKS (i1);
226918334Speter
227018334Speter    /* Ensure that we do not have something that should not be shared but
227118334Speter       occurs multiple times in the new insns.  Check this by first
227218334Speter       resetting all the `used' flags and then copying anything is shared.  */
227318334Speter
227418334Speter    reset_used_flags (i3notes);
227518334Speter    reset_used_flags (i2notes);
227618334Speter    reset_used_flags (i1notes);
227718334Speter    reset_used_flags (newpat);
227818334Speter    reset_used_flags (newi2pat);
227918334Speter    if (undobuf.other_insn)
228018334Speter      reset_used_flags (PATTERN (undobuf.other_insn));
228118334Speter
228218334Speter    i3notes = copy_rtx_if_shared (i3notes);
228318334Speter    i2notes = copy_rtx_if_shared (i2notes);
228418334Speter    i1notes = copy_rtx_if_shared (i1notes);
228518334Speter    newpat = copy_rtx_if_shared (newpat);
228618334Speter    newi2pat = copy_rtx_if_shared (newi2pat);
228718334Speter    if (undobuf.other_insn)
228818334Speter      reset_used_flags (PATTERN (undobuf.other_insn));
228918334Speter
229018334Speter    INSN_CODE (i3) = insn_code_number;
229118334Speter    PATTERN (i3) = newpat;
229218334Speter    if (undobuf.other_insn)
229318334Speter      INSN_CODE (undobuf.other_insn) = other_code_number;
229418334Speter
229518334Speter    /* We had one special case above where I2 had more than one set and
229618334Speter       we replaced a destination of one of those sets with the destination
229718334Speter       of I3.  In that case, we have to update LOG_LINKS of insns later
229818334Speter       in this basic block.  Note that this (expensive) case is rare.
229918334Speter
230018334Speter       Also, in this case, we must pretend that all REG_NOTEs for I2
230118334Speter       actually came from I3, so that REG_UNUSED notes from I2 will be
230218334Speter       properly handled.  */
230318334Speter
230418334Speter    if (i3_subst_into_i2)
230518334Speter      {
230618334Speter	for (i = 0; i < XVECLEN (PATTERN (i2), 0); i++)
230718334Speter	  if (GET_CODE (SET_DEST (XVECEXP (PATTERN (i2), 0, i))) == REG
230818334Speter	      && SET_DEST (XVECEXP (PATTERN (i2), 0, i)) != i2dest
230918334Speter	      && ! find_reg_note (i2, REG_UNUSED,
231018334Speter				  SET_DEST (XVECEXP (PATTERN (i2), 0, i))))
231118334Speter	    for (temp = NEXT_INSN (i2);
231218334Speter		 temp && (this_basic_block == n_basic_blocks - 1
231352284Sobrien			  || BLOCK_HEAD (this_basic_block) != temp);
231418334Speter		 temp = NEXT_INSN (temp))
231518334Speter	      if (temp != i3 && GET_RTX_CLASS (GET_CODE (temp)) == 'i')
231618334Speter		for (link = LOG_LINKS (temp); link; link = XEXP (link, 1))
231718334Speter		  if (XEXP (link, 0) == i2)
231818334Speter		    XEXP (link, 0) = i3;
231918334Speter
232018334Speter	if (i3notes)
232118334Speter	  {
232218334Speter	    rtx link = i3notes;
232318334Speter	    while (XEXP (link, 1))
232418334Speter	      link = XEXP (link, 1);
232518334Speter	    XEXP (link, 1) = i2notes;
232618334Speter	  }
232718334Speter	else
232818334Speter	  i3notes = i2notes;
232918334Speter	i2notes = 0;
233018334Speter      }
233118334Speter
233218334Speter    LOG_LINKS (i3) = 0;
233318334Speter    REG_NOTES (i3) = 0;
233418334Speter    LOG_LINKS (i2) = 0;
233518334Speter    REG_NOTES (i2) = 0;
233618334Speter
233718334Speter    if (newi2pat)
233818334Speter      {
233918334Speter	INSN_CODE (i2) = i2_code_number;
234018334Speter	PATTERN (i2) = newi2pat;
234118334Speter      }
234218334Speter    else
234318334Speter      {
234418334Speter	PUT_CODE (i2, NOTE);
234518334Speter	NOTE_LINE_NUMBER (i2) = NOTE_INSN_DELETED;
234618334Speter	NOTE_SOURCE_FILE (i2) = 0;
234718334Speter      }
234818334Speter
234918334Speter    if (i1)
235018334Speter      {
235118334Speter	LOG_LINKS (i1) = 0;
235218334Speter	REG_NOTES (i1) = 0;
235318334Speter	PUT_CODE (i1, NOTE);
235418334Speter	NOTE_LINE_NUMBER (i1) = NOTE_INSN_DELETED;
235518334Speter	NOTE_SOURCE_FILE (i1) = 0;
235618334Speter      }
235718334Speter
235818334Speter    /* Get death notes for everything that is now used in either I3 or
235950397Sobrien       I2 and used to die in a previous insn.  If we built two new
236050397Sobrien       patterns, move from I1 to I2 then I2 to I3 so that we get the
236150397Sobrien       proper movement on registers that I2 modifies.  */
236218334Speter
236318334Speter    if (newi2pat)
236450397Sobrien      {
236550397Sobrien	move_deaths (newi2pat, NULL_RTX, INSN_CUID (i1), i2, &midnotes);
236650397Sobrien	move_deaths (newpat, newi2pat, INSN_CUID (i1), i3, &midnotes);
236750397Sobrien      }
236850397Sobrien    else
236950397Sobrien      move_deaths (newpat, NULL_RTX, i1 ? INSN_CUID (i1) : INSN_CUID (i2),
237050397Sobrien		   i3, &midnotes);
237118334Speter
237218334Speter    /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3.  */
237318334Speter    if (i3notes)
237418334Speter      distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL_RTX,
237518334Speter			elim_i2, elim_i1);
237618334Speter    if (i2notes)
237718334Speter      distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL_RTX,
237818334Speter			elim_i2, elim_i1);
237918334Speter    if (i1notes)
238018334Speter      distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL_RTX,
238118334Speter			elim_i2, elim_i1);
238218334Speter    if (midnotes)
238318334Speter      distribute_notes (midnotes, NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
238418334Speter			elim_i2, elim_i1);
238518334Speter
238618334Speter    /* Distribute any notes added to I2 or I3 by recog_for_combine.  We
238718334Speter       know these are REG_UNUSED and want them to go to the desired insn,
238818334Speter       so we always pass it as i3.  We have not counted the notes in
238918334Speter       reg_n_deaths yet, so we need to do so now.  */
239018334Speter
239118334Speter    if (newi2pat && new_i2_notes)
239218334Speter      {
239318334Speter	for (temp = new_i2_notes; temp; temp = XEXP (temp, 1))
239418334Speter	  if (GET_CODE (XEXP (temp, 0)) == REG)
239550397Sobrien	    REG_N_DEATHS (REGNO (XEXP (temp, 0)))++;
239618334Speter
239718334Speter	distribute_notes (new_i2_notes, i2, i2, NULL_RTX, NULL_RTX, NULL_RTX);
239818334Speter      }
239918334Speter
240018334Speter    if (new_i3_notes)
240118334Speter      {
240218334Speter	for (temp = new_i3_notes; temp; temp = XEXP (temp, 1))
240318334Speter	  if (GET_CODE (XEXP (temp, 0)) == REG)
240450397Sobrien	    REG_N_DEATHS (REGNO (XEXP (temp, 0)))++;
240518334Speter
240618334Speter	distribute_notes (new_i3_notes, i3, i3, NULL_RTX, NULL_RTX, NULL_RTX);
240718334Speter      }
240818334Speter
240918334Speter    /* If I3DEST was used in I3SRC, it really died in I3.  We may need to
241050397Sobrien       put a REG_DEAD note for it somewhere.  If NEWI2PAT exists and sets
241150397Sobrien       I3DEST, the death must be somewhere before I2, not I3.  If we passed I3
241250397Sobrien       in that case, it might delete I2.  Similarly for I2 and I1.
241318334Speter       Show an additional death due to the REG_DEAD note we make here.  If
241418334Speter       we discard it in distribute_notes, we will decrement it again.  */
241518334Speter
241618334Speter    if (i3dest_killed)
241718334Speter      {
241818334Speter	if (GET_CODE (i3dest_killed) == REG)
241950397Sobrien	  REG_N_DEATHS (REGNO (i3dest_killed))++;
242018334Speter
242150397Sobrien	if (newi2pat && reg_set_p (i3dest_killed, newi2pat))
242250397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed,
242350397Sobrien					       NULL_RTX),
242450397Sobrien			    NULL_RTX, i2, NULL_RTX, elim_i2, elim_i1);
242550397Sobrien	else
242650397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed,
242750397Sobrien					       NULL_RTX),
242850397Sobrien			    NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
242950397Sobrien			    elim_i2, elim_i1);
243018334Speter      }
243118334Speter
243218334Speter    if (i2dest_in_i2src)
243318334Speter      {
243418334Speter	if (GET_CODE (i2dest) == REG)
243550397Sobrien	  REG_N_DEATHS (REGNO (i2dest))++;
243618334Speter
243718334Speter	if (newi2pat && reg_set_p (i2dest, newi2pat))
243850397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX),
243918334Speter			    NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX);
244018334Speter	else
244150397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX),
244218334Speter			    NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
244318334Speter			    NULL_RTX, NULL_RTX);
244418334Speter      }
244518334Speter
244618334Speter    if (i1dest_in_i1src)
244718334Speter      {
244818334Speter	if (GET_CODE (i1dest) == REG)
244950397Sobrien	  REG_N_DEATHS (REGNO (i1dest))++;
245018334Speter
245118334Speter	if (newi2pat && reg_set_p (i1dest, newi2pat))
245250397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX),
245318334Speter			    NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX);
245418334Speter	else
245550397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX),
245618334Speter			    NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
245718334Speter			    NULL_RTX, NULL_RTX);
245818334Speter      }
245918334Speter
246018334Speter    distribute_links (i3links);
246118334Speter    distribute_links (i2links);
246218334Speter    distribute_links (i1links);
246318334Speter
246418334Speter    if (GET_CODE (i2dest) == REG)
246518334Speter      {
246618334Speter	rtx link;
246718334Speter	rtx i2_insn = 0, i2_val = 0, set;
246818334Speter
246918334Speter	/* The insn that used to set this register doesn't exist, and
247018334Speter	   this life of the register may not exist either.  See if one of
247118334Speter	   I3's links points to an insn that sets I2DEST.  If it does,
247218334Speter	   that is now the last known value for I2DEST. If we don't update
247318334Speter	   this and I2 set the register to a value that depended on its old
247418334Speter	   contents, we will get confused.  If this insn is used, thing
247518334Speter	   will be set correctly in combine_instructions.  */
247618334Speter
247718334Speter	for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
247818334Speter	  if ((set = single_set (XEXP (link, 0))) != 0
247918334Speter	      && rtx_equal_p (i2dest, SET_DEST (set)))
248018334Speter	    i2_insn = XEXP (link, 0), i2_val = SET_SRC (set);
248118334Speter
248218334Speter	record_value_for_reg (i2dest, i2_insn, i2_val);
248318334Speter
248418334Speter	/* If the reg formerly set in I2 died only once and that was in I3,
248518334Speter	   zero its use count so it won't make `reload' do any work.  */
248650397Sobrien	if (! added_sets_2
248750397Sobrien	    && (newi2pat == 0 || ! reg_mentioned_p (i2dest, newi2pat))
248850397Sobrien	    && ! i2dest_in_i2src)
248918334Speter	  {
249018334Speter	    regno = REGNO (i2dest);
249150397Sobrien	    REG_N_SETS (regno)--;
249250397Sobrien	    if (REG_N_SETS (regno) == 0
249352284Sobrien		&& ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start,
249452284Sobrien				      regno))
249550397Sobrien	      REG_N_REFS (regno) = 0;
249618334Speter	  }
249718334Speter      }
249818334Speter
249918334Speter    if (i1 && GET_CODE (i1dest) == REG)
250018334Speter      {
250118334Speter	rtx link;
250218334Speter	rtx i1_insn = 0, i1_val = 0, set;
250318334Speter
250418334Speter	for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
250518334Speter	  if ((set = single_set (XEXP (link, 0))) != 0
250618334Speter	      && rtx_equal_p (i1dest, SET_DEST (set)))
250718334Speter	    i1_insn = XEXP (link, 0), i1_val = SET_SRC (set);
250818334Speter
250918334Speter	record_value_for_reg (i1dest, i1_insn, i1_val);
251018334Speter
251118334Speter	regno = REGNO (i1dest);
251218334Speter	if (! added_sets_1 && ! i1dest_in_i1src)
251318334Speter	  {
251450397Sobrien	    REG_N_SETS (regno)--;
251550397Sobrien	    if (REG_N_SETS (regno) == 0
251652284Sobrien		&& ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start,
251752284Sobrien				      regno))
251850397Sobrien	      REG_N_REFS (regno) = 0;
251918334Speter	  }
252018334Speter      }
252118334Speter
252218334Speter    /* Update reg_nonzero_bits et al for any changes that may have been made
252318334Speter       to this insn.  */
252418334Speter
252518334Speter    note_stores (newpat, set_nonzero_bits_and_sign_copies);
252618334Speter    if (newi2pat)
252718334Speter      note_stores (newi2pat, set_nonzero_bits_and_sign_copies);
252818334Speter
252918334Speter    /* If I3 is now an unconditional jump, ensure that it has a
253018334Speter       BARRIER following it since it may have initially been a
253118334Speter       conditional jump.  It may also be the last nonnote insn.  */
253218334Speter
253318334Speter    if ((GET_CODE (newpat) == RETURN || simplejump_p (i3))
253418334Speter	&& ((temp = next_nonnote_insn (i3)) == NULL_RTX
253518334Speter	    || GET_CODE (temp) != BARRIER))
253618334Speter      emit_barrier_after (i3);
253718334Speter  }
253818334Speter
253918334Speter  combine_successes++;
254018334Speter
254118334Speter  /* Clear this here, so that subsequent get_last_value calls are not
254218334Speter     affected.  */
254318334Speter  subst_prev_insn = NULL_RTX;
254418334Speter
254518334Speter  if (added_links_insn
254618334Speter      && (newi2pat == 0 || INSN_CUID (added_links_insn) < INSN_CUID (i2))
254718334Speter      && INSN_CUID (added_links_insn) < INSN_CUID (i3))
254818334Speter    return added_links_insn;
254918334Speter  else
255018334Speter    return newi2pat ? i2 : i3;
255118334Speter}
255218334Speter
255318334Speter/* Undo all the modifications recorded in undobuf.  */
255418334Speter
255518334Speterstatic void
255618334Speterundo_all ()
255718334Speter{
255850397Sobrien  struct undo *undo, *next;
255950397Sobrien
256050397Sobrien  for (undo = undobuf.undos; undo; undo = next)
256118334Speter    {
256250397Sobrien      next = undo->next;
256350397Sobrien      if (undo->is_int)
256450397Sobrien	*undo->where.i = undo->old_contents.i;
256518334Speter      else
256650397Sobrien	*undo->where.r = undo->old_contents.r;
256750397Sobrien
256850397Sobrien      undo->next = undobuf.frees;
256950397Sobrien      undobuf.frees = undo;
257018334Speter    }
257118334Speter
257218334Speter  obfree (undobuf.storage);
257350397Sobrien  undobuf.undos = undobuf.previous_undos = 0;
257418334Speter
257518334Speter  /* Clear this here, so that subsequent get_last_value calls are not
257618334Speter     affected.  */
257718334Speter  subst_prev_insn = NULL_RTX;
257818334Speter}
257918334Speter
258018334Speter/* Find the innermost point within the rtx at LOC, possibly LOC itself,
258118334Speter   where we have an arithmetic expression and return that point.  LOC will
258218334Speter   be inside INSN.
258318334Speter
258418334Speter   try_combine will call this function to see if an insn can be split into
258518334Speter   two insns.  */
258618334Speter
258718334Speterstatic rtx *
258818334Speterfind_split_point (loc, insn)
258918334Speter     rtx *loc;
259018334Speter     rtx insn;
259118334Speter{
259218334Speter  rtx x = *loc;
259318334Speter  enum rtx_code code = GET_CODE (x);
259418334Speter  rtx *split;
259518334Speter  int len = 0, pos, unsignedp;
259618334Speter  rtx inner;
259718334Speter
259818334Speter  /* First special-case some codes.  */
259918334Speter  switch (code)
260018334Speter    {
260118334Speter    case SUBREG:
260218334Speter#ifdef INSN_SCHEDULING
260318334Speter      /* If we are making a paradoxical SUBREG invalid, it becomes a split
260418334Speter	 point.  */
260518334Speter      if (GET_CODE (SUBREG_REG (x)) == MEM)
260618334Speter	return loc;
260718334Speter#endif
260818334Speter      return find_split_point (&SUBREG_REG (x), insn);
260918334Speter
261018334Speter    case MEM:
261118334Speter#ifdef HAVE_lo_sum
261218334Speter      /* If we have (mem (const ..)) or (mem (symbol_ref ...)), split it
261318334Speter	 using LO_SUM and HIGH.  */
261418334Speter      if (GET_CODE (XEXP (x, 0)) == CONST
261518334Speter	  || GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
261618334Speter	{
261718334Speter	  SUBST (XEXP (x, 0),
261818334Speter		 gen_rtx_combine (LO_SUM, Pmode,
261918334Speter				  gen_rtx_combine (HIGH, Pmode, XEXP (x, 0)),
262018334Speter				  XEXP (x, 0)));
262118334Speter	  return &XEXP (XEXP (x, 0), 0);
262218334Speter	}
262318334Speter#endif
262418334Speter
262518334Speter      /* If we have a PLUS whose second operand is a constant and the
262618334Speter	 address is not valid, perhaps will can split it up using
262718334Speter	 the machine-specific way to split large constants.  We use
262818334Speter	 the first pseudo-reg (one of the virtual regs) as a placeholder;
262918334Speter	 it will not remain in the result.  */
263018334Speter      if (GET_CODE (XEXP (x, 0)) == PLUS
263118334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
263218334Speter	  && ! memory_address_p (GET_MODE (x), XEXP (x, 0)))
263318334Speter	{
263418334Speter	  rtx reg = regno_reg_rtx[FIRST_PSEUDO_REGISTER];
263550397Sobrien	  rtx seq = split_insns (gen_rtx_SET (VOIDmode, reg, XEXP (x, 0)),
263618334Speter				 subst_insn);
263718334Speter
263818334Speter	  /* This should have produced two insns, each of which sets our
263918334Speter	     placeholder.  If the source of the second is a valid address,
264018334Speter	     we can make put both sources together and make a split point
264118334Speter	     in the middle.  */
264218334Speter
264318334Speter	  if (seq && XVECLEN (seq, 0) == 2
264418334Speter	      && GET_CODE (XVECEXP (seq, 0, 0)) == INSN
264518334Speter	      && GET_CODE (PATTERN (XVECEXP (seq, 0, 0))) == SET
264618334Speter	      && SET_DEST (PATTERN (XVECEXP (seq, 0, 0))) == reg
264718334Speter	      && ! reg_mentioned_p (reg,
264818334Speter				    SET_SRC (PATTERN (XVECEXP (seq, 0, 0))))
264918334Speter	      && GET_CODE (XVECEXP (seq, 0, 1)) == INSN
265018334Speter	      && GET_CODE (PATTERN (XVECEXP (seq, 0, 1))) == SET
265118334Speter	      && SET_DEST (PATTERN (XVECEXP (seq, 0, 1))) == reg
265218334Speter	      && memory_address_p (GET_MODE (x),
265318334Speter				   SET_SRC (PATTERN (XVECEXP (seq, 0, 1)))))
265418334Speter	    {
265518334Speter	      rtx src1 = SET_SRC (PATTERN (XVECEXP (seq, 0, 0)));
265618334Speter	      rtx src2 = SET_SRC (PATTERN (XVECEXP (seq, 0, 1)));
265718334Speter
265818334Speter	      /* Replace the placeholder in SRC2 with SRC1.  If we can
265918334Speter		 find where in SRC2 it was placed, that can become our
266018334Speter		 split point and we can replace this address with SRC2.
266118334Speter		 Just try two obvious places.  */
266218334Speter
266318334Speter	      src2 = replace_rtx (src2, reg, src1);
266418334Speter	      split = 0;
266518334Speter	      if (XEXP (src2, 0) == src1)
266618334Speter		split = &XEXP (src2, 0);
266718334Speter	      else if (GET_RTX_FORMAT (GET_CODE (XEXP (src2, 0)))[0] == 'e'
266818334Speter		       && XEXP (XEXP (src2, 0), 0) == src1)
266918334Speter		split = &XEXP (XEXP (src2, 0), 0);
267018334Speter
267118334Speter	      if (split)
267218334Speter		{
267318334Speter		  SUBST (XEXP (x, 0), src2);
267418334Speter		  return split;
267518334Speter		}
267618334Speter	    }
267718334Speter
267818334Speter	  /* If that didn't work, perhaps the first operand is complex and
267918334Speter	     needs to be computed separately, so make a split point there.
268018334Speter	     This will occur on machines that just support REG + CONST
268118334Speter	     and have a constant moved through some previous computation.  */
268218334Speter
268318334Speter	  else if (GET_RTX_CLASS (GET_CODE (XEXP (XEXP (x, 0), 0))) != 'o'
268418334Speter		   && ! (GET_CODE (XEXP (XEXP (x, 0), 0)) == SUBREG
268518334Speter			 && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (XEXP (x, 0), 0))))
268618334Speter			     == 'o')))
268718334Speter	    return &XEXP (XEXP (x, 0), 0);
268818334Speter	}
268918334Speter      break;
269018334Speter
269118334Speter    case SET:
269218334Speter#ifdef HAVE_cc0
269318334Speter      /* If SET_DEST is CC0 and SET_SRC is not an operand, a COMPARE, or a
269418334Speter	 ZERO_EXTRACT, the most likely reason why this doesn't match is that
269518334Speter	 we need to put the operand into a register.  So split at that
269618334Speter	 point.  */
269718334Speter
269818334Speter      if (SET_DEST (x) == cc0_rtx
269918334Speter	  && GET_CODE (SET_SRC (x)) != COMPARE
270018334Speter	  && GET_CODE (SET_SRC (x)) != ZERO_EXTRACT
270118334Speter	  && GET_RTX_CLASS (GET_CODE (SET_SRC (x))) != 'o'
270218334Speter	  && ! (GET_CODE (SET_SRC (x)) == SUBREG
270318334Speter		&& GET_RTX_CLASS (GET_CODE (SUBREG_REG (SET_SRC (x)))) == 'o'))
270418334Speter	return &SET_SRC (x);
270518334Speter#endif
270618334Speter
270718334Speter      /* See if we can split SET_SRC as it stands.  */
270818334Speter      split = find_split_point (&SET_SRC (x), insn);
270918334Speter      if (split && split != &SET_SRC (x))
271018334Speter	return split;
271118334Speter
271250397Sobrien      /* See if we can split SET_DEST as it stands.  */
271350397Sobrien      split = find_split_point (&SET_DEST (x), insn);
271450397Sobrien      if (split && split != &SET_DEST (x))
271550397Sobrien	return split;
271650397Sobrien
271718334Speter      /* See if this is a bitfield assignment with everything constant.  If
271818334Speter	 so, this is an IOR of an AND, so split it into that.  */
271918334Speter      if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
272018334Speter	  && (GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0)))
272118334Speter	      <= HOST_BITS_PER_WIDE_INT)
272218334Speter	  && GET_CODE (XEXP (SET_DEST (x), 1)) == CONST_INT
272318334Speter	  && GET_CODE (XEXP (SET_DEST (x), 2)) == CONST_INT
272418334Speter	  && GET_CODE (SET_SRC (x)) == CONST_INT
272518334Speter	  && ((INTVAL (XEXP (SET_DEST (x), 1))
272618334Speter	      + INTVAL (XEXP (SET_DEST (x), 2)))
272718334Speter	      <= GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0))))
272818334Speter	  && ! side_effects_p (XEXP (SET_DEST (x), 0)))
272918334Speter	{
273018334Speter	  int pos = INTVAL (XEXP (SET_DEST (x), 2));
273118334Speter	  int len = INTVAL (XEXP (SET_DEST (x), 1));
273218334Speter	  int src = INTVAL (SET_SRC (x));
273318334Speter	  rtx dest = XEXP (SET_DEST (x), 0);
273418334Speter	  enum machine_mode mode = GET_MODE (dest);
273518334Speter	  unsigned HOST_WIDE_INT mask = ((HOST_WIDE_INT) 1 << len) - 1;
273618334Speter
273718334Speter	  if (BITS_BIG_ENDIAN)
273818334Speter	    pos = GET_MODE_BITSIZE (mode) - len - pos;
273918334Speter
274052284Sobrien	  if ((unsigned HOST_WIDE_INT) src == mask)
274118334Speter	    SUBST (SET_SRC (x),
274218334Speter		   gen_binary (IOR, mode, dest, GEN_INT (src << pos)));
274318334Speter	  else
274418334Speter	    SUBST (SET_SRC (x),
274518334Speter		   gen_binary (IOR, mode,
274618334Speter			       gen_binary (AND, mode, dest,
274718334Speter					   GEN_INT (~ (mask << pos)
274818334Speter						    & GET_MODE_MASK (mode))),
274918334Speter			       GEN_INT (src << pos)));
275018334Speter
275118334Speter	  SUBST (SET_DEST (x), dest);
275218334Speter
275318334Speter	  split = find_split_point (&SET_SRC (x), insn);
275418334Speter	  if (split && split != &SET_SRC (x))
275518334Speter	    return split;
275618334Speter	}
275718334Speter
275818334Speter      /* Otherwise, see if this is an operation that we can split into two.
275918334Speter	 If so, try to split that.  */
276018334Speter      code = GET_CODE (SET_SRC (x));
276118334Speter
276218334Speter      switch (code)
276318334Speter	{
276418334Speter	case AND:
276518334Speter	  /* If we are AND'ing with a large constant that is only a single
276618334Speter	     bit and the result is only being used in a context where we
276718334Speter	     need to know if it is zero or non-zero, replace it with a bit
276818334Speter	     extraction.  This will avoid the large constant, which might
276918334Speter	     have taken more than one insn to make.  If the constant were
277018334Speter	     not a valid argument to the AND but took only one insn to make,
277118334Speter	     this is no worse, but if it took more than one insn, it will
277218334Speter	     be better.  */
277318334Speter
277418334Speter	  if (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
277518334Speter	      && GET_CODE (XEXP (SET_SRC (x), 0)) == REG
277618334Speter	      && (pos = exact_log2 (INTVAL (XEXP (SET_SRC (x), 1)))) >= 7
277718334Speter	      && GET_CODE (SET_DEST (x)) == REG
277818334Speter	      && (split = find_single_use (SET_DEST (x), insn, NULL_PTR)) != 0
277918334Speter	      && (GET_CODE (*split) == EQ || GET_CODE (*split) == NE)
278018334Speter	      && XEXP (*split, 0) == SET_DEST (x)
278118334Speter	      && XEXP (*split, 1) == const0_rtx)
278218334Speter	    {
278350397Sobrien	      rtx extraction = make_extraction (GET_MODE (SET_DEST (x)),
278450397Sobrien						XEXP (SET_SRC (x), 0),
278550397Sobrien						pos, NULL_RTX, 1, 1, 0, 0);
278650397Sobrien	      if (extraction != 0)
278750397Sobrien		{
278850397Sobrien		  SUBST (SET_SRC (x), extraction);
278950397Sobrien		  return find_split_point (loc, insn);
279050397Sobrien		}
279150397Sobrien	    }
279250397Sobrien	  break;
279350397Sobrien
279450397Sobrien	case NE:
279550397Sobrien	  /* if STORE_FLAG_VALUE is -1, this is (NE X 0) and only one bit of X
279650397Sobrien	     is known to be on, this can be converted into a NEG of a shift. */
279750397Sobrien	  if (STORE_FLAG_VALUE == -1 && XEXP (SET_SRC (x), 1) == const0_rtx
279850397Sobrien	      && GET_MODE (SET_SRC (x)) == GET_MODE (XEXP (SET_SRC (x), 0))
279950397Sobrien	      && 1 <= (pos = exact_log2
280050397Sobrien		       (nonzero_bits (XEXP (SET_SRC (x), 0),
280150397Sobrien				      GET_MODE (XEXP (SET_SRC (x), 0))))))
280250397Sobrien	    {
280350397Sobrien	      enum machine_mode mode = GET_MODE (XEXP (SET_SRC (x), 0));
280450397Sobrien
280518334Speter	      SUBST (SET_SRC (x),
280650397Sobrien		     gen_rtx_combine (NEG, mode,
280750397Sobrien				      gen_rtx_combine (LSHIFTRT, mode,
280850397Sobrien						       XEXP (SET_SRC (x), 0),
280950397Sobrien						       GEN_INT (pos))));
281050397Sobrien
281150397Sobrien	      split = find_split_point (&SET_SRC (x), insn);
281250397Sobrien	      if (split && split != &SET_SRC (x))
281350397Sobrien		return split;
281418334Speter	    }
281518334Speter	  break;
281618334Speter
281718334Speter	case SIGN_EXTEND:
281818334Speter	  inner = XEXP (SET_SRC (x), 0);
281950397Sobrien
282050397Sobrien	  /* We can't optimize if either mode is a partial integer
282150397Sobrien	     mode as we don't know how many bits are significant
282250397Sobrien	     in those modes.  */
282350397Sobrien	  if (GET_MODE_CLASS (GET_MODE (inner)) == MODE_PARTIAL_INT
282450397Sobrien	      || GET_MODE_CLASS (GET_MODE (SET_SRC (x))) == MODE_PARTIAL_INT)
282550397Sobrien	    break;
282650397Sobrien
282718334Speter	  pos = 0;
282818334Speter	  len = GET_MODE_BITSIZE (GET_MODE (inner));
282918334Speter	  unsignedp = 0;
283018334Speter	  break;
283118334Speter
283218334Speter	case SIGN_EXTRACT:
283318334Speter	case ZERO_EXTRACT:
283418334Speter	  if (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
283518334Speter	      && GET_CODE (XEXP (SET_SRC (x), 2)) == CONST_INT)
283618334Speter	    {
283718334Speter	      inner = XEXP (SET_SRC (x), 0);
283818334Speter	      len = INTVAL (XEXP (SET_SRC (x), 1));
283918334Speter	      pos = INTVAL (XEXP (SET_SRC (x), 2));
284018334Speter
284118334Speter	      if (BITS_BIG_ENDIAN)
284218334Speter		pos = GET_MODE_BITSIZE (GET_MODE (inner)) - len - pos;
284318334Speter	      unsignedp = (code == ZERO_EXTRACT);
284418334Speter	    }
284518334Speter	  break;
284650397Sobrien
284750397Sobrien	default:
284850397Sobrien	  break;
284918334Speter	}
285018334Speter
285118334Speter      if (len && pos >= 0 && pos + len <= GET_MODE_BITSIZE (GET_MODE (inner)))
285218334Speter	{
285318334Speter	  enum machine_mode mode = GET_MODE (SET_SRC (x));
285418334Speter
285518334Speter	  /* For unsigned, we have a choice of a shift followed by an
285618334Speter	     AND or two shifts.  Use two shifts for field sizes where the
285718334Speter	     constant might be too large.  We assume here that we can
285818334Speter	     always at least get 8-bit constants in an AND insn, which is
285918334Speter	     true for every current RISC.  */
286018334Speter
286118334Speter	  if (unsignedp && len <= 8)
286218334Speter	    {
286318334Speter	      SUBST (SET_SRC (x),
286418334Speter		     gen_rtx_combine
286518334Speter		     (AND, mode,
286618334Speter		      gen_rtx_combine (LSHIFTRT, mode,
286718334Speter				       gen_lowpart_for_combine (mode, inner),
286818334Speter				       GEN_INT (pos)),
286918334Speter		      GEN_INT (((HOST_WIDE_INT) 1 << len) - 1)));
287018334Speter
287118334Speter	      split = find_split_point (&SET_SRC (x), insn);
287218334Speter	      if (split && split != &SET_SRC (x))
287318334Speter		return split;
287418334Speter	    }
287518334Speter	  else
287618334Speter	    {
287718334Speter	      SUBST (SET_SRC (x),
287818334Speter		     gen_rtx_combine
287918334Speter		     (unsignedp ? LSHIFTRT : ASHIFTRT, mode,
288018334Speter		      gen_rtx_combine (ASHIFT, mode,
288118334Speter				       gen_lowpart_for_combine (mode, inner),
288218334Speter				       GEN_INT (GET_MODE_BITSIZE (mode)
288318334Speter						- len - pos)),
288418334Speter		      GEN_INT (GET_MODE_BITSIZE (mode) - len)));
288518334Speter
288618334Speter	      split = find_split_point (&SET_SRC (x), insn);
288718334Speter	      if (split && split != &SET_SRC (x))
288818334Speter		return split;
288918334Speter	    }
289018334Speter	}
289118334Speter
289218334Speter      /* See if this is a simple operation with a constant as the second
289318334Speter	 operand.  It might be that this constant is out of range and hence
289418334Speter	 could be used as a split point.  */
289518334Speter      if ((GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '2'
289618334Speter	   || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == 'c'
289718334Speter	   || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '<')
289818334Speter	  && CONSTANT_P (XEXP (SET_SRC (x), 1))
289918334Speter	  && (GET_RTX_CLASS (GET_CODE (XEXP (SET_SRC (x), 0))) == 'o'
290018334Speter	      || (GET_CODE (XEXP (SET_SRC (x), 0)) == SUBREG
290118334Speter		  && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (SET_SRC (x), 0))))
290218334Speter		      == 'o'))))
290318334Speter	return &XEXP (SET_SRC (x), 1);
290418334Speter
290518334Speter      /* Finally, see if this is a simple operation with its first operand
290618334Speter	 not in a register.  The operation might require this operand in a
290718334Speter	 register, so return it as a split point.  We can always do this
290818334Speter	 because if the first operand were another operation, we would have
290918334Speter	 already found it as a split point.  */
291018334Speter      if ((GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '2'
291118334Speter	   || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == 'c'
291218334Speter	   || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '<'
291318334Speter	   || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '1')
291418334Speter	  && ! register_operand (XEXP (SET_SRC (x), 0), VOIDmode))
291518334Speter	return &XEXP (SET_SRC (x), 0);
291618334Speter
291718334Speter      return 0;
291818334Speter
291918334Speter    case AND:
292018334Speter    case IOR:
292118334Speter      /* We write NOR as (and (not A) (not B)), but if we don't have a NOR,
292218334Speter	 it is better to write this as (not (ior A B)) so we can split it.
292318334Speter	 Similarly for IOR.  */
292418334Speter      if (GET_CODE (XEXP (x, 0)) == NOT && GET_CODE (XEXP (x, 1)) == NOT)
292518334Speter	{
292618334Speter	  SUBST (*loc,
292718334Speter		 gen_rtx_combine (NOT, GET_MODE (x),
292818334Speter				  gen_rtx_combine (code == IOR ? AND : IOR,
292918334Speter						   GET_MODE (x),
293018334Speter						   XEXP (XEXP (x, 0), 0),
293118334Speter						   XEXP (XEXP (x, 1), 0))));
293218334Speter	  return find_split_point (loc, insn);
293318334Speter	}
293418334Speter
293518334Speter      /* Many RISC machines have a large set of logical insns.  If the
293618334Speter	 second operand is a NOT, put it first so we will try to split the
293718334Speter	 other operand first.  */
293818334Speter      if (GET_CODE (XEXP (x, 1)) == NOT)
293918334Speter	{
294018334Speter	  rtx tem = XEXP (x, 0);
294118334Speter	  SUBST (XEXP (x, 0), XEXP (x, 1));
294218334Speter	  SUBST (XEXP (x, 1), tem);
294318334Speter	}
294418334Speter      break;
294550397Sobrien
294650397Sobrien    default:
294750397Sobrien      break;
294818334Speter    }
294918334Speter
295018334Speter  /* Otherwise, select our actions depending on our rtx class.  */
295118334Speter  switch (GET_RTX_CLASS (code))
295218334Speter    {
295318334Speter    case 'b':			/* This is ZERO_EXTRACT and SIGN_EXTRACT.  */
295418334Speter    case '3':
295518334Speter      split = find_split_point (&XEXP (x, 2), insn);
295618334Speter      if (split)
295718334Speter	return split;
295850397Sobrien      /* ... fall through ...  */
295918334Speter    case '2':
296018334Speter    case 'c':
296118334Speter    case '<':
296218334Speter      split = find_split_point (&XEXP (x, 1), insn);
296318334Speter      if (split)
296418334Speter	return split;
296550397Sobrien      /* ... fall through ...  */
296618334Speter    case '1':
296718334Speter      /* Some machines have (and (shift ...) ...) insns.  If X is not
296818334Speter	 an AND, but XEXP (X, 0) is, use it as our split point.  */
296918334Speter      if (GET_CODE (x) != AND && GET_CODE (XEXP (x, 0)) == AND)
297018334Speter	return &XEXP (x, 0);
297118334Speter
297218334Speter      split = find_split_point (&XEXP (x, 0), insn);
297318334Speter      if (split)
297418334Speter	return split;
297518334Speter      return loc;
297618334Speter    }
297718334Speter
297818334Speter  /* Otherwise, we don't have a split point.  */
297918334Speter  return 0;
298018334Speter}
298118334Speter
298218334Speter/* Throughout X, replace FROM with TO, and return the result.
298318334Speter   The result is TO if X is FROM;
298418334Speter   otherwise the result is X, but its contents may have been modified.
298518334Speter   If they were modified, a record was made in undobuf so that
298618334Speter   undo_all will (among other things) return X to its original state.
298718334Speter
298818334Speter   If the number of changes necessary is too much to record to undo,
298918334Speter   the excess changes are not made, so the result is invalid.
299018334Speter   The changes already made can still be undone.
299118334Speter   undobuf.num_undo is incremented for such changes, so by testing that
299218334Speter   the caller can tell whether the result is valid.
299318334Speter
299418334Speter   `n_occurrences' is incremented each time FROM is replaced.
299518334Speter
299618334Speter   IN_DEST is non-zero if we are processing the SET_DEST of a SET.
299718334Speter
299818334Speter   UNIQUE_COPY is non-zero if each substitution must be unique.  We do this
299918334Speter   by copying if `n_occurrences' is non-zero.  */
300018334Speter
300118334Speterstatic rtx
300218334Spetersubst (x, from, to, in_dest, unique_copy)
300318334Speter     register rtx x, from, to;
300418334Speter     int in_dest;
300518334Speter     int unique_copy;
300618334Speter{
300718334Speter  register enum rtx_code code = GET_CODE (x);
300818334Speter  enum machine_mode op0_mode = VOIDmode;
300918334Speter  register char *fmt;
301018334Speter  register int len, i;
301118334Speter  rtx new;
301218334Speter
301318334Speter/* Two expressions are equal if they are identical copies of a shared
301418334Speter   RTX or if they are both registers with the same register number
301518334Speter   and mode.  */
301618334Speter
301718334Speter#define COMBINE_RTX_EQUAL_P(X,Y)			\
301818334Speter  ((X) == (Y)						\
301918334Speter   || (GET_CODE (X) == REG && GET_CODE (Y) == REG	\
302018334Speter       && REGNO (X) == REGNO (Y) && GET_MODE (X) == GET_MODE (Y)))
302118334Speter
302218334Speter  if (! in_dest && COMBINE_RTX_EQUAL_P (x, from))
302318334Speter    {
302418334Speter      n_occurrences++;
302518334Speter      return (unique_copy && n_occurrences > 1 ? copy_rtx (to) : to);
302618334Speter    }
302718334Speter
302818334Speter  /* If X and FROM are the same register but different modes, they will
302918334Speter     not have been seen as equal above.  However, flow.c will make a
303018334Speter     LOG_LINKS entry for that case.  If we do nothing, we will try to
303118334Speter     rerecognize our original insn and, when it succeeds, we will
303218334Speter     delete the feeding insn, which is incorrect.
303318334Speter
303418334Speter     So force this insn not to match in this (rare) case.  */
303518334Speter  if (! in_dest && code == REG && GET_CODE (from) == REG
303618334Speter      && REGNO (x) == REGNO (from))
303750397Sobrien    return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
303818334Speter
303918334Speter  /* If this is an object, we are done unless it is a MEM or LO_SUM, both
304018334Speter     of which may contain things that can be combined.  */
304118334Speter  if (code != MEM && code != LO_SUM && GET_RTX_CLASS (code) == 'o')
304218334Speter    return x;
304318334Speter
304418334Speter  /* It is possible to have a subexpression appear twice in the insn.
304518334Speter     Suppose that FROM is a register that appears within TO.
304618334Speter     Then, after that subexpression has been scanned once by `subst',
304718334Speter     the second time it is scanned, TO may be found.  If we were
304818334Speter     to scan TO here, we would find FROM within it and create a
304918334Speter     self-referent rtl structure which is completely wrong.  */
305018334Speter  if (COMBINE_RTX_EQUAL_P (x, to))
305118334Speter    return to;
305218334Speter
305350397Sobrien  /* Parallel asm_operands need special attention because all of the
305450397Sobrien     inputs are shared across the arms.  Furthermore, unsharing the
305550397Sobrien     rtl results in recognition failures.  Failure to handle this case
305650397Sobrien     specially can result in circular rtl.
305718334Speter
305850397Sobrien     Solve this by doing a normal pass across the first entry of the
305950397Sobrien     parallel, and only processing the SET_DESTs of the subsequent
306050397Sobrien     entries.  Ug.  */
306118334Speter
306250397Sobrien  if (code == PARALLEL
306350397Sobrien      && GET_CODE (XVECEXP (x, 0, 0)) == SET
306450397Sobrien      && GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS)
306550397Sobrien    {
306650397Sobrien      new = subst (XVECEXP (x, 0, 0), from, to, 0, unique_copy);
306718334Speter
306850397Sobrien      /* If this substitution failed, this whole thing fails.  */
306950397Sobrien      if (GET_CODE (new) == CLOBBER
307050397Sobrien	  && XEXP (new, 0) == const0_rtx)
307150397Sobrien	return new;
307250397Sobrien
307350397Sobrien      SUBST (XVECEXP (x, 0, 0), new);
307450397Sobrien
307550397Sobrien      for (i = XVECLEN (x, 0) - 1; i >= 1; i--)
307618334Speter	{
307750397Sobrien	  rtx dest = SET_DEST (XVECEXP (x, 0, i));
307850397Sobrien
307950397Sobrien	  if (GET_CODE (dest) != REG
308050397Sobrien	      && GET_CODE (dest) != CC0
308150397Sobrien	      && GET_CODE (dest) != PC)
308218334Speter	    {
308350397Sobrien	      new = subst (dest, from, to, 0, unique_copy);
308418334Speter
308550397Sobrien	      /* If this substitution failed, this whole thing fails.  */
308650397Sobrien	      if (GET_CODE (new) == CLOBBER
308750397Sobrien		  && XEXP (new, 0) == const0_rtx)
308850397Sobrien		return new;
308918334Speter
309050397Sobrien	      SUBST (SET_DEST (XVECEXP (x, 0, i)), new);
309118334Speter	    }
309218334Speter	}
309350397Sobrien    }
309450397Sobrien  else
309550397Sobrien    {
309650397Sobrien      len = GET_RTX_LENGTH (code);
309750397Sobrien      fmt = GET_RTX_FORMAT (code);
309850397Sobrien
309950397Sobrien      /* We don't need to process a SET_DEST that is a register, CC0,
310050397Sobrien	 or PC, so set up to skip this common case.  All other cases
310150397Sobrien	 where we want to suppress replacing something inside a
310250397Sobrien	 SET_SRC are handled via the IN_DEST operand.  */
310350397Sobrien      if (code == SET
310450397Sobrien	  && (GET_CODE (SET_DEST (x)) == REG
310550397Sobrien	      || GET_CODE (SET_DEST (x)) == CC0
310650397Sobrien	      || GET_CODE (SET_DEST (x)) == PC))
310750397Sobrien	fmt = "ie";
310850397Sobrien
310950397Sobrien      /* Get the mode of operand 0 in case X is now a SIGN_EXTEND of a
311050397Sobrien	 constant.  */
311150397Sobrien      if (fmt[0] == 'e')
311250397Sobrien	op0_mode = GET_MODE (XEXP (x, 0));
311350397Sobrien
311450397Sobrien      for (i = 0; i < len; i++)
311518334Speter	{
311650397Sobrien	  if (fmt[i] == 'E')
311718334Speter	    {
311850397Sobrien	      register int j;
311950397Sobrien	      for (j = XVECLEN (x, i) - 1; j >= 0; j--)
312050397Sobrien		{
312150397Sobrien		  if (COMBINE_RTX_EQUAL_P (XVECEXP (x, i, j), from))
312250397Sobrien		    {
312350397Sobrien		      new = (unique_copy && n_occurrences
312450397Sobrien			     ? copy_rtx (to) : to);
312550397Sobrien		      n_occurrences++;
312650397Sobrien		    }
312750397Sobrien		  else
312850397Sobrien		    {
312950397Sobrien		      new = subst (XVECEXP (x, i, j), from, to, 0,
313050397Sobrien				   unique_copy);
313118334Speter
313250397Sobrien		      /* If this substitution failed, this whole thing
313350397Sobrien			 fails.  */
313450397Sobrien		      if (GET_CODE (new) == CLOBBER
313550397Sobrien			  && XEXP (new, 0) == const0_rtx)
313650397Sobrien			return new;
313750397Sobrien		    }
313850397Sobrien
313950397Sobrien		  SUBST (XVECEXP (x, i, j), new);
314050397Sobrien		}
314150397Sobrien	    }
314250397Sobrien	  else if (fmt[i] == 'e')
314350397Sobrien	    {
314450397Sobrien	      if (COMBINE_RTX_EQUAL_P (XEXP (x, i), from))
314550397Sobrien		{
314650397Sobrien		  /* In general, don't install a subreg involving two
314750397Sobrien		     modes not tieable.  It can worsen register
314850397Sobrien		     allocation, and can even make invalid reload
314950397Sobrien		     insns, since the reg inside may need to be copied
315050397Sobrien		     from in the outside mode, and that may be invalid
315150397Sobrien		     if it is an fp reg copied in integer mode.
315250397Sobrien
315350397Sobrien		     We allow two exceptions to this: It is valid if
315450397Sobrien		     it is inside another SUBREG and the mode of that
315550397Sobrien		     SUBREG and the mode of the inside of TO is
315650397Sobrien		     tieable and it is valid if X is a SET that copies
315750397Sobrien		     FROM to CC0.  */
315850397Sobrien
315950397Sobrien		  if (GET_CODE (to) == SUBREG
316050397Sobrien		      && ! MODES_TIEABLE_P (GET_MODE (to),
316150397Sobrien					    GET_MODE (SUBREG_REG (to)))
316250397Sobrien		      && ! (code == SUBREG
316350397Sobrien			    && MODES_TIEABLE_P (GET_MODE (x),
316450397Sobrien						GET_MODE (SUBREG_REG (to))))
316518334Speter#ifdef HAVE_cc0
316650397Sobrien		      && ! (code == SET && i == 1 && XEXP (x, 0) == cc0_rtx)
316718334Speter#endif
316850397Sobrien		      )
316950397Sobrien		    return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
317018334Speter
317150397Sobrien		  new = (unique_copy && n_occurrences ? copy_rtx (to) : to);
317250397Sobrien		  n_occurrences++;
317350397Sobrien		}
317450397Sobrien	      else
317550397Sobrien		/* If we are in a SET_DEST, suppress most cases unless we
317650397Sobrien		   have gone inside a MEM, in which case we want to
317750397Sobrien		   simplify the address.  We assume here that things that
317850397Sobrien		   are actually part of the destination have their inner
317950397Sobrien		   parts in the first expression.  This is true for SUBREG,
318050397Sobrien		   STRICT_LOW_PART, and ZERO_EXTRACT, which are the only
318150397Sobrien		   things aside from REG and MEM that should appear in a
318250397Sobrien		   SET_DEST.  */
318350397Sobrien		new = subst (XEXP (x, i), from, to,
318450397Sobrien			     (((in_dest
318550397Sobrien				&& (code == SUBREG || code == STRICT_LOW_PART
318650397Sobrien				    || code == ZERO_EXTRACT))
318750397Sobrien			       || code == SET)
318850397Sobrien			      && i == 0), unique_copy);
318918334Speter
319050397Sobrien	      /* If we found that we will have to reject this combination,
319150397Sobrien		 indicate that by returning the CLOBBER ourselves, rather than
319250397Sobrien		 an expression containing it.  This will speed things up as
319350397Sobrien		 well as prevent accidents where two CLOBBERs are considered
319450397Sobrien		 to be equal, thus producing an incorrect simplification.  */
319518334Speter
319650397Sobrien	      if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx)
319750397Sobrien		return new;
319818334Speter
319950397Sobrien	      SUBST (XEXP (x, i), new);
320050397Sobrien	    }
320118334Speter	}
320218334Speter    }
320318334Speter
320418334Speter  /* Try to simplify X.  If the simplification changed the code, it is likely
320518334Speter     that further simplification will help, so loop, but limit the number
320618334Speter     of repetitions that will be performed.  */
320718334Speter
320818334Speter  for (i = 0; i < 4; i++)
320918334Speter    {
321018334Speter      /* If X is sufficiently simple, don't bother trying to do anything
321118334Speter	 with it.  */
321218334Speter      if (code != CONST_INT && code != REG && code != CLOBBER)
321318334Speter	x = simplify_rtx (x, op0_mode, i == 3, in_dest);
321418334Speter
321518334Speter      if (GET_CODE (x) == code)
321618334Speter	break;
321718334Speter
321818334Speter      code = GET_CODE (x);
321918334Speter
322018334Speter      /* We no longer know the original mode of operand 0 since we
322118334Speter	 have changed the form of X)  */
322218334Speter      op0_mode = VOIDmode;
322318334Speter    }
322418334Speter
322518334Speter  return x;
322618334Speter}
322718334Speter
322818334Speter/* Simplify X, a piece of RTL.  We just operate on the expression at the
322918334Speter   outer level; call `subst' to simplify recursively.  Return the new
323018334Speter   expression.
323118334Speter
323218334Speter   OP0_MODE is the original mode of XEXP (x, 0); LAST is nonzero if this
323318334Speter   will be the iteration even if an expression with a code different from
323418334Speter   X is returned; IN_DEST is nonzero if we are inside a SET_DEST.  */
323518334Speter
323618334Speterstatic rtx
323718334Spetersimplify_rtx (x, op0_mode, last, in_dest)
323818334Speter     rtx x;
323918334Speter     enum machine_mode op0_mode;
324018334Speter     int last;
324118334Speter     int in_dest;
324218334Speter{
324318334Speter  enum rtx_code code = GET_CODE (x);
324418334Speter  enum machine_mode mode = GET_MODE (x);
324518334Speter  rtx temp;
324618334Speter  int i;
324718334Speter
324818334Speter  /* If this is a commutative operation, put a constant last and a complex
324918334Speter     expression first.  We don't need to do this for comparisons here.  */
325018334Speter  if (GET_RTX_CLASS (code) == 'c'
325118334Speter      && ((CONSTANT_P (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) != CONST_INT)
325218334Speter	  || (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == 'o'
325318334Speter	      && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) != 'o')
325418334Speter	  || (GET_CODE (XEXP (x, 0)) == SUBREG
325518334Speter	      && GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0)))) == 'o'
325618334Speter	      && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) != 'o')))
325718334Speter    {
325818334Speter      temp = XEXP (x, 0);
325918334Speter      SUBST (XEXP (x, 0), XEXP (x, 1));
326018334Speter      SUBST (XEXP (x, 1), temp);
326118334Speter    }
326218334Speter
326318334Speter  /* If this is a PLUS, MINUS, or MULT, and the first operand is the
326418334Speter     sign extension of a PLUS with a constant, reverse the order of the sign
326518334Speter     extension and the addition. Note that this not the same as the original
326618334Speter     code, but overflow is undefined for signed values.  Also note that the
326718334Speter     PLUS will have been partially moved "inside" the sign-extension, so that
326818334Speter     the first operand of X will really look like:
326918334Speter         (ashiftrt (plus (ashift A C4) C5) C4).
327018334Speter     We convert this to
327118334Speter         (plus (ashiftrt (ashift A C4) C2) C4)
327218334Speter     and replace the first operand of X with that expression.  Later parts
327318334Speter     of this function may simplify the expression further.
327418334Speter
327518334Speter     For example, if we start with (mult (sign_extend (plus A C1)) C2),
327618334Speter     we swap the SIGN_EXTEND and PLUS.  Later code will apply the
327718334Speter     distributive law to produce (plus (mult (sign_extend X) C1) C3).
327818334Speter
327918334Speter     We do this to simplify address expressions.  */
328018334Speter
328118334Speter  if ((code == PLUS || code == MINUS || code == MULT)
328218334Speter      && GET_CODE (XEXP (x, 0)) == ASHIFTRT
328318334Speter      && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS
328418334Speter      && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ASHIFT
328518334Speter      && GET_CODE (XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 1)) == CONST_INT
328618334Speter      && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
328718334Speter      && XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 1) == XEXP (XEXP (x, 0), 1)
328818334Speter      && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
328918334Speter      && (temp = simplify_binary_operation (ASHIFTRT, mode,
329018334Speter					    XEXP (XEXP (XEXP (x, 0), 0), 1),
329118334Speter					    XEXP (XEXP (x, 0), 1))) != 0)
329218334Speter    {
329318334Speter      rtx new
329418334Speter	= simplify_shift_const (NULL_RTX, ASHIFT, mode,
329518334Speter				XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 0),
329618334Speter				INTVAL (XEXP (XEXP (x, 0), 1)));
329718334Speter
329818334Speter      new = simplify_shift_const (NULL_RTX, ASHIFTRT, mode, new,
329918334Speter				  INTVAL (XEXP (XEXP (x, 0), 1)));
330018334Speter
330118334Speter      SUBST (XEXP (x, 0), gen_binary (PLUS, mode, new, temp));
330218334Speter    }
330318334Speter
330418334Speter  /* If this is a simple operation applied to an IF_THEN_ELSE, try
330518334Speter     applying it to the arms of the IF_THEN_ELSE.  This often simplifies
330618334Speter     things.  Check for cases where both arms are testing the same
330718334Speter     condition.
330818334Speter
330918334Speter     Don't do anything if all operands are very simple.  */
331018334Speter
331118334Speter  if (((GET_RTX_CLASS (code) == '2' || GET_RTX_CLASS (code) == 'c'
331218334Speter	|| GET_RTX_CLASS (code) == '<')
331318334Speter       && ((GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) != 'o'
331418334Speter	    && ! (GET_CODE (XEXP (x, 0)) == SUBREG
331518334Speter		  && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0))))
331618334Speter		      == 'o')))
331718334Speter	   || (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) != 'o'
331818334Speter	       && ! (GET_CODE (XEXP (x, 1)) == SUBREG
331918334Speter		     && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 1))))
332018334Speter			 == 'o')))))
332118334Speter      || (GET_RTX_CLASS (code) == '1'
332218334Speter	  && ((GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) != 'o'
332318334Speter	       && ! (GET_CODE (XEXP (x, 0)) == SUBREG
332418334Speter		     && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0))))
332518334Speter			 == 'o'))))))
332618334Speter    {
332718334Speter      rtx cond, true, false;
332818334Speter
332918334Speter      cond = if_then_else_cond (x, &true, &false);
333050397Sobrien      if (cond != 0
333150397Sobrien	  /* If everything is a comparison, what we have is highly unlikely
333250397Sobrien	     to be simpler, so don't use it.  */
333350397Sobrien	  && ! (GET_RTX_CLASS (code) == '<'
333450397Sobrien		&& (GET_RTX_CLASS (GET_CODE (true)) == '<'
333550397Sobrien		    || GET_RTX_CLASS (GET_CODE (false)) == '<')))
333618334Speter	{
333718334Speter	  rtx cop1 = const0_rtx;
333818334Speter	  enum rtx_code cond_code = simplify_comparison (NE, &cond, &cop1);
333918334Speter
334018334Speter	  if (cond_code == NE && GET_RTX_CLASS (GET_CODE (cond)) == '<')
334118334Speter	    return x;
334218334Speter
334318334Speter	  /* Simplify the alternative arms; this may collapse the true and
334418334Speter	     false arms to store-flag values.  */
334518334Speter	  true = subst (true, pc_rtx, pc_rtx, 0, 0);
334618334Speter	  false = subst (false, pc_rtx, pc_rtx, 0, 0);
334718334Speter
334818334Speter	  /* Restarting if we generate a store-flag expression will cause
334918334Speter	     us to loop.  Just drop through in this case.  */
335018334Speter
335118334Speter	  /* If the result values are STORE_FLAG_VALUE and zero, we can
335218334Speter	     just make the comparison operation.  */
335318334Speter	  if (true == const_true_rtx && false == const0_rtx)
335418334Speter	    x = gen_binary (cond_code, mode, cond, cop1);
335518334Speter	  else if (true == const0_rtx && false == const_true_rtx)
335618334Speter	    x = gen_binary (reverse_condition (cond_code), mode, cond, cop1);
335718334Speter
335818334Speter	  /* Likewise, we can make the negate of a comparison operation
335918334Speter	     if the result values are - STORE_FLAG_VALUE and zero.  */
336018334Speter	  else if (GET_CODE (true) == CONST_INT
336118334Speter		   && INTVAL (true) == - STORE_FLAG_VALUE
336218334Speter		   && false == const0_rtx)
336318334Speter	    x = gen_unary (NEG, mode, mode,
336418334Speter			   gen_binary (cond_code, mode, cond, cop1));
336518334Speter	  else if (GET_CODE (false) == CONST_INT
336618334Speter		   && INTVAL (false) == - STORE_FLAG_VALUE
336718334Speter		   && true == const0_rtx)
336818334Speter	    x = gen_unary (NEG, mode, mode,
336918334Speter			   gen_binary (reverse_condition (cond_code),
337018334Speter				       mode, cond, cop1));
337118334Speter	  else
337250397Sobrien	    return gen_rtx_IF_THEN_ELSE (mode,
337350397Sobrien					 gen_binary (cond_code, VOIDmode,
337450397Sobrien						     cond, cop1),
337550397Sobrien					 true, false);
337618334Speter
337718334Speter	  code = GET_CODE (x);
337818334Speter	  op0_mode = VOIDmode;
337918334Speter	}
338018334Speter    }
338118334Speter
338218334Speter  /* Try to fold this expression in case we have constants that weren't
338318334Speter     present before.  */
338418334Speter  temp = 0;
338518334Speter  switch (GET_RTX_CLASS (code))
338618334Speter    {
338718334Speter    case '1':
338818334Speter      temp = simplify_unary_operation (code, mode, XEXP (x, 0), op0_mode);
338918334Speter      break;
339018334Speter    case '<':
339118334Speter      temp = simplify_relational_operation (code, op0_mode,
339218334Speter					    XEXP (x, 0), XEXP (x, 1));
339318334Speter#ifdef FLOAT_STORE_FLAG_VALUE
339418334Speter      if (temp != 0 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
339518334Speter	temp = ((temp == const0_rtx) ? CONST0_RTX (GET_MODE (x))
339618334Speter		: immed_real_const_1 (FLOAT_STORE_FLAG_VALUE, GET_MODE (x)));
339718334Speter#endif
339818334Speter      break;
339918334Speter    case 'c':
340018334Speter    case '2':
340118334Speter      temp = simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
340218334Speter      break;
340318334Speter    case 'b':
340418334Speter    case '3':
340518334Speter      temp = simplify_ternary_operation (code, mode, op0_mode, XEXP (x, 0),
340618334Speter					 XEXP (x, 1), XEXP (x, 2));
340718334Speter      break;
340818334Speter    }
340918334Speter
341018334Speter  if (temp)
341118334Speter    x = temp, code = GET_CODE (temp);
341218334Speter
341318334Speter  /* First see if we can apply the inverse distributive law.  */
341418334Speter  if (code == PLUS || code == MINUS
341518334Speter      || code == AND || code == IOR || code == XOR)
341618334Speter    {
341718334Speter      x = apply_distributive_law (x);
341818334Speter      code = GET_CODE (x);
341918334Speter    }
342018334Speter
342118334Speter  /* If CODE is an associative operation not otherwise handled, see if we
342218334Speter     can associate some operands.  This can win if they are constants or
342318334Speter     if they are logically related (i.e. (a & b) & a.  */
342418334Speter  if ((code == PLUS || code == MINUS
342518334Speter       || code == MULT || code == AND || code == IOR || code == XOR
342618334Speter       || code == DIV || code == UDIV
342718334Speter       || code == SMAX || code == SMIN || code == UMAX || code == UMIN)
342818334Speter      && INTEGRAL_MODE_P (mode))
342918334Speter    {
343018334Speter      if (GET_CODE (XEXP (x, 0)) == code)
343118334Speter	{
343218334Speter	  rtx other = XEXP (XEXP (x, 0), 0);
343318334Speter	  rtx inner_op0 = XEXP (XEXP (x, 0), 1);
343418334Speter	  rtx inner_op1 = XEXP (x, 1);
343518334Speter	  rtx inner;
343618334Speter
343718334Speter	  /* Make sure we pass the constant operand if any as the second
343818334Speter	     one if this is a commutative operation.  */
343918334Speter	  if (CONSTANT_P (inner_op0) && GET_RTX_CLASS (code) == 'c')
344018334Speter	    {
344118334Speter	      rtx tem = inner_op0;
344218334Speter	      inner_op0 = inner_op1;
344318334Speter	      inner_op1 = tem;
344418334Speter	    }
344518334Speter	  inner = simplify_binary_operation (code == MINUS ? PLUS
344618334Speter					     : code == DIV ? MULT
344718334Speter					     : code == UDIV ? MULT
344818334Speter					     : code,
344918334Speter					     mode, inner_op0, inner_op1);
345018334Speter
345118334Speter	  /* For commutative operations, try the other pair if that one
345218334Speter	     didn't simplify.  */
345318334Speter	  if (inner == 0 && GET_RTX_CLASS (code) == 'c')
345418334Speter	    {
345518334Speter	      other = XEXP (XEXP (x, 0), 1);
345618334Speter	      inner = simplify_binary_operation (code, mode,
345718334Speter						 XEXP (XEXP (x, 0), 0),
345818334Speter						 XEXP (x, 1));
345918334Speter	    }
346018334Speter
346118334Speter	  if (inner)
346218334Speter	    return gen_binary (code, mode, other, inner);
346318334Speter	}
346418334Speter    }
346518334Speter
346618334Speter  /* A little bit of algebraic simplification here.  */
346718334Speter  switch (code)
346818334Speter    {
346918334Speter    case MEM:
347018334Speter      /* Ensure that our address has any ASHIFTs converted to MULT in case
347118334Speter	 address-recognizing predicates are called later.  */
347218334Speter      temp = make_compound_operation (XEXP (x, 0), MEM);
347318334Speter      SUBST (XEXP (x, 0), temp);
347418334Speter      break;
347518334Speter
347618334Speter    case SUBREG:
347718334Speter      /* (subreg:A (mem:B X) N) becomes a modified MEM unless the SUBREG
347818334Speter	 is paradoxical.  If we can't do that safely, then it becomes
347918334Speter	 something nonsensical so that this combination won't take place.  */
348018334Speter
348118334Speter      if (GET_CODE (SUBREG_REG (x)) == MEM
348218334Speter	  && (GET_MODE_SIZE (mode)
348318334Speter	      <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
348418334Speter	{
348518334Speter	  rtx inner = SUBREG_REG (x);
348618334Speter	  int endian_offset = 0;
348718334Speter	  /* Don't change the mode of the MEM
348818334Speter	     if that would change the meaning of the address.  */
348918334Speter	  if (MEM_VOLATILE_P (SUBREG_REG (x))
349018334Speter	      || mode_dependent_address_p (XEXP (inner, 0)))
349150397Sobrien	    return gen_rtx_CLOBBER (mode, const0_rtx);
349218334Speter
349318334Speter	  if (BYTES_BIG_ENDIAN)
349418334Speter	    {
349518334Speter	      if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
349618334Speter		endian_offset += UNITS_PER_WORD - GET_MODE_SIZE (mode);
349718334Speter	      if (GET_MODE_SIZE (GET_MODE (inner)) < UNITS_PER_WORD)
349818334Speter		endian_offset -= (UNITS_PER_WORD
349918334Speter				  - GET_MODE_SIZE (GET_MODE (inner)));
350018334Speter	    }
350118334Speter	  /* Note if the plus_constant doesn't make a valid address
350218334Speter	     then this combination won't be accepted.  */
350350397Sobrien	  x = gen_rtx_MEM (mode,
350450397Sobrien			   plus_constant (XEXP (inner, 0),
350550397Sobrien					  (SUBREG_WORD (x) * UNITS_PER_WORD
350650397Sobrien					   + endian_offset)));
350718334Speter	  RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (inner);
350852284Sobrien	  MEM_COPY_ATTRIBUTES (x, inner);
350918334Speter	  return x;
351018334Speter	}
351118334Speter
351218334Speter      /* If we are in a SET_DEST, these other cases can't apply.  */
351318334Speter      if (in_dest)
351418334Speter	return x;
351518334Speter
351618334Speter      /* Changing mode twice with SUBREG => just change it once,
351718334Speter	 or not at all if changing back to starting mode.  */
351818334Speter      if (GET_CODE (SUBREG_REG (x)) == SUBREG)
351918334Speter	{
352018334Speter	  if (mode == GET_MODE (SUBREG_REG (SUBREG_REG (x)))
352118334Speter	      && SUBREG_WORD (x) == 0 && SUBREG_WORD (SUBREG_REG (x)) == 0)
352218334Speter	    return SUBREG_REG (SUBREG_REG (x));
352318334Speter
352418334Speter	  SUBST_INT (SUBREG_WORD (x),
352518334Speter		     SUBREG_WORD (x) + SUBREG_WORD (SUBREG_REG (x)));
352618334Speter	  SUBST (SUBREG_REG (x), SUBREG_REG (SUBREG_REG (x)));
352718334Speter	}
352818334Speter
352918334Speter      /* SUBREG of a hard register => just change the register number
353018334Speter	 and/or mode.  If the hard register is not valid in that mode,
353118334Speter	 suppress this combination.  If the hard register is the stack,
353218334Speter	 frame, or argument pointer, leave this as a SUBREG.  */
353318334Speter
353418334Speter      if (GET_CODE (SUBREG_REG (x)) == REG
353518334Speter	  && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER
353618334Speter	  && REGNO (SUBREG_REG (x)) != FRAME_POINTER_REGNUM
353718334Speter#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
353818334Speter	  && REGNO (SUBREG_REG (x)) != HARD_FRAME_POINTER_REGNUM
353918334Speter#endif
354018334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
354118334Speter	  && REGNO (SUBREG_REG (x)) != ARG_POINTER_REGNUM
354218334Speter#endif
354318334Speter	  && REGNO (SUBREG_REG (x)) != STACK_POINTER_REGNUM)
354418334Speter	{
354518334Speter	  if (HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (x)) + SUBREG_WORD (x),
354618334Speter				  mode))
354750397Sobrien	    return gen_rtx_REG (mode,
354850397Sobrien				REGNO (SUBREG_REG (x)) + SUBREG_WORD (x));
354918334Speter	  else
355050397Sobrien	    return gen_rtx_CLOBBER (mode, const0_rtx);
355118334Speter	}
355218334Speter
355318334Speter      /* For a constant, try to pick up the part we want.  Handle a full
355418334Speter	 word and low-order part.  Only do this if we are narrowing
355518334Speter	 the constant; if it is being widened, we have no idea what
355618334Speter	 the extra bits will have been set to.  */
355718334Speter
355818334Speter      if (CONSTANT_P (SUBREG_REG (x)) && op0_mode != VOIDmode
355918334Speter	  && GET_MODE_SIZE (mode) == UNITS_PER_WORD
356050397Sobrien	  && GET_MODE_SIZE (op0_mode) > UNITS_PER_WORD
356118334Speter	  && GET_MODE_CLASS (mode) == MODE_INT)
356218334Speter	{
356318334Speter	  temp = operand_subword (SUBREG_REG (x), SUBREG_WORD (x),
356418334Speter				  0, op0_mode);
356518334Speter	  if (temp)
356618334Speter	    return temp;
356718334Speter	}
356818334Speter
356918334Speter      /* If we want a subreg of a constant, at offset 0,
357018334Speter	 take the low bits.  On a little-endian machine, that's
357118334Speter	 always valid.  On a big-endian machine, it's valid
357250397Sobrien	 only if the constant's mode fits in one word.   Note that we
357350397Sobrien	 cannot use subreg_lowpart_p since SUBREG_REG may be VOIDmode.  */
357450397Sobrien      if (CONSTANT_P (SUBREG_REG (x))
357550397Sobrien	  && ((GET_MODE_SIZE (op0_mode) <= UNITS_PER_WORD
357650397Sobrien	      || ! WORDS_BIG_ENDIAN)
357750397Sobrien	      ? SUBREG_WORD (x) == 0
357850397Sobrien	      : (SUBREG_WORD (x)
357950397Sobrien		 == ((GET_MODE_SIZE (op0_mode)
358050397Sobrien		      - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD))
358150397Sobrien		     / UNITS_PER_WORD)))
358250397Sobrien	  && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (op0_mode)
358318334Speter	  && (! WORDS_BIG_ENDIAN
358418334Speter	      || GET_MODE_BITSIZE (op0_mode) <= BITS_PER_WORD))
358518334Speter	return gen_lowpart_for_combine (mode, SUBREG_REG (x));
358618334Speter
358718334Speter      /* A paradoxical SUBREG of a VOIDmode constant is the same constant,
358818334Speter	 since we are saying that the high bits don't matter.  */
358918334Speter      if (CONSTANT_P (SUBREG_REG (x)) && GET_MODE (SUBREG_REG (x)) == VOIDmode
359018334Speter	  && GET_MODE_SIZE (mode) > GET_MODE_SIZE (op0_mode))
359118334Speter	return SUBREG_REG (x);
359218334Speter
359318334Speter      /* Note that we cannot do any narrowing for non-constants since
359418334Speter	 we might have been counting on using the fact that some bits were
359518334Speter	 zero.  We now do this in the SET.  */
359618334Speter
359718334Speter      break;
359818334Speter
359918334Speter    case NOT:
360018334Speter      /* (not (plus X -1)) can become (neg X).  */
360118334Speter      if (GET_CODE (XEXP (x, 0)) == PLUS
360218334Speter	  && XEXP (XEXP (x, 0), 1) == constm1_rtx)
360318334Speter	return gen_rtx_combine (NEG, mode, XEXP (XEXP (x, 0), 0));
360418334Speter
360518334Speter      /* Similarly, (not (neg X)) is (plus X -1).  */
360618334Speter      if (GET_CODE (XEXP (x, 0)) == NEG)
360718334Speter	return gen_rtx_combine (PLUS, mode, XEXP (XEXP (x, 0), 0),
360818334Speter				constm1_rtx);
360918334Speter
361018334Speter      /* (not (xor X C)) for C constant is (xor X D) with D = ~ C.  */
361118334Speter      if (GET_CODE (XEXP (x, 0)) == XOR
361218334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
361318334Speter	  && (temp = simplify_unary_operation (NOT, mode,
361418334Speter					       XEXP (XEXP (x, 0), 1),
361518334Speter					       mode)) != 0)
361618334Speter	return gen_binary (XOR, mode, XEXP (XEXP (x, 0), 0), temp);
361718334Speter
361818334Speter      /* (not (ashift 1 X)) is (rotate ~1 X).  We used to do this for operands
361918334Speter	 other than 1, but that is not valid.  We could do a similar
362018334Speter	 simplification for (not (lshiftrt C X)) where C is just the sign bit,
362118334Speter	 but this doesn't seem common enough to bother with.  */
362218334Speter      if (GET_CODE (XEXP (x, 0)) == ASHIFT
362318334Speter	  && XEXP (XEXP (x, 0), 0) == const1_rtx)
362450397Sobrien	return gen_rtx_ROTATE (mode, gen_unary (NOT, mode, mode, const1_rtx),
362550397Sobrien			       XEXP (XEXP (x, 0), 1));
362618334Speter
362718334Speter      if (GET_CODE (XEXP (x, 0)) == SUBREG
362818334Speter	  && subreg_lowpart_p (XEXP (x, 0))
362918334Speter	  && (GET_MODE_SIZE (GET_MODE (XEXP (x, 0)))
363018334Speter	      < GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (x, 0)))))
363118334Speter	  && GET_CODE (SUBREG_REG (XEXP (x, 0))) == ASHIFT
363218334Speter	  && XEXP (SUBREG_REG (XEXP (x, 0)), 0) == const1_rtx)
363318334Speter	{
363418334Speter	  enum machine_mode inner_mode = GET_MODE (SUBREG_REG (XEXP (x, 0)));
363518334Speter
363650397Sobrien	  x = gen_rtx_ROTATE (inner_mode,
363750397Sobrien			      gen_unary (NOT, inner_mode, inner_mode,
363850397Sobrien					 const1_rtx),
363950397Sobrien			      XEXP (SUBREG_REG (XEXP (x, 0)), 1));
364018334Speter	  return gen_lowpart_for_combine (mode, x);
364118334Speter	}
364218334Speter
364350397Sobrien      /* If STORE_FLAG_VALUE is -1, (not (comparison foo bar)) can be done by
364450397Sobrien	 reversing the comparison code if valid.  */
364550397Sobrien      if (STORE_FLAG_VALUE == -1
364650397Sobrien	  && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
364718334Speter	  && reversible_comparison_p (XEXP (x, 0)))
364818334Speter	return gen_rtx_combine (reverse_condition (GET_CODE (XEXP (x, 0))),
364918334Speter				mode, XEXP (XEXP (x, 0), 0),
365018334Speter				XEXP (XEXP (x, 0), 1));
365118334Speter
365218334Speter      /* (ashiftrt foo C) where C is the number of bits in FOO minus 1
365350397Sobrien	 is (lt foo (const_int 0)) if STORE_FLAG_VALUE is -1, so we can
365450397Sobrien	 perform the above simplification.  */
365518334Speter
365650397Sobrien      if (STORE_FLAG_VALUE == -1
365750397Sobrien	  && XEXP (x, 1) == const1_rtx
365818334Speter	  && GET_CODE (XEXP (x, 0)) == ASHIFTRT
365918334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
366018334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) == GET_MODE_BITSIZE (mode) - 1)
366118334Speter	return gen_rtx_combine (GE, mode, XEXP (XEXP (x, 0), 0), const0_rtx);
366218334Speter
366318334Speter      /* Apply De Morgan's laws to reduce number of patterns for machines
366418334Speter 	 with negating logical insns (and-not, nand, etc.).  If result has
366518334Speter 	 only one NOT, put it first, since that is how the patterns are
366618334Speter 	 coded.  */
366718334Speter
366818334Speter      if (GET_CODE (XEXP (x, 0)) == IOR || GET_CODE (XEXP (x, 0)) == AND)
366918334Speter 	{
367018334Speter 	 rtx in1 = XEXP (XEXP (x, 0), 0), in2 = XEXP (XEXP (x, 0), 1);
367118334Speter
367218334Speter	 if (GET_CODE (in1) == NOT)
367318334Speter	   in1 = XEXP (in1, 0);
367418334Speter 	 else
367518334Speter	   in1 = gen_rtx_combine (NOT, GET_MODE (in1), in1);
367618334Speter
367718334Speter	 if (GET_CODE (in2) == NOT)
367818334Speter	   in2 = XEXP (in2, 0);
367918334Speter 	 else if (GET_CODE (in2) == CONST_INT
368018334Speter		  && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
368118334Speter	   in2 = GEN_INT (GET_MODE_MASK (mode) & ~ INTVAL (in2));
368218334Speter	 else
368318334Speter	   in2 = gen_rtx_combine (NOT, GET_MODE (in2), in2);
368418334Speter
368518334Speter	 if (GET_CODE (in2) == NOT)
368618334Speter	   {
368718334Speter	     rtx tem = in2;
368818334Speter	     in2 = in1; in1 = tem;
368918334Speter	   }
369018334Speter
369118334Speter	 return gen_rtx_combine (GET_CODE (XEXP (x, 0)) == IOR ? AND : IOR,
369218334Speter				 mode, in1, in2);
369318334Speter       }
369418334Speter      break;
369518334Speter
369618334Speter    case NEG:
369718334Speter      /* (neg (plus X 1)) can become (not X).  */
369818334Speter      if (GET_CODE (XEXP (x, 0)) == PLUS
369918334Speter	  && XEXP (XEXP (x, 0), 1) == const1_rtx)
370018334Speter	return gen_rtx_combine (NOT, mode, XEXP (XEXP (x, 0), 0));
370118334Speter
370218334Speter      /* Similarly, (neg (not X)) is (plus X 1).  */
370318334Speter      if (GET_CODE (XEXP (x, 0)) == NOT)
370418334Speter	return plus_constant (XEXP (XEXP (x, 0), 0), 1);
370518334Speter
370618334Speter      /* (neg (minus X Y)) can become (minus Y X).  */
370718334Speter      if (GET_CODE (XEXP (x, 0)) == MINUS
370818334Speter	  && (! FLOAT_MODE_P (mode)
370950397Sobrien	      /* x-y != -(y-x) with IEEE floating point.  */
371018334Speter	      || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
371118334Speter	      || flag_fast_math))
371218334Speter	return gen_binary (MINUS, mode, XEXP (XEXP (x, 0), 1),
371318334Speter			   XEXP (XEXP (x, 0), 0));
371418334Speter
371550397Sobrien      /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1.  */
371618334Speter      if (GET_CODE (XEXP (x, 0)) == XOR && XEXP (XEXP (x, 0), 1) == const1_rtx
371718334Speter	  && nonzero_bits (XEXP (XEXP (x, 0), 0), mode) == 1)
371818334Speter	return gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0), constm1_rtx);
371918334Speter
372018334Speter      /* NEG commutes with ASHIFT since it is multiplication.  Only do this
372118334Speter	 if we can then eliminate the NEG (e.g.,
372218334Speter	 if the operand is a constant).  */
372318334Speter
372418334Speter      if (GET_CODE (XEXP (x, 0)) == ASHIFT)
372518334Speter	{
372618334Speter	  temp = simplify_unary_operation (NEG, mode,
372718334Speter					   XEXP (XEXP (x, 0), 0), mode);
372818334Speter	  if (temp)
372918334Speter	    {
373018334Speter	      SUBST (XEXP (XEXP (x, 0), 0), temp);
373118334Speter	      return XEXP (x, 0);
373218334Speter	    }
373318334Speter	}
373418334Speter
373518334Speter      temp = expand_compound_operation (XEXP (x, 0));
373618334Speter
373718334Speter      /* For C equal to the width of MODE minus 1, (neg (ashiftrt X C)) can be
373818334Speter 	 replaced by (lshiftrt X C).  This will convert
373918334Speter	 (neg (sign_extract X 1 Y)) to (zero_extract X 1 Y).  */
374018334Speter
374118334Speter      if (GET_CODE (temp) == ASHIFTRT
374218334Speter	  && GET_CODE (XEXP (temp, 1)) == CONST_INT
374318334Speter	  && INTVAL (XEXP (temp, 1)) == GET_MODE_BITSIZE (mode) - 1)
374418334Speter	return simplify_shift_const (temp, LSHIFTRT, mode, XEXP (temp, 0),
374518334Speter				     INTVAL (XEXP (temp, 1)));
374618334Speter
374718334Speter      /* If X has only a single bit that might be nonzero, say, bit I, convert
374818334Speter	 (neg X) to (ashiftrt (ashift X C-I) C-I) where C is the bitsize of
374918334Speter	 MODE minus 1.  This will convert (neg (zero_extract X 1 Y)) to
375018334Speter	 (sign_extract X 1 Y).  But only do this if TEMP isn't a register
375118334Speter	 or a SUBREG of one since we'd be making the expression more
375218334Speter	 complex if it was just a register.  */
375318334Speter
375418334Speter      if (GET_CODE (temp) != REG
375518334Speter	  && ! (GET_CODE (temp) == SUBREG
375618334Speter		&& GET_CODE (SUBREG_REG (temp)) == REG)
375718334Speter	  && (i = exact_log2 (nonzero_bits (temp, mode))) >= 0)
375818334Speter	{
375918334Speter	  rtx temp1 = simplify_shift_const
376018334Speter	    (NULL_RTX, ASHIFTRT, mode,
376118334Speter	     simplify_shift_const (NULL_RTX, ASHIFT, mode, temp,
376218334Speter				   GET_MODE_BITSIZE (mode) - 1 - i),
376318334Speter	     GET_MODE_BITSIZE (mode) - 1 - i);
376418334Speter
376518334Speter	  /* If all we did was surround TEMP with the two shifts, we
376618334Speter	     haven't improved anything, so don't use it.  Otherwise,
376718334Speter	     we are better off with TEMP1.  */
376818334Speter	  if (GET_CODE (temp1) != ASHIFTRT
376918334Speter	      || GET_CODE (XEXP (temp1, 0)) != ASHIFT
377018334Speter	      || XEXP (XEXP (temp1, 0), 0) != temp)
377118334Speter	    return temp1;
377218334Speter	}
377318334Speter      break;
377418334Speter
377518334Speter    case TRUNCATE:
377650397Sobrien      /* We can't handle truncation to a partial integer mode here
377750397Sobrien	 because we don't know the real bitsize of the partial
377850397Sobrien	 integer mode.  */
377950397Sobrien      if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
378050397Sobrien	break;
378150397Sobrien
378250397Sobrien      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
378350397Sobrien	  && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
378450397Sobrien				    GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))))
378518334Speter	SUBST (XEXP (x, 0),
378618334Speter	       force_to_mode (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
378718334Speter			      GET_MODE_MASK (mode), NULL_RTX, 0));
378850397Sobrien
378950397Sobrien      /* (truncate:SI ({sign,zero}_extend:DI foo:SI)) == foo:SI.  */
379050397Sobrien      if ((GET_CODE (XEXP (x, 0)) == SIGN_EXTEND
379150397Sobrien	   || GET_CODE (XEXP (x, 0)) == ZERO_EXTEND)
379250397Sobrien	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode)
379350397Sobrien	return XEXP (XEXP (x, 0), 0);
379450397Sobrien
379550397Sobrien      /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is
379650397Sobrien	 (OP:SI foo:SI) if OP is NEG or ABS.  */
379750397Sobrien      if ((GET_CODE (XEXP (x, 0)) == ABS
379850397Sobrien	   || GET_CODE (XEXP (x, 0)) == NEG)
379950397Sobrien	  && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SIGN_EXTEND
380050397Sobrien	      || GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND)
380150397Sobrien	  && GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == mode)
380250397Sobrien	return gen_unary (GET_CODE (XEXP (x, 0)), mode, mode,
380350397Sobrien			  XEXP (XEXP (XEXP (x, 0), 0), 0));
380450397Sobrien
380550397Sobrien      /* (truncate:SI (subreg:DI (truncate:SI X) 0)) is
380650397Sobrien	 (truncate:SI x).  */
380750397Sobrien      if (GET_CODE (XEXP (x, 0)) == SUBREG
380850397Sobrien	  && GET_CODE (SUBREG_REG (XEXP (x, 0))) == TRUNCATE
380950397Sobrien	  && subreg_lowpart_p (XEXP (x, 0)))
381050397Sobrien	return SUBREG_REG (XEXP (x, 0));
381150397Sobrien
381250397Sobrien      /* If we know that the value is already truncated, we can
381352284Sobrien         replace the TRUNCATE with a SUBREG if TRULY_NOOP_TRUNCATION is
381452284Sobrien	 nonzero for the corresponding modes.  */
381552284Sobrien      if (TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
381652284Sobrien				 GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))))
381752284Sobrien	  && num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
381852284Sobrien	     >= GET_MODE_BITSIZE (mode) + 1)
381950397Sobrien	return gen_lowpart_for_combine (mode, XEXP (x, 0));
382050397Sobrien
382150397Sobrien      /* A truncate of a comparison can be replaced with a subreg if
382250397Sobrien         STORE_FLAG_VALUE permits.  This is like the previous test,
382350397Sobrien         but it works even if the comparison is done in a mode larger
382450397Sobrien         than HOST_BITS_PER_WIDE_INT.  */
382550397Sobrien      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
382650397Sobrien	  && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
382750397Sobrien	  && ((HOST_WIDE_INT) STORE_FLAG_VALUE &~ GET_MODE_MASK (mode)) == 0)
382850397Sobrien	return gen_lowpart_for_combine (mode, XEXP (x, 0));
382950397Sobrien
383050397Sobrien      /* Similarly, a truncate of a register whose value is a
383150397Sobrien         comparison can be replaced with a subreg if STORE_FLAG_VALUE
383250397Sobrien         permits.  */
383350397Sobrien      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
383450397Sobrien	  && ((HOST_WIDE_INT) STORE_FLAG_VALUE &~ GET_MODE_MASK (mode)) == 0
383550397Sobrien	  && (temp = get_last_value (XEXP (x, 0)))
383650397Sobrien	  && GET_RTX_CLASS (GET_CODE (temp)) == '<')
383750397Sobrien	return gen_lowpart_for_combine (mode, XEXP (x, 0));
383850397Sobrien
383918334Speter      break;
384018334Speter
384118334Speter    case FLOAT_TRUNCATE:
384218334Speter      /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF.  */
384318334Speter      if (GET_CODE (XEXP (x, 0)) == FLOAT_EXTEND
384418334Speter	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode)
384518334Speter 	return XEXP (XEXP (x, 0), 0);
384618334Speter
384718334Speter      /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
384818334Speter	 (OP:SF foo:SF) if OP is NEG or ABS.  */
384918334Speter      if ((GET_CODE (XEXP (x, 0)) == ABS
385018334Speter	   || GET_CODE (XEXP (x, 0)) == NEG)
385118334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == FLOAT_EXTEND
385218334Speter	  && GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == mode)
385318334Speter	return gen_unary (GET_CODE (XEXP (x, 0)), mode, mode,
385418334Speter			  XEXP (XEXP (XEXP (x, 0), 0), 0));
385518334Speter
385618334Speter      /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
385718334Speter	 is (float_truncate:SF x).  */
385818334Speter      if (GET_CODE (XEXP (x, 0)) == SUBREG
385918334Speter	  && subreg_lowpart_p (XEXP (x, 0))
386018334Speter	  && GET_CODE (SUBREG_REG (XEXP (x, 0))) == FLOAT_TRUNCATE)
386118334Speter	return SUBREG_REG (XEXP (x, 0));
386218334Speter      break;
386318334Speter
386418334Speter#ifdef HAVE_cc0
386518334Speter    case COMPARE:
386618334Speter      /* Convert (compare FOO (const_int 0)) to FOO unless we aren't
386718334Speter	 using cc0, in which case we want to leave it as a COMPARE
386818334Speter	 so we can distinguish it from a register-register-copy.  */
386918334Speter      if (XEXP (x, 1) == const0_rtx)
387018334Speter	return XEXP (x, 0);
387118334Speter
387218334Speter      /* In IEEE floating point, x-0 is not the same as x.  */
387318334Speter      if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
387418334Speter	   || ! FLOAT_MODE_P (GET_MODE (XEXP (x, 0)))
387518334Speter	   || flag_fast_math)
387618334Speter	  && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 0))))
387718334Speter	return XEXP (x, 0);
387818334Speter      break;
387918334Speter#endif
388018334Speter
388118334Speter    case CONST:
388218334Speter      /* (const (const X)) can become (const X).  Do it this way rather than
388318334Speter	 returning the inner CONST since CONST can be shared with a
388418334Speter	 REG_EQUAL note.  */
388518334Speter      if (GET_CODE (XEXP (x, 0)) == CONST)
388618334Speter	SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
388718334Speter      break;
388818334Speter
388918334Speter#ifdef HAVE_lo_sum
389018334Speter    case LO_SUM:
389118334Speter      /* Convert (lo_sum (high FOO) FOO) to FOO.  This is necessary so we
389218334Speter	 can add in an offset.  find_split_point will split this address up
389318334Speter	 again if it doesn't match.  */
389418334Speter      if (GET_CODE (XEXP (x, 0)) == HIGH
389518334Speter	  && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
389618334Speter	return XEXP (x, 1);
389718334Speter      break;
389818334Speter#endif
389918334Speter
390018334Speter    case PLUS:
390118334Speter      /* If we have (plus (plus (A const) B)), associate it so that CONST is
390218334Speter	 outermost.  That's because that's the way indexed addresses are
390318334Speter	 supposed to appear.  This code used to check many more cases, but
390418334Speter	 they are now checked elsewhere.  */
390518334Speter      if (GET_CODE (XEXP (x, 0)) == PLUS
390618334Speter	  && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
390718334Speter	return gen_binary (PLUS, mode,
390818334Speter			   gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0),
390918334Speter				       XEXP (x, 1)),
391018334Speter			   XEXP (XEXP (x, 0), 1));
391118334Speter
391218334Speter      /* (plus (xor (and <foo> (const_int pow2 - 1)) <c>) <-c>)
391318334Speter	 when c is (const_int (pow2 + 1) / 2) is a sign extension of a
391418334Speter	 bit-field and can be replaced by either a sign_extend or a
391518334Speter	 sign_extract.  The `and' may be a zero_extend.  */
391618334Speter      if (GET_CODE (XEXP (x, 0)) == XOR
391718334Speter	  && GET_CODE (XEXP (x, 1)) == CONST_INT
391818334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
391918334Speter	  && INTVAL (XEXP (x, 1)) == - INTVAL (XEXP (XEXP (x, 0), 1))
392018334Speter	  && (i = exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) >= 0
392118334Speter	  && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
392218334Speter	  && ((GET_CODE (XEXP (XEXP (x, 0), 0)) == AND
392318334Speter	       && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
392418334Speter	       && (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))
392518334Speter		   == ((HOST_WIDE_INT) 1 << (i + 1)) - 1))
392618334Speter	      || (GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND
392718334Speter		  && (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)))
392818334Speter		      == i + 1))))
392918334Speter	return simplify_shift_const
393018334Speter	  (NULL_RTX, ASHIFTRT, mode,
393118334Speter	   simplify_shift_const (NULL_RTX, ASHIFT, mode,
393218334Speter				 XEXP (XEXP (XEXP (x, 0), 0), 0),
393318334Speter				 GET_MODE_BITSIZE (mode) - (i + 1)),
393418334Speter	   GET_MODE_BITSIZE (mode) - (i + 1));
393518334Speter
393618334Speter      /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
393718334Speter	 C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
393818334Speter	 is 1.  This produces better code than the alternative immediately
393918334Speter	 below.  */
394018334Speter      if (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
394118334Speter	  && reversible_comparison_p (XEXP (x, 0))
394218334Speter	  && ((STORE_FLAG_VALUE == -1 && XEXP (x, 1) == const1_rtx)
394318334Speter	      || (STORE_FLAG_VALUE == 1 && XEXP (x, 1) == constm1_rtx)))
394418334Speter	return
394518334Speter	  gen_unary (NEG, mode, mode,
394618334Speter		     gen_binary (reverse_condition (GET_CODE (XEXP (x, 0))),
394718334Speter				 mode, XEXP (XEXP (x, 0), 0),
394818334Speter				 XEXP (XEXP (x, 0), 1)));
394918334Speter
395018334Speter      /* If only the low-order bit of X is possibly nonzero, (plus x -1)
395118334Speter	 can become (ashiftrt (ashift (xor x 1) C) C) where C is
395218334Speter	 the bitsize of the mode - 1.  This allows simplification of
395318334Speter	 "a = (b & 8) == 0;"  */
395418334Speter      if (XEXP (x, 1) == constm1_rtx
395518334Speter	  && GET_CODE (XEXP (x, 0)) != REG
395618334Speter	  && ! (GET_CODE (XEXP (x,0)) == SUBREG
395718334Speter		&& GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG)
395818334Speter	  && nonzero_bits (XEXP (x, 0), mode) == 1)
395918334Speter	return simplify_shift_const (NULL_RTX, ASHIFTRT, mode,
396018334Speter	   simplify_shift_const (NULL_RTX, ASHIFT, mode,
396118334Speter				 gen_rtx_combine (XOR, mode,
396218334Speter						  XEXP (x, 0), const1_rtx),
396318334Speter				 GET_MODE_BITSIZE (mode) - 1),
396418334Speter	   GET_MODE_BITSIZE (mode) - 1);
396518334Speter
396618334Speter      /* If we are adding two things that have no bits in common, convert
396718334Speter	 the addition into an IOR.  This will often be further simplified,
396818334Speter	 for example in cases like ((a & 1) + (a & 2)), which can
396918334Speter	 become a & 3.  */
397018334Speter
397118334Speter      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
397218334Speter	  && (nonzero_bits (XEXP (x, 0), mode)
397318334Speter	      & nonzero_bits (XEXP (x, 1), mode)) == 0)
397418334Speter	return gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1));
397518334Speter      break;
397618334Speter
397718334Speter    case MINUS:
397850397Sobrien      /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
397950397Sobrien	 by reversing the comparison code if valid.  */
398050397Sobrien      if (STORE_FLAG_VALUE == 1
398150397Sobrien	  && XEXP (x, 0) == const1_rtx
398218334Speter	  && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<'
398318334Speter	  && reversible_comparison_p (XEXP (x, 1)))
398418334Speter	return gen_binary (reverse_condition (GET_CODE (XEXP (x, 1))),
398518334Speter			   mode, XEXP (XEXP (x, 1), 0),
398618334Speter				XEXP (XEXP (x, 1), 1));
398718334Speter
398818334Speter      /* (minus <foo> (and <foo> (const_int -pow2))) becomes
398918334Speter	 (and <foo> (const_int pow2-1))  */
399018334Speter      if (GET_CODE (XEXP (x, 1)) == AND
399118334Speter	  && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
399218334Speter	  && exact_log2 (- INTVAL (XEXP (XEXP (x, 1), 1))) >= 0
399318334Speter	  && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
399418334Speter	return simplify_and_const_int (NULL_RTX, mode, XEXP (x, 0),
399518334Speter				       - INTVAL (XEXP (XEXP (x, 1), 1)) - 1);
399618334Speter
399718334Speter      /* Canonicalize (minus A (plus B C)) to (minus (minus A B) C) for
399818334Speter	 integers.  */
399918334Speter      if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode))
400018334Speter	return gen_binary (MINUS, mode,
400118334Speter			   gen_binary (MINUS, mode, XEXP (x, 0),
400218334Speter				       XEXP (XEXP (x, 1), 0)),
400318334Speter			   XEXP (XEXP (x, 1), 1));
400418334Speter      break;
400518334Speter
400618334Speter    case MULT:
400718334Speter      /* If we have (mult (plus A B) C), apply the distributive law and then
400818334Speter	 the inverse distributive law to see if things simplify.  This
400918334Speter	 occurs mostly in addresses, often when unrolling loops.  */
401018334Speter
401118334Speter      if (GET_CODE (XEXP (x, 0)) == PLUS)
401218334Speter	{
401318334Speter	  x = apply_distributive_law
401418334Speter	    (gen_binary (PLUS, mode,
401518334Speter			 gen_binary (MULT, mode,
401618334Speter				     XEXP (XEXP (x, 0), 0), XEXP (x, 1)),
401718334Speter			 gen_binary (MULT, mode,
401818334Speter				     XEXP (XEXP (x, 0), 1), XEXP (x, 1))));
401918334Speter
402018334Speter	  if (GET_CODE (x) != MULT)
402118334Speter	    return x;
402218334Speter	}
402318334Speter      break;
402418334Speter
402518334Speter    case UDIV:
402618334Speter      /* If this is a divide by a power of two, treat it as a shift if
402718334Speter	 its first operand is a shift.  */
402818334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
402918334Speter	  && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0
403018334Speter	  && (GET_CODE (XEXP (x, 0)) == ASHIFT
403118334Speter	      || GET_CODE (XEXP (x, 0)) == LSHIFTRT
403218334Speter	      || GET_CODE (XEXP (x, 0)) == ASHIFTRT
403318334Speter	      || GET_CODE (XEXP (x, 0)) == ROTATE
403418334Speter	      || GET_CODE (XEXP (x, 0)) == ROTATERT))
403518334Speter	return simplify_shift_const (NULL_RTX, LSHIFTRT, mode, XEXP (x, 0), i);
403618334Speter      break;
403718334Speter
403818334Speter    case EQ:  case NE:
403918334Speter    case GT:  case GTU:  case GE:  case GEU:
404018334Speter    case LT:  case LTU:  case LE:  case LEU:
404118334Speter      /* If the first operand is a condition code, we can't do anything
404218334Speter	 with it.  */
404318334Speter      if (GET_CODE (XEXP (x, 0)) == COMPARE
404418334Speter	  || (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_CC
404518334Speter#ifdef HAVE_cc0
404618334Speter	      && XEXP (x, 0) != cc0_rtx
404718334Speter#endif
404818334Speter	       ))
404918334Speter	{
405018334Speter	  rtx op0 = XEXP (x, 0);
405118334Speter	  rtx op1 = XEXP (x, 1);
405218334Speter	  enum rtx_code new_code;
405318334Speter
405418334Speter	  if (GET_CODE (op0) == COMPARE)
405518334Speter	    op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);
405618334Speter
405718334Speter	  /* Simplify our comparison, if possible.  */
405818334Speter	  new_code = simplify_comparison (code, &op0, &op1);
405918334Speter
406018334Speter	  /* If STORE_FLAG_VALUE is 1, we can convert (ne x 0) to simply X
406118334Speter	     if only the low-order bit is possibly nonzero in X (such as when
406218334Speter	     X is a ZERO_EXTRACT of one bit).  Similarly, we can convert EQ to
406318334Speter	     (xor X 1) or (minus 1 X); we use the former.  Finally, if X is
406418334Speter	     known to be either 0 or -1, NE becomes a NEG and EQ becomes
406518334Speter	     (plus X 1).
406618334Speter
406718334Speter	     Remove any ZERO_EXTRACT we made when thinking this was a
406818334Speter	     comparison.  It may now be simpler to use, e.g., an AND.  If a
406918334Speter	     ZERO_EXTRACT is indeed appropriate, it will be placed back by
407018334Speter	     the call to make_compound_operation in the SET case.  */
407118334Speter
407250397Sobrien	  if (STORE_FLAG_VALUE == 1
407350397Sobrien	      && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
407450397Sobrien	      && op1 == const0_rtx && nonzero_bits (op0, mode) == 1)
407518334Speter	    return gen_lowpart_for_combine (mode,
407618334Speter					    expand_compound_operation (op0));
407718334Speter
407850397Sobrien	  else if (STORE_FLAG_VALUE == 1
407950397Sobrien		   && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
408018334Speter		   && op1 == const0_rtx
408118334Speter		   && (num_sign_bit_copies (op0, mode)
408218334Speter		       == GET_MODE_BITSIZE (mode)))
408318334Speter	    {
408418334Speter	      op0 = expand_compound_operation (op0);
408518334Speter	      return gen_unary (NEG, mode, mode,
408618334Speter				gen_lowpart_for_combine (mode, op0));
408718334Speter	    }
408818334Speter
408950397Sobrien	  else if (STORE_FLAG_VALUE == 1
409050397Sobrien		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
409118334Speter		   && op1 == const0_rtx
409218334Speter		   && nonzero_bits (op0, mode) == 1)
409318334Speter	    {
409418334Speter	      op0 = expand_compound_operation (op0);
409518334Speter	      return gen_binary (XOR, mode,
409618334Speter				 gen_lowpart_for_combine (mode, op0),
409718334Speter				 const1_rtx);
409818334Speter	    }
409918334Speter
410050397Sobrien	  else if (STORE_FLAG_VALUE == 1
410150397Sobrien		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
410218334Speter		   && op1 == const0_rtx
410318334Speter		   && (num_sign_bit_copies (op0, mode)
410418334Speter		       == GET_MODE_BITSIZE (mode)))
410518334Speter	    {
410618334Speter	      op0 = expand_compound_operation (op0);
410718334Speter	      return plus_constant (gen_lowpart_for_combine (mode, op0), 1);
410818334Speter	    }
410918334Speter
411018334Speter	  /* If STORE_FLAG_VALUE is -1, we have cases similar to
411118334Speter	     those above.  */
411250397Sobrien	  if (STORE_FLAG_VALUE == -1
411350397Sobrien	      && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
411418334Speter	      && op1 == const0_rtx
411518334Speter	      && (num_sign_bit_copies (op0, mode)
411618334Speter		  == GET_MODE_BITSIZE (mode)))
411718334Speter	    return gen_lowpart_for_combine (mode,
411818334Speter					    expand_compound_operation (op0));
411918334Speter
412050397Sobrien	  else if (STORE_FLAG_VALUE == -1
412150397Sobrien		   && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
412218334Speter		   && op1 == const0_rtx
412318334Speter		   && nonzero_bits (op0, mode) == 1)
412418334Speter	    {
412518334Speter	      op0 = expand_compound_operation (op0);
412618334Speter	      return gen_unary (NEG, mode, mode,
412718334Speter				gen_lowpart_for_combine (mode, op0));
412818334Speter	    }
412918334Speter
413050397Sobrien	  else if (STORE_FLAG_VALUE == -1
413150397Sobrien		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
413218334Speter		   && op1 == const0_rtx
413318334Speter		   && (num_sign_bit_copies (op0, mode)
413418334Speter		       == GET_MODE_BITSIZE (mode)))
413518334Speter	    {
413618334Speter	      op0 = expand_compound_operation (op0);
413718334Speter	      return gen_unary (NOT, mode, mode,
413818334Speter				gen_lowpart_for_combine (mode, op0));
413918334Speter	    }
414018334Speter
414118334Speter	  /* If X is 0/1, (eq X 0) is X-1.  */
414250397Sobrien	  else if (STORE_FLAG_VALUE == -1
414350397Sobrien		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
414418334Speter		   && op1 == const0_rtx
414518334Speter		   && nonzero_bits (op0, mode) == 1)
414618334Speter	    {
414718334Speter	      op0 = expand_compound_operation (op0);
414818334Speter	      return plus_constant (gen_lowpart_for_combine (mode, op0), -1);
414918334Speter	    }
415018334Speter
415118334Speter	  /* If STORE_FLAG_VALUE says to just test the sign bit and X has just
415218334Speter	     one bit that might be nonzero, we can convert (ne x 0) to
415318334Speter	     (ashift x c) where C puts the bit in the sign bit.  Remove any
415418334Speter	     AND with STORE_FLAG_VALUE when we are done, since we are only
415518334Speter	     going to test the sign bit.  */
415618334Speter	  if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
415718334Speter	      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
415850397Sobrien	      && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
415952284Sobrien		  == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE(mode)-1))
416018334Speter	      && op1 == const0_rtx
416118334Speter	      && mode == GET_MODE (op0)
416218334Speter	      && (i = exact_log2 (nonzero_bits (op0, mode))) >= 0)
416318334Speter	    {
416418334Speter	      x = simplify_shift_const (NULL_RTX, ASHIFT, mode,
416518334Speter					expand_compound_operation (op0),
416618334Speter					GET_MODE_BITSIZE (mode) - 1 - i);
416718334Speter	      if (GET_CODE (x) == AND && XEXP (x, 1) == const_true_rtx)
416818334Speter		return XEXP (x, 0);
416918334Speter	      else
417018334Speter		return x;
417118334Speter	    }
417218334Speter
417318334Speter	  /* If the code changed, return a whole new comparison.  */
417418334Speter	  if (new_code != code)
417518334Speter	    return gen_rtx_combine (new_code, mode, op0, op1);
417618334Speter
417718334Speter	  /* Otherwise, keep this operation, but maybe change its operands.
417818334Speter	     This also converts (ne (compare FOO BAR) 0) to (ne FOO BAR).  */
417918334Speter	  SUBST (XEXP (x, 0), op0);
418018334Speter	  SUBST (XEXP (x, 1), op1);
418118334Speter	}
418218334Speter      break;
418318334Speter
418418334Speter    case IF_THEN_ELSE:
418518334Speter      return simplify_if_then_else (x);
418618334Speter
418718334Speter    case ZERO_EXTRACT:
418818334Speter    case SIGN_EXTRACT:
418918334Speter    case ZERO_EXTEND:
419018334Speter    case SIGN_EXTEND:
419150397Sobrien      /* If we are processing SET_DEST, we are done.  */
419218334Speter      if (in_dest)
419318334Speter	return x;
419418334Speter
419518334Speter      return expand_compound_operation (x);
419618334Speter
419718334Speter    case SET:
419818334Speter      return simplify_set (x);
419918334Speter
420018334Speter    case AND:
420118334Speter    case IOR:
420218334Speter    case XOR:
420318334Speter      return simplify_logical (x, last);
420418334Speter
420550397Sobrien    case ABS:
420618334Speter      /* (abs (neg <foo>)) -> (abs <foo>) */
420718334Speter      if (GET_CODE (XEXP (x, 0)) == NEG)
420818334Speter	SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
420918334Speter
421050397Sobrien      /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
421150397Sobrien         do nothing.  */
421250397Sobrien      if (GET_MODE (XEXP (x, 0)) == VOIDmode)
421350397Sobrien	break;
421450397Sobrien
421518334Speter      /* If operand is something known to be positive, ignore the ABS.  */
421618334Speter      if (GET_CODE (XEXP (x, 0)) == FFS || GET_CODE (XEXP (x, 0)) == ABS
421718334Speter	  || ((GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
421818334Speter	       <= HOST_BITS_PER_WIDE_INT)
421918334Speter	      && ((nonzero_bits (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
422018334Speter		   & ((HOST_WIDE_INT) 1
422118334Speter		      << (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - 1)))
422218334Speter		  == 0)))
422318334Speter	return XEXP (x, 0);
422418334Speter
422518334Speter
422618334Speter      /* If operand is known to be only -1 or 0, convert ABS to NEG.  */
422718334Speter      if (num_sign_bit_copies (XEXP (x, 0), mode) == GET_MODE_BITSIZE (mode))
422818334Speter	return gen_rtx_combine (NEG, mode, XEXP (x, 0));
422918334Speter
423018334Speter      break;
423118334Speter
423218334Speter    case FFS:
423318334Speter      /* (ffs (*_extend <X>)) = (ffs <X>) */
423418334Speter      if (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND
423518334Speter	  || GET_CODE (XEXP (x, 0)) == ZERO_EXTEND)
423618334Speter	SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
423718334Speter      break;
423818334Speter
423918334Speter    case FLOAT:
424018334Speter      /* (float (sign_extend <X>)) = (float <X>).  */
424118334Speter      if (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)
424218334Speter	SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
424318334Speter      break;
424418334Speter
424518334Speter    case ASHIFT:
424618334Speter    case LSHIFTRT:
424718334Speter    case ASHIFTRT:
424818334Speter    case ROTATE:
424918334Speter    case ROTATERT:
425018334Speter      /* If this is a shift by a constant amount, simplify it.  */
425118334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
425218334Speter	return simplify_shift_const (x, code, mode, XEXP (x, 0),
425318334Speter				     INTVAL (XEXP (x, 1)));
425418334Speter
425518334Speter#ifdef SHIFT_COUNT_TRUNCATED
425618334Speter      else if (SHIFT_COUNT_TRUNCATED && GET_CODE (XEXP (x, 1)) != REG)
425718334Speter	SUBST (XEXP (x, 1),
425818334Speter	       force_to_mode (XEXP (x, 1), GET_MODE (x),
425918334Speter			      ((HOST_WIDE_INT) 1
426018334Speter			       << exact_log2 (GET_MODE_BITSIZE (GET_MODE (x))))
426118334Speter			      - 1,
426218334Speter			      NULL_RTX, 0));
426318334Speter#endif
426418334Speter
426518334Speter      break;
426650397Sobrien
426750397Sobrien    default:
426850397Sobrien      break;
426918334Speter    }
427018334Speter
427118334Speter  return x;
427218334Speter}
427318334Speter
427418334Speter/* Simplify X, an IF_THEN_ELSE expression.  Return the new expression.  */
427518334Speter
427618334Speterstatic rtx
427718334Spetersimplify_if_then_else (x)
427818334Speter     rtx x;
427918334Speter{
428018334Speter  enum machine_mode mode = GET_MODE (x);
428118334Speter  rtx cond = XEXP (x, 0);
428218334Speter  rtx true = XEXP (x, 1);
428318334Speter  rtx false = XEXP (x, 2);
428418334Speter  enum rtx_code true_code = GET_CODE (cond);
428518334Speter  int comparison_p = GET_RTX_CLASS (true_code) == '<';
428618334Speter  rtx temp;
428718334Speter  int i;
428818334Speter
428950397Sobrien  /* Simplify storing of the truth value.  */
429018334Speter  if (comparison_p && true == const_true_rtx && false == const0_rtx)
429118334Speter    return gen_binary (true_code, mode, XEXP (cond, 0), XEXP (cond, 1));
429218334Speter
429350397Sobrien  /* Also when the truth value has to be reversed.  */
429418334Speter  if (comparison_p && reversible_comparison_p (cond)
429518334Speter      && true == const0_rtx && false == const_true_rtx)
429618334Speter    return gen_binary (reverse_condition (true_code),
429718334Speter		       mode, XEXP (cond, 0), XEXP (cond, 1));
429818334Speter
429918334Speter  /* Sometimes we can simplify the arm of an IF_THEN_ELSE if a register used
430018334Speter     in it is being compared against certain values.  Get the true and false
430118334Speter     comparisons and see if that says anything about the value of each arm.  */
430218334Speter
430318334Speter  if (comparison_p && reversible_comparison_p (cond)
430418334Speter      && GET_CODE (XEXP (cond, 0)) == REG)
430518334Speter    {
430618334Speter      HOST_WIDE_INT nzb;
430718334Speter      rtx from = XEXP (cond, 0);
430818334Speter      enum rtx_code false_code = reverse_condition (true_code);
430918334Speter      rtx true_val = XEXP (cond, 1);
431018334Speter      rtx false_val = true_val;
431118334Speter      int swapped = 0;
431218334Speter
431318334Speter      /* If FALSE_CODE is EQ, swap the codes and arms.  */
431418334Speter
431518334Speter      if (false_code == EQ)
431618334Speter	{
431718334Speter	  swapped = 1, true_code = EQ, false_code = NE;
431818334Speter	  temp = true, true = false, false = temp;
431918334Speter	}
432018334Speter
432118334Speter      /* If we are comparing against zero and the expression being tested has
432218334Speter	 only a single bit that might be nonzero, that is its value when it is
432318334Speter	 not equal to zero.  Similarly if it is known to be -1 or 0.  */
432418334Speter
432518334Speter      if (true_code == EQ && true_val == const0_rtx
432618334Speter	  && exact_log2 (nzb = nonzero_bits (from, GET_MODE (from))) >= 0)
432718334Speter	false_code = EQ, false_val = GEN_INT (nzb);
432818334Speter      else if (true_code == EQ && true_val == const0_rtx
432918334Speter	       && (num_sign_bit_copies (from, GET_MODE (from))
433018334Speter		   == GET_MODE_BITSIZE (GET_MODE (from))))
433118334Speter	false_code = EQ, false_val = constm1_rtx;
433218334Speter
433318334Speter      /* Now simplify an arm if we know the value of the register in the
433418334Speter	 branch and it is used in the arm.  Be careful due to the potential
433518334Speter	 of locally-shared RTL.  */
433618334Speter
433718334Speter      if (reg_mentioned_p (from, true))
433818334Speter	true = subst (known_cond (copy_rtx (true), true_code, from, true_val),
433918334Speter		      pc_rtx, pc_rtx, 0, 0);
434018334Speter      if (reg_mentioned_p (from, false))
434118334Speter	false = subst (known_cond (copy_rtx (false), false_code,
434218334Speter				   from, false_val),
434318334Speter		       pc_rtx, pc_rtx, 0, 0);
434418334Speter
434518334Speter      SUBST (XEXP (x, 1), swapped ? false : true);
434618334Speter      SUBST (XEXP (x, 2), swapped ? true : false);
434718334Speter
434818334Speter      true = XEXP (x, 1), false = XEXP (x, 2), true_code = GET_CODE (cond);
434918334Speter    }
435018334Speter
435118334Speter  /* If we have (if_then_else FOO (pc) (label_ref BAR)) and FOO can be
435218334Speter     reversed, do so to avoid needing two sets of patterns for
435318334Speter     subtract-and-branch insns.  Similarly if we have a constant in the true
435418334Speter     arm, the false arm is the same as the first operand of the comparison, or
435518334Speter     the false arm is more complicated than the true arm.  */
435618334Speter
435718334Speter  if (comparison_p && reversible_comparison_p (cond)
435818334Speter      && (true == pc_rtx
435918334Speter	  || (CONSTANT_P (true)
436018334Speter	      && GET_CODE (false) != CONST_INT && false != pc_rtx)
436118334Speter	  || true == const0_rtx
436218334Speter	  || (GET_RTX_CLASS (GET_CODE (true)) == 'o'
436318334Speter	      && GET_RTX_CLASS (GET_CODE (false)) != 'o')
436418334Speter	  || (GET_CODE (true) == SUBREG
436518334Speter	      && GET_RTX_CLASS (GET_CODE (SUBREG_REG (true))) == 'o'
436618334Speter	      && GET_RTX_CLASS (GET_CODE (false)) != 'o')
436718334Speter	  || reg_mentioned_p (true, false)
436818334Speter	  || rtx_equal_p (false, XEXP (cond, 0))))
436918334Speter    {
437018334Speter      true_code = reverse_condition (true_code);
437118334Speter      SUBST (XEXP (x, 0),
437218334Speter	     gen_binary (true_code, GET_MODE (cond), XEXP (cond, 0),
437318334Speter			 XEXP (cond, 1)));
437418334Speter
437518334Speter      SUBST (XEXP (x, 1), false);
437618334Speter      SUBST (XEXP (x, 2), true);
437718334Speter
437818334Speter      temp = true, true = false, false = temp, cond = XEXP (x, 0);
437950397Sobrien
438050397Sobrien      /* It is possible that the conditional has been simplified out.  */
438150397Sobrien      true_code = GET_CODE (cond);
438250397Sobrien      comparison_p = GET_RTX_CLASS (true_code) == '<';
438318334Speter    }
438418334Speter
438518334Speter  /* If the two arms are identical, we don't need the comparison.  */
438618334Speter
438718334Speter  if (rtx_equal_p (true, false) && ! side_effects_p (cond))
438818334Speter    return true;
438918334Speter
439050397Sobrien  /* Convert a == b ? b : a to "a".  */
439150397Sobrien  if (true_code == EQ && ! side_effects_p (cond)
439250397Sobrien      && rtx_equal_p (XEXP (cond, 0), false)
439350397Sobrien      && rtx_equal_p (XEXP (cond, 1), true))
439450397Sobrien    return false;
439550397Sobrien  else if (true_code == NE && ! side_effects_p (cond)
439650397Sobrien	   && rtx_equal_p (XEXP (cond, 0), true)
439750397Sobrien	   && rtx_equal_p (XEXP (cond, 1), false))
439850397Sobrien    return true;
439950397Sobrien
440018334Speter  /* Look for cases where we have (abs x) or (neg (abs X)).  */
440118334Speter
440218334Speter  if (GET_MODE_CLASS (mode) == MODE_INT
440318334Speter      && GET_CODE (false) == NEG
440418334Speter      && rtx_equal_p (true, XEXP (false, 0))
440518334Speter      && comparison_p
440618334Speter      && rtx_equal_p (true, XEXP (cond, 0))
440718334Speter      && ! side_effects_p (true))
440818334Speter    switch (true_code)
440918334Speter      {
441018334Speter      case GT:
441118334Speter      case GE:
441218334Speter	return gen_unary (ABS, mode, mode, true);
441318334Speter      case LT:
441418334Speter      case LE:
441518334Speter	return gen_unary (NEG, mode, mode, gen_unary (ABS, mode, mode, true));
441650397Sobrien    default:
441750397Sobrien      break;
441818334Speter      }
441918334Speter
442018334Speter  /* Look for MIN or MAX.  */
442118334Speter
442218334Speter  if ((! FLOAT_MODE_P (mode) || flag_fast_math)
442318334Speter      && comparison_p
442418334Speter      && rtx_equal_p (XEXP (cond, 0), true)
442518334Speter      && rtx_equal_p (XEXP (cond, 1), false)
442618334Speter      && ! side_effects_p (cond))
442718334Speter    switch (true_code)
442818334Speter      {
442918334Speter      case GE:
443018334Speter      case GT:
443118334Speter	return gen_binary (SMAX, mode, true, false);
443218334Speter      case LE:
443318334Speter      case LT:
443418334Speter	return gen_binary (SMIN, mode, true, false);
443518334Speter      case GEU:
443618334Speter      case GTU:
443718334Speter	return gen_binary (UMAX, mode, true, false);
443818334Speter      case LEU:
443918334Speter      case LTU:
444018334Speter	return gen_binary (UMIN, mode, true, false);
444150397Sobrien      default:
444250397Sobrien	break;
444318334Speter      }
444418334Speter
444518334Speter  /* If we have (if_then_else COND (OP Z C1) Z) and OP is an identity when its
444618334Speter     second operand is zero, this can be done as (OP Z (mult COND C2)) where
444718334Speter     C2 = C1 * STORE_FLAG_VALUE. Similarly if OP has an outer ZERO_EXTEND or
444818334Speter     SIGN_EXTEND as long as Z is already extended (so we don't destroy it).
444918334Speter     We can do this kind of thing in some cases when STORE_FLAG_VALUE is
445050397Sobrien     neither 1 or -1, but it isn't worth checking for.  */
445118334Speter
445250397Sobrien  if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
445350397Sobrien      && comparison_p && mode != VOIDmode && ! side_effects_p (x))
445418334Speter    {
445518334Speter      rtx t = make_compound_operation (true, SET);
445618334Speter      rtx f = make_compound_operation (false, SET);
445718334Speter      rtx cond_op0 = XEXP (cond, 0);
445818334Speter      rtx cond_op1 = XEXP (cond, 1);
445918334Speter      enum rtx_code op, extend_op = NIL;
446018334Speter      enum machine_mode m = mode;
446118334Speter      rtx z = 0, c1;
446218334Speter
446318334Speter      if ((GET_CODE (t) == PLUS || GET_CODE (t) == MINUS
446418334Speter	   || GET_CODE (t) == IOR || GET_CODE (t) == XOR
446518334Speter	   || GET_CODE (t) == ASHIFT
446618334Speter	   || GET_CODE (t) == LSHIFTRT || GET_CODE (t) == ASHIFTRT)
446718334Speter	  && rtx_equal_p (XEXP (t, 0), f))
446818334Speter	c1 = XEXP (t, 1), op = GET_CODE (t), z = f;
446918334Speter
447018334Speter      /* If an identity-zero op is commutative, check whether there
447150397Sobrien	 would be a match if we swapped the operands.  */
447218334Speter      else if ((GET_CODE (t) == PLUS || GET_CODE (t) == IOR
447318334Speter		|| GET_CODE (t) == XOR)
447418334Speter	       && rtx_equal_p (XEXP (t, 1), f))
447518334Speter	c1 = XEXP (t, 0), op = GET_CODE (t), z = f;
447618334Speter      else if (GET_CODE (t) == SIGN_EXTEND
447718334Speter	       && (GET_CODE (XEXP (t, 0)) == PLUS
447818334Speter		   || GET_CODE (XEXP (t, 0)) == MINUS
447918334Speter		   || GET_CODE (XEXP (t, 0)) == IOR
448018334Speter		   || GET_CODE (XEXP (t, 0)) == XOR
448118334Speter		   || GET_CODE (XEXP (t, 0)) == ASHIFT
448218334Speter		   || GET_CODE (XEXP (t, 0)) == LSHIFTRT
448318334Speter		   || GET_CODE (XEXP (t, 0)) == ASHIFTRT)
448418334Speter	       && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG
448518334Speter	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 0))
448618334Speter	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f)
448718334Speter	       && (num_sign_bit_copies (f, GET_MODE (f))
448818334Speter		   > (GET_MODE_BITSIZE (mode)
448918334Speter		      - GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (t, 0), 0))))))
449018334Speter	{
449118334Speter	  c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0));
449218334Speter	  extend_op = SIGN_EXTEND;
449318334Speter	  m = GET_MODE (XEXP (t, 0));
449418334Speter	}
449518334Speter      else if (GET_CODE (t) == SIGN_EXTEND
449618334Speter	       && (GET_CODE (XEXP (t, 0)) == PLUS
449718334Speter		   || GET_CODE (XEXP (t, 0)) == IOR
449818334Speter		   || GET_CODE (XEXP (t, 0)) == XOR)
449918334Speter	       && GET_CODE (XEXP (XEXP (t, 0), 1)) == SUBREG
450018334Speter	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 1))
450118334Speter	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 1)), f)
450218334Speter	       && (num_sign_bit_copies (f, GET_MODE (f))
450318334Speter		   > (GET_MODE_BITSIZE (mode)
450418334Speter		      - GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (t, 0), 1))))))
450518334Speter	{
450618334Speter	  c1 = XEXP (XEXP (t, 0), 0); z = f; op = GET_CODE (XEXP (t, 0));
450718334Speter	  extend_op = SIGN_EXTEND;
450818334Speter	  m = GET_MODE (XEXP (t, 0));
450918334Speter	}
451018334Speter      else if (GET_CODE (t) == ZERO_EXTEND
451118334Speter	       && (GET_CODE (XEXP (t, 0)) == PLUS
451218334Speter		   || GET_CODE (XEXP (t, 0)) == MINUS
451318334Speter		   || GET_CODE (XEXP (t, 0)) == IOR
451418334Speter		   || GET_CODE (XEXP (t, 0)) == XOR
451518334Speter		   || GET_CODE (XEXP (t, 0)) == ASHIFT
451618334Speter		   || GET_CODE (XEXP (t, 0)) == LSHIFTRT
451718334Speter		   || GET_CODE (XEXP (t, 0)) == ASHIFTRT)
451818334Speter	       && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG
451918334Speter	       && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
452018334Speter	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 0))
452118334Speter	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f)
452218334Speter	       && ((nonzero_bits (f, GET_MODE (f))
452318334Speter		    & ~ GET_MODE_MASK (GET_MODE (XEXP (XEXP (t, 0), 0))))
452418334Speter		   == 0))
452518334Speter	{
452618334Speter	  c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0));
452718334Speter	  extend_op = ZERO_EXTEND;
452818334Speter	  m = GET_MODE (XEXP (t, 0));
452918334Speter	}
453018334Speter      else if (GET_CODE (t) == ZERO_EXTEND
453118334Speter	       && (GET_CODE (XEXP (t, 0)) == PLUS
453218334Speter		   || GET_CODE (XEXP (t, 0)) == IOR
453318334Speter		   || GET_CODE (XEXP (t, 0)) == XOR)
453418334Speter	       && GET_CODE (XEXP (XEXP (t, 0), 1)) == SUBREG
453518334Speter	       && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
453618334Speter	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 1))
453718334Speter	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 1)), f)
453818334Speter	       && ((nonzero_bits (f, GET_MODE (f))
453918334Speter		    & ~ GET_MODE_MASK (GET_MODE (XEXP (XEXP (t, 0), 1))))
454018334Speter		   == 0))
454118334Speter	{
454218334Speter	  c1 = XEXP (XEXP (t, 0), 0); z = f; op = GET_CODE (XEXP (t, 0));
454318334Speter	  extend_op = ZERO_EXTEND;
454418334Speter	  m = GET_MODE (XEXP (t, 0));
454518334Speter	}
454618334Speter
454718334Speter      if (z)
454818334Speter	{
454918334Speter	  temp = subst (gen_binary (true_code, m, cond_op0, cond_op1),
455018334Speter			pc_rtx, pc_rtx, 0, 0);
455118334Speter	  temp = gen_binary (MULT, m, temp,
455218334Speter			     gen_binary (MULT, m, c1, const_true_rtx));
455318334Speter	  temp = subst (temp, pc_rtx, pc_rtx, 0, 0);
455418334Speter	  temp = gen_binary (op, m, gen_lowpart_for_combine (m, z), temp);
455518334Speter
455618334Speter	  if (extend_op != NIL)
455718334Speter	    temp = gen_unary (extend_op, mode, m, temp);
455818334Speter
455918334Speter	  return temp;
456018334Speter	}
456118334Speter    }
456218334Speter
456318334Speter  /* If we have (if_then_else (ne A 0) C1 0) and either A is known to be 0 or
456418334Speter     1 and C1 is a single bit or A is known to be 0 or -1 and C1 is the
456518334Speter     negation of a single bit, we can convert this operation to a shift.  We
456618334Speter     can actually do this more generally, but it doesn't seem worth it.  */
456718334Speter
456818334Speter  if (true_code == NE && XEXP (cond, 1) == const0_rtx
456918334Speter      && false == const0_rtx && GET_CODE (true) == CONST_INT
457018334Speter      && ((1 == nonzero_bits (XEXP (cond, 0), mode)
457118334Speter	   && (i = exact_log2 (INTVAL (true))) >= 0)
457218334Speter	  || ((num_sign_bit_copies (XEXP (cond, 0), mode)
457318334Speter	       == GET_MODE_BITSIZE (mode))
457418334Speter	      && (i = exact_log2 (- INTVAL (true))) >= 0)))
457518334Speter    return
457618334Speter      simplify_shift_const (NULL_RTX, ASHIFT, mode,
457718334Speter			    gen_lowpart_for_combine (mode, XEXP (cond, 0)), i);
457818334Speter
457918334Speter  return x;
458018334Speter}
458118334Speter
458218334Speter/* Simplify X, a SET expression.  Return the new expression.  */
458318334Speter
458418334Speterstatic rtx
458518334Spetersimplify_set (x)
458618334Speter     rtx x;
458718334Speter{
458818334Speter  rtx src = SET_SRC (x);
458918334Speter  rtx dest = SET_DEST (x);
459018334Speter  enum machine_mode mode
459118334Speter    = GET_MODE (src) != VOIDmode ? GET_MODE (src) : GET_MODE (dest);
459218334Speter  rtx other_insn;
459318334Speter  rtx *cc_use;
459418334Speter
459518334Speter  /* (set (pc) (return)) gets written as (return).  */
459618334Speter  if (GET_CODE (dest) == PC && GET_CODE (src) == RETURN)
459718334Speter    return src;
459818334Speter
459918334Speter  /* Now that we know for sure which bits of SRC we are using, see if we can
460018334Speter     simplify the expression for the object knowing that we only need the
460118334Speter     low-order bits.  */
460218334Speter
460318334Speter  if (GET_MODE_CLASS (mode) == MODE_INT)
460418334Speter    src = force_to_mode (src, mode, GET_MODE_MASK (mode), NULL_RTX, 0);
460518334Speter
460618334Speter  /* If we are setting CC0 or if the source is a COMPARE, look for the use of
460718334Speter     the comparison result and try to simplify it unless we already have used
460818334Speter     undobuf.other_insn.  */
460918334Speter  if ((GET_CODE (src) == COMPARE
461018334Speter#ifdef HAVE_cc0
461118334Speter       || dest == cc0_rtx
461218334Speter#endif
461318334Speter       )
461418334Speter      && (cc_use = find_single_use (dest, subst_insn, &other_insn)) != 0
461518334Speter      && (undobuf.other_insn == 0 || other_insn == undobuf.other_insn)
461618334Speter      && GET_RTX_CLASS (GET_CODE (*cc_use)) == '<'
461718334Speter      && rtx_equal_p (XEXP (*cc_use, 0), dest))
461818334Speter    {
461918334Speter      enum rtx_code old_code = GET_CODE (*cc_use);
462018334Speter      enum rtx_code new_code;
462118334Speter      rtx op0, op1;
462218334Speter      int other_changed = 0;
462318334Speter      enum machine_mode compare_mode = GET_MODE (dest);
462418334Speter
462518334Speter      if (GET_CODE (src) == COMPARE)
462618334Speter	op0 = XEXP (src, 0), op1 = XEXP (src, 1);
462718334Speter      else
462818334Speter	op0 = src, op1 = const0_rtx;
462918334Speter
463018334Speter      /* Simplify our comparison, if possible.  */
463118334Speter      new_code = simplify_comparison (old_code, &op0, &op1);
463218334Speter
463318334Speter#ifdef EXTRA_CC_MODES
463418334Speter      /* If this machine has CC modes other than CCmode, check to see if we
463518334Speter	 need to use a different CC mode here.  */
463618334Speter      compare_mode = SELECT_CC_MODE (new_code, op0, op1);
463718334Speter#endif /* EXTRA_CC_MODES */
463818334Speter
463918334Speter#if !defined (HAVE_cc0) && defined (EXTRA_CC_MODES)
464018334Speter      /* If the mode changed, we have to change SET_DEST, the mode in the
464118334Speter	 compare, and the mode in the place SET_DEST is used.  If SET_DEST is
464218334Speter	 a hard register, just build new versions with the proper mode.  If it
464318334Speter	 is a pseudo, we lose unless it is only time we set the pseudo, in
464418334Speter	 which case we can safely change its mode.  */
464518334Speter      if (compare_mode != GET_MODE (dest))
464618334Speter	{
464718334Speter	  int regno = REGNO (dest);
464850397Sobrien	  rtx new_dest = gen_rtx_REG (compare_mode, regno);
464918334Speter
465018334Speter	  if (regno < FIRST_PSEUDO_REGISTER
465150397Sobrien	      || (REG_N_SETS (regno) == 1 && ! REG_USERVAR_P (dest)))
465218334Speter	    {
465318334Speter	      if (regno >= FIRST_PSEUDO_REGISTER)
465418334Speter		SUBST (regno_reg_rtx[regno], new_dest);
465518334Speter
465618334Speter	      SUBST (SET_DEST (x), new_dest);
465718334Speter	      SUBST (XEXP (*cc_use, 0), new_dest);
465818334Speter	      other_changed = 1;
465918334Speter
466018334Speter	      dest = new_dest;
466118334Speter	    }
466218334Speter	}
466318334Speter#endif
466418334Speter
466518334Speter      /* If the code changed, we have to build a new comparison in
466618334Speter	 undobuf.other_insn.  */
466718334Speter      if (new_code != old_code)
466818334Speter	{
466918334Speter	  unsigned HOST_WIDE_INT mask;
467018334Speter
467118334Speter	  SUBST (*cc_use, gen_rtx_combine (new_code, GET_MODE (*cc_use),
467218334Speter					   dest, const0_rtx));
467318334Speter
467418334Speter	  /* If the only change we made was to change an EQ into an NE or
467518334Speter	     vice versa, OP0 has only one bit that might be nonzero, and OP1
467618334Speter	     is zero, check if changing the user of the condition code will
467718334Speter	     produce a valid insn.  If it won't, we can keep the original code
467818334Speter	     in that insn by surrounding our operation with an XOR.  */
467918334Speter
468018334Speter	  if (((old_code == NE && new_code == EQ)
468118334Speter	       || (old_code == EQ && new_code == NE))
468218334Speter	      && ! other_changed && op1 == const0_rtx
468318334Speter	      && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT
468418334Speter	      && exact_log2 (mask = nonzero_bits (op0, GET_MODE (op0))) >= 0)
468518334Speter	    {
468618334Speter	      rtx pat = PATTERN (other_insn), note = 0;
468718334Speter
468852284Sobrien	      if ((recog_for_combine (&pat, other_insn, &note) < 0
468918334Speter		   && ! check_asm_operands (pat)))
469018334Speter		{
469118334Speter		  PUT_CODE (*cc_use, old_code);
469218334Speter		  other_insn = 0;
469318334Speter
469418334Speter		  op0 = gen_binary (XOR, GET_MODE (op0), op0, GEN_INT (mask));
469518334Speter		}
469618334Speter	    }
469718334Speter
469818334Speter	  other_changed = 1;
469918334Speter	}
470018334Speter
470118334Speter      if (other_changed)
470218334Speter	undobuf.other_insn = other_insn;
470318334Speter
470418334Speter#ifdef HAVE_cc0
470518334Speter      /* If we are now comparing against zero, change our source if
470618334Speter	 needed.  If we do not use cc0, we always have a COMPARE.  */
470718334Speter      if (op1 == const0_rtx && dest == cc0_rtx)
470818334Speter	{
470918334Speter	  SUBST (SET_SRC (x), op0);
471018334Speter	  src = op0;
471118334Speter	}
471218334Speter      else
471318334Speter#endif
471418334Speter
471518334Speter      /* Otherwise, if we didn't previously have a COMPARE in the
471618334Speter	 correct mode, we need one.  */
471718334Speter      if (GET_CODE (src) != COMPARE || GET_MODE (src) != compare_mode)
471818334Speter	{
471918334Speter	  SUBST (SET_SRC (x),
472018334Speter		 gen_rtx_combine (COMPARE, compare_mode, op0, op1));
472118334Speter	  src = SET_SRC (x);
472218334Speter	}
472318334Speter      else
472418334Speter	{
472518334Speter	  /* Otherwise, update the COMPARE if needed.  */
472618334Speter	  SUBST (XEXP (src, 0), op0);
472718334Speter	  SUBST (XEXP (src, 1), op1);
472818334Speter	}
472918334Speter    }
473018334Speter  else
473118334Speter    {
473218334Speter      /* Get SET_SRC in a form where we have placed back any
473318334Speter	 compound expressions.  Then do the checks below.  */
473418334Speter      src = make_compound_operation (src, SET);
473518334Speter      SUBST (SET_SRC (x), src);
473618334Speter    }
473718334Speter
473818334Speter  /* If we have (set x (subreg:m1 (op:m2 ...) 0)) with OP being some operation,
473918334Speter     and X being a REG or (subreg (reg)), we may be able to convert this to
474018334Speter     (set (subreg:m2 x) (op)).
474118334Speter
474218334Speter     We can always do this if M1 is narrower than M2 because that means that
474318334Speter     we only care about the low bits of the result.
474418334Speter
474518334Speter     However, on machines without WORD_REGISTER_OPERATIONS defined, we cannot
474650397Sobrien     perform a narrower operation than requested since the high-order bits will
474718334Speter     be undefined.  On machine where it is defined, this transformation is safe
474818334Speter     as long as M1 and M2 have the same number of words.  */
474918334Speter
475018334Speter  if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)
475118334Speter      && GET_RTX_CLASS (GET_CODE (SUBREG_REG (src))) != 'o'
475218334Speter      && (((GET_MODE_SIZE (GET_MODE (src)) + (UNITS_PER_WORD - 1))
475318334Speter	   / UNITS_PER_WORD)
475418334Speter	  == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
475518334Speter	       + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
475618334Speter#ifndef WORD_REGISTER_OPERATIONS
475718334Speter      && (GET_MODE_SIZE (GET_MODE (src))
475818334Speter	  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
475918334Speter#endif
476018334Speter#ifdef CLASS_CANNOT_CHANGE_SIZE
476118334Speter      && ! (GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER
476218334Speter	    && (TEST_HARD_REG_BIT
476318334Speter		(reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE],
476418334Speter		 REGNO (dest)))
476518334Speter	    && (GET_MODE_SIZE (GET_MODE (src))
476618334Speter		!= GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))
476718334Speter#endif
476818334Speter      && (GET_CODE (dest) == REG
476918334Speter	  || (GET_CODE (dest) == SUBREG
477018334Speter	      && GET_CODE (SUBREG_REG (dest)) == REG)))
477118334Speter    {
477218334Speter      SUBST (SET_DEST (x),
477318334Speter	     gen_lowpart_for_combine (GET_MODE (SUBREG_REG (src)),
477418334Speter				      dest));
477518334Speter      SUBST (SET_SRC (x), SUBREG_REG (src));
477618334Speter
477718334Speter      src = SET_SRC (x), dest = SET_DEST (x);
477818334Speter    }
477918334Speter
478018334Speter#ifdef LOAD_EXTEND_OP
478118334Speter  /* If we have (set FOO (subreg:M (mem:N BAR) 0)) with M wider than N, this
478218334Speter     would require a paradoxical subreg.  Replace the subreg with a
478350397Sobrien     zero_extend to avoid the reload that would otherwise be required.  */
478418334Speter
478518334Speter  if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)
478618334Speter      && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (src))) != NIL
478718334Speter      && SUBREG_WORD (src) == 0
478818334Speter      && (GET_MODE_SIZE (GET_MODE (src))
478918334Speter	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
479018334Speter      && GET_CODE (SUBREG_REG (src)) == MEM)
479118334Speter    {
479218334Speter      SUBST (SET_SRC (x),
479318334Speter	     gen_rtx_combine (LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (src))),
479418334Speter			      GET_MODE (src), XEXP (src, 0)));
479518334Speter
479618334Speter      src = SET_SRC (x);
479718334Speter    }
479818334Speter#endif
479918334Speter
480018334Speter  /* If we don't have a conditional move, SET_SRC is an IF_THEN_ELSE, and we
480118334Speter     are comparing an item known to be 0 or -1 against 0, use a logical
480218334Speter     operation instead. Check for one of the arms being an IOR of the other
480318334Speter     arm with some value.  We compute three terms to be IOR'ed together.  In
480418334Speter     practice, at most two will be nonzero.  Then we do the IOR's.  */
480518334Speter
480618334Speter  if (GET_CODE (dest) != PC
480718334Speter      && GET_CODE (src) == IF_THEN_ELSE
480818334Speter      && GET_MODE_CLASS (GET_MODE (src)) == MODE_INT
480918334Speter      && (GET_CODE (XEXP (src, 0)) == EQ || GET_CODE (XEXP (src, 0)) == NE)
481018334Speter      && XEXP (XEXP (src, 0), 1) == const0_rtx
481118334Speter      && GET_MODE (src) == GET_MODE (XEXP (XEXP (src, 0), 0))
481218334Speter#ifdef HAVE_conditional_move
481318334Speter      && ! can_conditionally_move_p (GET_MODE (src))
481418334Speter#endif
481518334Speter      && (num_sign_bit_copies (XEXP (XEXP (src, 0), 0),
481618334Speter			       GET_MODE (XEXP (XEXP (src, 0), 0)))
481718334Speter	  == GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (src, 0), 0))))
481818334Speter      && ! side_effects_p (src))
481918334Speter    {
482018334Speter      rtx true = (GET_CODE (XEXP (src, 0)) == NE
482118334Speter		      ? XEXP (src, 1) : XEXP (src, 2));
482218334Speter      rtx false = (GET_CODE (XEXP (src, 0)) == NE
482318334Speter		   ? XEXP (src, 2) : XEXP (src, 1));
482418334Speter      rtx term1 = const0_rtx, term2, term3;
482518334Speter
482618334Speter      if (GET_CODE (true) == IOR && rtx_equal_p (XEXP (true, 0), false))
482718334Speter	term1 = false, true = XEXP (true, 1), false = const0_rtx;
482818334Speter      else if (GET_CODE (true) == IOR
482918334Speter	       && rtx_equal_p (XEXP (true, 1), false))
483018334Speter	term1 = false, true = XEXP (true, 0), false = const0_rtx;
483118334Speter      else if (GET_CODE (false) == IOR
483218334Speter	       && rtx_equal_p (XEXP (false, 0), true))
483318334Speter	term1 = true, false = XEXP (false, 1), true = const0_rtx;
483418334Speter      else if (GET_CODE (false) == IOR
483518334Speter	       && rtx_equal_p (XEXP (false, 1), true))
483618334Speter	term1 = true, false = XEXP (false, 0), true = const0_rtx;
483718334Speter
483818334Speter      term2 = gen_binary (AND, GET_MODE (src), XEXP (XEXP (src, 0), 0), true);
483918334Speter      term3 = gen_binary (AND, GET_MODE (src),
484018334Speter			  gen_unary (NOT, GET_MODE (src), GET_MODE (src),
484118334Speter				     XEXP (XEXP (src, 0), 0)),
484218334Speter			  false);
484318334Speter
484418334Speter      SUBST (SET_SRC (x),
484518334Speter	     gen_binary (IOR, GET_MODE (src),
484618334Speter			 gen_binary (IOR, GET_MODE (src), term1, term2),
484718334Speter			 term3));
484818334Speter
484918334Speter      src = SET_SRC (x);
485018334Speter    }
485118334Speter
485218334Speter  /* If either SRC or DEST is a CLOBBER of (const_int 0), make this
485318334Speter     whole thing fail.  */
485418334Speter  if (GET_CODE (src) == CLOBBER && XEXP (src, 0) == const0_rtx)
485518334Speter    return src;
485618334Speter  else if (GET_CODE (dest) == CLOBBER && XEXP (dest, 0) == const0_rtx)
485718334Speter    return dest;
485818334Speter  else
485918334Speter    /* Convert this into a field assignment operation, if possible.  */
486018334Speter    return make_field_assignment (x);
486118334Speter}
486218334Speter
486318334Speter/* Simplify, X, and AND, IOR, or XOR operation, and return the simplified
486418334Speter   result.  LAST is nonzero if this is the last retry.  */
486518334Speter
486618334Speterstatic rtx
486718334Spetersimplify_logical (x, last)
486818334Speter     rtx x;
486918334Speter     int last;
487018334Speter{
487118334Speter  enum machine_mode mode = GET_MODE (x);
487218334Speter  rtx op0 = XEXP (x, 0);
487318334Speter  rtx op1 = XEXP (x, 1);
487418334Speter
487518334Speter  switch (GET_CODE (x))
487618334Speter    {
487718334Speter    case AND:
487818334Speter      /* Convert (A ^ B) & A to A & (~ B) since the latter is often a single
487918334Speter	 insn (and may simplify more).  */
488018334Speter      if (GET_CODE (op0) == XOR
488118334Speter	  && rtx_equal_p (XEXP (op0, 0), op1)
488218334Speter	  && ! side_effects_p (op1))
488318334Speter	x = gen_binary (AND, mode,
488418334Speter			gen_unary (NOT, mode, mode, XEXP (op0, 1)), op1);
488518334Speter
488618334Speter      if (GET_CODE (op0) == XOR
488718334Speter	  && rtx_equal_p (XEXP (op0, 1), op1)
488818334Speter	  && ! side_effects_p (op1))
488918334Speter	x = gen_binary (AND, mode,
489018334Speter			gen_unary (NOT, mode, mode, XEXP (op0, 0)), op1);
489118334Speter
489218334Speter      /* Similarly for (~ (A ^ B)) & A.  */
489318334Speter      if (GET_CODE (op0) == NOT
489418334Speter	  && GET_CODE (XEXP (op0, 0)) == XOR
489518334Speter	  && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
489618334Speter	  && ! side_effects_p (op1))
489718334Speter	x = gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
489818334Speter
489918334Speter      if (GET_CODE (op0) == NOT
490018334Speter	  && GET_CODE (XEXP (op0, 0)) == XOR
490118334Speter	  && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
490218334Speter	  && ! side_effects_p (op1))
490318334Speter	x = gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
490418334Speter
490518334Speter      if (GET_CODE (op1) == CONST_INT)
490618334Speter	{
490718334Speter	  x = simplify_and_const_int (x, mode, op0, INTVAL (op1));
490818334Speter
490918334Speter	  /* If we have (ior (and (X C1) C2)) and the next restart would be
491018334Speter	     the last, simplify this by making C1 as small as possible
491150397Sobrien	     and then exit.  */
491218334Speter	  if (last
491318334Speter	      && GET_CODE (x) == IOR && GET_CODE (op0) == AND
491418334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
491518334Speter	      && GET_CODE (op1) == CONST_INT)
491618334Speter	    return gen_binary (IOR, mode,
491718334Speter			       gen_binary (AND, mode, XEXP (op0, 0),
491818334Speter					   GEN_INT (INTVAL (XEXP (op0, 1))
491918334Speter						    & ~ INTVAL (op1))), op1);
492018334Speter
492118334Speter	  if (GET_CODE (x) != AND)
492218334Speter	    return x;
492318334Speter
492418334Speter	  if (GET_RTX_CLASS (GET_CODE (x)) == 'c'
492518334Speter	      || GET_RTX_CLASS (GET_CODE (x)) == '2')
492618334Speter	    op0 = XEXP (x, 0), op1 = XEXP (x, 1);
492718334Speter	}
492818334Speter
492918334Speter      /* Convert (A | B) & A to A.  */
493018334Speter      if (GET_CODE (op0) == IOR
493118334Speter	  && (rtx_equal_p (XEXP (op0, 0), op1)
493218334Speter	      || rtx_equal_p (XEXP (op0, 1), op1))
493318334Speter	  && ! side_effects_p (XEXP (op0, 0))
493418334Speter	  && ! side_effects_p (XEXP (op0, 1)))
493518334Speter	return op1;
493618334Speter
493718334Speter      /* In the following group of tests (and those in case IOR below),
493818334Speter	 we start with some combination of logical operations and apply
493918334Speter	 the distributive law followed by the inverse distributive law.
494018334Speter	 Most of the time, this results in no change.  However, if some of
494118334Speter	 the operands are the same or inverses of each other, simplifications
494218334Speter	 will result.
494318334Speter
494418334Speter	 For example, (and (ior A B) (not B)) can occur as the result of
494518334Speter	 expanding a bit field assignment.  When we apply the distributive
494618334Speter	 law to this, we get (ior (and (A (not B))) (and (B (not B)))),
494718334Speter	 which then simplifies to (and (A (not B))).
494818334Speter
494918334Speter	 If we have (and (ior A B) C), apply the distributive law and then
495018334Speter	 the inverse distributive law to see if things simplify.  */
495118334Speter
495218334Speter      if (GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
495318334Speter	{
495418334Speter	  x = apply_distributive_law
495518334Speter	    (gen_binary (GET_CODE (op0), mode,
495618334Speter			 gen_binary (AND, mode, XEXP (op0, 0), op1),
495718334Speter			 gen_binary (AND, mode, XEXP (op0, 1), op1)));
495818334Speter	  if (GET_CODE (x) != AND)
495918334Speter	    return x;
496018334Speter	}
496118334Speter
496218334Speter      if (GET_CODE (op1) == IOR || GET_CODE (op1) == XOR)
496318334Speter	return apply_distributive_law
496418334Speter	  (gen_binary (GET_CODE (op1), mode,
496518334Speter		       gen_binary (AND, mode, XEXP (op1, 0), op0),
496618334Speter		       gen_binary (AND, mode, XEXP (op1, 1), op0)));
496718334Speter
496818334Speter      /* Similarly, taking advantage of the fact that
496918334Speter	 (and (not A) (xor B C)) == (xor (ior A B) (ior A C))  */
497018334Speter
497118334Speter      if (GET_CODE (op0) == NOT && GET_CODE (op1) == XOR)
497218334Speter	return apply_distributive_law
497318334Speter	  (gen_binary (XOR, mode,
497418334Speter		       gen_binary (IOR, mode, XEXP (op0, 0), XEXP (op1, 0)),
497518334Speter		       gen_binary (IOR, mode, XEXP (op0, 0), XEXP (op1, 1))));
497618334Speter
497718334Speter      else if (GET_CODE (op1) == NOT && GET_CODE (op0) == XOR)
497818334Speter	return apply_distributive_law
497918334Speter	  (gen_binary (XOR, mode,
498018334Speter		       gen_binary (IOR, mode, XEXP (op1, 0), XEXP (op0, 0)),
498118334Speter		       gen_binary (IOR, mode, XEXP (op1, 0), XEXP (op0, 1))));
498218334Speter      break;
498318334Speter
498418334Speter    case IOR:
498518334Speter      /* (ior A C) is C if all bits of A that might be nonzero are on in C.  */
498618334Speter      if (GET_CODE (op1) == CONST_INT
498718334Speter	  && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
498818334Speter	  && (nonzero_bits (op0, mode) & ~ INTVAL (op1)) == 0)
498918334Speter	return op1;
499018334Speter
499118334Speter      /* Convert (A & B) | A to A.  */
499218334Speter      if (GET_CODE (op0) == AND
499318334Speter	  && (rtx_equal_p (XEXP (op0, 0), op1)
499418334Speter	      || rtx_equal_p (XEXP (op0, 1), op1))
499518334Speter	  && ! side_effects_p (XEXP (op0, 0))
499618334Speter	  && ! side_effects_p (XEXP (op0, 1)))
499718334Speter	return op1;
499818334Speter
499918334Speter      /* If we have (ior (and A B) C), apply the distributive law and then
500018334Speter	 the inverse distributive law to see if things simplify.  */
500118334Speter
500218334Speter      if (GET_CODE (op0) == AND)
500318334Speter	{
500418334Speter	  x = apply_distributive_law
500518334Speter	    (gen_binary (AND, mode,
500618334Speter			 gen_binary (IOR, mode, XEXP (op0, 0), op1),
500718334Speter			 gen_binary (IOR, mode, XEXP (op0, 1), op1)));
500818334Speter
500918334Speter	  if (GET_CODE (x) != IOR)
501018334Speter	    return x;
501118334Speter	}
501218334Speter
501318334Speter      if (GET_CODE (op1) == AND)
501418334Speter	{
501518334Speter	  x = apply_distributive_law
501618334Speter	    (gen_binary (AND, mode,
501718334Speter			 gen_binary (IOR, mode, XEXP (op1, 0), op0),
501818334Speter			 gen_binary (IOR, mode, XEXP (op1, 1), op0)));
501918334Speter
502018334Speter	  if (GET_CODE (x) != IOR)
502118334Speter	    return x;
502218334Speter	}
502318334Speter
502418334Speter      /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
502518334Speter	 mode size to (rotate A CX).  */
502618334Speter
502718334Speter      if (((GET_CODE (op0) == ASHIFT && GET_CODE (op1) == LSHIFTRT)
502818334Speter	   || (GET_CODE (op1) == ASHIFT && GET_CODE (op0) == LSHIFTRT))
502918334Speter	  && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
503018334Speter	  && GET_CODE (XEXP (op0, 1)) == CONST_INT
503118334Speter	  && GET_CODE (XEXP (op1, 1)) == CONST_INT
503218334Speter	  && (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1))
503318334Speter	      == GET_MODE_BITSIZE (mode)))
503450397Sobrien	return gen_rtx_ROTATE (mode, XEXP (op0, 0),
503550397Sobrien			       (GET_CODE (op0) == ASHIFT
503650397Sobrien				? XEXP (op0, 1) : XEXP (op1, 1)));
503718334Speter
503818334Speter      /* If OP0 is (ashiftrt (plus ...) C), it might actually be
503918334Speter	 a (sign_extend (plus ...)).  If so, OP1 is a CONST_INT, and the PLUS
504018334Speter	 does not affect any of the bits in OP1, it can really be done
504118334Speter	 as a PLUS and we can associate.  We do this by seeing if OP1
504218334Speter	 can be safely shifted left C bits.  */
504318334Speter      if (GET_CODE (op1) == CONST_INT && GET_CODE (op0) == ASHIFTRT
504418334Speter	  && GET_CODE (XEXP (op0, 0)) == PLUS
504518334Speter	  && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
504618334Speter	  && GET_CODE (XEXP (op0, 1)) == CONST_INT
504718334Speter	  && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
504818334Speter	{
504918334Speter	  int count = INTVAL (XEXP (op0, 1));
505018334Speter	  HOST_WIDE_INT mask = INTVAL (op1) << count;
505118334Speter
505218334Speter	  if (mask >> count == INTVAL (op1)
505318334Speter	      && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
505418334Speter	    {
505518334Speter	      SUBST (XEXP (XEXP (op0, 0), 1),
505618334Speter		     GEN_INT (INTVAL (XEXP (XEXP (op0, 0), 1)) | mask));
505718334Speter	      return op0;
505818334Speter	    }
505918334Speter	}
506018334Speter      break;
506118334Speter
506218334Speter    case XOR:
506318334Speter      /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
506418334Speter	 Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
506518334Speter	 (NOT y).  */
506618334Speter      {
506718334Speter	int num_negated = 0;
506818334Speter
506918334Speter	if (GET_CODE (op0) == NOT)
507018334Speter	  num_negated++, op0 = XEXP (op0, 0);
507118334Speter	if (GET_CODE (op1) == NOT)
507218334Speter	  num_negated++, op1 = XEXP (op1, 0);
507318334Speter
507418334Speter	if (num_negated == 2)
507518334Speter	  {
507618334Speter	    SUBST (XEXP (x, 0), op0);
507718334Speter	    SUBST (XEXP (x, 1), op1);
507818334Speter	  }
507918334Speter	else if (num_negated == 1)
508018334Speter	  return gen_unary (NOT, mode, mode, gen_binary (XOR, mode, op0, op1));
508118334Speter      }
508218334Speter
508318334Speter      /* Convert (xor (and A B) B) to (and (not A) B).  The latter may
508418334Speter	 correspond to a machine insn or result in further simplifications
508518334Speter	 if B is a constant.  */
508618334Speter
508718334Speter      if (GET_CODE (op0) == AND
508818334Speter	  && rtx_equal_p (XEXP (op0, 1), op1)
508918334Speter	  && ! side_effects_p (op1))
509018334Speter	return gen_binary (AND, mode,
509118334Speter			   gen_unary (NOT, mode, mode, XEXP (op0, 0)),
509218334Speter			   op1);
509318334Speter
509418334Speter      else if (GET_CODE (op0) == AND
509518334Speter	       && rtx_equal_p (XEXP (op0, 0), op1)
509618334Speter	       && ! side_effects_p (op1))
509718334Speter	return gen_binary (AND, mode,
509818334Speter			   gen_unary (NOT, mode, mode, XEXP (op0, 1)),
509918334Speter			   op1);
510018334Speter
510118334Speter      /* (xor (comparison foo bar) (const_int 1)) can become the reversed
510250397Sobrien	 comparison if STORE_FLAG_VALUE is 1.  */
510350397Sobrien      if (STORE_FLAG_VALUE == 1
510450397Sobrien	  && op1 == const1_rtx
510518334Speter	  && GET_RTX_CLASS (GET_CODE (op0)) == '<'
510618334Speter	  && reversible_comparison_p (op0))
510718334Speter	return gen_rtx_combine (reverse_condition (GET_CODE (op0)),
510818334Speter				mode, XEXP (op0, 0), XEXP (op0, 1));
510918334Speter
511018334Speter      /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
511118334Speter	 is (lt foo (const_int 0)), so we can perform the above
511250397Sobrien	 simplification if STORE_FLAG_VALUE is 1.  */
511318334Speter
511450397Sobrien      if (STORE_FLAG_VALUE == 1
511550397Sobrien	  && op1 == const1_rtx
511618334Speter	  && GET_CODE (op0) == LSHIFTRT
511718334Speter	  && GET_CODE (XEXP (op0, 1)) == CONST_INT
511818334Speter	  && INTVAL (XEXP (op0, 1)) == GET_MODE_BITSIZE (mode) - 1)
511918334Speter	return gen_rtx_combine (GE, mode, XEXP (op0, 0), const0_rtx);
512018334Speter
512118334Speter      /* (xor (comparison foo bar) (const_int sign-bit))
512218334Speter	 when STORE_FLAG_VALUE is the sign bit.  */
512318334Speter      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
512450397Sobrien	  && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
512552284Sobrien	      == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))
512618334Speter	  && op1 == const_true_rtx
512718334Speter	  && GET_RTX_CLASS (GET_CODE (op0)) == '<'
512818334Speter	  && reversible_comparison_p (op0))
512918334Speter	return gen_rtx_combine (reverse_condition (GET_CODE (op0)),
513018334Speter				mode, XEXP (op0, 0), XEXP (op0, 1));
513118334Speter      break;
513250397Sobrien
513350397Sobrien    default:
513450397Sobrien      abort ();
513518334Speter    }
513618334Speter
513718334Speter  return x;
513818334Speter}
513918334Speter
514018334Speter/* We consider ZERO_EXTRACT, SIGN_EXTRACT, and SIGN_EXTEND as "compound
514118334Speter   operations" because they can be replaced with two more basic operations.
514218334Speter   ZERO_EXTEND is also considered "compound" because it can be replaced with
514318334Speter   an AND operation, which is simpler, though only one operation.
514418334Speter
514518334Speter   The function expand_compound_operation is called with an rtx expression
514618334Speter   and will convert it to the appropriate shifts and AND operations,
514718334Speter   simplifying at each stage.
514818334Speter
514918334Speter   The function make_compound_operation is called to convert an expression
515018334Speter   consisting of shifts and ANDs into the equivalent compound expression.
515118334Speter   It is the inverse of this function, loosely speaking.  */
515218334Speter
515318334Speterstatic rtx
515418334Speterexpand_compound_operation (x)
515518334Speter     rtx x;
515618334Speter{
515718334Speter  int pos = 0, len;
515818334Speter  int unsignedp = 0;
515918334Speter  int modewidth;
516018334Speter  rtx tem;
516118334Speter
516218334Speter  switch (GET_CODE (x))
516318334Speter    {
516418334Speter    case ZERO_EXTEND:
516518334Speter      unsignedp = 1;
516618334Speter    case SIGN_EXTEND:
516718334Speter      /* We can't necessarily use a const_int for a multiword mode;
516818334Speter	 it depends on implicitly extending the value.
516918334Speter	 Since we don't know the right way to extend it,
517018334Speter	 we can't tell whether the implicit way is right.
517118334Speter
517218334Speter	 Even for a mode that is no wider than a const_int,
517318334Speter	 we can't win, because we need to sign extend one of its bits through
517418334Speter	 the rest of it, and we don't know which bit.  */
517518334Speter      if (GET_CODE (XEXP (x, 0)) == CONST_INT)
517618334Speter	return x;
517718334Speter
517818334Speter      /* Return if (subreg:MODE FROM 0) is not a safe replacement for
517918334Speter	 (zero_extend:MODE FROM) or (sign_extend:MODE FROM).  It is for any MEM
518018334Speter	 because (SUBREG (MEM...)) is guaranteed to cause the MEM to be
518118334Speter	 reloaded. If not for that, MEM's would very rarely be safe.
518218334Speter
518318334Speter	 Reject MODEs bigger than a word, because we might not be able
518418334Speter	 to reference a two-register group starting with an arbitrary register
518518334Speter	 (and currently gen_lowpart might crash for a SUBREG).  */
518618334Speter
518718334Speter      if (GET_MODE_SIZE (GET_MODE (XEXP (x, 0))) > UNITS_PER_WORD)
518818334Speter	return x;
518918334Speter
519018334Speter      len = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)));
519118334Speter      /* If the inner object has VOIDmode (the only way this can happen
519218334Speter	 is if it is a ASM_OPERANDS), we can't do anything since we don't
519318334Speter	 know how much masking to do.  */
519418334Speter      if (len == 0)
519518334Speter	return x;
519618334Speter
519718334Speter      break;
519818334Speter
519918334Speter    case ZERO_EXTRACT:
520018334Speter      unsignedp = 1;
520118334Speter    case SIGN_EXTRACT:
520218334Speter      /* If the operand is a CLOBBER, just return it.  */
520318334Speter      if (GET_CODE (XEXP (x, 0)) == CLOBBER)
520418334Speter	return XEXP (x, 0);
520518334Speter
520618334Speter      if (GET_CODE (XEXP (x, 1)) != CONST_INT
520718334Speter	  || GET_CODE (XEXP (x, 2)) != CONST_INT
520818334Speter	  || GET_MODE (XEXP (x, 0)) == VOIDmode)
520918334Speter	return x;
521018334Speter
521118334Speter      len = INTVAL (XEXP (x, 1));
521218334Speter      pos = INTVAL (XEXP (x, 2));
521318334Speter
521418334Speter      /* If this goes outside the object being extracted, replace the object
521518334Speter	 with a (use (mem ...)) construct that only combine understands
521618334Speter	 and is used only for this purpose.  */
521718334Speter      if (len + pos > GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))))
521850397Sobrien	SUBST (XEXP (x, 0), gen_rtx_USE (GET_MODE (x), XEXP (x, 0)));
521918334Speter
522018334Speter      if (BITS_BIG_ENDIAN)
522118334Speter	pos = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - len - pos;
522218334Speter
522318334Speter      break;
522418334Speter
522518334Speter    default:
522618334Speter      return x;
522718334Speter    }
522818334Speter
522950397Sobrien  /* We can optimize some special cases of ZERO_EXTEND.  */
523050397Sobrien  if (GET_CODE (x) == ZERO_EXTEND)
523150397Sobrien    {
523250397Sobrien      /* (zero_extend:DI (truncate:SI foo:DI)) is just foo:DI if we
523350397Sobrien         know that the last value didn't have any inappropriate bits
523450397Sobrien         set.  */
523550397Sobrien      if (GET_CODE (XEXP (x, 0)) == TRUNCATE
523650397Sobrien	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == GET_MODE (x)
523750397Sobrien	  && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
523850397Sobrien	  && (nonzero_bits (XEXP (XEXP (x, 0), 0), GET_MODE (x))
523950397Sobrien	      & ~ GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
524050397Sobrien	return XEXP (XEXP (x, 0), 0);
524150397Sobrien
524250397Sobrien      /* Likewise for (zero_extend:DI (subreg:SI foo:DI 0)).  */
524350397Sobrien      if (GET_CODE (XEXP (x, 0)) == SUBREG
524450397Sobrien	  && GET_MODE (SUBREG_REG (XEXP (x, 0))) == GET_MODE (x)
524550397Sobrien	  && subreg_lowpart_p (XEXP (x, 0))
524650397Sobrien	  && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
524750397Sobrien	  && (nonzero_bits (SUBREG_REG (XEXP (x, 0)), GET_MODE (x))
524850397Sobrien	      & ~ GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
524950397Sobrien	return SUBREG_REG (XEXP (x, 0));
525050397Sobrien
525150397Sobrien      /* (zero_extend:DI (truncate:SI foo:DI)) is just foo:DI when foo
525250397Sobrien         is a comparison and STORE_FLAG_VALUE permits.  This is like
525350397Sobrien         the first case, but it works even when GET_MODE (x) is larger
525450397Sobrien         than HOST_WIDE_INT.  */
525550397Sobrien      if (GET_CODE (XEXP (x, 0)) == TRUNCATE
525650397Sobrien	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == GET_MODE (x)
525750397Sobrien	  && GET_RTX_CLASS (GET_CODE (XEXP (XEXP (x, 0), 0))) == '<'
525850397Sobrien	  && (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
525950397Sobrien	      <= HOST_BITS_PER_WIDE_INT)
526050397Sobrien 	  && ((HOST_WIDE_INT) STORE_FLAG_VALUE
526150397Sobrien	      & ~ GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
526250397Sobrien	return XEXP (XEXP (x, 0), 0);
526350397Sobrien
526450397Sobrien      /* Likewise for (zero_extend:DI (subreg:SI foo:DI 0)).  */
526550397Sobrien      if (GET_CODE (XEXP (x, 0)) == SUBREG
526650397Sobrien	  && GET_MODE (SUBREG_REG (XEXP (x, 0))) == GET_MODE (x)
526750397Sobrien	  && subreg_lowpart_p (XEXP (x, 0))
526850397Sobrien	  && GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0)))) == '<'
526950397Sobrien	  && (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
527050397Sobrien	      <= HOST_BITS_PER_WIDE_INT)
527150397Sobrien	  && ((HOST_WIDE_INT) STORE_FLAG_VALUE
527250397Sobrien	      & ~ GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
527350397Sobrien	return SUBREG_REG (XEXP (x, 0));
527450397Sobrien
527550397Sobrien      /* If sign extension is cheaper than zero extension, then use it
527650397Sobrien	 if we know that no extraneous bits are set, and that the high
527750397Sobrien	 bit is not set.  */
527850397Sobrien      if (flag_expensive_optimizations
527950397Sobrien	  && ((GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
528050397Sobrien	       && ((nonzero_bits (XEXP (x, 0), GET_MODE (x))
528150397Sobrien		    & ~ (((unsigned HOST_WIDE_INT)
528250397Sobrien			  GET_MODE_MASK (GET_MODE (XEXP (x, 0))))
528350397Sobrien			 >> 1))
528450397Sobrien		   == 0))
528550397Sobrien	      || (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
528650397Sobrien		  && (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
528750397Sobrien		      <= HOST_BITS_PER_WIDE_INT)
528850397Sobrien		  && (((HOST_WIDE_INT) STORE_FLAG_VALUE
528950397Sobrien		       & ~ (((unsigned HOST_WIDE_INT)
529050397Sobrien			     GET_MODE_MASK (GET_MODE (XEXP (x, 0))))
529150397Sobrien			    >> 1))
529250397Sobrien		      == 0))))
529350397Sobrien	{
529450397Sobrien	  rtx temp = gen_rtx_SIGN_EXTEND (GET_MODE (x), XEXP (x, 0));
529550397Sobrien
529650397Sobrien	  if (rtx_cost (temp, SET) < rtx_cost (x, SET))
529750397Sobrien	    return expand_compound_operation (temp);
529850397Sobrien	}
529950397Sobrien    }
530050397Sobrien
530118334Speter  /* If we reach here, we want to return a pair of shifts.  The inner
530218334Speter     shift is a left shift of BITSIZE - POS - LEN bits.  The outer
530318334Speter     shift is a right shift of BITSIZE - LEN bits.  It is arithmetic or
530418334Speter     logical depending on the value of UNSIGNEDP.
530518334Speter
530618334Speter     If this was a ZERO_EXTEND or ZERO_EXTRACT, this pair of shifts will be
530718334Speter     converted into an AND of a shift.
530818334Speter
530918334Speter     We must check for the case where the left shift would have a negative
531018334Speter     count.  This can happen in a case like (x >> 31) & 255 on machines
531118334Speter     that can't shift by a constant.  On those machines, we would first
531218334Speter     combine the shift with the AND to produce a variable-position
531318334Speter     extraction.  Then the constant of 31 would be substituted in to produce
531418334Speter     a such a position.  */
531518334Speter
531618334Speter  modewidth = GET_MODE_BITSIZE (GET_MODE (x));
531718334Speter  if (modewidth >= pos - len)
531818334Speter    tem = simplify_shift_const (NULL_RTX, unsignedp ? LSHIFTRT : ASHIFTRT,
531918334Speter				GET_MODE (x),
532018334Speter				simplify_shift_const (NULL_RTX, ASHIFT,
532118334Speter						      GET_MODE (x),
532218334Speter						      XEXP (x, 0),
532318334Speter						      modewidth - pos - len),
532418334Speter				modewidth - len);
532518334Speter
532618334Speter  else if (unsignedp && len < HOST_BITS_PER_WIDE_INT)
532718334Speter    tem = simplify_and_const_int (NULL_RTX, GET_MODE (x),
532818334Speter				  simplify_shift_const (NULL_RTX, LSHIFTRT,
532918334Speter							GET_MODE (x),
533018334Speter							XEXP (x, 0), pos),
533118334Speter				  ((HOST_WIDE_INT) 1 << len) - 1);
533218334Speter  else
533318334Speter    /* Any other cases we can't handle.  */
533418334Speter    return x;
533518334Speter
533618334Speter
533718334Speter  /* If we couldn't do this for some reason, return the original
533818334Speter     expression.  */
533918334Speter  if (GET_CODE (tem) == CLOBBER)
534018334Speter    return x;
534118334Speter
534218334Speter  return tem;
534318334Speter}
534418334Speter
534518334Speter/* X is a SET which contains an assignment of one object into
534618334Speter   a part of another (such as a bit-field assignment, STRICT_LOW_PART,
534718334Speter   or certain SUBREGS). If possible, convert it into a series of
534818334Speter   logical operations.
534918334Speter
535018334Speter   We half-heartedly support variable positions, but do not at all
535118334Speter   support variable lengths.  */
535218334Speter
535318334Speterstatic rtx
535418334Speterexpand_field_assignment (x)
535518334Speter     rtx x;
535618334Speter{
535718334Speter  rtx inner;
535850397Sobrien  rtx pos;			/* Always counts from low bit.  */
535918334Speter  int len;
536018334Speter  rtx mask;
536118334Speter  enum machine_mode compute_mode;
536218334Speter
536318334Speter  /* Loop until we find something we can't simplify.  */
536418334Speter  while (1)
536518334Speter    {
536618334Speter      if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART
536718334Speter	  && GET_CODE (XEXP (SET_DEST (x), 0)) == SUBREG)
536818334Speter	{
536918334Speter	  inner = SUBREG_REG (XEXP (SET_DEST (x), 0));
537018334Speter	  len = GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0)));
537150397Sobrien	  pos = GEN_INT (BITS_PER_WORD * SUBREG_WORD (XEXP (SET_DEST (x), 0)));
537218334Speter	}
537318334Speter      else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
537418334Speter	       && GET_CODE (XEXP (SET_DEST (x), 1)) == CONST_INT)
537518334Speter	{
537618334Speter	  inner = XEXP (SET_DEST (x), 0);
537718334Speter	  len = INTVAL (XEXP (SET_DEST (x), 1));
537818334Speter	  pos = XEXP (SET_DEST (x), 2);
537918334Speter
538018334Speter	  /* If the position is constant and spans the width of INNER,
538118334Speter	     surround INNER  with a USE to indicate this.  */
538218334Speter	  if (GET_CODE (pos) == CONST_INT
538318334Speter	      && INTVAL (pos) + len > GET_MODE_BITSIZE (GET_MODE (inner)))
538450397Sobrien	    inner = gen_rtx_USE (GET_MODE (SET_DEST (x)), inner);
538518334Speter
538618334Speter	  if (BITS_BIG_ENDIAN)
538718334Speter	    {
538818334Speter	      if (GET_CODE (pos) == CONST_INT)
538918334Speter		pos = GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner)) - len
539018334Speter			       - INTVAL (pos));
539118334Speter	      else if (GET_CODE (pos) == MINUS
539218334Speter		       && GET_CODE (XEXP (pos, 1)) == CONST_INT
539318334Speter		       && (INTVAL (XEXP (pos, 1))
539418334Speter			   == GET_MODE_BITSIZE (GET_MODE (inner)) - len))
539518334Speter		/* If position is ADJUST - X, new position is X.  */
539618334Speter		pos = XEXP (pos, 0);
539718334Speter	      else
539818334Speter		pos = gen_binary (MINUS, GET_MODE (pos),
539918334Speter				  GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner))
540018334Speter					   - len),
540118334Speter				  pos);
540218334Speter	    }
540318334Speter	}
540418334Speter
540518334Speter      /* A SUBREG between two modes that occupy the same numbers of words
540618334Speter	 can be done by moving the SUBREG to the source.  */
540718334Speter      else if (GET_CODE (SET_DEST (x)) == SUBREG
540818334Speter	       && (((GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
540918334Speter		     + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
541018334Speter		   == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x))))
541118334Speter			+ (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
541218334Speter	{
541350397Sobrien	  x = gen_rtx_SET (VOIDmode, SUBREG_REG (SET_DEST (x)),
541450397Sobrien			   gen_lowpart_for_combine (GET_MODE (SUBREG_REG (SET_DEST (x))),
541550397Sobrien						    SET_SRC (x)));
541618334Speter	  continue;
541718334Speter	}
541818334Speter      else
541918334Speter	break;
542018334Speter
542118334Speter      while (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner))
542218334Speter	inner = SUBREG_REG (inner);
542318334Speter
542418334Speter      compute_mode = GET_MODE (inner);
542518334Speter
542652284Sobrien      /* Don't attempt bitwise arithmetic on non-integral modes.  */
542752284Sobrien      if (! INTEGRAL_MODE_P (compute_mode))
542852284Sobrien	{
542952284Sobrien	  enum machine_mode imode;
543052284Sobrien
543152284Sobrien	  /* Something is probably seriously wrong if this matches.  */
543252284Sobrien	  if (! FLOAT_MODE_P (compute_mode))
543352284Sobrien	    break;
543452284Sobrien
543552284Sobrien	  /* Try to find an integral mode to pun with.  */
543652284Sobrien	  imode = mode_for_size (GET_MODE_BITSIZE (compute_mode), MODE_INT, 0);
543752284Sobrien	  if (imode == BLKmode)
543852284Sobrien	    break;
543952284Sobrien
544052284Sobrien	  compute_mode = imode;
544152284Sobrien	  inner = gen_lowpart_for_combine (imode, inner);
544252284Sobrien	}
544352284Sobrien
544418334Speter      /* Compute a mask of LEN bits, if we can do this on the host machine.  */
544518334Speter      if (len < HOST_BITS_PER_WIDE_INT)
544618334Speter	mask = GEN_INT (((HOST_WIDE_INT) 1 << len) - 1);
544718334Speter      else
544818334Speter	break;
544918334Speter
545018334Speter      /* Now compute the equivalent expression.  Make a copy of INNER
545118334Speter	 for the SET_DEST in case it is a MEM into which we will substitute;
545218334Speter	 we don't want shared RTL in that case.  */
545350397Sobrien      x = gen_rtx_SET (VOIDmode, copy_rtx (inner),
545450397Sobrien		       gen_binary (IOR, compute_mode,
545550397Sobrien				   gen_binary (AND, compute_mode,
545650397Sobrien					       gen_unary (NOT, compute_mode,
545750397Sobrien							  compute_mode,
545850397Sobrien							  gen_binary (ASHIFT,
545950397Sobrien								      compute_mode,
546050397Sobrien								      mask, pos)),
546150397Sobrien					       inner),
546250397Sobrien				   gen_binary (ASHIFT, compute_mode,
546350397Sobrien					       gen_binary (AND, compute_mode,
546450397Sobrien							   gen_lowpart_for_combine
546550397Sobrien							   (compute_mode,
546650397Sobrien							    SET_SRC (x)),
546750397Sobrien							   mask),
546850397Sobrien					       pos)));
546918334Speter    }
547018334Speter
547118334Speter  return x;
547218334Speter}
547318334Speter
547418334Speter/* Return an RTX for a reference to LEN bits of INNER.  If POS_RTX is nonzero,
547518334Speter   it is an RTX that represents a variable starting position; otherwise,
547618334Speter   POS is the (constant) starting bit position (counted from the LSB).
547718334Speter
547818334Speter   INNER may be a USE.  This will occur when we started with a bitfield
547918334Speter   that went outside the boundary of the object in memory, which is
548018334Speter   allowed on most machines.  To isolate this case, we produce a USE
548118334Speter   whose mode is wide enough and surround the MEM with it.  The only
548218334Speter   code that understands the USE is this routine.  If it is not removed,
548318334Speter   it will cause the resulting insn not to match.
548418334Speter
548518334Speter   UNSIGNEDP is non-zero for an unsigned reference and zero for a
548618334Speter   signed reference.
548718334Speter
548818334Speter   IN_DEST is non-zero if this is a reference in the destination of a
548918334Speter   SET.  This is used when a ZERO_ or SIGN_EXTRACT isn't needed.  If non-zero,
549018334Speter   a STRICT_LOW_PART will be used, if zero, ZERO_EXTEND or SIGN_EXTEND will
549118334Speter   be used.
549218334Speter
549318334Speter   IN_COMPARE is non-zero if we are in a COMPARE.  This means that a
549418334Speter   ZERO_EXTRACT should be built even for bits starting at bit 0.
549518334Speter
549650397Sobrien   MODE is the desired mode of the result (if IN_DEST == 0).
549718334Speter
549850397Sobrien   The result is an RTX for the extraction or NULL_RTX if the target
549950397Sobrien   can't handle it.  */
550050397Sobrien
550118334Speterstatic rtx
550218334Spetermake_extraction (mode, inner, pos, pos_rtx, len,
550318334Speter		 unsignedp, in_dest, in_compare)
550418334Speter     enum machine_mode mode;
550518334Speter     rtx inner;
550618334Speter     int pos;
550718334Speter     rtx pos_rtx;
550818334Speter     int len;
550918334Speter     int unsignedp;
551018334Speter     int in_dest, in_compare;
551118334Speter{
551218334Speter  /* This mode describes the size of the storage area
551318334Speter     to fetch the overall value from.  Within that, we
551418334Speter     ignore the POS lowest bits, etc.  */
551518334Speter  enum machine_mode is_mode = GET_MODE (inner);
551618334Speter  enum machine_mode inner_mode;
551750397Sobrien  enum machine_mode wanted_inner_mode = byte_mode;
551850397Sobrien  enum machine_mode wanted_inner_reg_mode = word_mode;
551918334Speter  enum machine_mode pos_mode = word_mode;
552018334Speter  enum machine_mode extraction_mode = word_mode;
552118334Speter  enum machine_mode tmode = mode_for_size (len, MODE_INT, 1);
552218334Speter  int spans_byte = 0;
552318334Speter  rtx new = 0;
552418334Speter  rtx orig_pos_rtx = pos_rtx;
552518334Speter  int orig_pos;
552618334Speter
552718334Speter  /* Get some information about INNER and get the innermost object.  */
552818334Speter  if (GET_CODE (inner) == USE)
552918334Speter    /* (use:SI (mem:QI foo)) stands for (mem:SI foo).  */
553018334Speter    /* We don't need to adjust the position because we set up the USE
553118334Speter       to pretend that it was a full-word object.  */
553218334Speter    spans_byte = 1, inner = XEXP (inner, 0);
553318334Speter  else if (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner))
553418334Speter    {
553518334Speter      /* If going from (subreg:SI (mem:QI ...)) to (mem:QI ...),
553618334Speter	 consider just the QI as the memory to extract from.
553718334Speter	 The subreg adds or removes high bits; its mode is
553818334Speter	 irrelevant to the meaning of this extraction,
553918334Speter	 since POS and LEN count from the lsb.  */
554018334Speter      if (GET_CODE (SUBREG_REG (inner)) == MEM)
554118334Speter	is_mode = GET_MODE (SUBREG_REG (inner));
554218334Speter      inner = SUBREG_REG (inner);
554318334Speter    }
554418334Speter
554518334Speter  inner_mode = GET_MODE (inner);
554618334Speter
554718334Speter  if (pos_rtx && GET_CODE (pos_rtx) == CONST_INT)
554818334Speter    pos = INTVAL (pos_rtx), pos_rtx = 0;
554918334Speter
555018334Speter  /* See if this can be done without an extraction.  We never can if the
555118334Speter     width of the field is not the same as that of some integer mode. For
555218334Speter     registers, we can only avoid the extraction if the position is at the
555318334Speter     low-order bit and this is either not in the destination or we have the
555418334Speter     appropriate STRICT_LOW_PART operation available.
555518334Speter
555618334Speter     For MEM, we can avoid an extract if the field starts on an appropriate
555718334Speter     boundary and we can change the mode of the memory reference.  However,
555818334Speter     we cannot directly access the MEM if we have a USE and the underlying
555918334Speter     MEM is not TMODE.  This combination means that MEM was being used in a
556018334Speter     context where bits outside its mode were being referenced; that is only
556118334Speter     valid in bit-field insns.  */
556218334Speter
556318334Speter  if (tmode != BLKmode
556418334Speter      && ! (spans_byte && inner_mode != tmode)
556550397Sobrien      && ((pos_rtx == 0 && (pos % BITS_PER_WORD) == 0
556650397Sobrien	   && GET_CODE (inner) != MEM
556718334Speter	   && (! in_dest
556818334Speter	       || (GET_CODE (inner) == REG
556918334Speter		   && (movstrict_optab->handlers[(int) tmode].insn_code
557018334Speter		       != CODE_FOR_nothing))))
557118334Speter	  || (GET_CODE (inner) == MEM && pos_rtx == 0
557218334Speter	      && (pos
557318334Speter		  % (STRICT_ALIGNMENT ? GET_MODE_ALIGNMENT (tmode)
557418334Speter		     : BITS_PER_UNIT)) == 0
557518334Speter	      /* We can't do this if we are widening INNER_MODE (it
557618334Speter		 may not be aligned, for one thing).  */
557718334Speter	      && GET_MODE_BITSIZE (inner_mode) >= GET_MODE_BITSIZE (tmode)
557818334Speter	      && (inner_mode == tmode
557918334Speter		  || (! mode_dependent_address_p (XEXP (inner, 0))
558018334Speter		      && ! MEM_VOLATILE_P (inner))))))
558118334Speter    {
558218334Speter      /* If INNER is a MEM, make a new MEM that encompasses just the desired
558318334Speter	 field.  If the original and current mode are the same, we need not
558418334Speter	 adjust the offset.  Otherwise, we do if bytes big endian.
558518334Speter
558650397Sobrien	 If INNER is not a MEM, get a piece consisting of just the field
558750397Sobrien	 of interest (in this case POS % BITS_PER_WORD must be 0).  */
558818334Speter
558918334Speter      if (GET_CODE (inner) == MEM)
559018334Speter	{
559118334Speter	  int offset;
559218334Speter	  /* POS counts from lsb, but make OFFSET count in memory order.  */
559318334Speter	  if (BYTES_BIG_ENDIAN)
559418334Speter	    offset = (GET_MODE_BITSIZE (is_mode) - len - pos) / BITS_PER_UNIT;
559518334Speter	  else
559618334Speter	    offset = pos / BITS_PER_UNIT;
559718334Speter
559850397Sobrien	  new = gen_rtx_MEM (tmode, plus_constant (XEXP (inner, 0), offset));
559918334Speter	  RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (inner);
560052284Sobrien	  MEM_COPY_ATTRIBUTES (new, inner);
560118334Speter	}
560218334Speter      else if (GET_CODE (inner) == REG)
560318334Speter	{
560418334Speter	  /* We can't call gen_lowpart_for_combine here since we always want
560518334Speter	     a SUBREG and it would sometimes return a new hard register.  */
560618334Speter	  if (tmode != inner_mode)
560750397Sobrien	    new = gen_rtx_SUBREG (tmode, inner,
560850397Sobrien				  (WORDS_BIG_ENDIAN
560950397Sobrien				   && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD
561050397Sobrien				   ? (((GET_MODE_SIZE (inner_mode)
561150397Sobrien					- GET_MODE_SIZE (tmode))
561250397Sobrien				       / UNITS_PER_WORD)
561350397Sobrien				      - pos / BITS_PER_WORD)
561450397Sobrien				   : pos / BITS_PER_WORD));
561518334Speter	  else
561618334Speter	    new = inner;
561718334Speter	}
561818334Speter      else
561918334Speter	new = force_to_mode (inner, tmode,
562018334Speter			     len >= HOST_BITS_PER_WIDE_INT
562118334Speter			     ? GET_MODE_MASK (tmode)
562218334Speter			     : ((HOST_WIDE_INT) 1 << len) - 1,
562318334Speter			     NULL_RTX, 0);
562418334Speter
562518334Speter      /* If this extraction is going into the destination of a SET,
562618334Speter	 make a STRICT_LOW_PART unless we made a MEM.  */
562718334Speter
562818334Speter      if (in_dest)
562918334Speter	return (GET_CODE (new) == MEM ? new
563018334Speter		: (GET_CODE (new) != SUBREG
563150397Sobrien		   ? gen_rtx_CLOBBER (tmode, const0_rtx)
563218334Speter		   : gen_rtx_combine (STRICT_LOW_PART, VOIDmode, new)));
563318334Speter
563418334Speter      /* Otherwise, sign- or zero-extend unless we already are in the
563518334Speter	 proper mode.  */
563618334Speter
563718334Speter      return (mode == tmode ? new
563818334Speter	      : gen_rtx_combine (unsignedp ? ZERO_EXTEND : SIGN_EXTEND,
563918334Speter				 mode, new));
564018334Speter    }
564118334Speter
564218334Speter  /* Unless this is a COMPARE or we have a funny memory reference,
564318334Speter     don't do anything with zero-extending field extracts starting at
564418334Speter     the low-order bit since they are simple AND operations.  */
564518334Speter  if (pos_rtx == 0 && pos == 0 && ! in_dest
564618334Speter      && ! in_compare && ! spans_byte && unsignedp)
564718334Speter    return 0;
564818334Speter
564918334Speter  /* Unless we are allowed to span bytes, reject this if we would be
565018334Speter     spanning bytes or if the position is not a constant and the length
565118334Speter     is not 1.  In all other cases, we would only be going outside
565218334Speter     out object in cases when an original shift would have been
565318334Speter     undefined.  */
565418334Speter  if (! spans_byte
565518334Speter      && ((pos_rtx == 0 && pos + len > GET_MODE_BITSIZE (is_mode))
565618334Speter	  || (pos_rtx != 0 && len != 1)))
565718334Speter    return 0;
565818334Speter
565950397Sobrien  /* Get the mode to use should INNER not be a MEM, the mode for the position,
566018334Speter     and the mode for the result.  */
566118334Speter#ifdef HAVE_insv
566218334Speter  if (in_dest)
566318334Speter    {
566452284Sobrien      wanted_inner_reg_mode
566552284Sobrien	= (insn_operand_mode[(int) CODE_FOR_insv][0] == VOIDmode
566652284Sobrien	   ? word_mode
566752284Sobrien	   : insn_operand_mode[(int) CODE_FOR_insv][0]);
566852284Sobrien      pos_mode = (insn_operand_mode[(int) CODE_FOR_insv][2] == VOIDmode
566952284Sobrien		  ? word_mode : insn_operand_mode[(int) CODE_FOR_insv][2]);
567052284Sobrien      extraction_mode = (insn_operand_mode[(int) CODE_FOR_insv][3] == VOIDmode
567152284Sobrien			 ? word_mode
567252284Sobrien			 : insn_operand_mode[(int) CODE_FOR_insv][3]);
567318334Speter    }
567418334Speter#endif
567518334Speter
567618334Speter#ifdef HAVE_extzv
567718334Speter  if (! in_dest && unsignedp)
567818334Speter    {
567952284Sobrien      wanted_inner_reg_mode
568052284Sobrien	= (insn_operand_mode[(int) CODE_FOR_extzv][1] == VOIDmode
568152284Sobrien	   ? word_mode
568252284Sobrien	   : insn_operand_mode[(int) CODE_FOR_extzv][1]);
568352284Sobrien      pos_mode = (insn_operand_mode[(int) CODE_FOR_extzv][3] == VOIDmode
568452284Sobrien		  ? word_mode : insn_operand_mode[(int) CODE_FOR_extzv][3]);
568552284Sobrien      extraction_mode = (insn_operand_mode[(int) CODE_FOR_extzv][0] == VOIDmode
568652284Sobrien			 ? word_mode
568752284Sobrien			 : insn_operand_mode[(int) CODE_FOR_extzv][0]);
568818334Speter    }
568918334Speter#endif
569018334Speter
569118334Speter#ifdef HAVE_extv
569218334Speter  if (! in_dest && ! unsignedp)
569318334Speter    {
569452284Sobrien      wanted_inner_reg_mode
569552284Sobrien	= (insn_operand_mode[(int) CODE_FOR_extv][1] == VOIDmode
569652284Sobrien	   ? word_mode
569752284Sobrien	   : insn_operand_mode[(int) CODE_FOR_extv][1]);
569852284Sobrien      pos_mode = (insn_operand_mode[(int) CODE_FOR_extv][3] == VOIDmode
569952284Sobrien		  ? word_mode : insn_operand_mode[(int) CODE_FOR_extv][3]);
570052284Sobrien      extraction_mode = (insn_operand_mode[(int) CODE_FOR_extv][0] == VOIDmode
570152284Sobrien			 ? word_mode
570252284Sobrien			 : insn_operand_mode[(int) CODE_FOR_extv][0]);
570318334Speter    }
570418334Speter#endif
570518334Speter
570618334Speter  /* Never narrow an object, since that might not be safe.  */
570718334Speter
570818334Speter  if (mode != VOIDmode
570918334Speter      && GET_MODE_SIZE (extraction_mode) < GET_MODE_SIZE (mode))
571018334Speter    extraction_mode = mode;
571118334Speter
571218334Speter  if (pos_rtx && GET_MODE (pos_rtx) != VOIDmode
571318334Speter      && GET_MODE_SIZE (pos_mode) < GET_MODE_SIZE (GET_MODE (pos_rtx)))
571418334Speter    pos_mode = GET_MODE (pos_rtx);
571518334Speter
571650397Sobrien  /* If this is not from memory, the desired mode is wanted_inner_reg_mode;
571750397Sobrien     if we have to change the mode of memory and cannot, the desired mode is
571850397Sobrien     EXTRACTION_MODE.  */
571950397Sobrien  if (GET_CODE (inner) != MEM)
572050397Sobrien    wanted_inner_mode = wanted_inner_reg_mode;
572150397Sobrien  else if (inner_mode != wanted_inner_mode
572250397Sobrien	   && (mode_dependent_address_p (XEXP (inner, 0))
572350397Sobrien	       || MEM_VOLATILE_P (inner)))
572450397Sobrien    wanted_inner_mode = extraction_mode;
572518334Speter
572618334Speter  orig_pos = pos;
572718334Speter
572818334Speter  if (BITS_BIG_ENDIAN)
572918334Speter    {
573050397Sobrien      /* POS is passed as if BITS_BIG_ENDIAN == 0, so we need to convert it to
573150397Sobrien	 BITS_BIG_ENDIAN style.  If position is constant, compute new
573250397Sobrien	 position.  Otherwise, build subtraction.
573350397Sobrien	 Note that POS is relative to the mode of the original argument.
573450397Sobrien	 If it's a MEM we need to recompute POS relative to that.
573550397Sobrien	 However, if we're extracting from (or inserting into) a register,
573650397Sobrien	 we want to recompute POS relative to wanted_inner_mode.  */
573750397Sobrien      int width = (GET_CODE (inner) == MEM
573850397Sobrien		   ? GET_MODE_BITSIZE (is_mode)
573950397Sobrien		   : GET_MODE_BITSIZE (wanted_inner_mode));
574050397Sobrien
574118334Speter      if (pos_rtx == 0)
574250397Sobrien	pos = width - len - pos;
574318334Speter      else
574418334Speter	pos_rtx
574518334Speter	  = gen_rtx_combine (MINUS, GET_MODE (pos_rtx),
574650397Sobrien			     GEN_INT (width - len), pos_rtx);
574750397Sobrien      /* POS may be less than 0 now, but we check for that below.
574850397Sobrien	 Note that it can only be less than 0 if GET_CODE (inner) != MEM.  */
574918334Speter    }
575018334Speter
575118334Speter  /* If INNER has a wider mode, make it smaller.  If this is a constant
575218334Speter     extract, try to adjust the byte to point to the byte containing
575318334Speter     the value.  */
575450397Sobrien  if (wanted_inner_mode != VOIDmode
575550397Sobrien      && GET_MODE_SIZE (wanted_inner_mode) < GET_MODE_SIZE (is_mode)
575618334Speter      && ((GET_CODE (inner) == MEM
575750397Sobrien	   && (inner_mode == wanted_inner_mode
575818334Speter	       || (! mode_dependent_address_p (XEXP (inner, 0))
575918334Speter		   && ! MEM_VOLATILE_P (inner))))))
576018334Speter    {
576118334Speter      int offset = 0;
576218334Speter
576318334Speter      /* The computations below will be correct if the machine is big
576418334Speter	 endian in both bits and bytes or little endian in bits and bytes.
576518334Speter	 If it is mixed, we must adjust.  */
576618334Speter
576718334Speter      /* If bytes are big endian and we had a paradoxical SUBREG, we must
576850397Sobrien	 adjust OFFSET to compensate.  */
576918334Speter      if (BYTES_BIG_ENDIAN
577018334Speter	  && ! spans_byte
577118334Speter	  && GET_MODE_SIZE (inner_mode) < GET_MODE_SIZE (is_mode))
577218334Speter	offset -= GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (inner_mode);
577318334Speter
577418334Speter      /* If this is a constant position, we can move to the desired byte.  */
577518334Speter      if (pos_rtx == 0)
577618334Speter	{
577718334Speter	  offset += pos / BITS_PER_UNIT;
577850397Sobrien	  pos %= GET_MODE_BITSIZE (wanted_inner_mode);
577918334Speter	}
578018334Speter
578118334Speter      if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN
578218334Speter	  && ! spans_byte
578350397Sobrien	  && is_mode != wanted_inner_mode)
578418334Speter	offset = (GET_MODE_SIZE (is_mode)
578550397Sobrien		  - GET_MODE_SIZE (wanted_inner_mode) - offset);
578618334Speter
578750397Sobrien      if (offset != 0 || inner_mode != wanted_inner_mode)
578818334Speter	{
578950397Sobrien	  rtx newmem = gen_rtx_MEM (wanted_inner_mode,
579050397Sobrien				    plus_constant (XEXP (inner, 0), offset));
579118334Speter	  RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (inner);
579252284Sobrien	  MEM_COPY_ATTRIBUTES (newmem, inner);
579318334Speter	  inner = newmem;
579418334Speter	}
579518334Speter    }
579618334Speter
579750397Sobrien  /* If INNER is not memory, we can always get it into the proper mode.  If we
579850397Sobrien     are changing its mode, POS must be a constant and smaller than the size
579950397Sobrien     of the new mode.  */
580018334Speter  else if (GET_CODE (inner) != MEM)
580150397Sobrien    {
580250397Sobrien      if (GET_MODE (inner) != wanted_inner_mode
580350397Sobrien	  && (pos_rtx != 0
580450397Sobrien	      || orig_pos + len > GET_MODE_BITSIZE (wanted_inner_mode)))
580550397Sobrien	return 0;
580618334Speter
580750397Sobrien      inner = force_to_mode (inner, wanted_inner_mode,
580850397Sobrien			     pos_rtx
580950397Sobrien			     || len + orig_pos >= HOST_BITS_PER_WIDE_INT
581050397Sobrien			     ? GET_MODE_MASK (wanted_inner_mode)
581150397Sobrien			     : (((HOST_WIDE_INT) 1 << len) - 1) << orig_pos,
581250397Sobrien			     NULL_RTX, 0);
581350397Sobrien    }
581450397Sobrien
581518334Speter  /* Adjust mode of POS_RTX, if needed.  If we want a wider mode, we
581618334Speter     have to zero extend.  Otherwise, we can just use a SUBREG.  */
581718334Speter  if (pos_rtx != 0
581818334Speter      && GET_MODE_SIZE (pos_mode) > GET_MODE_SIZE (GET_MODE (pos_rtx)))
581918334Speter    pos_rtx = gen_rtx_combine (ZERO_EXTEND, pos_mode, pos_rtx);
582018334Speter  else if (pos_rtx != 0
582118334Speter	   && GET_MODE_SIZE (pos_mode) < GET_MODE_SIZE (GET_MODE (pos_rtx)))
582218334Speter    pos_rtx = gen_lowpart_for_combine (pos_mode, pos_rtx);
582318334Speter
582418334Speter  /* Make POS_RTX unless we already have it and it is correct.  If we don't
582518334Speter     have a POS_RTX but we do have an ORIG_POS_RTX, the latter must
582650397Sobrien     be a CONST_INT.  */
582718334Speter  if (pos_rtx == 0 && orig_pos_rtx != 0 && INTVAL (orig_pos_rtx) == pos)
582818334Speter    pos_rtx = orig_pos_rtx;
582918334Speter
583018334Speter  else if (pos_rtx == 0)
583118334Speter    pos_rtx = GEN_INT (pos);
583218334Speter
583318334Speter  /* Make the required operation.  See if we can use existing rtx.  */
583418334Speter  new = gen_rtx_combine (unsignedp ? ZERO_EXTRACT : SIGN_EXTRACT,
583518334Speter			 extraction_mode, inner, GEN_INT (len), pos_rtx);
583618334Speter  if (! in_dest)
583718334Speter    new = gen_lowpart_for_combine (mode, new);
583818334Speter
583918334Speter  return new;
584018334Speter}
584118334Speter
584218334Speter/* See if X contains an ASHIFT of COUNT or more bits that can be commuted
584318334Speter   with any other operations in X.  Return X without that shift if so.  */
584418334Speter
584518334Speterstatic rtx
584618334Speterextract_left_shift (x, count)
584718334Speter     rtx x;
584818334Speter     int count;
584918334Speter{
585018334Speter  enum rtx_code code = GET_CODE (x);
585118334Speter  enum machine_mode mode = GET_MODE (x);
585218334Speter  rtx tem;
585318334Speter
585418334Speter  switch (code)
585518334Speter    {
585618334Speter    case ASHIFT:
585718334Speter      /* This is the shift itself.  If it is wide enough, we will return
585818334Speter	 either the value being shifted if the shift count is equal to
585918334Speter	 COUNT or a shift for the difference.  */
586018334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
586118334Speter	  && INTVAL (XEXP (x, 1)) >= count)
586218334Speter	return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (x, 0),
586318334Speter				     INTVAL (XEXP (x, 1)) - count);
586418334Speter      break;
586518334Speter
586618334Speter    case NEG:  case NOT:
586718334Speter      if ((tem = extract_left_shift (XEXP (x, 0), count)) != 0)
586818334Speter	return gen_unary (code, mode, mode, tem);
586918334Speter
587018334Speter      break;
587118334Speter
587218334Speter    case PLUS:  case IOR:  case XOR:  case AND:
587318334Speter      /* If we can safely shift this constant and we find the inner shift,
587418334Speter	 make a new operation.  */
587518334Speter      if (GET_CODE (XEXP (x,1)) == CONST_INT
587650397Sobrien	  && (INTVAL (XEXP (x, 1)) & ((((HOST_WIDE_INT) 1 << count)) - 1)) == 0
587718334Speter	  && (tem = extract_left_shift (XEXP (x, 0), count)) != 0)
587818334Speter	return gen_binary (code, mode, tem,
587918334Speter			   GEN_INT (INTVAL (XEXP (x, 1)) >> count));
588018334Speter
588118334Speter      break;
588250397Sobrien
588350397Sobrien    default:
588450397Sobrien      break;
588518334Speter    }
588618334Speter
588718334Speter  return 0;
588818334Speter}
588918334Speter
589018334Speter/* Look at the expression rooted at X.  Look for expressions
589118334Speter   equivalent to ZERO_EXTRACT, SIGN_EXTRACT, ZERO_EXTEND, SIGN_EXTEND.
589218334Speter   Form these expressions.
589318334Speter
589418334Speter   Return the new rtx, usually just X.
589518334Speter
589618334Speter   Also, for machines like the Vax that don't have logical shift insns,
589718334Speter   try to convert logical to arithmetic shift operations in cases where
589818334Speter   they are equivalent.  This undoes the canonicalizations to logical
589918334Speter   shifts done elsewhere.
590018334Speter
590118334Speter   We try, as much as possible, to re-use rtl expressions to save memory.
590218334Speter
590318334Speter   IN_CODE says what kind of expression we are processing.  Normally, it is
590418334Speter   SET.  In a memory address (inside a MEM, PLUS or minus, the latter two
590518334Speter   being kludges), it is MEM.  When processing the arguments of a comparison
590618334Speter   or a COMPARE against zero, it is COMPARE.  */
590718334Speter
590818334Speterstatic rtx
590918334Spetermake_compound_operation (x, in_code)
591018334Speter     rtx x;
591118334Speter     enum rtx_code in_code;
591218334Speter{
591318334Speter  enum rtx_code code = GET_CODE (x);
591418334Speter  enum machine_mode mode = GET_MODE (x);
591518334Speter  int mode_width = GET_MODE_BITSIZE (mode);
591618334Speter  rtx rhs, lhs;
591718334Speter  enum rtx_code next_code;
591818334Speter  int i;
591918334Speter  rtx new = 0;
592018334Speter  rtx tem;
592118334Speter  char *fmt;
592218334Speter
592318334Speter  /* Select the code to be used in recursive calls.  Once we are inside an
592418334Speter     address, we stay there.  If we have a comparison, set to COMPARE,
592518334Speter     but once inside, go back to our default of SET.  */
592618334Speter
592718334Speter  next_code = (code == MEM || code == PLUS || code == MINUS ? MEM
592818334Speter	       : ((code == COMPARE || GET_RTX_CLASS (code) == '<')
592918334Speter		  && XEXP (x, 1) == const0_rtx) ? COMPARE
593018334Speter	       : in_code == COMPARE ? SET : in_code);
593118334Speter
593218334Speter  /* Process depending on the code of this operation.  If NEW is set
593318334Speter     non-zero, it will be returned.  */
593418334Speter
593518334Speter  switch (code)
593618334Speter    {
593718334Speter    case ASHIFT:
593818334Speter      /* Convert shifts by constants into multiplications if inside
593918334Speter	 an address.  */
594018334Speter      if (in_code == MEM && GET_CODE (XEXP (x, 1)) == CONST_INT
594118334Speter	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
594218334Speter	  && INTVAL (XEXP (x, 1)) >= 0)
594318334Speter	{
594418334Speter	  new = make_compound_operation (XEXP (x, 0), next_code);
594518334Speter	  new = gen_rtx_combine (MULT, mode, new,
594618334Speter				 GEN_INT ((HOST_WIDE_INT) 1
594718334Speter					  << INTVAL (XEXP (x, 1))));
594818334Speter	}
594918334Speter      break;
595018334Speter
595118334Speter    case AND:
595218334Speter      /* If the second operand is not a constant, we can't do anything
595318334Speter	 with it.  */
595418334Speter      if (GET_CODE (XEXP (x, 1)) != CONST_INT)
595518334Speter	break;
595618334Speter
595718334Speter      /* If the constant is a power of two minus one and the first operand
595818334Speter	 is a logical right shift, make an extraction.  */
595918334Speter      if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
596018334Speter	  && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
596118334Speter	{
596218334Speter	  new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
596318334Speter	  new = make_extraction (mode, new, 0, XEXP (XEXP (x, 0), 1), i, 1,
596418334Speter				 0, in_code == COMPARE);
596518334Speter	}
596618334Speter
596718334Speter      /* Same as previous, but for (subreg (lshiftrt ...)) in first op.  */
596818334Speter      else if (GET_CODE (XEXP (x, 0)) == SUBREG
596918334Speter	       && subreg_lowpart_p (XEXP (x, 0))
597018334Speter	       && GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT
597118334Speter	       && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
597218334Speter	{
597318334Speter	  new = make_compound_operation (XEXP (SUBREG_REG (XEXP (x, 0)), 0),
597418334Speter					 next_code);
597518334Speter	  new = make_extraction (GET_MODE (SUBREG_REG (XEXP (x, 0))), new, 0,
597618334Speter				 XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1,
597718334Speter				 0, in_code == COMPARE);
597818334Speter	}
597918334Speter      /* Same as previous, but for (xor/ior (lshiftrt...) (lshiftrt...)).  */
598018334Speter      else if ((GET_CODE (XEXP (x, 0)) == XOR
598118334Speter		|| GET_CODE (XEXP (x, 0)) == IOR)
598218334Speter	       && GET_CODE (XEXP (XEXP (x, 0), 0)) == LSHIFTRT
598318334Speter	       && GET_CODE (XEXP (XEXP (x, 0), 1)) == LSHIFTRT
598418334Speter	       && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
598518334Speter	{
598618334Speter	  /* Apply the distributive law, and then try to make extractions.  */
598718334Speter	  new = gen_rtx_combine (GET_CODE (XEXP (x, 0)), mode,
598850397Sobrien				 gen_rtx_AND (mode, XEXP (XEXP (x, 0), 0),
598950397Sobrien					      XEXP (x, 1)),
599050397Sobrien				 gen_rtx_AND (mode, XEXP (XEXP (x, 0), 1),
599150397Sobrien					      XEXP (x, 1)));
599218334Speter	  new = make_compound_operation (new, in_code);
599318334Speter	}
599418334Speter
599518334Speter      /* If we are have (and (rotate X C) M) and C is larger than the number
599618334Speter	 of bits in M, this is an extraction.  */
599718334Speter
599818334Speter      else if (GET_CODE (XEXP (x, 0)) == ROTATE
599918334Speter	       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
600018334Speter	       && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0
600118334Speter	       && i <= INTVAL (XEXP (XEXP (x, 0), 1)))
600218334Speter	{
600318334Speter	  new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
600418334Speter	  new = make_extraction (mode, new,
600518334Speter				 (GET_MODE_BITSIZE (mode)
600618334Speter				  - INTVAL (XEXP (XEXP (x, 0), 1))),
600718334Speter				 NULL_RTX, i, 1, 0, in_code == COMPARE);
600818334Speter	}
600918334Speter
601018334Speter      /* On machines without logical shifts, if the operand of the AND is
601118334Speter	 a logical shift and our mask turns off all the propagated sign
601218334Speter	 bits, we can replace the logical shift with an arithmetic shift.  */
601318334Speter      else if (ashr_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
601418334Speter	       && (lshr_optab->handlers[(int) mode].insn_code
601518334Speter		   == CODE_FOR_nothing)
601618334Speter	       && GET_CODE (XEXP (x, 0)) == LSHIFTRT
601718334Speter	       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
601818334Speter	       && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
601918334Speter	       && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT
602018334Speter	       && mode_width <= HOST_BITS_PER_WIDE_INT)
602118334Speter	{
602218334Speter	  unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
602318334Speter
602418334Speter	  mask >>= INTVAL (XEXP (XEXP (x, 0), 1));
602518334Speter	  if ((INTVAL (XEXP (x, 1)) & ~mask) == 0)
602618334Speter	    SUBST (XEXP (x, 0),
602718334Speter		   gen_rtx_combine (ASHIFTRT, mode,
602818334Speter				    make_compound_operation (XEXP (XEXP (x, 0), 0),
602918334Speter							     next_code),
603018334Speter				    XEXP (XEXP (x, 0), 1)));
603118334Speter	}
603218334Speter
603318334Speter      /* If the constant is one less than a power of two, this might be
603418334Speter	 representable by an extraction even if no shift is present.
603518334Speter	 If it doesn't end up being a ZERO_EXTEND, we will ignore it unless
603618334Speter	 we are in a COMPARE.  */
603718334Speter      else if ((i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
603818334Speter	new = make_extraction (mode,
603918334Speter			       make_compound_operation (XEXP (x, 0),
604018334Speter							next_code),
604118334Speter			       0, NULL_RTX, i, 1, 0, in_code == COMPARE);
604218334Speter
604318334Speter      /* If we are in a comparison and this is an AND with a power of two,
604418334Speter	 convert this into the appropriate bit extract.  */
604518334Speter      else if (in_code == COMPARE
604618334Speter	       && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0)
604718334Speter	new = make_extraction (mode,
604818334Speter			       make_compound_operation (XEXP (x, 0),
604918334Speter							next_code),
605018334Speter			       i, NULL_RTX, 1, 1, 0, 1);
605118334Speter
605218334Speter      break;
605318334Speter
605418334Speter    case LSHIFTRT:
605518334Speter      /* If the sign bit is known to be zero, replace this with an
605618334Speter	 arithmetic shift.  */
605718334Speter      if (ashr_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing
605818334Speter	  && lshr_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
605918334Speter	  && mode_width <= HOST_BITS_PER_WIDE_INT
606018334Speter	  && (nonzero_bits (XEXP (x, 0), mode) & (1 << (mode_width - 1))) == 0)
606118334Speter	{
606218334Speter	  new = gen_rtx_combine (ASHIFTRT, mode,
606318334Speter				 make_compound_operation (XEXP (x, 0),
606418334Speter							  next_code),
606518334Speter				 XEXP (x, 1));
606618334Speter	  break;
606718334Speter	}
606818334Speter
606950397Sobrien      /* ... fall through ...  */
607018334Speter
607118334Speter    case ASHIFTRT:
607218334Speter      lhs = XEXP (x, 0);
607318334Speter      rhs = XEXP (x, 1);
607418334Speter
607518334Speter      /* If we have (ashiftrt (ashift foo C1) C2) with C2 >= C1,
607618334Speter	 this is a SIGN_EXTRACT.  */
607718334Speter      if (GET_CODE (rhs) == CONST_INT
607818334Speter	  && GET_CODE (lhs) == ASHIFT
607918334Speter	  && GET_CODE (XEXP (lhs, 1)) == CONST_INT
608018334Speter	  && INTVAL (rhs) >= INTVAL (XEXP (lhs, 1)))
608118334Speter	{
608218334Speter	  new = make_compound_operation (XEXP (lhs, 0), next_code);
608318334Speter	  new = make_extraction (mode, new,
608418334Speter				 INTVAL (rhs) - INTVAL (XEXP (lhs, 1)),
608518334Speter				 NULL_RTX, mode_width - INTVAL (rhs),
608618334Speter				 code == LSHIFTRT, 0, in_code == COMPARE);
608718334Speter	}
608818334Speter
608918334Speter      /* See if we have operations between an ASHIFTRT and an ASHIFT.
609018334Speter	 If so, try to merge the shifts into a SIGN_EXTEND.  We could
609118334Speter	 also do this for some cases of SIGN_EXTRACT, but it doesn't
609218334Speter	 seem worth the effort; the case checked for occurs on Alpha.  */
609318334Speter
609418334Speter      if (GET_RTX_CLASS (GET_CODE (lhs)) != 'o'
609518334Speter	  && ! (GET_CODE (lhs) == SUBREG
609618334Speter		&& (GET_RTX_CLASS (GET_CODE (SUBREG_REG (lhs))) == 'o'))
609718334Speter	  && GET_CODE (rhs) == CONST_INT
609818334Speter	  && INTVAL (rhs) < HOST_BITS_PER_WIDE_INT
609918334Speter	  && (new = extract_left_shift (lhs, INTVAL (rhs))) != 0)
610018334Speter	new = make_extraction (mode, make_compound_operation (new, next_code),
610118334Speter			       0, NULL_RTX, mode_width - INTVAL (rhs),
610218334Speter			       code == LSHIFTRT, 0, in_code == COMPARE);
610318334Speter
610418334Speter      break;
610518334Speter
610618334Speter    case SUBREG:
610718334Speter      /* Call ourselves recursively on the inner expression.  If we are
610818334Speter	 narrowing the object and it has a different RTL code from
610918334Speter	 what it originally did, do this SUBREG as a force_to_mode.  */
611018334Speter
611118334Speter      tem = make_compound_operation (SUBREG_REG (x), in_code);
611218334Speter      if (GET_CODE (tem) != GET_CODE (SUBREG_REG (x))
611318334Speter	  && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (tem))
611418334Speter	  && subreg_lowpart_p (x))
611518334Speter	{
611618334Speter	  rtx newer = force_to_mode (tem, mode,
611718334Speter				     GET_MODE_MASK (mode), NULL_RTX, 0);
611818334Speter
611918334Speter	  /* If we have something other than a SUBREG, we might have
612018334Speter	     done an expansion, so rerun outselves.  */
612118334Speter	  if (GET_CODE (newer) != SUBREG)
612218334Speter	    newer = make_compound_operation (newer, in_code);
612318334Speter
612418334Speter	  return newer;
612518334Speter	}
612650397Sobrien
612750397Sobrien      /* If this is a paradoxical subreg, and the new code is a sign or
612850397Sobrien	 zero extension, omit the subreg and widen the extension.  If it
612950397Sobrien	 is a regular subreg, we can still get rid of the subreg by not
613050397Sobrien	 widening so much, or in fact removing the extension entirely.  */
613150397Sobrien      if ((GET_CODE (tem) == SIGN_EXTEND
613250397Sobrien	   || GET_CODE (tem) == ZERO_EXTEND)
613350397Sobrien	  && subreg_lowpart_p (x))
613450397Sobrien	{
613550397Sobrien	  if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (tem))
613650397Sobrien	      || (GET_MODE_SIZE (mode) >
613750397Sobrien		  GET_MODE_SIZE (GET_MODE (XEXP (tem, 0)))))
613850397Sobrien	    tem = gen_rtx_combine (GET_CODE (tem), mode, XEXP (tem, 0));
613950397Sobrien	  else
614050397Sobrien	    tem = gen_lowpart_for_combine (mode, XEXP (tem, 0));
614150397Sobrien	  return tem;
614250397Sobrien	}
614350397Sobrien      break;
614450397Sobrien
614550397Sobrien    default:
614650397Sobrien      break;
614718334Speter    }
614818334Speter
614918334Speter  if (new)
615018334Speter    {
615118334Speter      x = gen_lowpart_for_combine (mode, new);
615218334Speter      code = GET_CODE (x);
615318334Speter    }
615418334Speter
615518334Speter  /* Now recursively process each operand of this operation.  */
615618334Speter  fmt = GET_RTX_FORMAT (code);
615718334Speter  for (i = 0; i < GET_RTX_LENGTH (code); i++)
615818334Speter    if (fmt[i] == 'e')
615918334Speter      {
616018334Speter	new = make_compound_operation (XEXP (x, i), next_code);
616118334Speter	SUBST (XEXP (x, i), new);
616218334Speter      }
616318334Speter
616418334Speter  return x;
616518334Speter}
616618334Speter
616718334Speter/* Given M see if it is a value that would select a field of bits
616818334Speter    within an item, but not the entire word.  Return -1 if not.
616918334Speter    Otherwise, return the starting position of the field, where 0 is the
617018334Speter    low-order bit.
617118334Speter
617218334Speter   *PLEN is set to the length of the field.  */
617318334Speter
617418334Speterstatic int
617518334Speterget_pos_from_mask (m, plen)
617618334Speter     unsigned HOST_WIDE_INT m;
617718334Speter     int *plen;
617818334Speter{
617918334Speter  /* Get the bit number of the first 1 bit from the right, -1 if none.  */
618018334Speter  int pos = exact_log2 (m & - m);
618118334Speter
618218334Speter  if (pos < 0)
618318334Speter    return -1;
618418334Speter
618518334Speter  /* Now shift off the low-order zero bits and see if we have a power of
618618334Speter     two minus 1.  */
618718334Speter  *plen = exact_log2 ((m >> pos) + 1);
618818334Speter
618918334Speter  if (*plen <= 0)
619018334Speter    return -1;
619118334Speter
619218334Speter  return pos;
619318334Speter}
619418334Speter
619518334Speter/* See if X can be simplified knowing that we will only refer to it in
619618334Speter   MODE and will only refer to those bits that are nonzero in MASK.
619718334Speter   If other bits are being computed or if masking operations are done
619818334Speter   that select a superset of the bits in MASK, they can sometimes be
619918334Speter   ignored.
620018334Speter
620118334Speter   Return a possibly simplified expression, but always convert X to
620218334Speter   MODE.  If X is a CONST_INT, AND the CONST_INT with MASK.
620318334Speter
620418334Speter   Also, if REG is non-zero and X is a register equal in value to REG,
620518334Speter   replace X with REG.
620618334Speter
620718334Speter   If JUST_SELECT is nonzero, don't optimize by noticing that bits in MASK
620818334Speter   are all off in X.  This is used when X will be complemented, by either
620918334Speter   NOT, NEG, or XOR.  */
621018334Speter
621118334Speterstatic rtx
621218334Speterforce_to_mode (x, mode, mask, reg, just_select)
621318334Speter     rtx x;
621418334Speter     enum machine_mode mode;
621518334Speter     unsigned HOST_WIDE_INT mask;
621618334Speter     rtx reg;
621718334Speter     int just_select;
621818334Speter{
621918334Speter  enum rtx_code code = GET_CODE (x);
622018334Speter  int next_select = just_select || code == XOR || code == NOT || code == NEG;
622118334Speter  enum machine_mode op_mode;
622218334Speter  unsigned HOST_WIDE_INT fuller_mask, nonzero;
622318334Speter  rtx op0, op1, temp;
622418334Speter
622550397Sobrien  /* If this is a CALL or ASM_OPERANDS, don't do anything.  Some of the
622650397Sobrien     code below will do the wrong thing since the mode of such an
622750397Sobrien     expression is VOIDmode.
622850397Sobrien
622950397Sobrien     Also do nothing if X is a CLOBBER; this can happen if X was
623050397Sobrien     the return value from a call to gen_lowpart_for_combine.  */
623150397Sobrien  if (code == CALL || code == ASM_OPERANDS || code == CLOBBER)
623218334Speter    return x;
623318334Speter
623418334Speter  /* We want to perform the operation is its present mode unless we know
623518334Speter     that the operation is valid in MODE, in which case we do the operation
623618334Speter     in MODE.  */
623718334Speter  op_mode = ((GET_MODE_CLASS (mode) == GET_MODE_CLASS (GET_MODE (x))
623818334Speter	      && code_to_optab[(int) code] != 0
623918334Speter	      && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
624018334Speter		  != CODE_FOR_nothing))
624118334Speter	     ? mode : GET_MODE (x));
624218334Speter
624318334Speter  /* It is not valid to do a right-shift in a narrower mode
624418334Speter     than the one it came in with.  */
624518334Speter  if ((code == LSHIFTRT || code == ASHIFTRT)
624618334Speter      && GET_MODE_BITSIZE (mode) < GET_MODE_BITSIZE (GET_MODE (x)))
624718334Speter    op_mode = GET_MODE (x);
624818334Speter
624918334Speter  /* Truncate MASK to fit OP_MODE.  */
625018334Speter  if (op_mode)
625118334Speter    mask &= GET_MODE_MASK (op_mode);
625218334Speter
625318334Speter  /* When we have an arithmetic operation, or a shift whose count we
625418334Speter     do not know, we need to assume that all bit the up to the highest-order
625518334Speter     bit in MASK will be needed.  This is how we form such a mask.  */
625618334Speter  if (op_mode)
625718334Speter    fuller_mask = (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT
625818334Speter		   ? GET_MODE_MASK (op_mode)
625918334Speter		   : ((HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1)) - 1);
626018334Speter  else
626118334Speter    fuller_mask = ~ (HOST_WIDE_INT) 0;
626218334Speter
626318334Speter  /* Determine what bits of X are guaranteed to be (non)zero.  */
626418334Speter  nonzero = nonzero_bits (x, mode);
626518334Speter
626618334Speter  /* If none of the bits in X are needed, return a zero.  */
626718334Speter  if (! just_select && (nonzero & mask) == 0)
626818334Speter    return const0_rtx;
626918334Speter
627018334Speter  /* If X is a CONST_INT, return a new one.  Do this here since the
627118334Speter     test below will fail.  */
627218334Speter  if (GET_CODE (x) == CONST_INT)
627318334Speter    {
627418334Speter      HOST_WIDE_INT cval = INTVAL (x) & mask;
627518334Speter      int width = GET_MODE_BITSIZE (mode);
627618334Speter
627718334Speter      /* If MODE is narrower that HOST_WIDE_INT and CVAL is a negative
627818334Speter	 number, sign extend it.  */
627918334Speter      if (width > 0 && width < HOST_BITS_PER_WIDE_INT
628018334Speter	  && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
628118334Speter	cval |= (HOST_WIDE_INT) -1 << width;
628218334Speter
628318334Speter      return GEN_INT (cval);
628418334Speter    }
628518334Speter
628618334Speter  /* If X is narrower than MODE and we want all the bits in X's mode, just
628718334Speter     get X in the proper mode.  */
628818334Speter  if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode)
628918334Speter      && (GET_MODE_MASK (GET_MODE (x)) & ~ mask) == 0)
629018334Speter    return gen_lowpart_for_combine (mode, x);
629118334Speter
629218334Speter  /* If we aren't changing the mode, X is not a SUBREG, and all zero bits in
629318334Speter     MASK are already known to be zero in X, we need not do anything.  */
629418334Speter  if (GET_MODE (x) == mode && code != SUBREG && (~ mask & nonzero) == 0)
629518334Speter    return x;
629618334Speter
629718334Speter  switch (code)
629818334Speter    {
629918334Speter    case CLOBBER:
630018334Speter      /* If X is a (clobber (const_int)), return it since we know we are
630150397Sobrien	 generating something that won't match.  */
630218334Speter      return x;
630318334Speter
630418334Speter    case USE:
630518334Speter      /* X is a (use (mem ..)) that was made from a bit-field extraction that
630618334Speter	 spanned the boundary of the MEM.  If we are now masking so it is
630718334Speter	 within that boundary, we don't need the USE any more.  */
630818334Speter      if (! BITS_BIG_ENDIAN
630918334Speter	  && (mask & ~ GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
631018334Speter	return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select);
631118334Speter      break;
631218334Speter
631318334Speter    case SIGN_EXTEND:
631418334Speter    case ZERO_EXTEND:
631518334Speter    case ZERO_EXTRACT:
631618334Speter    case SIGN_EXTRACT:
631718334Speter      x = expand_compound_operation (x);
631818334Speter      if (GET_CODE (x) != code)
631918334Speter	return force_to_mode (x, mode, mask, reg, next_select);
632018334Speter      break;
632118334Speter
632218334Speter    case REG:
632318334Speter      if (reg != 0 && (rtx_equal_p (get_last_value (reg), x)
632418334Speter		       || rtx_equal_p (reg, get_last_value (x))))
632518334Speter	x = reg;
632618334Speter      break;
632718334Speter
632818334Speter    case SUBREG:
632918334Speter      if (subreg_lowpart_p (x)
633018334Speter	  /* We can ignore the effect of this SUBREG if it narrows the mode or
633118334Speter	     if the constant masks to zero all the bits the mode doesn't
633218334Speter	     have.  */
633318334Speter	  && ((GET_MODE_SIZE (GET_MODE (x))
633418334Speter	       < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
633518334Speter	      || (0 == (mask
633618334Speter			& GET_MODE_MASK (GET_MODE (x))
633718334Speter			& ~ GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))))))
633818334Speter	return force_to_mode (SUBREG_REG (x), mode, mask, reg, next_select);
633918334Speter      break;
634018334Speter
634118334Speter    case AND:
634218334Speter      /* If this is an AND with a constant, convert it into an AND
634318334Speter	 whose constant is the AND of that constant with MASK.  If it
634418334Speter	 remains an AND of MASK, delete it since it is redundant.  */
634518334Speter
634618334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
634718334Speter	{
634818334Speter	  x = simplify_and_const_int (x, op_mode, XEXP (x, 0),
634918334Speter				      mask & INTVAL (XEXP (x, 1)));
635018334Speter
635118334Speter	  /* If X is still an AND, see if it is an AND with a mask that
635218334Speter	     is just some low-order bits.  If so, and it is MASK, we don't
635318334Speter	     need it.  */
635418334Speter
635518334Speter	  if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT
635652284Sobrien	      && (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) == mask)
635718334Speter	    x = XEXP (x, 0);
635818334Speter
635918334Speter	  /* If it remains an AND, try making another AND with the bits
636018334Speter	     in the mode mask that aren't in MASK turned on.  If the
636118334Speter	     constant in the AND is wide enough, this might make a
636218334Speter	     cheaper constant.  */
636318334Speter
636418334Speter	  if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT
636518334Speter	      && GET_MODE_MASK (GET_MODE (x)) != mask
636618334Speter	      && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
636718334Speter	    {
636818334Speter	      HOST_WIDE_INT cval = (INTVAL (XEXP (x, 1))
636918334Speter				    | (GET_MODE_MASK (GET_MODE (x)) & ~ mask));
637018334Speter	      int width = GET_MODE_BITSIZE (GET_MODE (x));
637118334Speter	      rtx y;
637218334Speter
637318334Speter	      /* If MODE is narrower that HOST_WIDE_INT and CVAL is a negative
637418334Speter		 number, sign extend it.  */
637518334Speter	      if (width > 0 && width < HOST_BITS_PER_WIDE_INT
637618334Speter		  && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
637718334Speter		cval |= (HOST_WIDE_INT) -1 << width;
637818334Speter
637918334Speter	      y = gen_binary (AND, GET_MODE (x), XEXP (x, 0), GEN_INT (cval));
638018334Speter	      if (rtx_cost (y, SET) < rtx_cost (x, SET))
638118334Speter		x = y;
638218334Speter	    }
638318334Speter
638418334Speter	  break;
638518334Speter	}
638618334Speter
638718334Speter      goto binop;
638818334Speter
638918334Speter    case PLUS:
639018334Speter      /* In (and (plus FOO C1) M), if M is a mask that just turns off
639118334Speter	 low-order bits (as in an alignment operation) and FOO is already
639218334Speter	 aligned to that boundary, mask C1 to that boundary as well.
639318334Speter	 This may eliminate that PLUS and, later, the AND.  */
639418334Speter
639518334Speter      {
639618334Speter	int width = GET_MODE_BITSIZE (mode);
639718334Speter	unsigned HOST_WIDE_INT smask = mask;
639818334Speter
639918334Speter	/* If MODE is narrower than HOST_WIDE_INT and mask is a negative
640018334Speter	   number, sign extend it.  */
640118334Speter
640218334Speter	if (width < HOST_BITS_PER_WIDE_INT
640318334Speter	    && (smask & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
640418334Speter	  smask |= (HOST_WIDE_INT) -1 << width;
640518334Speter
640618334Speter	if (GET_CODE (XEXP (x, 1)) == CONST_INT
640750397Sobrien	    && exact_log2 (- smask) >= 0)
640850397Sobrien	  {
640950397Sobrien#ifdef STACK_BIAS
641050397Sobrien	    if (STACK_BIAS
641150397Sobrien	        && (XEXP (x, 0) == stack_pointer_rtx
641250397Sobrien	            || XEXP (x, 0) == frame_pointer_rtx))
641350397Sobrien	      {
641450397Sobrien                int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
641550397Sobrien                unsigned HOST_WIDE_INT sp_mask = GET_MODE_MASK (mode);
641650397Sobrien
641750397Sobrien		sp_mask &= ~ (sp_alignment - 1);
641852284Sobrien		if ((sp_mask & ~ smask) == 0
641952284Sobrien		    && ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~ smask) != 0)
642050397Sobrien		  return force_to_mode (plus_constant (XEXP (x, 0),
642150397Sobrien		  				       ((INTVAL (XEXP (x, 1)) -
642252284Sobrien							 STACK_BIAS) & smask)
642350397Sobrien						       + STACK_BIAS),
642452284Sobrien		 			mode, smask, reg, next_select);
642550397Sobrien              }
642650397Sobrien#endif
642752284Sobrien	    if ((nonzero_bits (XEXP (x, 0), mode) & ~ smask) == 0
642852284Sobrien	        && (INTVAL (XEXP (x, 1)) & ~ smask) != 0)
642950397Sobrien	      return force_to_mode (plus_constant (XEXP (x, 0),
643052284Sobrien					           (INTVAL (XEXP (x, 1))
643152284Sobrien						    & smask)),
643252284Sobrien				    mode, smask, reg, next_select);
643350397Sobrien	  }
643418334Speter      }
643518334Speter
643650397Sobrien      /* ... fall through ...  */
643718334Speter
643818334Speter    case MINUS:
643918334Speter    case MULT:
644018334Speter      /* For PLUS, MINUS and MULT, we need any bits less significant than the
644118334Speter	 most significant bit in MASK since carries from those bits will
644218334Speter	 affect the bits we are interested in.  */
644318334Speter      mask = fuller_mask;
644418334Speter      goto binop;
644518334Speter
644618334Speter    case IOR:
644718334Speter    case XOR:
644818334Speter      /* If X is (ior (lshiftrt FOO C1) C2), try to commute the IOR and
644918334Speter	 LSHIFTRT so we end up with an (and (lshiftrt (ior ...) ...) ...)
645018334Speter	 operation which may be a bitfield extraction.  Ensure that the
645118334Speter	 constant we form is not wider than the mode of X.  */
645218334Speter
645318334Speter      if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
645418334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
645518334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
645618334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT
645718334Speter	  && GET_CODE (XEXP (x, 1)) == CONST_INT
645818334Speter	  && ((INTVAL (XEXP (XEXP (x, 0), 1))
645918334Speter	       + floor_log2 (INTVAL (XEXP (x, 1))))
646018334Speter	      < GET_MODE_BITSIZE (GET_MODE (x)))
646118334Speter	  && (INTVAL (XEXP (x, 1))
646250397Sobrien	      & ~ nonzero_bits (XEXP (x, 0), GET_MODE (x))) == 0)
646318334Speter	{
646418334Speter	  temp = GEN_INT ((INTVAL (XEXP (x, 1)) & mask)
646518334Speter			      << INTVAL (XEXP (XEXP (x, 0), 1)));
646618334Speter	  temp = gen_binary (GET_CODE (x), GET_MODE (x),
646718334Speter			     XEXP (XEXP (x, 0), 0), temp);
646850397Sobrien	  x = gen_binary (LSHIFTRT, GET_MODE (x), temp,
646950397Sobrien			  XEXP (XEXP (x, 0), 1));
647018334Speter	  return force_to_mode (x, mode, mask, reg, next_select);
647118334Speter	}
647218334Speter
647318334Speter    binop:
647418334Speter      /* For most binary operations, just propagate into the operation and
647518334Speter	 change the mode if we have an operation of that mode.   */
647618334Speter
647718334Speter      op0 = gen_lowpart_for_combine (op_mode,
647818334Speter				     force_to_mode (XEXP (x, 0), mode, mask,
647918334Speter						    reg, next_select));
648018334Speter      op1 = gen_lowpart_for_combine (op_mode,
648118334Speter				     force_to_mode (XEXP (x, 1), mode, mask,
648218334Speter						    reg, next_select));
648318334Speter
648418334Speter      /* If OP1 is a CONST_INT and X is an IOR or XOR, clear bits outside
648518334Speter	 MASK since OP1 might have been sign-extended but we never want
648618334Speter	 to turn on extra bits, since combine might have previously relied
648718334Speter	 on them being off.  */
648818334Speter      if (GET_CODE (op1) == CONST_INT && (code == IOR || code == XOR)
648918334Speter	  && (INTVAL (op1) & mask) != 0)
649018334Speter	op1 = GEN_INT (INTVAL (op1) & mask);
649118334Speter
649218334Speter      if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
649318334Speter	x = gen_binary (code, op_mode, op0, op1);
649418334Speter      break;
649518334Speter
649618334Speter    case ASHIFT:
649718334Speter      /* For left shifts, do the same, but just for the first operand.
649818334Speter	 However, we cannot do anything with shifts where we cannot
649918334Speter	 guarantee that the counts are smaller than the size of the mode
650018334Speter	 because such a count will have a different meaning in a
650118334Speter	 wider mode.  */
650218334Speter
650318334Speter      if (! (GET_CODE (XEXP (x, 1)) == CONST_INT
650418334Speter	     && INTVAL (XEXP (x, 1)) >= 0
650518334Speter	     && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (mode))
650618334Speter	  && ! (GET_MODE (XEXP (x, 1)) != VOIDmode
650718334Speter		&& (nonzero_bits (XEXP (x, 1), GET_MODE (XEXP (x, 1)))
650818334Speter		    < (unsigned HOST_WIDE_INT) GET_MODE_BITSIZE (mode))))
650918334Speter	break;
651018334Speter
651118334Speter      /* If the shift count is a constant and we can do arithmetic in
651218334Speter	 the mode of the shift, refine which bits we need.  Otherwise, use the
651318334Speter	 conservative form of the mask.  */
651418334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
651518334Speter	  && INTVAL (XEXP (x, 1)) >= 0
651618334Speter	  && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (op_mode)
651718334Speter	  && GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT)
651818334Speter	mask >>= INTVAL (XEXP (x, 1));
651918334Speter      else
652018334Speter	mask = fuller_mask;
652118334Speter
652218334Speter      op0 = gen_lowpart_for_combine (op_mode,
652318334Speter				     force_to_mode (XEXP (x, 0), op_mode,
652418334Speter						    mask, reg, next_select));
652518334Speter
652618334Speter      if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0))
652718334Speter	x =  gen_binary (code, op_mode, op0, XEXP (x, 1));
652818334Speter      break;
652918334Speter
653018334Speter    case LSHIFTRT:
653118334Speter      /* Here we can only do something if the shift count is a constant,
653218334Speter	 this shift constant is valid for the host, and we can do arithmetic
653318334Speter	 in OP_MODE.  */
653418334Speter
653518334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
653618334Speter	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
653718334Speter	  && GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT)
653818334Speter	{
653918334Speter	  rtx inner = XEXP (x, 0);
654018334Speter
654118334Speter	  /* Select the mask of the bits we need for the shift operand.  */
654218334Speter	  mask <<= INTVAL (XEXP (x, 1));
654318334Speter
654418334Speter	  /* We can only change the mode of the shift if we can do arithmetic
654518334Speter	     in the mode of the shift and MASK is no wider than the width of
654618334Speter	     OP_MODE.  */
654718334Speter	  if (GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT
654818334Speter	      || (mask & ~ GET_MODE_MASK (op_mode)) != 0)
654918334Speter	    op_mode = GET_MODE (x);
655018334Speter
655118334Speter	  inner = force_to_mode (inner, op_mode, mask, reg, next_select);
655218334Speter
655318334Speter	  if (GET_MODE (x) != op_mode || inner != XEXP (x, 0))
655418334Speter	    x = gen_binary (LSHIFTRT, op_mode, inner, XEXP (x, 1));
655518334Speter	}
655618334Speter
655718334Speter      /* If we have (and (lshiftrt FOO C1) C2) where the combination of the
655818334Speter	 shift and AND produces only copies of the sign bit (C2 is one less
655918334Speter	 than a power of two), we can do this with just a shift.  */
656018334Speter
656118334Speter      if (GET_CODE (x) == LSHIFTRT
656218334Speter	  && GET_CODE (XEXP (x, 1)) == CONST_INT
656318334Speter	  && ((INTVAL (XEXP (x, 1))
656418334Speter	       + num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0))))
656518334Speter	      >= GET_MODE_BITSIZE (GET_MODE (x)))
656618334Speter	  && exact_log2 (mask + 1) >= 0
656718334Speter	  && (num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
656818334Speter	      >= exact_log2 (mask + 1)))
656918334Speter	x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0),
657018334Speter			GEN_INT (GET_MODE_BITSIZE (GET_MODE (x))
657118334Speter				 - exact_log2 (mask + 1)));
657218334Speter      break;
657318334Speter
657418334Speter    case ASHIFTRT:
657518334Speter      /* If we are just looking for the sign bit, we don't need this shift at
657618334Speter	 all, even if it has a variable count.  */
657718334Speter      if (GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
657852284Sobrien	  && (mask == ((unsigned HOST_WIDE_INT) 1
657918334Speter		       << (GET_MODE_BITSIZE (GET_MODE (x)) - 1))))
658018334Speter	return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select);
658118334Speter
658218334Speter      /* If this is a shift by a constant, get a mask that contains those bits
658318334Speter	 that are not copies of the sign bit.  We then have two cases:  If
658418334Speter	 MASK only includes those bits, this can be a logical shift, which may
658518334Speter	 allow simplifications.  If MASK is a single-bit field not within
658618334Speter	 those bits, we are requesting a copy of the sign bit and hence can
658718334Speter	 shift the sign bit to the appropriate location.  */
658818334Speter
658918334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) >= 0
659018334Speter	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
659118334Speter	{
659218334Speter	  int i = -1;
659318334Speter
659418334Speter	  /* If the considered data is wider then HOST_WIDE_INT, we can't
659518334Speter	     represent a mask for all its bits in a single scalar.
659618334Speter	     But we only care about the lower bits, so calculate these.  */
659718334Speter
659818334Speter	  if (GET_MODE_BITSIZE (GET_MODE (x)) > HOST_BITS_PER_WIDE_INT)
659918334Speter	    {
660050397Sobrien	      nonzero = ~ (HOST_WIDE_INT) 0;
660118334Speter
660218334Speter	      /* GET_MODE_BITSIZE (GET_MODE (x)) - INTVAL (XEXP (x, 1))
660318334Speter		 is the number of bits a full-width mask would have set.
660418334Speter		 We need only shift if these are fewer than nonzero can
660518334Speter		 hold.  If not, we must keep all bits set in nonzero.  */
660618334Speter
660718334Speter	      if (GET_MODE_BITSIZE (GET_MODE (x)) - INTVAL (XEXP (x, 1))
660818334Speter		  < HOST_BITS_PER_WIDE_INT)
660918334Speter		nonzero >>= INTVAL (XEXP (x, 1))
661018334Speter			    + HOST_BITS_PER_WIDE_INT
661118334Speter			    - GET_MODE_BITSIZE (GET_MODE (x)) ;
661218334Speter	    }
661318334Speter	  else
661418334Speter	    {
661518334Speter	      nonzero = GET_MODE_MASK (GET_MODE (x));
661618334Speter	      nonzero >>= INTVAL (XEXP (x, 1));
661718334Speter	    }
661818334Speter
661918334Speter	  if ((mask & ~ nonzero) == 0
662018334Speter	      || (i = exact_log2 (mask)) >= 0)
662118334Speter	    {
662218334Speter	      x = simplify_shift_const
662318334Speter		(x, LSHIFTRT, GET_MODE (x), XEXP (x, 0),
662418334Speter		 i < 0 ? INTVAL (XEXP (x, 1))
662518334Speter		 : GET_MODE_BITSIZE (GET_MODE (x)) - 1 - i);
662618334Speter
662718334Speter	      if (GET_CODE (x) != ASHIFTRT)
662818334Speter		return force_to_mode (x, mode, mask, reg, next_select);
662918334Speter	    }
663018334Speter	}
663118334Speter
663218334Speter      /* If MASK is 1, convert this to a LSHIFTRT.  This can be done
663318334Speter	 even if the shift count isn't a constant.  */
663418334Speter      if (mask == 1)
663518334Speter	x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0), XEXP (x, 1));
663618334Speter
663718334Speter      /* If this is a sign-extension operation that just affects bits
663818334Speter	 we don't care about, remove it.  Be sure the call above returned
663918334Speter	 something that is still a shift.  */
664018334Speter
664118334Speter      if ((GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ASHIFTRT)
664218334Speter	  && GET_CODE (XEXP (x, 1)) == CONST_INT
664318334Speter	  && INTVAL (XEXP (x, 1)) >= 0
664418334Speter	  && (INTVAL (XEXP (x, 1))
664518334Speter	      <= GET_MODE_BITSIZE (GET_MODE (x)) - (floor_log2 (mask) + 1))
664618334Speter	  && GET_CODE (XEXP (x, 0)) == ASHIFT
664718334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
664818334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) == INTVAL (XEXP (x, 1)))
664918334Speter	return force_to_mode (XEXP (XEXP (x, 0), 0), mode, mask,
665018334Speter			      reg, next_select);
665118334Speter
665218334Speter      break;
665318334Speter
665418334Speter    case ROTATE:
665518334Speter    case ROTATERT:
665618334Speter      /* If the shift count is constant and we can do computations
665718334Speter	 in the mode of X, compute where the bits we care about are.
665818334Speter	 Otherwise, we can't do anything.  Don't change the mode of
665918334Speter	 the shift or propagate MODE into the shift, though.  */
666018334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
666118334Speter	  && INTVAL (XEXP (x, 1)) >= 0)
666218334Speter	{
666318334Speter	  temp = simplify_binary_operation (code == ROTATE ? ROTATERT : ROTATE,
666418334Speter					    GET_MODE (x), GEN_INT (mask),
666518334Speter					    XEXP (x, 1));
666618334Speter	  if (temp && GET_CODE(temp) == CONST_INT)
666718334Speter	    SUBST (XEXP (x, 0),
666818334Speter		   force_to_mode (XEXP (x, 0), GET_MODE (x),
666918334Speter				  INTVAL (temp), reg, next_select));
667018334Speter	}
667118334Speter      break;
667218334Speter
667318334Speter    case NEG:
667418334Speter      /* If we just want the low-order bit, the NEG isn't needed since it
667518334Speter	 won't change the low-order bit.    */
667618334Speter      if (mask == 1)
667718334Speter	return force_to_mode (XEXP (x, 0), mode, mask, reg, just_select);
667818334Speter
667918334Speter      /* We need any bits less significant than the most significant bit in
668018334Speter	 MASK since carries from those bits will affect the bits we are
668118334Speter	 interested in.  */
668218334Speter      mask = fuller_mask;
668318334Speter      goto unop;
668418334Speter
668518334Speter    case NOT:
668618334Speter      /* (not FOO) is (xor FOO CONST), so if FOO is an LSHIFTRT, we can do the
668718334Speter	 same as the XOR case above.  Ensure that the constant we form is not
668818334Speter	 wider than the mode of X.  */
668918334Speter
669018334Speter      if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
669118334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
669218334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
669318334Speter	  && (INTVAL (XEXP (XEXP (x, 0), 1)) + floor_log2 (mask)
669418334Speter	      < GET_MODE_BITSIZE (GET_MODE (x)))
669518334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT)
669618334Speter	{
669718334Speter	  temp = GEN_INT (mask << INTVAL (XEXP (XEXP (x, 0), 1)));
669818334Speter	  temp = gen_binary (XOR, GET_MODE (x), XEXP (XEXP (x, 0), 0), temp);
669918334Speter	  x = gen_binary (LSHIFTRT, GET_MODE (x), temp, XEXP (XEXP (x, 0), 1));
670018334Speter
670118334Speter	  return force_to_mode (x, mode, mask, reg, next_select);
670218334Speter	}
670318334Speter
670450397Sobrien      /* (and (not FOO) CONST) is (not (or FOO (not CONST))), so we must
670550397Sobrien	 use the full mask inside the NOT.  */
670650397Sobrien      mask = fuller_mask;
670750397Sobrien
670818334Speter    unop:
670918334Speter      op0 = gen_lowpart_for_combine (op_mode,
671018334Speter				     force_to_mode (XEXP (x, 0), mode, mask,
671118334Speter						    reg, next_select));
671218334Speter      if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0))
671318334Speter	x = gen_unary (code, op_mode, op_mode, op0);
671418334Speter      break;
671518334Speter
671618334Speter    case NE:
671718334Speter      /* (and (ne FOO 0) CONST) can be (and FOO CONST) if CONST is included
671850397Sobrien	 in STORE_FLAG_VALUE and FOO has a single bit that might be nonzero,
671950397Sobrien	 which is equal to STORE_FLAG_VALUE.  */
672050397Sobrien      if ((mask & ~ STORE_FLAG_VALUE) == 0 && XEXP (x, 1) == const0_rtx
672150397Sobrien	  && exact_log2 (nonzero_bits (XEXP (x, 0), mode)) >= 0
672250397Sobrien	  && nonzero_bits (XEXP (x, 0), mode) == STORE_FLAG_VALUE)
672318334Speter	return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select);
672418334Speter
672518334Speter      break;
672618334Speter
672718334Speter    case IF_THEN_ELSE:
672818334Speter      /* We have no way of knowing if the IF_THEN_ELSE can itself be
672918334Speter	 written in a narrower mode.  We play it safe and do not do so.  */
673018334Speter
673118334Speter      SUBST (XEXP (x, 1),
673218334Speter	     gen_lowpart_for_combine (GET_MODE (x),
673318334Speter				      force_to_mode (XEXP (x, 1), mode,
673418334Speter						     mask, reg, next_select)));
673518334Speter      SUBST (XEXP (x, 2),
673618334Speter	     gen_lowpart_for_combine (GET_MODE (x),
673718334Speter				      force_to_mode (XEXP (x, 2), mode,
673818334Speter						     mask, reg,next_select)));
673918334Speter      break;
674050397Sobrien
674150397Sobrien    default:
674250397Sobrien      break;
674318334Speter    }
674418334Speter
674518334Speter  /* Ensure we return a value of the proper mode.  */
674618334Speter  return gen_lowpart_for_combine (mode, x);
674718334Speter}
674818334Speter
674918334Speter/* Return nonzero if X is an expression that has one of two values depending on
675018334Speter   whether some other value is zero or nonzero.  In that case, we return the
675118334Speter   value that is being tested, *PTRUE is set to the value if the rtx being
675218334Speter   returned has a nonzero value, and *PFALSE is set to the other alternative.
675318334Speter
675418334Speter   If we return zero, we set *PTRUE and *PFALSE to X.  */
675518334Speter
675618334Speterstatic rtx
675718334Speterif_then_else_cond (x, ptrue, pfalse)
675818334Speter     rtx x;
675918334Speter     rtx *ptrue, *pfalse;
676018334Speter{
676118334Speter  enum machine_mode mode = GET_MODE (x);
676218334Speter  enum rtx_code code = GET_CODE (x);
676318334Speter  int size = GET_MODE_BITSIZE (mode);
676418334Speter  rtx cond0, cond1, true0, true1, false0, false1;
676518334Speter  unsigned HOST_WIDE_INT nz;
676618334Speter
676718334Speter  /* If this is a unary operation whose operand has one of two values, apply
676818334Speter     our opcode to compute those values.  */
676918334Speter  if (GET_RTX_CLASS (code) == '1'
677018334Speter      && (cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0)) != 0)
677118334Speter    {
677218334Speter      *ptrue = gen_unary (code, mode, GET_MODE (XEXP (x, 0)), true0);
677318334Speter      *pfalse = gen_unary (code, mode, GET_MODE (XEXP (x, 0)), false0);
677418334Speter      return cond0;
677518334Speter    }
677618334Speter
677718334Speter  /* If this is a COMPARE, do nothing, since the IF_THEN_ELSE we would
677818334Speter     make can't possibly match and would suppress other optimizations.  */
677918334Speter  else if (code == COMPARE)
678018334Speter    ;
678118334Speter
678218334Speter  /* If this is a binary operation, see if either side has only one of two
678318334Speter     values.  If either one does or if both do and they are conditional on
678418334Speter     the same value, compute the new true and false values.  */
678518334Speter  else if (GET_RTX_CLASS (code) == 'c' || GET_RTX_CLASS (code) == '2'
678618334Speter	   || GET_RTX_CLASS (code) == '<')
678718334Speter    {
678818334Speter      cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0);
678918334Speter      cond1 = if_then_else_cond (XEXP (x, 1), &true1, &false1);
679018334Speter
679118334Speter      if ((cond0 != 0 || cond1 != 0)
679218334Speter	  && ! (cond0 != 0 && cond1 != 0 && ! rtx_equal_p (cond0, cond1)))
679318334Speter	{
679450397Sobrien	  /* If if_then_else_cond returned zero, then true/false are the
679550397Sobrien	     same rtl.  We must copy one of them to prevent invalid rtl
679650397Sobrien	     sharing.  */
679750397Sobrien	  if (cond0 == 0)
679850397Sobrien	    true0 = copy_rtx (true0);
679950397Sobrien	  else if (cond1 == 0)
680050397Sobrien	    true1 = copy_rtx (true1);
680150397Sobrien
680218334Speter	  *ptrue = gen_binary (code, mode, true0, true1);
680318334Speter	  *pfalse = gen_binary (code, mode, false0, false1);
680418334Speter	  return cond0 ? cond0 : cond1;
680518334Speter	}
680618334Speter
680718334Speter      /* See if we have PLUS, IOR, XOR, MINUS or UMAX, where one of the
680850397Sobrien	 operands is zero when the other is non-zero, and vice-versa,
680950397Sobrien	 and STORE_FLAG_VALUE is 1 or -1.  */
681018334Speter
681150397Sobrien      if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
681250397Sobrien	  && (code == PLUS || code == IOR || code == XOR || code == MINUS
681318334Speter	   || code == UMAX)
681418334Speter	  && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == MULT)
681518334Speter	{
681618334Speter	  rtx op0 = XEXP (XEXP (x, 0), 1);
681718334Speter	  rtx op1 = XEXP (XEXP (x, 1), 1);
681818334Speter
681918334Speter	  cond0 = XEXP (XEXP (x, 0), 0);
682018334Speter	  cond1 = XEXP (XEXP (x, 1), 0);
682118334Speter
682218334Speter	  if (GET_RTX_CLASS (GET_CODE (cond0)) == '<'
682318334Speter	      && GET_RTX_CLASS (GET_CODE (cond1)) == '<'
682418334Speter	      && reversible_comparison_p (cond1)
682518334Speter	      && ((GET_CODE (cond0) == reverse_condition (GET_CODE (cond1))
682618334Speter		   && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0))
682718334Speter		   && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1)))
682818334Speter		  || ((swap_condition (GET_CODE (cond0))
682918334Speter		       == reverse_condition (GET_CODE (cond1)))
683018334Speter		      && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 1))
683118334Speter		      && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0))))
683218334Speter	      && ! side_effects_p (x))
683318334Speter	    {
683418334Speter	      *ptrue = gen_binary (MULT, mode, op0, const_true_rtx);
683518334Speter	      *pfalse = gen_binary (MULT, mode,
683618334Speter				    (code == MINUS
683718334Speter				     ? gen_unary (NEG, mode, mode, op1) : op1),
683818334Speter				    const_true_rtx);
683918334Speter	      return cond0;
684018334Speter	    }
684118334Speter	}
684218334Speter
684318334Speter      /* Similarly for MULT, AND and UMIN, execpt that for these the result
684418334Speter	 is always zero.  */
684550397Sobrien      if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
684650397Sobrien	  && (code == MULT || code == AND || code == UMIN)
684718334Speter	  && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == MULT)
684818334Speter	{
684918334Speter	  cond0 = XEXP (XEXP (x, 0), 0);
685018334Speter	  cond1 = XEXP (XEXP (x, 1), 0);
685118334Speter
685218334Speter	  if (GET_RTX_CLASS (GET_CODE (cond0)) == '<'
685318334Speter	      && GET_RTX_CLASS (GET_CODE (cond1)) == '<'
685418334Speter	      && reversible_comparison_p (cond1)
685518334Speter	      && ((GET_CODE (cond0) == reverse_condition (GET_CODE (cond1))
685618334Speter		   && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0))
685718334Speter		   && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1)))
685818334Speter		  || ((swap_condition (GET_CODE (cond0))
685918334Speter		       == reverse_condition (GET_CODE (cond1)))
686018334Speter		      && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 1))
686118334Speter		      && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0))))
686218334Speter	      && ! side_effects_p (x))
686318334Speter	    {
686418334Speter	      *ptrue = *pfalse = const0_rtx;
686518334Speter	      return cond0;
686618334Speter	    }
686718334Speter	}
686818334Speter    }
686918334Speter
687018334Speter  else if (code == IF_THEN_ELSE)
687118334Speter    {
687218334Speter      /* If we have IF_THEN_ELSE already, extract the condition and
687318334Speter	 canonicalize it if it is NE or EQ.  */
687418334Speter      cond0 = XEXP (x, 0);
687518334Speter      *ptrue = XEXP (x, 1), *pfalse = XEXP (x, 2);
687618334Speter      if (GET_CODE (cond0) == NE && XEXP (cond0, 1) == const0_rtx)
687718334Speter	return XEXP (cond0, 0);
687818334Speter      else if (GET_CODE (cond0) == EQ && XEXP (cond0, 1) == const0_rtx)
687918334Speter	{
688018334Speter	  *ptrue = XEXP (x, 2), *pfalse = XEXP (x, 1);
688118334Speter	  return XEXP (cond0, 0);
688218334Speter	}
688318334Speter      else
688418334Speter	return cond0;
688518334Speter    }
688618334Speter
688718334Speter  /* If X is a normal SUBREG with both inner and outer modes integral,
688818334Speter     we can narrow both the true and false values of the inner expression,
688918334Speter     if there is a condition.  */
689018334Speter  else if (code == SUBREG && GET_MODE_CLASS (mode) == MODE_INT
689118334Speter	   && GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_INT
689218334Speter	   && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))
689318334Speter	   && 0 != (cond0 = if_then_else_cond (SUBREG_REG (x),
689418334Speter					       &true0, &false0)))
689518334Speter    {
689618334Speter      *ptrue = force_to_mode (true0, mode, GET_MODE_MASK (mode), NULL_RTX, 0);
689718334Speter      *pfalse
689818334Speter	= force_to_mode (false0, mode, GET_MODE_MASK (mode), NULL_RTX, 0);
689918334Speter
690018334Speter      return cond0;
690118334Speter    }
690218334Speter
690318334Speter  /* If X is a constant, this isn't special and will cause confusions
690418334Speter     if we treat it as such.  Likewise if it is equivalent to a constant.  */
690518334Speter  else if (CONSTANT_P (x)
690618334Speter	   || ((cond0 = get_last_value (x)) != 0 && CONSTANT_P (cond0)))
690718334Speter    ;
690818334Speter
690918334Speter  /* If X is known to be either 0 or -1, those are the true and
691018334Speter     false values when testing X.  */
691118334Speter  else if (num_sign_bit_copies (x, mode) == size)
691218334Speter    {
691318334Speter      *ptrue = constm1_rtx, *pfalse = const0_rtx;
691418334Speter      return x;
691518334Speter    }
691618334Speter
691718334Speter  /* Likewise for 0 or a single bit.  */
691818334Speter  else if (exact_log2 (nz = nonzero_bits (x, mode)) >= 0)
691918334Speter    {
692018334Speter      *ptrue = GEN_INT (nz), *pfalse = const0_rtx;
692118334Speter      return x;
692218334Speter    }
692318334Speter
692418334Speter  /* Otherwise fail; show no condition with true and false values the same.  */
692518334Speter  *ptrue = *pfalse = x;
692618334Speter  return 0;
692718334Speter}
692818334Speter
692918334Speter/* Return the value of expression X given the fact that condition COND
693018334Speter   is known to be true when applied to REG as its first operand and VAL
693118334Speter   as its second.  X is known to not be shared and so can be modified in
693218334Speter   place.
693318334Speter
693418334Speter   We only handle the simplest cases, and specifically those cases that
693518334Speter   arise with IF_THEN_ELSE expressions.  */
693618334Speter
693718334Speterstatic rtx
693818334Speterknown_cond (x, cond, reg, val)
693918334Speter     rtx x;
694018334Speter     enum rtx_code cond;
694118334Speter     rtx reg, val;
694218334Speter{
694318334Speter  enum rtx_code code = GET_CODE (x);
694418334Speter  rtx temp;
694518334Speter  char *fmt;
694618334Speter  int i, j;
694718334Speter
694818334Speter  if (side_effects_p (x))
694918334Speter    return x;
695018334Speter
695118334Speter  if (cond == EQ && rtx_equal_p (x, reg))
695218334Speter    return val;
695318334Speter
695418334Speter  /* If X is (abs REG) and we know something about REG's relationship
695518334Speter     with zero, we may be able to simplify this.  */
695618334Speter
695718334Speter  if (code == ABS && rtx_equal_p (XEXP (x, 0), reg) && val == const0_rtx)
695818334Speter    switch (cond)
695918334Speter      {
696018334Speter      case GE:  case GT:  case EQ:
696118334Speter	return XEXP (x, 0);
696218334Speter      case LT:  case LE:
696318334Speter	return gen_unary (NEG, GET_MODE (XEXP (x, 0)), GET_MODE (XEXP (x, 0)),
696418334Speter			  XEXP (x, 0));
696550397Sobrien      default:
696650397Sobrien	break;
696718334Speter      }
696818334Speter
696918334Speter  /* The only other cases we handle are MIN, MAX, and comparisons if the
697018334Speter     operands are the same as REG and VAL.  */
697118334Speter
697218334Speter  else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == 'c')
697318334Speter    {
697418334Speter      if (rtx_equal_p (XEXP (x, 0), val))
697518334Speter	cond = swap_condition (cond), temp = val, val = reg, reg = temp;
697618334Speter
697718334Speter      if (rtx_equal_p (XEXP (x, 0), reg) && rtx_equal_p (XEXP (x, 1), val))
697818334Speter	{
697918334Speter	  if (GET_RTX_CLASS (code) == '<')
698018334Speter	    return (comparison_dominates_p (cond, code) ? const_true_rtx
698118334Speter		    : (comparison_dominates_p (cond,
698218334Speter					       reverse_condition (code))
698318334Speter		       ? const0_rtx : x));
698418334Speter
698518334Speter	  else if (code == SMAX || code == SMIN
698618334Speter		   || code == UMIN || code == UMAX)
698718334Speter	    {
698818334Speter	      int unsignedp = (code == UMIN || code == UMAX);
698918334Speter
699018334Speter	      if (code == SMAX || code == UMAX)
699118334Speter		cond = reverse_condition (cond);
699218334Speter
699318334Speter	      switch (cond)
699418334Speter		{
699518334Speter		case GE:   case GT:
699618334Speter		  return unsignedp ? x : XEXP (x, 1);
699718334Speter		case LE:   case LT:
699818334Speter		  return unsignedp ? x : XEXP (x, 0);
699918334Speter		case GEU:  case GTU:
700018334Speter		  return unsignedp ? XEXP (x, 1) : x;
700118334Speter		case LEU:  case LTU:
700218334Speter		  return unsignedp ? XEXP (x, 0) : x;
700350397Sobrien		default:
700450397Sobrien		  break;
700518334Speter		}
700618334Speter	    }
700718334Speter	}
700818334Speter    }
700918334Speter
701018334Speter  fmt = GET_RTX_FORMAT (code);
701118334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
701218334Speter    {
701318334Speter      if (fmt[i] == 'e')
701418334Speter	SUBST (XEXP (x, i), known_cond (XEXP (x, i), cond, reg, val));
701518334Speter      else if (fmt[i] == 'E')
701618334Speter	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
701718334Speter	  SUBST (XVECEXP (x, i, j), known_cond (XVECEXP (x, i, j),
701818334Speter						cond, reg, val));
701918334Speter    }
702018334Speter
702118334Speter  return x;
702218334Speter}
702318334Speter
702450397Sobrien/* See if X and Y are equal for the purposes of seeing if we can rewrite an
702550397Sobrien   assignment as a field assignment.  */
702650397Sobrien
702750397Sobrienstatic int
702850397Sobrienrtx_equal_for_field_assignment_p (x, y)
702950397Sobrien     rtx x;
703050397Sobrien     rtx y;
703150397Sobrien{
703250397Sobrien  if (x == y || rtx_equal_p (x, y))
703350397Sobrien    return 1;
703450397Sobrien
703550397Sobrien  if (x == 0 || y == 0 || GET_MODE (x) != GET_MODE (y))
703650397Sobrien    return 0;
703750397Sobrien
703850397Sobrien  /* Check for a paradoxical SUBREG of a MEM compared with the MEM.
703950397Sobrien     Note that all SUBREGs of MEM are paradoxical; otherwise they
704050397Sobrien     would have been rewritten.  */
704150397Sobrien  if (GET_CODE (x) == MEM && GET_CODE (y) == SUBREG
704250397Sobrien      && GET_CODE (SUBREG_REG (y)) == MEM
704350397Sobrien      && rtx_equal_p (SUBREG_REG (y),
704450397Sobrien		      gen_lowpart_for_combine (GET_MODE (SUBREG_REG (y)), x)))
704550397Sobrien    return 1;
704650397Sobrien
704750397Sobrien  if (GET_CODE (y) == MEM && GET_CODE (x) == SUBREG
704850397Sobrien      && GET_CODE (SUBREG_REG (x)) == MEM
704950397Sobrien      && rtx_equal_p (SUBREG_REG (x),
705050397Sobrien		      gen_lowpart_for_combine (GET_MODE (SUBREG_REG (x)), y)))
705150397Sobrien    return 1;
705250397Sobrien
705350397Sobrien  /* We used to see if get_last_value of X and Y were the same but that's
705450397Sobrien     not correct.  In one direction, we'll cause the assignment to have
705550397Sobrien     the wrong destination and in the case, we'll import a register into this
705650397Sobrien     insn that might have already have been dead.   So fail if none of the
705750397Sobrien     above cases are true.  */
705850397Sobrien  return 0;
705950397Sobrien}
706050397Sobrien
706118334Speter/* See if X, a SET operation, can be rewritten as a bit-field assignment.
706218334Speter   Return that assignment if so.
706318334Speter
706418334Speter   We only handle the most common cases.  */
706518334Speter
706618334Speterstatic rtx
706718334Spetermake_field_assignment (x)
706818334Speter     rtx x;
706918334Speter{
707018334Speter  rtx dest = SET_DEST (x);
707118334Speter  rtx src = SET_SRC (x);
707218334Speter  rtx assign;
707350397Sobrien  rtx rhs, lhs;
707418334Speter  HOST_WIDE_INT c1;
707518334Speter  int pos, len;
707618334Speter  rtx other;
707718334Speter  enum machine_mode mode;
707818334Speter
707918334Speter  /* If SRC was (and (not (ashift (const_int 1) POS)) DEST), this is
708018334Speter     a clear of a one-bit field.  We will have changed it to
708118334Speter     (and (rotate (const_int -2) POS) DEST), so check for that.  Also check
708218334Speter     for a SUBREG.  */
708318334Speter
708418334Speter  if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == ROTATE
708518334Speter      && GET_CODE (XEXP (XEXP (src, 0), 0)) == CONST_INT
708618334Speter      && INTVAL (XEXP (XEXP (src, 0), 0)) == -2
708750397Sobrien      && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
708818334Speter    {
708918334Speter      assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1),
709018334Speter				1, 1, 1, 0);
709150397Sobrien      if (assign != 0)
709250397Sobrien	return gen_rtx_SET (VOIDmode, assign, const0_rtx);
709350397Sobrien      return x;
709418334Speter    }
709518334Speter
709618334Speter  else if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == SUBREG
709718334Speter	   && subreg_lowpart_p (XEXP (src, 0))
709818334Speter	   && (GET_MODE_SIZE (GET_MODE (XEXP (src, 0)))
709918334Speter	       < GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (src, 0)))))
710018334Speter	   && GET_CODE (SUBREG_REG (XEXP (src, 0))) == ROTATE
710118334Speter	   && INTVAL (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == -2
710250397Sobrien	   && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
710318334Speter    {
710418334Speter      assign = make_extraction (VOIDmode, dest, 0,
710518334Speter				XEXP (SUBREG_REG (XEXP (src, 0)), 1),
710618334Speter				1, 1, 1, 0);
710750397Sobrien      if (assign != 0)
710850397Sobrien	return gen_rtx_SET (VOIDmode, assign, const0_rtx);
710950397Sobrien      return x;
711018334Speter    }
711118334Speter
711250397Sobrien  /* If SRC is (ior (ashift (const_int 1) POS) DEST), this is a set of a
711318334Speter     one-bit field.  */
711418334Speter  else if (GET_CODE (src) == IOR && GET_CODE (XEXP (src, 0)) == ASHIFT
711518334Speter	   && XEXP (XEXP (src, 0), 0) == const1_rtx
711650397Sobrien	   && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
711718334Speter    {
711818334Speter      assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1),
711918334Speter				1, 1, 1, 0);
712050397Sobrien      if (assign != 0)
712150397Sobrien	return gen_rtx_SET (VOIDmode, assign, const1_rtx);
712250397Sobrien      return x;
712318334Speter    }
712418334Speter
712518334Speter  /* The other case we handle is assignments into a constant-position
712650397Sobrien     field.  They look like (ior/xor (and DEST C1) OTHER).  If C1 represents
712718334Speter     a mask that has all one bits except for a group of zero bits and
712818334Speter     OTHER is known to have zeros where C1 has ones, this is such an
712918334Speter     assignment.  Compute the position and length from C1.  Shift OTHER
713018334Speter     to the appropriate position, force it to the required mode, and
713118334Speter     make the extraction.  Check for the AND in both operands.  */
713218334Speter
713350397Sobrien  if (GET_CODE (src) != IOR && GET_CODE (src) != XOR)
713450397Sobrien    return x;
713550397Sobrien
713650397Sobrien  rhs = expand_compound_operation (XEXP (src, 0));
713750397Sobrien  lhs = expand_compound_operation (XEXP (src, 1));
713850397Sobrien
713950397Sobrien  if (GET_CODE (rhs) == AND
714050397Sobrien      && GET_CODE (XEXP (rhs, 1)) == CONST_INT
714150397Sobrien      && rtx_equal_for_field_assignment_p (XEXP (rhs, 0), dest))
714250397Sobrien    c1 = INTVAL (XEXP (rhs, 1)), other = lhs;
714350397Sobrien  else if (GET_CODE (lhs) == AND
714450397Sobrien	   && GET_CODE (XEXP (lhs, 1)) == CONST_INT
714550397Sobrien	   && rtx_equal_for_field_assignment_p (XEXP (lhs, 0), dest))
714650397Sobrien    c1 = INTVAL (XEXP (lhs, 1)), other = rhs;
714718334Speter  else
714818334Speter    return x;
714918334Speter
715050397Sobrien  pos = get_pos_from_mask ((~ c1) & GET_MODE_MASK (GET_MODE (dest)), &len);
715118334Speter  if (pos < 0 || pos + len > GET_MODE_BITSIZE (GET_MODE (dest))
715250397Sobrien      || GET_MODE_BITSIZE (GET_MODE (dest)) > HOST_BITS_PER_WIDE_INT
715350397Sobrien      || (c1 & nonzero_bits (other, GET_MODE (dest))) != 0)
715418334Speter    return x;
715518334Speter
715618334Speter  assign = make_extraction (VOIDmode, dest, pos, NULL_RTX, len, 1, 1, 0);
715750397Sobrien  if (assign == 0)
715850397Sobrien    return x;
715918334Speter
716018334Speter  /* The mode to use for the source is the mode of the assignment, or of
716118334Speter     what is inside a possible STRICT_LOW_PART.  */
716218334Speter  mode = (GET_CODE (assign) == STRICT_LOW_PART
716318334Speter	  ? GET_MODE (XEXP (assign, 0)) : GET_MODE (assign));
716418334Speter
716518334Speter  /* Shift OTHER right POS places and make it the source, restricting it
716618334Speter     to the proper length and mode.  */
716718334Speter
716818334Speter  src = force_to_mode (simplify_shift_const (NULL_RTX, LSHIFTRT,
716918334Speter					     GET_MODE (src), other, pos),
717018334Speter		       mode,
717118334Speter		       GET_MODE_BITSIZE (mode) >= HOST_BITS_PER_WIDE_INT
717218334Speter		       ? GET_MODE_MASK (mode)
717318334Speter		       : ((HOST_WIDE_INT) 1 << len) - 1,
717418334Speter		       dest, 0);
717518334Speter
717618334Speter  return gen_rtx_combine (SET, VOIDmode, assign, src);
717718334Speter}
717818334Speter
717918334Speter/* See if X is of the form (+ (* a c) (* b c)) and convert to (* (+ a b) c)
718018334Speter   if so.  */
718118334Speter
718218334Speterstatic rtx
718318334Speterapply_distributive_law (x)
718418334Speter     rtx x;
718518334Speter{
718618334Speter  enum rtx_code code = GET_CODE (x);
718718334Speter  rtx lhs, rhs, other;
718818334Speter  rtx tem;
718918334Speter  enum rtx_code inner_code;
719018334Speter
719118334Speter  /* Distributivity is not true for floating point.
719218334Speter     It can change the value.  So don't do it.
719318334Speter     -- rms and moshier@world.std.com.  */
719418334Speter  if (FLOAT_MODE_P (GET_MODE (x)))
719518334Speter    return x;
719618334Speter
719718334Speter  /* The outer operation can only be one of the following:  */
719818334Speter  if (code != IOR && code != AND && code != XOR
719918334Speter      && code != PLUS && code != MINUS)
720018334Speter    return x;
720118334Speter
720218334Speter  lhs = XEXP (x, 0), rhs = XEXP (x, 1);
720318334Speter
720450397Sobrien  /* If either operand is a primitive we can't do anything, so get out
720550397Sobrien     fast.  */
720618334Speter  if (GET_RTX_CLASS (GET_CODE (lhs)) == 'o'
720718334Speter      || GET_RTX_CLASS (GET_CODE (rhs)) == 'o')
720818334Speter    return x;
720918334Speter
721018334Speter  lhs = expand_compound_operation (lhs);
721118334Speter  rhs = expand_compound_operation (rhs);
721218334Speter  inner_code = GET_CODE (lhs);
721318334Speter  if (inner_code != GET_CODE (rhs))
721418334Speter    return x;
721518334Speter
721618334Speter  /* See if the inner and outer operations distribute.  */
721718334Speter  switch (inner_code)
721818334Speter    {
721918334Speter    case LSHIFTRT:
722018334Speter    case ASHIFTRT:
722118334Speter    case AND:
722218334Speter    case IOR:
722318334Speter      /* These all distribute except over PLUS.  */
722418334Speter      if (code == PLUS || code == MINUS)
722518334Speter	return x;
722618334Speter      break;
722718334Speter
722818334Speter    case MULT:
722918334Speter      if (code != PLUS && code != MINUS)
723018334Speter	return x;
723118334Speter      break;
723218334Speter
723318334Speter    case ASHIFT:
723418334Speter      /* This is also a multiply, so it distributes over everything.  */
723518334Speter      break;
723618334Speter
723718334Speter    case SUBREG:
723818334Speter      /* Non-paradoxical SUBREGs distributes over all operations, provided
723918334Speter	 the inner modes and word numbers are the same, this is an extraction
724018334Speter	 of a low-order part, we don't convert an fp operation to int or
724118334Speter	 vice versa, and we would not be converting a single-word
724218334Speter	 operation into a multi-word operation.  The latter test is not
724318334Speter	 required, but it prevents generating unneeded multi-word operations.
724418334Speter	 Some of the previous tests are redundant given the latter test, but
724518334Speter	 are retained because they are required for correctness.
724618334Speter
724718334Speter	 We produce the result slightly differently in this case.  */
724818334Speter
724918334Speter      if (GET_MODE (SUBREG_REG (lhs)) != GET_MODE (SUBREG_REG (rhs))
725018334Speter	  || SUBREG_WORD (lhs) != SUBREG_WORD (rhs)
725118334Speter	  || ! subreg_lowpart_p (lhs)
725218334Speter	  || (GET_MODE_CLASS (GET_MODE (lhs))
725318334Speter	      != GET_MODE_CLASS (GET_MODE (SUBREG_REG (lhs))))
725418334Speter	  || (GET_MODE_SIZE (GET_MODE (lhs))
725518334Speter	      > GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))))
725618334Speter	  || GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))) > UNITS_PER_WORD)
725718334Speter	return x;
725818334Speter
725918334Speter      tem = gen_binary (code, GET_MODE (SUBREG_REG (lhs)),
726018334Speter			SUBREG_REG (lhs), SUBREG_REG (rhs));
726118334Speter      return gen_lowpart_for_combine (GET_MODE (x), tem);
726218334Speter
726318334Speter    default:
726418334Speter      return x;
726518334Speter    }
726618334Speter
726718334Speter  /* Set LHS and RHS to the inner operands (A and B in the example
726818334Speter     above) and set OTHER to the common operand (C in the example).
726918334Speter     These is only one way to do this unless the inner operation is
727018334Speter     commutative.  */
727118334Speter  if (GET_RTX_CLASS (inner_code) == 'c'
727218334Speter      && rtx_equal_p (XEXP (lhs, 0), XEXP (rhs, 0)))
727318334Speter    other = XEXP (lhs, 0), lhs = XEXP (lhs, 1), rhs = XEXP (rhs, 1);
727418334Speter  else if (GET_RTX_CLASS (inner_code) == 'c'
727518334Speter	   && rtx_equal_p (XEXP (lhs, 0), XEXP (rhs, 1)))
727618334Speter    other = XEXP (lhs, 0), lhs = XEXP (lhs, 1), rhs = XEXP (rhs, 0);
727718334Speter  else if (GET_RTX_CLASS (inner_code) == 'c'
727818334Speter	   && rtx_equal_p (XEXP (lhs, 1), XEXP (rhs, 0)))
727918334Speter    other = XEXP (lhs, 1), lhs = XEXP (lhs, 0), rhs = XEXP (rhs, 1);
728018334Speter  else if (rtx_equal_p (XEXP (lhs, 1), XEXP (rhs, 1)))
728118334Speter    other = XEXP (lhs, 1), lhs = XEXP (lhs, 0), rhs = XEXP (rhs, 0);
728218334Speter  else
728318334Speter    return x;
728418334Speter
728518334Speter  /* Form the new inner operation, seeing if it simplifies first.  */
728618334Speter  tem = gen_binary (code, GET_MODE (x), lhs, rhs);
728718334Speter
728818334Speter  /* There is one exception to the general way of distributing:
728918334Speter     (a ^ b) | (a ^ c) -> (~a) & (b ^ c)  */
729018334Speter  if (code == XOR && inner_code == IOR)
729118334Speter    {
729218334Speter      inner_code = AND;
729318334Speter      other = gen_unary (NOT, GET_MODE (x), GET_MODE (x), other);
729418334Speter    }
729518334Speter
729618334Speter  /* We may be able to continuing distributing the result, so call
729718334Speter     ourselves recursively on the inner operation before forming the
729818334Speter     outer operation, which we return.  */
729918334Speter  return gen_binary (inner_code, GET_MODE (x),
730018334Speter		     apply_distributive_law (tem), other);
730118334Speter}
730218334Speter
730318334Speter/* We have X, a logical `and' of VAROP with the constant CONSTOP, to be done
730418334Speter   in MODE.
730518334Speter
730618334Speter   Return an equivalent form, if different from X.  Otherwise, return X.  If
730718334Speter   X is zero, we are to always construct the equivalent form.  */
730818334Speter
730918334Speterstatic rtx
731018334Spetersimplify_and_const_int (x, mode, varop, constop)
731118334Speter     rtx x;
731218334Speter     enum machine_mode mode;
731318334Speter     rtx varop;
731418334Speter     unsigned HOST_WIDE_INT constop;
731518334Speter{
731618334Speter  unsigned HOST_WIDE_INT nonzero;
731718334Speter  int width = GET_MODE_BITSIZE (mode);
731818334Speter  int i;
731918334Speter
732018334Speter  /* Simplify VAROP knowing that we will be only looking at some of the
732118334Speter     bits in it.  */
732218334Speter  varop = force_to_mode (varop, mode, constop, NULL_RTX, 0);
732318334Speter
732418334Speter  /* If VAROP is a CLOBBER, we will fail so return it; if it is a
732518334Speter     CONST_INT, we are done.  */
732618334Speter  if (GET_CODE (varop) == CLOBBER || GET_CODE (varop) == CONST_INT)
732718334Speter    return varop;
732818334Speter
732918334Speter  /* See what bits may be nonzero in VAROP.  Unlike the general case of
733018334Speter     a call to nonzero_bits, here we don't care about bits outside
733118334Speter     MODE.  */
733218334Speter
733318334Speter  nonzero = nonzero_bits (varop, mode) & GET_MODE_MASK (mode);
733418334Speter
733518334Speter  /* If this would be an entire word for the target, but is not for
733618334Speter     the host, then sign-extend on the host so that the number will look
733718334Speter     the same way on the host that it would on the target.
733818334Speter
733918334Speter     For example, when building a 64 bit alpha hosted 32 bit sparc
734018334Speter     targeted compiler, then we want the 32 bit unsigned value -1 to be
734118334Speter     represented as a 64 bit value -1, and not as 0x00000000ffffffff.
734218334Speter     The later confuses the sparc backend.  */
734318334Speter
734418334Speter  if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
734518334Speter      && (nonzero & ((HOST_WIDE_INT) 1 << (width - 1))))
734618334Speter    nonzero |= ((HOST_WIDE_INT) (-1) << width);
734718334Speter
734818334Speter  /* Turn off all bits in the constant that are known to already be zero.
734918334Speter     Thus, if the AND isn't needed at all, we will have CONSTOP == NONZERO_BITS
735018334Speter     which is tested below.  */
735118334Speter
735218334Speter  constop &= nonzero;
735318334Speter
735418334Speter  /* If we don't have any bits left, return zero.  */
735518334Speter  if (constop == 0)
735618334Speter    return const0_rtx;
735718334Speter
735818334Speter  /* If VAROP is a NEG of something known to be zero or 1 and CONSTOP is
735918334Speter     a power of two, we can replace this with a ASHIFT.  */
736018334Speter  if (GET_CODE (varop) == NEG && nonzero_bits (XEXP (varop, 0), mode) == 1
736118334Speter      && (i = exact_log2 (constop)) >= 0)
736218334Speter    return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (varop, 0), i);
736318334Speter
736418334Speter  /* If VAROP is an IOR or XOR, apply the AND to both branches of the IOR
736518334Speter     or XOR, then try to apply the distributive law.  This may eliminate
736618334Speter     operations if either branch can be simplified because of the AND.
736718334Speter     It may also make some cases more complex, but those cases probably
736818334Speter     won't match a pattern either with or without this.  */
736918334Speter
737018334Speter  if (GET_CODE (varop) == IOR || GET_CODE (varop) == XOR)
737118334Speter    return
737218334Speter      gen_lowpart_for_combine
737318334Speter	(mode,
737418334Speter	 apply_distributive_law
737518334Speter	 (gen_binary (GET_CODE (varop), GET_MODE (varop),
737618334Speter		      simplify_and_const_int (NULL_RTX, GET_MODE (varop),
737718334Speter					      XEXP (varop, 0), constop),
737818334Speter		      simplify_and_const_int (NULL_RTX, GET_MODE (varop),
737918334Speter					      XEXP (varop, 1), constop))));
738018334Speter
738118334Speter  /* Get VAROP in MODE.  Try to get a SUBREG if not.  Don't make a new SUBREG
738218334Speter     if we already had one (just check for the simplest cases).  */
738318334Speter  if (x && GET_CODE (XEXP (x, 0)) == SUBREG
738418334Speter      && GET_MODE (XEXP (x, 0)) == mode
738518334Speter      && SUBREG_REG (XEXP (x, 0)) == varop)
738618334Speter    varop = XEXP (x, 0);
738718334Speter  else
738818334Speter    varop = gen_lowpart_for_combine (mode, varop);
738918334Speter
739050397Sobrien  /* If we can't make the SUBREG, try to return what we were given.  */
739118334Speter  if (GET_CODE (varop) == CLOBBER)
739218334Speter    return x ? x : varop;
739318334Speter
739418334Speter  /* If we are only masking insignificant bits, return VAROP.  */
739518334Speter  if (constop == nonzero)
739618334Speter    x = varop;
739718334Speter
739818334Speter  /* Otherwise, return an AND.  See how much, if any, of X we can use.  */
739918334Speter  else if (x == 0 || GET_CODE (x) != AND || GET_MODE (x) != mode)
740018334Speter    x = gen_binary (AND, mode, varop, GEN_INT (constop));
740118334Speter
740218334Speter  else
740318334Speter    {
740418334Speter      if (GET_CODE (XEXP (x, 1)) != CONST_INT
740552284Sobrien	  || (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) != constop)
740618334Speter	SUBST (XEXP (x, 1), GEN_INT (constop));
740718334Speter
740818334Speter      SUBST (XEXP (x, 0), varop);
740918334Speter    }
741018334Speter
741118334Speter  return x;
741218334Speter}
741318334Speter
741450397Sobrien/* We let num_sign_bit_copies recur into nonzero_bits as that is useful.
741550397Sobrien   We don't let nonzero_bits recur into num_sign_bit_copies, because that
741650397Sobrien   is less useful.  We can't allow both, because that results in exponential
741750397Sobrien   run time recursion.  There is a nullstone testcase that triggered
741850397Sobrien   this.  This macro avoids accidental uses of num_sign_bit_copies.  */
741950397Sobrien#define num_sign_bit_copies()
742050397Sobrien
742118334Speter/* Given an expression, X, compute which bits in X can be non-zero.
742218334Speter   We don't care about bits outside of those defined in MODE.
742318334Speter
742418334Speter   For most X this is simply GET_MODE_MASK (GET_MODE (MODE)), but if X is
742518334Speter   a shift, AND, or zero_extract, we can do better.  */
742618334Speter
742718334Speterstatic unsigned HOST_WIDE_INT
742818334Speternonzero_bits (x, mode)
742918334Speter     rtx x;
743018334Speter     enum machine_mode mode;
743118334Speter{
743218334Speter  unsigned HOST_WIDE_INT nonzero = GET_MODE_MASK (mode);
743318334Speter  unsigned HOST_WIDE_INT inner_nz;
743418334Speter  enum rtx_code code;
743518334Speter  int mode_width = GET_MODE_BITSIZE (mode);
743618334Speter  rtx tem;
743718334Speter
743818334Speter  /* For floating-point values, assume all bits are needed.  */
743918334Speter  if (FLOAT_MODE_P (GET_MODE (x)) || FLOAT_MODE_P (mode))
744018334Speter    return nonzero;
744118334Speter
744218334Speter  /* If X is wider than MODE, use its mode instead.  */
744318334Speter  if (GET_MODE_BITSIZE (GET_MODE (x)) > mode_width)
744418334Speter    {
744518334Speter      mode = GET_MODE (x);
744618334Speter      nonzero = GET_MODE_MASK (mode);
744718334Speter      mode_width = GET_MODE_BITSIZE (mode);
744818334Speter    }
744918334Speter
745018334Speter  if (mode_width > HOST_BITS_PER_WIDE_INT)
745118334Speter    /* Our only callers in this case look for single bit values.  So
745218334Speter       just return the mode mask.  Those tests will then be false.  */
745318334Speter    return nonzero;
745418334Speter
745518334Speter#ifndef WORD_REGISTER_OPERATIONS
745618334Speter  /* If MODE is wider than X, but both are a single word for both the host
745718334Speter     and target machines, we can compute this from which bits of the
745818334Speter     object might be nonzero in its own mode, taking into account the fact
745918334Speter     that on many CISC machines, accessing an object in a wider mode
746018334Speter     causes the high-order bits to become undefined.  So they are
746118334Speter     not known to be zero.  */
746218334Speter
746318334Speter  if (GET_MODE (x) != VOIDmode && GET_MODE (x) != mode
746418334Speter      && GET_MODE_BITSIZE (GET_MODE (x)) <= BITS_PER_WORD
746518334Speter      && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
746618334Speter      && GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (GET_MODE (x)))
746718334Speter    {
746818334Speter      nonzero &= nonzero_bits (x, GET_MODE (x));
746918334Speter      nonzero |= GET_MODE_MASK (mode) & ~ GET_MODE_MASK (GET_MODE (x));
747018334Speter      return nonzero;
747118334Speter    }
747218334Speter#endif
747318334Speter
747418334Speter  code = GET_CODE (x);
747518334Speter  switch (code)
747618334Speter    {
747718334Speter    case REG:
747818334Speter#ifdef POINTERS_EXTEND_UNSIGNED
747918334Speter      /* If pointers extend unsigned and this is a pointer in Pmode, say that
748018334Speter	 all the bits above ptr_mode are known to be zero.  */
748118334Speter      if (POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
748218334Speter	  && REGNO_POINTER_FLAG (REGNO (x)))
748318334Speter	nonzero &= GET_MODE_MASK (ptr_mode);
748418334Speter#endif
748518334Speter
748618334Speter#ifdef STACK_BOUNDARY
748718334Speter      /* If this is the stack pointer, we may know something about its
748818334Speter	 alignment.  If PUSH_ROUNDING is defined, it is possible for the
748918334Speter	 stack to be momentarily aligned only to that amount, so we pick
749018334Speter	 the least alignment.  */
749118334Speter
749250397Sobrien      /* We can't check for arg_pointer_rtx here, because it is not
749350397Sobrien	 guaranteed to have as much alignment as the stack pointer.
749450397Sobrien	 In particular, in the Irix6 n64 ABI, the stack has 128 bit
749550397Sobrien	 alignment but the argument pointer has only 64 bit alignment.  */
749650397Sobrien
749750397Sobrien      if ((x == frame_pointer_rtx
749850397Sobrien	   || x == stack_pointer_rtx
749950397Sobrien	   || x == hard_frame_pointer_rtx
750050397Sobrien	   || (REGNO (x) >= FIRST_VIRTUAL_REGISTER
750150397Sobrien	       && REGNO (x) <= LAST_VIRTUAL_REGISTER))
750250397Sobrien#ifdef STACK_BIAS
750350397Sobrien	  && !STACK_BIAS
750450397Sobrien#endif
750550397Sobrien	      )
750618334Speter	{
750718334Speter	  int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
750818334Speter
750918334Speter#ifdef PUSH_ROUNDING
751050397Sobrien	  if (REGNO (x) == STACK_POINTER_REGNUM)
751150397Sobrien	    sp_alignment = MIN (PUSH_ROUNDING (1), sp_alignment);
751218334Speter#endif
751318334Speter
751418334Speter	  /* We must return here, otherwise we may get a worse result from
751518334Speter	     one of the choices below.  There is nothing useful below as
751618334Speter	     far as the stack pointer is concerned.  */
751718334Speter	  return nonzero &= ~ (sp_alignment - 1);
751818334Speter	}
751918334Speter#endif
752018334Speter
752118334Speter      /* If X is a register whose nonzero bits value is current, use it.
752218334Speter	 Otherwise, if X is a register whose value we can find, use that
752318334Speter	 value.  Otherwise, use the previously-computed global nonzero bits
752418334Speter	 for this register.  */
752518334Speter
752618334Speter      if (reg_last_set_value[REGNO (x)] != 0
752718334Speter	  && reg_last_set_mode[REGNO (x)] == mode
752850397Sobrien	  && (REG_N_SETS (REGNO (x)) == 1
752918334Speter	      || reg_last_set_label[REGNO (x)] == label_tick)
753018334Speter	  && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
753118334Speter	return reg_last_set_nonzero_bits[REGNO (x)];
753218334Speter
753318334Speter      tem = get_last_value (x);
753418334Speter
753518334Speter      if (tem)
753618334Speter	{
753718334Speter#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
753818334Speter	  /* If X is narrower than MODE and TEM is a non-negative
753918334Speter	     constant that would appear negative in the mode of X,
754018334Speter	     sign-extend it for use in reg_nonzero_bits because some
754118334Speter	     machines (maybe most) will actually do the sign-extension
754218334Speter	     and this is the conservative approach.
754318334Speter
754418334Speter	     ??? For 2.5, try to tighten up the MD files in this regard
754518334Speter	     instead of this kludge.  */
754618334Speter
754718334Speter	  if (GET_MODE_BITSIZE (GET_MODE (x)) < mode_width
754818334Speter	      && GET_CODE (tem) == CONST_INT
754918334Speter	      && INTVAL (tem) > 0
755018334Speter	      && 0 != (INTVAL (tem)
755118334Speter		       & ((HOST_WIDE_INT) 1
755218334Speter			  << (GET_MODE_BITSIZE (GET_MODE (x)) - 1))))
755318334Speter	    tem = GEN_INT (INTVAL (tem)
755418334Speter			   | ((HOST_WIDE_INT) (-1)
755518334Speter			      << GET_MODE_BITSIZE (GET_MODE (x))));
755618334Speter#endif
755718334Speter	  return nonzero_bits (tem, mode);
755818334Speter	}
755918334Speter      else if (nonzero_sign_valid && reg_nonzero_bits[REGNO (x)])
756018334Speter	return reg_nonzero_bits[REGNO (x)] & nonzero;
756118334Speter      else
756218334Speter	return nonzero;
756318334Speter
756418334Speter    case CONST_INT:
756518334Speter#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
756618334Speter      /* If X is negative in MODE, sign-extend the value.  */
756718334Speter      if (INTVAL (x) > 0 && mode_width < BITS_PER_WORD
756818334Speter	  && 0 != (INTVAL (x) & ((HOST_WIDE_INT) 1 << (mode_width - 1))))
756918334Speter	return (INTVAL (x) | ((HOST_WIDE_INT) (-1) << mode_width));
757018334Speter#endif
757118334Speter
757218334Speter      return INTVAL (x);
757318334Speter
757418334Speter    case MEM:
757518334Speter#ifdef LOAD_EXTEND_OP
757618334Speter      /* In many, if not most, RISC machines, reading a byte from memory
757718334Speter	 zeros the rest of the register.  Noticing that fact saves a lot
757818334Speter	 of extra zero-extends.  */
757918334Speter      if (LOAD_EXTEND_OP (GET_MODE (x)) == ZERO_EXTEND)
758018334Speter	nonzero &= GET_MODE_MASK (GET_MODE (x));
758118334Speter#endif
758218334Speter      break;
758318334Speter
758418334Speter    case EQ:  case NE:
758518334Speter    case GT:  case GTU:
758618334Speter    case LT:  case LTU:
758718334Speter    case GE:  case GEU:
758818334Speter    case LE:  case LEU:
758918334Speter
759018334Speter      /* If this produces an integer result, we know which bits are set.
759118334Speter	 Code here used to clear bits outside the mode of X, but that is
759218334Speter	 now done above.  */
759318334Speter
759418334Speter      if (GET_MODE_CLASS (mode) == MODE_INT
759518334Speter	  && mode_width <= HOST_BITS_PER_WIDE_INT)
759618334Speter	nonzero = STORE_FLAG_VALUE;
759718334Speter      break;
759818334Speter
759918334Speter    case NEG:
760050397Sobrien#if 0
760150397Sobrien      /* Disabled to avoid exponential mutual recursion between nonzero_bits
760250397Sobrien	 and num_sign_bit_copies.  */
760318334Speter      if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (x))
760418334Speter	  == GET_MODE_BITSIZE (GET_MODE (x)))
760518334Speter	nonzero = 1;
760650397Sobrien#endif
760718334Speter
760818334Speter      if (GET_MODE_SIZE (GET_MODE (x)) < mode_width)
760918334Speter	nonzero |= (GET_MODE_MASK (mode) & ~ GET_MODE_MASK (GET_MODE (x)));
761018334Speter      break;
761118334Speter
761218334Speter    case ABS:
761350397Sobrien#if 0
761450397Sobrien      /* Disabled to avoid exponential mutual recursion between nonzero_bits
761550397Sobrien	 and num_sign_bit_copies.  */
761618334Speter      if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (x))
761718334Speter	  == GET_MODE_BITSIZE (GET_MODE (x)))
761818334Speter	nonzero = 1;
761950397Sobrien#endif
762018334Speter      break;
762118334Speter
762218334Speter    case TRUNCATE:
762318334Speter      nonzero &= (nonzero_bits (XEXP (x, 0), mode) & GET_MODE_MASK (mode));
762418334Speter      break;
762518334Speter
762618334Speter    case ZERO_EXTEND:
762718334Speter      nonzero &= nonzero_bits (XEXP (x, 0), mode);
762818334Speter      if (GET_MODE (XEXP (x, 0)) != VOIDmode)
762918334Speter	nonzero &= GET_MODE_MASK (GET_MODE (XEXP (x, 0)));
763018334Speter      break;
763118334Speter
763218334Speter    case SIGN_EXTEND:
763318334Speter      /* If the sign bit is known clear, this is the same as ZERO_EXTEND.
763418334Speter	 Otherwise, show all the bits in the outer mode but not the inner
763518334Speter	 may be non-zero.  */
763618334Speter      inner_nz = nonzero_bits (XEXP (x, 0), mode);
763718334Speter      if (GET_MODE (XEXP (x, 0)) != VOIDmode)
763818334Speter	{
763918334Speter	  inner_nz &= GET_MODE_MASK (GET_MODE (XEXP (x, 0)));
764050397Sobrien	  if (inner_nz
764150397Sobrien	      & (((HOST_WIDE_INT) 1
764250397Sobrien		  << (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - 1))))
764318334Speter	    inner_nz |= (GET_MODE_MASK (mode)
764418334Speter			  & ~ GET_MODE_MASK (GET_MODE (XEXP (x, 0))));
764518334Speter	}
764618334Speter
764718334Speter      nonzero &= inner_nz;
764818334Speter      break;
764918334Speter
765018334Speter    case AND:
765118334Speter      nonzero &= (nonzero_bits (XEXP (x, 0), mode)
765218334Speter		  & nonzero_bits (XEXP (x, 1), mode));
765318334Speter      break;
765418334Speter
765518334Speter    case XOR:   case IOR:
765618334Speter    case UMIN:  case UMAX:  case SMIN:  case SMAX:
765718334Speter      nonzero &= (nonzero_bits (XEXP (x, 0), mode)
765818334Speter		  | nonzero_bits (XEXP (x, 1), mode));
765918334Speter      break;
766018334Speter
766118334Speter    case PLUS:  case MINUS:
766218334Speter    case MULT:
766318334Speter    case DIV:   case UDIV:
766418334Speter    case MOD:   case UMOD:
766518334Speter      /* We can apply the rules of arithmetic to compute the number of
766618334Speter	 high- and low-order zero bits of these operations.  We start by
766718334Speter	 computing the width (position of the highest-order non-zero bit)
766818334Speter	 and the number of low-order zero bits for each value.  */
766918334Speter      {
767018334Speter	unsigned HOST_WIDE_INT nz0 = nonzero_bits (XEXP (x, 0), mode);
767118334Speter	unsigned HOST_WIDE_INT nz1 = nonzero_bits (XEXP (x, 1), mode);
767218334Speter	int width0 = floor_log2 (nz0) + 1;
767318334Speter	int width1 = floor_log2 (nz1) + 1;
767418334Speter	int low0 = floor_log2 (nz0 & -nz0);
767518334Speter	int low1 = floor_log2 (nz1 & -nz1);
767618334Speter	HOST_WIDE_INT op0_maybe_minusp
767718334Speter	  = (nz0 & ((HOST_WIDE_INT) 1 << (mode_width - 1)));
767818334Speter	HOST_WIDE_INT op1_maybe_minusp
767918334Speter	  = (nz1 & ((HOST_WIDE_INT) 1 << (mode_width - 1)));
768018334Speter	int result_width = mode_width;
768118334Speter	int result_low = 0;
768218334Speter
768318334Speter	switch (code)
768418334Speter	  {
768518334Speter	  case PLUS:
768650397Sobrien#ifdef STACK_BIAS
768750397Sobrien	    if (STACK_BIAS
768850397Sobrien	        && (XEXP (x, 0) == stack_pointer_rtx
768950397Sobrien	            || XEXP (x, 0) == frame_pointer_rtx)
769050397Sobrien	        && GET_CODE (XEXP (x, 1)) == CONST_INT)
769150397Sobrien	      {
769250397Sobrien		int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
769350397Sobrien
769450397Sobrien	        nz0 = (GET_MODE_MASK (mode) & ~ (sp_alignment - 1));
769550397Sobrien	        nz1 = INTVAL (XEXP (x, 1)) - STACK_BIAS;
769650397Sobrien	        width0 = floor_log2 (nz0) + 1;
769750397Sobrien	        width1 = floor_log2 (nz1) + 1;
769850397Sobrien	        low0 = floor_log2 (nz0 & -nz0);
769950397Sobrien	        low1 = floor_log2 (nz1 & -nz1);
770050397Sobrien	      }
770150397Sobrien#endif
770218334Speter	    result_width = MAX (width0, width1) + 1;
770318334Speter	    result_low = MIN (low0, low1);
770418334Speter	    break;
770518334Speter	  case MINUS:
770618334Speter	    result_low = MIN (low0, low1);
770718334Speter	    break;
770818334Speter	  case MULT:
770918334Speter	    result_width = width0 + width1;
771018334Speter	    result_low = low0 + low1;
771118334Speter	    break;
771218334Speter	  case DIV:
771318334Speter	    if (! op0_maybe_minusp && ! op1_maybe_minusp)
771418334Speter	      result_width = width0;
771518334Speter	    break;
771618334Speter	  case UDIV:
771718334Speter	    result_width = width0;
771818334Speter	    break;
771918334Speter	  case MOD:
772018334Speter	    if (! op0_maybe_minusp && ! op1_maybe_minusp)
772118334Speter	      result_width = MIN (width0, width1);
772218334Speter	    result_low = MIN (low0, low1);
772318334Speter	    break;
772418334Speter	  case UMOD:
772518334Speter	    result_width = MIN (width0, width1);
772618334Speter	    result_low = MIN (low0, low1);
772718334Speter	    break;
772850397Sobrien	  default:
772950397Sobrien	    abort ();
773018334Speter	  }
773118334Speter
773218334Speter	if (result_width < mode_width)
773318334Speter	  nonzero &= ((HOST_WIDE_INT) 1 << result_width) - 1;
773418334Speter
773518334Speter	if (result_low > 0)
773618334Speter	  nonzero &= ~ (((HOST_WIDE_INT) 1 << result_low) - 1);
773718334Speter      }
773818334Speter      break;
773918334Speter
774018334Speter    case ZERO_EXTRACT:
774118334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
774218334Speter	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
774318334Speter	nonzero &= ((HOST_WIDE_INT) 1 << INTVAL (XEXP (x, 1))) - 1;
774418334Speter      break;
774518334Speter
774618334Speter    case SUBREG:
774718334Speter      /* If this is a SUBREG formed for a promoted variable that has
774818334Speter	 been zero-extended, we know that at least the high-order bits
774918334Speter	 are zero, though others might be too.  */
775018334Speter
775118334Speter      if (SUBREG_PROMOTED_VAR_P (x) && SUBREG_PROMOTED_UNSIGNED_P (x))
775218334Speter	nonzero = (GET_MODE_MASK (GET_MODE (x))
775318334Speter		   & nonzero_bits (SUBREG_REG (x), GET_MODE (x)));
775418334Speter
775518334Speter      /* If the inner mode is a single word for both the host and target
775618334Speter	 machines, we can compute this from which bits of the inner
775718334Speter	 object might be nonzero.  */
775818334Speter      if (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) <= BITS_PER_WORD
775918334Speter	  && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
776018334Speter	      <= HOST_BITS_PER_WIDE_INT))
776118334Speter	{
776218334Speter	  nonzero &= nonzero_bits (SUBREG_REG (x), mode);
776318334Speter
776450397Sobrien#if defined (WORD_REGISTER_OPERATIONS) && defined (LOAD_EXTEND_OP)
776550397Sobrien	  /* If this is a typical RISC machine, we only have to worry
776650397Sobrien	     about the way loads are extended.  */
776750397Sobrien	  if (LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND
776850397Sobrien	      ? (nonzero
776950397Sobrien		 & (1L << (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) - 1)))
777050397Sobrien	      : LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) != ZERO_EXTEND)
777118334Speter#endif
777250397Sobrien	    {
777350397Sobrien	      /* On many CISC machines, accessing an object in a wider mode
777450397Sobrien		 causes the high-order bits to become undefined.  So they are
777550397Sobrien		 not known to be zero.  */
777650397Sobrien	      if (GET_MODE_SIZE (GET_MODE (x))
777750397Sobrien		  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
777850397Sobrien		nonzero |= (GET_MODE_MASK (GET_MODE (x))
777950397Sobrien			    & ~ GET_MODE_MASK (GET_MODE (SUBREG_REG (x))));
778050397Sobrien	    }
778118334Speter	}
778218334Speter      break;
778318334Speter
778418334Speter    case ASHIFTRT:
778518334Speter    case LSHIFTRT:
778618334Speter    case ASHIFT:
778718334Speter    case ROTATE:
778818334Speter      /* The nonzero bits are in two classes: any bits within MODE
778918334Speter	 that aren't in GET_MODE (x) are always significant.  The rest of the
779018334Speter	 nonzero bits are those that are significant in the operand of
779118334Speter	 the shift when shifted the appropriate number of bits.  This
779218334Speter	 shows that high-order bits are cleared by the right shift and
779318334Speter	 low-order bits by left shifts.  */
779418334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
779518334Speter	  && INTVAL (XEXP (x, 1)) >= 0
779618334Speter	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
779718334Speter	{
779818334Speter	  enum machine_mode inner_mode = GET_MODE (x);
779918334Speter	  int width = GET_MODE_BITSIZE (inner_mode);
780018334Speter	  int count = INTVAL (XEXP (x, 1));
780118334Speter	  unsigned HOST_WIDE_INT mode_mask = GET_MODE_MASK (inner_mode);
780218334Speter	  unsigned HOST_WIDE_INT op_nonzero = nonzero_bits (XEXP (x, 0), mode);
780318334Speter	  unsigned HOST_WIDE_INT inner = op_nonzero & mode_mask;
780418334Speter	  unsigned HOST_WIDE_INT outer = 0;
780518334Speter
780618334Speter	  if (mode_width > width)
780718334Speter	    outer = (op_nonzero & nonzero & ~ mode_mask);
780818334Speter
780918334Speter	  if (code == LSHIFTRT)
781018334Speter	    inner >>= count;
781118334Speter	  else if (code == ASHIFTRT)
781218334Speter	    {
781318334Speter	      inner >>= count;
781418334Speter
781518334Speter	      /* If the sign bit may have been nonzero before the shift, we
781618334Speter		 need to mark all the places it could have been copied to
781718334Speter		 by the shift as possibly nonzero.  */
781818334Speter	      if (inner & ((HOST_WIDE_INT) 1 << (width - 1 - count)))
781918334Speter		inner |= (((HOST_WIDE_INT) 1 << count) - 1) << (width - count);
782018334Speter	    }
782118334Speter	  else if (code == ASHIFT)
782218334Speter	    inner <<= count;
782318334Speter	  else
782418334Speter	    inner = ((inner << (count % width)
782518334Speter		      | (inner >> (width - (count % width)))) & mode_mask);
782618334Speter
782718334Speter	  nonzero &= (outer | inner);
782818334Speter	}
782918334Speter      break;
783018334Speter
783118334Speter    case FFS:
783218334Speter      /* This is at most the number of bits in the mode.  */
783318334Speter      nonzero = ((HOST_WIDE_INT) 1 << (floor_log2 (mode_width) + 1)) - 1;
783418334Speter      break;
783518334Speter
783618334Speter    case IF_THEN_ELSE:
783718334Speter      nonzero &= (nonzero_bits (XEXP (x, 1), mode)
783818334Speter		  | nonzero_bits (XEXP (x, 2), mode));
783918334Speter      break;
784050397Sobrien
784150397Sobrien    default:
784250397Sobrien      break;
784318334Speter    }
784418334Speter
784518334Speter  return nonzero;
784618334Speter}
784750397Sobrien
784850397Sobrien/* See the macro definition above.  */
784950397Sobrien#undef num_sign_bit_copies
785018334Speter
785118334Speter/* Return the number of bits at the high-order end of X that are known to
785218334Speter   be equal to the sign bit.  X will be used in mode MODE; if MODE is
785318334Speter   VOIDmode, X will be used in its own mode.  The returned value  will always
785418334Speter   be between 1 and the number of bits in MODE.  */
785518334Speter
785618334Speterstatic int
785718334Speternum_sign_bit_copies (x, mode)
785818334Speter     rtx x;
785918334Speter     enum machine_mode mode;
786018334Speter{
786118334Speter  enum rtx_code code = GET_CODE (x);
786218334Speter  int bitwidth;
786318334Speter  int num0, num1, result;
786418334Speter  unsigned HOST_WIDE_INT nonzero;
786518334Speter  rtx tem;
786618334Speter
786718334Speter  /* If we weren't given a mode, use the mode of X.  If the mode is still
786818334Speter     VOIDmode, we don't know anything.  Likewise if one of the modes is
786918334Speter     floating-point.  */
787018334Speter
787118334Speter  if (mode == VOIDmode)
787218334Speter    mode = GET_MODE (x);
787318334Speter
787418334Speter  if (mode == VOIDmode || FLOAT_MODE_P (mode) || FLOAT_MODE_P (GET_MODE (x)))
787518334Speter    return 1;
787618334Speter
787718334Speter  bitwidth = GET_MODE_BITSIZE (mode);
787818334Speter
787950397Sobrien  /* For a smaller object, just ignore the high bits.  */
788018334Speter  if (bitwidth < GET_MODE_BITSIZE (GET_MODE (x)))
788118334Speter    return MAX (1, (num_sign_bit_copies (x, GET_MODE (x))
788218334Speter		    - (GET_MODE_BITSIZE (GET_MODE (x)) - bitwidth)));
788318334Speter
788450397Sobrien  if (GET_MODE (x) != VOIDmode && bitwidth > GET_MODE_BITSIZE (GET_MODE (x)))
788550397Sobrien    {
788618334Speter#ifndef WORD_REGISTER_OPERATIONS
788718334Speter  /* If this machine does not do all register operations on the entire
788818334Speter     register and MODE is wider than the mode of X, we can say nothing
788918334Speter     at all about the high-order bits.  */
789050397Sobrien      return 1;
789150397Sobrien#else
789250397Sobrien      /* Likewise on machines that do, if the mode of the object is smaller
789350397Sobrien	 than a word and loads of that size don't sign extend, we can say
789450397Sobrien	 nothing about the high order bits.  */
789550397Sobrien      if (GET_MODE_BITSIZE (GET_MODE (x)) < BITS_PER_WORD
789650397Sobrien#ifdef LOAD_EXTEND_OP
789750397Sobrien	  && LOAD_EXTEND_OP (GET_MODE (x)) != SIGN_EXTEND
789818334Speter#endif
789950397Sobrien	  )
790050397Sobrien	return 1;
790150397Sobrien#endif
790250397Sobrien    }
790318334Speter
790418334Speter  switch (code)
790518334Speter    {
790618334Speter    case REG:
790718334Speter
790818334Speter#ifdef POINTERS_EXTEND_UNSIGNED
790918334Speter      /* If pointers extend signed and this is a pointer in Pmode, say that
791018334Speter	 all the bits above ptr_mode are known to be sign bit copies.  */
791118334Speter      if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode && mode == Pmode
791218334Speter	  && REGNO_POINTER_FLAG (REGNO (x)))
791318334Speter	return GET_MODE_BITSIZE (Pmode) - GET_MODE_BITSIZE (ptr_mode) + 1;
791418334Speter#endif
791518334Speter
791618334Speter      if (reg_last_set_value[REGNO (x)] != 0
791718334Speter	  && reg_last_set_mode[REGNO (x)] == mode
791850397Sobrien	  && (REG_N_SETS (REGNO (x)) == 1
791918334Speter	      || reg_last_set_label[REGNO (x)] == label_tick)
792018334Speter	  && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
792118334Speter	return reg_last_set_sign_bit_copies[REGNO (x)];
792218334Speter
792318334Speter      tem =  get_last_value (x);
792418334Speter      if (tem != 0)
792518334Speter	return num_sign_bit_copies (tem, mode);
792618334Speter
792718334Speter      if (nonzero_sign_valid && reg_sign_bit_copies[REGNO (x)] != 0)
792818334Speter	return reg_sign_bit_copies[REGNO (x)];
792918334Speter      break;
793018334Speter
793118334Speter    case MEM:
793218334Speter#ifdef LOAD_EXTEND_OP
793318334Speter      /* Some RISC machines sign-extend all loads of smaller than a word.  */
793418334Speter      if (LOAD_EXTEND_OP (GET_MODE (x)) == SIGN_EXTEND)
793518334Speter	return MAX (1, bitwidth - GET_MODE_BITSIZE (GET_MODE (x)) + 1);
793618334Speter#endif
793718334Speter      break;
793818334Speter
793918334Speter    case CONST_INT:
794018334Speter      /* If the constant is negative, take its 1's complement and remask.
794118334Speter	 Then see how many zero bits we have.  */
794218334Speter      nonzero = INTVAL (x) & GET_MODE_MASK (mode);
794318334Speter      if (bitwidth <= HOST_BITS_PER_WIDE_INT
794418334Speter	  && (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
794518334Speter	nonzero = (~ nonzero) & GET_MODE_MASK (mode);
794618334Speter
794718334Speter      return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1);
794818334Speter
794918334Speter    case SUBREG:
795018334Speter      /* If this is a SUBREG for a promoted object that is sign-extended
795118334Speter	 and we are looking at it in a wider mode, we know that at least the
795218334Speter	 high-order bits are known to be sign bit copies.  */
795318334Speter
795418334Speter      if (SUBREG_PROMOTED_VAR_P (x) && ! SUBREG_PROMOTED_UNSIGNED_P (x))
795518334Speter	return MAX (bitwidth - GET_MODE_BITSIZE (GET_MODE (x)) + 1,
795618334Speter		    num_sign_bit_copies (SUBREG_REG (x), mode));
795718334Speter
795850397Sobrien      /* For a smaller object, just ignore the high bits.  */
795918334Speter      if (bitwidth <= GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))))
796018334Speter	{
796118334Speter	  num0 = num_sign_bit_copies (SUBREG_REG (x), VOIDmode);
796218334Speter	  return MAX (1, (num0
796318334Speter			  - (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
796418334Speter			     - bitwidth)));
796518334Speter	}
796618334Speter
796718334Speter#ifdef WORD_REGISTER_OPERATIONS
796818334Speter#ifdef LOAD_EXTEND_OP
796918334Speter      /* For paradoxical SUBREGs on machines where all register operations
797018334Speter	 affect the entire register, just look inside.  Note that we are
797118334Speter	 passing MODE to the recursive call, so the number of sign bit copies
797218334Speter	 will remain relative to that mode, not the inner mode.  */
797318334Speter
797418334Speter      /* This works only if loads sign extend.  Otherwise, if we get a
797518334Speter	 reload for the inner part, it may be loaded from the stack, and
797618334Speter	 then we lose all sign bit copies that existed before the store
797718334Speter	 to the stack.  */
797818334Speter
797918334Speter      if ((GET_MODE_SIZE (GET_MODE (x))
798018334Speter	   > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
798118334Speter	  && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND)
798218334Speter	return num_sign_bit_copies (SUBREG_REG (x), mode);
798318334Speter#endif
798418334Speter#endif
798518334Speter      break;
798618334Speter
798718334Speter    case SIGN_EXTRACT:
798818334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
798918334Speter	return MAX (1, bitwidth - INTVAL (XEXP (x, 1)));
799018334Speter      break;
799118334Speter
799218334Speter    case SIGN_EXTEND:
799318334Speter      return (bitwidth - GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
799418334Speter	      + num_sign_bit_copies (XEXP (x, 0), VOIDmode));
799518334Speter
799618334Speter    case TRUNCATE:
799750397Sobrien      /* For a smaller object, just ignore the high bits.  */
799818334Speter      num0 = num_sign_bit_copies (XEXP (x, 0), VOIDmode);
799918334Speter      return MAX (1, (num0 - (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
800018334Speter			      - bitwidth)));
800118334Speter
800218334Speter    case NOT:
800318334Speter      return num_sign_bit_copies (XEXP (x, 0), mode);
800418334Speter
800518334Speter    case ROTATE:       case ROTATERT:
800618334Speter      /* If we are rotating left by a number of bits less than the number
800718334Speter	 of sign bit copies, we can just subtract that amount from the
800818334Speter	 number.  */
800918334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
801018334Speter	  && INTVAL (XEXP (x, 1)) >= 0 && INTVAL (XEXP (x, 1)) < bitwidth)
801118334Speter	{
801218334Speter	  num0 = num_sign_bit_copies (XEXP (x, 0), mode);
801318334Speter	  return MAX (1, num0 - (code == ROTATE ? INTVAL (XEXP (x, 1))
801418334Speter				 : bitwidth - INTVAL (XEXP (x, 1))));
801518334Speter	}
801618334Speter      break;
801718334Speter
801818334Speter    case NEG:
801918334Speter      /* In general, this subtracts one sign bit copy.  But if the value
802018334Speter	 is known to be positive, the number of sign bit copies is the
802118334Speter	 same as that of the input.  Finally, if the input has just one bit
802218334Speter	 that might be nonzero, all the bits are copies of the sign bit.  */
802350397Sobrien      num0 = num_sign_bit_copies (XEXP (x, 0), mode);
802450397Sobrien      if (bitwidth > HOST_BITS_PER_WIDE_INT)
802550397Sobrien	return num0 > 1 ? num0 - 1 : 1;
802650397Sobrien
802718334Speter      nonzero = nonzero_bits (XEXP (x, 0), mode);
802818334Speter      if (nonzero == 1)
802918334Speter	return bitwidth;
803018334Speter
803118334Speter      if (num0 > 1
803218334Speter	  && (((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero))
803318334Speter	num0--;
803418334Speter
803518334Speter      return num0;
803618334Speter
803718334Speter    case IOR:   case AND:   case XOR:
803818334Speter    case SMIN:  case SMAX:  case UMIN:  case UMAX:
803918334Speter      /* Logical operations will preserve the number of sign-bit copies.
804018334Speter	 MIN and MAX operations always return one of the operands.  */
804118334Speter      num0 = num_sign_bit_copies (XEXP (x, 0), mode);
804218334Speter      num1 = num_sign_bit_copies (XEXP (x, 1), mode);
804318334Speter      return MIN (num0, num1);
804418334Speter
804518334Speter    case PLUS:  case MINUS:
804618334Speter      /* For addition and subtraction, we can have a 1-bit carry.  However,
804718334Speter	 if we are subtracting 1 from a positive number, there will not
804818334Speter	 be such a carry.  Furthermore, if the positive number is known to
804918334Speter	 be 0 or 1, we know the result is either -1 or 0.  */
805018334Speter
805118334Speter      if (code == PLUS && XEXP (x, 1) == constm1_rtx
805218334Speter	  && bitwidth <= HOST_BITS_PER_WIDE_INT)
805318334Speter	{
805418334Speter	  nonzero = nonzero_bits (XEXP (x, 0), mode);
805518334Speter	  if ((((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero) == 0)
805618334Speter	    return (nonzero == 1 || nonzero == 0 ? bitwidth
805718334Speter		    : bitwidth - floor_log2 (nonzero) - 1);
805818334Speter	}
805918334Speter
806018334Speter      num0 = num_sign_bit_copies (XEXP (x, 0), mode);
806118334Speter      num1 = num_sign_bit_copies (XEXP (x, 1), mode);
806218334Speter      return MAX (1, MIN (num0, num1) - 1);
806318334Speter
806418334Speter    case MULT:
806518334Speter      /* The number of bits of the product is the sum of the number of
806618334Speter	 bits of both terms.  However, unless one of the terms if known
806718334Speter	 to be positive, we must allow for an additional bit since negating
806818334Speter	 a negative number can remove one sign bit copy.  */
806918334Speter
807018334Speter      num0 = num_sign_bit_copies (XEXP (x, 0), mode);
807118334Speter      num1 = num_sign_bit_copies (XEXP (x, 1), mode);
807218334Speter
807318334Speter      result = bitwidth - (bitwidth - num0) - (bitwidth - num1);
807418334Speter      if (result > 0
807550397Sobrien	  && (bitwidth > HOST_BITS_PER_WIDE_INT
807650397Sobrien	      || (((nonzero_bits (XEXP (x, 0), mode)
807750397Sobrien		    & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
807850397Sobrien		  && ((nonzero_bits (XEXP (x, 1), mode)
807950397Sobrien		       & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))))
808018334Speter	result--;
808118334Speter
808218334Speter      return MAX (1, result);
808318334Speter
808418334Speter    case UDIV:
808550397Sobrien      /* The result must be <= the first operand.  If the first operand
808650397Sobrien         has the high bit set, we know nothing about the number of sign
808750397Sobrien         bit copies.  */
808850397Sobrien      if (bitwidth > HOST_BITS_PER_WIDE_INT)
808950397Sobrien	return 1;
809050397Sobrien      else if ((nonzero_bits (XEXP (x, 0), mode)
809150397Sobrien		& ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
809250397Sobrien	return 1;
809350397Sobrien      else
809450397Sobrien	return num_sign_bit_copies (XEXP (x, 0), mode);
809550397Sobrien
809618334Speter    case UMOD:
809718334Speter      /* The result must be <= the scond operand.  */
809818334Speter      return num_sign_bit_copies (XEXP (x, 1), mode);
809918334Speter
810018334Speter    case DIV:
810118334Speter      /* Similar to unsigned division, except that we have to worry about
810218334Speter	 the case where the divisor is negative, in which case we have
810318334Speter	 to add 1.  */
810418334Speter      result = num_sign_bit_copies (XEXP (x, 0), mode);
810518334Speter      if (result > 1
810650397Sobrien	  && (bitwidth > HOST_BITS_PER_WIDE_INT
810750397Sobrien	      || (nonzero_bits (XEXP (x, 1), mode)
810850397Sobrien		  & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
810950397Sobrien	result--;
811018334Speter
811118334Speter      return result;
811218334Speter
811318334Speter    case MOD:
811418334Speter      result = num_sign_bit_copies (XEXP (x, 1), mode);
811518334Speter      if (result > 1
811650397Sobrien	  && (bitwidth > HOST_BITS_PER_WIDE_INT
811750397Sobrien	      || (nonzero_bits (XEXP (x, 1), mode)
811850397Sobrien		  & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
811950397Sobrien	result--;
812018334Speter
812118334Speter      return result;
812218334Speter
812318334Speter    case ASHIFTRT:
812418334Speter      /* Shifts by a constant add to the number of bits equal to the
812518334Speter	 sign bit.  */
812618334Speter      num0 = num_sign_bit_copies (XEXP (x, 0), mode);
812718334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
812818334Speter	  && INTVAL (XEXP (x, 1)) > 0)
812918334Speter	num0 = MIN (bitwidth, num0 + INTVAL (XEXP (x, 1)));
813018334Speter
813118334Speter      return num0;
813218334Speter
813318334Speter    case ASHIFT:
813418334Speter      /* Left shifts destroy copies.  */
813518334Speter      if (GET_CODE (XEXP (x, 1)) != CONST_INT
813618334Speter	  || INTVAL (XEXP (x, 1)) < 0
813718334Speter	  || INTVAL (XEXP (x, 1)) >= bitwidth)
813818334Speter	return 1;
813918334Speter
814018334Speter      num0 = num_sign_bit_copies (XEXP (x, 0), mode);
814118334Speter      return MAX (1, num0 - INTVAL (XEXP (x, 1)));
814218334Speter
814318334Speter    case IF_THEN_ELSE:
814418334Speter      num0 = num_sign_bit_copies (XEXP (x, 1), mode);
814518334Speter      num1 = num_sign_bit_copies (XEXP (x, 2), mode);
814618334Speter      return MIN (num0, num1);
814718334Speter
814818334Speter    case EQ:  case NE:  case GE:  case GT:  case LE:  case LT:
814918334Speter    case GEU: case GTU: case LEU: case LTU:
815050397Sobrien      if (STORE_FLAG_VALUE == -1)
815150397Sobrien	return bitwidth;
815250397Sobrien      break;
815350397Sobrien
815450397Sobrien    default:
815550397Sobrien      break;
815618334Speter    }
815718334Speter
815818334Speter  /* If we haven't been able to figure it out by one of the above rules,
815918334Speter     see if some of the high-order bits are known to be zero.  If so,
816018334Speter     count those bits and return one less than that amount.  If we can't
816118334Speter     safely compute the mask for this mode, always return BITWIDTH.  */
816218334Speter
816318334Speter  if (bitwidth > HOST_BITS_PER_WIDE_INT)
816418334Speter    return 1;
816518334Speter
816618334Speter  nonzero = nonzero_bits (x, mode);
816718334Speter  return (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))
816818334Speter	  ? 1 : bitwidth - floor_log2 (nonzero) - 1);
816918334Speter}
817018334Speter
817118334Speter/* Return the number of "extended" bits there are in X, when interpreted
817218334Speter   as a quantity in MODE whose signedness is indicated by UNSIGNEDP.  For
817318334Speter   unsigned quantities, this is the number of high-order zero bits.
817418334Speter   For signed quantities, this is the number of copies of the sign bit
817518334Speter   minus 1.  In both case, this function returns the number of "spare"
817618334Speter   bits.  For example, if two quantities for which this function returns
817718334Speter   at least 1 are added, the addition is known not to overflow.
817818334Speter
817918334Speter   This function will always return 0 unless called during combine, which
818018334Speter   implies that it must be called from a define_split.  */
818118334Speter
818218334Speterint
818318334Speterextended_count (x, mode, unsignedp)
818418334Speter     rtx x;
818518334Speter     enum machine_mode mode;
818618334Speter     int unsignedp;
818718334Speter{
818818334Speter  if (nonzero_sign_valid == 0)
818918334Speter    return 0;
819018334Speter
819118334Speter  return (unsignedp
819218334Speter	  ? (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
819318334Speter	     && (GET_MODE_BITSIZE (mode) - 1
819418334Speter		 - floor_log2 (nonzero_bits (x, mode))))
819518334Speter	  : num_sign_bit_copies (x, mode) - 1);
819618334Speter}
819718334Speter
819818334Speter/* This function is called from `simplify_shift_const' to merge two
819918334Speter   outer operations.  Specifically, we have already found that we need
820018334Speter   to perform operation *POP0 with constant *PCONST0 at the outermost
820118334Speter   position.  We would now like to also perform OP1 with constant CONST1
820218334Speter   (with *POP0 being done last).
820318334Speter
820418334Speter   Return 1 if we can do the operation and update *POP0 and *PCONST0 with
820518334Speter   the resulting operation.  *PCOMP_P is set to 1 if we would need to
820618334Speter   complement the innermost operand, otherwise it is unchanged.
820718334Speter
820818334Speter   MODE is the mode in which the operation will be done.  No bits outside
820918334Speter   the width of this mode matter.  It is assumed that the width of this mode
821018334Speter   is smaller than or equal to HOST_BITS_PER_WIDE_INT.
821118334Speter
821218334Speter   If *POP0 or OP1 are NIL, it means no operation is required.  Only NEG, PLUS,
821318334Speter   IOR, XOR, and AND are supported.  We may set *POP0 to SET if the proper
821418334Speter   result is simply *PCONST0.
821518334Speter
821618334Speter   If the resulting operation cannot be expressed as one operation, we
821718334Speter   return 0 and do not change *POP0, *PCONST0, and *PCOMP_P.  */
821818334Speter
821918334Speterstatic int
822018334Spetermerge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p)
822118334Speter     enum rtx_code *pop0;
822218334Speter     HOST_WIDE_INT *pconst0;
822318334Speter     enum rtx_code op1;
822418334Speter     HOST_WIDE_INT const1;
822518334Speter     enum machine_mode mode;
822618334Speter     int *pcomp_p;
822718334Speter{
822818334Speter  enum rtx_code op0 = *pop0;
822918334Speter  HOST_WIDE_INT const0 = *pconst0;
823018334Speter  int width = GET_MODE_BITSIZE (mode);
823118334Speter
823218334Speter  const0 &= GET_MODE_MASK (mode);
823318334Speter  const1 &= GET_MODE_MASK (mode);
823418334Speter
823518334Speter  /* If OP0 is an AND, clear unimportant bits in CONST1.  */
823618334Speter  if (op0 == AND)
823718334Speter    const1 &= const0;
823818334Speter
823918334Speter  /* If OP0 or OP1 is NIL, this is easy.  Similarly if they are the same or
824018334Speter     if OP0 is SET.  */
824118334Speter
824218334Speter  if (op1 == NIL || op0 == SET)
824318334Speter    return 1;
824418334Speter
824518334Speter  else if (op0 == NIL)
824618334Speter    op0 = op1, const0 = const1;
824718334Speter
824818334Speter  else if (op0 == op1)
824918334Speter    {
825018334Speter      switch (op0)
825118334Speter	{
825218334Speter	case AND:
825318334Speter	  const0 &= const1;
825418334Speter	  break;
825518334Speter	case IOR:
825618334Speter	  const0 |= const1;
825718334Speter	  break;
825818334Speter	case XOR:
825918334Speter	  const0 ^= const1;
826018334Speter	  break;
826118334Speter	case PLUS:
826218334Speter	  const0 += const1;
826318334Speter	  break;
826418334Speter	case NEG:
826518334Speter	  op0 = NIL;
826618334Speter	  break;
826750397Sobrien	default:
826850397Sobrien	  break;
826918334Speter	}
827018334Speter    }
827118334Speter
827218334Speter  /* Otherwise, if either is a PLUS or NEG, we can't do anything.  */
827318334Speter  else if (op0 == PLUS || op1 == PLUS || op0 == NEG || op1 == NEG)
827418334Speter    return 0;
827518334Speter
827618334Speter  /* If the two constants aren't the same, we can't do anything.  The
827718334Speter     remaining six cases can all be done.  */
827818334Speter  else if (const0 != const1)
827918334Speter    return 0;
828018334Speter
828118334Speter  else
828218334Speter    switch (op0)
828318334Speter      {
828418334Speter      case IOR:
828518334Speter	if (op1 == AND)
828618334Speter	  /* (a & b) | b == b */
828718334Speter	  op0 = SET;
828818334Speter	else /* op1 == XOR */
828918334Speter	  /* (a ^ b) | b == a | b */
829050397Sobrien	  {;}
829118334Speter	break;
829218334Speter
829318334Speter      case XOR:
829418334Speter	if (op1 == AND)
829518334Speter	  /* (a & b) ^ b == (~a) & b */
829618334Speter	  op0 = AND, *pcomp_p = 1;
829718334Speter	else /* op1 == IOR */
829818334Speter	  /* (a | b) ^ b == a & ~b */
829918334Speter	  op0 = AND, *pconst0 = ~ const0;
830018334Speter	break;
830118334Speter
830218334Speter      case AND:
830318334Speter	if (op1 == IOR)
830418334Speter	  /* (a | b) & b == b */
830518334Speter	op0 = SET;
830618334Speter	else /* op1 == XOR */
830718334Speter	  /* (a ^ b) & b) == (~a) & b */
830818334Speter	  *pcomp_p = 1;
830918334Speter	break;
831050397Sobrien      default:
831150397Sobrien	break;
831218334Speter      }
831318334Speter
831418334Speter  /* Check for NO-OP cases.  */
831518334Speter  const0 &= GET_MODE_MASK (mode);
831618334Speter  if (const0 == 0
831718334Speter      && (op0 == IOR || op0 == XOR || op0 == PLUS))
831818334Speter    op0 = NIL;
831918334Speter  else if (const0 == 0 && op0 == AND)
832018334Speter    op0 = SET;
832152284Sobrien  else if ((unsigned HOST_WIDE_INT) const0 == GET_MODE_MASK (mode)
832252284Sobrien	   && op0 == AND)
832318334Speter    op0 = NIL;
832418334Speter
832518334Speter  /* If this would be an entire word for the target, but is not for
832618334Speter     the host, then sign-extend on the host so that the number will look
832718334Speter     the same way on the host that it would on the target.
832818334Speter
832918334Speter     For example, when building a 64 bit alpha hosted 32 bit sparc
833018334Speter     targeted compiler, then we want the 32 bit unsigned value -1 to be
833118334Speter     represented as a 64 bit value -1, and not as 0x00000000ffffffff.
833218334Speter     The later confuses the sparc backend.  */
833318334Speter
833418334Speter  if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
833518334Speter      && (const0 & ((HOST_WIDE_INT) 1 << (width - 1))))
833618334Speter    const0 |= ((HOST_WIDE_INT) (-1) << width);
833718334Speter
833818334Speter  *pop0 = op0;
833918334Speter  *pconst0 = const0;
834018334Speter
834118334Speter  return 1;
834218334Speter}
834318334Speter
834418334Speter/* Simplify a shift of VAROP by COUNT bits.  CODE says what kind of shift.
834518334Speter   The result of the shift is RESULT_MODE.  X, if non-zero, is an expression
834618334Speter   that we started with.
834718334Speter
834818334Speter   The shift is normally computed in the widest mode we find in VAROP, as
834918334Speter   long as it isn't a different number of words than RESULT_MODE.  Exceptions
835018334Speter   are ASHIFTRT and ROTATE, which are always done in their original mode,  */
835118334Speter
835218334Speterstatic rtx
835318334Spetersimplify_shift_const (x, code, result_mode, varop, count)
835418334Speter     rtx x;
835518334Speter     enum rtx_code code;
835618334Speter     enum machine_mode result_mode;
835718334Speter     rtx varop;
835818334Speter     int count;
835918334Speter{
836018334Speter  enum rtx_code orig_code = code;
836118334Speter  int orig_count = count;
836218334Speter  enum machine_mode mode = result_mode;
836318334Speter  enum machine_mode shift_mode, tmode;
836418334Speter  int mode_words
836518334Speter    = (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
836618334Speter  /* We form (outer_op (code varop count) (outer_const)).  */
836718334Speter  enum rtx_code outer_op = NIL;
836818334Speter  HOST_WIDE_INT outer_const = 0;
836918334Speter  rtx const_rtx;
837018334Speter  int complement_p = 0;
837118334Speter  rtx new;
837218334Speter
837318334Speter  /* If we were given an invalid count, don't do anything except exactly
837418334Speter     what was requested.  */
837518334Speter
837618334Speter  if (count < 0 || count > GET_MODE_BITSIZE (mode))
837718334Speter    {
837818334Speter      if (x)
837918334Speter	return x;
838018334Speter
838150397Sobrien      return gen_rtx_fmt_ee (code, mode, varop, GEN_INT (count));
838218334Speter    }
838318334Speter
838418334Speter  /* Unless one of the branches of the `if' in this loop does a `continue',
838518334Speter     we will `break' the loop after the `if'.  */
838618334Speter
838718334Speter  while (count != 0)
838818334Speter    {
838918334Speter      /* If we have an operand of (clobber (const_int 0)), just return that
839018334Speter	 value.  */
839118334Speter      if (GET_CODE (varop) == CLOBBER)
839218334Speter	return varop;
839318334Speter
839418334Speter      /* If we discovered we had to complement VAROP, leave.  Making a NOT
839518334Speter	 here would cause an infinite loop.  */
839618334Speter      if (complement_p)
839718334Speter	break;
839818334Speter
839918334Speter      /* Convert ROTATERT to ROTATE.  */
840018334Speter      if (code == ROTATERT)
840118334Speter	code = ROTATE, count = GET_MODE_BITSIZE (result_mode) - count;
840218334Speter
840318334Speter      /* We need to determine what mode we will do the shift in.  If the
840418334Speter	 shift is a right shift or a ROTATE, we must always do it in the mode
840518334Speter	 it was originally done in.  Otherwise, we can do it in MODE, the
840650397Sobrien	 widest mode encountered.  */
840718334Speter      shift_mode
840818334Speter	= (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE
840918334Speter	   ? result_mode : mode);
841018334Speter
841118334Speter      /* Handle cases where the count is greater than the size of the mode
841218334Speter	 minus 1.  For ASHIFT, use the size minus one as the count (this can
841318334Speter	 occur when simplifying (lshiftrt (ashiftrt ..))).  For rotates,
841418334Speter	 take the count modulo the size.  For other shifts, the result is
841518334Speter	 zero.
841618334Speter
841718334Speter	 Since these shifts are being produced by the compiler by combining
841818334Speter	 multiple operations, each of which are defined, we know what the
841918334Speter	 result is supposed to be.  */
842018334Speter
842118334Speter      if (count > GET_MODE_BITSIZE (shift_mode) - 1)
842218334Speter	{
842318334Speter	  if (code == ASHIFTRT)
842418334Speter	    count = GET_MODE_BITSIZE (shift_mode) - 1;
842518334Speter	  else if (code == ROTATE || code == ROTATERT)
842618334Speter	    count %= GET_MODE_BITSIZE (shift_mode);
842718334Speter	  else
842818334Speter	    {
842918334Speter	      /* We can't simply return zero because there may be an
843018334Speter		 outer op.  */
843118334Speter	      varop = const0_rtx;
843218334Speter	      count = 0;
843318334Speter	      break;
843418334Speter	    }
843518334Speter	}
843618334Speter
843718334Speter      /* Negative counts are invalid and should not have been made (a
843818334Speter	 programmer-specified negative count should have been handled
843950397Sobrien	 above).  */
844018334Speter      else if (count < 0)
844118334Speter	abort ();
844218334Speter
844318334Speter      /* An arithmetic right shift of a quantity known to be -1 or 0
844418334Speter	 is a no-op.  */
844518334Speter      if (code == ASHIFTRT
844618334Speter	  && (num_sign_bit_copies (varop, shift_mode)
844718334Speter	      == GET_MODE_BITSIZE (shift_mode)))
844818334Speter	{
844918334Speter	  count = 0;
845018334Speter	  break;
845118334Speter	}
845218334Speter
845318334Speter      /* If we are doing an arithmetic right shift and discarding all but
845418334Speter	 the sign bit copies, this is equivalent to doing a shift by the
845518334Speter	 bitsize minus one.  Convert it into that shift because it will often
845618334Speter	 allow other simplifications.  */
845718334Speter
845818334Speter      if (code == ASHIFTRT
845918334Speter	  && (count + num_sign_bit_copies (varop, shift_mode)
846018334Speter	      >= GET_MODE_BITSIZE (shift_mode)))
846118334Speter	count = GET_MODE_BITSIZE (shift_mode) - 1;
846218334Speter
846318334Speter      /* We simplify the tests below and elsewhere by converting
846418334Speter	 ASHIFTRT to LSHIFTRT if we know the sign bit is clear.
846518334Speter	 `make_compound_operation' will convert it to a ASHIFTRT for
846618334Speter	 those machines (such as Vax) that don't have a LSHIFTRT.  */
846718334Speter      if (GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT
846818334Speter	  && code == ASHIFTRT
846918334Speter	  && ((nonzero_bits (varop, shift_mode)
847018334Speter	       & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (shift_mode) - 1)))
847118334Speter	      == 0))
847218334Speter	code = LSHIFTRT;
847318334Speter
847418334Speter      switch (GET_CODE (varop))
847518334Speter	{
847618334Speter	case SIGN_EXTEND:
847718334Speter	case ZERO_EXTEND:
847818334Speter	case SIGN_EXTRACT:
847918334Speter	case ZERO_EXTRACT:
848018334Speter	  new = expand_compound_operation (varop);
848118334Speter	  if (new != varop)
848218334Speter	    {
848318334Speter	      varop = new;
848418334Speter	      continue;
848518334Speter	    }
848618334Speter	  break;
848718334Speter
848818334Speter	case MEM:
848918334Speter	  /* If we have (xshiftrt (mem ...) C) and C is MODE_WIDTH
849018334Speter	     minus the width of a smaller mode, we can do this with a
849118334Speter	     SIGN_EXTEND or ZERO_EXTEND from the narrower memory location.  */
849218334Speter	  if ((code == ASHIFTRT || code == LSHIFTRT)
849318334Speter	      && ! mode_dependent_address_p (XEXP (varop, 0))
849418334Speter	      && ! MEM_VOLATILE_P (varop)
849518334Speter	      && (tmode = mode_for_size (GET_MODE_BITSIZE (mode) - count,
849618334Speter					 MODE_INT, 1)) != BLKmode)
849718334Speter	    {
849818334Speter	      if (BYTES_BIG_ENDIAN)
849950397Sobrien		new = gen_rtx_MEM (tmode, XEXP (varop, 0));
850018334Speter	      else
850150397Sobrien		new = gen_rtx_MEM (tmode,
850250397Sobrien				   plus_constant (XEXP (varop, 0),
850350397Sobrien						  count / BITS_PER_UNIT));
850418334Speter	      RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (varop);
850552284Sobrien	      MEM_COPY_ATTRIBUTES (new, varop);
850618334Speter	      varop = gen_rtx_combine (code == ASHIFTRT ? SIGN_EXTEND
850718334Speter				       : ZERO_EXTEND, mode, new);
850818334Speter	      count = 0;
850918334Speter	      continue;
851018334Speter	    }
851118334Speter	  break;
851218334Speter
851318334Speter	case USE:
851418334Speter	  /* Similar to the case above, except that we can only do this if
851518334Speter	     the resulting mode is the same as that of the underlying
851618334Speter	     MEM and adjust the address depending on the *bits* endianness
851718334Speter	     because of the way that bit-field extract insns are defined.  */
851818334Speter	  if ((code == ASHIFTRT || code == LSHIFTRT)
851918334Speter	      && (tmode = mode_for_size (GET_MODE_BITSIZE (mode) - count,
852018334Speter					 MODE_INT, 1)) != BLKmode
852118334Speter	      && tmode == GET_MODE (XEXP (varop, 0)))
852218334Speter	    {
852318334Speter	      if (BITS_BIG_ENDIAN)
852418334Speter		new = XEXP (varop, 0);
852518334Speter	      else
852618334Speter		{
852718334Speter		  new = copy_rtx (XEXP (varop, 0));
852818334Speter		  SUBST (XEXP (new, 0),
852918334Speter			 plus_constant (XEXP (new, 0),
853018334Speter					count / BITS_PER_UNIT));
853118334Speter		}
853218334Speter
853318334Speter	      varop = gen_rtx_combine (code == ASHIFTRT ? SIGN_EXTEND
853418334Speter				       : ZERO_EXTEND, mode, new);
853518334Speter	      count = 0;
853618334Speter	      continue;
853718334Speter	    }
853818334Speter	  break;
853918334Speter
854018334Speter	case SUBREG:
854118334Speter	  /* If VAROP is a SUBREG, strip it as long as the inner operand has
854218334Speter	     the same number of words as what we've seen so far.  Then store
854318334Speter	     the widest mode in MODE.  */
854418334Speter	  if (subreg_lowpart_p (varop)
854518334Speter	      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (varop)))
854618334Speter		  > GET_MODE_SIZE (GET_MODE (varop)))
854718334Speter	      && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (varop)))
854818334Speter		    + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
854918334Speter		  == mode_words))
855018334Speter	    {
855118334Speter	      varop = SUBREG_REG (varop);
855218334Speter	      if (GET_MODE_SIZE (GET_MODE (varop)) > GET_MODE_SIZE (mode))
855318334Speter		mode = GET_MODE (varop);
855418334Speter	      continue;
855518334Speter	    }
855618334Speter	  break;
855718334Speter
855818334Speter	case MULT:
855918334Speter	  /* Some machines use MULT instead of ASHIFT because MULT
856018334Speter	     is cheaper.  But it is still better on those machines to
856118334Speter	     merge two shifts into one.  */
856218334Speter	  if (GET_CODE (XEXP (varop, 1)) == CONST_INT
856318334Speter	      && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
856418334Speter	    {
856518334Speter	      varop = gen_binary (ASHIFT, GET_MODE (varop), XEXP (varop, 0),
856618334Speter				  GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));;
856718334Speter	      continue;
856818334Speter	    }
856918334Speter	  break;
857018334Speter
857118334Speter	case UDIV:
857218334Speter	  /* Similar, for when divides are cheaper.  */
857318334Speter	  if (GET_CODE (XEXP (varop, 1)) == CONST_INT
857418334Speter	      && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
857518334Speter	    {
857618334Speter	      varop = gen_binary (LSHIFTRT, GET_MODE (varop), XEXP (varop, 0),
857718334Speter				  GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));
857818334Speter	      continue;
857918334Speter	    }
858018334Speter	  break;
858118334Speter
858218334Speter	case ASHIFTRT:
858318334Speter	  /* If we are extracting just the sign bit of an arithmetic right
858418334Speter	     shift, that shift is not needed.  */
858518334Speter	  if (code == LSHIFTRT && count == GET_MODE_BITSIZE (result_mode) - 1)
858618334Speter	    {
858718334Speter	      varop = XEXP (varop, 0);
858818334Speter	      continue;
858918334Speter	    }
859018334Speter
859150397Sobrien	  /* ... fall through ...  */
859218334Speter
859318334Speter	case LSHIFTRT:
859418334Speter	case ASHIFT:
859518334Speter	case ROTATE:
859618334Speter	  /* Here we have two nested shifts.  The result is usually the
859718334Speter	     AND of a new shift with a mask.  We compute the result below.  */
859818334Speter	  if (GET_CODE (XEXP (varop, 1)) == CONST_INT
859918334Speter	      && INTVAL (XEXP (varop, 1)) >= 0
860018334Speter	      && INTVAL (XEXP (varop, 1)) < GET_MODE_BITSIZE (GET_MODE (varop))
860118334Speter	      && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT
860218334Speter	      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
860318334Speter	    {
860418334Speter	      enum rtx_code first_code = GET_CODE (varop);
860518334Speter	      int first_count = INTVAL (XEXP (varop, 1));
860618334Speter	      unsigned HOST_WIDE_INT mask;
860718334Speter	      rtx mask_rtx;
860818334Speter
860918334Speter	      /* We have one common special case.  We can't do any merging if
861018334Speter		 the inner code is an ASHIFTRT of a smaller mode.  However, if
861118334Speter		 we have (ashift:M1 (subreg:M1 (ashiftrt:M2 FOO C1) 0) C2)
861218334Speter		 with C2 == GET_MODE_BITSIZE (M1) - GET_MODE_BITSIZE (M2),
861318334Speter		 we can convert it to
861418334Speter		 (ashiftrt:M1 (ashift:M1 (and:M1 (subreg:M1 FOO 0 C2) C3) C1).
861518334Speter		 This simplifies certain SIGN_EXTEND operations.  */
861618334Speter	      if (code == ASHIFT && first_code == ASHIFTRT
861718334Speter		  && (GET_MODE_BITSIZE (result_mode)
861818334Speter		      - GET_MODE_BITSIZE (GET_MODE (varop))) == count)
861918334Speter		{
862018334Speter		  /* C3 has the low-order C1 bits zero.  */
862118334Speter
862218334Speter		  mask = (GET_MODE_MASK (mode)
862318334Speter			  & ~ (((HOST_WIDE_INT) 1 << first_count) - 1));
862418334Speter
862518334Speter		  varop = simplify_and_const_int (NULL_RTX, result_mode,
862618334Speter						  XEXP (varop, 0), mask);
862718334Speter		  varop = simplify_shift_const (NULL_RTX, ASHIFT, result_mode,
862818334Speter						varop, count);
862918334Speter		  count = first_count;
863018334Speter		  code = ASHIFTRT;
863118334Speter		  continue;
863218334Speter		}
863318334Speter
863418334Speter	      /* If this was (ashiftrt (ashift foo C1) C2) and FOO has more
863518334Speter		 than C1 high-order bits equal to the sign bit, we can convert
863618334Speter		 this to either an ASHIFT or a ASHIFTRT depending on the
863718334Speter		 two counts.
863818334Speter
863918334Speter		 We cannot do this if VAROP's mode is not SHIFT_MODE.  */
864018334Speter
864118334Speter	      if (code == ASHIFTRT && first_code == ASHIFT
864218334Speter		  && GET_MODE (varop) == shift_mode
864318334Speter		  && (num_sign_bit_copies (XEXP (varop, 0), shift_mode)
864418334Speter		      > first_count))
864518334Speter		{
864618334Speter		  count -= first_count;
864718334Speter		  if (count < 0)
864818334Speter		    count = - count, code = ASHIFT;
864918334Speter		  varop = XEXP (varop, 0);
865018334Speter		  continue;
865118334Speter		}
865218334Speter
865318334Speter	      /* There are some cases we can't do.  If CODE is ASHIFTRT,
865418334Speter		 we can only do this if FIRST_CODE is also ASHIFTRT.
865518334Speter
865618334Speter		 We can't do the case when CODE is ROTATE and FIRST_CODE is
865718334Speter		 ASHIFTRT.
865818334Speter
865918334Speter		 If the mode of this shift is not the mode of the outer shift,
866018334Speter		 we can't do this if either shift is a right shift or ROTATE.
866118334Speter
866218334Speter		 Finally, we can't do any of these if the mode is too wide
866318334Speter		 unless the codes are the same.
866418334Speter
866518334Speter		 Handle the case where the shift codes are the same
866618334Speter		 first.  */
866718334Speter
866818334Speter	      if (code == first_code)
866918334Speter		{
867018334Speter		  if (GET_MODE (varop) != result_mode
867118334Speter		      && (code == ASHIFTRT || code == LSHIFTRT
867218334Speter			  || code == ROTATE))
867318334Speter		    break;
867418334Speter
867518334Speter		  count += first_count;
867618334Speter		  varop = XEXP (varop, 0);
867718334Speter		  continue;
867818334Speter		}
867918334Speter
868018334Speter	      if (code == ASHIFTRT
868118334Speter		  || (code == ROTATE && first_code == ASHIFTRT)
868218334Speter		  || GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT
868318334Speter		  || (GET_MODE (varop) != result_mode
868418334Speter		      && (first_code == ASHIFTRT || first_code == LSHIFTRT
868518334Speter			  || first_code == ROTATE
868618334Speter			  || code == ROTATE)))
868718334Speter		break;
868818334Speter
868918334Speter	      /* To compute the mask to apply after the shift, shift the
869018334Speter		 nonzero bits of the inner shift the same way the
869118334Speter		 outer shift will.  */
869218334Speter
869318334Speter	      mask_rtx = GEN_INT (nonzero_bits (varop, GET_MODE (varop)));
869418334Speter
869518334Speter	      mask_rtx
869618334Speter		= simplify_binary_operation (code, result_mode, mask_rtx,
869718334Speter					     GEN_INT (count));
869818334Speter
869918334Speter	      /* Give up if we can't compute an outer operation to use.  */
870018334Speter	      if (mask_rtx == 0
870118334Speter		  || GET_CODE (mask_rtx) != CONST_INT
870218334Speter		  || ! merge_outer_ops (&outer_op, &outer_const, AND,
870318334Speter					INTVAL (mask_rtx),
870418334Speter					result_mode, &complement_p))
870518334Speter		break;
870618334Speter
870718334Speter	      /* If the shifts are in the same direction, we add the
870818334Speter		 counts.  Otherwise, we subtract them.  */
870918334Speter	      if ((code == ASHIFTRT || code == LSHIFTRT)
871018334Speter		  == (first_code == ASHIFTRT || first_code == LSHIFTRT))
871118334Speter		count += first_count;
871218334Speter	      else
871318334Speter		count -= first_count;
871418334Speter
871518334Speter	      /* If COUNT is positive, the new shift is usually CODE,
871618334Speter		 except for the two exceptions below, in which case it is
871718334Speter		 FIRST_CODE.  If the count is negative, FIRST_CODE should
871818334Speter		 always be used  */
871918334Speter	      if (count > 0
872018334Speter		  && ((first_code == ROTATE && code == ASHIFT)
872118334Speter		      || (first_code == ASHIFTRT && code == LSHIFTRT)))
872218334Speter		code = first_code;
872318334Speter	      else if (count < 0)
872418334Speter		code = first_code, count = - count;
872518334Speter
872618334Speter	      varop = XEXP (varop, 0);
872718334Speter	      continue;
872818334Speter	    }
872918334Speter
873018334Speter	  /* If we have (A << B << C) for any shift, we can convert this to
873118334Speter	     (A << C << B).  This wins if A is a constant.  Only try this if
873218334Speter	     B is not a constant.  */
873318334Speter
873418334Speter	  else if (GET_CODE (varop) == code
873518334Speter		   && GET_CODE (XEXP (varop, 1)) != CONST_INT
873618334Speter		   && 0 != (new
873718334Speter			    = simplify_binary_operation (code, mode,
873818334Speter							 XEXP (varop, 0),
873918334Speter							 GEN_INT (count))))
874018334Speter	    {
874118334Speter	      varop = gen_rtx_combine (code, mode, new, XEXP (varop, 1));
874218334Speter	      count = 0;
874318334Speter	      continue;
874418334Speter	    }
874518334Speter	  break;
874618334Speter
874718334Speter	case NOT:
874818334Speter	  /* Make this fit the case below.  */
874918334Speter	  varop = gen_rtx_combine (XOR, mode, XEXP (varop, 0),
875018334Speter				   GEN_INT (GET_MODE_MASK (mode)));
875118334Speter	  continue;
875218334Speter
875318334Speter	case IOR:
875418334Speter	case AND:
875518334Speter	case XOR:
875618334Speter	  /* If we have (xshiftrt (ior (plus X (const_int -1)) X) C)
875718334Speter	     with C the size of VAROP - 1 and the shift is logical if
875818334Speter	     STORE_FLAG_VALUE is 1 and arithmetic if STORE_FLAG_VALUE is -1,
875918334Speter	     we have an (le X 0) operation.   If we have an arithmetic shift
876018334Speter	     and STORE_FLAG_VALUE is 1 or we have a logical shift with
876118334Speter	     STORE_FLAG_VALUE of -1, we have a (neg (le X 0)) operation.  */
876218334Speter
876318334Speter	  if (GET_CODE (varop) == IOR && GET_CODE (XEXP (varop, 0)) == PLUS
876418334Speter	      && XEXP (XEXP (varop, 0), 1) == constm1_rtx
876518334Speter	      && (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
876618334Speter	      && (code == LSHIFTRT || code == ASHIFTRT)
876718334Speter	      && count == GET_MODE_BITSIZE (GET_MODE (varop)) - 1
876818334Speter	      && rtx_equal_p (XEXP (XEXP (varop, 0), 0), XEXP (varop, 1)))
876918334Speter	    {
877018334Speter	      count = 0;
877118334Speter	      varop = gen_rtx_combine (LE, GET_MODE (varop), XEXP (varop, 1),
877218334Speter				       const0_rtx);
877318334Speter
877418334Speter	      if (STORE_FLAG_VALUE == 1 ? code == ASHIFTRT : code == LSHIFTRT)
877518334Speter		varop = gen_rtx_combine (NEG, GET_MODE (varop), varop);
877618334Speter
877718334Speter	      continue;
877818334Speter	    }
877918334Speter
878018334Speter	  /* If we have (shift (logical)), move the logical to the outside
878118334Speter	     to allow it to possibly combine with another logical and the
878218334Speter	     shift to combine with another shift.  This also canonicalizes to
878318334Speter	     what a ZERO_EXTRACT looks like.  Also, some machines have
878418334Speter	     (and (shift)) insns.  */
878518334Speter
878618334Speter	  if (GET_CODE (XEXP (varop, 1)) == CONST_INT
878718334Speter	      && (new = simplify_binary_operation (code, result_mode,
878818334Speter						   XEXP (varop, 1),
878918334Speter						   GEN_INT (count))) != 0
879018334Speter	      && GET_CODE(new) == CONST_INT
879118334Speter	      && merge_outer_ops (&outer_op, &outer_const, GET_CODE (varop),
879218334Speter				  INTVAL (new), result_mode, &complement_p))
879318334Speter	    {
879418334Speter	      varop = XEXP (varop, 0);
879518334Speter	      continue;
879618334Speter	    }
879718334Speter
879818334Speter	  /* If we can't do that, try to simplify the shift in each arm of the
879918334Speter	     logical expression, make a new logical expression, and apply
880018334Speter	     the inverse distributive law.  */
880118334Speter	  {
880218334Speter	    rtx lhs = simplify_shift_const (NULL_RTX, code, shift_mode,
880318334Speter					    XEXP (varop, 0), count);
880418334Speter	    rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode,
880518334Speter					    XEXP (varop, 1), count);
880618334Speter
880718334Speter	    varop = gen_binary (GET_CODE (varop), shift_mode, lhs, rhs);
880818334Speter	    varop = apply_distributive_law (varop);
880918334Speter
881018334Speter	    count = 0;
881118334Speter	  }
881218334Speter	  break;
881318334Speter
881418334Speter	case EQ:
881518334Speter	  /* convert (lshiftrt (eq FOO 0) C) to (xor FOO 1) if STORE_FLAG_VALUE
881618334Speter	     says that the sign bit can be tested, FOO has mode MODE, C is
881718334Speter	     GET_MODE_BITSIZE (MODE) - 1, and FOO has only its low-order bit
881818334Speter	     that may be nonzero.  */
881918334Speter	  if (code == LSHIFTRT
882018334Speter	      && XEXP (varop, 1) == const0_rtx
882118334Speter	      && GET_MODE (XEXP (varop, 0)) == result_mode
882218334Speter	      && count == GET_MODE_BITSIZE (result_mode) - 1
882318334Speter	      && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT
882418334Speter	      && ((STORE_FLAG_VALUE
882518334Speter		   & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (result_mode) - 1))))
882618334Speter	      && nonzero_bits (XEXP (varop, 0), result_mode) == 1
882718334Speter	      && merge_outer_ops (&outer_op, &outer_const, XOR,
882818334Speter				  (HOST_WIDE_INT) 1, result_mode,
882918334Speter				  &complement_p))
883018334Speter	    {
883118334Speter	      varop = XEXP (varop, 0);
883218334Speter	      count = 0;
883318334Speter	      continue;
883418334Speter	    }
883518334Speter	  break;
883618334Speter
883718334Speter	case NEG:
883818334Speter	  /* (lshiftrt (neg A) C) where A is either 0 or 1 and C is one less
883918334Speter	     than the number of bits in the mode is equivalent to A.  */
884018334Speter	  if (code == LSHIFTRT && count == GET_MODE_BITSIZE (result_mode) - 1
884118334Speter	      && nonzero_bits (XEXP (varop, 0), result_mode) == 1)
884218334Speter	    {
884318334Speter	      varop = XEXP (varop, 0);
884418334Speter	      count = 0;
884518334Speter	      continue;
884618334Speter	    }
884718334Speter
884818334Speter	  /* NEG commutes with ASHIFT since it is multiplication.  Move the
884918334Speter	     NEG outside to allow shifts to combine.  */
885018334Speter	  if (code == ASHIFT
885118334Speter	      && merge_outer_ops (&outer_op, &outer_const, NEG,
885218334Speter				  (HOST_WIDE_INT) 0, result_mode,
885318334Speter				  &complement_p))
885418334Speter	    {
885518334Speter	      varop = XEXP (varop, 0);
885618334Speter	      continue;
885718334Speter	    }
885818334Speter	  break;
885918334Speter
886018334Speter	case PLUS:
886118334Speter	  /* (lshiftrt (plus A -1) C) where A is either 0 or 1 and C
886218334Speter	     is one less than the number of bits in the mode is
886318334Speter	     equivalent to (xor A 1).  */
886418334Speter	  if (code == LSHIFTRT && count == GET_MODE_BITSIZE (result_mode) - 1
886518334Speter	      && XEXP (varop, 1) == constm1_rtx
886618334Speter	      && nonzero_bits (XEXP (varop, 0), result_mode) == 1
886718334Speter	      && merge_outer_ops (&outer_op, &outer_const, XOR,
886818334Speter				  (HOST_WIDE_INT) 1, result_mode,
886918334Speter				  &complement_p))
887018334Speter	    {
887118334Speter	      count = 0;
887218334Speter	      varop = XEXP (varop, 0);
887318334Speter	      continue;
887418334Speter	    }
887518334Speter
887618334Speter	  /* If we have (xshiftrt (plus FOO BAR) C), and the only bits
887718334Speter	     that might be nonzero in BAR are those being shifted out and those
887818334Speter	     bits are known zero in FOO, we can replace the PLUS with FOO.
887918334Speter	     Similarly in the other operand order.  This code occurs when
888018334Speter	     we are computing the size of a variable-size array.  */
888118334Speter
888218334Speter	  if ((code == ASHIFTRT || code == LSHIFTRT)
888318334Speter	      && count < HOST_BITS_PER_WIDE_INT
888418334Speter	      && nonzero_bits (XEXP (varop, 1), result_mode) >> count == 0
888518334Speter	      && (nonzero_bits (XEXP (varop, 1), result_mode)
888618334Speter		  & nonzero_bits (XEXP (varop, 0), result_mode)) == 0)
888718334Speter	    {
888818334Speter	      varop = XEXP (varop, 0);
888918334Speter	      continue;
889018334Speter	    }
889118334Speter	  else if ((code == ASHIFTRT || code == LSHIFTRT)
889218334Speter		   && count < HOST_BITS_PER_WIDE_INT
889318334Speter		   && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT
889418334Speter		   && 0 == (nonzero_bits (XEXP (varop, 0), result_mode)
889518334Speter			    >> count)
889618334Speter		   && 0 == (nonzero_bits (XEXP (varop, 0), result_mode)
889718334Speter			    & nonzero_bits (XEXP (varop, 1),
889818334Speter						 result_mode)))
889918334Speter	    {
890018334Speter	      varop = XEXP (varop, 1);
890118334Speter	      continue;
890218334Speter	    }
890318334Speter
890418334Speter	  /* (ashift (plus foo C) N) is (plus (ashift foo N) C').  */
890518334Speter	  if (code == ASHIFT
890618334Speter	      && GET_CODE (XEXP (varop, 1)) == CONST_INT
890718334Speter	      && (new = simplify_binary_operation (ASHIFT, result_mode,
890818334Speter						   XEXP (varop, 1),
890918334Speter						   GEN_INT (count))) != 0
891018334Speter	      && GET_CODE(new) == CONST_INT
891118334Speter	      && merge_outer_ops (&outer_op, &outer_const, PLUS,
891218334Speter				  INTVAL (new), result_mode, &complement_p))
891318334Speter	    {
891418334Speter	      varop = XEXP (varop, 0);
891518334Speter	      continue;
891618334Speter	    }
891718334Speter	  break;
891818334Speter
891918334Speter	case MINUS:
892018334Speter	  /* If we have (xshiftrt (minus (ashiftrt X C)) X) C)
892118334Speter	     with C the size of VAROP - 1 and the shift is logical if
892218334Speter	     STORE_FLAG_VALUE is 1 and arithmetic if STORE_FLAG_VALUE is -1,
892318334Speter	     we have a (gt X 0) operation.  If the shift is arithmetic with
892418334Speter	     STORE_FLAG_VALUE of 1 or logical with STORE_FLAG_VALUE == -1,
892518334Speter	     we have a (neg (gt X 0)) operation.  */
892618334Speter
892750397Sobrien	  if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
892850397Sobrien	      && GET_CODE (XEXP (varop, 0)) == ASHIFTRT
892918334Speter	      && count == GET_MODE_BITSIZE (GET_MODE (varop)) - 1
893018334Speter	      && (code == LSHIFTRT || code == ASHIFTRT)
893118334Speter	      && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT
893218334Speter	      && INTVAL (XEXP (XEXP (varop, 0), 1)) == count
893318334Speter	      && rtx_equal_p (XEXP (XEXP (varop, 0), 0), XEXP (varop, 1)))
893418334Speter	    {
893518334Speter	      count = 0;
893618334Speter	      varop = gen_rtx_combine (GT, GET_MODE (varop), XEXP (varop, 1),
893718334Speter				       const0_rtx);
893818334Speter
893918334Speter	      if (STORE_FLAG_VALUE == 1 ? code == ASHIFTRT : code == LSHIFTRT)
894018334Speter		varop = gen_rtx_combine (NEG, GET_MODE (varop), varop);
894118334Speter
894218334Speter	      continue;
894318334Speter	    }
894418334Speter	  break;
894550397Sobrien
894650397Sobrien	case TRUNCATE:
894750397Sobrien	  /* Change (lshiftrt (truncate (lshiftrt))) to (truncate (lshiftrt))
894850397Sobrien	     if the truncate does not affect the value.  */
894950397Sobrien	  if (code == LSHIFTRT
895050397Sobrien	      && GET_CODE (XEXP (varop, 0)) == LSHIFTRT
895150397Sobrien	      && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT
895250397Sobrien	      && (INTVAL (XEXP (XEXP (varop, 0), 1))
895350397Sobrien		  >= (GET_MODE_BITSIZE (GET_MODE (XEXP (varop, 0)))
895450397Sobrien		      - GET_MODE_BITSIZE (GET_MODE (varop)))))
895550397Sobrien	    {
895650397Sobrien	      rtx varop_inner = XEXP (varop, 0);
895750397Sobrien
895850397Sobrien	      varop_inner = gen_rtx_combine (LSHIFTRT,
895950397Sobrien					     GET_MODE (varop_inner),
896050397Sobrien					     XEXP (varop_inner, 0),
896150397Sobrien					     GEN_INT (count + INTVAL (XEXP (varop_inner, 1))));
896250397Sobrien	      varop = gen_rtx_combine (TRUNCATE, GET_MODE (varop),
896350397Sobrien				       varop_inner);
896450397Sobrien	      count = 0;
896550397Sobrien	      continue;
896650397Sobrien	    }
896750397Sobrien	  break;
896850397Sobrien
896950397Sobrien	default:
897050397Sobrien	  break;
897118334Speter	}
897218334Speter
897318334Speter      break;
897418334Speter    }
897518334Speter
897618334Speter  /* We need to determine what mode to do the shift in.  If the shift is
897718334Speter     a right shift or ROTATE, we must always do it in the mode it was
897818334Speter     originally done in.  Otherwise, we can do it in MODE, the widest mode
897918334Speter     encountered.  The code we care about is that of the shift that will
898018334Speter     actually be done, not the shift that was originally requested.  */
898118334Speter  shift_mode
898218334Speter    = (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE
898318334Speter       ? result_mode : mode);
898418334Speter
898518334Speter  /* We have now finished analyzing the shift.  The result should be
898618334Speter     a shift of type CODE with SHIFT_MODE shifting VAROP COUNT places.  If
898718334Speter     OUTER_OP is non-NIL, it is an operation that needs to be applied
898818334Speter     to the result of the shift.  OUTER_CONST is the relevant constant,
898918334Speter     but we must turn off all bits turned off in the shift.
899018334Speter
899118334Speter     If we were passed a value for X, see if we can use any pieces of
899218334Speter     it.  If not, make new rtx.  */
899318334Speter
899418334Speter  if (x && GET_RTX_CLASS (GET_CODE (x)) == '2'
899518334Speter      && GET_CODE (XEXP (x, 1)) == CONST_INT
899618334Speter      && INTVAL (XEXP (x, 1)) == count)
899718334Speter    const_rtx = XEXP (x, 1);
899818334Speter  else
899918334Speter    const_rtx = GEN_INT (count);
900018334Speter
900118334Speter  if (x && GET_CODE (XEXP (x, 0)) == SUBREG
900218334Speter      && GET_MODE (XEXP (x, 0)) == shift_mode
900318334Speter      && SUBREG_REG (XEXP (x, 0)) == varop)
900418334Speter    varop = XEXP (x, 0);
900518334Speter  else if (GET_MODE (varop) != shift_mode)
900618334Speter    varop = gen_lowpart_for_combine (shift_mode, varop);
900718334Speter
900850397Sobrien  /* If we can't make the SUBREG, try to return what we were given.  */
900918334Speter  if (GET_CODE (varop) == CLOBBER)
901018334Speter    return x ? x : varop;
901118334Speter
901218334Speter  new = simplify_binary_operation (code, shift_mode, varop, const_rtx);
901318334Speter  if (new != 0)
901418334Speter    x = new;
901518334Speter  else
901618334Speter    {
901718334Speter      if (x == 0 || GET_CODE (x) != code || GET_MODE (x) != shift_mode)
901818334Speter	x = gen_rtx_combine (code, shift_mode, varop, const_rtx);
901918334Speter
902018334Speter      SUBST (XEXP (x, 0), varop);
902118334Speter      SUBST (XEXP (x, 1), const_rtx);
902218334Speter    }
902318334Speter
902418334Speter  /* If we have an outer operation and we just made a shift, it is
902518334Speter     possible that we could have simplified the shift were it not
902618334Speter     for the outer operation.  So try to do the simplification
902718334Speter     recursively.  */
902818334Speter
902918334Speter  if (outer_op != NIL && GET_CODE (x) == code
903018334Speter      && GET_CODE (XEXP (x, 1)) == CONST_INT)
903118334Speter    x = simplify_shift_const (x, code, shift_mode, XEXP (x, 0),
903218334Speter			      INTVAL (XEXP (x, 1)));
903318334Speter
903418334Speter  /* If we were doing a LSHIFTRT in a wider mode than it was originally,
903518334Speter     turn off all the bits that the shift would have turned off.  */
903618334Speter  if (orig_code == LSHIFTRT && result_mode != shift_mode)
903718334Speter    x = simplify_and_const_int (NULL_RTX, shift_mode, x,
903818334Speter				GET_MODE_MASK (result_mode) >> orig_count);
903918334Speter
904018334Speter  /* Do the remainder of the processing in RESULT_MODE.  */
904118334Speter  x = gen_lowpart_for_combine (result_mode, x);
904218334Speter
904318334Speter  /* If COMPLEMENT_P is set, we have to complement X before doing the outer
904418334Speter     operation.  */
904518334Speter  if (complement_p)
904618334Speter    x = gen_unary (NOT, result_mode, result_mode, x);
904718334Speter
904818334Speter  if (outer_op != NIL)
904918334Speter    {
905018334Speter      if (GET_MODE_BITSIZE (result_mode) < HOST_BITS_PER_WIDE_INT)
905118334Speter	{
905218334Speter	  int width = GET_MODE_BITSIZE (result_mode);
905318334Speter
905418334Speter	  outer_const &= GET_MODE_MASK (result_mode);
905518334Speter
905618334Speter	  /* If this would be an entire word for the target, but is not for
905718334Speter	     the host, then sign-extend on the host so that the number will
905818334Speter	     look the same way on the host that it would on the target.
905918334Speter
906018334Speter	     For example, when building a 64 bit alpha hosted 32 bit sparc
906118334Speter	     targeted compiler, then we want the 32 bit unsigned value -1 to be
906218334Speter	     represented as a 64 bit value -1, and not as 0x00000000ffffffff.
906318334Speter	     The later confuses the sparc backend.  */
906418334Speter
906518334Speter	  if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
906618334Speter	      && (outer_const & ((HOST_WIDE_INT) 1 << (width - 1))))
906718334Speter	    outer_const |= ((HOST_WIDE_INT) (-1) << width);
906818334Speter	}
906918334Speter
907018334Speter      if (outer_op == AND)
907118334Speter	x = simplify_and_const_int (NULL_RTX, result_mode, x, outer_const);
907218334Speter      else if (outer_op == SET)
907318334Speter	/* This means that we have determined that the result is
907418334Speter	   equivalent to a constant.  This should be rare.  */
907518334Speter	x = GEN_INT (outer_const);
907618334Speter      else if (GET_RTX_CLASS (outer_op) == '1')
907718334Speter	x = gen_unary (outer_op, result_mode, result_mode, x);
907818334Speter      else
907918334Speter	x = gen_binary (outer_op, result_mode, x, GEN_INT (outer_const));
908018334Speter    }
908118334Speter
908218334Speter  return x;
908318334Speter}
908418334Speter
908518334Speter/* Like recog, but we receive the address of a pointer to a new pattern.
908618334Speter   We try to match the rtx that the pointer points to.
908718334Speter   If that fails, we may try to modify or replace the pattern,
908818334Speter   storing the replacement into the same pointer object.
908918334Speter
909018334Speter   Modifications include deletion or addition of CLOBBERs.
909118334Speter
909218334Speter   PNOTES is a pointer to a location where any REG_UNUSED notes added for
909318334Speter   the CLOBBERs are placed.
909418334Speter
909518334Speter   The value is the final insn code from the pattern ultimately matched,
909618334Speter   or -1.  */
909718334Speter
909818334Speterstatic int
909952284Sobrienrecog_for_combine (pnewpat, insn, pnotes)
910018334Speter     rtx *pnewpat;
910118334Speter     rtx insn;
910218334Speter     rtx *pnotes;
910318334Speter{
910418334Speter  register rtx pat = *pnewpat;
910518334Speter  int insn_code_number;
910618334Speter  int num_clobbers_to_add = 0;
910718334Speter  int i;
910818334Speter  rtx notes = 0;
910918334Speter
911018334Speter  /* If PAT is a PARALLEL, check to see if it contains the CLOBBER
911118334Speter     we use to indicate that something didn't match.  If we find such a
911218334Speter     thing, force rejection.  */
911318334Speter  if (GET_CODE (pat) == PARALLEL)
911418334Speter    for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
911518334Speter      if (GET_CODE (XVECEXP (pat, 0, i)) == CLOBBER
911618334Speter	  && XEXP (XVECEXP (pat, 0, i), 0) == const0_rtx)
911718334Speter	return -1;
911818334Speter
911918334Speter  /* Is the result of combination a valid instruction?  */
912018334Speter  insn_code_number = recog (pat, insn, &num_clobbers_to_add);
912118334Speter
912218334Speter  /* If it isn't, there is the possibility that we previously had an insn
912318334Speter     that clobbered some register as a side effect, but the combined
912418334Speter     insn doesn't need to do that.  So try once more without the clobbers
912518334Speter     unless this represents an ASM insn.  */
912618334Speter
912718334Speter  if (insn_code_number < 0 && ! check_asm_operands (pat)
912818334Speter      && GET_CODE (pat) == PARALLEL)
912918334Speter    {
913018334Speter      int pos;
913118334Speter
913218334Speter      for (pos = 0, i = 0; i < XVECLEN (pat, 0); i++)
913318334Speter	if (GET_CODE (XVECEXP (pat, 0, i)) != CLOBBER)
913418334Speter	  {
913518334Speter	    if (i != pos)
913618334Speter	      SUBST (XVECEXP (pat, 0, pos), XVECEXP (pat, 0, i));
913718334Speter	    pos++;
913818334Speter	  }
913918334Speter
914018334Speter      SUBST_INT (XVECLEN (pat, 0), pos);
914118334Speter
914218334Speter      if (pos == 1)
914318334Speter	pat = XVECEXP (pat, 0, 0);
914418334Speter
914518334Speter      insn_code_number = recog (pat, insn, &num_clobbers_to_add);
914618334Speter    }
914718334Speter
914818334Speter  /* If we had any clobbers to add, make a new pattern than contains
914918334Speter     them.  Then check to make sure that all of them are dead.  */
915018334Speter  if (num_clobbers_to_add)
915118334Speter    {
915250397Sobrien      rtx newpat = gen_rtx_PARALLEL (VOIDmode,
915350397Sobrien				     gen_rtvec (GET_CODE (pat) == PARALLEL
915450397Sobrien						? XVECLEN (pat, 0) + num_clobbers_to_add
915550397Sobrien						: num_clobbers_to_add + 1));
915618334Speter
915718334Speter      if (GET_CODE (pat) == PARALLEL)
915818334Speter	for (i = 0; i < XVECLEN (pat, 0); i++)
915918334Speter	  XVECEXP (newpat, 0, i) = XVECEXP (pat, 0, i);
916018334Speter      else
916118334Speter	XVECEXP (newpat, 0, 0) = pat;
916218334Speter
916318334Speter      add_clobbers (newpat, insn_code_number);
916418334Speter
916518334Speter      for (i = XVECLEN (newpat, 0) - num_clobbers_to_add;
916618334Speter	   i < XVECLEN (newpat, 0); i++)
916718334Speter	{
916818334Speter	  if (GET_CODE (XEXP (XVECEXP (newpat, 0, i), 0)) == REG
916918334Speter	      && ! reg_dead_at_p (XEXP (XVECEXP (newpat, 0, i), 0), insn))
917018334Speter	    return -1;
917150397Sobrien	  notes = gen_rtx_EXPR_LIST (REG_UNUSED,
917250397Sobrien				     XEXP (XVECEXP (newpat, 0, i), 0), notes);
917318334Speter	}
917418334Speter      pat = newpat;
917518334Speter    }
917618334Speter
917718334Speter  *pnewpat = pat;
917818334Speter  *pnotes = notes;
917918334Speter
918018334Speter  return insn_code_number;
918118334Speter}
918218334Speter
918318334Speter/* Like gen_lowpart but for use by combine.  In combine it is not possible
918418334Speter   to create any new pseudoregs.  However, it is safe to create
918518334Speter   invalid memory addresses, because combine will try to recognize
918618334Speter   them and all they will do is make the combine attempt fail.
918718334Speter
918818334Speter   If for some reason this cannot do its job, an rtx
918918334Speter   (clobber (const_int 0)) is returned.
919018334Speter   An insn containing that will not be recognized.  */
919118334Speter
919218334Speter#undef gen_lowpart
919318334Speter
919418334Speterstatic rtx
919518334Spetergen_lowpart_for_combine (mode, x)
919618334Speter     enum machine_mode mode;
919718334Speter     register rtx x;
919818334Speter{
919918334Speter  rtx result;
920018334Speter
920118334Speter  if (GET_MODE (x) == mode)
920218334Speter    return x;
920318334Speter
920418334Speter  /* We can only support MODE being wider than a word if X is a
920518334Speter     constant integer or has a mode the same size.  */
920618334Speter
920718334Speter  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
920818334Speter      && ! ((GET_MODE (x) == VOIDmode
920918334Speter	     && (GET_CODE (x) == CONST_INT
921018334Speter		 || GET_CODE (x) == CONST_DOUBLE))
921118334Speter	    || GET_MODE_SIZE (GET_MODE (x)) == GET_MODE_SIZE (mode)))
921250397Sobrien    return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
921318334Speter
921418334Speter  /* X might be a paradoxical (subreg (mem)).  In that case, gen_lowpart
921518334Speter     won't know what to do.  So we will strip off the SUBREG here and
921618334Speter     process normally.  */
921718334Speter  if (GET_CODE (x) == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM)
921818334Speter    {
921918334Speter      x = SUBREG_REG (x);
922018334Speter      if (GET_MODE (x) == mode)
922118334Speter	return x;
922218334Speter    }
922318334Speter
922418334Speter  result = gen_lowpart_common (mode, x);
922518334Speter  if (result != 0
922618334Speter      && GET_CODE (result) == SUBREG
922718334Speter      && GET_CODE (SUBREG_REG (result)) == REG
922818334Speter      && REGNO (SUBREG_REG (result)) >= FIRST_PSEUDO_REGISTER
922918334Speter      && (GET_MODE_SIZE (GET_MODE (result))
923018334Speter	  != GET_MODE_SIZE (GET_MODE (SUBREG_REG (result)))))
923150397Sobrien    REG_CHANGES_SIZE (REGNO (SUBREG_REG (result))) = 1;
923218334Speter
923318334Speter  if (result)
923418334Speter    return result;
923518334Speter
923618334Speter  if (GET_CODE (x) == MEM)
923718334Speter    {
923818334Speter      register int offset = 0;
923918334Speter      rtx new;
924018334Speter
924118334Speter      /* Refuse to work on a volatile memory ref or one with a mode-dependent
924218334Speter	 address.  */
924318334Speter      if (MEM_VOLATILE_P (x) || mode_dependent_address_p (XEXP (x, 0)))
924450397Sobrien	return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
924518334Speter
924618334Speter      /* If we want to refer to something bigger than the original memref,
924718334Speter	 generate a perverse subreg instead.  That will force a reload
924818334Speter	 of the original memref X.  */
924918334Speter      if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode))
925050397Sobrien	return gen_rtx_SUBREG (mode, x, 0);
925118334Speter
925218334Speter      if (WORDS_BIG_ENDIAN)
925318334Speter	offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
925418334Speter		  - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
925518334Speter      if (BYTES_BIG_ENDIAN)
925618334Speter	{
925718334Speter	  /* Adjust the address so that the address-after-the-data is
925818334Speter	     unchanged.  */
925918334Speter	  offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
926018334Speter		     - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
926118334Speter	}
926250397Sobrien      new = gen_rtx_MEM (mode, plus_constant (XEXP (x, 0), offset));
926318334Speter      RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
926452284Sobrien      MEM_COPY_ATTRIBUTES (new, x);
926518334Speter      return new;
926618334Speter    }
926718334Speter
926818334Speter  /* If X is a comparison operator, rewrite it in a new mode.  This
926918334Speter     probably won't match, but may allow further simplifications.  */
927018334Speter  else if (GET_RTX_CLASS (GET_CODE (x)) == '<')
927118334Speter    return gen_rtx_combine (GET_CODE (x), mode, XEXP (x, 0), XEXP (x, 1));
927218334Speter
927318334Speter  /* If we couldn't simplify X any other way, just enclose it in a
927418334Speter     SUBREG.  Normally, this SUBREG won't match, but some patterns may
927518334Speter     include an explicit SUBREG or we may simplify it further in combine.  */
927618334Speter  else
927718334Speter    {
927818334Speter      int word = 0;
927918334Speter
928018334Speter      if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
928118334Speter	word = ((GET_MODE_SIZE (GET_MODE (x))
928218334Speter		 - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD))
928318334Speter		/ UNITS_PER_WORD);
928450397Sobrien      return gen_rtx_SUBREG (mode, x, word);
928518334Speter    }
928618334Speter}
928718334Speter
928818334Speter/* Make an rtx expression.  This is a subset of gen_rtx and only supports
928918334Speter   expressions of 1, 2, or 3 operands, each of which are rtx expressions.
929018334Speter
929118334Speter   If the identical expression was previously in the insn (in the undobuf),
929218334Speter   it will be returned.  Only if it is not found will a new expression
929318334Speter   be made.  */
929418334Speter
929518334Speter/*VARARGS2*/
929618334Speterstatic rtx
929718334Spetergen_rtx_combine VPROTO((enum rtx_code code, enum machine_mode mode, ...))
929818334Speter{
929952284Sobrien#ifndef ANSI_PROTOTYPES
930018334Speter  enum rtx_code code;
930118334Speter  enum machine_mode mode;
930218334Speter#endif
930318334Speter  va_list p;
930418334Speter  int n_args;
930518334Speter  rtx args[3];
930650397Sobrien  int j;
930718334Speter  char *fmt;
930818334Speter  rtx rt;
930950397Sobrien  struct undo *undo;
931018334Speter
931118334Speter  VA_START (p, mode);
931218334Speter
931352284Sobrien#ifndef ANSI_PROTOTYPES
931418334Speter  code = va_arg (p, enum rtx_code);
931518334Speter  mode = va_arg (p, enum machine_mode);
931618334Speter#endif
931718334Speter
931818334Speter  n_args = GET_RTX_LENGTH (code);
931918334Speter  fmt = GET_RTX_FORMAT (code);
932018334Speter
932118334Speter  if (n_args == 0 || n_args > 3)
932218334Speter    abort ();
932318334Speter
932418334Speter  /* Get each arg and verify that it is supposed to be an expression.  */
932518334Speter  for (j = 0; j < n_args; j++)
932618334Speter    {
932718334Speter      if (*fmt++ != 'e')
932818334Speter	abort ();
932918334Speter
933018334Speter      args[j] = va_arg (p, rtx);
933118334Speter    }
933218334Speter
933318334Speter  /* See if this is in undobuf.  Be sure we don't use objects that came
933418334Speter     from another insn; this could produce circular rtl structures.  */
933518334Speter
933650397Sobrien  for (undo = undobuf.undos; undo != undobuf.previous_undos; undo = undo->next)
933750397Sobrien    if (!undo->is_int
933850397Sobrien	&& GET_CODE (undo->old_contents.r) == code
933950397Sobrien	&& GET_MODE (undo->old_contents.r) == mode)
934018334Speter      {
934118334Speter	for (j = 0; j < n_args; j++)
934250397Sobrien	  if (XEXP (undo->old_contents.r, j) != args[j])
934318334Speter	    break;
934418334Speter
934518334Speter	if (j == n_args)
934650397Sobrien	  return undo->old_contents.r;
934718334Speter      }
934818334Speter
934918334Speter  /* Otherwise make a new rtx.  We know we have 1, 2, or 3 args.
935018334Speter     Use rtx_alloc instead of gen_rtx because it's faster on RISC.  */
935118334Speter  rt = rtx_alloc (code);
935218334Speter  PUT_MODE (rt, mode);
935318334Speter  XEXP (rt, 0) = args[0];
935418334Speter  if (n_args > 1)
935518334Speter    {
935618334Speter      XEXP (rt, 1) = args[1];
935718334Speter      if (n_args > 2)
935818334Speter	XEXP (rt, 2) = args[2];
935918334Speter    }
936018334Speter  return rt;
936118334Speter}
936218334Speter
936318334Speter/* These routines make binary and unary operations by first seeing if they
936418334Speter   fold; if not, a new expression is allocated.  */
936518334Speter
936618334Speterstatic rtx
936718334Spetergen_binary (code, mode, op0, op1)
936818334Speter     enum rtx_code code;
936918334Speter     enum machine_mode mode;
937018334Speter     rtx op0, op1;
937118334Speter{
937218334Speter  rtx result;
937318334Speter  rtx tem;
937418334Speter
937518334Speter  if (GET_RTX_CLASS (code) == 'c'
937618334Speter      && (GET_CODE (op0) == CONST_INT
937718334Speter	  || (CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT)))
937818334Speter    tem = op0, op0 = op1, op1 = tem;
937918334Speter
938018334Speter  if (GET_RTX_CLASS (code) == '<')
938118334Speter    {
938218334Speter      enum machine_mode op_mode = GET_MODE (op0);
938318334Speter
938418334Speter      /* Strip the COMPARE from (REL_OP (compare X Y) 0) to get
938550397Sobrien	 just (REL_OP X Y).  */
938618334Speter      if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
938718334Speter	{
938818334Speter	  op1 = XEXP (op0, 1);
938918334Speter	  op0 = XEXP (op0, 0);
939018334Speter	  op_mode = GET_MODE (op0);
939118334Speter	}
939218334Speter
939318334Speter      if (op_mode == VOIDmode)
939418334Speter	op_mode = GET_MODE (op1);
939518334Speter      result = simplify_relational_operation (code, op_mode, op0, op1);
939618334Speter    }
939718334Speter  else
939818334Speter    result = simplify_binary_operation (code, mode, op0, op1);
939918334Speter
940018334Speter  if (result)
940118334Speter    return result;
940218334Speter
940318334Speter  /* Put complex operands first and constants second.  */
940418334Speter  if (GET_RTX_CLASS (code) == 'c'
940518334Speter      && ((CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT)
940618334Speter	  || (GET_RTX_CLASS (GET_CODE (op0)) == 'o'
940718334Speter	      && GET_RTX_CLASS (GET_CODE (op1)) != 'o')
940818334Speter	  || (GET_CODE (op0) == SUBREG
940918334Speter	      && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op0))) == 'o'
941018334Speter	      && GET_RTX_CLASS (GET_CODE (op1)) != 'o')))
941118334Speter    return gen_rtx_combine (code, mode, op1, op0);
941218334Speter
941350397Sobrien  /* If we are turning off bits already known off in OP0, we need not do
941450397Sobrien     an AND.  */
941550397Sobrien  else if (code == AND && GET_CODE (op1) == CONST_INT
941650397Sobrien	   && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
941750397Sobrien	   && (nonzero_bits (op0, mode) & ~ INTVAL (op1)) == 0)
941850397Sobrien    return op0;
941950397Sobrien
942018334Speter  return gen_rtx_combine (code, mode, op0, op1);
942118334Speter}
942218334Speter
942318334Speterstatic rtx
942418334Spetergen_unary (code, mode, op0_mode, op0)
942518334Speter     enum rtx_code code;
942618334Speter     enum machine_mode mode, op0_mode;
942718334Speter     rtx op0;
942818334Speter{
942918334Speter  rtx result = simplify_unary_operation (code, mode, op0, op0_mode);
943018334Speter
943118334Speter  if (result)
943218334Speter    return result;
943318334Speter
943418334Speter  return gen_rtx_combine (code, mode, op0);
943518334Speter}
943618334Speter
943718334Speter/* Simplify a comparison between *POP0 and *POP1 where CODE is the
943818334Speter   comparison code that will be tested.
943918334Speter
944018334Speter   The result is a possibly different comparison code to use.  *POP0 and
944118334Speter   *POP1 may be updated.
944218334Speter
944318334Speter   It is possible that we might detect that a comparison is either always
944418334Speter   true or always false.  However, we do not perform general constant
944518334Speter   folding in combine, so this knowledge isn't useful.  Such tautologies
944618334Speter   should have been detected earlier.  Hence we ignore all such cases.  */
944718334Speter
944818334Speterstatic enum rtx_code
944918334Spetersimplify_comparison (code, pop0, pop1)
945018334Speter     enum rtx_code code;
945118334Speter     rtx *pop0;
945218334Speter     rtx *pop1;
945318334Speter{
945418334Speter  rtx op0 = *pop0;
945518334Speter  rtx op1 = *pop1;
945618334Speter  rtx tem, tem1;
945718334Speter  int i;
945818334Speter  enum machine_mode mode, tmode;
945918334Speter
946018334Speter  /* Try a few ways of applying the same transformation to both operands.  */
946118334Speter  while (1)
946218334Speter    {
946318334Speter#ifndef WORD_REGISTER_OPERATIONS
946418334Speter      /* The test below this one won't handle SIGN_EXTENDs on these machines,
946518334Speter	 so check specially.  */
946618334Speter      if (code != GTU && code != GEU && code != LTU && code != LEU
946718334Speter	  && GET_CODE (op0) == ASHIFTRT && GET_CODE (op1) == ASHIFTRT
946818334Speter	  && GET_CODE (XEXP (op0, 0)) == ASHIFT
946918334Speter	  && GET_CODE (XEXP (op1, 0)) == ASHIFT
947018334Speter	  && GET_CODE (XEXP (XEXP (op0, 0), 0)) == SUBREG
947118334Speter	  && GET_CODE (XEXP (XEXP (op1, 0), 0)) == SUBREG
947218334Speter	  && (GET_MODE (SUBREG_REG (XEXP (XEXP (op0, 0), 0)))
947318334Speter	      == GET_MODE (SUBREG_REG (XEXP (XEXP (op1, 0), 0))))
947418334Speter	  && GET_CODE (XEXP (op0, 1)) == CONST_INT
947518334Speter	  && GET_CODE (XEXP (op1, 1)) == CONST_INT
947618334Speter	  && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
947718334Speter	  && GET_CODE (XEXP (XEXP (op1, 0), 1)) == CONST_INT
947818334Speter	  && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (op1, 1))
947918334Speter	  && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (XEXP (op0, 0), 1))
948018334Speter	  && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (XEXP (op1, 0), 1))
948118334Speter	  && (INTVAL (XEXP (op0, 1))
948218334Speter	      == (GET_MODE_BITSIZE (GET_MODE (op0))
948318334Speter		  - (GET_MODE_BITSIZE
948418334Speter		     (GET_MODE (SUBREG_REG (XEXP (XEXP (op0, 0), 0))))))))
948518334Speter	{
948618334Speter	  op0 = SUBREG_REG (XEXP (XEXP (op0, 0), 0));
948718334Speter	  op1 = SUBREG_REG (XEXP (XEXP (op1, 0), 0));
948818334Speter	}
948918334Speter#endif
949018334Speter
949118334Speter      /* If both operands are the same constant shift, see if we can ignore the
949218334Speter	 shift.  We can if the shift is a rotate or if the bits shifted out of
949318334Speter	 this shift are known to be zero for both inputs and if the type of
949418334Speter	 comparison is compatible with the shift.  */
949518334Speter      if (GET_CODE (op0) == GET_CODE (op1)
949618334Speter	  && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT
949718334Speter	  && ((GET_CODE (op0) == ROTATE && (code == NE || code == EQ))
949818334Speter	      || ((GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFT)
949918334Speter		  && (code != GT && code != LT && code != GE && code != LE))
950018334Speter	      || (GET_CODE (op0) == ASHIFTRT
950118334Speter		  && (code != GTU && code != LTU
950218334Speter		      && code != GEU && code != GEU)))
950318334Speter	  && GET_CODE (XEXP (op0, 1)) == CONST_INT
950418334Speter	  && INTVAL (XEXP (op0, 1)) >= 0
950518334Speter	  && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT
950618334Speter	  && XEXP (op0, 1) == XEXP (op1, 1))
950718334Speter	{
950818334Speter	  enum machine_mode mode = GET_MODE (op0);
950918334Speter	  unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
951018334Speter	  int shift_count = INTVAL (XEXP (op0, 1));
951118334Speter
951218334Speter	  if (GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFTRT)
951318334Speter	    mask &= (mask >> shift_count) << shift_count;
951418334Speter	  else if (GET_CODE (op0) == ASHIFT)
951518334Speter	    mask = (mask & (mask << shift_count)) >> shift_count;
951618334Speter
951718334Speter	  if ((nonzero_bits (XEXP (op0, 0), mode) & ~ mask) == 0
951818334Speter	      && (nonzero_bits (XEXP (op1, 0), mode) & ~ mask) == 0)
951918334Speter	    op0 = XEXP (op0, 0), op1 = XEXP (op1, 0);
952018334Speter	  else
952118334Speter	    break;
952218334Speter	}
952318334Speter
952418334Speter      /* If both operands are AND's of a paradoxical SUBREG by constant, the
952518334Speter	 SUBREGs are of the same mode, and, in both cases, the AND would
952618334Speter	 be redundant if the comparison was done in the narrower mode,
952718334Speter	 do the comparison in the narrower mode (e.g., we are AND'ing with 1
952818334Speter	 and the operand's possibly nonzero bits are 0xffffff01; in that case
952918334Speter	 if we only care about QImode, we don't need the AND).  This case
953018334Speter	 occurs if the output mode of an scc insn is not SImode and
953118334Speter	 STORE_FLAG_VALUE == 1 (e.g., the 386).
953218334Speter
953318334Speter	 Similarly, check for a case where the AND's are ZERO_EXTEND
953418334Speter	 operations from some narrower mode even though a SUBREG is not
953518334Speter	 present.  */
953618334Speter
953718334Speter      else if  (GET_CODE (op0) == AND && GET_CODE (op1) == AND
953818334Speter		&& GET_CODE (XEXP (op0, 1)) == CONST_INT
953918334Speter		&& GET_CODE (XEXP (op1, 1)) == CONST_INT)
954018334Speter	{
954118334Speter	  rtx inner_op0 = XEXP (op0, 0);
954218334Speter	  rtx inner_op1 = XEXP (op1, 0);
954318334Speter	  HOST_WIDE_INT c0 = INTVAL (XEXP (op0, 1));
954418334Speter	  HOST_WIDE_INT c1 = INTVAL (XEXP (op1, 1));
954518334Speter	  int changed = 0;
954618334Speter
954718334Speter	  if (GET_CODE (inner_op0) == SUBREG && GET_CODE (inner_op1) == SUBREG
954818334Speter	      && (GET_MODE_SIZE (GET_MODE (inner_op0))
954918334Speter		  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner_op0))))
955018334Speter	      && (GET_MODE (SUBREG_REG (inner_op0))
955118334Speter		  == GET_MODE (SUBREG_REG (inner_op1)))
955250397Sobrien	      && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (inner_op0)))
955318334Speter		  <= HOST_BITS_PER_WIDE_INT)
955450397Sobrien	      && (0 == ((~c0) & nonzero_bits (SUBREG_REG (inner_op0),
955550397Sobrien					     GET_MODE (SUBREG_REG (inner_op0)))))
955650397Sobrien	      && (0 == ((~c1) & nonzero_bits (SUBREG_REG (inner_op1),
955750397Sobrien					     GET_MODE (SUBREG_REG (inner_op1))))))
955818334Speter	    {
955918334Speter	      op0 = SUBREG_REG (inner_op0);
956018334Speter	      op1 = SUBREG_REG (inner_op1);
956118334Speter
956218334Speter	      /* The resulting comparison is always unsigned since we masked
956350397Sobrien		 off the original sign bit.  */
956418334Speter	      code = unsigned_condition (code);
956518334Speter
956618334Speter	      changed = 1;
956718334Speter	    }
956818334Speter
956918334Speter	  else if (c0 == c1)
957018334Speter	    for (tmode = GET_CLASS_NARROWEST_MODE
957118334Speter		 (GET_MODE_CLASS (GET_MODE (op0)));
957218334Speter		 tmode != GET_MODE (op0); tmode = GET_MODE_WIDER_MODE (tmode))
957352284Sobrien	      if ((unsigned HOST_WIDE_INT) c0 == GET_MODE_MASK (tmode))
957418334Speter		{
957518334Speter		  op0 = gen_lowpart_for_combine (tmode, inner_op0);
957618334Speter		  op1 = gen_lowpart_for_combine (tmode, inner_op1);
957718334Speter		  code = unsigned_condition (code);
957818334Speter		  changed = 1;
957918334Speter		  break;
958018334Speter		}
958118334Speter
958218334Speter	  if (! changed)
958318334Speter	    break;
958418334Speter	}
958518334Speter
958618334Speter      /* If both operands are NOT, we can strip off the outer operation
958718334Speter	 and adjust the comparison code for swapped operands; similarly for
958818334Speter	 NEG, except that this must be an equality comparison.  */
958918334Speter      else if ((GET_CODE (op0) == NOT && GET_CODE (op1) == NOT)
959018334Speter	       || (GET_CODE (op0) == NEG && GET_CODE (op1) == NEG
959118334Speter		   && (code == EQ || code == NE)))
959218334Speter	op0 = XEXP (op0, 0), op1 = XEXP (op1, 0), code = swap_condition (code);
959318334Speter
959418334Speter      else
959518334Speter	break;
959618334Speter    }
959718334Speter
959818334Speter  /* If the first operand is a constant, swap the operands and adjust the
959950397Sobrien     comparison code appropriately, but don't do this if the second operand
960050397Sobrien     is already a constant integer.  */
960150397Sobrien  if (CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT)
960218334Speter    {
960318334Speter      tem = op0, op0 = op1, op1 = tem;
960418334Speter      code = swap_condition (code);
960518334Speter    }
960618334Speter
960718334Speter  /* We now enter a loop during which we will try to simplify the comparison.
960818334Speter     For the most part, we only are concerned with comparisons with zero,
960918334Speter     but some things may really be comparisons with zero but not start
961018334Speter     out looking that way.  */
961118334Speter
961218334Speter  while (GET_CODE (op1) == CONST_INT)
961318334Speter    {
961418334Speter      enum machine_mode mode = GET_MODE (op0);
961518334Speter      int mode_width = GET_MODE_BITSIZE (mode);
961618334Speter      unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
961718334Speter      int equality_comparison_p;
961818334Speter      int sign_bit_comparison_p;
961918334Speter      int unsigned_comparison_p;
962018334Speter      HOST_WIDE_INT const_op;
962118334Speter
962218334Speter      /* We only want to handle integral modes.  This catches VOIDmode,
962318334Speter	 CCmode, and the floating-point modes.  An exception is that we
962418334Speter	 can handle VOIDmode if OP0 is a COMPARE or a comparison
962518334Speter	 operation.  */
962618334Speter
962718334Speter      if (GET_MODE_CLASS (mode) != MODE_INT
962818334Speter	  && ! (mode == VOIDmode
962918334Speter		&& (GET_CODE (op0) == COMPARE
963018334Speter		    || GET_RTX_CLASS (GET_CODE (op0)) == '<')))
963118334Speter	break;
963218334Speter
963318334Speter      /* Get the constant we are comparing against and turn off all bits
963418334Speter	 not on in our mode.  */
963518334Speter      const_op = INTVAL (op1);
963618334Speter      if (mode_width <= HOST_BITS_PER_WIDE_INT)
963718334Speter	const_op &= mask;
963818334Speter
963918334Speter      /* If we are comparing against a constant power of two and the value
964018334Speter	 being compared can only have that single bit nonzero (e.g., it was
964118334Speter	 `and'ed with that bit), we can replace this with a comparison
964218334Speter	 with zero.  */
964318334Speter      if (const_op
964418334Speter	  && (code == EQ || code == NE || code == GE || code == GEU
964518334Speter	      || code == LT || code == LTU)
964618334Speter	  && mode_width <= HOST_BITS_PER_WIDE_INT
964718334Speter	  && exact_log2 (const_op) >= 0
964852284Sobrien	  && nonzero_bits (op0, mode) == (unsigned HOST_WIDE_INT) const_op)
964918334Speter	{
965018334Speter	  code = (code == EQ || code == GE || code == GEU ? NE : EQ);
965118334Speter	  op1 = const0_rtx, const_op = 0;
965218334Speter	}
965318334Speter
965418334Speter      /* Similarly, if we are comparing a value known to be either -1 or
965518334Speter	 0 with -1, change it to the opposite comparison against zero.  */
965618334Speter
965718334Speter      if (const_op == -1
965818334Speter	  && (code == EQ || code == NE || code == GT || code == LE
965918334Speter	      || code == GEU || code == LTU)
966018334Speter	  && num_sign_bit_copies (op0, mode) == mode_width)
966118334Speter	{
966218334Speter	  code = (code == EQ || code == LE || code == GEU ? NE : EQ);
966318334Speter	  op1 = const0_rtx, const_op = 0;
966418334Speter	}
966518334Speter
966618334Speter      /* Do some canonicalizations based on the comparison code.  We prefer
966718334Speter	 comparisons against zero and then prefer equality comparisons.
966818334Speter	 If we can reduce the size of a constant, we will do that too.  */
966918334Speter
967018334Speter      switch (code)
967118334Speter	{
967218334Speter	case LT:
967318334Speter	  /* < C is equivalent to <= (C - 1) */
967418334Speter	  if (const_op > 0)
967518334Speter	    {
967618334Speter	      const_op -= 1;
967718334Speter	      op1 = GEN_INT (const_op);
967818334Speter	      code = LE;
967918334Speter	      /* ... fall through to LE case below.  */
968018334Speter	    }
968118334Speter	  else
968218334Speter	    break;
968318334Speter
968418334Speter	case LE:
968518334Speter	  /* <= C is equivalent to < (C + 1); we do this for C < 0  */
968618334Speter	  if (const_op < 0)
968718334Speter	    {
968818334Speter	      const_op += 1;
968918334Speter	      op1 = GEN_INT (const_op);
969018334Speter	      code = LT;
969118334Speter	    }
969218334Speter
969318334Speter	  /* If we are doing a <= 0 comparison on a value known to have
969418334Speter	     a zero sign bit, we can replace this with == 0.  */
969518334Speter	  else if (const_op == 0
969618334Speter		   && mode_width <= HOST_BITS_PER_WIDE_INT
969718334Speter		   && (nonzero_bits (op0, mode)
969818334Speter		       & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0)
969918334Speter	    code = EQ;
970018334Speter	  break;
970118334Speter
970218334Speter	case GE:
970350397Sobrien	  /* >= C is equivalent to > (C - 1).  */
970418334Speter	  if (const_op > 0)
970518334Speter	    {
970618334Speter	      const_op -= 1;
970718334Speter	      op1 = GEN_INT (const_op);
970818334Speter	      code = GT;
970918334Speter	      /* ... fall through to GT below.  */
971018334Speter	    }
971118334Speter	  else
971218334Speter	    break;
971318334Speter
971418334Speter	case GT:
971518334Speter	  /* > C is equivalent to >= (C + 1); we do this for C < 0*/
971618334Speter	  if (const_op < 0)
971718334Speter	    {
971818334Speter	      const_op += 1;
971918334Speter	      op1 = GEN_INT (const_op);
972018334Speter	      code = GE;
972118334Speter	    }
972218334Speter
972318334Speter	  /* If we are doing a > 0 comparison on a value known to have
972418334Speter	     a zero sign bit, we can replace this with != 0.  */
972518334Speter	  else if (const_op == 0
972618334Speter		   && mode_width <= HOST_BITS_PER_WIDE_INT
972718334Speter		   && (nonzero_bits (op0, mode)
972818334Speter		       & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0)
972918334Speter	    code = NE;
973018334Speter	  break;
973118334Speter
973218334Speter	case LTU:
973318334Speter	  /* < C is equivalent to <= (C - 1).  */
973418334Speter	  if (const_op > 0)
973518334Speter	    {
973618334Speter	      const_op -= 1;
973718334Speter	      op1 = GEN_INT (const_op);
973818334Speter	      code = LEU;
973950397Sobrien	      /* ... fall through ...  */
974018334Speter	    }
974118334Speter
974218334Speter	  /* (unsigned) < 0x80000000 is equivalent to >= 0.  */
974350397Sobrien	  else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
974450397Sobrien		   && (const_op == (HOST_WIDE_INT) 1 << (mode_width - 1)))
974518334Speter	    {
974618334Speter	      const_op = 0, op1 = const0_rtx;
974718334Speter	      code = GE;
974818334Speter	      break;
974918334Speter	    }
975018334Speter	  else
975118334Speter	    break;
975218334Speter
975318334Speter	case LEU:
975418334Speter	  /* unsigned <= 0 is equivalent to == 0 */
975518334Speter	  if (const_op == 0)
975618334Speter	    code = EQ;
975718334Speter
975850397Sobrien	  /* (unsigned) <= 0x7fffffff is equivalent to >= 0.  */
975950397Sobrien	  else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
976050397Sobrien		   && (const_op == ((HOST_WIDE_INT) 1 << (mode_width - 1)) - 1))
976118334Speter	    {
976218334Speter	      const_op = 0, op1 = const0_rtx;
976318334Speter	      code = GE;
976418334Speter	    }
976518334Speter	  break;
976618334Speter
976718334Speter	case GEU:
976818334Speter	  /* >= C is equivalent to < (C - 1).  */
976918334Speter	  if (const_op > 1)
977018334Speter	    {
977118334Speter	      const_op -= 1;
977218334Speter	      op1 = GEN_INT (const_op);
977318334Speter	      code = GTU;
977450397Sobrien	      /* ... fall through ...  */
977518334Speter	    }
977618334Speter
977718334Speter	  /* (unsigned) >= 0x80000000 is equivalent to < 0.  */
977850397Sobrien	  else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
977950397Sobrien		   && (const_op == (HOST_WIDE_INT) 1 << (mode_width - 1)))
978018334Speter	    {
978118334Speter	      const_op = 0, op1 = const0_rtx;
978218334Speter	      code = LT;
978318334Speter	      break;
978418334Speter	    }
978518334Speter	  else
978618334Speter	    break;
978718334Speter
978818334Speter	case GTU:
978918334Speter	  /* unsigned > 0 is equivalent to != 0 */
979018334Speter	  if (const_op == 0)
979118334Speter	    code = NE;
979218334Speter
979318334Speter	  /* (unsigned) > 0x7fffffff is equivalent to < 0.  */
979450397Sobrien	  else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
979550397Sobrien		    && (const_op == ((HOST_WIDE_INT) 1 << (mode_width - 1)) - 1))
979618334Speter	    {
979718334Speter	      const_op = 0, op1 = const0_rtx;
979818334Speter	      code = LT;
979918334Speter	    }
980018334Speter	  break;
980150397Sobrien
980250397Sobrien	default:
980350397Sobrien	  break;
980418334Speter	}
980518334Speter
980618334Speter      /* Compute some predicates to simplify code below.  */
980718334Speter
980818334Speter      equality_comparison_p = (code == EQ || code == NE);
980918334Speter      sign_bit_comparison_p = ((code == LT || code == GE) && const_op == 0);
981018334Speter      unsigned_comparison_p = (code == LTU || code == LEU || code == GTU
981118334Speter			       || code == LEU);
981218334Speter
981318334Speter      /* If this is a sign bit comparison and we can do arithmetic in
981418334Speter	 MODE, say that we will only be needing the sign bit of OP0.  */
981518334Speter      if (sign_bit_comparison_p
981618334Speter	  && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
981718334Speter	op0 = force_to_mode (op0, mode,
981818334Speter			     ((HOST_WIDE_INT) 1
981918334Speter			      << (GET_MODE_BITSIZE (mode) - 1)),
982018334Speter			     NULL_RTX, 0);
982118334Speter
982218334Speter      /* Now try cases based on the opcode of OP0.  If none of the cases
982318334Speter	 does a "continue", we exit this loop immediately after the
982418334Speter	 switch.  */
982518334Speter
982618334Speter      switch (GET_CODE (op0))
982718334Speter	{
982818334Speter	case ZERO_EXTRACT:
982918334Speter	  /* If we are extracting a single bit from a variable position in
983018334Speter	     a constant that has only a single bit set and are comparing it
983118334Speter	     with zero, we can convert this into an equality comparison
983250397Sobrien	     between the position and the location of the single bit.  */
983318334Speter
983418334Speter	  if (GET_CODE (XEXP (op0, 0)) == CONST_INT
983518334Speter	      && XEXP (op0, 1) == const1_rtx
983618334Speter	      && equality_comparison_p && const_op == 0
983750397Sobrien	      && (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0)
983818334Speter	    {
983950397Sobrien	      if (BITS_BIG_ENDIAN)
984052284Sobrien		{
984118334Speter#ifdef HAVE_extzv
984252284Sobrien		  mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
984352284Sobrien		  if (mode == VOIDmode)
984452284Sobrien		    mode = word_mode;
984552284Sobrien		  i = (GET_MODE_BITSIZE (mode) - 1 - i);
984650397Sobrien#else
984752284Sobrien	          i = BITS_PER_WORD - 1 - i;
984818334Speter#endif
984952284Sobrien		}
985018334Speter
985118334Speter	      op0 = XEXP (op0, 2);
985218334Speter	      op1 = GEN_INT (i);
985318334Speter	      const_op = i;
985418334Speter
985518334Speter	      /* Result is nonzero iff shift count is equal to I.  */
985618334Speter	      code = reverse_condition (code);
985718334Speter	      continue;
985818334Speter	    }
985918334Speter
986050397Sobrien	  /* ... fall through ...  */
986118334Speter
986218334Speter	case SIGN_EXTRACT:
986318334Speter	  tem = expand_compound_operation (op0);
986418334Speter	  if (tem != op0)
986518334Speter	    {
986618334Speter	      op0 = tem;
986718334Speter	      continue;
986818334Speter	    }
986918334Speter	  break;
987018334Speter
987118334Speter	case NOT:
987218334Speter	  /* If testing for equality, we can take the NOT of the constant.  */
987318334Speter	  if (equality_comparison_p
987418334Speter	      && (tem = simplify_unary_operation (NOT, mode, op1, mode)) != 0)
987518334Speter	    {
987618334Speter	      op0 = XEXP (op0, 0);
987718334Speter	      op1 = tem;
987818334Speter	      continue;
987918334Speter	    }
988018334Speter
988118334Speter	  /* If just looking at the sign bit, reverse the sense of the
988218334Speter	     comparison.  */
988318334Speter	  if (sign_bit_comparison_p)
988418334Speter	    {
988518334Speter	      op0 = XEXP (op0, 0);
988618334Speter	      code = (code == GE ? LT : GE);
988718334Speter	      continue;
988818334Speter	    }
988918334Speter	  break;
989018334Speter
989118334Speter	case NEG:
989218334Speter	  /* If testing for equality, we can take the NEG of the constant.  */
989318334Speter	  if (equality_comparison_p
989418334Speter	      && (tem = simplify_unary_operation (NEG, mode, op1, mode)) != 0)
989518334Speter	    {
989618334Speter	      op0 = XEXP (op0, 0);
989718334Speter	      op1 = tem;
989818334Speter	      continue;
989918334Speter	    }
990018334Speter
990118334Speter	  /* The remaining cases only apply to comparisons with zero.  */
990218334Speter	  if (const_op != 0)
990318334Speter	    break;
990418334Speter
990518334Speter	  /* When X is ABS or is known positive,
990618334Speter	     (neg X) is < 0 if and only if X != 0.  */
990718334Speter
990818334Speter	  if (sign_bit_comparison_p
990918334Speter	      && (GET_CODE (XEXP (op0, 0)) == ABS
991018334Speter		  || (mode_width <= HOST_BITS_PER_WIDE_INT
991118334Speter		      && (nonzero_bits (XEXP (op0, 0), mode)
991218334Speter			  & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0)))
991318334Speter	    {
991418334Speter	      op0 = XEXP (op0, 0);
991518334Speter	      code = (code == LT ? NE : EQ);
991618334Speter	      continue;
991718334Speter	    }
991818334Speter
991918334Speter	  /* If we have NEG of something whose two high-order bits are the
992050397Sobrien	     same, we know that "(-a) < 0" is equivalent to "a > 0".  */
992118334Speter	  if (num_sign_bit_copies (op0, mode) >= 2)
992218334Speter	    {
992318334Speter	      op0 = XEXP (op0, 0);
992418334Speter	      code = swap_condition (code);
992518334Speter	      continue;
992618334Speter	    }
992718334Speter	  break;
992818334Speter
992918334Speter	case ROTATE:
993018334Speter	  /* If we are testing equality and our count is a constant, we
993118334Speter	     can perform the inverse operation on our RHS.  */
993218334Speter	  if (equality_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT
993318334Speter	      && (tem = simplify_binary_operation (ROTATERT, mode,
993418334Speter						   op1, XEXP (op0, 1))) != 0)
993518334Speter	    {
993618334Speter	      op0 = XEXP (op0, 0);
993718334Speter	      op1 = tem;
993818334Speter	      continue;
993918334Speter	    }
994018334Speter
994118334Speter	  /* If we are doing a < 0 or >= 0 comparison, it means we are testing
994218334Speter	     a particular bit.  Convert it to an AND of a constant of that
994318334Speter	     bit.  This will be converted into a ZERO_EXTRACT.  */
994418334Speter	  if (const_op == 0 && sign_bit_comparison_p
994518334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
994618334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT)
994718334Speter	    {
994818334Speter	      op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
994918334Speter					    ((HOST_WIDE_INT) 1
995018334Speter					     << (mode_width - 1
995118334Speter						 - INTVAL (XEXP (op0, 1)))));
995218334Speter	      code = (code == LT ? NE : EQ);
995318334Speter	      continue;
995418334Speter	    }
995518334Speter
995650397Sobrien	  /* ... fall through ...  */
995718334Speter
995818334Speter	case ABS:
995918334Speter	  /* ABS is ignorable inside an equality comparison with zero.  */
996018334Speter	  if (const_op == 0 && equality_comparison_p)
996118334Speter	    {
996218334Speter	      op0 = XEXP (op0, 0);
996318334Speter	      continue;
996418334Speter	    }
996518334Speter	  break;
996618334Speter
996718334Speter
996818334Speter	case SIGN_EXTEND:
996918334Speter	  /* Can simplify (compare (zero/sign_extend FOO) CONST)
997018334Speter	     to (compare FOO CONST) if CONST fits in FOO's mode and we
997118334Speter	     are either testing inequality or have an unsigned comparison
997218334Speter	     with ZERO_EXTEND or a signed comparison with SIGN_EXTEND.  */
997318334Speter	  if (! unsigned_comparison_p
997418334Speter	      && (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0)))
997518334Speter		  <= HOST_BITS_PER_WIDE_INT)
997618334Speter	      && ((unsigned HOST_WIDE_INT) const_op
997752284Sobrien		  < (((unsigned HOST_WIDE_INT) 1
997818334Speter		      << (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))) - 1)))))
997918334Speter	    {
998018334Speter	      op0 = XEXP (op0, 0);
998118334Speter	      continue;
998218334Speter	    }
998318334Speter	  break;
998418334Speter
998518334Speter	case SUBREG:
998618334Speter	  /* Check for the case where we are comparing A - C1 with C2,
998718334Speter	     both constants are smaller than 1/2 the maximum positive
998818334Speter	     value in MODE, and the comparison is equality or unsigned.
998918334Speter	     In that case, if A is either zero-extended to MODE or has
999018334Speter	     sufficient sign bits so that the high-order bit in MODE
999118334Speter	     is a copy of the sign in the inner mode, we can prove that it is
999218334Speter	     safe to do the operation in the wider mode.  This simplifies
999318334Speter	     many range checks.  */
999418334Speter
999518334Speter	  if (mode_width <= HOST_BITS_PER_WIDE_INT
999618334Speter	      && subreg_lowpart_p (op0)
999718334Speter	      && GET_CODE (SUBREG_REG (op0)) == PLUS
999818334Speter	      && GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT
999918334Speter	      && INTVAL (XEXP (SUBREG_REG (op0), 1)) < 0
1000018334Speter	      && (- INTVAL (XEXP (SUBREG_REG (op0), 1))
1000152284Sobrien		  < (HOST_WIDE_INT)(GET_MODE_MASK (mode) / 2))
1000218334Speter	      && (unsigned HOST_WIDE_INT) const_op < GET_MODE_MASK (mode) / 2
1000318334Speter	      && (0 == (nonzero_bits (XEXP (SUBREG_REG (op0), 0),
1000418334Speter				      GET_MODE (SUBREG_REG (op0)))
1000518334Speter			& ~ GET_MODE_MASK (mode))
1000618334Speter		  || (num_sign_bit_copies (XEXP (SUBREG_REG (op0), 0),
1000718334Speter					   GET_MODE (SUBREG_REG (op0)))
1000818334Speter		      > (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
1000918334Speter			 - GET_MODE_BITSIZE (mode)))))
1001018334Speter	    {
1001118334Speter	      op0 = SUBREG_REG (op0);
1001218334Speter	      continue;
1001318334Speter	    }
1001418334Speter
1001518334Speter	  /* If the inner mode is narrower and we are extracting the low part,
1001618334Speter	     we can treat the SUBREG as if it were a ZERO_EXTEND.  */
1001718334Speter	  if (subreg_lowpart_p (op0)
1001818334Speter	      && GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) < mode_width)
1001918334Speter	    /* Fall through */ ;
1002018334Speter	  else
1002118334Speter	    break;
1002218334Speter
1002350397Sobrien	  /* ... fall through ...  */
1002418334Speter
1002518334Speter	case ZERO_EXTEND:
1002618334Speter	  if ((unsigned_comparison_p || equality_comparison_p)
1002718334Speter	      && (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0)))
1002818334Speter		  <= HOST_BITS_PER_WIDE_INT)
1002918334Speter	      && ((unsigned HOST_WIDE_INT) const_op
1003018334Speter		  < GET_MODE_MASK (GET_MODE (XEXP (op0, 0)))))
1003118334Speter	    {
1003218334Speter	      op0 = XEXP (op0, 0);
1003318334Speter	      continue;
1003418334Speter	    }
1003518334Speter	  break;
1003618334Speter
1003718334Speter	case PLUS:
1003818334Speter	  /* (eq (plus X A) B) -> (eq X (minus B A)).  We can only do
1003918334Speter	     this for equality comparisons due to pathological cases involving
1004018334Speter	     overflows.  */
1004118334Speter	  if (equality_comparison_p
1004218334Speter	      && 0 != (tem = simplify_binary_operation (MINUS, mode,
1004318334Speter							op1, XEXP (op0, 1))))
1004418334Speter	    {
1004518334Speter	      op0 = XEXP (op0, 0);
1004618334Speter	      op1 = tem;
1004718334Speter	      continue;
1004818334Speter	    }
1004918334Speter
1005018334Speter	  /* (plus (abs X) (const_int -1)) is < 0 if and only if X == 0.  */
1005118334Speter	  if (const_op == 0 && XEXP (op0, 1) == constm1_rtx
1005218334Speter	      && GET_CODE (XEXP (op0, 0)) == ABS && sign_bit_comparison_p)
1005318334Speter	    {
1005418334Speter	      op0 = XEXP (XEXP (op0, 0), 0);
1005518334Speter	      code = (code == LT ? EQ : NE);
1005618334Speter	      continue;
1005718334Speter	    }
1005818334Speter	  break;
1005918334Speter
1006018334Speter	case MINUS:
1006118334Speter	  /* (eq (minus A B) C) -> (eq A (plus B C)) or
1006218334Speter	     (eq B (minus A C)), whichever simplifies.  We can only do
1006318334Speter	     this for equality comparisons due to pathological cases involving
1006418334Speter	     overflows.  */
1006518334Speter	  if (equality_comparison_p
1006618334Speter	      && 0 != (tem = simplify_binary_operation (PLUS, mode,
1006718334Speter							XEXP (op0, 1), op1)))
1006818334Speter	    {
1006918334Speter	      op0 = XEXP (op0, 0);
1007018334Speter	      op1 = tem;
1007118334Speter	      continue;
1007218334Speter	    }
1007318334Speter
1007418334Speter	  if (equality_comparison_p
1007518334Speter	      && 0 != (tem = simplify_binary_operation (MINUS, mode,
1007618334Speter							XEXP (op0, 0), op1)))
1007718334Speter	    {
1007818334Speter	      op0 = XEXP (op0, 1);
1007918334Speter	      op1 = tem;
1008018334Speter	      continue;
1008118334Speter	    }
1008218334Speter
1008318334Speter	  /* The sign bit of (minus (ashiftrt X C) X), where C is the number
1008418334Speter	     of bits in X minus 1, is one iff X > 0.  */
1008518334Speter	  if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 0)) == ASHIFTRT
1008618334Speter	      && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
1008718334Speter	      && INTVAL (XEXP (XEXP (op0, 0), 1)) == mode_width - 1
1008818334Speter	      && rtx_equal_p (XEXP (XEXP (op0, 0), 0), XEXP (op0, 1)))
1008918334Speter	    {
1009018334Speter	      op0 = XEXP (op0, 1);
1009118334Speter	      code = (code == GE ? LE : GT);
1009218334Speter	      continue;
1009318334Speter	    }
1009418334Speter	  break;
1009518334Speter
1009618334Speter	case XOR:
1009718334Speter	  /* (eq (xor A B) C) -> (eq A (xor B C)).  This is a simplification
1009818334Speter	     if C is zero or B is a constant.  */
1009918334Speter	  if (equality_comparison_p
1010018334Speter	      && 0 != (tem = simplify_binary_operation (XOR, mode,
1010118334Speter							XEXP (op0, 1), op1)))
1010218334Speter	    {
1010318334Speter	      op0 = XEXP (op0, 0);
1010418334Speter	      op1 = tem;
1010518334Speter	      continue;
1010618334Speter	    }
1010718334Speter	  break;
1010818334Speter
1010918334Speter	case EQ:  case NE:
1011018334Speter	case LT:  case LTU:  case LE:  case LEU:
1011118334Speter	case GT:  case GTU:  case GE:  case GEU:
1011218334Speter	  /* We can't do anything if OP0 is a condition code value, rather
1011318334Speter	     than an actual data value.  */
1011418334Speter	  if (const_op != 0
1011518334Speter#ifdef HAVE_cc0
1011618334Speter	      || XEXP (op0, 0) == cc0_rtx
1011718334Speter#endif
1011818334Speter	      || GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC)
1011918334Speter	    break;
1012018334Speter
1012118334Speter	  /* Get the two operands being compared.  */
1012218334Speter	  if (GET_CODE (XEXP (op0, 0)) == COMPARE)
1012318334Speter	    tem = XEXP (XEXP (op0, 0), 0), tem1 = XEXP (XEXP (op0, 0), 1);
1012418334Speter	  else
1012518334Speter	    tem = XEXP (op0, 0), tem1 = XEXP (op0, 1);
1012618334Speter
1012718334Speter	  /* Check for the cases where we simply want the result of the
1012818334Speter	     earlier test or the opposite of that result.  */
1012918334Speter	  if (code == NE
1013018334Speter	      || (code == EQ && reversible_comparison_p (op0))
1013118334Speter	      || (GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT
1013218334Speter		  && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
1013318334Speter		  && (STORE_FLAG_VALUE
1013418334Speter		      & (((HOST_WIDE_INT) 1
1013518334Speter			  << (GET_MODE_BITSIZE (GET_MODE (op0)) - 1))))
1013618334Speter		  && (code == LT
1013718334Speter		      || (code == GE && reversible_comparison_p (op0)))))
1013818334Speter	    {
1013918334Speter	      code = (code == LT || code == NE
1014018334Speter		      ? GET_CODE (op0) : reverse_condition (GET_CODE (op0)));
1014118334Speter	      op0 = tem, op1 = tem1;
1014218334Speter	      continue;
1014318334Speter	    }
1014418334Speter	  break;
1014518334Speter
1014618334Speter	case IOR:
1014718334Speter	  /* The sign bit of (ior (plus X (const_int -1)) X) is non-zero
1014818334Speter	     iff X <= 0.  */
1014918334Speter	  if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 0)) == PLUS
1015018334Speter	      && XEXP (XEXP (op0, 0), 1) == constm1_rtx
1015118334Speter	      && rtx_equal_p (XEXP (XEXP (op0, 0), 0), XEXP (op0, 1)))
1015218334Speter	    {
1015318334Speter	      op0 = XEXP (op0, 1);
1015418334Speter	      code = (code == GE ? GT : LE);
1015518334Speter	      continue;
1015618334Speter	    }
1015718334Speter	  break;
1015818334Speter
1015918334Speter	case AND:
1016018334Speter	  /* Convert (and (xshift 1 X) Y) to (and (lshiftrt Y X) 1).  This
1016118334Speter	     will be converted to a ZERO_EXTRACT later.  */
1016218334Speter	  if (const_op == 0 && equality_comparison_p
1016318334Speter	      && GET_CODE (XEXP (op0, 0)) == ASHIFT
1016418334Speter	      && XEXP (XEXP (op0, 0), 0) == const1_rtx)
1016518334Speter	    {
1016618334Speter	      op0 = simplify_and_const_int
1016718334Speter		(op0, mode, gen_rtx_combine (LSHIFTRT, mode,
1016818334Speter					     XEXP (op0, 1),
1016918334Speter					     XEXP (XEXP (op0, 0), 1)),
1017018334Speter		 (HOST_WIDE_INT) 1);
1017118334Speter	      continue;
1017218334Speter	    }
1017318334Speter
1017418334Speter	  /* If we are comparing (and (lshiftrt X C1) C2) for equality with
1017518334Speter	     zero and X is a comparison and C1 and C2 describe only bits set
1017618334Speter	     in STORE_FLAG_VALUE, we can compare with X.  */
1017718334Speter	  if (const_op == 0 && equality_comparison_p
1017818334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT
1017918334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1018018334Speter	      && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
1018118334Speter	      && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
1018218334Speter	      && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
1018318334Speter	      && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT)
1018418334Speter	    {
1018518334Speter	      mask = ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode))
1018618334Speter		      << INTVAL (XEXP (XEXP (op0, 0), 1)));
1018718334Speter	      if ((~ STORE_FLAG_VALUE & mask) == 0
1018818334Speter		  && (GET_RTX_CLASS (GET_CODE (XEXP (XEXP (op0, 0), 0))) == '<'
1018918334Speter		      || ((tem = get_last_value (XEXP (XEXP (op0, 0), 0))) != 0
1019018334Speter			  && GET_RTX_CLASS (GET_CODE (tem)) == '<')))
1019118334Speter		{
1019218334Speter		  op0 = XEXP (XEXP (op0, 0), 0);
1019318334Speter		  continue;
1019418334Speter		}
1019518334Speter	    }
1019618334Speter
1019718334Speter	  /* If we are doing an equality comparison of an AND of a bit equal
1019818334Speter	     to the sign bit, replace this with a LT or GE comparison of
1019918334Speter	     the underlying value.  */
1020018334Speter	  if (equality_comparison_p
1020118334Speter	      && const_op == 0
1020218334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1020318334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT
1020418334Speter	      && ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode))
1020552284Sobrien		  == (unsigned HOST_WIDE_INT) 1 << (mode_width - 1)))
1020618334Speter	    {
1020718334Speter	      op0 = XEXP (op0, 0);
1020818334Speter	      code = (code == EQ ? GE : LT);
1020918334Speter	      continue;
1021018334Speter	    }
1021118334Speter
1021218334Speter	  /* If this AND operation is really a ZERO_EXTEND from a narrower
1021318334Speter	     mode, the constant fits within that mode, and this is either an
1021418334Speter	     equality or unsigned comparison, try to do this comparison in
1021518334Speter	     the narrower mode.  */
1021618334Speter	  if ((equality_comparison_p || unsigned_comparison_p)
1021718334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1021818334Speter	      && (i = exact_log2 ((INTVAL (XEXP (op0, 1))
1021918334Speter				   & GET_MODE_MASK (mode))
1022018334Speter				  + 1)) >= 0
1022118334Speter	      && const_op >> i == 0
1022218334Speter	      && (tmode = mode_for_size (i, MODE_INT, 1)) != BLKmode)
1022318334Speter	    {
1022418334Speter	      op0 = gen_lowpart_for_combine (tmode, XEXP (op0, 0));
1022518334Speter	      continue;
1022618334Speter	    }
1022750397Sobrien
1022850397Sobrien	  /* If this is (and:M1 (subreg:M2 X 0) (const_int C1)) where C1 fits
1022950397Sobrien	     in both M1 and M2 and the SUBREG is either paradoxical or
1023050397Sobrien	     represents the low part, permute the SUBREG and the AND and
1023150397Sobrien	     try again.  */
1023250397Sobrien	  if (GET_CODE (XEXP (op0, 0)) == SUBREG
1023350397Sobrien	      && ((mode_width
1023450397Sobrien		   >= GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0)))))
1023550397Sobrien#ifdef WORD_REGISTER_OPERATIONS
1023650397Sobrien		  || subreg_lowpart_p (XEXP (op0, 0))
1023750397Sobrien#endif
1023850397Sobrien		  )
1023950397Sobrien#ifndef WORD_REGISTER_OPERATIONS
1024050397Sobrien	      /* It is unsafe to commute the AND into the SUBREG if the SUBREG
1024150397Sobrien		 is paradoxical and WORD_REGISTER_OPERATIONS is not defined.
1024250397Sobrien		 As originally written the upper bits have a defined value
1024350397Sobrien		 due to the AND operation.  However, if we commute the AND
1024450397Sobrien		 inside the SUBREG then they no longer have defined values
1024550397Sobrien		 and the meaning of the code has been changed.  */
1024650397Sobrien	      && (GET_MODE_SIZE (GET_MODE (XEXP (op0, 0)))
1024750397Sobrien		  <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0)))))
1024850397Sobrien#endif
1024950397Sobrien	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1025050397Sobrien	      && mode_width <= HOST_BITS_PER_WIDE_INT
1025150397Sobrien	      && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0))))
1025250397Sobrien		  <= HOST_BITS_PER_WIDE_INT)
1025350397Sobrien	      && (INTVAL (XEXP (op0, 1)) & ~ mask) == 0
1025450397Sobrien	      && 0 == (~ GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0))))
1025550397Sobrien		       & INTVAL (XEXP (op0, 1)))
1025652284Sobrien	      && (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1)) != mask
1025752284Sobrien	      && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1))
1025850397Sobrien		  != GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0))))))
1025950397Sobrien
1026050397Sobrien	    {
1026150397Sobrien	      op0
1026250397Sobrien		= gen_lowpart_for_combine
1026350397Sobrien		  (mode,
1026450397Sobrien		   gen_binary (AND, GET_MODE (SUBREG_REG (XEXP (op0, 0))),
1026550397Sobrien			       SUBREG_REG (XEXP (op0, 0)), XEXP (op0, 1)));
1026650397Sobrien	      continue;
1026750397Sobrien	    }
1026850397Sobrien
1026918334Speter	  break;
1027018334Speter
1027118334Speter	case ASHIFT:
1027218334Speter	  /* If we have (compare (ashift FOO N) (const_int C)) and
1027318334Speter	     the high order N bits of FOO (N+1 if an inequality comparison)
1027418334Speter	     are known to be zero, we can do this by comparing FOO with C
1027518334Speter	     shifted right N bits so long as the low-order N bits of C are
1027618334Speter	     zero.  */
1027718334Speter	  if (GET_CODE (XEXP (op0, 1)) == CONST_INT
1027818334Speter	      && INTVAL (XEXP (op0, 1)) >= 0
1027918334Speter	      && ((INTVAL (XEXP (op0, 1)) + ! equality_comparison_p)
1028018334Speter		  < HOST_BITS_PER_WIDE_INT)
1028118334Speter	      && ((const_op
1028218334Speter		   & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0)
1028318334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT
1028418334Speter	      && (nonzero_bits (XEXP (op0, 0), mode)
1028518334Speter		  & ~ (mask >> (INTVAL (XEXP (op0, 1))
1028618334Speter				+ ! equality_comparison_p))) == 0)
1028718334Speter	    {
1028818334Speter	      const_op >>= INTVAL (XEXP (op0, 1));
1028918334Speter	      op1 = GEN_INT (const_op);
1029018334Speter	      op0 = XEXP (op0, 0);
1029118334Speter	      continue;
1029218334Speter	    }
1029318334Speter
1029418334Speter	  /* If we are doing a sign bit comparison, it means we are testing
1029518334Speter	     a particular bit.  Convert it to the appropriate AND.  */
1029618334Speter	  if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT
1029718334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT)
1029818334Speter	    {
1029918334Speter	      op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
1030018334Speter					    ((HOST_WIDE_INT) 1
1030118334Speter					     << (mode_width - 1
1030218334Speter						 - INTVAL (XEXP (op0, 1)))));
1030318334Speter	      code = (code == LT ? NE : EQ);
1030418334Speter	      continue;
1030518334Speter	    }
1030618334Speter
1030718334Speter	  /* If this an equality comparison with zero and we are shifting
1030818334Speter	     the low bit to the sign bit, we can convert this to an AND of the
1030918334Speter	     low-order bit.  */
1031018334Speter	  if (const_op == 0 && equality_comparison_p
1031118334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1031218334Speter	      && INTVAL (XEXP (op0, 1)) == mode_width - 1)
1031318334Speter	    {
1031418334Speter	      op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
1031518334Speter					    (HOST_WIDE_INT) 1);
1031618334Speter	      continue;
1031718334Speter	    }
1031818334Speter	  break;
1031918334Speter
1032018334Speter	case ASHIFTRT:
1032118334Speter	  /* If this is an equality comparison with zero, we can do this
1032218334Speter	     as a logical shift, which might be much simpler.  */
1032318334Speter	  if (equality_comparison_p && const_op == 0
1032418334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT)
1032518334Speter	    {
1032618334Speter	      op0 = simplify_shift_const (NULL_RTX, LSHIFTRT, mode,
1032718334Speter					  XEXP (op0, 0),
1032818334Speter					  INTVAL (XEXP (op0, 1)));
1032918334Speter	      continue;
1033018334Speter	    }
1033118334Speter
1033218334Speter	  /* If OP0 is a sign extension and CODE is not an unsigned comparison,
1033318334Speter	     do the comparison in a narrower mode.  */
1033418334Speter	  if (! unsigned_comparison_p
1033518334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1033618334Speter	      && GET_CODE (XEXP (op0, 0)) == ASHIFT
1033718334Speter	      && XEXP (op0, 1) == XEXP (XEXP (op0, 0), 1)
1033818334Speter	      && (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)),
1033918334Speter					 MODE_INT, 1)) != BLKmode
1034018334Speter	      && ((unsigned HOST_WIDE_INT) const_op <= GET_MODE_MASK (tmode)
1034118334Speter		  || ((unsigned HOST_WIDE_INT) - const_op
1034218334Speter		      <= GET_MODE_MASK (tmode))))
1034318334Speter	    {
1034418334Speter	      op0 = gen_lowpart_for_combine (tmode, XEXP (XEXP (op0, 0), 0));
1034518334Speter	      continue;
1034618334Speter	    }
1034718334Speter
1034850397Sobrien	  /* ... fall through ...  */
1034918334Speter	case LSHIFTRT:
1035018334Speter	  /* If we have (compare (xshiftrt FOO N) (const_int C)) and
1035118334Speter	     the low order N bits of FOO are known to be zero, we can do this
1035218334Speter	     by comparing FOO with C shifted left N bits so long as no
1035318334Speter	     overflow occurs.  */
1035418334Speter	  if (GET_CODE (XEXP (op0, 1)) == CONST_INT
1035518334Speter	      && INTVAL (XEXP (op0, 1)) >= 0
1035618334Speter	      && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT
1035718334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT
1035818334Speter	      && (nonzero_bits (XEXP (op0, 0), mode)
1035918334Speter		  & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0
1036018334Speter	      && (const_op == 0
1036118334Speter		  || (floor_log2 (const_op) + INTVAL (XEXP (op0, 1))
1036218334Speter		      < mode_width)))
1036318334Speter	    {
1036418334Speter	      const_op <<= INTVAL (XEXP (op0, 1));
1036518334Speter	      op1 = GEN_INT (const_op);
1036618334Speter	      op0 = XEXP (op0, 0);
1036718334Speter	      continue;
1036818334Speter	    }
1036918334Speter
1037018334Speter	  /* If we are using this shift to extract just the sign bit, we
1037118334Speter	     can replace this with an LT or GE comparison.  */
1037218334Speter	  if (const_op == 0
1037318334Speter	      && (equality_comparison_p || sign_bit_comparison_p)
1037418334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1037518334Speter	      && INTVAL (XEXP (op0, 1)) == mode_width - 1)
1037618334Speter	    {
1037718334Speter	      op0 = XEXP (op0, 0);
1037818334Speter	      code = (code == NE || code == GT ? LT : GE);
1037918334Speter	      continue;
1038018334Speter	    }
1038118334Speter	  break;
1038250397Sobrien
1038350397Sobrien	default:
1038450397Sobrien	  break;
1038518334Speter	}
1038618334Speter
1038718334Speter      break;
1038818334Speter    }
1038918334Speter
1039018334Speter  /* Now make any compound operations involved in this comparison.  Then,
1039150397Sobrien     check for an outmost SUBREG on OP0 that is not doing anything or is
1039218334Speter     paradoxical.  The latter case can only occur when it is known that the
1039318334Speter     "extra" bits will be zero.  Therefore, it is safe to remove the SUBREG.
1039418334Speter     We can never remove a SUBREG for a non-equality comparison because the
1039518334Speter     sign bit is in a different place in the underlying object.  */
1039618334Speter
1039718334Speter  op0 = make_compound_operation (op0, op1 == const0_rtx ? COMPARE : SET);
1039818334Speter  op1 = make_compound_operation (op1, SET);
1039918334Speter
1040018334Speter  if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0)
1040118334Speter      && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
1040218334Speter      && (code == NE || code == EQ)
1040318334Speter      && ((GET_MODE_SIZE (GET_MODE (op0))
1040418334Speter	   > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))))
1040518334Speter    {
1040618334Speter      op0 = SUBREG_REG (op0);
1040718334Speter      op1 = gen_lowpart_for_combine (GET_MODE (op0), op1);
1040818334Speter    }
1040918334Speter
1041018334Speter  else if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0)
1041118334Speter	   && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
1041218334Speter	   && (code == NE || code == EQ)
1041318334Speter	   && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
1041418334Speter	       <= HOST_BITS_PER_WIDE_INT)
1041518334Speter	   && (nonzero_bits (SUBREG_REG (op0), GET_MODE (SUBREG_REG (op0)))
1041618334Speter	       & ~ GET_MODE_MASK (GET_MODE (op0))) == 0
1041718334Speter	   && (tem = gen_lowpart_for_combine (GET_MODE (SUBREG_REG (op0)),
1041818334Speter					      op1),
1041918334Speter	       (nonzero_bits (tem, GET_MODE (SUBREG_REG (op0)))
1042018334Speter		& ~ GET_MODE_MASK (GET_MODE (op0))) == 0))
1042118334Speter    op0 = SUBREG_REG (op0), op1 = tem;
1042218334Speter
1042318334Speter  /* We now do the opposite procedure: Some machines don't have compare
1042418334Speter     insns in all modes.  If OP0's mode is an integer mode smaller than a
1042518334Speter     word and we can't do a compare in that mode, see if there is a larger
1042618334Speter     mode for which we can do the compare.  There are a number of cases in
1042718334Speter     which we can use the wider mode.  */
1042818334Speter
1042918334Speter  mode = GET_MODE (op0);
1043018334Speter  if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT
1043118334Speter      && GET_MODE_SIZE (mode) < UNITS_PER_WORD
1043218334Speter      && cmp_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1043318334Speter    for (tmode = GET_MODE_WIDER_MODE (mode);
1043418334Speter	 (tmode != VOIDmode
1043518334Speter	  && GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT);
1043618334Speter	 tmode = GET_MODE_WIDER_MODE (tmode))
1043718334Speter      if (cmp_optab->handlers[(int) tmode].insn_code != CODE_FOR_nothing)
1043818334Speter	{
1043918334Speter	  /* If the only nonzero bits in OP0 and OP1 are those in the
1044018334Speter	     narrower mode and this is an equality or unsigned comparison,
1044118334Speter	     we can use the wider mode.  Similarly for sign-extended
1044218334Speter	     values, in which case it is true for all comparisons.  */
1044318334Speter	  if (((code == EQ || code == NE
1044418334Speter		|| code == GEU || code == GTU || code == LEU || code == LTU)
1044518334Speter	       && (nonzero_bits (op0, tmode) & ~ GET_MODE_MASK (mode)) == 0
1044618334Speter	       && (nonzero_bits (op1, tmode) & ~ GET_MODE_MASK (mode)) == 0)
1044718334Speter	      || ((num_sign_bit_copies (op0, tmode)
1044818334Speter		   > GET_MODE_BITSIZE (tmode) - GET_MODE_BITSIZE (mode))
1044918334Speter		  && (num_sign_bit_copies (op1, tmode)
1045018334Speter		      > GET_MODE_BITSIZE (tmode) - GET_MODE_BITSIZE (mode))))
1045118334Speter	    {
1045218334Speter	      op0 = gen_lowpart_for_combine (tmode, op0);
1045318334Speter	      op1 = gen_lowpart_for_combine (tmode, op1);
1045418334Speter	      break;
1045518334Speter	    }
1045618334Speter
1045718334Speter	  /* If this is a test for negative, we can make an explicit
1045818334Speter	     test of the sign bit.  */
1045918334Speter
1046018334Speter	  if (op1 == const0_rtx && (code == LT || code == GE)
1046118334Speter	      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
1046218334Speter	    {
1046318334Speter	      op0 = gen_binary (AND, tmode,
1046418334Speter				gen_lowpart_for_combine (tmode, op0),
1046518334Speter				GEN_INT ((HOST_WIDE_INT) 1
1046618334Speter					 << (GET_MODE_BITSIZE (mode) - 1)));
1046718334Speter	      code = (code == LT) ? NE : EQ;
1046818334Speter	      break;
1046918334Speter	    }
1047018334Speter	}
1047118334Speter
1047218334Speter#ifdef CANONICALIZE_COMPARISON
1047318334Speter  /* If this machine only supports a subset of valid comparisons, see if we
1047418334Speter     can convert an unsupported one into a supported one.  */
1047518334Speter  CANONICALIZE_COMPARISON (code, op0, op1);
1047618334Speter#endif
1047718334Speter
1047818334Speter  *pop0 = op0;
1047918334Speter  *pop1 = op1;
1048018334Speter
1048118334Speter  return code;
1048218334Speter}
1048318334Speter
1048418334Speter/* Return 1 if we know that X, a comparison operation, is not operating
1048518334Speter   on a floating-point value or is EQ or NE, meaning that we can safely
1048618334Speter   reverse it.  */
1048718334Speter
1048818334Speterstatic int
1048918334Speterreversible_comparison_p (x)
1049018334Speter     rtx x;
1049118334Speter{
1049218334Speter  if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
1049318334Speter      || flag_fast_math
1049418334Speter      || GET_CODE (x) == NE || GET_CODE (x) == EQ)
1049518334Speter    return 1;
1049618334Speter
1049718334Speter  switch (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))))
1049818334Speter    {
1049918334Speter    case MODE_INT:
1050018334Speter    case MODE_PARTIAL_INT:
1050118334Speter    case MODE_COMPLEX_INT:
1050218334Speter      return 1;
1050318334Speter
1050418334Speter    case MODE_CC:
1050518334Speter      /* If the mode of the condition codes tells us that this is safe,
1050618334Speter	 we need look no further.  */
1050718334Speter      if (REVERSIBLE_CC_MODE (GET_MODE (XEXP (x, 0))))
1050818334Speter	return 1;
1050918334Speter
1051018334Speter      /* Otherwise try and find where the condition codes were last set and
1051118334Speter	 use that.  */
1051218334Speter      x = get_last_value (XEXP (x, 0));
1051318334Speter      return (x && GET_CODE (x) == COMPARE
1051418334Speter	      && ! FLOAT_MODE_P (GET_MODE (XEXP (x, 0))));
1051550397Sobrien
1051650397Sobrien    default:
1051750397Sobrien      return 0;
1051818334Speter    }
1051918334Speter}
1052018334Speter
1052118334Speter/* Utility function for following routine.  Called when X is part of a value
1052218334Speter   being stored into reg_last_set_value.  Sets reg_last_set_table_tick
1052318334Speter   for each register mentioned.  Similar to mention_regs in cse.c  */
1052418334Speter
1052518334Speterstatic void
1052618334Speterupdate_table_tick (x)
1052718334Speter     rtx x;
1052818334Speter{
1052918334Speter  register enum rtx_code code = GET_CODE (x);
1053018334Speter  register char *fmt = GET_RTX_FORMAT (code);
1053118334Speter  register int i;
1053218334Speter
1053318334Speter  if (code == REG)
1053418334Speter    {
1053518334Speter      int regno = REGNO (x);
1053618334Speter      int endregno = regno + (regno < FIRST_PSEUDO_REGISTER
1053718334Speter			      ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
1053818334Speter
1053918334Speter      for (i = regno; i < endregno; i++)
1054018334Speter	reg_last_set_table_tick[i] = label_tick;
1054118334Speter
1054218334Speter      return;
1054318334Speter    }
1054418334Speter
1054518334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1054618334Speter    /* Note that we can't have an "E" in values stored; see
1054718334Speter       get_last_value_validate.  */
1054818334Speter    if (fmt[i] == 'e')
1054918334Speter      update_table_tick (XEXP (x, i));
1055018334Speter}
1055118334Speter
1055218334Speter/* Record that REG is set to VALUE in insn INSN.  If VALUE is zero, we
1055318334Speter   are saying that the register is clobbered and we no longer know its
1055418334Speter   value.  If INSN is zero, don't update reg_last_set; this is only permitted
1055518334Speter   with VALUE also zero and is used to invalidate the register.  */
1055618334Speter
1055718334Speterstatic void
1055818334Speterrecord_value_for_reg (reg, insn, value)
1055918334Speter     rtx reg;
1056018334Speter     rtx insn;
1056118334Speter     rtx value;
1056218334Speter{
1056318334Speter  int regno = REGNO (reg);
1056418334Speter  int endregno = regno + (regno < FIRST_PSEUDO_REGISTER
1056518334Speter			  ? HARD_REGNO_NREGS (regno, GET_MODE (reg)) : 1);
1056618334Speter  int i;
1056718334Speter
1056818334Speter  /* If VALUE contains REG and we have a previous value for REG, substitute
1056918334Speter     the previous value.  */
1057018334Speter  if (value && insn && reg_overlap_mentioned_p (reg, value))
1057118334Speter    {
1057218334Speter      rtx tem;
1057318334Speter
1057418334Speter      /* Set things up so get_last_value is allowed to see anything set up to
1057518334Speter	 our insn.  */
1057618334Speter      subst_low_cuid = INSN_CUID (insn);
1057718334Speter      tem = get_last_value (reg);
1057818334Speter
1057918334Speter      if (tem)
1058018334Speter	value = replace_rtx (copy_rtx (value), reg, tem);
1058118334Speter    }
1058218334Speter
1058318334Speter  /* For each register modified, show we don't know its value, that
1058418334Speter     we don't know about its bitwise content, that its value has been
1058518334Speter     updated, and that we don't know the location of the death of the
1058618334Speter     register.  */
1058718334Speter  for (i = regno; i < endregno; i ++)
1058818334Speter    {
1058918334Speter      if (insn)
1059018334Speter	reg_last_set[i] = insn;
1059118334Speter      reg_last_set_value[i] = 0;
1059218334Speter      reg_last_set_mode[i] = 0;
1059318334Speter      reg_last_set_nonzero_bits[i] = 0;
1059418334Speter      reg_last_set_sign_bit_copies[i] = 0;
1059518334Speter      reg_last_death[i] = 0;
1059618334Speter    }
1059718334Speter
1059818334Speter  /* Mark registers that are being referenced in this value.  */
1059918334Speter  if (value)
1060018334Speter    update_table_tick (value);
1060118334Speter
1060218334Speter  /* Now update the status of each register being set.
1060318334Speter     If someone is using this register in this block, set this register
1060418334Speter     to invalid since we will get confused between the two lives in this
1060518334Speter     basic block.  This makes using this register always invalid.  In cse, we
1060618334Speter     scan the table to invalidate all entries using this register, but this
1060718334Speter     is too much work for us.  */
1060818334Speter
1060918334Speter  for (i = regno; i < endregno; i++)
1061018334Speter    {
1061118334Speter      reg_last_set_label[i] = label_tick;
1061218334Speter      if (value && reg_last_set_table_tick[i] == label_tick)
1061318334Speter	reg_last_set_invalid[i] = 1;
1061418334Speter      else
1061518334Speter	reg_last_set_invalid[i] = 0;
1061618334Speter    }
1061718334Speter
1061818334Speter  /* The value being assigned might refer to X (like in "x++;").  In that
1061918334Speter     case, we must replace it with (clobber (const_int 0)) to prevent
1062018334Speter     infinite loops.  */
1062150397Sobrien  if (value && ! get_last_value_validate (&value, insn,
1062218334Speter					  reg_last_set_label[regno], 0))
1062318334Speter    {
1062418334Speter      value = copy_rtx (value);
1062550397Sobrien      if (! get_last_value_validate (&value, insn,
1062650397Sobrien				     reg_last_set_label[regno], 1))
1062718334Speter	value = 0;
1062818334Speter    }
1062918334Speter
1063018334Speter  /* For the main register being modified, update the value, the mode, the
1063118334Speter     nonzero bits, and the number of sign bit copies.  */
1063218334Speter
1063318334Speter  reg_last_set_value[regno] = value;
1063418334Speter
1063518334Speter  if (value)
1063618334Speter    {
1063718334Speter      subst_low_cuid = INSN_CUID (insn);
1063818334Speter      reg_last_set_mode[regno] = GET_MODE (reg);
1063918334Speter      reg_last_set_nonzero_bits[regno] = nonzero_bits (value, GET_MODE (reg));
1064018334Speter      reg_last_set_sign_bit_copies[regno]
1064118334Speter	= num_sign_bit_copies (value, GET_MODE (reg));
1064218334Speter    }
1064318334Speter}
1064418334Speter
1064518334Speter/* Used for communication between the following two routines.  */
1064618334Speterstatic rtx record_dead_insn;
1064718334Speter
1064818334Speter/* Called via note_stores from record_dead_and_set_regs to handle one
1064918334Speter   SET or CLOBBER in an insn.  */
1065018334Speter
1065118334Speterstatic void
1065218334Speterrecord_dead_and_set_regs_1 (dest, setter)
1065318334Speter     rtx dest, setter;
1065418334Speter{
1065518334Speter  if (GET_CODE (dest) == SUBREG)
1065618334Speter    dest = SUBREG_REG (dest);
1065718334Speter
1065818334Speter  if (GET_CODE (dest) == REG)
1065918334Speter    {
1066018334Speter      /* If we are setting the whole register, we know its value.  Otherwise
1066118334Speter	 show that we don't know the value.  We can handle SUBREG in
1066218334Speter	 some cases.  */
1066318334Speter      if (GET_CODE (setter) == SET && dest == SET_DEST (setter))
1066418334Speter	record_value_for_reg (dest, record_dead_insn, SET_SRC (setter));
1066518334Speter      else if (GET_CODE (setter) == SET
1066618334Speter	       && GET_CODE (SET_DEST (setter)) == SUBREG
1066718334Speter	       && SUBREG_REG (SET_DEST (setter)) == dest
1066818334Speter	       && GET_MODE_BITSIZE (GET_MODE (dest)) <= BITS_PER_WORD
1066918334Speter	       && subreg_lowpart_p (SET_DEST (setter)))
1067018334Speter	record_value_for_reg (dest, record_dead_insn,
1067118334Speter			      gen_lowpart_for_combine (GET_MODE (dest),
1067218334Speter						       SET_SRC (setter)));
1067318334Speter      else
1067418334Speter	record_value_for_reg (dest, record_dead_insn, NULL_RTX);
1067518334Speter    }
1067618334Speter  else if (GET_CODE (dest) == MEM
1067718334Speter	   /* Ignore pushes, they clobber nothing.  */
1067818334Speter	   && ! push_operand (dest, GET_MODE (dest)))
1067918334Speter    mem_last_set = INSN_CUID (record_dead_insn);
1068018334Speter}
1068118334Speter
1068218334Speter/* Update the records of when each REG was most recently set or killed
1068318334Speter   for the things done by INSN.  This is the last thing done in processing
1068418334Speter   INSN in the combiner loop.
1068518334Speter
1068618334Speter   We update reg_last_set, reg_last_set_value, reg_last_set_mode,
1068718334Speter   reg_last_set_nonzero_bits, reg_last_set_sign_bit_copies, reg_last_death,
1068818334Speter   and also the similar information mem_last_set (which insn most recently
1068918334Speter   modified memory) and last_call_cuid (which insn was the most recent
1069018334Speter   subroutine call).  */
1069118334Speter
1069218334Speterstatic void
1069318334Speterrecord_dead_and_set_regs (insn)
1069418334Speter     rtx insn;
1069518334Speter{
1069618334Speter  register rtx link;
1069718334Speter  int i;
1069818334Speter
1069918334Speter  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1070018334Speter    {
1070118334Speter      if (REG_NOTE_KIND (link) == REG_DEAD
1070218334Speter	  && GET_CODE (XEXP (link, 0)) == REG)
1070318334Speter	{
1070418334Speter	  int regno = REGNO (XEXP (link, 0));
1070518334Speter	  int endregno
1070618334Speter	    = regno + (regno < FIRST_PSEUDO_REGISTER
1070718334Speter		       ? HARD_REGNO_NREGS (regno, GET_MODE (XEXP (link, 0)))
1070818334Speter		       : 1);
1070918334Speter
1071018334Speter	  for (i = regno; i < endregno; i++)
1071118334Speter	    reg_last_death[i] = insn;
1071218334Speter	}
1071318334Speter      else if (REG_NOTE_KIND (link) == REG_INC)
1071418334Speter	record_value_for_reg (XEXP (link, 0), insn, NULL_RTX);
1071518334Speter    }
1071618334Speter
1071718334Speter  if (GET_CODE (insn) == CALL_INSN)
1071818334Speter    {
1071918334Speter      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1072018334Speter	if (call_used_regs[i])
1072118334Speter	  {
1072218334Speter	    reg_last_set_value[i] = 0;
1072318334Speter	    reg_last_set_mode[i] = 0;
1072418334Speter	    reg_last_set_nonzero_bits[i] = 0;
1072518334Speter	    reg_last_set_sign_bit_copies[i] = 0;
1072618334Speter	    reg_last_death[i] = 0;
1072718334Speter	  }
1072818334Speter
1072918334Speter      last_call_cuid = mem_last_set = INSN_CUID (insn);
1073018334Speter    }
1073118334Speter
1073218334Speter  record_dead_insn = insn;
1073318334Speter  note_stores (PATTERN (insn), record_dead_and_set_regs_1);
1073418334Speter}
1073518334Speter
1073618334Speter/* Utility routine for the following function.  Verify that all the registers
1073718334Speter   mentioned in *LOC are valid when *LOC was part of a value set when
1073818334Speter   label_tick == TICK.  Return 0 if some are not.
1073918334Speter
1074018334Speter   If REPLACE is non-zero, replace the invalid reference with
1074118334Speter   (clobber (const_int 0)) and return 1.  This replacement is useful because
1074218334Speter   we often can get useful information about the form of a value (e.g., if
1074318334Speter   it was produced by a shift that always produces -1 or 0) even though
1074418334Speter   we don't know exactly what registers it was produced from.  */
1074518334Speter
1074618334Speterstatic int
1074750397Sobrienget_last_value_validate (loc, insn, tick, replace)
1074818334Speter     rtx *loc;
1074950397Sobrien     rtx insn;
1075018334Speter     int tick;
1075118334Speter     int replace;
1075218334Speter{
1075318334Speter  rtx x = *loc;
1075418334Speter  char *fmt = GET_RTX_FORMAT (GET_CODE (x));
1075518334Speter  int len = GET_RTX_LENGTH (GET_CODE (x));
1075618334Speter  int i;
1075718334Speter
1075818334Speter  if (GET_CODE (x) == REG)
1075918334Speter    {
1076018334Speter      int regno = REGNO (x);
1076118334Speter      int endregno = regno + (regno < FIRST_PSEUDO_REGISTER
1076218334Speter			      ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
1076318334Speter      int j;
1076418334Speter
1076518334Speter      for (j = regno; j < endregno; j++)
1076618334Speter	if (reg_last_set_invalid[j]
1076718334Speter	    /* If this is a pseudo-register that was only set once, it is
1076818334Speter	       always valid.  */
1076950397Sobrien	    || (! (regno >= FIRST_PSEUDO_REGISTER && REG_N_SETS (regno) == 1)
1077018334Speter		&& reg_last_set_label[j] > tick))
1077118334Speter	  {
1077218334Speter	    if (replace)
1077350397Sobrien	      *loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
1077418334Speter	    return replace;
1077518334Speter	  }
1077618334Speter
1077718334Speter      return 1;
1077818334Speter    }
1077950397Sobrien  /* If this is a memory reference, make sure that there were
1078050397Sobrien     no stores after it that might have clobbered the value.  We don't
1078150397Sobrien     have alias info, so we assume any store invalidates it.  */
1078250397Sobrien  else if (GET_CODE (x) == MEM && ! RTX_UNCHANGING_P (x)
1078350397Sobrien	   && INSN_CUID (insn) <= mem_last_set)
1078450397Sobrien    {
1078550397Sobrien      if (replace)
1078650397Sobrien	*loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
1078750397Sobrien      return replace;
1078850397Sobrien    }
1078918334Speter
1079018334Speter  for (i = 0; i < len; i++)
1079118334Speter    if ((fmt[i] == 'e'
1079250397Sobrien	 && get_last_value_validate (&XEXP (x, i), insn, tick, replace) == 0)
1079318334Speter	/* Don't bother with these.  They shouldn't occur anyway.  */
1079418334Speter	|| fmt[i] == 'E')
1079518334Speter      return 0;
1079618334Speter
1079718334Speter  /* If we haven't found a reason for it to be invalid, it is valid.  */
1079818334Speter  return 1;
1079918334Speter}
1080018334Speter
1080118334Speter/* Get the last value assigned to X, if known.  Some registers
1080218334Speter   in the value may be replaced with (clobber (const_int 0)) if their value
1080318334Speter   is known longer known reliably.  */
1080418334Speter
1080518334Speterstatic rtx
1080618334Speterget_last_value (x)
1080718334Speter     rtx x;
1080818334Speter{
1080918334Speter  int regno;
1081018334Speter  rtx value;
1081118334Speter
1081218334Speter  /* If this is a non-paradoxical SUBREG, get the value of its operand and
1081318334Speter     then convert it to the desired mode.  If this is a paradoxical SUBREG,
1081450397Sobrien     we cannot predict what values the "extra" bits might have.  */
1081518334Speter  if (GET_CODE (x) == SUBREG
1081618334Speter      && subreg_lowpart_p (x)
1081718334Speter      && (GET_MODE_SIZE (GET_MODE (x))
1081818334Speter	  <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
1081918334Speter      && (value = get_last_value (SUBREG_REG (x))) != 0)
1082018334Speter    return gen_lowpart_for_combine (GET_MODE (x), value);
1082118334Speter
1082218334Speter  if (GET_CODE (x) != REG)
1082318334Speter    return 0;
1082418334Speter
1082518334Speter  regno = REGNO (x);
1082618334Speter  value = reg_last_set_value[regno];
1082718334Speter
1082850397Sobrien  /* If we don't have a value or if it isn't for this basic block,
1082950397Sobrien     return 0.  */
1083018334Speter
1083118334Speter  if (value == 0
1083250397Sobrien      || (REG_N_SETS (regno) != 1
1083318334Speter	  && reg_last_set_label[regno] != label_tick))
1083418334Speter    return 0;
1083518334Speter
1083618334Speter  /* If the value was set in a later insn than the ones we are processing,
1083718334Speter     we can't use it even if the register was only set once, but make a quick
1083818334Speter     check to see if the previous insn set it to something.  This is commonly
1083918334Speter     the case when the same pseudo is used by repeated insns.
1084018334Speter
1084118334Speter     This does not work if there exists an instruction which is temporarily
1084218334Speter     not on the insn chain.  */
1084318334Speter
1084418334Speter  if (INSN_CUID (reg_last_set[regno]) >= subst_low_cuid)
1084518334Speter    {
1084618334Speter      rtx insn, set;
1084718334Speter
1084818334Speter      /* We can not do anything useful in this case, because there is
1084918334Speter	 an instruction which is not on the insn chain.  */
1085018334Speter      if (subst_prev_insn)
1085118334Speter	return 0;
1085218334Speter
1085318334Speter      /* Skip over USE insns.  They are not useful here, and they may have
1085418334Speter	 been made by combine, in which case they do not have a INSN_CUID
1085518334Speter	 value.  We can't use prev_real_insn, because that would incorrectly
1085618334Speter	 take us backwards across labels.  Skip over BARRIERs also, since
1085718334Speter	 they could have been made by combine.  If we see one, we must be
1085818334Speter	 optimizing dead code, so it doesn't matter what we do.  */
1085918334Speter      for (insn = prev_nonnote_insn (subst_insn);
1086018334Speter	   insn && ((GET_CODE (insn) == INSN
1086118334Speter		     && GET_CODE (PATTERN (insn)) == USE)
1086218334Speter		    || GET_CODE (insn) == BARRIER
1086318334Speter		    || INSN_CUID (insn) >= subst_low_cuid);
1086418334Speter	   insn = prev_nonnote_insn (insn))
1086518334Speter	;
1086618334Speter
1086718334Speter      if (insn
1086818334Speter	  && (set = single_set (insn)) != 0
1086918334Speter	  && rtx_equal_p (SET_DEST (set), x))
1087018334Speter	{
1087118334Speter	  value = SET_SRC (set);
1087218334Speter
1087318334Speter	  /* Make sure that VALUE doesn't reference X.  Replace any
1087418334Speter	     explicit references with a CLOBBER.  If there are any remaining
1087518334Speter	     references (rare), don't use the value.  */
1087618334Speter
1087718334Speter	  if (reg_mentioned_p (x, value))
1087818334Speter	    value = replace_rtx (copy_rtx (value), x,
1087950397Sobrien				 gen_rtx_CLOBBER (GET_MODE (x), const0_rtx));
1088018334Speter
1088118334Speter	  if (reg_overlap_mentioned_p (x, value))
1088218334Speter	    return 0;
1088318334Speter	}
1088418334Speter      else
1088518334Speter	return 0;
1088618334Speter    }
1088718334Speter
1088818334Speter  /* If the value has all its registers valid, return it.  */
1088950397Sobrien  if (get_last_value_validate (&value, reg_last_set[regno],
1089050397Sobrien			       reg_last_set_label[regno], 0))
1089118334Speter    return value;
1089218334Speter
1089318334Speter  /* Otherwise, make a copy and replace any invalid register with
1089418334Speter     (clobber (const_int 0)).  If that fails for some reason, return 0.  */
1089518334Speter
1089618334Speter  value = copy_rtx (value);
1089750397Sobrien  if (get_last_value_validate (&value, reg_last_set[regno],
1089850397Sobrien			       reg_last_set_label[regno], 1))
1089918334Speter    return value;
1090018334Speter
1090118334Speter  return 0;
1090218334Speter}
1090318334Speter
1090418334Speter/* Return nonzero if expression X refers to a REG or to memory
1090518334Speter   that is set in an instruction more recent than FROM_CUID.  */
1090618334Speter
1090718334Speterstatic int
1090818334Speteruse_crosses_set_p (x, from_cuid)
1090918334Speter     register rtx x;
1091018334Speter     int from_cuid;
1091118334Speter{
1091218334Speter  register char *fmt;
1091318334Speter  register int i;
1091418334Speter  register enum rtx_code code = GET_CODE (x);
1091518334Speter
1091618334Speter  if (code == REG)
1091718334Speter    {
1091818334Speter      register int regno = REGNO (x);
1091918334Speter      int endreg = regno + (regno < FIRST_PSEUDO_REGISTER
1092018334Speter			    ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
1092118334Speter
1092218334Speter#ifdef PUSH_ROUNDING
1092318334Speter      /* Don't allow uses of the stack pointer to be moved,
1092418334Speter	 because we don't know whether the move crosses a push insn.  */
1092518334Speter      if (regno == STACK_POINTER_REGNUM)
1092618334Speter	return 1;
1092718334Speter#endif
1092818334Speter      for (;regno < endreg; regno++)
1092918334Speter	if (reg_last_set[regno]
1093018334Speter	    && INSN_CUID (reg_last_set[regno]) > from_cuid)
1093118334Speter	  return 1;
1093218334Speter      return 0;
1093318334Speter    }
1093418334Speter
1093518334Speter  if (code == MEM && mem_last_set > from_cuid)
1093618334Speter    return 1;
1093718334Speter
1093818334Speter  fmt = GET_RTX_FORMAT (code);
1093918334Speter
1094018334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1094118334Speter    {
1094218334Speter      if (fmt[i] == 'E')
1094318334Speter	{
1094418334Speter	  register int j;
1094518334Speter	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1094618334Speter	    if (use_crosses_set_p (XVECEXP (x, i, j), from_cuid))
1094718334Speter	      return 1;
1094818334Speter	}
1094918334Speter      else if (fmt[i] == 'e'
1095018334Speter	       && use_crosses_set_p (XEXP (x, i), from_cuid))
1095118334Speter	return 1;
1095218334Speter    }
1095318334Speter  return 0;
1095418334Speter}
1095518334Speter
1095618334Speter/* Define three variables used for communication between the following
1095718334Speter   routines.  */
1095818334Speter
1095918334Speterstatic int reg_dead_regno, reg_dead_endregno;
1096018334Speterstatic int reg_dead_flag;
1096118334Speter
1096218334Speter/* Function called via note_stores from reg_dead_at_p.
1096318334Speter
1096418334Speter   If DEST is within [reg_dead_regno, reg_dead_endregno), set
1096518334Speter   reg_dead_flag to 1 if X is a CLOBBER and to -1 it is a SET.  */
1096618334Speter
1096718334Speterstatic void
1096818334Speterreg_dead_at_p_1 (dest, x)
1096918334Speter     rtx dest;
1097018334Speter     rtx x;
1097118334Speter{
1097218334Speter  int regno, endregno;
1097318334Speter
1097418334Speter  if (GET_CODE (dest) != REG)
1097518334Speter    return;
1097618334Speter
1097718334Speter  regno = REGNO (dest);
1097818334Speter  endregno = regno + (regno < FIRST_PSEUDO_REGISTER
1097918334Speter		      ? HARD_REGNO_NREGS (regno, GET_MODE (dest)) : 1);
1098018334Speter
1098118334Speter  if (reg_dead_endregno > regno && reg_dead_regno < endregno)
1098218334Speter    reg_dead_flag = (GET_CODE (x) == CLOBBER) ? 1 : -1;
1098318334Speter}
1098418334Speter
1098518334Speter/* Return non-zero if REG is known to be dead at INSN.
1098618334Speter
1098718334Speter   We scan backwards from INSN.  If we hit a REG_DEAD note or a CLOBBER
1098818334Speter   referencing REG, it is dead.  If we hit a SET referencing REG, it is
1098918334Speter   live.  Otherwise, see if it is live or dead at the start of the basic
1099018334Speter   block we are in.  Hard regs marked as being live in NEWPAT_USED_REGS
1099118334Speter   must be assumed to be always live.  */
1099218334Speter
1099318334Speterstatic int
1099418334Speterreg_dead_at_p (reg, insn)
1099518334Speter     rtx reg;
1099618334Speter     rtx insn;
1099718334Speter{
1099818334Speter  int block, i;
1099918334Speter
1100018334Speter  /* Set variables for reg_dead_at_p_1.  */
1100118334Speter  reg_dead_regno = REGNO (reg);
1100218334Speter  reg_dead_endregno = reg_dead_regno + (reg_dead_regno < FIRST_PSEUDO_REGISTER
1100318334Speter					? HARD_REGNO_NREGS (reg_dead_regno,
1100418334Speter							    GET_MODE (reg))
1100518334Speter					: 1);
1100618334Speter
1100718334Speter  reg_dead_flag = 0;
1100818334Speter
1100918334Speter  /* Check that reg isn't mentioned in NEWPAT_USED_REGS.  */
1101018334Speter  if (reg_dead_regno < FIRST_PSEUDO_REGISTER)
1101118334Speter    {
1101218334Speter      for (i = reg_dead_regno; i < reg_dead_endregno; i++)
1101318334Speter	if (TEST_HARD_REG_BIT (newpat_used_regs, i))
1101418334Speter	  return 0;
1101518334Speter    }
1101618334Speter
1101718334Speter  /* Scan backwards until we find a REG_DEAD note, SET, CLOBBER, label, or
1101818334Speter     beginning of function.  */
1101918334Speter  for (; insn && GET_CODE (insn) != CODE_LABEL && GET_CODE (insn) != BARRIER;
1102018334Speter       insn = prev_nonnote_insn (insn))
1102118334Speter    {
1102218334Speter      note_stores (PATTERN (insn), reg_dead_at_p_1);
1102318334Speter      if (reg_dead_flag)
1102418334Speter	return reg_dead_flag == 1 ? 1 : 0;
1102518334Speter
1102618334Speter      if (find_regno_note (insn, REG_DEAD, reg_dead_regno))
1102718334Speter	return 1;
1102818334Speter    }
1102918334Speter
1103018334Speter  /* Get the basic block number that we were in.  */
1103118334Speter  if (insn == 0)
1103218334Speter    block = 0;
1103318334Speter  else
1103418334Speter    {
1103518334Speter      for (block = 0; block < n_basic_blocks; block++)
1103652284Sobrien	if (insn == BLOCK_HEAD (block))
1103718334Speter	  break;
1103818334Speter
1103918334Speter      if (block == n_basic_blocks)
1104018334Speter	return 0;
1104118334Speter    }
1104218334Speter
1104318334Speter  for (i = reg_dead_regno; i < reg_dead_endregno; i++)
1104452284Sobrien    if (REGNO_REG_SET_P (BASIC_BLOCK (block)->global_live_at_start, i))
1104518334Speter      return 0;
1104618334Speter
1104718334Speter  return 1;
1104818334Speter}
1104918334Speter
1105018334Speter/* Note hard registers in X that are used.  This code is similar to
1105118334Speter   that in flow.c, but much simpler since we don't care about pseudos.  */
1105218334Speter
1105318334Speterstatic void
1105418334Spetermark_used_regs_combine (x)
1105518334Speter     rtx x;
1105618334Speter{
1105718334Speter  register RTX_CODE code = GET_CODE (x);
1105818334Speter  register int regno;
1105918334Speter  int i;
1106018334Speter
1106118334Speter  switch (code)
1106218334Speter    {
1106318334Speter    case LABEL_REF:
1106418334Speter    case SYMBOL_REF:
1106518334Speter    case CONST_INT:
1106618334Speter    case CONST:
1106718334Speter    case CONST_DOUBLE:
1106818334Speter    case PC:
1106918334Speter    case ADDR_VEC:
1107018334Speter    case ADDR_DIFF_VEC:
1107118334Speter    case ASM_INPUT:
1107218334Speter#ifdef HAVE_cc0
1107318334Speter    /* CC0 must die in the insn after it is set, so we don't need to take
1107418334Speter       special note of it here.  */
1107518334Speter    case CC0:
1107618334Speter#endif
1107718334Speter      return;
1107818334Speter
1107918334Speter    case CLOBBER:
1108018334Speter      /* If we are clobbering a MEM, mark any hard registers inside the
1108118334Speter	 address as used.  */
1108218334Speter      if (GET_CODE (XEXP (x, 0)) == MEM)
1108318334Speter	mark_used_regs_combine (XEXP (XEXP (x, 0), 0));
1108418334Speter      return;
1108518334Speter
1108618334Speter    case REG:
1108718334Speter      regno = REGNO (x);
1108818334Speter      /* A hard reg in a wide mode may really be multiple registers.
1108918334Speter	 If so, mark all of them just like the first.  */
1109018334Speter      if (regno < FIRST_PSEUDO_REGISTER)
1109118334Speter	{
1109218334Speter	  /* None of this applies to the stack, frame or arg pointers */
1109318334Speter	  if (regno == STACK_POINTER_REGNUM
1109418334Speter#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
1109518334Speter	      || regno == HARD_FRAME_POINTER_REGNUM
1109618334Speter#endif
1109718334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
1109818334Speter	      || (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
1109918334Speter#endif
1110018334Speter	      || regno == FRAME_POINTER_REGNUM)
1110118334Speter	    return;
1110218334Speter
1110318334Speter	  i = HARD_REGNO_NREGS (regno, GET_MODE (x));
1110418334Speter	  while (i-- > 0)
1110518334Speter	    SET_HARD_REG_BIT (newpat_used_regs, regno + i);
1110618334Speter	}
1110718334Speter      return;
1110818334Speter
1110918334Speter    case SET:
1111018334Speter      {
1111118334Speter	/* If setting a MEM, or a SUBREG of a MEM, then note any hard regs in
1111218334Speter	   the address.  */
1111318334Speter	register rtx testreg = SET_DEST (x);
1111418334Speter
1111518334Speter	while (GET_CODE (testreg) == SUBREG
1111618334Speter	       || GET_CODE (testreg) == ZERO_EXTRACT
1111718334Speter	       || GET_CODE (testreg) == SIGN_EXTRACT
1111818334Speter	       || GET_CODE (testreg) == STRICT_LOW_PART)
1111918334Speter	  testreg = XEXP (testreg, 0);
1112018334Speter
1112118334Speter	if (GET_CODE (testreg) == MEM)
1112218334Speter	  mark_used_regs_combine (XEXP (testreg, 0));
1112318334Speter
1112418334Speter	mark_used_regs_combine (SET_SRC (x));
1112518334Speter      }
1112650397Sobrien      return;
1112750397Sobrien
1112850397Sobrien    default:
1112950397Sobrien      break;
1113018334Speter    }
1113118334Speter
1113218334Speter  /* Recursively scan the operands of this expression.  */
1113318334Speter
1113418334Speter  {
1113518334Speter    register char *fmt = GET_RTX_FORMAT (code);
1113618334Speter
1113718334Speter    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1113818334Speter      {
1113918334Speter        if (fmt[i] == 'e')
1114018334Speter	  mark_used_regs_combine (XEXP (x, i));
1114118334Speter        else if (fmt[i] == 'E')
1114218334Speter          {
1114318334Speter            register int j;
1114418334Speter
1114518334Speter            for (j = 0; j < XVECLEN (x, i); j++)
1114618334Speter              mark_used_regs_combine (XVECEXP (x, i, j));
1114718334Speter          }
1114818334Speter      }
1114918334Speter  }
1115018334Speter}
1115118334Speter
1115218334Speter
1115318334Speter/* Remove register number REGNO from the dead registers list of INSN.
1115418334Speter
1115518334Speter   Return the note used to record the death, if there was one.  */
1115618334Speter
1115718334Speterrtx
1115818334Speterremove_death (regno, insn)
1115918334Speter     int regno;
1116018334Speter     rtx insn;
1116118334Speter{
1116218334Speter  register rtx note = find_regno_note (insn, REG_DEAD, regno);
1116318334Speter
1116418334Speter  if (note)
1116518334Speter    {
1116650397Sobrien      REG_N_DEATHS (regno)--;
1116718334Speter      remove_note (insn, note);
1116818334Speter    }
1116918334Speter
1117018334Speter  return note;
1117118334Speter}
1117218334Speter
1117318334Speter/* For each register (hardware or pseudo) used within expression X, if its
1117418334Speter   death is in an instruction with cuid between FROM_CUID (inclusive) and
1117518334Speter   TO_INSN (exclusive), put a REG_DEAD note for that register in the
1117618334Speter   list headed by PNOTES.
1117718334Speter
1117850397Sobrien   That said, don't move registers killed by maybe_kill_insn.
1117950397Sobrien
1118018334Speter   This is done when X is being merged by combination into TO_INSN.  These
1118118334Speter   notes will then be distributed as needed.  */
1118218334Speter
1118318334Speterstatic void
1118450397Sobrienmove_deaths (x, maybe_kill_insn, from_cuid, to_insn, pnotes)
1118518334Speter     rtx x;
1118650397Sobrien     rtx maybe_kill_insn;
1118718334Speter     int from_cuid;
1118818334Speter     rtx to_insn;
1118918334Speter     rtx *pnotes;
1119018334Speter{
1119118334Speter  register char *fmt;
1119218334Speter  register int len, i;
1119318334Speter  register enum rtx_code code = GET_CODE (x);
1119418334Speter
1119518334Speter  if (code == REG)
1119618334Speter    {
1119718334Speter      register int regno = REGNO (x);
1119818334Speter      register rtx where_dead = reg_last_death[regno];
1119918334Speter      register rtx before_dead, after_dead;
1120018334Speter
1120150397Sobrien      /* Don't move the register if it gets killed in between from and to */
1120250397Sobrien      if (maybe_kill_insn && reg_set_p (x, maybe_kill_insn)
1120350397Sobrien	  && !reg_referenced_p (x, maybe_kill_insn))
1120450397Sobrien	return;
1120550397Sobrien
1120618334Speter      /* WHERE_DEAD could be a USE insn made by combine, so first we
1120718334Speter	 make sure that we have insns with valid INSN_CUID values.  */
1120818334Speter      before_dead = where_dead;
1120918334Speter      while (before_dead && INSN_UID (before_dead) > max_uid_cuid)
1121018334Speter	before_dead = PREV_INSN (before_dead);
1121118334Speter      after_dead = where_dead;
1121218334Speter      while (after_dead && INSN_UID (after_dead) > max_uid_cuid)
1121318334Speter	after_dead = NEXT_INSN (after_dead);
1121418334Speter
1121518334Speter      if (before_dead && after_dead
1121618334Speter	  && INSN_CUID (before_dead) >= from_cuid
1121718334Speter	  && (INSN_CUID (after_dead) < INSN_CUID (to_insn)
1121818334Speter	      || (where_dead != after_dead
1121918334Speter		  && INSN_CUID (after_dead) == INSN_CUID (to_insn))))
1122018334Speter	{
1122118334Speter	  rtx note = remove_death (regno, where_dead);
1122218334Speter
1122318334Speter	  /* It is possible for the call above to return 0.  This can occur
1122418334Speter	     when reg_last_death points to I2 or I1 that we combined with.
1122518334Speter	     In that case make a new note.
1122618334Speter
1122718334Speter	     We must also check for the case where X is a hard register
1122818334Speter	     and NOTE is a death note for a range of hard registers
1122918334Speter	     including X.  In that case, we must put REG_DEAD notes for
1123018334Speter	     the remaining registers in place of NOTE.  */
1123118334Speter
1123218334Speter	  if (note != 0 && regno < FIRST_PSEUDO_REGISTER
1123318334Speter	      && (GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
1123450397Sobrien		  > GET_MODE_SIZE (GET_MODE (x))))
1123518334Speter	    {
1123618334Speter	      int deadregno = REGNO (XEXP (note, 0));
1123718334Speter	      int deadend
1123818334Speter		= (deadregno + HARD_REGNO_NREGS (deadregno,
1123918334Speter						 GET_MODE (XEXP (note, 0))));
1124018334Speter	      int ourend = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
1124118334Speter	      int i;
1124218334Speter
1124318334Speter	      for (i = deadregno; i < deadend; i++)
1124418334Speter		if (i < regno || i >= ourend)
1124518334Speter		  REG_NOTES (where_dead)
1124650397Sobrien		    = gen_rtx_EXPR_LIST (REG_DEAD,
1124750397Sobrien					 gen_rtx_REG (reg_raw_mode[i], i),
1124850397Sobrien					 REG_NOTES (where_dead));
1124918334Speter	    }
1125050397Sobrien	  /* If we didn't find any note, or if we found a REG_DEAD note that
1125150397Sobrien	     covers only part of the given reg, and we have a multi-reg hard
1125218334Speter	     register, then to be safe we must check for REG_DEAD notes
1125318334Speter	     for each register other than the first.  They could have
1125418334Speter	     their own REG_DEAD notes lying around.  */
1125550397Sobrien	  else if ((note == 0
1125650397Sobrien		    || (note != 0
1125750397Sobrien			&& (GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
1125850397Sobrien			    < GET_MODE_SIZE (GET_MODE (x)))))
1125950397Sobrien		   && regno < FIRST_PSEUDO_REGISTER
1126018334Speter		   && HARD_REGNO_NREGS (regno, GET_MODE (x)) > 1)
1126118334Speter	    {
1126218334Speter	      int ourend = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
1126350397Sobrien	      int i, offset;
1126418334Speter	      rtx oldnotes = 0;
1126518334Speter
1126650397Sobrien	      if (note)
1126750397Sobrien		offset = HARD_REGNO_NREGS (regno, GET_MODE (XEXP (note, 0)));
1126850397Sobrien	      else
1126950397Sobrien		offset = 1;
1127050397Sobrien
1127150397Sobrien	      for (i = regno + offset; i < ourend; i++)
1127250397Sobrien		move_deaths (gen_rtx_REG (reg_raw_mode[i], i),
1127350397Sobrien			     maybe_kill_insn, from_cuid, to_insn, &oldnotes);
1127418334Speter	    }
1127518334Speter
1127618334Speter	  if (note != 0 && GET_MODE (XEXP (note, 0)) == GET_MODE (x))
1127718334Speter	    {
1127818334Speter	      XEXP (note, 1) = *pnotes;
1127918334Speter	      *pnotes = note;
1128018334Speter	    }
1128118334Speter	  else
1128250397Sobrien	    *pnotes = gen_rtx_EXPR_LIST (REG_DEAD, x, *pnotes);
1128318334Speter
1128450397Sobrien	  REG_N_DEATHS (regno)++;
1128518334Speter	}
1128618334Speter
1128718334Speter      return;
1128818334Speter    }
1128918334Speter
1129018334Speter  else if (GET_CODE (x) == SET)
1129118334Speter    {
1129218334Speter      rtx dest = SET_DEST (x);
1129318334Speter
1129450397Sobrien      move_deaths (SET_SRC (x), maybe_kill_insn, from_cuid, to_insn, pnotes);
1129518334Speter
1129618334Speter      /* In the case of a ZERO_EXTRACT, a STRICT_LOW_PART, or a SUBREG
1129718334Speter	 that accesses one word of a multi-word item, some
1129818334Speter	 piece of everything register in the expression is used by
1129918334Speter	 this insn, so remove any old death.  */
1130018334Speter
1130118334Speter      if (GET_CODE (dest) == ZERO_EXTRACT
1130218334Speter	  || GET_CODE (dest) == STRICT_LOW_PART
1130318334Speter	  || (GET_CODE (dest) == SUBREG
1130418334Speter	      && (((GET_MODE_SIZE (GET_MODE (dest))
1130518334Speter		    + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
1130618334Speter		  == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
1130718334Speter		       + UNITS_PER_WORD - 1) / UNITS_PER_WORD))))
1130818334Speter	{
1130950397Sobrien	  move_deaths (dest, maybe_kill_insn, from_cuid, to_insn, pnotes);
1131018334Speter	  return;
1131118334Speter	}
1131218334Speter
1131318334Speter      /* If this is some other SUBREG, we know it replaces the entire
1131418334Speter	 value, so use that as the destination.  */
1131518334Speter      if (GET_CODE (dest) == SUBREG)
1131618334Speter	dest = SUBREG_REG (dest);
1131718334Speter
1131818334Speter      /* If this is a MEM, adjust deaths of anything used in the address.
1131918334Speter	 For a REG (the only other possibility), the entire value is
1132018334Speter	 being replaced so the old value is not used in this insn.  */
1132118334Speter
1132218334Speter      if (GET_CODE (dest) == MEM)
1132350397Sobrien	move_deaths (XEXP (dest, 0), maybe_kill_insn, from_cuid,
1132450397Sobrien		     to_insn, pnotes);
1132518334Speter      return;
1132618334Speter    }
1132718334Speter
1132818334Speter  else if (GET_CODE (x) == CLOBBER)
1132918334Speter    return;
1133018334Speter
1133118334Speter  len = GET_RTX_LENGTH (code);
1133218334Speter  fmt = GET_RTX_FORMAT (code);
1133318334Speter
1133418334Speter  for (i = 0; i < len; i++)
1133518334Speter    {
1133618334Speter      if (fmt[i] == 'E')
1133718334Speter	{
1133818334Speter	  register int j;
1133918334Speter	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1134050397Sobrien	    move_deaths (XVECEXP (x, i, j), maybe_kill_insn, from_cuid,
1134150397Sobrien			 to_insn, pnotes);
1134218334Speter	}
1134318334Speter      else if (fmt[i] == 'e')
1134450397Sobrien	move_deaths (XEXP (x, i), maybe_kill_insn, from_cuid, to_insn, pnotes);
1134518334Speter    }
1134618334Speter}
1134718334Speter
1134818334Speter/* Return 1 if X is the target of a bit-field assignment in BODY, the
1134918334Speter   pattern of an insn.  X must be a REG.  */
1135018334Speter
1135118334Speterstatic int
1135218334Speterreg_bitfield_target_p (x, body)
1135318334Speter     rtx x;
1135418334Speter     rtx body;
1135518334Speter{
1135618334Speter  int i;
1135718334Speter
1135818334Speter  if (GET_CODE (body) == SET)
1135918334Speter    {
1136018334Speter      rtx dest = SET_DEST (body);
1136118334Speter      rtx target;
1136218334Speter      int regno, tregno, endregno, endtregno;
1136318334Speter
1136418334Speter      if (GET_CODE (dest) == ZERO_EXTRACT)
1136518334Speter	target = XEXP (dest, 0);
1136618334Speter      else if (GET_CODE (dest) == STRICT_LOW_PART)
1136718334Speter	target = SUBREG_REG (XEXP (dest, 0));
1136818334Speter      else
1136918334Speter	return 0;
1137018334Speter
1137118334Speter      if (GET_CODE (target) == SUBREG)
1137218334Speter	target = SUBREG_REG (target);
1137318334Speter
1137418334Speter      if (GET_CODE (target) != REG)
1137518334Speter	return 0;
1137618334Speter
1137718334Speter      tregno = REGNO (target), regno = REGNO (x);
1137818334Speter      if (tregno >= FIRST_PSEUDO_REGISTER || regno >= FIRST_PSEUDO_REGISTER)
1137918334Speter	return target == x;
1138018334Speter
1138118334Speter      endtregno = tregno + HARD_REGNO_NREGS (tregno, GET_MODE (target));
1138218334Speter      endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
1138318334Speter
1138418334Speter      return endregno > tregno && regno < endtregno;
1138518334Speter    }
1138618334Speter
1138718334Speter  else if (GET_CODE (body) == PARALLEL)
1138818334Speter    for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
1138918334Speter      if (reg_bitfield_target_p (x, XVECEXP (body, 0, i)))
1139018334Speter	return 1;
1139118334Speter
1139218334Speter  return 0;
1139318334Speter}
1139418334Speter
1139518334Speter/* Given a chain of REG_NOTES originally from FROM_INSN, try to place them
1139618334Speter   as appropriate.  I3 and I2 are the insns resulting from the combination
1139718334Speter   insns including FROM (I2 may be zero).
1139818334Speter
1139918334Speter   ELIM_I2 and ELIM_I1 are either zero or registers that we know will
1140018334Speter   not need REG_DEAD notes because they are being substituted for.  This
1140118334Speter   saves searching in the most common cases.
1140218334Speter
1140318334Speter   Each note in the list is either ignored or placed on some insns, depending
1140418334Speter   on the type of note.  */
1140518334Speter
1140618334Speterstatic void
1140718334Speterdistribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
1140818334Speter     rtx notes;
1140918334Speter     rtx from_insn;
1141018334Speter     rtx i3, i2;
1141118334Speter     rtx elim_i2, elim_i1;
1141218334Speter{
1141318334Speter  rtx note, next_note;
1141418334Speter  rtx tem;
1141518334Speter
1141618334Speter  for (note = notes; note; note = next_note)
1141718334Speter    {
1141818334Speter      rtx place = 0, place2 = 0;
1141918334Speter
1142018334Speter      /* If this NOTE references a pseudo register, ensure it references
1142118334Speter	 the latest copy of that register.  */
1142218334Speter      if (XEXP (note, 0) && GET_CODE (XEXP (note, 0)) == REG
1142318334Speter	  && REGNO (XEXP (note, 0)) >= FIRST_PSEUDO_REGISTER)
1142418334Speter	XEXP (note, 0) = regno_reg_rtx[REGNO (XEXP (note, 0))];
1142518334Speter
1142618334Speter      next_note = XEXP (note, 1);
1142718334Speter      switch (REG_NOTE_KIND (note))
1142818334Speter	{
1142950397Sobrien	case REG_BR_PROB:
1143050397Sobrien	case REG_EXEC_COUNT:
1143150397Sobrien	  /* Doesn't matter much where we put this, as long as it's somewhere.
1143250397Sobrien	     It is preferable to keep these notes on branches, which is most
1143350397Sobrien	     likely to be i3.  */
1143450397Sobrien	  place = i3;
1143550397Sobrien	  break;
1143650397Sobrien
1143752284Sobrien	case REG_EH_REGION:
1143852284Sobrien	  /* This note must remain with the call.  It should not be possible
1143952284Sobrien	     for both I2 and I3 to be a call.  */
1144052284Sobrien	  if (GET_CODE (i3) == CALL_INSN)
1144152284Sobrien	    place = i3;
1144252284Sobrien	  else if (i2 && GET_CODE (i2) == CALL_INSN)
1144352284Sobrien	    place = i2;
1144452284Sobrien	  else
1144552284Sobrien	    abort ();
1144652284Sobrien	  break;
1144752284Sobrien
1144818334Speter	case REG_UNUSED:
1144918334Speter	  /* Any clobbers for i3 may still exist, and so we must process
1145018334Speter	     REG_UNUSED notes from that insn.
1145118334Speter
1145218334Speter	     Any clobbers from i2 or i1 can only exist if they were added by
1145318334Speter	     recog_for_combine.  In that case, recog_for_combine created the
1145418334Speter	     necessary REG_UNUSED notes.  Trying to keep any original
1145518334Speter	     REG_UNUSED notes from these insns can cause incorrect output
1145618334Speter	     if it is for the same register as the original i3 dest.
1145718334Speter	     In that case, we will notice that the register is set in i3,
1145818334Speter	     and then add a REG_UNUSED note for the destination of i3, which
1145918334Speter	     is wrong.  However, it is possible to have REG_UNUSED notes from
1146018334Speter	     i2 or i1 for register which were both used and clobbered, so
1146118334Speter	     we keep notes from i2 or i1 if they will turn into REG_DEAD
1146218334Speter	     notes.  */
1146318334Speter
1146418334Speter	  /* If this register is set or clobbered in I3, put the note there
1146518334Speter	     unless there is one already.  */
1146618334Speter	  if (reg_set_p (XEXP (note, 0), PATTERN (i3)))
1146718334Speter	    {
1146818334Speter	      if (from_insn != i3)
1146918334Speter		break;
1147018334Speter
1147118334Speter	      if (! (GET_CODE (XEXP (note, 0)) == REG
1147218334Speter		     ? find_regno_note (i3, REG_UNUSED, REGNO (XEXP (note, 0)))
1147318334Speter		     : find_reg_note (i3, REG_UNUSED, XEXP (note, 0))))
1147418334Speter		place = i3;
1147518334Speter	    }
1147618334Speter	  /* Otherwise, if this register is used by I3, then this register
1147718334Speter	     now dies here, so we must put a REG_DEAD note here unless there
1147818334Speter	     is one already.  */
1147918334Speter	  else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3))
1148018334Speter		   && ! (GET_CODE (XEXP (note, 0)) == REG
1148118334Speter			 ? find_regno_note (i3, REG_DEAD, REGNO (XEXP (note, 0)))
1148218334Speter			 : find_reg_note (i3, REG_DEAD, XEXP (note, 0))))
1148318334Speter	    {
1148418334Speter	      PUT_REG_NOTE_KIND (note, REG_DEAD);
1148518334Speter	      place = i3;
1148618334Speter	    }
1148718334Speter	  break;
1148818334Speter
1148918334Speter	case REG_EQUAL:
1149018334Speter	case REG_EQUIV:
1149118334Speter	case REG_NONNEG:
1149250397Sobrien	case REG_NOALIAS:
1149318334Speter	  /* These notes say something about results of an insn.  We can
1149418334Speter	     only support them if they used to be on I3 in which case they
1149518334Speter	     remain on I3.  Otherwise they are ignored.
1149618334Speter
1149718334Speter	     If the note refers to an expression that is not a constant, we
1149818334Speter	     must also ignore the note since we cannot tell whether the
1149918334Speter	     equivalence is still true.  It might be possible to do
1150018334Speter	     slightly better than this (we only have a problem if I2DEST
1150118334Speter	     or I1DEST is present in the expression), but it doesn't
1150218334Speter	     seem worth the trouble.  */
1150318334Speter
1150418334Speter	  if (from_insn == i3
1150518334Speter	      && (XEXP (note, 0) == 0 || CONSTANT_P (XEXP (note, 0))))
1150618334Speter	    place = i3;
1150718334Speter	  break;
1150818334Speter
1150918334Speter	case REG_INC:
1151018334Speter	case REG_NO_CONFLICT:
1151118334Speter	  /* These notes say something about how a register is used.  They must
1151218334Speter	     be present on any use of the register in I2 or I3.  */
1151318334Speter	  if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3)))
1151418334Speter	    place = i3;
1151518334Speter
1151618334Speter	  if (i2 && reg_mentioned_p (XEXP (note, 0), PATTERN (i2)))
1151718334Speter	    {
1151818334Speter	      if (place)
1151918334Speter		place2 = i2;
1152018334Speter	      else
1152118334Speter		place = i2;
1152218334Speter	    }
1152318334Speter	  break;
1152418334Speter
1152552284Sobrien	case REG_LABEL:
1152652284Sobrien	  /* This can show up in several ways -- either directly in the
1152752284Sobrien	     pattern, or hidden off in the constant pool with (or without?)
1152852284Sobrien	     a REG_EQUAL note.  */
1152952284Sobrien	  /* ??? Ignore the without-reg_equal-note problem for now.  */
1153052284Sobrien	  if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3))
1153152284Sobrien	      || ((tem = find_reg_note (i3, REG_EQUAL, NULL_RTX))
1153252284Sobrien		  && GET_CODE (XEXP (tem, 0)) == LABEL_REF
1153352284Sobrien		  && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0)))
1153452284Sobrien	    place = i3;
1153552284Sobrien
1153652284Sobrien	  if (i2
1153752284Sobrien	      && (reg_mentioned_p (XEXP (note, 0), PATTERN (i2))
1153852284Sobrien	          || ((tem = find_reg_note (i2, REG_EQUAL, NULL_RTX))
1153952284Sobrien		      && GET_CODE (XEXP (tem, 0)) == LABEL_REF
1154052284Sobrien		      && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0))))
1154152284Sobrien	    {
1154252284Sobrien	      if (place)
1154352284Sobrien		place2 = i2;
1154452284Sobrien	      else
1154552284Sobrien		place = i2;
1154652284Sobrien	    }
1154752284Sobrien	  break;
1154852284Sobrien
1154918334Speter	case REG_WAS_0:
1155018334Speter	  /* It is too much trouble to try to see if this note is still
1155118334Speter	     correct in all situations.  It is better to simply delete it.  */
1155218334Speter	  break;
1155318334Speter
1155418334Speter	case REG_RETVAL:
1155518334Speter	  /* If the insn previously containing this note still exists,
1155618334Speter	     put it back where it was.  Otherwise move it to the previous
1155718334Speter	     insn.  Adjust the corresponding REG_LIBCALL note.  */
1155818334Speter	  if (GET_CODE (from_insn) != NOTE)
1155918334Speter	    place = from_insn;
1156018334Speter	  else
1156118334Speter	    {
1156218334Speter	      tem = find_reg_note (XEXP (note, 0), REG_LIBCALL, NULL_RTX);
1156318334Speter	      place = prev_real_insn (from_insn);
1156418334Speter	      if (tem && place)
1156518334Speter		XEXP (tem, 0) = place;
1156618334Speter	    }
1156718334Speter	  break;
1156818334Speter
1156918334Speter	case REG_LIBCALL:
1157018334Speter	  /* This is handled similarly to REG_RETVAL.  */
1157118334Speter	  if (GET_CODE (from_insn) != NOTE)
1157218334Speter	    place = from_insn;
1157318334Speter	  else
1157418334Speter	    {
1157518334Speter	      tem = find_reg_note (XEXP (note, 0), REG_RETVAL, NULL_RTX);
1157618334Speter	      place = next_real_insn (from_insn);
1157718334Speter	      if (tem && place)
1157818334Speter		XEXP (tem, 0) = place;
1157918334Speter	    }
1158018334Speter	  break;
1158118334Speter
1158218334Speter	case REG_DEAD:
1158318334Speter	  /* If the register is used as an input in I3, it dies there.
1158418334Speter	     Similarly for I2, if it is non-zero and adjacent to I3.
1158518334Speter
1158618334Speter	     If the register is not used as an input in either I3 or I2
1158718334Speter	     and it is not one of the registers we were supposed to eliminate,
1158818334Speter	     there are two possibilities.  We might have a non-adjacent I2
1158918334Speter	     or we might have somehow eliminated an additional register
1159018334Speter	     from a computation.  For example, we might have had A & B where
1159118334Speter	     we discover that B will always be zero.  In this case we will
1159218334Speter	     eliminate the reference to A.
1159318334Speter
1159418334Speter	     In both cases, we must search to see if we can find a previous
1159518334Speter	     use of A and put the death note there.  */
1159618334Speter
1159718334Speter	  if (from_insn
1159818334Speter	      && GET_CODE (from_insn) == CALL_INSN
1159918334Speter              && find_reg_fusage (from_insn, USE, XEXP (note, 0)))
1160018334Speter	    place = from_insn;
1160118334Speter	  else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)))
1160218334Speter	    place = i3;
1160318334Speter	  else if (i2 != 0 && next_nonnote_insn (i2) == i3
1160418334Speter		   && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
1160518334Speter	    place = i2;
1160618334Speter
1160718334Speter	  if (XEXP (note, 0) == elim_i2 || XEXP (note, 0) == elim_i1)
1160818334Speter	    break;
1160918334Speter
1161018334Speter	  /* If the register is used in both I2 and I3 and it dies in I3,
1161118334Speter	     we might have added another reference to it.  If reg_n_refs
1161218334Speter	     was 2, bump it to 3.  This has to be correct since the
1161318334Speter	     register must have been set somewhere.  The reason this is
1161418334Speter	     done is because local-alloc.c treats 2 references as a
1161518334Speter	     special case.  */
1161618334Speter
1161718334Speter	  if (place == i3 && i2 != 0 && GET_CODE (XEXP (note, 0)) == REG
1161850397Sobrien	      && REG_N_REFS (REGNO (XEXP (note, 0)))== 2
1161918334Speter	      && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
1162050397Sobrien	    REG_N_REFS (REGNO (XEXP (note, 0))) = 3;
1162118334Speter
1162218334Speter	  if (place == 0)
1162318334Speter	    {
1162418334Speter	      for (tem = prev_nonnote_insn (i3);
1162518334Speter		   place == 0 && tem
1162618334Speter		   && (GET_CODE (tem) == INSN || GET_CODE (tem) == CALL_INSN);
1162718334Speter		   tem = prev_nonnote_insn (tem))
1162818334Speter		{
1162918334Speter		  /* If the register is being set at TEM, see if that is all
1163018334Speter		     TEM is doing.  If so, delete TEM.  Otherwise, make this
1163118334Speter		     into a REG_UNUSED note instead.  */
1163218334Speter		  if (reg_set_p (XEXP (note, 0), PATTERN (tem)))
1163318334Speter		    {
1163418334Speter		      rtx set = single_set (tem);
1163550397Sobrien		      rtx inner_dest = 0;
1163652284Sobrien#ifdef HAVE_cc0
1163752284Sobrien		      rtx cc0_setter = NULL_RTX;
1163852284Sobrien#endif
1163918334Speter
1164050397Sobrien		      if (set != 0)
1164150397Sobrien			for (inner_dest = SET_DEST (set);
1164250397Sobrien			     GET_CODE (inner_dest) == STRICT_LOW_PART
1164350397Sobrien			     || GET_CODE (inner_dest) == SUBREG
1164450397Sobrien			     || GET_CODE (inner_dest) == ZERO_EXTRACT;
1164550397Sobrien			     inner_dest = XEXP (inner_dest, 0))
1164650397Sobrien			  ;
1164750397Sobrien
1164818334Speter		      /* Verify that it was the set, and not a clobber that
1164952284Sobrien			 modified the register.
1165018334Speter
1165152284Sobrien			 CC0 targets must be careful to maintain setter/user
1165252284Sobrien			 pairs.  If we cannot delete the setter due to side
1165352284Sobrien			 effects, mark the user with an UNUSED note instead
1165452284Sobrien			 of deleting it.  */
1165552284Sobrien
1165618334Speter		      if (set != 0 && ! side_effects_p (SET_SRC (set))
1165752284Sobrien			  && rtx_equal_p (XEXP (note, 0), inner_dest)
1165852284Sobrien#ifdef HAVE_cc0
1165952284Sobrien			  && (! reg_mentioned_p (cc0_rtx, SET_SRC (set))
1166052284Sobrien			      || ((cc0_setter = prev_cc0_setter (tem)) != NULL
1166152284Sobrien				  && sets_cc0_p (PATTERN (cc0_setter)) > 0))
1166252284Sobrien#endif
1166352284Sobrien			  )
1166418334Speter			{
1166518334Speter			  /* Move the notes and links of TEM elsewhere.
1166618334Speter			     This might delete other dead insns recursively.
1166718334Speter			     First set the pattern to something that won't use
1166818334Speter			     any register.  */
1166918334Speter
1167018334Speter			  PATTERN (tem) = pc_rtx;
1167118334Speter
1167218334Speter			  distribute_notes (REG_NOTES (tem), tem, tem,
1167318334Speter					    NULL_RTX, NULL_RTX, NULL_RTX);
1167418334Speter			  distribute_links (LOG_LINKS (tem));
1167518334Speter
1167618334Speter			  PUT_CODE (tem, NOTE);
1167718334Speter			  NOTE_LINE_NUMBER (tem) = NOTE_INSN_DELETED;
1167818334Speter			  NOTE_SOURCE_FILE (tem) = 0;
1167952284Sobrien
1168052284Sobrien#ifdef HAVE_cc0
1168152284Sobrien			  /* Delete the setter too.  */
1168252284Sobrien			  if (cc0_setter)
1168352284Sobrien			    {
1168452284Sobrien			      PATTERN (cc0_setter) = pc_rtx;
1168552284Sobrien
1168652284Sobrien			      distribute_notes (REG_NOTES (cc0_setter),
1168752284Sobrien						cc0_setter, cc0_setter,
1168852284Sobrien						NULL_RTX, NULL_RTX, NULL_RTX);
1168952284Sobrien			      distribute_links (LOG_LINKS (cc0_setter));
1169052284Sobrien
1169152284Sobrien			      PUT_CODE (cc0_setter, NOTE);
1169252284Sobrien			      NOTE_LINE_NUMBER (cc0_setter) = NOTE_INSN_DELETED;
1169352284Sobrien			      NOTE_SOURCE_FILE (cc0_setter) = 0;
1169452284Sobrien			    }
1169552284Sobrien#endif
1169618334Speter			}
1169750397Sobrien		      /* If the register is both set and used here, put the
1169850397Sobrien			 REG_DEAD note here, but place a REG_UNUSED note
1169950397Sobrien			 here too unless there already is one.  */
1170050397Sobrien		      else if (reg_referenced_p (XEXP (note, 0),
1170150397Sobrien						 PATTERN (tem)))
1170250397Sobrien			{
1170350397Sobrien			  place = tem;
1170450397Sobrien
1170550397Sobrien			  if (! find_regno_note (tem, REG_UNUSED,
1170650397Sobrien						 REGNO (XEXP (note, 0))))
1170750397Sobrien			    REG_NOTES (tem)
1170850397Sobrien			      = gen_rtx_EXPR_LIST (REG_UNUSED,
1170950397Sobrien						   XEXP (note, 0),
1171050397Sobrien						   REG_NOTES (tem));
1171150397Sobrien			}
1171218334Speter		      else
1171318334Speter			{
1171418334Speter			  PUT_REG_NOTE_KIND (note, REG_UNUSED);
1171518334Speter
1171618334Speter			  /*  If there isn't already a REG_UNUSED note, put one
1171718334Speter			      here.  */
1171818334Speter			  if (! find_regno_note (tem, REG_UNUSED,
1171918334Speter						 REGNO (XEXP (note, 0))))
1172018334Speter			    place = tem;
1172118334Speter			  break;
1172218334Speter		      }
1172318334Speter		  }
1172418334Speter		else if (reg_referenced_p (XEXP (note, 0), PATTERN (tem))
1172518334Speter			 || (GET_CODE (tem) == CALL_INSN
1172618334Speter			     && find_reg_fusage (tem, USE, XEXP (note, 0))))
1172718334Speter		  {
1172818334Speter		    place = tem;
1172918334Speter
1173018334Speter		    /* If we are doing a 3->2 combination, and we have a
1173118334Speter		       register which formerly died in i3 and was not used
1173218334Speter		       by i2, which now no longer dies in i3 and is used in
1173318334Speter		       i2 but does not die in i2, and place is between i2
1173418334Speter		       and i3, then we may need to move a link from place to
1173518334Speter		       i2.  */
1173618334Speter		    if (i2 && INSN_UID (place) <= max_uid_cuid
1173718334Speter			&& INSN_CUID (place) > INSN_CUID (i2)
1173818334Speter			&& from_insn && INSN_CUID (from_insn) > INSN_CUID (i2)
1173918334Speter			&& reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
1174018334Speter		      {
1174118334Speter			rtx links = LOG_LINKS (place);
1174218334Speter			LOG_LINKS (place) = 0;
1174318334Speter			distribute_links (links);
1174418334Speter		      }
1174518334Speter		    break;
1174618334Speter		  }
1174718334Speter		}
1174818334Speter
1174918334Speter	      /* If we haven't found an insn for the death note and it
1175018334Speter		 is still a REG_DEAD note, but we have hit a CODE_LABEL,
1175118334Speter		 insert a USE insn for the register at that label and
1175218334Speter		 put the death node there.  This prevents problems with
1175318334Speter		 call-state tracking in caller-save.c.  */
1175418334Speter	      if (REG_NOTE_KIND (note) == REG_DEAD && place == 0 && tem != 0)
1175518334Speter		{
1175618334Speter		  place
1175750397Sobrien		    = emit_insn_after (gen_rtx_USE (VOIDmode, XEXP (note, 0)),
1175818334Speter				       tem);
1175918334Speter
1176018334Speter		  /* If this insn was emitted between blocks, then update
1176152284Sobrien		     BLOCK_HEAD of the current block to include it.  */
1176252284Sobrien		  if (BLOCK_END (this_basic_block - 1) == tem)
1176352284Sobrien		    BLOCK_HEAD (this_basic_block) = place;
1176418334Speter		}
1176518334Speter	    }
1176618334Speter
1176718334Speter	  /* If the register is set or already dead at PLACE, we needn't do
1176850397Sobrien	     anything with this note if it is still a REG_DEAD note.
1176950397Sobrien	     We can here if it is set at all, not if is it totally replace,
1177050397Sobrien	     which is what `dead_or_set_p' checks, so also check for it being
1177150397Sobrien	     set partially.  */
1177218334Speter
1177350397Sobrien
1177418334Speter	  if (place && REG_NOTE_KIND (note) == REG_DEAD)
1177518334Speter	    {
1177618334Speter	      int regno = REGNO (XEXP (note, 0));
1177718334Speter
1177818334Speter	      if (dead_or_set_p (place, XEXP (note, 0))
1177918334Speter		  || reg_bitfield_target_p (XEXP (note, 0), PATTERN (place)))
1178018334Speter		{
1178118334Speter		  /* Unless the register previously died in PLACE, clear
1178218334Speter		     reg_last_death.  [I no longer understand why this is
1178318334Speter		     being done.] */
1178418334Speter		  if (reg_last_death[regno] != place)
1178518334Speter		    reg_last_death[regno] = 0;
1178618334Speter		  place = 0;
1178718334Speter		}
1178818334Speter	      else
1178918334Speter		reg_last_death[regno] = place;
1179018334Speter
1179118334Speter	      /* If this is a death note for a hard reg that is occupying
1179218334Speter		 multiple registers, ensure that we are still using all
1179318334Speter		 parts of the object.  If we find a piece of the object
1179418334Speter		 that is unused, we must add a USE for that piece before
1179518334Speter		 PLACE and put the appropriate REG_DEAD note on it.
1179618334Speter
1179718334Speter		 An alternative would be to put a REG_UNUSED for the pieces
1179818334Speter		 on the insn that set the register, but that can't be done if
1179918334Speter		 it is not in the same block.  It is simpler, though less
1180018334Speter		 efficient, to add the USE insns.  */
1180118334Speter
1180218334Speter	      if (place && regno < FIRST_PSEUDO_REGISTER
1180318334Speter		  && HARD_REGNO_NREGS (regno, GET_MODE (XEXP (note, 0))) > 1)
1180418334Speter		{
1180518334Speter		  int endregno
1180618334Speter		    = regno + HARD_REGNO_NREGS (regno,
1180718334Speter						GET_MODE (XEXP (note, 0)));
1180818334Speter		  int all_used = 1;
1180918334Speter		  int i;
1181018334Speter
1181118334Speter		  for (i = regno; i < endregno; i++)
1181218334Speter		    if (! refers_to_regno_p (i, i + 1, PATTERN (place), 0)
1181318334Speter			&& ! find_regno_fusage (place, USE, i))
1181418334Speter		      {
1181550397Sobrien			rtx piece = gen_rtx_REG (reg_raw_mode[i], i);
1181618334Speter			rtx p;
1181718334Speter
1181818334Speter			/* See if we already placed a USE note for this
1181918334Speter			   register in front of PLACE.  */
1182018334Speter			for (p = place;
1182118334Speter			     GET_CODE (PREV_INSN (p)) == INSN
1182218334Speter			     && GET_CODE (PATTERN (PREV_INSN (p))) == USE;
1182318334Speter			     p = PREV_INSN (p))
1182418334Speter			  if (rtx_equal_p (piece,
1182518334Speter					   XEXP (PATTERN (PREV_INSN (p)), 0)))
1182618334Speter			    {
1182718334Speter			      p = 0;
1182818334Speter			      break;
1182918334Speter			    }
1183018334Speter
1183118334Speter			if (p)
1183218334Speter			  {
1183318334Speter			    rtx use_insn
1183450397Sobrien			      = emit_insn_before (gen_rtx_USE (VOIDmode,
1183550397Sobrien							       piece),
1183618334Speter						  p);
1183718334Speter			    REG_NOTES (use_insn)
1183850397Sobrien			      = gen_rtx_EXPR_LIST (REG_DEAD, piece,
1183950397Sobrien						   REG_NOTES (use_insn));
1184018334Speter			  }
1184118334Speter
1184218334Speter			all_used = 0;
1184318334Speter		      }
1184418334Speter
1184518334Speter		  /* Check for the case where the register dying partially
1184618334Speter		     overlaps the register set by this insn.  */
1184718334Speter		  if (all_used)
1184818334Speter		    for (i = regno; i < endregno; i++)
1184918334Speter		      if (dead_or_set_regno_p (place, i))
1185018334Speter			  {
1185118334Speter			    all_used = 0;
1185218334Speter			    break;
1185318334Speter			  }
1185418334Speter
1185518334Speter		  if (! all_used)
1185618334Speter		    {
1185718334Speter		      /* Put only REG_DEAD notes for pieces that are
1185818334Speter			 still used and that are not already dead or set.  */
1185918334Speter
1186018334Speter		      for (i = regno; i < endregno; i++)
1186118334Speter			{
1186250397Sobrien			  rtx piece = gen_rtx_REG (reg_raw_mode[i], i);
1186318334Speter
1186418334Speter			  if ((reg_referenced_p (piece, PATTERN (place))
1186518334Speter			       || (GET_CODE (place) == CALL_INSN
1186618334Speter				   && find_reg_fusage (place, USE, piece)))
1186718334Speter			      && ! dead_or_set_p (place, piece)
1186818334Speter			      && ! reg_bitfield_target_p (piece,
1186918334Speter							  PATTERN (place)))
1187050397Sobrien			    REG_NOTES (place)
1187150397Sobrien			      = gen_rtx_EXPR_LIST (REG_DEAD,
1187250397Sobrien						   piece, REG_NOTES (place));
1187318334Speter			}
1187418334Speter
1187518334Speter		      place = 0;
1187618334Speter		    }
1187718334Speter		}
1187818334Speter	    }
1187918334Speter	  break;
1188018334Speter
1188118334Speter	default:
1188218334Speter	  /* Any other notes should not be present at this point in the
1188318334Speter	     compilation.  */
1188418334Speter	  abort ();
1188518334Speter	}
1188618334Speter
1188718334Speter      if (place)
1188818334Speter	{
1188918334Speter	  XEXP (note, 1) = REG_NOTES (place);
1189018334Speter	  REG_NOTES (place) = note;
1189118334Speter	}
1189218334Speter      else if ((REG_NOTE_KIND (note) == REG_DEAD
1189318334Speter		|| REG_NOTE_KIND (note) == REG_UNUSED)
1189418334Speter	       && GET_CODE (XEXP (note, 0)) == REG)
1189550397Sobrien	REG_N_DEATHS (REGNO (XEXP (note, 0)))--;
1189618334Speter
1189718334Speter      if (place2)
1189818334Speter	{
1189918334Speter	  if ((REG_NOTE_KIND (note) == REG_DEAD
1190018334Speter	       || REG_NOTE_KIND (note) == REG_UNUSED)
1190118334Speter	      && GET_CODE (XEXP (note, 0)) == REG)
1190250397Sobrien	    REG_N_DEATHS (REGNO (XEXP (note, 0)))++;
1190318334Speter
1190450397Sobrien	  REG_NOTES (place2) = gen_rtx_fmt_ee (GET_CODE (note),
1190550397Sobrien					       REG_NOTE_KIND (note),
1190650397Sobrien					       XEXP (note, 0),
1190750397Sobrien					       REG_NOTES (place2));
1190818334Speter	}
1190918334Speter    }
1191018334Speter}
1191118334Speter
1191218334Speter/* Similarly to above, distribute the LOG_LINKS that used to be present on
1191318334Speter   I3, I2, and I1 to new locations.  This is also called in one case to
1191418334Speter   add a link pointing at I3 when I3's destination is changed.  */
1191518334Speter
1191618334Speterstatic void
1191718334Speterdistribute_links (links)
1191818334Speter     rtx links;
1191918334Speter{
1192018334Speter  rtx link, next_link;
1192118334Speter
1192218334Speter  for (link = links; link; link = next_link)
1192318334Speter    {
1192418334Speter      rtx place = 0;
1192518334Speter      rtx insn;
1192618334Speter      rtx set, reg;
1192718334Speter
1192818334Speter      next_link = XEXP (link, 1);
1192918334Speter
1193018334Speter      /* If the insn that this link points to is a NOTE or isn't a single
1193118334Speter	 set, ignore it.  In the latter case, it isn't clear what we
1193218334Speter	 can do other than ignore the link, since we can't tell which
1193318334Speter	 register it was for.  Such links wouldn't be used by combine
1193418334Speter	 anyway.
1193518334Speter
1193618334Speter	 It is not possible for the destination of the target of the link to
1193718334Speter	 have been changed by combine.  The only potential of this is if we
1193818334Speter	 replace I3, I2, and I1 by I3 and I2.  But in that case the
1193918334Speter	 destination of I2 also remains unchanged.  */
1194018334Speter
1194118334Speter      if (GET_CODE (XEXP (link, 0)) == NOTE
1194218334Speter	  || (set = single_set (XEXP (link, 0))) == 0)
1194318334Speter	continue;
1194418334Speter
1194518334Speter      reg = SET_DEST (set);
1194618334Speter      while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT
1194718334Speter	     || GET_CODE (reg) == SIGN_EXTRACT
1194818334Speter	     || GET_CODE (reg) == STRICT_LOW_PART)
1194918334Speter	reg = XEXP (reg, 0);
1195018334Speter
1195118334Speter      /* A LOG_LINK is defined as being placed on the first insn that uses
1195218334Speter	 a register and points to the insn that sets the register.  Start
1195318334Speter	 searching at the next insn after the target of the link and stop
1195418334Speter	 when we reach a set of the register or the end of the basic block.
1195518334Speter
1195618334Speter	 Note that this correctly handles the link that used to point from
1195718334Speter	 I3 to I2.  Also note that not much searching is typically done here
1195818334Speter	 since most links don't point very far away.  */
1195918334Speter
1196018334Speter      for (insn = NEXT_INSN (XEXP (link, 0));
1196118334Speter	   (insn && (this_basic_block == n_basic_blocks - 1
1196252284Sobrien		     || BLOCK_HEAD (this_basic_block + 1) != insn));
1196318334Speter	   insn = NEXT_INSN (insn))
1196418334Speter	if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
1196518334Speter	    && reg_overlap_mentioned_p (reg, PATTERN (insn)))
1196618334Speter	  {
1196718334Speter	    if (reg_referenced_p (reg, PATTERN (insn)))
1196818334Speter	      place = insn;
1196918334Speter	    break;
1197018334Speter	  }
1197118334Speter	else if (GET_CODE (insn) == CALL_INSN
1197218334Speter	      && find_reg_fusage (insn, USE, reg))
1197318334Speter	  {
1197418334Speter	    place = insn;
1197518334Speter	    break;
1197618334Speter	  }
1197718334Speter
1197818334Speter      /* If we found a place to put the link, place it there unless there
1197918334Speter	 is already a link to the same insn as LINK at that point.  */
1198018334Speter
1198118334Speter      if (place)
1198218334Speter	{
1198318334Speter	  rtx link2;
1198418334Speter
1198518334Speter	  for (link2 = LOG_LINKS (place); link2; link2 = XEXP (link2, 1))
1198618334Speter	    if (XEXP (link2, 0) == XEXP (link, 0))
1198718334Speter	      break;
1198818334Speter
1198918334Speter	  if (link2 == 0)
1199018334Speter	    {
1199118334Speter	      XEXP (link, 1) = LOG_LINKS (place);
1199218334Speter	      LOG_LINKS (place) = link;
1199318334Speter
1199418334Speter	      /* Set added_links_insn to the earliest insn we added a
1199518334Speter		 link to.  */
1199618334Speter	      if (added_links_insn == 0
1199718334Speter		  || INSN_CUID (added_links_insn) > INSN_CUID (place))
1199818334Speter		added_links_insn = place;
1199918334Speter	    }
1200018334Speter	}
1200118334Speter    }
1200218334Speter}
1200318334Speter
1200450397Sobrien/* Compute INSN_CUID for INSN, which is an insn made by combine.  */
1200550397Sobrien
1200650397Sobrienstatic int
1200750397Sobrieninsn_cuid (insn)
1200850397Sobrien     rtx insn;
1200950397Sobrien{
1201050397Sobrien  while (insn != 0 && INSN_UID (insn) > max_uid_cuid
1201150397Sobrien	 && GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == USE)
1201250397Sobrien    insn = NEXT_INSN (insn);
1201350397Sobrien
1201450397Sobrien  if (INSN_UID (insn) > max_uid_cuid)
1201550397Sobrien    abort ();
1201650397Sobrien
1201750397Sobrien  return INSN_CUID (insn);
1201850397Sobrien}
1201950397Sobrien
1202018334Spetervoid
1202118334Speterdump_combine_stats (file)
1202218334Speter     FILE *file;
1202318334Speter{
1202452284Sobrien  fnotice
1202518334Speter    (file,
1202618334Speter     ";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n",
1202718334Speter     combine_attempts, combine_merges, combine_extras, combine_successes);
1202818334Speter}
1202918334Speter
1203018334Spetervoid
1203118334Speterdump_combine_total_stats (file)
1203218334Speter     FILE *file;
1203318334Speter{
1203452284Sobrien  fnotice
1203518334Speter    (file,
1203618334Speter     "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n",
1203718334Speter     total_attempts, total_merges, total_extras, total_successes);
1203818334Speter}
12039