118334Speter/* Optimize by combining instructions for GNU compiler.
272562Sobrien   Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3169689Skan   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
418334Speter
590075SobrienThis file is part of GCC.
618334Speter
790075SobrienGCC is free software; you can redistribute it and/or modify it under
890075Sobrienthe terms of the GNU General Public License as published by the Free
990075SobrienSoftware Foundation; either version 2, or (at your option) any later
1090075Sobrienversion.
1118334Speter
1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590075Sobrienfor more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan02110-1301, USA.  */
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
56169689Skan   - reg_n_refs is not adjusted in the rare case when a register is
57169689Skan     no longer required in a computation
58169689Skan   - there are extremely rare cases (see distribute_notes) when a
59169689Skan     REG_DEAD note is lost
6018334Speter   - a LOG_LINKS entry that refers to an insn with multiple SETs may be
6190075Sobrien     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"
79132718Skan#include "coretypes.h"
80132718Skan#include "tm.h"
8190075Sobrien#include "rtl.h"
82132718Skan#include "tree.h"
8390075Sobrien#include "tm_p.h"
8418334Speter#include "flags.h"
8518334Speter#include "regs.h"
8618334Speter#include "hard-reg-set.h"
8718334Speter#include "basic-block.h"
8818334Speter#include "insn-config.h"
8990075Sobrien#include "function.h"
9090075Sobrien/* Include expr.h after insn-config.h so we get HAVE_conditional_move.  */
9150397Sobrien#include "expr.h"
9218334Speter#include "insn-attr.h"
9318334Speter#include "recog.h"
9418334Speter#include "real.h"
9550397Sobrien#include "toplev.h"
96132718Skan#include "target.h"
97169689Skan#include "optabs.h"
98169689Skan#include "insn-codes.h"
99169689Skan#include "rtlhooks-def.h"
100169689Skan/* Include output.h for dump_file.  */
101169689Skan#include "output.h"
102146895Skan#include "params.h"
103169689Skan#include "timevar.h"
104169689Skan#include "tree-pass.h"
10518334Speter
10618334Speter/* Number of attempts to combine instructions in this function.  */
10718334Speter
10818334Speterstatic int combine_attempts;
10918334Speter
11018334Speter/* Number of attempts that got as far as substitution in this function.  */
11118334Speter
11218334Speterstatic int combine_merges;
11318334Speter
11418334Speter/* Number of instructions combined with added SETs in this function.  */
11518334Speter
11618334Speterstatic int combine_extras;
11718334Speter
11818334Speter/* Number of instructions combined in this function.  */
11918334Speter
12018334Speterstatic int combine_successes;
12118334Speter
12218334Speter/* Totals over entire compilation.  */
12318334Speter
12418334Speterstatic int total_attempts, total_merges, total_extras, total_successes;
12518334Speter
126169689Skan/* combine_instructions may try to replace the right hand side of the
127169689Skan   second instruction with the value of an associated REG_EQUAL note
128169689Skan   before throwing it at try_combine.  That is problematic when there
129169689Skan   is a REG_DEAD note for a register used in the old right hand side
130169689Skan   and can cause distribute_notes to do wrong things.  This is the
131169689Skan   second instruction if it has been so modified, null otherwise.  */
132169689Skan
133169689Skanstatic rtx i2mod;
134169689Skan
135169689Skan/* When I2MOD is nonnull, this is a copy of the old right hand side.  */
136169689Skan
137169689Skanstatic rtx i2mod_old_rhs;
138169689Skan
139169689Skan/* When I2MOD is nonnull, this is a copy of the new right hand side.  */
140169689Skan
141169689Skanstatic rtx i2mod_new_rhs;
14218334Speter
14318334Speter/* Vector mapping INSN_UIDs to cuids.
14418334Speter   The cuids are like uids but increase monotonically always.
14518334Speter   Combine always uses cuids so that it can compare them.
14618334Speter   But actually renumbering the uids, which we used to do,
14718334Speter   proves to be a bad idea because it makes it hard to compare
14818334Speter   the dumps produced by earlier passes with those from later passes.  */
14918334Speter
15018334Speterstatic int *uid_cuid;
15118334Speterstatic int max_uid_cuid;
15218334Speter
15318334Speter/* Get the cuid of an insn.  */
15418334Speter
15550397Sobrien#define INSN_CUID(INSN) \
15650397Sobrien(INSN_UID (INSN) > max_uid_cuid ? insn_cuid (INSN) : uid_cuid[INSN_UID (INSN)])
15718334Speter
158169689Skan/* Maximum register number, which is the size of the tables below.  */
15990075Sobrien
160169689Skanstatic unsigned int combine_max_regno;
16190075Sobrien
162169689Skanstruct reg_stat {
163169689Skan  /* Record last point of death of (hard or pseudo) register n.  */
164169689Skan  rtx				last_death;
165117395Skan
166169689Skan  /* Record last point of modification of (hard or pseudo) register n.  */
167169689Skan  rtx				last_set;
168117395Skan
169169689Skan  /* The next group of fields allows the recording of the last value assigned
170169689Skan     to (hard or pseudo) register n.  We use this information to see if an
171169689Skan     operation being processed is redundant given a prior operation performed
172169689Skan     on the register.  For example, an `and' with a constant is redundant if
173169689Skan     all the zero bits are already known to be turned off.
17418334Speter
175169689Skan     We use an approach similar to that used by cse, but change it in the
176169689Skan     following ways:
17718334Speter
178169689Skan     (1) We do not want to reinitialize at each label.
179169689Skan     (2) It is useful, but not critical, to know the actual value assigned
180169689Skan	 to a register.  Often just its form is helpful.
18118334Speter
182169689Skan     Therefore, we maintain the following fields:
18318334Speter
184169689Skan     last_set_value		the last value assigned
185169689Skan     last_set_label		records the value of label_tick when the
186169689Skan				register was assigned
187169689Skan     last_set_table_tick	records the value of label_tick when a
188169689Skan				value using the register is assigned
189169689Skan     last_set_invalid		set to nonzero when it is not valid
190169689Skan				to use the value of this register in some
191169689Skan				register's value
19218334Speter
193169689Skan     To understand the usage of these tables, it is important to understand
194169689Skan     the distinction between the value in last_set_value being valid and
195169689Skan     the register being validly contained in some other expression in the
196169689Skan     table.
19718334Speter
198169689Skan     (The next two parameters are out of date).
199169689Skan
200169689Skan     reg_stat[i].last_set_value is valid if it is nonzero, and either
201169689Skan     reg_n_sets[i] is 1 or reg_stat[i].last_set_label == label_tick.
202169689Skan
203169689Skan     Register I may validly appear in any expression returned for the value
204169689Skan     of another register if reg_n_sets[i] is 1.  It may also appear in the
205169689Skan     value for register J if reg_stat[j].last_set_invalid is zero, or
206169689Skan     reg_stat[i].last_set_label < reg_stat[j].last_set_label.
207169689Skan
208169689Skan     If an expression is found in the table containing a register which may
209169689Skan     not validly appear in an expression, the register is replaced by
210169689Skan     something that won't match, (clobber (const_int 0)).  */
211169689Skan
212169689Skan  /* Record last value assigned to (hard or pseudo) register n.  */
213169689Skan
214169689Skan  rtx				last_set_value;
215169689Skan
216169689Skan  /* Record the value of label_tick when an expression involving register n
217169689Skan     is placed in last_set_value.  */
218169689Skan
219169689Skan  int				last_set_table_tick;
220169689Skan
221169689Skan  /* Record the value of label_tick when the value for register n is placed in
222169689Skan     last_set_value.  */
223169689Skan
224169689Skan  int				last_set_label;
225169689Skan
226169689Skan  /* These fields are maintained in parallel with last_set_value and are
227169689Skan     used to store the mode in which the register was last set, the bits
228169689Skan     that were known to be zero when it was last set, and the number of
229169689Skan     sign bits copies it was known to have when it was last set.  */
230169689Skan
231169689Skan  unsigned HOST_WIDE_INT	last_set_nonzero_bits;
232169689Skan  char				last_set_sign_bit_copies;
233169689Skan  ENUM_BITFIELD(machine_mode)	last_set_mode : 8;
234169689Skan
235169689Skan  /* Set nonzero if references to register n in expressions should not be
236169689Skan     used.  last_set_invalid is set nonzero when this register is being
237169689Skan     assigned to and last_set_table_tick == label_tick.  */
238169689Skan
239169689Skan  char				last_set_invalid;
240169689Skan
241169689Skan  /* Some registers that are set more than once and used in more than one
242169689Skan     basic block are nevertheless always set in similar ways.  For example,
243169689Skan     a QImode register may be loaded from memory in two places on a machine
244169689Skan     where byte loads zero extend.
245169689Skan
246169689Skan     We record in the following fields if a register has some leading bits
247169689Skan     that are always equal to the sign bit, and what we know about the
248169689Skan     nonzero bits of a register, specifically which bits are known to be
249169689Skan     zero.
250169689Skan
251169689Skan     If an entry is zero, it means that we don't know anything special.  */
252169689Skan
253169689Skan  unsigned char			sign_bit_copies;
254169689Skan
255169689Skan  unsigned HOST_WIDE_INT	nonzero_bits;
256169689Skan
257169689Skan  /* Record the value of the label_tick when the last truncation
258169689Skan     happened.  The field truncated_to_mode is only valid if
259169689Skan     truncation_label == label_tick.  */
260169689Skan
261169689Skan  int				truncation_label;
262169689Skan
263169689Skan  /* Record the last truncation seen for this register.  If truncation
264169689Skan     is not a nop to this mode we might be able to save an explicit
265169689Skan     truncation if we know that value already contains a truncated
266169689Skan     value.  */
267169689Skan
268169689Skan  ENUM_BITFIELD(machine_mode)	truncated_to_mode : 8;
269169689Skan};
270169689Skan
271169689Skanstatic struct reg_stat *reg_stat;
272169689Skan
27318334Speter/* Record the cuid of the last insn that invalidated memory
27418334Speter   (anything that writes memory, and subroutine calls, but not pushes).  */
27518334Speter
27618334Speterstatic int mem_last_set;
27718334Speter
27818334Speter/* Record the cuid of the last CALL_INSN
27918334Speter   so we can tell whether a potential combination crosses any calls.  */
28018334Speter
28118334Speterstatic int last_call_cuid;
28218334Speter
28318334Speter/* When `subst' is called, this is the insn that is being modified
28418334Speter   (by combining in a previous insn).  The PATTERN of this insn
28518334Speter   is still the old pattern partially modified and it should not be
28618334Speter   looked at, but this may be used to examine the successors of the insn
28718334Speter   to judge whether a simplification is valid.  */
28818334Speter
28918334Speterstatic rtx subst_insn;
29018334Speter
29118334Speter/* This is the lowest CUID that `subst' is currently dealing with.
29218334Speter   get_last_value will not return a value if the register was set at or
29318334Speter   after this CUID.  If not for this mechanism, we could get confused if
29418334Speter   I2 or I1 in try_combine were an insn that used the old value of a register
29518334Speter   to obtain a new value.  In that case, we might erroneously get the
29618334Speter   new value of the register when we wanted the old one.  */
29718334Speter
29818334Speterstatic int subst_low_cuid;
29918334Speter
30018334Speter/* This contains any hard registers that are used in newpat; reg_dead_at_p
30118334Speter   must consider all these registers to be always live.  */
30218334Speter
30318334Speterstatic HARD_REG_SET newpat_used_regs;
30418334Speter
30518334Speter/* This is an insn to which a LOG_LINKS entry has been added.  If this
30618334Speter   insn is the earlier than I2 or I3, combine should rescan starting at
30718334Speter   that location.  */
30818334Speter
30918334Speterstatic rtx added_links_insn;
31018334Speter
311117395Skan/* Basic block in which we are performing combines.  */
312117395Skanstatic basic_block this_basic_block;
31390075Sobrien
31490075Sobrien/* A bitmap indicating which blocks had registers go dead at entry.
31590075Sobrien   After combine, we'll need to re-do global life analysis with
31690075Sobrien   those blocks as starting points.  */
31790075Sobrienstatic sbitmap refresh_blocks;
31818334Speter
319169689Skan/* The following array records the insn_rtx_cost for every insn
320169689Skan   in the instruction stream.  */
32118334Speter
322169689Skanstatic int *uid_insn_cost;
32318334Speter
324169689Skan/* Length of the currently allocated uid_insn_cost array.  */
32518334Speter
326169689Skanstatic int last_insn_cost;
32718334Speter
32850397Sobrien/* Incremented for each label.  */
32918334Speter
33018334Speterstatic int label_tick;
33118334Speter
332169689Skan/* Mode used to compute significance in reg_stat[].nonzero_bits.  It is the
333169689Skan   largest integer mode that can fit in HOST_BITS_PER_WIDE_INT.  */
33418334Speter
33518334Speterstatic enum machine_mode nonzero_bits_mode;
33618334Speter
337169689Skan/* Nonzero when reg_stat[].nonzero_bits and reg_stat[].sign_bit_copies can
338169689Skan   be safely used.  It is zero while computing them and after combine has
339169689Skan   completed.  This former test prevents propagating values based on
340169689Skan   previously set values, which can be incorrect if a variable is modified
341169689Skan   in a loop.  */
34218334Speter
34318334Speterstatic int nonzero_sign_valid;
34418334Speter
34518334Speter
34618334Speter/* Record one modification to rtl structure
347169689Skan   to be undone by storing old_contents into *where.  */
34818334Speter
34918334Speterstruct undo
35018334Speter{
35150397Sobrien  struct undo *next;
352169689Skan  enum { UNDO_RTX, UNDO_INT, UNDO_MODE } kind;
353169689Skan  union { rtx r; int i; enum machine_mode m; } old_contents;
354169689Skan  union { rtx *r; int *i; } where;
35518334Speter};
35618334Speter
35718334Speter/* Record a bunch of changes to be undone, up to MAX_UNDO of them.
35818334Speter   num_undo says how many are currently recorded.
35918334Speter
36018334Speter   other_insn is nonzero if we have modified some other insn in the process
36190075Sobrien   of working on subst_insn.  It must be verified too.  */
36218334Speter
36318334Speterstruct undobuf
36418334Speter{
36550397Sobrien  struct undo *undos;
36650397Sobrien  struct undo *frees;
36718334Speter  rtx other_insn;
36818334Speter};
36918334Speter
37018334Speterstatic struct undobuf undobuf;
37118334Speter
37290075Sobrien/* Number of times the pseudo being substituted for
37390075Sobrien   was found and replaced.  */
37490075Sobrien
37590075Sobrienstatic int n_occurrences;
37690075Sobrien
377169689Skanstatic rtx reg_nonzero_bits_for_combine (rtx, enum machine_mode, rtx,
378169689Skan					 enum machine_mode,
379169689Skan					 unsigned HOST_WIDE_INT,
380169689Skan					 unsigned HOST_WIDE_INT *);
381169689Skanstatic rtx reg_num_sign_bit_copies_for_combine (rtx, enum machine_mode, rtx,
382169689Skan						enum machine_mode,
383169689Skan						unsigned int, unsigned int *);
384132718Skanstatic void do_SUBST (rtx *, rtx);
385132718Skanstatic void do_SUBST_INT (int *, int);
386169689Skanstatic void init_reg_last (void);
387132718Skanstatic void setup_incoming_promotions (void);
388132718Skanstatic void set_nonzero_bits_and_sign_copies (rtx, rtx, void *);
389132718Skanstatic int cant_combine_insn_p (rtx);
390132718Skanstatic int can_combine_p (rtx, rtx, rtx, rtx, rtx *, rtx *);
391132718Skanstatic int combinable_i3pat (rtx, rtx *, rtx, rtx, int, rtx *);
392132718Skanstatic int contains_muldiv (rtx);
393132718Skanstatic rtx try_combine (rtx, rtx, rtx, int *);
394132718Skanstatic void undo_all (void);
395132718Skanstatic void undo_commit (void);
396132718Skanstatic rtx *find_split_point (rtx *, rtx);
397132718Skanstatic rtx subst (rtx, rtx, rtx, int, int);
398169689Skanstatic rtx combine_simplify_rtx (rtx, enum machine_mode, int);
399132718Skanstatic rtx simplify_if_then_else (rtx);
400132718Skanstatic rtx simplify_set (rtx);
401169689Skanstatic rtx simplify_logical (rtx);
402132718Skanstatic rtx expand_compound_operation (rtx);
403132718Skanstatic rtx expand_field_assignment (rtx);
404132718Skanstatic rtx make_extraction (enum machine_mode, rtx, HOST_WIDE_INT,
405132718Skan			    rtx, unsigned HOST_WIDE_INT, int, int, int);
406132718Skanstatic rtx extract_left_shift (rtx, int);
407132718Skanstatic rtx make_compound_operation (rtx, enum rtx_code);
408132718Skanstatic int get_pos_from_mask (unsigned HOST_WIDE_INT,
409132718Skan			      unsigned HOST_WIDE_INT *);
410169689Skanstatic rtx canon_reg_for_combine (rtx, rtx);
411132718Skanstatic rtx force_to_mode (rtx, enum machine_mode,
412169689Skan			  unsigned HOST_WIDE_INT, int);
413132718Skanstatic rtx if_then_else_cond (rtx, rtx *, rtx *);
414132718Skanstatic rtx known_cond (rtx, enum rtx_code, rtx, rtx);
415132718Skanstatic int rtx_equal_for_field_assignment_p (rtx, rtx);
416132718Skanstatic rtx make_field_assignment (rtx);
417132718Skanstatic rtx apply_distributive_law (rtx);
418169689Skanstatic rtx distribute_and_simplify_rtx (rtx, int);
419169689Skanstatic rtx simplify_and_const_int_1 (enum machine_mode, rtx,
420169689Skan				     unsigned HOST_WIDE_INT);
421132718Skanstatic rtx simplify_and_const_int (rtx, enum machine_mode, rtx,
422132718Skan				   unsigned HOST_WIDE_INT);
423132718Skanstatic int merge_outer_ops (enum rtx_code *, HOST_WIDE_INT *, enum rtx_code,
424132718Skan			    HOST_WIDE_INT, enum machine_mode, int *);
425169689Skanstatic rtx simplify_shift_const_1 (enum rtx_code, enum machine_mode, rtx, int);
426169689Skanstatic rtx simplify_shift_const (rtx, enum rtx_code, enum machine_mode, rtx,
427132718Skan				 int);
428132718Skanstatic int recog_for_combine (rtx *, rtx, rtx *);
429132718Skanstatic rtx gen_lowpart_for_combine (enum machine_mode, rtx);
430132718Skanstatic enum rtx_code simplify_comparison (enum rtx_code, rtx *, rtx *);
431132718Skanstatic void update_table_tick (rtx);
432132718Skanstatic void record_value_for_reg (rtx, rtx, rtx);
433169689Skanstatic void check_conversions (rtx, rtx);
434132718Skanstatic void record_dead_and_set_regs_1 (rtx, rtx, void *);
435132718Skanstatic void record_dead_and_set_regs (rtx);
436132718Skanstatic int get_last_value_validate (rtx *, rtx, int, int);
437132718Skanstatic rtx get_last_value (rtx);
438132718Skanstatic int use_crosses_set_p (rtx, int);
439132718Skanstatic void reg_dead_at_p_1 (rtx, rtx, void *);
440132718Skanstatic int reg_dead_at_p (rtx, rtx);
441132718Skanstatic void move_deaths (rtx, rtx, int, rtx, rtx *);
442132718Skanstatic int reg_bitfield_target_p (rtx, rtx);
443169689Skanstatic void distribute_notes (rtx, rtx, rtx, rtx, rtx, rtx);
444132718Skanstatic void distribute_links (rtx);
445132718Skanstatic void mark_used_regs_combine (rtx);
446132718Skanstatic int insn_cuid (rtx);
447132718Skanstatic void record_promoted_value (rtx, rtx);
448169689Skanstatic int unmentioned_reg_p_1 (rtx *, void *);
449169689Skanstatic bool unmentioned_reg_p (rtx, rtx);
450169689Skanstatic void record_truncated_value (rtx);
451169689Skanstatic bool reg_truncated_to_mode (enum machine_mode, rtx);
452169689Skanstatic rtx gen_lowpart_or_truncate (enum machine_mode, rtx);
45390075Sobrien
454169689Skan
455169689Skan/* It is not safe to use ordinary gen_lowpart in combine.
456169689Skan   See comments in gen_lowpart_for_combine.  */
457169689Skan#undef RTL_HOOKS_GEN_LOWPART
458169689Skan#define RTL_HOOKS_GEN_LOWPART              gen_lowpart_for_combine
459169689Skan
460169689Skan/* Our implementation of gen_lowpart never emits a new pseudo.  */
461169689Skan#undef RTL_HOOKS_GEN_LOWPART_NO_EMIT
462169689Skan#define RTL_HOOKS_GEN_LOWPART_NO_EMIT      gen_lowpart_for_combine
463169689Skan
464169689Skan#undef RTL_HOOKS_REG_NONZERO_REG_BITS
465169689Skan#define RTL_HOOKS_REG_NONZERO_REG_BITS     reg_nonzero_bits_for_combine
466169689Skan
467169689Skan#undef RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES
468169689Skan#define RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES  reg_num_sign_bit_copies_for_combine
469169689Skan
470169689Skan#undef RTL_HOOKS_REG_TRUNCATED_TO_MODE
471169689Skan#define RTL_HOOKS_REG_TRUNCATED_TO_MODE    reg_truncated_to_mode
472169689Skan
473169689Skanstatic const struct rtl_hooks combine_rtl_hooks = RTL_HOOKS_INITIALIZER;
474169689Skan
475169689Skan
47618334Speter/* Substitute NEWVAL, an rtx expression, into INTO, a place in some
47718334Speter   insn.  The substitution can be undone by undo_all.  If INTO is already
47818334Speter   set to NEWVAL, do not record this change.  Because computing NEWVAL might
47918334Speter   also call SUBST, we have to compute it before we put anything into
48018334Speter   the undo table.  */
48118334Speter
48290075Sobrienstatic void
483132718Skando_SUBST (rtx *into, rtx newval)
48490075Sobrien{
48590075Sobrien  struct undo *buf;
48690075Sobrien  rtx oldval = *into;
48718334Speter
48890075Sobrien  if (oldval == newval)
48990075Sobrien    return;
49090075Sobrien
49196263Sobrien  /* We'd like to catch as many invalid transformations here as
49296263Sobrien     possible.  Unfortunately, there are way too many mode changes
49396263Sobrien     that are perfectly valid, so we'd waste too much effort for
49496263Sobrien     little gain doing the checks here.  Focus on catching invalid
49596263Sobrien     transformations involving integer constants.  */
49696263Sobrien  if (GET_MODE_CLASS (GET_MODE (oldval)) == MODE_INT
49796263Sobrien      && GET_CODE (newval) == CONST_INT)
49896263Sobrien    {
49996263Sobrien      /* Sanity check that we're replacing oldval with a CONST_INT
50096263Sobrien	 that is a valid sign-extension for the original mode.  */
501169689Skan      gcc_assert (INTVAL (newval)
502169689Skan		  == trunc_int_for_mode (INTVAL (newval), GET_MODE (oldval)));
50396263Sobrien
50496263Sobrien      /* Replacing the operand of a SUBREG or a ZERO_EXTEND with a
50596263Sobrien	 CONST_INT is not valid, because after the replacement, the
50696263Sobrien	 original mode would be gone.  Unfortunately, we can't tell
50796263Sobrien	 when do_SUBST is called to replace the operand thereof, so we
50896263Sobrien	 perform this test on oldval instead, checking whether an
50996263Sobrien	 invalid replacement took place before we got here.  */
510169689Skan      gcc_assert (!(GET_CODE (oldval) == SUBREG
511169689Skan		    && GET_CODE (SUBREG_REG (oldval)) == CONST_INT));
512169689Skan      gcc_assert (!(GET_CODE (oldval) == ZERO_EXTEND
513169689Skan		    && GET_CODE (XEXP (oldval, 0)) == CONST_INT));
514132718Skan    }
51596263Sobrien
51690075Sobrien  if (undobuf.frees)
51790075Sobrien    buf = undobuf.frees, undobuf.frees = buf->next;
51890075Sobrien  else
519169689Skan    buf = XNEW (struct undo);
52090075Sobrien
521169689Skan  buf->kind = UNDO_RTX;
52290075Sobrien  buf->where.r = into;
52390075Sobrien  buf->old_contents.r = oldval;
52490075Sobrien  *into = newval;
52590075Sobrien
52690075Sobrien  buf->next = undobuf.undos, undobuf.undos = buf;
52790075Sobrien}
52890075Sobrien
52990075Sobrien#define SUBST(INTO, NEWVAL)	do_SUBST(&(INTO), (NEWVAL))
53090075Sobrien
53150397Sobrien/* Similar to SUBST, but NEWVAL is an int expression.  Note that substitution
53250397Sobrien   for the value of a HOST_WIDE_INT value (including CONST_INT) is
53350397Sobrien   not safe.  */
53418334Speter
53590075Sobrienstatic void
536132718Skando_SUBST_INT (int *into, int newval)
53790075Sobrien{
53890075Sobrien  struct undo *buf;
539117395Skan  int oldval = *into;
54018334Speter
54190075Sobrien  if (oldval == newval)
54290075Sobrien    return;
54318334Speter
54490075Sobrien  if (undobuf.frees)
54590075Sobrien    buf = undobuf.frees, undobuf.frees = buf->next;
54690075Sobrien  else
547169689Skan    buf = XNEW (struct undo);
54818334Speter
549169689Skan  buf->kind = UNDO_INT;
55090075Sobrien  buf->where.i = into;
55190075Sobrien  buf->old_contents.i = oldval;
55290075Sobrien  *into = newval;
55390075Sobrien
55490075Sobrien  buf->next = undobuf.undos, undobuf.undos = buf;
55590075Sobrien}
55690075Sobrien
55790075Sobrien#define SUBST_INT(INTO, NEWVAL)  do_SUBST_INT(&(INTO), (NEWVAL))
558169689Skan
559169689Skan/* Similar to SUBST, but just substitute the mode.  This is used when
560169689Skan   changing the mode of a pseudo-register, so that any other
561169689Skan   references to the entry in the regno_reg_rtx array will change as
562169689Skan   well.  */
563169689Skan
564169689Skanstatic void
565169689Skando_SUBST_MODE (rtx *into, enum machine_mode newval)
566169689Skan{
567169689Skan  struct undo *buf;
568169689Skan  enum machine_mode oldval = GET_MODE (*into);
569169689Skan
570169689Skan  if (oldval == newval)
571169689Skan    return;
572169689Skan
573169689Skan  if (undobuf.frees)
574169689Skan    buf = undobuf.frees, undobuf.frees = buf->next;
575169689Skan  else
576169689Skan    buf = XNEW (struct undo);
577169689Skan
578169689Skan  buf->kind = UNDO_MODE;
579169689Skan  buf->where.r = into;
580169689Skan  buf->old_contents.m = oldval;
581169689Skan  PUT_MODE (*into, newval);
582169689Skan
583169689Skan  buf->next = undobuf.undos, undobuf.undos = buf;
584169689Skan}
585169689Skan
586169689Skan#define SUBST_MODE(INTO, NEWVAL)  do_SUBST_MODE(&(INTO), (NEWVAL))
58718334Speter
588169689Skan/* Subroutine of try_combine.  Determine whether the combine replacement
589169689Skan   patterns NEWPAT and NEWI2PAT are cheaper according to insn_rtx_cost
590169689Skan   that the original instruction sequence I1, I2 and I3.  Note that I1
591169689Skan   and/or NEWI2PAT may be NULL_RTX.  This function returns false, if the
592169689Skan   costs of all instructions can be estimated, and the replacements are
593169689Skan   more expensive than the original sequence.  */
594169689Skan
595169689Skanstatic bool
596169689Skancombine_validate_cost (rtx i1, rtx i2, rtx i3, rtx newpat, rtx newi2pat)
597169689Skan{
598169689Skan  int i1_cost, i2_cost, i3_cost;
599169689Skan  int new_i2_cost, new_i3_cost;
600169689Skan  int old_cost, new_cost;
601169689Skan
602169689Skan  /* Lookup the original insn_rtx_costs.  */
603169689Skan  i2_cost = INSN_UID (i2) <= last_insn_cost
604169689Skan	    ? uid_insn_cost[INSN_UID (i2)] : 0;
605169689Skan  i3_cost = INSN_UID (i3) <= last_insn_cost
606169689Skan	    ? uid_insn_cost[INSN_UID (i3)] : 0;
607169689Skan
608169689Skan  if (i1)
609169689Skan    {
610169689Skan      i1_cost = INSN_UID (i1) <= last_insn_cost
611169689Skan		? uid_insn_cost[INSN_UID (i1)] : 0;
612169689Skan      old_cost = (i1_cost > 0 && i2_cost > 0 && i3_cost > 0)
613169689Skan		 ? i1_cost + i2_cost + i3_cost : 0;
614169689Skan    }
615169689Skan  else
616169689Skan    {
617169689Skan      old_cost = (i2_cost > 0 && i3_cost > 0) ? i2_cost + i3_cost : 0;
618169689Skan      i1_cost = 0;
619169689Skan    }
620169689Skan
621169689Skan  /* Calculate the replacement insn_rtx_costs.  */
622169689Skan  new_i3_cost = insn_rtx_cost (newpat);
623169689Skan  if (newi2pat)
624169689Skan    {
625169689Skan      new_i2_cost = insn_rtx_cost (newi2pat);
626169689Skan      new_cost = (new_i2_cost > 0 && new_i3_cost > 0)
627169689Skan		 ? new_i2_cost + new_i3_cost : 0;
628169689Skan    }
629169689Skan  else
630169689Skan    {
631169689Skan      new_cost = new_i3_cost;
632169689Skan      new_i2_cost = 0;
633169689Skan    }
634169689Skan
635169689Skan  if (undobuf.other_insn)
636169689Skan    {
637169689Skan      int old_other_cost, new_other_cost;
638169689Skan
639169689Skan      old_other_cost = (INSN_UID (undobuf.other_insn) <= last_insn_cost
640169689Skan			? uid_insn_cost[INSN_UID (undobuf.other_insn)] : 0);
641169689Skan      new_other_cost = insn_rtx_cost (PATTERN (undobuf.other_insn));
642169689Skan      if (old_other_cost > 0 && new_other_cost > 0)
643169689Skan	{
644169689Skan	  old_cost += old_other_cost;
645169689Skan	  new_cost += new_other_cost;
646169689Skan	}
647169689Skan      else
648169689Skan	old_cost = 0;
649169689Skan    }
650169689Skan
651169689Skan  /* Disallow this recombination if both new_cost and old_cost are
652169689Skan     greater than zero, and new_cost is greater than old cost.  */
653169689Skan  if (old_cost > 0
654169689Skan      && new_cost > old_cost)
655169689Skan    {
656169689Skan      if (dump_file)
657169689Skan	{
658169689Skan	  if (i1)
659169689Skan	    {
660169689Skan	      fprintf (dump_file,
661169689Skan		       "rejecting combination of insns %d, %d and %d\n",
662169689Skan		       INSN_UID (i1), INSN_UID (i2), INSN_UID (i3));
663169689Skan	      fprintf (dump_file, "original costs %d + %d + %d = %d\n",
664169689Skan		       i1_cost, i2_cost, i3_cost, old_cost);
665169689Skan	    }
666169689Skan	  else
667169689Skan	    {
668169689Skan	      fprintf (dump_file,
669169689Skan		       "rejecting combination of insns %d and %d\n",
670169689Skan		       INSN_UID (i2), INSN_UID (i3));
671169689Skan	      fprintf (dump_file, "original costs %d + %d = %d\n",
672169689Skan		       i2_cost, i3_cost, old_cost);
673169689Skan	    }
674169689Skan
675169689Skan	  if (newi2pat)
676169689Skan	    {
677169689Skan	      fprintf (dump_file, "replacement costs %d + %d = %d\n",
678169689Skan		       new_i2_cost, new_i3_cost, new_cost);
679169689Skan	    }
680169689Skan	  else
681169689Skan	    fprintf (dump_file, "replacement cost %d\n", new_cost);
682169689Skan	}
683169689Skan
684169689Skan      return false;
685169689Skan    }
686169689Skan
687169689Skan  /* Update the uid_insn_cost array with the replacement costs.  */
688169689Skan  uid_insn_cost[INSN_UID (i2)] = new_i2_cost;
689169689Skan  uid_insn_cost[INSN_UID (i3)] = new_i3_cost;
690169689Skan  if (i1)
691169689Skan    uid_insn_cost[INSN_UID (i1)] = 0;
692169689Skan
693169689Skan  return true;
694169689Skan}
695169689Skan
69618334Speter/* Main entry point for combiner.  F is the first insn of the function.
69790075Sobrien   NREGS is the first unused pseudo-reg number.
69818334Speter
699117395Skan   Return nonzero if the combiner has turned an indirect jump
70090075Sobrien   instruction into a direct jump.  */
701169689Skanstatic int
702132718Skancombine_instructions (rtx f, unsigned int nregs)
70318334Speter{
70490075Sobrien  rtx insn, next;
70550397Sobrien#ifdef HAVE_cc0
70690075Sobrien  rtx prev;
70750397Sobrien#endif
70890075Sobrien  int i;
709169689Skan  unsigned int j = 0;
71090075Sobrien  rtx links, nextlinks;
711169689Skan  sbitmap_iterator sbi;
71218334Speter
71390075Sobrien  int new_direct_jump_p = 0;
71490075Sobrien
71518334Speter  combine_attempts = 0;
71618334Speter  combine_merges = 0;
71718334Speter  combine_extras = 0;
71818334Speter  combine_successes = 0;
71918334Speter
72018334Speter  combine_max_regno = nregs;
72118334Speter
722169689Skan  rtl_hooks = combine_rtl_hooks;
72318334Speter
724169689Skan  reg_stat = XCNEWVEC (struct reg_stat, nregs);
72518334Speter
72618334Speter  init_recog_no_volatile ();
72718334Speter
72818334Speter  /* Compute maximum uid value so uid_cuid can be allocated.  */
72918334Speter
73018334Speter  for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
73118334Speter    if (INSN_UID (insn) > i)
73218334Speter      i = INSN_UID (insn);
73318334Speter
734169689Skan  uid_cuid = XNEWVEC (int, i + 1);
73518334Speter  max_uid_cuid = i;
73618334Speter
73718334Speter  nonzero_bits_mode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
73818334Speter
739169689Skan  /* Don't use reg_stat[].nonzero_bits when computing it.  This can cause
740169689Skan     problems when, for example, we have j <<= 1 in a loop.  */
74118334Speter
74218334Speter  nonzero_sign_valid = 0;
74318334Speter
74418334Speter  /* Compute the mapping from uids to cuids.
74518334Speter     Cuids are numbers assigned to insns, like uids,
74690075Sobrien     except that cuids increase monotonically through the code.
74718334Speter
74818334Speter     Scan all SETs and see if we can deduce anything about what
74918334Speter     bits are known to be zero for some registers and how many copies
75018334Speter     of the sign bit are known to exist for those registers.
75118334Speter
75218334Speter     Also set any known values so that we can use it while searching
75318334Speter     for what bits are known to be set.  */
75418334Speter
75518334Speter  label_tick = 1;
75618334Speter
75718334Speter  setup_incoming_promotions ();
75818334Speter
759117395Skan  refresh_blocks = sbitmap_alloc (last_basic_block);
76090075Sobrien  sbitmap_zero (refresh_blocks);
76190075Sobrien
762169689Skan  /* Allocate array of current insn_rtx_costs.  */
763169689Skan  uid_insn_cost = XCNEWVEC (int, max_uid_cuid + 1);
764169689Skan  last_insn_cost = max_uid_cuid;
765169689Skan
76618334Speter  for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
76718334Speter    {
76818334Speter      uid_cuid[INSN_UID (insn)] = ++i;
76918334Speter      subst_low_cuid = i;
77018334Speter      subst_insn = insn;
77118334Speter
77290075Sobrien      if (INSN_P (insn))
77318334Speter	{
77490075Sobrien	  note_stores (PATTERN (insn), set_nonzero_bits_and_sign_copies,
77590075Sobrien		       NULL);
77618334Speter	  record_dead_and_set_regs (insn);
77750397Sobrien
77850397Sobrien#ifdef AUTO_INC_DEC
77950397Sobrien	  for (links = REG_NOTES (insn); links; links = XEXP (links, 1))
78050397Sobrien	    if (REG_NOTE_KIND (links) == REG_INC)
78190075Sobrien	      set_nonzero_bits_and_sign_copies (XEXP (links, 0), NULL_RTX,
78290075Sobrien						NULL);
78350397Sobrien#endif
784169689Skan
785169689Skan	  /* Record the current insn_rtx_cost of this instruction.  */
786169689Skan	  if (NONJUMP_INSN_P (insn))
787169689Skan	    uid_insn_cost[INSN_UID (insn)] = insn_rtx_cost (PATTERN (insn));
788169689Skan	  if (dump_file)
789169689Skan	    fprintf(dump_file, "insn_cost %d: %d\n",
790169689Skan		    INSN_UID (insn), uid_insn_cost[INSN_UID (insn)]);
79118334Speter	}
79218334Speter
793169689Skan      if (LABEL_P (insn))
79418334Speter	label_tick++;
79518334Speter    }
79618334Speter
79718334Speter  nonzero_sign_valid = 1;
79818334Speter
79918334Speter  /* Now scan all the insns in forward order.  */
80018334Speter
80118334Speter  label_tick = 1;
80218334Speter  last_call_cuid = 0;
80318334Speter  mem_last_set = 0;
804169689Skan  init_reg_last ();
80518334Speter  setup_incoming_promotions ();
80618334Speter
807117395Skan  FOR_EACH_BB (this_basic_block)
80818334Speter    {
809132718Skan      for (insn = BB_HEAD (this_basic_block);
810169689Skan	   insn != NEXT_INSN (BB_END (this_basic_block));
811117395Skan	   insn = next ? next : NEXT_INSN (insn))
812117395Skan	{
813117395Skan	  next = 0;
81418334Speter
815169689Skan	  if (LABEL_P (insn))
816117395Skan	    label_tick++;
81718334Speter
818117395Skan	  else if (INSN_P (insn))
819117395Skan	    {
820117395Skan	      /* See if we know about function return values before this
821117395Skan		 insn based upon SUBREG flags.  */
822169689Skan	      check_conversions (insn, PATTERN (insn));
82318334Speter
824117395Skan	      /* Try this insn with each insn it links back to.  */
82590075Sobrien
826117395Skan	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
827117395Skan		if ((next = try_combine (insn, XEXP (links, 0),
828117395Skan					 NULL_RTX, &new_direct_jump_p)) != 0)
829117395Skan		  goto retry;
83018334Speter
831117395Skan	      /* Try each sequence of three linked insns ending with this one.  */
83218334Speter
833117395Skan	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
834117395Skan		{
835117395Skan		  rtx link = XEXP (links, 0);
83618334Speter
837117395Skan		  /* If the linked insn has been replaced by a note, then there
838117395Skan		     is no point in pursuing this chain any further.  */
839169689Skan		  if (NOTE_P (link))
840117395Skan		    continue;
84118334Speter
842117395Skan		  for (nextlinks = LOG_LINKS (link);
843117395Skan		       nextlinks;
844117395Skan		       nextlinks = XEXP (nextlinks, 1))
845117395Skan		    if ((next = try_combine (insn, link,
846117395Skan					     XEXP (nextlinks, 0),
847117395Skan					     &new_direct_jump_p)) != 0)
848117395Skan		      goto retry;
849117395Skan		}
85090075Sobrien
85118334Speter#ifdef HAVE_cc0
852117395Skan	      /* Try to combine a jump insn that uses CC0
853117395Skan		 with a preceding insn that sets CC0, and maybe with its
854117395Skan		 logical predecessor as well.
855117395Skan		 This is how we make decrement-and-branch insns.
856117395Skan		 We need this special code because data flow connections
857117395Skan		 via CC0 do not get entered in LOG_LINKS.  */
85818334Speter
859169689Skan	      if (JUMP_P (insn)
860117395Skan		  && (prev = prev_nonnote_insn (insn)) != 0
861169689Skan		  && NONJUMP_INSN_P (prev)
862117395Skan		  && sets_cc0_p (PATTERN (prev)))
863117395Skan		{
864117395Skan		  if ((next = try_combine (insn, prev,
865117395Skan					   NULL_RTX, &new_direct_jump_p)) != 0)
866117395Skan		    goto retry;
86718334Speter
868117395Skan		  for (nextlinks = LOG_LINKS (prev); nextlinks;
869117395Skan		       nextlinks = XEXP (nextlinks, 1))
870117395Skan		    if ((next = try_combine (insn, prev,
871117395Skan					     XEXP (nextlinks, 0),
872117395Skan					     &new_direct_jump_p)) != 0)
873117395Skan		      goto retry;
874117395Skan		}
87518334Speter
876117395Skan	      /* Do the same for an insn that explicitly references CC0.  */
877169689Skan	      if (NONJUMP_INSN_P (insn)
878117395Skan		  && (prev = prev_nonnote_insn (insn)) != 0
879169689Skan		  && NONJUMP_INSN_P (prev)
880117395Skan		  && sets_cc0_p (PATTERN (prev))
881117395Skan		  && GET_CODE (PATTERN (insn)) == SET
882117395Skan		  && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (insn))))
883117395Skan		{
884117395Skan		  if ((next = try_combine (insn, prev,
885117395Skan					   NULL_RTX, &new_direct_jump_p)) != 0)
886117395Skan		    goto retry;
88718334Speter
888117395Skan		  for (nextlinks = LOG_LINKS (prev); nextlinks;
889117395Skan		       nextlinks = XEXP (nextlinks, 1))
890117395Skan		    if ((next = try_combine (insn, prev,
891117395Skan					     XEXP (nextlinks, 0),
892117395Skan					     &new_direct_jump_p)) != 0)
893117395Skan		      goto retry;
894117395Skan		}
895117395Skan
896117395Skan	      /* Finally, see if any of the insns that this insn links to
897117395Skan		 explicitly references CC0.  If so, try this insn, that insn,
898117395Skan		 and its predecessor if it sets CC0.  */
899117395Skan	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
900169689Skan		if (NONJUMP_INSN_P (XEXP (links, 0))
901117395Skan		    && GET_CODE (PATTERN (XEXP (links, 0))) == SET
902117395Skan		    && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (XEXP (links, 0))))
903117395Skan		    && (prev = prev_nonnote_insn (XEXP (links, 0))) != 0
904169689Skan		    && NONJUMP_INSN_P (prev)
905117395Skan		    && sets_cc0_p (PATTERN (prev))
906117395Skan		    && (next = try_combine (insn, XEXP (links, 0),
907117395Skan					    prev, &new_direct_jump_p)) != 0)
90818334Speter		  goto retry;
90918334Speter#endif
91018334Speter
911117395Skan	      /* Try combining an insn with two different insns whose results it
912117395Skan		 uses.  */
913117395Skan	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
914117395Skan		for (nextlinks = XEXP (links, 1); nextlinks;
915117395Skan		     nextlinks = XEXP (nextlinks, 1))
916117395Skan		  if ((next = try_combine (insn, XEXP (links, 0),
917117395Skan					   XEXP (nextlinks, 0),
918117395Skan					   &new_direct_jump_p)) != 0)
919117395Skan		    goto retry;
92018334Speter
921169689Skan	      /* Try this insn with each REG_EQUAL note it links back to.  */
922169689Skan	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
923169689Skan		{
924169689Skan		  rtx set, note;
925169689Skan		  rtx temp = XEXP (links, 0);
926169689Skan		  if ((set = single_set (temp)) != 0
927169689Skan		      && (note = find_reg_equal_equiv_note (temp)) != 0
928169689Skan		      && (note = XEXP (note, 0), GET_CODE (note)) != EXPR_LIST
929169689Skan		      /* Avoid using a register that may already been marked
930169689Skan			 dead by an earlier instruction.  */
931169689Skan		      && ! unmentioned_reg_p (note, SET_SRC (set))
932169689Skan		      && (GET_MODE (note) == VOIDmode
933169689Skan			  ? SCALAR_INT_MODE_P (GET_MODE (SET_DEST (set)))
934169689Skan			  : GET_MODE (SET_DEST (set)) == GET_MODE (note)))
935169689Skan		    {
936169689Skan		      /* Temporarily replace the set's source with the
937169689Skan			 contents of the REG_EQUAL note.  The insn will
938169689Skan			 be deleted or recognized by try_combine.  */
939169689Skan		      rtx orig = SET_SRC (set);
940169689Skan		      SET_SRC (set) = note;
941169689Skan		      i2mod = temp;
942169689Skan		      i2mod_old_rhs = copy_rtx (orig);
943169689Skan		      i2mod_new_rhs = copy_rtx (note);
944169689Skan		      next = try_combine (insn, i2mod, NULL_RTX,
945169689Skan					  &new_direct_jump_p);
946169689Skan		      i2mod = NULL_RTX;
947169689Skan		      if (next)
948169689Skan			goto retry;
949169689Skan		      SET_SRC (set) = orig;
950169689Skan		    }
951169689Skan		}
952169689Skan
953169689Skan	      if (!NOTE_P (insn))
954117395Skan		record_dead_and_set_regs (insn);
95518334Speter
956117395Skan	    retry:
957117395Skan	      ;
958117395Skan	    }
95918334Speter	}
96018334Speter    }
961117395Skan  clear_bb_flags ();
96218334Speter
963169689Skan  EXECUTE_IF_SET_IN_SBITMAP (refresh_blocks, 0, j, sbi)
964169689Skan    BASIC_BLOCK (j)->flags |= BB_DIRTY;
965169689Skan  new_direct_jump_p |= purge_all_dead_edges ();
966169689Skan  delete_noop_moves ();
96790075Sobrien
968117395Skan  update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
969117395Skan				    PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
970117395Skan				    | PROP_KILL_DEAD_CODE);
97190075Sobrien
97290075Sobrien  /* Clean up.  */
97390075Sobrien  sbitmap_free (refresh_blocks);
974169689Skan  free (uid_insn_cost);
975169689Skan  free (reg_stat);
97690075Sobrien  free (uid_cuid);
97790075Sobrien
97890075Sobrien  {
97990075Sobrien    struct undo *undo, *next;
98090075Sobrien    for (undo = undobuf.frees; undo; undo = next)
98190075Sobrien      {
98290075Sobrien	next = undo->next;
98390075Sobrien	free (undo);
98490075Sobrien      }
98590075Sobrien    undobuf.frees = 0;
98690075Sobrien  }
98790075Sobrien
98818334Speter  total_attempts += combine_attempts;
98918334Speter  total_merges += combine_merges;
99018334Speter  total_extras += combine_extras;
99118334Speter  total_successes += combine_successes;
99218334Speter
99318334Speter  nonzero_sign_valid = 0;
994169689Skan  rtl_hooks = general_rtl_hooks;
99552284Sobrien
99652284Sobrien  /* Make recognizer allow volatile MEMs again.  */
99752284Sobrien  init_recog ();
99890075Sobrien
99990075Sobrien  return new_direct_jump_p;
100018334Speter}
100118334Speter
1002169689Skan/* Wipe the last_xxx fields of reg_stat in preparation for another pass.  */
100318334Speter
100418334Speterstatic void
1005169689Skaninit_reg_last (void)
100618334Speter{
1007169689Skan  unsigned int i;
1008169689Skan  for (i = 0; i < combine_max_regno; i++)
1009169689Skan    memset (reg_stat + i, 0, offsetof (struct reg_stat, sign_bit_copies));
101018334Speter}
101118334Speter
101218334Speter/* Set up any promoted values for incoming argument registers.  */
101318334Speter
101418334Speterstatic void
1015132718Skansetup_incoming_promotions (void)
101618334Speter{
101790075Sobrien  unsigned int regno;
101818334Speter  rtx reg;
101918334Speter  enum machine_mode mode;
102018334Speter  int unsignedp;
102118334Speter  rtx first = get_insns ();
102218334Speter
1023132718Skan  if (targetm.calls.promote_function_args (TREE_TYPE (cfun->decl)))
1024132718Skan    {
1025132718Skan      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1026132718Skan	/* Check whether this register can hold an incoming pointer
1027132718Skan	   argument.  FUNCTION_ARG_REGNO_P tests outgoing register
1028132718Skan	   numbers, so translate if necessary due to register windows.  */
1029132718Skan	if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (regno))
1030132718Skan	    && (reg = promoted_input_arg (regno, &mode, &unsignedp)) != 0)
1031132718Skan	  {
1032132718Skan	    record_value_for_reg
1033132718Skan	      (reg, first, gen_rtx_fmt_e ((unsignedp ? ZERO_EXTEND
1034132718Skan					   : SIGN_EXTEND),
1035132718Skan					  GET_MODE (reg),
1036132718Skan					  gen_rtx_CLOBBER (mode, const0_rtx)));
1037132718Skan	  }
1038132718Skan    }
103918334Speter}
104018334Speter
104150397Sobrien/* Called via note_stores.  If X is a pseudo that is narrower than
104250397Sobrien   HOST_BITS_PER_WIDE_INT and is being set, record what bits are known zero.
104318334Speter
104418334Speter   If we are setting only a portion of X and we can't figure out what
104518334Speter   portion, assume all bits will be used since we don't know what will
104618334Speter   be happening.
104718334Speter
104818334Speter   Similarly, set how many bits of X are known to be copies of the sign bit
104990075Sobrien   at all locations in the function.  This is the smallest number implied
105018334Speter   by any set of X.  */
105118334Speter
105218334Speterstatic void
1053132718Skanset_nonzero_bits_and_sign_copies (rtx x, rtx set,
1054132718Skan				  void *data ATTRIBUTE_UNUSED)
105518334Speter{
105690075Sobrien  unsigned int num;
105718334Speter
1058169689Skan  if (REG_P (x)
105918334Speter      && REGNO (x) >= FIRST_PSEUDO_REGISTER
106018334Speter      /* If this register is undefined at the start of the file, we can't
106118334Speter	 say what its contents were.  */
1062169689Skan      && ! REGNO_REG_SET_P
1063169689Skan	 (ENTRY_BLOCK_PTR->next_bb->il.rtl->global_live_at_start, REGNO (x))
106418334Speter      && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
106518334Speter    {
106650397Sobrien      if (set == 0 || GET_CODE (set) == CLOBBER)
106718334Speter	{
1068169689Skan	  reg_stat[REGNO (x)].nonzero_bits = GET_MODE_MASK (GET_MODE (x));
1069169689Skan	  reg_stat[REGNO (x)].sign_bit_copies = 1;
107018334Speter	  return;
107118334Speter	}
107218334Speter
107318334Speter      /* If this is a complex assignment, see if we can convert it into a
107418334Speter	 simple assignment.  */
107518334Speter      set = expand_field_assignment (set);
107618334Speter
107718334Speter      /* If this is a simple assignment, or we have a paradoxical SUBREG,
107818334Speter	 set what we know about X.  */
107918334Speter
108018334Speter      if (SET_DEST (set) == x
108118334Speter	  || (GET_CODE (SET_DEST (set)) == SUBREG
108218334Speter	      && (GET_MODE_SIZE (GET_MODE (SET_DEST (set)))
108318334Speter		  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (set)))))
108418334Speter	      && SUBREG_REG (SET_DEST (set)) == x))
108518334Speter	{
108618334Speter	  rtx src = SET_SRC (set);
108718334Speter
108818334Speter#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
108918334Speter	  /* If X is narrower than a word and SRC is a non-negative
109018334Speter	     constant that would appear negative in the mode of X,
1091169689Skan	     sign-extend it for use in reg_stat[].nonzero_bits because some
109218334Speter	     machines (maybe most) will actually do the sign-extension
109390075Sobrien	     and this is the conservative approach.
109418334Speter
109518334Speter	     ??? For 2.5, try to tighten up the MD files in this regard
109618334Speter	     instead of this kludge.  */
109718334Speter
109818334Speter	  if (GET_MODE_BITSIZE (GET_MODE (x)) < BITS_PER_WORD
109918334Speter	      && GET_CODE (src) == CONST_INT
110018334Speter	      && INTVAL (src) > 0
110118334Speter	      && 0 != (INTVAL (src)
110218334Speter		       & ((HOST_WIDE_INT) 1
110318334Speter			  << (GET_MODE_BITSIZE (GET_MODE (x)) - 1))))
110418334Speter	    src = GEN_INT (INTVAL (src)
110518334Speter			   | ((HOST_WIDE_INT) (-1)
110618334Speter			      << GET_MODE_BITSIZE (GET_MODE (x))));
110718334Speter#endif
110818334Speter
110996263Sobrien	  /* Don't call nonzero_bits if it cannot change anything.  */
1110169689Skan	  if (reg_stat[REGNO (x)].nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
1111169689Skan	    reg_stat[REGNO (x)].nonzero_bits
111296263Sobrien	      |= nonzero_bits (src, nonzero_bits_mode);
111318334Speter	  num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
1114169689Skan	  if (reg_stat[REGNO (x)].sign_bit_copies == 0
1115169689Skan	      || reg_stat[REGNO (x)].sign_bit_copies > num)
1116169689Skan	    reg_stat[REGNO (x)].sign_bit_copies = num;
111718334Speter	}
111818334Speter      else
111918334Speter	{
1120169689Skan	  reg_stat[REGNO (x)].nonzero_bits = GET_MODE_MASK (GET_MODE (x));
1121169689Skan	  reg_stat[REGNO (x)].sign_bit_copies = 1;
112218334Speter	}
112318334Speter    }
112418334Speter}
112518334Speter
112618334Speter/* See if INSN can be combined into I3.  PRED and SUCC are optionally
112718334Speter   insns that were previously combined into I3 or that will be combined
112818334Speter   into the merger of INSN and I3.
112918334Speter
113018334Speter   Return 0 if the combination is not allowed for any reason.
113118334Speter
113290075Sobrien   If the combination is allowed, *PDEST will be set to the single
113318334Speter   destination of INSN and *PSRC to the single source, and this function
113418334Speter   will return 1.  */
113518334Speter
113618334Speterstatic int
1137132718Skancan_combine_p (rtx insn, rtx i3, rtx pred ATTRIBUTE_UNUSED, rtx succ,
1138132718Skan	       rtx *pdest, rtx *psrc)
113918334Speter{
114018334Speter  int i;
114118334Speter  rtx set = 0, src, dest;
114250397Sobrien  rtx p;
114350397Sobrien#ifdef AUTO_INC_DEC
114450397Sobrien  rtx link;
114550397Sobrien#endif
114618334Speter  int all_adjacent = (succ ? (next_active_insn (insn) == succ
114718334Speter			      && next_active_insn (succ) == i3)
114818334Speter		      : next_active_insn (insn) == i3);
114918334Speter
115018334Speter  /* Can combine only if previous insn is a SET of a REG, a SUBREG or CC0.
115190075Sobrien     or a PARALLEL consisting of such a SET and CLOBBERs.
115218334Speter
115318334Speter     If INSN has CLOBBER parallel parts, ignore them for our processing.
115418334Speter     By definition, these happen during the execution of the insn.  When it
115518334Speter     is merged with another insn, all bets are off.  If they are, in fact,
115618334Speter     needed and aren't also supplied in I3, they may be added by
115790075Sobrien     recog_for_combine.  Otherwise, it won't match.
115818334Speter
115918334Speter     We can also ignore a SET whose SET_DEST is mentioned in a REG_UNUSED
116018334Speter     note.
116118334Speter
116290075Sobrien     Get the source and destination of INSN.  If more than one, can't
116318334Speter     combine.  */
116490075Sobrien
116518334Speter  if (GET_CODE (PATTERN (insn)) == SET)
116618334Speter    set = PATTERN (insn);
116718334Speter  else if (GET_CODE (PATTERN (insn)) == PARALLEL
116818334Speter	   && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
116918334Speter    {
117018334Speter      for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
117118334Speter	{
117218334Speter	  rtx elt = XVECEXP (PATTERN (insn), 0, i);
1173132718Skan	  rtx note;
117418334Speter
117518334Speter	  switch (GET_CODE (elt))
117618334Speter	    {
117750397Sobrien	    /* This is important to combine floating point insns
117850397Sobrien	       for the SH4 port.  */
117950397Sobrien	    case USE:
118050397Sobrien	      /* Combining an isolated USE doesn't make sense.
118190075Sobrien		 We depend here on combinable_i3pat to reject them.  */
118250397Sobrien	      /* The code below this loop only verifies that the inputs of
118350397Sobrien		 the SET in INSN do not change.  We call reg_set_between_p
118490075Sobrien		 to verify that the REG in the USE does not change between
118550397Sobrien		 I3 and INSN.
118650397Sobrien		 If the USE in INSN was for a pseudo register, the matching
118750397Sobrien		 insn pattern will likely match any register; combining this
118850397Sobrien		 with any other USE would only be safe if we knew that the
118950397Sobrien		 used registers have identical values, or if there was
119050397Sobrien		 something to tell them apart, e.g. different modes.  For
119190075Sobrien		 now, we forgo such complicated tests and simply disallow
119250397Sobrien		 combining of USES of pseudo registers with any other USE.  */
1193169689Skan	      if (REG_P (XEXP (elt, 0))
119450397Sobrien		  && GET_CODE (PATTERN (i3)) == PARALLEL)
119550397Sobrien		{
119650397Sobrien		  rtx i3pat = PATTERN (i3);
119750397Sobrien		  int i = XVECLEN (i3pat, 0) - 1;
119890075Sobrien		  unsigned int regno = REGNO (XEXP (elt, 0));
119990075Sobrien
120050397Sobrien		  do
120150397Sobrien		    {
120250397Sobrien		      rtx i3elt = XVECEXP (i3pat, 0, i);
120390075Sobrien
120450397Sobrien		      if (GET_CODE (i3elt) == USE
1205169689Skan			  && REG_P (XEXP (i3elt, 0))
120650397Sobrien			  && (REGNO (XEXP (i3elt, 0)) == regno
120750397Sobrien			      ? reg_set_between_p (XEXP (elt, 0),
120850397Sobrien						   PREV_INSN (insn), i3)
120950397Sobrien			      : regno >= FIRST_PSEUDO_REGISTER))
121050397Sobrien			return 0;
121150397Sobrien		    }
121250397Sobrien		  while (--i >= 0);
121350397Sobrien		}
121450397Sobrien	      break;
121550397Sobrien
121618334Speter	      /* We can ignore CLOBBERs.  */
121718334Speter	    case CLOBBER:
121818334Speter	      break;
121918334Speter
122018334Speter	    case SET:
122118334Speter	      /* Ignore SETs whose result isn't used but not those that
122218334Speter		 have side-effects.  */
122318334Speter	      if (find_reg_note (insn, REG_UNUSED, SET_DEST (elt))
1224132718Skan		  && (!(note = find_reg_note (insn, REG_EH_REGION, NULL_RTX))
1225132718Skan		      || INTVAL (XEXP (note, 0)) <= 0)
122618334Speter		  && ! side_effects_p (elt))
122718334Speter		break;
122818334Speter
122918334Speter	      /* If we have already found a SET, this is a second one and
123018334Speter		 so we cannot combine with this insn.  */
123118334Speter	      if (set)
123218334Speter		return 0;
123318334Speter
123418334Speter	      set = elt;
123518334Speter	      break;
123618334Speter
123718334Speter	    default:
123818334Speter	      /* Anything else means we can't combine.  */
123918334Speter	      return 0;
124018334Speter	    }
124118334Speter	}
124218334Speter
124318334Speter      if (set == 0
124418334Speter	  /* If SET_SRC is an ASM_OPERANDS we can't throw away these CLOBBERs,
124518334Speter	     so don't do anything with it.  */
124618334Speter	  || GET_CODE (SET_SRC (set)) == ASM_OPERANDS)
124718334Speter	return 0;
124818334Speter    }
124918334Speter  else
125018334Speter    return 0;
125118334Speter
125218334Speter  if (set == 0)
125318334Speter    return 0;
125418334Speter
125518334Speter  set = expand_field_assignment (set);
125618334Speter  src = SET_SRC (set), dest = SET_DEST (set);
125718334Speter
125818334Speter  /* Don't eliminate a store in the stack pointer.  */
125918334Speter  if (dest == stack_pointer_rtx
126018334Speter      /* Don't combine with an insn that sets a register to itself if it has
126118334Speter	 a REG_EQUAL note.  This may be part of a REG_NO_CONFLICT sequence.  */
126218334Speter      || (rtx_equal_p (src, dest) && find_reg_note (insn, REG_EQUAL, NULL_RTX))
126390075Sobrien      /* Can't merge an ASM_OPERANDS.  */
126490075Sobrien      || GET_CODE (src) == ASM_OPERANDS
126518334Speter      /* Can't merge a function call.  */
126618334Speter      || GET_CODE (src) == CALL
126718334Speter      /* Don't eliminate a function call argument.  */
1268169689Skan      || (CALL_P (i3)
126918334Speter	  && (find_reg_fusage (i3, USE, dest)
1270169689Skan	      || (REG_P (dest)
127118334Speter		  && REGNO (dest) < FIRST_PSEUDO_REGISTER
127218334Speter		  && global_regs[REGNO (dest)])))
127318334Speter      /* Don't substitute into an incremented register.  */
127418334Speter      || FIND_REG_INC_NOTE (i3, dest)
127518334Speter      || (succ && FIND_REG_INC_NOTE (succ, dest))
1276169689Skan      /* Don't substitute into a non-local goto, this confuses CFG.  */
1277169689Skan      || (JUMP_P (i3) && find_reg_note (i3, REG_NON_LOCAL_GOTO, NULL_RTX))
127852284Sobrien#if 0
127918334Speter      /* Don't combine the end of a libcall into anything.  */
128052284Sobrien      /* ??? This gives worse code, and appears to be unnecessary, since no
128152284Sobrien	 pass after flow uses REG_LIBCALL/REG_RETVAL notes.  Local-alloc does
128252284Sobrien	 use REG_RETVAL notes for noconflict blocks, but other code here
128352284Sobrien	 makes sure that those insns don't disappear.  */
128418334Speter      || find_reg_note (insn, REG_RETVAL, NULL_RTX)
128552284Sobrien#endif
128618334Speter      /* Make sure that DEST is not used after SUCC but before I3.  */
128718334Speter      || (succ && ! all_adjacent
128818334Speter	  && reg_used_between_p (dest, succ, i3))
128918334Speter      /* Make sure that the value that is to be substituted for the register
129018334Speter	 does not use any registers whose values alter in between.  However,
129118334Speter	 If the insns are adjacent, a use can't cross a set even though we
129218334Speter	 think it might (this can happen for a sequence of insns each setting
1293169689Skan	 the same destination; last_set of that register might point to
129418334Speter	 a NOTE).  If INSN has a REG_EQUIV note, the register is always
129518334Speter	 equivalent to the memory so the substitution is valid even if there
129618334Speter	 are intervening stores.  Also, don't move a volatile asm or
129718334Speter	 UNSPEC_VOLATILE across any other insns.  */
129818334Speter      || (! all_adjacent
1299169689Skan	  && (((!MEM_P (src)
130018334Speter		|| ! find_reg_note (insn, REG_EQUIV, src))
130118334Speter	       && use_crosses_set_p (src, INSN_CUID (insn)))
130218334Speter	      || (GET_CODE (src) == ASM_OPERANDS && MEM_VOLATILE_P (src))
130318334Speter	      || GET_CODE (src) == UNSPEC_VOLATILE))
130418334Speter      /* If there is a REG_NO_CONFLICT note for DEST in I3 or SUCC, we get
130518334Speter	 better register allocation by not doing the combine.  */
130618334Speter      || find_reg_note (i3, REG_NO_CONFLICT, dest)
130718334Speter      || (succ && find_reg_note (succ, REG_NO_CONFLICT, dest))
130818334Speter      /* Don't combine across a CALL_INSN, because that would possibly
130918334Speter	 change whether the life span of some REGs crosses calls or not,
131018334Speter	 and it is a pain to update that information.
131118334Speter	 Exception: if source is a constant, moving it later can't hurt.
131218334Speter	 Accept that special case, because it helps -fforce-addr a lot.  */
131318334Speter      || (INSN_CUID (insn) < last_call_cuid && ! CONSTANT_P (src)))
131418334Speter    return 0;
131518334Speter
131618334Speter  /* DEST must either be a REG or CC0.  */
1317169689Skan  if (REG_P (dest))
131818334Speter    {
131918334Speter      /* If register alignment is being enforced for multi-word items in all
132018334Speter	 cases except for parameters, it is possible to have a register copy
132118334Speter	 insn referencing a hard register that is not allowed to contain the
132218334Speter	 mode being copied and which would not be valid as an operand of most
132318334Speter	 insns.  Eliminate this problem by not combining with such an insn.
132418334Speter
132518334Speter	 Also, on some machines we don't want to extend the life of a hard
132690075Sobrien	 register.  */
132718334Speter
1328169689Skan      if (REG_P (src)
132918334Speter	  && ((REGNO (dest) < FIRST_PSEUDO_REGISTER
133018334Speter	       && ! HARD_REGNO_MODE_OK (REGNO (dest), GET_MODE (dest)))
133118334Speter	      /* Don't extend the life of a hard register unless it is
133218334Speter		 user variable (if we have few registers) or it can't
133318334Speter		 fit into the desired register (meaning something special
133450397Sobrien		 is going on).
133550397Sobrien		 Also avoid substituting a return register into I3, because
133650397Sobrien		 reload can't handle a conflict with constraints of other
133750397Sobrien		 inputs.  */
133818334Speter	      || (REGNO (src) < FIRST_PSEUDO_REGISTER
133990075Sobrien		  && ! HARD_REGNO_MODE_OK (REGNO (src), GET_MODE (src)))))
134018334Speter	return 0;
134118334Speter    }
134218334Speter  else if (GET_CODE (dest) != CC0)
134318334Speter    return 0;
134418334Speter
1345169689Skan
134618334Speter  if (GET_CODE (PATTERN (i3)) == PARALLEL)
134718334Speter    for (i = XVECLEN (PATTERN (i3), 0) - 1; i >= 0; i--)
1348169689Skan      if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER)
1349169689Skan	{
1350169689Skan	  /* Don't substitute for a register intended as a clobberable
1351169689Skan	     operand.  */
1352169689Skan	  rtx reg = XEXP (XVECEXP (PATTERN (i3), 0, i), 0);
1353169689Skan	  if (rtx_equal_p (reg, dest))
1354169689Skan	    return 0;
135518334Speter
1356169689Skan	  /* If the clobber represents an earlyclobber operand, we must not
1357169689Skan	     substitute an expression containing the clobbered register.
1358169689Skan	     As we do not analyze the constraint strings here, we have to
1359169689Skan	     make the conservative assumption.  However, if the register is
1360169689Skan	     a fixed hard reg, the clobber cannot represent any operand;
1361169689Skan	     we leave it up to the machine description to either accept or
1362169689Skan	     reject use-and-clobber patterns.  */
1363169689Skan	  if (!REG_P (reg)
1364169689Skan	      || REGNO (reg) >= FIRST_PSEUDO_REGISTER
1365169689Skan	      || !fixed_regs[REGNO (reg)])
1366169689Skan	    if (reg_overlap_mentioned_p (reg, src))
1367169689Skan	      return 0;
1368169689Skan	}
1369169689Skan
137018334Speter  /* If INSN contains anything volatile, or is an `asm' (whether volatile
137150397Sobrien     or not), reject, unless nothing volatile comes between it and I3 */
137218334Speter
137318334Speter  if (GET_CODE (src) == ASM_OPERANDS || volatile_refs_p (src))
137450397Sobrien    {
137550397Sobrien      /* Make sure succ doesn't contain a volatile reference.  */
137650397Sobrien      if (succ != 0 && volatile_refs_p (PATTERN (succ)))
1377169689Skan	return 0;
137890075Sobrien
137950397Sobrien      for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p))
1380169689Skan	if (INSN_P (p) && p != succ && volatile_refs_p (PATTERN (p)))
138190075Sobrien	  return 0;
138250397Sobrien    }
138318334Speter
138450397Sobrien  /* If INSN is an asm, and DEST is a hard register, reject, since it has
138550397Sobrien     to be an explicit register variable, and was chosen for a reason.  */
138650397Sobrien
138750397Sobrien  if (GET_CODE (src) == ASM_OPERANDS
1388169689Skan      && REG_P (dest) && REGNO (dest) < FIRST_PSEUDO_REGISTER)
138950397Sobrien    return 0;
139050397Sobrien
139118334Speter  /* If there are any volatile insns between INSN and I3, reject, because
139218334Speter     they might affect machine state.  */
139318334Speter
139418334Speter  for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p))
139590075Sobrien    if (INSN_P (p) && p != succ && volatile_insn_p (PATTERN (p)))
139618334Speter      return 0;
139718334Speter
1398169689Skan  /* If INSN contains an autoincrement or autodecrement, make sure that
1399169689Skan     register is not used between there and I3, and not already used in
1400169689Skan     I3 either.  Neither must it be used in PRED or SUCC, if they exist.
140118334Speter     Also insist that I3 not be a jump; if it were one
140218334Speter     and the incremented register were spilled, we would lose.  */
140318334Speter
140418334Speter#ifdef AUTO_INC_DEC
140518334Speter  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
140618334Speter    if (REG_NOTE_KIND (link) == REG_INC
1407169689Skan	&& (JUMP_P (i3)
140818334Speter	    || reg_used_between_p (XEXP (link, 0), insn, i3)
1409169689Skan	    || (pred != NULL_RTX
1410169689Skan		&& reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (pred)))
1411169689Skan	    || (succ != NULL_RTX
1412169689Skan		&& reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (succ)))
141318334Speter	    || reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i3))))
141418334Speter      return 0;
141518334Speter#endif
141618334Speter
141718334Speter#ifdef HAVE_cc0
141818334Speter  /* Don't combine an insn that follows a CC0-setting insn.
141918334Speter     An insn that uses CC0 must not be separated from the one that sets it.
142018334Speter     We do, however, allow I2 to follow a CC0-setting insn if that insn
142118334Speter     is passed as I1; in that case it will be deleted also.
142218334Speter     We also allow combining in this case if all the insns are adjacent
142318334Speter     because that would leave the two CC0 insns adjacent as well.
142418334Speter     It would be more logical to test whether CC0 occurs inside I1 or I2,
142518334Speter     but that would be much slower, and this ought to be equivalent.  */
142618334Speter
142718334Speter  p = prev_nonnote_insn (insn);
1428169689Skan  if (p && p != pred && NONJUMP_INSN_P (p) && sets_cc0_p (PATTERN (p))
142918334Speter      && ! all_adjacent)
143018334Speter    return 0;
143118334Speter#endif
143218334Speter
143318334Speter  /* If we get here, we have passed all the tests and the combination is
143418334Speter     to be allowed.  */
143518334Speter
143618334Speter  *pdest = dest;
143718334Speter  *psrc = src;
143818334Speter
143918334Speter  return 1;
144018334Speter}
144118334Speter
144218334Speter/* LOC is the location within I3 that contains its pattern or the component
144318334Speter   of a PARALLEL of the pattern.  We validate that it is valid for combining.
144418334Speter
144518334Speter   One problem is if I3 modifies its output, as opposed to replacing it
144618334Speter   entirely, we can't allow the output to contain I2DEST or I1DEST as doing
144718334Speter   so would produce an insn that is not equivalent to the original insns.
144818334Speter
144918334Speter   Consider:
145018334Speter
1451169689Skan	 (set (reg:DI 101) (reg:DI 100))
145218334Speter	 (set (subreg:SI (reg:DI 101) 0) <foo>)
145318334Speter
145418334Speter   This is NOT equivalent to:
145518334Speter
1456169689Skan	 (parallel [(set (subreg:SI (reg:DI 100) 0) <foo>)
145790075Sobrien		    (set (reg:DI 101) (reg:DI 100))])
145818334Speter
145918334Speter   Not only does this modify 100 (in which case it might still be valid
146090075Sobrien   if 100 were dead in I2), it sets 101 to the ORIGINAL value of 100.
146118334Speter
146218334Speter   We can also run into a problem if I2 sets a register that I1
146318334Speter   uses and I1 gets directly substituted into I3 (not via I2).  In that
146418334Speter   case, we would be getting the wrong value of I2DEST into I3, so we
146518334Speter   must reject the combination.  This case occurs when I2 and I1 both
146618334Speter   feed into I3, rather than when I1 feeds into I2, which feeds into I3.
1467117395Skan   If I1_NOT_IN_SRC is nonzero, it means that finding I1 in the source
146818334Speter   of a SET must prevent combination from occurring.
146918334Speter
147018334Speter   Before doing the above check, we first try to expand a field assignment
147118334Speter   into a set of logical operations.
147218334Speter
1473117395Skan   If PI3_DEST_KILLED is nonzero, it is a pointer to a location in which
147418334Speter   we place a register that is both set and used within I3.  If more than one
147518334Speter   such register is detected, we fail.
147618334Speter
147718334Speter   Return 1 if the combination is valid, zero otherwise.  */
147818334Speter
147918334Speterstatic int
1480132718Skancombinable_i3pat (rtx i3, rtx *loc, rtx i2dest, rtx i1dest,
1481132718Skan		  int i1_not_in_src, rtx *pi3dest_killed)
148218334Speter{
148318334Speter  rtx x = *loc;
148418334Speter
148518334Speter  if (GET_CODE (x) == SET)
148618334Speter    {
1487132718Skan      rtx set = x ;
148818334Speter      rtx dest = SET_DEST (set);
148918334Speter      rtx src = SET_SRC (set);
149050397Sobrien      rtx inner_dest = dest;
1491169689Skan      rtx subdest;
149290075Sobrien
149318334Speter      while (GET_CODE (inner_dest) == STRICT_LOW_PART
149418334Speter	     || GET_CODE (inner_dest) == SUBREG
149518334Speter	     || GET_CODE (inner_dest) == ZERO_EXTRACT)
149618334Speter	inner_dest = XEXP (inner_dest, 0);
149718334Speter
1498132718Skan      /* Check for the case where I3 modifies its output, as discussed
1499132718Skan	 above.  We don't want to prevent pseudos from being combined
1500132718Skan	 into the address of a MEM, so only prevent the combination if
1501132718Skan	 i1 or i2 set the same MEM.  */
1502132718Skan      if ((inner_dest != dest &&
1503169689Skan	   (!MEM_P (inner_dest)
1504132718Skan	    || rtx_equal_p (i2dest, inner_dest)
1505132718Skan	    || (i1dest && rtx_equal_p (i1dest, inner_dest)))
150618334Speter	   && (reg_overlap_mentioned_p (i2dest, inner_dest)
150718334Speter	       || (i1dest && reg_overlap_mentioned_p (i1dest, inner_dest))))
150850397Sobrien
150990075Sobrien	  /* This is the same test done in can_combine_p except we can't test
151090075Sobrien	     all_adjacent; we don't have to, since this instruction will stay
151190075Sobrien	     in place, thus we are not considering increasing the lifetime of
151290075Sobrien	     INNER_DEST.
151350397Sobrien
151450397Sobrien	     Also, if this insn sets a function argument, combining it with
151550397Sobrien	     something that might need a spill could clobber a previous
151650397Sobrien	     function argument; the all_adjacent test in can_combine_p also
151750397Sobrien	     checks this; here, we do a more specific test for this case.  */
151890075Sobrien
1519169689Skan	  || (REG_P (inner_dest)
152018334Speter	      && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER
152118334Speter	      && (! HARD_REGNO_MODE_OK (REGNO (inner_dest),
152290075Sobrien					GET_MODE (inner_dest))))
152318334Speter	  || (i1_not_in_src && reg_overlap_mentioned_p (i1dest, src)))
152418334Speter	return 0;
152518334Speter
1526169689Skan      /* If DEST is used in I3, it is being killed in this insn, so
1527169689Skan	 record that for later.  We have to consider paradoxical
1528169689Skan	 subregs here, since they kill the whole register, but we
1529169689Skan	 ignore partial subregs, STRICT_LOW_PART, etc.
153018334Speter	 Never add REG_DEAD notes for the FRAME_POINTER_REGNUM or the
153118334Speter	 STACK_POINTER_REGNUM, since these are always considered to be
153218334Speter	 live.  Similarly for ARG_POINTER_REGNUM if it is fixed.  */
1533169689Skan      subdest = dest;
1534169689Skan      if (GET_CODE (subdest) == SUBREG
1535169689Skan	  && (GET_MODE_SIZE (GET_MODE (subdest))
1536169689Skan	      >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (subdest)))))
1537169689Skan	subdest = SUBREG_REG (subdest);
1538169689Skan      if (pi3dest_killed
1539169689Skan	  && REG_P (subdest)
1540169689Skan	  && reg_referenced_p (subdest, PATTERN (i3))
1541169689Skan	  && REGNO (subdest) != FRAME_POINTER_REGNUM
154218334Speter#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
1543169689Skan	  && REGNO (subdest) != HARD_FRAME_POINTER_REGNUM
154418334Speter#endif
154518334Speter#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
1546169689Skan	  && (REGNO (subdest) != ARG_POINTER_REGNUM
1547169689Skan	      || ! fixed_regs [REGNO (subdest)])
154818334Speter#endif
1549169689Skan	  && REGNO (subdest) != STACK_POINTER_REGNUM)
155018334Speter	{
155118334Speter	  if (*pi3dest_killed)
155218334Speter	    return 0;
155318334Speter
1554169689Skan	  *pi3dest_killed = subdest;
155518334Speter	}
155618334Speter    }
155718334Speter
155818334Speter  else if (GET_CODE (x) == PARALLEL)
155918334Speter    {
156018334Speter      int i;
156118334Speter
156218334Speter      for (i = 0; i < XVECLEN (x, 0); i++)
156318334Speter	if (! combinable_i3pat (i3, &XVECEXP (x, 0, i), i2dest, i1dest,
156418334Speter				i1_not_in_src, pi3dest_killed))
156518334Speter	  return 0;
156618334Speter    }
156718334Speter
156818334Speter  return 1;
156918334Speter}
157018334Speter
157190075Sobrien/* Return 1 if X is an arithmetic expression that contains a multiplication
157290075Sobrien   and division.  We don't count multiplications by powers of two here.  */
157390075Sobrien
157490075Sobrienstatic int
1575132718Skancontains_muldiv (rtx x)
157690075Sobrien{
157790075Sobrien  switch (GET_CODE (x))
157890075Sobrien    {
157990075Sobrien    case MOD:  case DIV:  case UMOD:  case UDIV:
158090075Sobrien      return 1;
158190075Sobrien
158290075Sobrien    case MULT:
158390075Sobrien      return ! (GET_CODE (XEXP (x, 1)) == CONST_INT
158490075Sobrien		&& exact_log2 (INTVAL (XEXP (x, 1))) >= 0);
158590075Sobrien    default:
1586169689Skan      if (BINARY_P (x))
1587169689Skan	return contains_muldiv (XEXP (x, 0))
158890075Sobrien	    || contains_muldiv (XEXP (x, 1));
158990075Sobrien
1590169689Skan      if (UNARY_P (x))
1591169689Skan	return contains_muldiv (XEXP (x, 0));
159290075Sobrien
1593169689Skan      return 0;
159490075Sobrien    }
159590075Sobrien}
159690075Sobrien
159770635Sobrien/* Determine whether INSN can be used in a combination.  Return nonzero if
159870635Sobrien   not.  This is used in try_combine to detect early some cases where we
159970635Sobrien   can't perform combinations.  */
160070635Sobrien
160170635Sobrienstatic int
1602132718Skancant_combine_insn_p (rtx insn)
160370635Sobrien{
160470635Sobrien  rtx set;
160570635Sobrien  rtx src, dest;
160690075Sobrien
160770635Sobrien  /* If this isn't really an insn, we can't do anything.
160870635Sobrien     This can occur when flow deletes an insn that it has merged into an
160970635Sobrien     auto-increment address.  */
161090075Sobrien  if (! INSN_P (insn))
161170635Sobrien    return 1;
161270635Sobrien
1613132718Skan  /* Never combine loads and stores involving hard regs that are likely
1614132718Skan     to be spilled.  The register allocator can usually handle such
1615132718Skan     reg-reg moves by tying.  If we allow the combiner to make
1616169689Skan     substitutions of likely-spilled regs, reload might die.
161770635Sobrien     As an exception, we allow combinations involving fixed regs; these are
161870635Sobrien     not available to the register allocator so there's no risk involved.  */
161970635Sobrien
162070635Sobrien  set = single_set (insn);
162170635Sobrien  if (! set)
162270635Sobrien    return 0;
162370635Sobrien  src = SET_SRC (set);
162470635Sobrien  dest = SET_DEST (set);
162570635Sobrien  if (GET_CODE (src) == SUBREG)
162670635Sobrien    src = SUBREG_REG (src);
162770635Sobrien  if (GET_CODE (dest) == SUBREG)
162870635Sobrien    dest = SUBREG_REG (dest);
162970635Sobrien  if (REG_P (src) && REG_P (dest)
163070635Sobrien      && ((REGNO (src) < FIRST_PSEUDO_REGISTER
1631132718Skan	   && ! fixed_regs[REGNO (src)]
1632132718Skan	   && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (src))))
163370635Sobrien	  || (REGNO (dest) < FIRST_PSEUDO_REGISTER
1634132718Skan	      && ! fixed_regs[REGNO (dest)]
1635132718Skan	      && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (dest))))))
163670635Sobrien    return 1;
163770635Sobrien
163870635Sobrien  return 0;
163970635Sobrien}
164070635Sobrien
1641169689Skanstruct likely_spilled_retval_info
1642169689Skan{
1643169689Skan  unsigned regno, nregs;
1644169689Skan  unsigned mask;
1645169689Skan};
1646169689Skan
1647169689Skan/* Called via note_stores by likely_spilled_retval_p.  Remove from info->mask
1648169689Skan   hard registers that are known to be written to / clobbered in full.  */
1649169689Skanstatic void
1650169689Skanlikely_spilled_retval_1 (rtx x, rtx set, void *data)
1651169689Skan{
1652169689Skan  struct likely_spilled_retval_info *info = data;
1653169689Skan  unsigned regno, nregs;
1654169689Skan  unsigned new_mask;
1655169689Skan
1656169689Skan  if (!REG_P (XEXP (set, 0)))
1657169689Skan    return;
1658169689Skan  regno = REGNO (x);
1659169689Skan  if (regno >= info->regno + info->nregs)
1660169689Skan    return;
1661169689Skan  nregs = hard_regno_nregs[regno][GET_MODE (x)];
1662169689Skan  if (regno + nregs <= info->regno)
1663169689Skan    return;
1664169689Skan  new_mask = (2U << (nregs - 1)) - 1;
1665169689Skan  if (regno < info->regno)
1666169689Skan    new_mask >>= info->regno - regno;
1667169689Skan  else
1668169689Skan    new_mask <<= regno - info->regno;
1669169689Skan  info->mask &= new_mask;
1670169689Skan}
1671169689Skan
1672169689Skan/* Return nonzero iff part of the return value is live during INSN, and
1673169689Skan   it is likely spilled.  This can happen when more than one insn is needed
1674169689Skan   to copy the return value, e.g. when we consider to combine into the
1675169689Skan   second copy insn for a complex value.  */
1676169689Skan
1677169689Skanstatic int
1678169689Skanlikely_spilled_retval_p (rtx insn)
1679169689Skan{
1680169689Skan  rtx use = BB_END (this_basic_block);
1681169689Skan  rtx reg, p;
1682169689Skan  unsigned regno, nregs;
1683169689Skan  /* We assume here that no machine mode needs more than
1684169689Skan     32 hard registers when the value overlaps with a register
1685169689Skan     for which FUNCTION_VALUE_REGNO_P is true.  */
1686169689Skan  unsigned mask;
1687169689Skan  struct likely_spilled_retval_info info;
1688169689Skan
1689169689Skan  if (!NONJUMP_INSN_P (use) || GET_CODE (PATTERN (use)) != USE || insn == use)
1690169689Skan    return 0;
1691169689Skan  reg = XEXP (PATTERN (use), 0);
1692169689Skan  if (!REG_P (reg) || !FUNCTION_VALUE_REGNO_P (REGNO (reg)))
1693169689Skan    return 0;
1694169689Skan  regno = REGNO (reg);
1695169689Skan  nregs = hard_regno_nregs[regno][GET_MODE (reg)];
1696169689Skan  if (nregs == 1)
1697169689Skan    return 0;
1698169689Skan  mask = (2U << (nregs - 1)) - 1;
1699169689Skan
1700169689Skan  /* Disregard parts of the return value that are set later.  */
1701169689Skan  info.regno = regno;
1702169689Skan  info.nregs = nregs;
1703169689Skan  info.mask = mask;
1704169689Skan  for (p = PREV_INSN (use); info.mask && p != insn; p = PREV_INSN (p))
1705169689Skan    note_stores (PATTERN (insn), likely_spilled_retval_1, &info);
1706169689Skan  mask = info.mask;
1707169689Skan
1708169689Skan  /* Check if any of the (probably) live return value registers is
1709169689Skan     likely spilled.  */
1710169689Skan  nregs --;
1711169689Skan  do
1712169689Skan    {
1713169689Skan      if ((mask & 1 << nregs)
1714169689Skan	  && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (regno + nregs)))
1715169689Skan	return 1;
1716169689Skan    } while (nregs--);
1717169689Skan  return 0;
1718169689Skan}
1719169689Skan
1720122180Skan/* Adjust INSN after we made a change to its destination.
1721122180Skan
1722122180Skan   Changing the destination can invalidate notes that say something about
1723122180Skan   the results of the insn and a LOG_LINK pointing to the insn.  */
1724122180Skan
1725122180Skanstatic void
1726132718Skanadjust_for_new_dest (rtx insn)
1727122180Skan{
1728122180Skan  rtx *loc;
1729122180Skan
1730122180Skan  /* For notes, be conservative and simply remove them.  */
1731122180Skan  loc = &REG_NOTES (insn);
1732122180Skan  while (*loc)
1733122180Skan    {
1734122180Skan      enum reg_note kind = REG_NOTE_KIND (*loc);
1735122180Skan      if (kind == REG_EQUAL || kind == REG_EQUIV)
1736122180Skan	*loc = XEXP (*loc, 1);
1737122180Skan      else
1738122180Skan	loc = &XEXP (*loc, 1);
1739122180Skan    }
1740122180Skan
1741122180Skan  /* The new insn will have a destination that was previously the destination
1742122180Skan     of an insn just above it.  Call distribute_links to make a LOG_LINK from
1743122180Skan     the next use of that destination.  */
1744122180Skan  distribute_links (gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX));
1745122180Skan}
1746122180Skan
1747169689Skan/* Return TRUE if combine can reuse reg X in mode MODE.
1748169689Skan   ADDED_SETS is nonzero if the original set is still required.  */
1749169689Skanstatic bool
1750169689Skancan_change_dest_mode (rtx x, int added_sets, enum machine_mode mode)
1751169689Skan{
1752169689Skan  unsigned int regno;
1753169689Skan
1754169689Skan  if (!REG_P(x))
1755169689Skan    return false;
1756169689Skan
1757169689Skan  regno = REGNO (x);
1758169689Skan  /* Allow hard registers if the new mode is legal, and occupies no more
1759169689Skan     registers than the old mode.  */
1760169689Skan  if (regno < FIRST_PSEUDO_REGISTER)
1761169689Skan    return (HARD_REGNO_MODE_OK (regno, mode)
1762169689Skan	    && (hard_regno_nregs[regno][GET_MODE (x)]
1763169689Skan		>= hard_regno_nregs[regno][mode]));
1764169689Skan
1765169689Skan  /* Or a pseudo that is only used once.  */
1766169689Skan  return (REG_N_SETS (regno) == 1 && !added_sets
1767169689Skan	  && !REG_USERVAR_P (x));
1768169689Skan}
1769169689Skan
1770169689Skan
1771169689Skan/* Check whether X, the destination of a set, refers to part of
1772169689Skan   the register specified by REG.  */
1773169689Skan
1774169689Skanstatic bool
1775169689Skanreg_subword_p (rtx x, rtx reg)
1776169689Skan{
1777169689Skan  /* Check that reg is an integer mode register.  */
1778169689Skan  if (!REG_P (reg) || GET_MODE_CLASS (GET_MODE (reg)) != MODE_INT)
1779169689Skan    return false;
1780169689Skan
1781169689Skan  if (GET_CODE (x) == STRICT_LOW_PART
1782169689Skan      || GET_CODE (x) == ZERO_EXTRACT)
1783169689Skan    x = XEXP (x, 0);
1784169689Skan
1785169689Skan  return GET_CODE (x) == SUBREG
1786169689Skan	 && SUBREG_REG (x) == reg
1787169689Skan	 && GET_MODE_CLASS (GET_MODE (x)) == MODE_INT;
1788169689Skan}
1789169689Skan
1790169689Skan
179118334Speter/* Try to combine the insns I1 and I2 into I3.
179218334Speter   Here I1 and I2 appear earlier than I3.
179318334Speter   I1 can be zero; then we combine just I2 into I3.
179490075Sobrien
179590075Sobrien   If we are combining three insns and the resulting insn is not recognized,
179618334Speter   try splitting it into two insns.  If that happens, I2 and I3 are retained
179718334Speter   and I1 is pseudo-deleted by turning it into a NOTE.  Otherwise, I1 and I2
179818334Speter   are pseudo-deleted.
179918334Speter
180090075Sobrien   Return 0 if the combination does not work.  Then nothing is changed.
180118334Speter   If we did the combination, return the insn at which combine should
180290075Sobrien   resume scanning.
180318334Speter
1804117395Skan   Set NEW_DIRECT_JUMP_P to a nonzero value if try_combine creates a
180590075Sobrien   new direct jump instruction.  */
180690075Sobrien
180718334Speterstatic rtx
1808132718Skantry_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
180918334Speter{
181090075Sobrien  /* New patterns for I3 and I2, respectively.  */
181118334Speter  rtx newpat, newi2pat = 0;
1812169689Skan  rtvec newpat_vec_with_clobbers = 0;
181396263Sobrien  int substed_i2 = 0, substed_i1 = 0;
181418334Speter  /* Indicates need to preserve SET in I1 or I2 in I3 if it is not dead.  */
181518334Speter  int added_sets_1, added_sets_2;
181618334Speter  /* Total number of SETs to put into I3.  */
181718334Speter  int total_sets;
1818169689Skan  /* Nonzero if I2's body now appears in I3.  */
181918334Speter  int i2_is_used;
182018334Speter  /* INSN_CODEs for new I3, new I2, and user of condition code.  */
182190075Sobrien  int insn_code_number, i2_code_number = 0, other_code_number = 0;
182218334Speter  /* Contains I3 if the destination of I3 is used in its source, which means
182318334Speter     that the old life of I3 is being killed.  If that usage is placed into
182418334Speter     I2 and not in I3, a REG_DEAD note must be made.  */
182518334Speter  rtx i3dest_killed = 0;
182618334Speter  /* SET_DEST and SET_SRC of I2 and I1.  */
182718334Speter  rtx i2dest, i2src, i1dest = 0, i1src = 0;
1828169689Skan  /* PATTERN (I1) and PATTERN (I2), or a copy of it in certain cases.  */
1829169689Skan  rtx i1pat = 0, i2pat = 0;
183018334Speter  /* Indicates if I2DEST or I1DEST is in I2SRC or I1_SRC.  */
183118334Speter  int i2dest_in_i2src = 0, i1dest_in_i1src = 0, i2dest_in_i1src = 0;
1832169689Skan  int i2dest_killed = 0, i1dest_killed = 0;
183318334Speter  int i1_feeds_i3 = 0;
183418334Speter  /* Notes that must be added to REG_NOTES in I3 and I2.  */
183518334Speter  rtx new_i3_notes, new_i2_notes;
183618334Speter  /* Notes that we substituted I3 into I2 instead of the normal case.  */
183718334Speter  int i3_subst_into_i2 = 0;
183818334Speter  /* Notes that I1, I2 or I3 is a MULT operation.  */
183918334Speter  int have_mult = 0;
1840169689Skan  int swap_i2i3 = 0;
184118334Speter
184218334Speter  int maxreg;
184318334Speter  rtx temp;
184490075Sobrien  rtx link;
184518334Speter  int i;
184618334Speter
184770635Sobrien  /* Exit early if one of the insns involved can't be used for
184870635Sobrien     combinations.  */
184970635Sobrien  if (cant_combine_insn_p (i3)
185070635Sobrien      || cant_combine_insn_p (i2)
185170635Sobrien      || (i1 && cant_combine_insn_p (i1))
1852169689Skan      || likely_spilled_retval_p (i3)
185370635Sobrien      /* We also can't do anything if I3 has a
185470635Sobrien	 REG_LIBCALL note since we don't want to disrupt the contiguity of a
185570635Sobrien	 libcall.  */
185652284Sobrien#if 0
185752284Sobrien      /* ??? This gives worse code, and appears to be unnecessary, since no
185852284Sobrien	 pass after flow uses REG_LIBCALL/REG_RETVAL notes.  */
185952284Sobrien      || find_reg_note (i3, REG_LIBCALL, NULL_RTX)
186052284Sobrien#endif
186170635Sobrien      )
186218334Speter    return 0;
186318334Speter
186418334Speter  combine_attempts++;
186518334Speter  undobuf.other_insn = 0;
186618334Speter
186718334Speter  /* Reset the hard register usage information.  */
186818334Speter  CLEAR_HARD_REG_SET (newpat_used_regs);
186918334Speter
187018334Speter  /* If I1 and I2 both feed I3, they can be in any order.  To simplify the
187118334Speter     code below, set I1 to be the earlier of the two insns.  */
187218334Speter  if (i1 && INSN_CUID (i1) > INSN_CUID (i2))
187318334Speter    temp = i1, i1 = i2, i2 = temp;
187418334Speter
187518334Speter  added_links_insn = 0;
187618334Speter
187718334Speter  /* First check for one important special-case that the code below will
187890075Sobrien     not handle.  Namely, the case where I1 is zero, I2 is a PARALLEL
187918334Speter     and I3 is a SET whose SET_SRC is a SET_DEST in I2.  In that case,
188018334Speter     we may be able to replace that destination with the destination of I3.
188118334Speter     This occurs in the common code where we compute both a quotient and
188218334Speter     remainder into a structure, in which case we want to do the computation
188318334Speter     directly into the structure to avoid register-register copies.
188418334Speter
188590075Sobrien     Note that this case handles both multiple sets in I2 and also
188690075Sobrien     cases where I2 has a number of CLOBBER or PARALLELs.
188790075Sobrien
188818334Speter     We make very conservative checks below and only try to handle the
188918334Speter     most common cases of this.  For example, we only handle the case
189018334Speter     where I2 and I3 are adjacent to avoid making difficult register
189118334Speter     usage tests.  */
189218334Speter
1893169689Skan  if (i1 == 0 && NONJUMP_INSN_P (i3) && GET_CODE (PATTERN (i3)) == SET
1894169689Skan      && REG_P (SET_SRC (PATTERN (i3)))
189518334Speter      && REGNO (SET_SRC (PATTERN (i3))) >= FIRST_PSEUDO_REGISTER
189618334Speter      && find_reg_note (i3, REG_DEAD, SET_SRC (PATTERN (i3)))
189718334Speter      && GET_CODE (PATTERN (i2)) == PARALLEL
189818334Speter      && ! side_effects_p (SET_DEST (PATTERN (i3)))
189918334Speter      /* If the dest of I3 is a ZERO_EXTRACT or STRICT_LOW_PART, the code
190018334Speter	 below would need to check what is inside (and reg_overlap_mentioned_p
190118334Speter	 doesn't support those codes anyway).  Don't allow those destinations;
190218334Speter	 the resulting insn isn't likely to be recognized anyway.  */
190318334Speter      && GET_CODE (SET_DEST (PATTERN (i3))) != ZERO_EXTRACT
190418334Speter      && GET_CODE (SET_DEST (PATTERN (i3))) != STRICT_LOW_PART
190518334Speter      && ! reg_overlap_mentioned_p (SET_SRC (PATTERN (i3)),
190618334Speter				    SET_DEST (PATTERN (i3)))
190718334Speter      && next_real_insn (i2) == i3)
190818334Speter    {
190918334Speter      rtx p2 = PATTERN (i2);
191018334Speter
191118334Speter      /* Make sure that the destination of I3,
191218334Speter	 which we are going to substitute into one output of I2,
191318334Speter	 is not used within another output of I2.  We must avoid making this:
191418334Speter	 (parallel [(set (mem (reg 69)) ...)
191518334Speter		    (set (reg 69) ...)])
191618334Speter	 which is not well-defined as to order of actions.
191718334Speter	 (Besides, reload can't handle output reloads for this.)
191818334Speter
191918334Speter	 The problem can also happen if the dest of I3 is a memory ref,
192018334Speter	 if another dest in I2 is an indirect memory ref.  */
192118334Speter      for (i = 0; i < XVECLEN (p2, 0); i++)
192250397Sobrien	if ((GET_CODE (XVECEXP (p2, 0, i)) == SET
192350397Sobrien	     || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER)
192418334Speter	    && reg_overlap_mentioned_p (SET_DEST (PATTERN (i3)),
192518334Speter					SET_DEST (XVECEXP (p2, 0, i))))
192618334Speter	  break;
192718334Speter
192818334Speter      if (i == XVECLEN (p2, 0))
192918334Speter	for (i = 0; i < XVECLEN (p2, 0); i++)
193090075Sobrien	  if ((GET_CODE (XVECEXP (p2, 0, i)) == SET
193190075Sobrien	       || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER)
193290075Sobrien	      && SET_DEST (XVECEXP (p2, 0, i)) == SET_SRC (PATTERN (i3)))
193318334Speter	    {
193418334Speter	      combine_merges++;
193518334Speter
193618334Speter	      subst_insn = i3;
193718334Speter	      subst_low_cuid = INSN_CUID (i2);
193818334Speter
193918334Speter	      added_sets_2 = added_sets_1 = 0;
194018334Speter	      i2dest = SET_SRC (PATTERN (i3));
1941169689Skan	      i2dest_killed = dead_or_set_p (i2, i2dest);
194218334Speter
194318334Speter	      /* Replace the dest in I2 with our dest and make the resulting
194418334Speter		 insn the new pattern for I3.  Then skip to where we
194518334Speter		 validate the pattern.  Everything was set up above.  */
194690075Sobrien	      SUBST (SET_DEST (XVECEXP (p2, 0, i)),
194718334Speter		     SET_DEST (PATTERN (i3)));
194818334Speter
194918334Speter	      newpat = p2;
195018334Speter	      i3_subst_into_i2 = 1;
195118334Speter	      goto validate_replacement;
195218334Speter	    }
195318334Speter    }
195418334Speter
1955169689Skan  /* If I2 is setting a pseudo to a constant and I3 is setting some
1956169689Skan     sub-part of it to another constant, merge them by making a new
195790075Sobrien     constant.  */
195890075Sobrien  if (i1 == 0
195990075Sobrien      && (temp = single_set (i2)) != 0
196090075Sobrien      && (GET_CODE (SET_SRC (temp)) == CONST_INT
196190075Sobrien	  || GET_CODE (SET_SRC (temp)) == CONST_DOUBLE)
196290075Sobrien      && GET_CODE (PATTERN (i3)) == SET
1963169689Skan      && (GET_CODE (SET_SRC (PATTERN (i3))) == CONST_INT
1964169689Skan	  || GET_CODE (SET_SRC (PATTERN (i3))) == CONST_DOUBLE)
1965169689Skan      && reg_subword_p (SET_DEST (PATTERN (i3)), SET_DEST (temp)))
196690075Sobrien    {
1967169689Skan      rtx dest = SET_DEST (PATTERN (i3));
1968169689Skan      int offset = -1;
1969169689Skan      int width = 0;
197090075Sobrien
1971169689Skan      if (GET_CODE (dest) == ZERO_EXTRACT)
1972169689Skan	{
1973169689Skan	  if (GET_CODE (XEXP (dest, 1)) == CONST_INT
1974169689Skan	      && GET_CODE (XEXP (dest, 2)) == CONST_INT)
1975169689Skan	    {
1976169689Skan	      width = INTVAL (XEXP (dest, 1));
1977169689Skan	      offset = INTVAL (XEXP (dest, 2));
1978169689Skan	      dest = XEXP (dest, 0);
1979169689Skan	      if (BITS_BIG_ENDIAN)
1980169689Skan		offset = GET_MODE_BITSIZE (GET_MODE (dest)) - width - offset;
1981169689Skan	    }
1982169689Skan	}
198390075Sobrien      else
198490075Sobrien	{
1985169689Skan	  if (GET_CODE (dest) == STRICT_LOW_PART)
1986169689Skan	    dest = XEXP (dest, 0);
1987169689Skan	  width = GET_MODE_BITSIZE (GET_MODE (dest));
1988169689Skan	  offset = 0;
198990075Sobrien	}
199090075Sobrien
1991169689Skan      if (offset >= 0)
199290075Sobrien	{
1993169689Skan	  /* If this is the low part, we're done.  */
1994169689Skan	  if (subreg_lowpart_p (dest))
1995169689Skan	    ;
1996169689Skan	  /* Handle the case where inner is twice the size of outer.  */
1997169689Skan	  else if (GET_MODE_BITSIZE (GET_MODE (SET_DEST (temp)))
1998169689Skan		   == 2 * GET_MODE_BITSIZE (GET_MODE (dest)))
1999169689Skan	    offset += GET_MODE_BITSIZE (GET_MODE (dest));
2000169689Skan	  /* Otherwise give up for now.  */
2001169689Skan	  else
2002169689Skan	    offset = -1;
2003169689Skan	}
200490075Sobrien
2005169689Skan      if (offset >= 0)
200690075Sobrien	{
2007169689Skan	  HOST_WIDE_INT mhi, ohi, ihi;
2008169689Skan	  HOST_WIDE_INT mlo, olo, ilo;
2009169689Skan	  rtx inner = SET_SRC (PATTERN (i3));
2010169689Skan	  rtx outer = SET_SRC (temp);
201190075Sobrien
2012169689Skan	  if (GET_CODE (outer) == CONST_INT)
2013169689Skan	    {
2014169689Skan	      olo = INTVAL (outer);
2015169689Skan	      ohi = olo < 0 ? -1 : 0;
2016169689Skan	    }
2017169689Skan	  else
2018169689Skan	    {
2019169689Skan	      olo = CONST_DOUBLE_LOW (outer);
2020169689Skan	      ohi = CONST_DOUBLE_HIGH (outer);
2021169689Skan	    }
202290075Sobrien
2023169689Skan	  if (GET_CODE (inner) == CONST_INT)
2024169689Skan	    {
2025169689Skan	      ilo = INTVAL (inner);
2026169689Skan	      ihi = ilo < 0 ? -1 : 0;
2027169689Skan	    }
2028169689Skan	  else
2029169689Skan	    {
2030169689Skan	      ilo = CONST_DOUBLE_LOW (inner);
2031169689Skan	      ihi = CONST_DOUBLE_HIGH (inner);
2032169689Skan	    }
203390075Sobrien
2034169689Skan	  if (width < HOST_BITS_PER_WIDE_INT)
2035169689Skan	    {
2036169689Skan	      mlo = ((unsigned HOST_WIDE_INT) 1 << width) - 1;
2037169689Skan	      mhi = 0;
2038169689Skan	    }
2039169689Skan	  else if (width < HOST_BITS_PER_WIDE_INT * 2)
2040169689Skan	    {
2041169689Skan	      mhi = ((unsigned HOST_WIDE_INT) 1
2042169689Skan		     << (width - HOST_BITS_PER_WIDE_INT)) - 1;
2043169689Skan	      mlo = -1;
2044169689Skan	    }
2045169689Skan	  else
2046169689Skan	    {
2047169689Skan	      mlo = -1;
2048169689Skan	      mhi = -1;
2049169689Skan	    }
205090075Sobrien
2051169689Skan	  ilo &= mlo;
2052169689Skan	  ihi &= mhi;
2053169689Skan
2054169689Skan	  if (offset >= HOST_BITS_PER_WIDE_INT)
2055169689Skan	    {
2056169689Skan	      mhi = mlo << (offset - HOST_BITS_PER_WIDE_INT);
2057169689Skan	      mlo = 0;
2058169689Skan	      ihi = ilo << (offset - HOST_BITS_PER_WIDE_INT);
2059169689Skan	      ilo = 0;
2060169689Skan	    }
2061169689Skan	  else if (offset > 0)
2062169689Skan	    {
2063169689Skan	      mhi = (mhi << offset) | ((unsigned HOST_WIDE_INT) mlo
2064169689Skan		     		       >> (HOST_BITS_PER_WIDE_INT - offset));
2065169689Skan	      mlo = mlo << offset;
2066169689Skan	      ihi = (ihi << offset) | ((unsigned HOST_WIDE_INT) ilo
2067169689Skan		     		       >> (HOST_BITS_PER_WIDE_INT - offset));
2068169689Skan	      ilo = ilo << offset;
2069169689Skan	    }
2070169689Skan
2071169689Skan	  olo = (olo & ~mlo) | ilo;
2072169689Skan	  ohi = (ohi & ~mhi) | ihi;
2073169689Skan
2074169689Skan	  combine_merges++;
2075169689Skan	  subst_insn = i3;
2076169689Skan	  subst_low_cuid = INSN_CUID (i2);
2077169689Skan	  added_sets_2 = added_sets_1 = 0;
2078169689Skan	  i2dest = SET_DEST (temp);
2079169689Skan	  i2dest_killed = dead_or_set_p (i2, i2dest);
2080169689Skan
2081169689Skan	  SUBST (SET_SRC (temp),
2082169689Skan		 immed_double_const (olo, ohi, GET_MODE (SET_DEST (temp))));
2083169689Skan
2084169689Skan	  newpat = PATTERN (i2);
2085169689Skan	  goto validate_replacement;
2086169689Skan	}
208790075Sobrien    }
208890075Sobrien
208918334Speter#ifndef HAVE_cc0
209018334Speter  /* If we have no I1 and I2 looks like:
209118334Speter	(parallel [(set (reg:CC X) (compare:CC OP (const_int 0)))
209218334Speter		   (set Y OP)])
209318334Speter     make up a dummy I1 that is
209418334Speter	(set Y OP)
209518334Speter     and change I2 to be
2096169689Skan	(set (reg:CC X) (compare:CC Y (const_int 0)))
209718334Speter
209818334Speter     (We can ignore any trailing CLOBBERs.)
209918334Speter
210018334Speter     This undoes a previous combination and allows us to match a branch-and-
210118334Speter     decrement insn.  */
210218334Speter
210318334Speter  if (i1 == 0 && GET_CODE (PATTERN (i2)) == PARALLEL
210418334Speter      && XVECLEN (PATTERN (i2), 0) >= 2
210518334Speter      && GET_CODE (XVECEXP (PATTERN (i2), 0, 0)) == SET
210618334Speter      && (GET_MODE_CLASS (GET_MODE (SET_DEST (XVECEXP (PATTERN (i2), 0, 0))))
210718334Speter	  == MODE_CC)
210818334Speter      && GET_CODE (SET_SRC (XVECEXP (PATTERN (i2), 0, 0))) == COMPARE
210918334Speter      && XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 1) == const0_rtx
211018334Speter      && GET_CODE (XVECEXP (PATTERN (i2), 0, 1)) == SET
2111169689Skan      && REG_P (SET_DEST (XVECEXP (PATTERN (i2), 0, 1)))
211218334Speter      && rtx_equal_p (XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 0),
211318334Speter		      SET_SRC (XVECEXP (PATTERN (i2), 0, 1))))
211418334Speter    {
211590075Sobrien      for (i = XVECLEN (PATTERN (i2), 0) - 1; i >= 2; i--)
211618334Speter	if (GET_CODE (XVECEXP (PATTERN (i2), 0, i)) != CLOBBER)
211718334Speter	  break;
211818334Speter
211918334Speter      if (i == 1)
212018334Speter	{
212118334Speter	  /* We make I1 with the same INSN_UID as I2.  This gives it
212218334Speter	     the same INSN_CUID for value tracking.  Our fake I1 will
212318334Speter	     never appear in the insn stream so giving it the same INSN_UID
212418334Speter	     as I2 will not cause a problem.  */
212518334Speter
2126132718Skan	  i1 = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2,
2127132718Skan			     BLOCK_FOR_INSN (i2), INSN_LOCATOR (i2),
2128132718Skan			     XVECEXP (PATTERN (i2), 0, 1), -1, NULL_RTX,
2129132718Skan			     NULL_RTX);
213018334Speter
213118334Speter	  SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0));
213218334Speter	  SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),
213318334Speter		 SET_DEST (PATTERN (i1)));
213418334Speter	}
213518334Speter    }
213618334Speter#endif
213718334Speter
213818334Speter  /* Verify that I2 and I1 are valid for combining.  */
213918334Speter  if (! can_combine_p (i2, i3, i1, NULL_RTX, &i2dest, &i2src)
214018334Speter      || (i1 && ! can_combine_p (i1, i3, NULL_RTX, i2, &i1dest, &i1src)))
214118334Speter    {
214218334Speter      undo_all ();
214318334Speter      return 0;
214418334Speter    }
214518334Speter
214618334Speter  /* Record whether I2DEST is used in I2SRC and similarly for the other
214718334Speter     cases.  Knowing this will help in register status updating below.  */
214818334Speter  i2dest_in_i2src = reg_overlap_mentioned_p (i2dest, i2src);
214918334Speter  i1dest_in_i1src = i1 && reg_overlap_mentioned_p (i1dest, i1src);
215018334Speter  i2dest_in_i1src = i1 && reg_overlap_mentioned_p (i2dest, i1src);
2151169689Skan  i2dest_killed = dead_or_set_p (i2, i2dest);
2152169689Skan  i1dest_killed = i1 && dead_or_set_p (i1, i1dest);
215318334Speter
215418334Speter  /* See if I1 directly feeds into I3.  It does if I1DEST is not used
215518334Speter     in I2SRC.  */
215618334Speter  i1_feeds_i3 = i1 && ! reg_overlap_mentioned_p (i1dest, i2src);
215718334Speter
215818334Speter  /* Ensure that I3's pattern can be the destination of combines.  */
215918334Speter  if (! combinable_i3pat (i3, &PATTERN (i3), i2dest, i1dest,
216018334Speter			  i1 && i2dest_in_i1src && i1_feeds_i3,
216118334Speter			  &i3dest_killed))
216218334Speter    {
216318334Speter      undo_all ();
216418334Speter      return 0;
216518334Speter    }
216618334Speter
216718334Speter  /* See if any of the insns is a MULT operation.  Unless one is, we will
216818334Speter     reject a combination that is, since it must be slower.  Be conservative
216918334Speter     here.  */
217018334Speter  if (GET_CODE (i2src) == MULT
217118334Speter      || (i1 != 0 && GET_CODE (i1src) == MULT)
217218334Speter      || (GET_CODE (PATTERN (i3)) == SET
217318334Speter	  && GET_CODE (SET_SRC (PATTERN (i3))) == MULT))
217418334Speter    have_mult = 1;
217518334Speter
217618334Speter  /* If I3 has an inc, then give up if I1 or I2 uses the reg that is inc'd.
217718334Speter     We used to do this EXCEPT in one case: I3 has a post-inc in an
217818334Speter     output operand.  However, that exception can give rise to insns like
217990075Sobrien	mov r3,(r3)+
218018334Speter     which is a famous insn on the PDP-11 where the value of r3 used as the
218118334Speter     source was model-dependent.  Avoid this sort of thing.  */
218218334Speter
218318334Speter#if 0
218418334Speter  if (!(GET_CODE (PATTERN (i3)) == SET
2185169689Skan	&& REG_P (SET_SRC (PATTERN (i3)))
2186169689Skan	&& MEM_P (SET_DEST (PATTERN (i3)))
218718334Speter	&& (GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_INC
218818334Speter	    || GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_DEC)))
218918334Speter    /* It's not the exception.  */
219018334Speter#endif
219118334Speter#ifdef AUTO_INC_DEC
219218334Speter    for (link = REG_NOTES (i3); link; link = XEXP (link, 1))
219318334Speter      if (REG_NOTE_KIND (link) == REG_INC
219418334Speter	  && (reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i2))
219518334Speter	      || (i1 != 0
219618334Speter		  && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i1)))))
219718334Speter	{
219818334Speter	  undo_all ();
219918334Speter	  return 0;
220018334Speter	}
220118334Speter#endif
220218334Speter
220318334Speter  /* See if the SETs in I1 or I2 need to be kept around in the merged
220418334Speter     instruction: whenever the value set there is still needed past I3.
220518334Speter     For the SETs in I2, this is easy: we see if I2DEST dies or is set in I3.
220618334Speter
220718334Speter     For the SET in I1, we have two cases:  If I1 and I2 independently
220818334Speter     feed into I3, the set in I1 needs to be kept around if I1DEST dies
220918334Speter     or is set in I3.  Otherwise (if I1 feeds I2 which feeds I3), the set
221018334Speter     in I1 needs to be kept around unless I1DEST dies or is set in either
221118334Speter     I2 or I3.  We can distinguish these cases by seeing if I2SRC mentions
221218334Speter     I1DEST.  If so, we know I1 feeds into I2.  */
221318334Speter
221418334Speter  added_sets_2 = ! dead_or_set_p (i3, i2dest);
221518334Speter
221618334Speter  added_sets_1
221718334Speter    = i1 && ! (i1_feeds_i3 ? dead_or_set_p (i3, i1dest)
221818334Speter	       : (dead_or_set_p (i3, i1dest) || dead_or_set_p (i2, i1dest)));
221918334Speter
222018334Speter  /* If the set in I2 needs to be kept around, we must make a copy of
222118334Speter     PATTERN (I2), so that when we substitute I1SRC for I1DEST in
222218334Speter     PATTERN (I2), we are only substituting for the original I1DEST, not into
222318334Speter     an already-substituted copy.  This also prevents making self-referential
222418334Speter     rtx.  If I2 is a PARALLEL, we just need the piece that assigns I2SRC to
222518334Speter     I2DEST.  */
222618334Speter
222718334Speter  if (added_sets_2)
2228169689Skan    {
2229169689Skan      if (GET_CODE (PATTERN (i2)) == PARALLEL)
2230169689Skan	i2pat = gen_rtx_SET (VOIDmode, i2dest, copy_rtx (i2src));
2231169689Skan      else
2232169689Skan	i2pat = copy_rtx (PATTERN (i2));
2233169689Skan    }
223418334Speter
2235169689Skan  if (added_sets_1)
2236169689Skan    {
2237169689Skan      if (GET_CODE (PATTERN (i1)) == PARALLEL)
2238169689Skan	i1pat = gen_rtx_SET (VOIDmode, i1dest, copy_rtx (i1src));
2239169689Skan      else
2240169689Skan	i1pat = copy_rtx (PATTERN (i1));
2241169689Skan    }
2242169689Skan
224318334Speter  combine_merges++;
224418334Speter
224518334Speter  /* Substitute in the latest insn for the regs set by the earlier ones.  */
224618334Speter
224718334Speter  maxreg = max_reg_num ();
224818334Speter
224918334Speter  subst_insn = i3;
225018334Speter
225118334Speter#ifndef HAVE_cc0
225218334Speter  /* Many machines that don't use CC0 have insns that can both perform an
225318334Speter     arithmetic operation and set the condition code.  These operations will
225418334Speter     be represented as a PARALLEL with the first element of the vector
225518334Speter     being a COMPARE of an arithmetic operation with the constant zero.
225618334Speter     The second element of the vector will set some pseudo to the result
225718334Speter     of the same arithmetic operation.  If we simplify the COMPARE, we won't
225818334Speter     match such a pattern and so will generate an extra insn.   Here we test
225918334Speter     for this case, where both the comparison and the operation result are
226018334Speter     needed, and make the PARALLEL by just replacing I2DEST in I3SRC with
226118334Speter     I2SRC.  Later we will make the PARALLEL that contains I2.  */
226218334Speter
226318334Speter  if (i1 == 0 && added_sets_2 && GET_CODE (PATTERN (i3)) == SET
226418334Speter      && GET_CODE (SET_SRC (PATTERN (i3))) == COMPARE
226518334Speter      && XEXP (SET_SRC (PATTERN (i3)), 1) == const0_rtx
226618334Speter      && rtx_equal_p (XEXP (SET_SRC (PATTERN (i3)), 0), i2dest))
226718334Speter    {
2268132718Skan#ifdef SELECT_CC_MODE
226918334Speter      rtx *cc_use;
227018334Speter      enum machine_mode compare_mode;
227150397Sobrien#endif
227218334Speter
227318334Speter      newpat = PATTERN (i3);
227418334Speter      SUBST (XEXP (SET_SRC (newpat), 0), i2src);
227518334Speter
227618334Speter      i2_is_used = 1;
227718334Speter
2278132718Skan#ifdef SELECT_CC_MODE
227918334Speter      /* See if a COMPARE with the operand we substituted in should be done
228018334Speter	 with the mode that is currently being used.  If not, do the same
228118334Speter	 processing we do in `subst' for a SET; namely, if the destination
228218334Speter	 is used only once, try to replace it with a register of the proper
228318334Speter	 mode and also replace the COMPARE.  */
228418334Speter      if (undobuf.other_insn == 0
228518334Speter	  && (cc_use = find_single_use (SET_DEST (newpat), i3,
228618334Speter					&undobuf.other_insn))
228718334Speter	  && ((compare_mode = SELECT_CC_MODE (GET_CODE (*cc_use),
228818334Speter					      i2src, const0_rtx))
228918334Speter	      != GET_MODE (SET_DEST (newpat))))
229018334Speter	{
2291169689Skan	  if (can_change_dest_mode(SET_DEST (newpat), added_sets_2,
2292169689Skan				   compare_mode))
229318334Speter	    {
2294169689Skan	      unsigned int regno = REGNO (SET_DEST (newpat));
2295169689Skan	      rtx new_dest;
229618334Speter
2297169689Skan	      if (regno < FIRST_PSEUDO_REGISTER)
2298169689Skan		new_dest = gen_rtx_REG (compare_mode, regno);
2299169689Skan	      else
2300169689Skan		{
2301169689Skan		  SUBST_MODE (regno_reg_rtx[regno], compare_mode);
2302169689Skan		  new_dest = regno_reg_rtx[regno];
2303169689Skan		}
2304169689Skan
230518334Speter	      SUBST (SET_DEST (newpat), new_dest);
230618334Speter	      SUBST (XEXP (*cc_use, 0), new_dest);
230718334Speter	      SUBST (SET_SRC (newpat),
230890075Sobrien		     gen_rtx_COMPARE (compare_mode, i2src, const0_rtx));
230918334Speter	    }
231018334Speter	  else
231118334Speter	    undobuf.other_insn = 0;
231218334Speter	}
231390075Sobrien#endif
231418334Speter    }
231518334Speter  else
231618334Speter#endif
231718334Speter    {
2318169689Skan      /* It is possible that the source of I2 or I1 may be performing
2319169689Skan	 an unneeded operation, such as a ZERO_EXTEND of something
2320169689Skan	 that is known to have the high part zero.  Handle that case
2321169689Skan	 by letting subst look at the innermost one of them.
2322169689Skan
2323169689Skan	 Another way to do this would be to have a function that tries
2324169689Skan	 to simplify a single insn instead of merging two or more
2325169689Skan	 insns.  We don't do this because of the potential of infinite
2326169689Skan	 loops and because of the potential extra memory required.
2327169689Skan	 However, doing it the way we are is a bit of a kludge and
2328169689Skan	 doesn't catch all cases.
2329169689Skan
2330169689Skan	 But only do this if -fexpensive-optimizations since it slows
2331169689Skan	 things down and doesn't usually win.
2332169689Skan
2333169689Skan	 This is not done in the COMPARE case above because the
2334169689Skan	 unmodified I2PAT is used in the PARALLEL and so a pattern
2335169689Skan	 with a modified I2SRC would not match.  */
2336169689Skan
2337169689Skan      if (flag_expensive_optimizations)
2338169689Skan	{
2339169689Skan	  /* Pass pc_rtx so no substitutions are done, just
2340169689Skan	     simplifications.  */
2341169689Skan	  if (i1)
2342169689Skan	    {
2343169689Skan	      subst_low_cuid = INSN_CUID (i1);
2344169689Skan	      i1src = subst (i1src, pc_rtx, pc_rtx, 0, 0);
2345169689Skan	    }
2346169689Skan	  else
2347169689Skan	    {
2348169689Skan	      subst_low_cuid = INSN_CUID (i2);
2349169689Skan	      i2src = subst (i2src, pc_rtx, pc_rtx, 0, 0);
2350169689Skan	    }
2351169689Skan	}
2352169689Skan
235318334Speter      n_occurrences = 0;		/* `subst' counts here */
235418334Speter
235518334Speter      /* If I1 feeds into I2 (not into I3) and I1DEST is in I1SRC, we
235618334Speter	 need to make a unique copy of I2SRC each time we substitute it
235718334Speter	 to avoid self-referential rtl.  */
235818334Speter
235918334Speter      subst_low_cuid = INSN_CUID (i2);
236018334Speter      newpat = subst (PATTERN (i3), i2dest, i2src, 0,
236118334Speter		      ! i1_feeds_i3 && i1dest_in_i1src);
236296263Sobrien      substed_i2 = 1;
236318334Speter
236418334Speter      /* Record whether i2's body now appears within i3's body.  */
236518334Speter      i2_is_used = n_occurrences;
236618334Speter    }
236718334Speter
236818334Speter  /* If we already got a failure, don't try to do more.  Otherwise,
236918334Speter     try to substitute in I1 if we have it.  */
237018334Speter
237118334Speter  if (i1 && GET_CODE (newpat) != CLOBBER)
237218334Speter    {
2373260528Spfg      /* Check that an autoincrement side-effect on I1 has not been lost.
2374260528Spfg	 This happens if I1DEST is mentioned in I2 and dies there, and
2375260528Spfg	 has disappeared from the new pattern.  */
2376260528Spfg      if ((FIND_REG_INC_NOTE (i1, NULL_RTX) != 0
2377260528Spfg	   && !i1_feeds_i3
2378260528Spfg	   && dead_or_set_p (i2, i1dest)
2379260528Spfg	   && !reg_overlap_mentioned_p (i1dest, newpat))
2380260528Spfg	  /* Before we can do this substitution, we must redo the test done
2381260528Spfg	     above (see detailed comments there) that ensures  that I1DEST
2382260528Spfg	     isn't mentioned in any SETs in NEWPAT that are field assignments.  */
2383260528Spfg          || !combinable_i3pat (NULL_RTX, &newpat, i1dest, NULL_RTX, 0, 0))
238418334Speter	{
238518334Speter	  undo_all ();
238618334Speter	  return 0;
238718334Speter	}
238818334Speter
238918334Speter      n_occurrences = 0;
239018334Speter      subst_low_cuid = INSN_CUID (i1);
239118334Speter      newpat = subst (newpat, i1dest, i1src, 0, 0);
239296263Sobrien      substed_i1 = 1;
239318334Speter    }
239418334Speter
239518334Speter  /* Fail if an autoincrement side-effect has been duplicated.  Be careful
239618334Speter     to count all the ways that I2SRC and I1SRC can be used.  */
239718334Speter  if ((FIND_REG_INC_NOTE (i2, NULL_RTX) != 0
239818334Speter       && i2_is_used + added_sets_2 > 1)
239918334Speter      || (i1 != 0 && FIND_REG_INC_NOTE (i1, NULL_RTX) != 0
240018334Speter	  && (n_occurrences + added_sets_1 + (added_sets_2 && ! i1_feeds_i3)
240118334Speter	      > 1))
2402169689Skan      /* Fail if we tried to make a new register.  */
240318334Speter      || max_reg_num () != maxreg
240418334Speter      /* Fail if we couldn't do something and have a CLOBBER.  */
240518334Speter      || GET_CODE (newpat) == CLOBBER
240618334Speter      /* Fail if this new pattern is a MULT and we didn't have one before
240718334Speter	 at the outer level.  */
240818334Speter      || (GET_CODE (newpat) == SET && GET_CODE (SET_SRC (newpat)) == MULT
240918334Speter	  && ! have_mult))
241018334Speter    {
241118334Speter      undo_all ();
241218334Speter      return 0;
241318334Speter    }
241418334Speter
241518334Speter  /* If the actions of the earlier insns must be kept
241618334Speter     in addition to substituting them into the latest one,
241718334Speter     we must make a new PARALLEL for the latest insn
241818334Speter     to hold additional the SETs.  */
241918334Speter
242018334Speter  if (added_sets_1 || added_sets_2)
242118334Speter    {
242218334Speter      combine_extras++;
242318334Speter
242418334Speter      if (GET_CODE (newpat) == PARALLEL)
242518334Speter	{
242618334Speter	  rtvec old = XVEC (newpat, 0);
242718334Speter	  total_sets = XVECLEN (newpat, 0) + added_sets_1 + added_sets_2;
242850397Sobrien	  newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets));
242990075Sobrien	  memcpy (XVEC (newpat, 0)->elem, &old->elem[0],
243090075Sobrien		  sizeof (old->elem[0]) * old->num_elem);
243118334Speter	}
243218334Speter      else
243318334Speter	{
243418334Speter	  rtx old = newpat;
243518334Speter	  total_sets = 1 + added_sets_1 + added_sets_2;
243650397Sobrien	  newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets));
243718334Speter	  XVECEXP (newpat, 0, 0) = old;
243818334Speter	}
243918334Speter
244090075Sobrien      if (added_sets_1)
2441169689Skan	XVECEXP (newpat, 0, --total_sets) = i1pat;
244218334Speter
244390075Sobrien      if (added_sets_2)
244418334Speter	{
244518334Speter	  /* If there is no I1, use I2's body as is.  We used to also not do
244618334Speter	     the subst call below if I2 was substituted into I3,
244718334Speter	     but that could lose a simplification.  */
244818334Speter	  if (i1 == 0)
244918334Speter	    XVECEXP (newpat, 0, --total_sets) = i2pat;
245018334Speter	  else
245118334Speter	    /* See comment where i2pat is assigned.  */
245218334Speter	    XVECEXP (newpat, 0, --total_sets)
245318334Speter	      = subst (i2pat, i1dest, i1src, 0, 0);
245418334Speter	}
245518334Speter    }
245618334Speter
245718334Speter  /* We come here when we are replacing a destination in I2 with the
245818334Speter     destination of I3.  */
245918334Speter validate_replacement:
246018334Speter
246118334Speter  /* Note which hard regs this insn has as inputs.  */
246218334Speter  mark_used_regs_combine (newpat);
246318334Speter
2464169689Skan  /* If recog_for_combine fails, it strips existing clobbers.  If we'll
2465169689Skan     consider splitting this pattern, we might need these clobbers.  */
2466169689Skan  if (i1 && GET_CODE (newpat) == PARALLEL
2467169689Skan      && GET_CODE (XVECEXP (newpat, 0, XVECLEN (newpat, 0) - 1)) == CLOBBER)
2468169689Skan    {
2469169689Skan      int len = XVECLEN (newpat, 0);
2470169689Skan
2471169689Skan      newpat_vec_with_clobbers = rtvec_alloc (len);
2472169689Skan      for (i = 0; i < len; i++)
2473169689Skan	RTVEC_ELT (newpat_vec_with_clobbers, i) = XVECEXP (newpat, 0, i);
2474169689Skan    }
2475169689Skan
247618334Speter  /* Is the result of combination a valid instruction?  */
247752284Sobrien  insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
247818334Speter
247918334Speter  /* If the result isn't valid, see if it is a PARALLEL of two SETs where
2480132718Skan     the second SET's destination is a register that is unused and isn't
2481132718Skan     marked as an instruction that might trap in an EH region.  In that case,
248218334Speter     we just need the first SET.   This can occur when simplifying a divmod
248318334Speter     insn.  We *must* test for this case here because the code below that
248418334Speter     splits two independent SETs doesn't handle this case correctly when it
2485169689Skan     updates the register status.
248618334Speter
2487169689Skan     It's pointless doing this if we originally had two sets, one from
2488169689Skan     i3, and one from i2.  Combining then splitting the parallel results
2489169689Skan     in the original i2 again plus an invalid insn (which we delete).
2490169689Skan     The net effect is only to move instructions around, which makes
2491169689Skan     debug info less accurate.
2492169689Skan
2493169689Skan     Also check the case where the first SET's destination is unused.
2494169689Skan     That would not cause incorrect code, but does cause an unneeded
2495169689Skan     insn to remain.  */
2496169689Skan
2497169689Skan  if (insn_code_number < 0
2498169689Skan      && !(added_sets_2 && i1 == 0)
2499169689Skan      && GET_CODE (newpat) == PARALLEL
250018334Speter      && XVECLEN (newpat, 0) == 2
250118334Speter      && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
250218334Speter      && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
250318334Speter      && asm_noperands (newpat) < 0)
250418334Speter    {
2505132718Skan      rtx set0 = XVECEXP (newpat, 0, 0);
2506132718Skan      rtx set1 = XVECEXP (newpat, 0, 1);
2507132718Skan      rtx note;
250818334Speter
2509169689Skan      if (((REG_P (SET_DEST (set1))
2510132718Skan	    && find_reg_note (i3, REG_UNUSED, SET_DEST (set1)))
2511132718Skan	   || (GET_CODE (SET_DEST (set1)) == SUBREG
2512132718Skan	       && find_reg_note (i3, REG_UNUSED, SUBREG_REG (SET_DEST (set1)))))
2513132718Skan	  && (!(note = find_reg_note (i3, REG_EH_REGION, NULL_RTX))
2514132718Skan	      || INTVAL (XEXP (note, 0)) <= 0)
2515132718Skan	  && ! side_effects_p (SET_SRC (set1)))
2516122180Skan	{
2517132718Skan	  newpat = set0;
2518132718Skan	  insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
2519122180Skan	}
2520132718Skan
2521169689Skan      else if (((REG_P (SET_DEST (set0))
2522132718Skan		 && find_reg_note (i3, REG_UNUSED, SET_DEST (set0)))
2523132718Skan		|| (GET_CODE (SET_DEST (set0)) == SUBREG
2524132718Skan		    && find_reg_note (i3, REG_UNUSED,
2525132718Skan				      SUBREG_REG (SET_DEST (set0)))))
2526132718Skan	       && (!(note = find_reg_note (i3, REG_EH_REGION, NULL_RTX))
2527132718Skan		   || INTVAL (XEXP (note, 0)) <= 0)
2528132718Skan	       && ! side_effects_p (SET_SRC (set0)))
2529132718Skan	{
2530132718Skan	  newpat = set1;
2531132718Skan	  insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
2532132718Skan
2533132718Skan	  if (insn_code_number >= 0)
2534132718Skan	    {
2535132718Skan	      /* If we will be able to accept this, we have made a
2536132718Skan		 change to the destination of I3.  This requires us to
2537132718Skan		 do a few adjustments.  */
2538132718Skan
2539132718Skan	      PATTERN (i3) = newpat;
2540132718Skan	      adjust_for_new_dest (i3);
2541132718Skan	    }
2542132718Skan	}
254318334Speter    }
254418334Speter
254518334Speter  /* If we were combining three insns and the result is a simple SET
254618334Speter     with no ASM_OPERANDS that wasn't recognized, try to split it into two
254790075Sobrien     insns.  There are two ways to do this.  It can be split using a
254818334Speter     machine-specific method (like when you have an addition of a large
254918334Speter     constant) or by combine in the function find_split_point.  */
255018334Speter
255118334Speter  if (i1 && insn_code_number < 0 && GET_CODE (newpat) == SET
255218334Speter      && asm_noperands (newpat) < 0)
255318334Speter    {
255418334Speter      rtx m_split, *split;
255518334Speter
255618334Speter      /* See if the MD file can split NEWPAT.  If it can't, see if letting it
255718334Speter	 use I2DEST as a scratch register will help.  In the latter case,
255818334Speter	 convert I2DEST to the mode of the source of NEWPAT if we can.  */
255918334Speter
256018334Speter      m_split = split_insns (newpat, i3);
256118334Speter
256218334Speter      /* We can only use I2DEST as a scratch reg if it doesn't overlap any
256318334Speter	 inputs of NEWPAT.  */
256418334Speter
256518334Speter      /* ??? If I2DEST is not safe, and I1DEST exists, then it would be
256618334Speter	 possible to try that as a scratch reg.  This would require adding
256718334Speter	 more code to make it work though.  */
256818334Speter
2569169689Skan      if (m_split == 0 && ! reg_overlap_mentioned_p (i2dest, newpat))
257018334Speter	{
2571169689Skan	  enum machine_mode new_mode = GET_MODE (SET_DEST (newpat));
257218334Speter
2573169689Skan	  /* First try to split using the original register as a
2574169689Skan	     scratch register.  */
257590075Sobrien	  m_split = split_insns (gen_rtx_PARALLEL
257690075Sobrien				 (VOIDmode,
257790075Sobrien				  gen_rtvec (2, newpat,
257890075Sobrien					     gen_rtx_CLOBBER (VOIDmode,
2579169689Skan							      i2dest))),
258090075Sobrien				 i3);
2581169689Skan
2582169689Skan	  /* If that didn't work, try changing the mode of I2DEST if
2583169689Skan	     we can.  */
2584169689Skan	  if (m_split == 0
2585169689Skan	      && new_mode != GET_MODE (i2dest)
2586169689Skan	      && new_mode != VOIDmode
2587169689Skan	      && can_change_dest_mode (i2dest, added_sets_2, new_mode))
258890075Sobrien	    {
2589169689Skan	      enum machine_mode old_mode = GET_MODE (i2dest);
2590169689Skan	      rtx ni2dest;
2591169689Skan
2592169689Skan	      if (REGNO (i2dest) < FIRST_PSEUDO_REGISTER)
2593169689Skan		ni2dest = gen_rtx_REG (new_mode, REGNO (i2dest));
2594169689Skan	      else
2595169689Skan		{
2596169689Skan		  SUBST_MODE (regno_reg_rtx[REGNO (i2dest)], new_mode);
2597169689Skan		  ni2dest = regno_reg_rtx[REGNO (i2dest)];
2598169689Skan		}
2599169689Skan
260090075Sobrien	      m_split = split_insns (gen_rtx_PARALLEL
260190075Sobrien				     (VOIDmode,
260290075Sobrien				      gen_rtvec (2, newpat,
260390075Sobrien						 gen_rtx_CLOBBER (VOIDmode,
2604169689Skan								  ni2dest))),
260590075Sobrien				     i3);
2606169689Skan
2607169689Skan	      if (m_split == 0
2608169689Skan		  && REGNO (i2dest) >= FIRST_PSEUDO_REGISTER)
2609169689Skan		{
2610169689Skan		  struct undo *buf;
2611169689Skan
2612169689Skan		  PUT_MODE (regno_reg_rtx[REGNO (i2dest)], old_mode);
2613169689Skan		  buf = undobuf.undos;
2614169689Skan		  undobuf.undos = buf->next;
2615169689Skan		  buf->next = undobuf.frees;
2616169689Skan		  undobuf.frees = buf;
2617169689Skan		}
261890075Sobrien	    }
261918334Speter	}
262018334Speter
2621169689Skan      /* If recog_for_combine has discarded clobbers, try to use them
2622169689Skan	 again for the split.  */
2623169689Skan      if (m_split == 0 && newpat_vec_with_clobbers)
2624169689Skan	m_split
2625169689Skan	  = split_insns (gen_rtx_PARALLEL (VOIDmode,
2626169689Skan					   newpat_vec_with_clobbers), i3);
2627169689Skan
2628117395Skan      if (m_split && NEXT_INSN (m_split) == NULL_RTX)
262918334Speter	{
2630117395Skan	  m_split = PATTERN (m_split);
263190075Sobrien	  insn_code_number = recog_for_combine (&m_split, i3, &new_i3_notes);
263290075Sobrien	  if (insn_code_number >= 0)
263390075Sobrien	    newpat = m_split;
263490075Sobrien	}
2635117395Skan      else if (m_split && NEXT_INSN (NEXT_INSN (m_split)) == NULL_RTX
263690075Sobrien	       && (next_real_insn (i2) == i3
2637117395Skan		   || ! use_crosses_set_p (PATTERN (m_split), INSN_CUID (i2))))
263890075Sobrien	{
263918334Speter	  rtx i2set, i3set;
2640117395Skan	  rtx newi3pat = PATTERN (NEXT_INSN (m_split));
2641117395Skan	  newi2pat = PATTERN (m_split);
264218334Speter
2643117395Skan	  i3set = single_set (NEXT_INSN (m_split));
2644117395Skan	  i2set = single_set (m_split);
264518334Speter
264652284Sobrien	  i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
264718334Speter
264818334Speter	  /* If I2 or I3 has multiple SETs, we won't know how to track
264950397Sobrien	     register status, so don't use these insns.  If I2's destination
265050397Sobrien	     is used between I2 and I3, we also can't use these insns.  */
265118334Speter
265250397Sobrien	  if (i2_code_number >= 0 && i2set && i3set
265350397Sobrien	      && (next_real_insn (i2) == i3
265450397Sobrien		  || ! reg_used_between_p (SET_DEST (i2set), i2, i3)))
265552284Sobrien	    insn_code_number = recog_for_combine (&newi3pat, i3,
265652284Sobrien						  &new_i3_notes);
265718334Speter	  if (insn_code_number >= 0)
265818334Speter	    newpat = newi3pat;
265918334Speter
266018334Speter	  /* It is possible that both insns now set the destination of I3.
266118334Speter	     If so, we must show an extra use of it.  */
266218334Speter
266350397Sobrien	  if (insn_code_number >= 0)
266450397Sobrien	    {
266550397Sobrien	      rtx new_i3_dest = SET_DEST (i3set);
266650397Sobrien	      rtx new_i2_dest = SET_DEST (i2set);
266750397Sobrien
266850397Sobrien	      while (GET_CODE (new_i3_dest) == ZERO_EXTRACT
266950397Sobrien		     || GET_CODE (new_i3_dest) == STRICT_LOW_PART
267050397Sobrien		     || GET_CODE (new_i3_dest) == SUBREG)
267150397Sobrien		new_i3_dest = XEXP (new_i3_dest, 0);
267250397Sobrien
267350397Sobrien	      while (GET_CODE (new_i2_dest) == ZERO_EXTRACT
267450397Sobrien		     || GET_CODE (new_i2_dest) == STRICT_LOW_PART
267550397Sobrien		     || GET_CODE (new_i2_dest) == SUBREG)
267650397Sobrien		new_i2_dest = XEXP (new_i2_dest, 0);
267750397Sobrien
2678169689Skan	      if (REG_P (new_i3_dest)
2679169689Skan		  && REG_P (new_i2_dest)
268050397Sobrien		  && REGNO (new_i3_dest) == REGNO (new_i2_dest))
268150397Sobrien		REG_N_SETS (REGNO (new_i2_dest))++;
268250397Sobrien	    }
268318334Speter	}
268418334Speter
268518334Speter      /* If we can split it and use I2DEST, go ahead and see if that
268618334Speter	 helps things be recognized.  Verify that none of the registers
268718334Speter	 are set between I2 and I3.  */
268818334Speter      if (insn_code_number < 0 && (split = find_split_point (&newpat, i3)) != 0
268918334Speter#ifdef HAVE_cc0
2690169689Skan	  && REG_P (i2dest)
269118334Speter#endif
269218334Speter	  /* We need I2DEST in the proper mode.  If it is a hard register
2693169689Skan	     or the only use of a pseudo, we can change its mode.
2694169689Skan	     Make sure we don't change a hard register to have a mode that
2695169689Skan	     isn't valid for it, or change the number of registers.  */
269618334Speter	  && (GET_MODE (*split) == GET_MODE (i2dest)
269718334Speter	      || GET_MODE (*split) == VOIDmode
2698169689Skan	      || can_change_dest_mode (i2dest, added_sets_2,
2699169689Skan				       GET_MODE (*split)))
270018334Speter	  && (next_real_insn (i2) == i3
270118334Speter	      || ! use_crosses_set_p (*split, INSN_CUID (i2)))
270218334Speter	  /* We can't overwrite I2DEST if its value is still used by
270318334Speter	     NEWPAT.  */
270418334Speter	  && ! reg_referenced_p (i2dest, newpat))
270518334Speter	{
270618334Speter	  rtx newdest = i2dest;
270718334Speter	  enum rtx_code split_code = GET_CODE (*split);
270818334Speter	  enum machine_mode split_mode = GET_MODE (*split);
2709169689Skan	  bool subst_done = false;
2710169689Skan	  newi2pat = NULL_RTX;
271118334Speter
271218334Speter	  /* Get NEWDEST as a register in the proper mode.  We have already
271318334Speter	     validated that we can do this.  */
271418334Speter	  if (GET_MODE (i2dest) != split_mode && split_mode != VOIDmode)
271518334Speter	    {
2716169689Skan	      if (REGNO (i2dest) < FIRST_PSEUDO_REGISTER)
2717169689Skan		newdest = gen_rtx_REG (split_mode, REGNO (i2dest));
2718169689Skan	      else
2719169689Skan		{
2720169689Skan		  SUBST_MODE (regno_reg_rtx[REGNO (i2dest)], split_mode);
2721169689Skan		  newdest = regno_reg_rtx[REGNO (i2dest)];
2722169689Skan		}
272318334Speter	    }
272418334Speter
272518334Speter	  /* If *SPLIT is a (mult FOO (const_int pow2)), convert it to
272618334Speter	     an ASHIFT.  This can occur if it was inside a PLUS and hence
272718334Speter	     appeared to be a memory address.  This is a kludge.  */
272818334Speter	  if (split_code == MULT
272918334Speter	      && GET_CODE (XEXP (*split, 1)) == CONST_INT
273090075Sobrien	      && INTVAL (XEXP (*split, 1)) > 0
273118334Speter	      && (i = exact_log2 (INTVAL (XEXP (*split, 1)))) >= 0)
273218334Speter	    {
273390075Sobrien	      SUBST (*split, gen_rtx_ASHIFT (split_mode,
273490075Sobrien					     XEXP (*split, 0), GEN_INT (i)));
273518334Speter	      /* Update split_code because we may not have a multiply
273618334Speter		 anymore.  */
273718334Speter	      split_code = GET_CODE (*split);
273818334Speter	    }
273918334Speter
274018334Speter#ifdef INSN_SCHEDULING
274118334Speter	  /* If *SPLIT is a paradoxical SUBREG, when we split it, it should
274218334Speter	     be written as a ZERO_EXTEND.  */
2743169689Skan	  if (split_code == SUBREG && MEM_P (SUBREG_REG (*split)))
2744117395Skan	    {
2745117395Skan#ifdef LOAD_EXTEND_OP
2746117395Skan	      /* Or as a SIGN_EXTEND if LOAD_EXTEND_OP says that that's
2747117395Skan		 what it really is.  */
2748117395Skan	      if (LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (*split)))
2749117395Skan		  == SIGN_EXTEND)
2750117395Skan		SUBST (*split, gen_rtx_SIGN_EXTEND (split_mode,
2751117395Skan						    SUBREG_REG (*split)));
2752117395Skan	      else
275318334Speter#endif
2754117395Skan		SUBST (*split, gen_rtx_ZERO_EXTEND (split_mode,
2755117395Skan						    SUBREG_REG (*split)));
2756117395Skan	    }
2757117395Skan#endif
275818334Speter
2759169689Skan	  /* Attempt to split binary operators using arithmetic identities.  */
2760169689Skan	  if (BINARY_P (SET_SRC (newpat))
2761169689Skan	      && split_mode == GET_MODE (SET_SRC (newpat))
2762169689Skan	      && ! side_effects_p (SET_SRC (newpat)))
2763169689Skan	    {
2764169689Skan	      rtx setsrc = SET_SRC (newpat);
2765169689Skan	      enum machine_mode mode = GET_MODE (setsrc);
2766169689Skan	      enum rtx_code code = GET_CODE (setsrc);
2767169689Skan	      rtx src_op0 = XEXP (setsrc, 0);
2768169689Skan	      rtx src_op1 = XEXP (setsrc, 1);
2769169689Skan
2770169689Skan	      /* Split "X = Y op Y" as "Z = Y; X = Z op Z".  */
2771169689Skan	      if (rtx_equal_p (src_op0, src_op1))
2772169689Skan		{
2773169689Skan		  newi2pat = gen_rtx_SET (VOIDmode, newdest, src_op0);
2774169689Skan		  SUBST (XEXP (setsrc, 0), newdest);
2775169689Skan		  SUBST (XEXP (setsrc, 1), newdest);
2776169689Skan		  subst_done = true;
2777169689Skan		}
2778169689Skan	      /* Split "((P op Q) op R) op S" where op is PLUS or MULT.  */
2779169689Skan	      else if ((code == PLUS || code == MULT)
2780169689Skan		       && GET_CODE (src_op0) == code
2781169689Skan		       && GET_CODE (XEXP (src_op0, 0)) == code
2782169689Skan		       && (INTEGRAL_MODE_P (mode)
2783169689Skan			   || (FLOAT_MODE_P (mode)
2784169689Skan			       && flag_unsafe_math_optimizations)))
2785169689Skan		{
2786169689Skan		  rtx p = XEXP (XEXP (src_op0, 0), 0);
2787169689Skan		  rtx q = XEXP (XEXP (src_op0, 0), 1);
2788169689Skan		  rtx r = XEXP (src_op0, 1);
2789169689Skan		  rtx s = src_op1;
2790169689Skan
2791169689Skan		  /* Split both "((X op Y) op X) op Y" and
2792169689Skan		     "((X op Y) op Y) op X" as "T op T" where T is
2793169689Skan		     "X op Y".  */
2794169689Skan		  if ((rtx_equal_p (p,r) && rtx_equal_p (q,s))
2795169689Skan		       || (rtx_equal_p (p,s) && rtx_equal_p (q,r)))
2796169689Skan		    {
2797169689Skan		      newi2pat = gen_rtx_SET (VOIDmode, newdest,
2798169689Skan					      XEXP (src_op0, 0));
2799169689Skan		      SUBST (XEXP (setsrc, 0), newdest);
2800169689Skan		      SUBST (XEXP (setsrc, 1), newdest);
2801169689Skan		      subst_done = true;
2802169689Skan		    }
2803169689Skan		  /* Split "((X op X) op Y) op Y)" as "T op T" where
2804169689Skan		     T is "X op Y".  */
2805169689Skan		  else if (rtx_equal_p (p,q) && rtx_equal_p (r,s))
2806169689Skan		    {
2807169689Skan		      rtx tmp = simplify_gen_binary (code, mode, p, r);
2808169689Skan		      newi2pat = gen_rtx_SET (VOIDmode, newdest, tmp);
2809169689Skan		      SUBST (XEXP (setsrc, 0), newdest);
2810169689Skan		      SUBST (XEXP (setsrc, 1), newdest);
2811169689Skan		      subst_done = true;
2812169689Skan		    }
2813169689Skan		}
2814169689Skan	    }
2815169689Skan
2816169689Skan	  if (!subst_done)
2817169689Skan	    {
2818169689Skan	      newi2pat = gen_rtx_SET (VOIDmode, newdest, *split);
2819169689Skan	      SUBST (*split, newdest);
2820169689Skan	    }
2821169689Skan
282252284Sobrien	  i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
282318334Speter
2824169689Skan	  /* recog_for_combine might have added CLOBBERs to newi2pat.
2825169689Skan	     Make sure NEWPAT does not depend on the clobbered regs.  */
2826169689Skan	  if (GET_CODE (newi2pat) == PARALLEL)
2827169689Skan	    for (i = XVECLEN (newi2pat, 0) - 1; i >= 0; i--)
2828169689Skan	      if (GET_CODE (XVECEXP (newi2pat, 0, i)) == CLOBBER)
2829169689Skan		{
2830169689Skan		  rtx reg = XEXP (XVECEXP (newi2pat, 0, i), 0);
2831169689Skan		  if (reg_overlap_mentioned_p (reg, newpat))
2832169689Skan		    {
2833169689Skan		      undo_all ();
2834169689Skan		      return 0;
2835169689Skan		    }
2836169689Skan		}
2837169689Skan
283818334Speter	  /* If the split point was a MULT and we didn't have one before,
283918334Speter	     don't use one now.  */
284018334Speter	  if (i2_code_number >= 0 && ! (split_code == MULT && ! have_mult))
284152284Sobrien	    insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
284218334Speter	}
284318334Speter    }
284418334Speter
284518334Speter  /* Check for a case where we loaded from memory in a narrow mode and
284618334Speter     then sign extended it, but we need both registers.  In that case,
284718334Speter     we have a PARALLEL with both loads from the same memory location.
284818334Speter     We can split this into a load from memory followed by a register-register
284918334Speter     copy.  This saves at least one insn, more if register allocation can
285018334Speter     eliminate the copy.
285118334Speter
2852117395Skan     We cannot do this if the destination of the first assignment is a
2853117395Skan     condition code register or cc0.  We eliminate this case by making sure
2854117395Skan     the SET_DEST and SET_SRC have the same mode.
2855117395Skan
285618334Speter     We cannot do this if the destination of the second assignment is
285718334Speter     a register that we have already assumed is zero-extended.  Similarly
285818334Speter     for a SUBREG of such a register.  */
285918334Speter
286018334Speter  else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0
286118334Speter	   && GET_CODE (newpat) == PARALLEL
286218334Speter	   && XVECLEN (newpat, 0) == 2
286318334Speter	   && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
286418334Speter	   && GET_CODE (SET_SRC (XVECEXP (newpat, 0, 0))) == SIGN_EXTEND
2865117395Skan	   && (GET_MODE (SET_DEST (XVECEXP (newpat, 0, 0)))
2866117395Skan	       == GET_MODE (SET_SRC (XVECEXP (newpat, 0, 0))))
286718334Speter	   && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
286818334Speter	   && rtx_equal_p (SET_SRC (XVECEXP (newpat, 0, 1)),
286918334Speter			   XEXP (SET_SRC (XVECEXP (newpat, 0, 0)), 0))
287018334Speter	   && ! use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)),
287118334Speter				   INSN_CUID (i2))
287218334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT
287318334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
287418334Speter	   && ! (temp = SET_DEST (XVECEXP (newpat, 0, 1)),
2875169689Skan		 (REG_P (temp)
2876169689Skan		  && reg_stat[REGNO (temp)].nonzero_bits != 0
287718334Speter		  && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
287818334Speter		  && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
2879169689Skan		  && (reg_stat[REGNO (temp)].nonzero_bits
288018334Speter		      != GET_MODE_MASK (word_mode))))
288118334Speter	   && ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == SUBREG
288218334Speter		 && (temp = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1))),
2883169689Skan		     (REG_P (temp)
2884169689Skan		      && reg_stat[REGNO (temp)].nonzero_bits != 0
288518334Speter		      && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
288618334Speter		      && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
2887169689Skan		      && (reg_stat[REGNO (temp)].nonzero_bits
288818334Speter			  != GET_MODE_MASK (word_mode)))))
288918334Speter	   && ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1)),
289018334Speter					 SET_SRC (XVECEXP (newpat, 0, 1)))
289118334Speter	   && ! find_reg_note (i3, REG_UNUSED,
289218334Speter			       SET_DEST (XVECEXP (newpat, 0, 0))))
289318334Speter    {
289418334Speter      rtx ni2dest;
289518334Speter
289618334Speter      newi2pat = XVECEXP (newpat, 0, 0);
289718334Speter      ni2dest = SET_DEST (XVECEXP (newpat, 0, 0));
289818334Speter      newpat = XVECEXP (newpat, 0, 1);
289918334Speter      SUBST (SET_SRC (newpat),
2900169689Skan	     gen_lowpart (GET_MODE (SET_SRC (newpat)), ni2dest));
290152284Sobrien      i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
290218334Speter
290318334Speter      if (i2_code_number >= 0)
290452284Sobrien	insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
290518334Speter
290618334Speter      if (insn_code_number >= 0)
2907169689Skan	swap_i2i3 = 1;
290818334Speter    }
290990075Sobrien
291018334Speter  /* Similarly, check for a case where we have a PARALLEL of two independent
291118334Speter     SETs but we started with three insns.  In this case, we can do the sets
291218334Speter     as two separate insns.  This case occurs when some SET allows two
291318334Speter     other insns to combine, but the destination of that SET is still live.  */
291418334Speter
291518334Speter  else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0
291618334Speter	   && GET_CODE (newpat) == PARALLEL
291718334Speter	   && XVECLEN (newpat, 0) == 2
291818334Speter	   && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
291918334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != ZERO_EXTRACT
292018334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != STRICT_LOW_PART
292118334Speter	   && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
292218334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT
292318334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
292418334Speter	   && ! use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)),
292518334Speter				   INSN_CUID (i2))
292618334Speter	   && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 1)),
292718334Speter				  XVECEXP (newpat, 0, 0))
292818334Speter	   && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 0)),
292990075Sobrien				  XVECEXP (newpat, 0, 1))
293090075Sobrien	   && ! (contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 0)))
2931169689Skan		 && contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 1))))
2932169689Skan#ifdef HAVE_cc0
2933169689Skan	   /* We cannot split the parallel into two sets if both sets
2934169689Skan	      reference cc0.  */
2935169689Skan	   && ! (reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0))
2936169689Skan		 && reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 1)))
2937169689Skan#endif
2938169689Skan	   )
293918334Speter    {
294050397Sobrien      /* Normally, it doesn't matter which of the two is done first,
294150397Sobrien	 but it does if one references cc0.  In that case, it has to
294250397Sobrien	 be first.  */
294350397Sobrien#ifdef HAVE_cc0
294450397Sobrien      if (reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0)))
294550397Sobrien	{
294650397Sobrien	  newi2pat = XVECEXP (newpat, 0, 0);
294750397Sobrien	  newpat = XVECEXP (newpat, 0, 1);
294850397Sobrien	}
294950397Sobrien      else
295050397Sobrien#endif
295150397Sobrien	{
295250397Sobrien	  newi2pat = XVECEXP (newpat, 0, 1);
295350397Sobrien	  newpat = XVECEXP (newpat, 0, 0);
295450397Sobrien	}
295518334Speter
295652284Sobrien      i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
295718334Speter
295818334Speter      if (i2_code_number >= 0)
295952284Sobrien	insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
296018334Speter    }
296118334Speter
296218334Speter  /* If it still isn't recognized, fail and change things back the way they
296318334Speter     were.  */
296418334Speter  if ((insn_code_number < 0
296518334Speter       /* Is the result a reasonable ASM_OPERANDS?  */
296618334Speter       && (! check_asm_operands (newpat) || added_sets_1 || added_sets_2)))
296718334Speter    {
296818334Speter      undo_all ();
296918334Speter      return 0;
297018334Speter    }
297118334Speter
297218334Speter  /* If we had to change another insn, make sure it is valid also.  */
297318334Speter  if (undobuf.other_insn)
297418334Speter    {
297518334Speter      rtx other_pat = PATTERN (undobuf.other_insn);
297618334Speter      rtx new_other_notes;
297718334Speter      rtx note, next;
297818334Speter
297918334Speter      CLEAR_HARD_REG_SET (newpat_used_regs);
298018334Speter
298152284Sobrien      other_code_number = recog_for_combine (&other_pat, undobuf.other_insn,
298252284Sobrien					     &new_other_notes);
298318334Speter
298418334Speter      if (other_code_number < 0 && ! check_asm_operands (other_pat))
298518334Speter	{
298618334Speter	  undo_all ();
298718334Speter	  return 0;
298818334Speter	}
298918334Speter
299018334Speter      PATTERN (undobuf.other_insn) = other_pat;
299118334Speter
299218334Speter      /* If any of the notes in OTHER_INSN were REG_UNUSED, ensure that they
299318334Speter	 are still valid.  Then add any non-duplicate notes added by
299418334Speter	 recog_for_combine.  */
299518334Speter      for (note = REG_NOTES (undobuf.other_insn); note; note = next)
299618334Speter	{
299718334Speter	  next = XEXP (note, 1);
299818334Speter
299918334Speter	  if (REG_NOTE_KIND (note) == REG_UNUSED
300018334Speter	      && ! reg_set_p (XEXP (note, 0), PATTERN (undobuf.other_insn)))
300118334Speter	    {
3002169689Skan	      if (REG_P (XEXP (note, 0)))
300350397Sobrien		REG_N_DEATHS (REGNO (XEXP (note, 0)))--;
300418334Speter
300518334Speter	      remove_note (undobuf.other_insn, note);
300618334Speter	    }
300718334Speter	}
300818334Speter
300918334Speter      for (note = new_other_notes; note; note = XEXP (note, 1))
3010169689Skan	if (REG_P (XEXP (note, 0)))
301150397Sobrien	  REG_N_DEATHS (REGNO (XEXP (note, 0)))++;
301218334Speter
301318334Speter      distribute_notes (new_other_notes, undobuf.other_insn,
3014169689Skan			undobuf.other_insn, NULL_RTX, NULL_RTX, NULL_RTX);
301518334Speter    }
301690075Sobrien#ifdef HAVE_cc0
3017169689Skan  /* If I2 is the CC0 setter and I3 is the CC0 user then check whether
301890075Sobrien     they are adjacent to each other or not.  */
301990075Sobrien  {
302090075Sobrien    rtx p = prev_nonnote_insn (i3);
3021169689Skan    if (p && p != i2 && NONJUMP_INSN_P (p) && newi2pat
302290075Sobrien	&& sets_cc0_p (newi2pat))
302390075Sobrien      {
302490075Sobrien	undo_all ();
302590075Sobrien	return 0;
302690075Sobrien      }
302790075Sobrien  }
302890075Sobrien#endif
302918334Speter
3030169689Skan  /* Only allow this combination if insn_rtx_costs reports that the
3031169689Skan     replacement instructions are cheaper than the originals.  */
3032169689Skan  if (!combine_validate_cost (i1, i2, i3, newpat, newi2pat))
3033169689Skan    {
3034169689Skan      undo_all ();
3035169689Skan      return 0;
3036169689Skan    }
3037169689Skan
303890075Sobrien  /* We now know that we can do this combination.  Merge the insns and
303918334Speter     update the status of registers and LOG_LINKS.  */
304018334Speter
3041169689Skan  if (swap_i2i3)
3042169689Skan    {
3043169689Skan      rtx insn;
3044169689Skan      rtx link;
3045169689Skan      rtx ni2dest;
3046169689Skan
3047169689Skan      /* I3 now uses what used to be its destination and which is now
3048169689Skan	 I2's destination.  This requires us to do a few adjustments.  */
3049169689Skan      PATTERN (i3) = newpat;
3050169689Skan      adjust_for_new_dest (i3);
3051169689Skan
3052169689Skan      /* We need a LOG_LINK from I3 to I2.  But we used to have one,
3053169689Skan	 so we still will.
3054169689Skan
3055169689Skan	 However, some later insn might be using I2's dest and have
3056169689Skan	 a LOG_LINK pointing at I3.  We must remove this link.
3057169689Skan	 The simplest way to remove the link is to point it at I1,
3058169689Skan	 which we know will be a NOTE.  */
3059169689Skan
3060169689Skan      /* newi2pat is usually a SET here; however, recog_for_combine might
3061169689Skan	 have added some clobbers.  */
3062169689Skan      if (GET_CODE (newi2pat) == PARALLEL)
3063169689Skan	ni2dest = SET_DEST (XVECEXP (newi2pat, 0, 0));
3064169689Skan      else
3065169689Skan	ni2dest = SET_DEST (newi2pat);
3066169689Skan
3067169689Skan      for (insn = NEXT_INSN (i3);
3068169689Skan	   insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR
3069169689Skan		    || insn != BB_HEAD (this_basic_block->next_bb));
3070169689Skan	   insn = NEXT_INSN (insn))
3071169689Skan	{
3072169689Skan	  if (INSN_P (insn) && reg_referenced_p (ni2dest, PATTERN (insn)))
3073169689Skan	    {
3074169689Skan	      for (link = LOG_LINKS (insn); link;
3075169689Skan		   link = XEXP (link, 1))
3076169689Skan		if (XEXP (link, 0) == i3)
3077169689Skan		  XEXP (link, 0) = i1;
3078169689Skan
3079169689Skan	      break;
3080169689Skan	    }
3081169689Skan	}
3082169689Skan    }
3083169689Skan
308418334Speter  {
308518334Speter    rtx i3notes, i2notes, i1notes = 0;
308618334Speter    rtx i3links, i2links, i1links = 0;
308718334Speter    rtx midnotes = 0;
308890075Sobrien    unsigned int regno;
3089169689Skan    /* Compute which registers we expect to eliminate.  newi2pat may be setting
3090169689Skan       either i3dest or i2dest, so we must check it.  Also, i1dest may be the
3091169689Skan       same as i3dest, in which case newi2pat may be setting i1dest.  */
3092169689Skan    rtx elim_i2 = ((newi2pat && reg_set_p (i2dest, newi2pat))
3093169689Skan		   || i2dest_in_i2src || i2dest_in_i1src
3094169689Skan		   || !i2dest_killed
3095169689Skan		   ? 0 : i2dest);
3096169689Skan    rtx elim_i1 = (i1 == 0 || i1dest_in_i1src
3097169689Skan		   || (newi2pat && reg_set_p (i1dest, newi2pat))
3098169689Skan		   || !i1dest_killed
3099169689Skan		   ? 0 : i1dest);
310018334Speter
310118334Speter    /* Get the old REG_NOTES and LOG_LINKS from all our insns and
310218334Speter       clear them.  */
310318334Speter    i3notes = REG_NOTES (i3), i3links = LOG_LINKS (i3);
310418334Speter    i2notes = REG_NOTES (i2), i2links = LOG_LINKS (i2);
310518334Speter    if (i1)
310618334Speter      i1notes = REG_NOTES (i1), i1links = LOG_LINKS (i1);
310718334Speter
310818334Speter    /* Ensure that we do not have something that should not be shared but
310918334Speter       occurs multiple times in the new insns.  Check this by first
311018334Speter       resetting all the `used' flags and then copying anything is shared.  */
311118334Speter
311218334Speter    reset_used_flags (i3notes);
311318334Speter    reset_used_flags (i2notes);
311418334Speter    reset_used_flags (i1notes);
311518334Speter    reset_used_flags (newpat);
311618334Speter    reset_used_flags (newi2pat);
311718334Speter    if (undobuf.other_insn)
311818334Speter      reset_used_flags (PATTERN (undobuf.other_insn));
311918334Speter
312018334Speter    i3notes = copy_rtx_if_shared (i3notes);
312118334Speter    i2notes = copy_rtx_if_shared (i2notes);
312218334Speter    i1notes = copy_rtx_if_shared (i1notes);
312318334Speter    newpat = copy_rtx_if_shared (newpat);
312418334Speter    newi2pat = copy_rtx_if_shared (newi2pat);
312518334Speter    if (undobuf.other_insn)
312618334Speter      reset_used_flags (PATTERN (undobuf.other_insn));
312718334Speter
312818334Speter    INSN_CODE (i3) = insn_code_number;
312918334Speter    PATTERN (i3) = newpat;
313096263Sobrien
3131169689Skan    if (CALL_P (i3) && CALL_INSN_FUNCTION_USAGE (i3))
313296263Sobrien      {
313396263Sobrien	rtx call_usage = CALL_INSN_FUNCTION_USAGE (i3);
313496263Sobrien
313596263Sobrien	reset_used_flags (call_usage);
313696263Sobrien	call_usage = copy_rtx (call_usage);
313796263Sobrien
313896263Sobrien	if (substed_i2)
313996263Sobrien	  replace_rtx (call_usage, i2dest, i2src);
314096263Sobrien
314196263Sobrien	if (substed_i1)
314296263Sobrien	  replace_rtx (call_usage, i1dest, i1src);
314396263Sobrien
314496263Sobrien	CALL_INSN_FUNCTION_USAGE (i3) = call_usage;
314596263Sobrien      }
314696263Sobrien
314718334Speter    if (undobuf.other_insn)
314818334Speter      INSN_CODE (undobuf.other_insn) = other_code_number;
314918334Speter
315018334Speter    /* We had one special case above where I2 had more than one set and
315118334Speter       we replaced a destination of one of those sets with the destination
315218334Speter       of I3.  In that case, we have to update LOG_LINKS of insns later
315318334Speter       in this basic block.  Note that this (expensive) case is rare.
315418334Speter
315518334Speter       Also, in this case, we must pretend that all REG_NOTEs for I2
315618334Speter       actually came from I3, so that REG_UNUSED notes from I2 will be
315718334Speter       properly handled.  */
315818334Speter
315918334Speter    if (i3_subst_into_i2)
316018334Speter      {
316118334Speter	for (i = 0; i < XVECLEN (PATTERN (i2), 0); i++)
3162169689Skan	  if ((GET_CODE (XVECEXP (PATTERN (i2), 0, i)) == SET
3163169689Skan	       || GET_CODE (XVECEXP (PATTERN (i2), 0, i)) == CLOBBER)
3164169689Skan	      && REG_P (SET_DEST (XVECEXP (PATTERN (i2), 0, i)))
316518334Speter	      && SET_DEST (XVECEXP (PATTERN (i2), 0, i)) != i2dest
316618334Speter	      && ! find_reg_note (i2, REG_UNUSED,
316718334Speter				  SET_DEST (XVECEXP (PATTERN (i2), 0, i))))
316818334Speter	    for (temp = NEXT_INSN (i2);
3169117395Skan		 temp && (this_basic_block->next_bb == EXIT_BLOCK_PTR
3170132718Skan			  || BB_HEAD (this_basic_block) != temp);
317118334Speter		 temp = NEXT_INSN (temp))
317290075Sobrien	      if (temp != i3 && INSN_P (temp))
317318334Speter		for (link = LOG_LINKS (temp); link; link = XEXP (link, 1))
317418334Speter		  if (XEXP (link, 0) == i2)
317518334Speter		    XEXP (link, 0) = i3;
317618334Speter
317718334Speter	if (i3notes)
317818334Speter	  {
317918334Speter	    rtx link = i3notes;
318018334Speter	    while (XEXP (link, 1))
318118334Speter	      link = XEXP (link, 1);
318218334Speter	    XEXP (link, 1) = i2notes;
318318334Speter	  }
318418334Speter	else
318518334Speter	  i3notes = i2notes;
318618334Speter	i2notes = 0;
318718334Speter      }
318818334Speter
318918334Speter    LOG_LINKS (i3) = 0;
319018334Speter    REG_NOTES (i3) = 0;
319118334Speter    LOG_LINKS (i2) = 0;
319218334Speter    REG_NOTES (i2) = 0;
319318334Speter
319418334Speter    if (newi2pat)
319518334Speter      {
319618334Speter	INSN_CODE (i2) = i2_code_number;
319718334Speter	PATTERN (i2) = newi2pat;
319818334Speter      }
319918334Speter    else
3200169689Skan      SET_INSN_DELETED (i2);
320118334Speter
320218334Speter    if (i1)
320318334Speter      {
320418334Speter	LOG_LINKS (i1) = 0;
320518334Speter	REG_NOTES (i1) = 0;
3206169689Skan	SET_INSN_DELETED (i1);
320718334Speter      }
320818334Speter
320918334Speter    /* Get death notes for everything that is now used in either I3 or
321090075Sobrien       I2 and used to die in a previous insn.  If we built two new
321150397Sobrien       patterns, move from I1 to I2 then I2 to I3 so that we get the
321250397Sobrien       proper movement on registers that I2 modifies.  */
321318334Speter
321418334Speter    if (newi2pat)
321550397Sobrien      {
321650397Sobrien	move_deaths (newi2pat, NULL_RTX, INSN_CUID (i1), i2, &midnotes);
321750397Sobrien	move_deaths (newpat, newi2pat, INSN_CUID (i1), i3, &midnotes);
321850397Sobrien      }
321950397Sobrien    else
322050397Sobrien      move_deaths (newpat, NULL_RTX, i1 ? INSN_CUID (i1) : INSN_CUID (i2),
322150397Sobrien		   i3, &midnotes);
322218334Speter
322318334Speter    /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3.  */
322418334Speter    if (i3notes)
3225169689Skan      distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL_RTX,
3226169689Skan			elim_i2, elim_i1);
322718334Speter    if (i2notes)
3228169689Skan      distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL_RTX,
3229169689Skan			elim_i2, elim_i1);
323018334Speter    if (i1notes)
3231169689Skan      distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL_RTX,
3232169689Skan			elim_i2, elim_i1);
323318334Speter    if (midnotes)
3234169689Skan      distribute_notes (midnotes, NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
3235169689Skan			elim_i2, elim_i1);
323618334Speter
323718334Speter    /* Distribute any notes added to I2 or I3 by recog_for_combine.  We
323818334Speter       know these are REG_UNUSED and want them to go to the desired insn,
323990075Sobrien       so we always pass it as i3.  We have not counted the notes in
324018334Speter       reg_n_deaths yet, so we need to do so now.  */
324118334Speter
324218334Speter    if (newi2pat && new_i2_notes)
324318334Speter      {
324418334Speter	for (temp = new_i2_notes; temp; temp = XEXP (temp, 1))
3245169689Skan	  if (REG_P (XEXP (temp, 0)))
324650397Sobrien	    REG_N_DEATHS (REGNO (XEXP (temp, 0)))++;
324790075Sobrien
3248169689Skan	distribute_notes (new_i2_notes, i2, i2, NULL_RTX, NULL_RTX, NULL_RTX);
324918334Speter      }
325018334Speter
325118334Speter    if (new_i3_notes)
325218334Speter      {
325318334Speter	for (temp = new_i3_notes; temp; temp = XEXP (temp, 1))
3254169689Skan	  if (REG_P (XEXP (temp, 0)))
325550397Sobrien	    REG_N_DEATHS (REGNO (XEXP (temp, 0)))++;
325690075Sobrien
3257169689Skan	distribute_notes (new_i3_notes, i3, i3, NULL_RTX, NULL_RTX, NULL_RTX);
325818334Speter      }
325918334Speter
326018334Speter    /* If I3DEST was used in I3SRC, it really died in I3.  We may need to
326150397Sobrien       put a REG_DEAD note for it somewhere.  If NEWI2PAT exists and sets
326250397Sobrien       I3DEST, the death must be somewhere before I2, not I3.  If we passed I3
326350397Sobrien       in that case, it might delete I2.  Similarly for I2 and I1.
326418334Speter       Show an additional death due to the REG_DEAD note we make here.  If
326518334Speter       we discard it in distribute_notes, we will decrement it again.  */
326618334Speter
326718334Speter    if (i3dest_killed)
326818334Speter      {
3269169689Skan	if (REG_P (i3dest_killed))
327050397Sobrien	  REG_N_DEATHS (REGNO (i3dest_killed))++;
327118334Speter
327250397Sobrien	if (newi2pat && reg_set_p (i3dest_killed, newi2pat))
327350397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed,
327450397Sobrien					       NULL_RTX),
3275169689Skan			    NULL_RTX, i2, NULL_RTX, elim_i2, elim_i1);
327650397Sobrien	else
327750397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed,
327850397Sobrien					       NULL_RTX),
3279169689Skan			    NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
3280169689Skan			    elim_i2, elim_i1);
328118334Speter      }
328218334Speter
328318334Speter    if (i2dest_in_i2src)
328418334Speter      {
3285169689Skan	if (REG_P (i2dest))
328650397Sobrien	  REG_N_DEATHS (REGNO (i2dest))++;
328718334Speter
328818334Speter	if (newi2pat && reg_set_p (i2dest, newi2pat))
328950397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX),
3290169689Skan			    NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX);
329118334Speter	else
329250397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX),
3293169689Skan			    NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
3294169689Skan			    NULL_RTX, NULL_RTX);
329518334Speter      }
329618334Speter
329718334Speter    if (i1dest_in_i1src)
329818334Speter      {
3299169689Skan	if (REG_P (i1dest))
330050397Sobrien	  REG_N_DEATHS (REGNO (i1dest))++;
330118334Speter
330218334Speter	if (newi2pat && reg_set_p (i1dest, newi2pat))
330350397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX),
3304169689Skan			    NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX);
330518334Speter	else
330650397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX),
3307169689Skan			    NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
3308169689Skan			    NULL_RTX, NULL_RTX);
330918334Speter      }
331018334Speter
331118334Speter    distribute_links (i3links);
331218334Speter    distribute_links (i2links);
331318334Speter    distribute_links (i1links);
331418334Speter
3315169689Skan    if (REG_P (i2dest))
331618334Speter      {
331718334Speter	rtx link;
331818334Speter	rtx i2_insn = 0, i2_val = 0, set;
331918334Speter
332018334Speter	/* The insn that used to set this register doesn't exist, and
332118334Speter	   this life of the register may not exist either.  See if one of
332290075Sobrien	   I3's links points to an insn that sets I2DEST.  If it does,
332318334Speter	   that is now the last known value for I2DEST. If we don't update
332418334Speter	   this and I2 set the register to a value that depended on its old
332518334Speter	   contents, we will get confused.  If this insn is used, thing
332618334Speter	   will be set correctly in combine_instructions.  */
332718334Speter
332818334Speter	for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
332918334Speter	  if ((set = single_set (XEXP (link, 0))) != 0
333018334Speter	      && rtx_equal_p (i2dest, SET_DEST (set)))
333118334Speter	    i2_insn = XEXP (link, 0), i2_val = SET_SRC (set);
333218334Speter
333318334Speter	record_value_for_reg (i2dest, i2_insn, i2_val);
333418334Speter
333518334Speter	/* If the reg formerly set in I2 died only once and that was in I3,
333618334Speter	   zero its use count so it won't make `reload' do any work.  */
333750397Sobrien	if (! added_sets_2
333850397Sobrien	    && (newi2pat == 0 || ! reg_mentioned_p (i2dest, newi2pat))
333950397Sobrien	    && ! i2dest_in_i2src)
334018334Speter	  {
334118334Speter	    regno = REGNO (i2dest);
334250397Sobrien	    REG_N_SETS (regno)--;
334318334Speter	  }
334418334Speter      }
334518334Speter
3346169689Skan    if (i1 && REG_P (i1dest))
334718334Speter      {
334818334Speter	rtx link;
334918334Speter	rtx i1_insn = 0, i1_val = 0, set;
335018334Speter
335118334Speter	for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
335218334Speter	  if ((set = single_set (XEXP (link, 0))) != 0
335318334Speter	      && rtx_equal_p (i1dest, SET_DEST (set)))
335418334Speter	    i1_insn = XEXP (link, 0), i1_val = SET_SRC (set);
335518334Speter
335618334Speter	record_value_for_reg (i1dest, i1_insn, i1_val);
335718334Speter
335818334Speter	regno = REGNO (i1dest);
335918334Speter	if (! added_sets_1 && ! i1dest_in_i1src)
336090075Sobrien	  REG_N_SETS (regno)--;
336118334Speter      }
336218334Speter
3363169689Skan    /* Update reg_stat[].nonzero_bits et al for any changes that may have
3364169689Skan       been made to this insn.  The order of
3365169689Skan       set_nonzero_bits_and_sign_copies() is important.  Because newi2pat
3366169689Skan       can affect nonzero_bits of newpat */
336718334Speter    if (newi2pat)
336890075Sobrien      note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
336990075Sobrien    note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
337018334Speter
337190075Sobrien    /* Set new_direct_jump_p if a new return or simple jump instruction
337290075Sobrien       has been created.
337390075Sobrien
337490075Sobrien       If I3 is now an unconditional jump, ensure that it has a
337518334Speter       BARRIER following it since it may have initially been a
337618334Speter       conditional jump.  It may also be the last nonnote insn.  */
337718334Speter
3378117395Skan    if (returnjump_p (i3) || any_uncondjump_p (i3))
337990075Sobrien      {
338090075Sobrien	*new_direct_jump_p = 1;
3381132718Skan	mark_jump_label (PATTERN (i3), i3, 0);
338290075Sobrien
338390075Sobrien	if ((temp = next_nonnote_insn (i3)) == NULL_RTX
3384169689Skan	    || !BARRIER_P (temp))
338590075Sobrien	  emit_barrier_after (i3);
338690075Sobrien      }
3387117395Skan
3388117395Skan    if (undobuf.other_insn != NULL_RTX
3389117395Skan	&& (returnjump_p (undobuf.other_insn)
3390117395Skan	    || any_uncondjump_p (undobuf.other_insn)))
3391117395Skan      {
3392117395Skan	*new_direct_jump_p = 1;
3393117395Skan
3394117395Skan	if ((temp = next_nonnote_insn (undobuf.other_insn)) == NULL_RTX
3395169689Skan	    || !BARRIER_P (temp))
3396117395Skan	  emit_barrier_after (undobuf.other_insn);
3397117395Skan      }
3398132718Skan
339990075Sobrien    /* An NOOP jump does not need barrier, but it does need cleaning up
340090075Sobrien       of CFG.  */
340190075Sobrien    if (GET_CODE (newpat) == SET
340290075Sobrien	&& SET_SRC (newpat) == pc_rtx
340390075Sobrien	&& SET_DEST (newpat) == pc_rtx)
340490075Sobrien      *new_direct_jump_p = 1;
340518334Speter  }
340618334Speter
340718334Speter  combine_successes++;
340890075Sobrien  undo_commit ();
340918334Speter
341018334Speter  if (added_links_insn
341118334Speter      && (newi2pat == 0 || INSN_CUID (added_links_insn) < INSN_CUID (i2))
341218334Speter      && INSN_CUID (added_links_insn) < INSN_CUID (i3))
341318334Speter    return added_links_insn;
341418334Speter  else
341518334Speter    return newi2pat ? i2 : i3;
341618334Speter}
341718334Speter
341818334Speter/* Undo all the modifications recorded in undobuf.  */
341918334Speter
342018334Speterstatic void
3421132718Skanundo_all (void)
342218334Speter{
342350397Sobrien  struct undo *undo, *next;
342450397Sobrien
342550397Sobrien  for (undo = undobuf.undos; undo; undo = next)
342618334Speter    {
342750397Sobrien      next = undo->next;
3428169689Skan      switch (undo->kind)
3429169689Skan	{
3430169689Skan	case UNDO_RTX:
3431169689Skan	  *undo->where.r = undo->old_contents.r;
3432169689Skan	  break;
3433169689Skan	case UNDO_INT:
3434169689Skan	  *undo->where.i = undo->old_contents.i;
3435169689Skan	  break;
3436169689Skan	case UNDO_MODE:
3437169689Skan	  PUT_MODE (*undo->where.r, undo->old_contents.m);
3438169689Skan	  break;
3439169689Skan	default:
3440169689Skan	  gcc_unreachable ();
3441169689Skan	}
344250397Sobrien
344350397Sobrien      undo->next = undobuf.frees;
344450397Sobrien      undobuf.frees = undo;
344518334Speter    }
344618334Speter
344790075Sobrien  undobuf.undos = 0;
344818334Speter}
344990075Sobrien
345090075Sobrien/* We've committed to accepting the changes we made.  Move all
345190075Sobrien   of the undos to the free list.  */
345290075Sobrien
345390075Sobrienstatic void
3454132718Skanundo_commit (void)
345590075Sobrien{
345690075Sobrien  struct undo *undo, *next;
345790075Sobrien
345890075Sobrien  for (undo = undobuf.undos; undo; undo = next)
345990075Sobrien    {
346090075Sobrien      next = undo->next;
346190075Sobrien      undo->next = undobuf.frees;
346290075Sobrien      undobuf.frees = undo;
346390075Sobrien    }
346490075Sobrien  undobuf.undos = 0;
346590075Sobrien}
346618334Speter
346718334Speter/* Find the innermost point within the rtx at LOC, possibly LOC itself,
346818334Speter   where we have an arithmetic expression and return that point.  LOC will
346918334Speter   be inside INSN.
347018334Speter
347118334Speter   try_combine will call this function to see if an insn can be split into
347218334Speter   two insns.  */
347318334Speter
347418334Speterstatic rtx *
3475132718Skanfind_split_point (rtx *loc, rtx insn)
347618334Speter{
347718334Speter  rtx x = *loc;
347818334Speter  enum rtx_code code = GET_CODE (x);
347918334Speter  rtx *split;
348090075Sobrien  unsigned HOST_WIDE_INT len = 0;
348190075Sobrien  HOST_WIDE_INT pos = 0;
348290075Sobrien  int unsignedp = 0;
348390075Sobrien  rtx inner = NULL_RTX;
348418334Speter
348518334Speter  /* First special-case some codes.  */
348618334Speter  switch (code)
348718334Speter    {
348818334Speter    case SUBREG:
348918334Speter#ifdef INSN_SCHEDULING
349018334Speter      /* If we are making a paradoxical SUBREG invalid, it becomes a split
349118334Speter	 point.  */
3492169689Skan      if (MEM_P (SUBREG_REG (x)))
349318334Speter	return loc;
349418334Speter#endif
349518334Speter      return find_split_point (&SUBREG_REG (x), insn);
349618334Speter
349718334Speter    case MEM:
349818334Speter#ifdef HAVE_lo_sum
349918334Speter      /* If we have (mem (const ..)) or (mem (symbol_ref ...)), split it
350018334Speter	 using LO_SUM and HIGH.  */
350118334Speter      if (GET_CODE (XEXP (x, 0)) == CONST
350218334Speter	  || GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
350318334Speter	{
350418334Speter	  SUBST (XEXP (x, 0),
350590075Sobrien		 gen_rtx_LO_SUM (Pmode,
350690075Sobrien				 gen_rtx_HIGH (Pmode, XEXP (x, 0)),
350790075Sobrien				 XEXP (x, 0)));
350818334Speter	  return &XEXP (XEXP (x, 0), 0);
350918334Speter	}
351018334Speter#endif
351118334Speter
351218334Speter      /* If we have a PLUS whose second operand is a constant and the
351318334Speter	 address is not valid, perhaps will can split it up using
351418334Speter	 the machine-specific way to split large constants.  We use
351518334Speter	 the first pseudo-reg (one of the virtual regs) as a placeholder;
351618334Speter	 it will not remain in the result.  */
351718334Speter      if (GET_CODE (XEXP (x, 0)) == PLUS
351818334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
351918334Speter	  && ! memory_address_p (GET_MODE (x), XEXP (x, 0)))
352018334Speter	{
352118334Speter	  rtx reg = regno_reg_rtx[FIRST_PSEUDO_REGISTER];
352250397Sobrien	  rtx seq = split_insns (gen_rtx_SET (VOIDmode, reg, XEXP (x, 0)),
352318334Speter				 subst_insn);
352418334Speter
352518334Speter	  /* This should have produced two insns, each of which sets our
352618334Speter	     placeholder.  If the source of the second is a valid address,
352718334Speter	     we can make put both sources together and make a split point
352818334Speter	     in the middle.  */
352918334Speter
3530117395Skan	  if (seq
3531117395Skan	      && NEXT_INSN (seq) != NULL_RTX
3532117395Skan	      && NEXT_INSN (NEXT_INSN (seq)) == NULL_RTX
3533169689Skan	      && NONJUMP_INSN_P (seq)
3534117395Skan	      && GET_CODE (PATTERN (seq)) == SET
3535117395Skan	      && SET_DEST (PATTERN (seq)) == reg
353618334Speter	      && ! reg_mentioned_p (reg,
3537117395Skan				    SET_SRC (PATTERN (seq)))
3538169689Skan	      && NONJUMP_INSN_P (NEXT_INSN (seq))
3539117395Skan	      && GET_CODE (PATTERN (NEXT_INSN (seq))) == SET
3540117395Skan	      && SET_DEST (PATTERN (NEXT_INSN (seq))) == reg
354118334Speter	      && memory_address_p (GET_MODE (x),
3542117395Skan				   SET_SRC (PATTERN (NEXT_INSN (seq)))))
354318334Speter	    {
3544117395Skan	      rtx src1 = SET_SRC (PATTERN (seq));
3545117395Skan	      rtx src2 = SET_SRC (PATTERN (NEXT_INSN (seq)));
354618334Speter
354718334Speter	      /* Replace the placeholder in SRC2 with SRC1.  If we can
354818334Speter		 find where in SRC2 it was placed, that can become our
354918334Speter		 split point and we can replace this address with SRC2.
355018334Speter		 Just try two obvious places.  */
355118334Speter
355218334Speter	      src2 = replace_rtx (src2, reg, src1);
355318334Speter	      split = 0;
355418334Speter	      if (XEXP (src2, 0) == src1)
355518334Speter		split = &XEXP (src2, 0);
355618334Speter	      else if (GET_RTX_FORMAT (GET_CODE (XEXP (src2, 0)))[0] == 'e'
355718334Speter		       && XEXP (XEXP (src2, 0), 0) == src1)
355818334Speter		split = &XEXP (XEXP (src2, 0), 0);
355918334Speter
356018334Speter	      if (split)
356118334Speter		{
356218334Speter		  SUBST (XEXP (x, 0), src2);
356318334Speter		  return split;
356418334Speter		}
356518334Speter	    }
356690075Sobrien
356718334Speter	  /* If that didn't work, perhaps the first operand is complex and
356818334Speter	     needs to be computed separately, so make a split point there.
356918334Speter	     This will occur on machines that just support REG + CONST
357018334Speter	     and have a constant moved through some previous computation.  */
357118334Speter
3572169689Skan	  else if (!OBJECT_P (XEXP (XEXP (x, 0), 0))
357318334Speter		   && ! (GET_CODE (XEXP (XEXP (x, 0), 0)) == SUBREG
3574169689Skan			 && OBJECT_P (SUBREG_REG (XEXP (XEXP (x, 0), 0)))))
357518334Speter	    return &XEXP (XEXP (x, 0), 0);
357618334Speter	}
357718334Speter      break;
357818334Speter
357918334Speter    case SET:
358018334Speter#ifdef HAVE_cc0
358118334Speter      /* If SET_DEST is CC0 and SET_SRC is not an operand, a COMPARE, or a
358218334Speter	 ZERO_EXTRACT, the most likely reason why this doesn't match is that
358318334Speter	 we need to put the operand into a register.  So split at that
358418334Speter	 point.  */
358518334Speter
358618334Speter      if (SET_DEST (x) == cc0_rtx
358718334Speter	  && GET_CODE (SET_SRC (x)) != COMPARE
358818334Speter	  && GET_CODE (SET_SRC (x)) != ZERO_EXTRACT
3589169689Skan	  && !OBJECT_P (SET_SRC (x))
359018334Speter	  && ! (GET_CODE (SET_SRC (x)) == SUBREG
3591169689Skan		&& OBJECT_P (SUBREG_REG (SET_SRC (x)))))
359218334Speter	return &SET_SRC (x);
359318334Speter#endif
359418334Speter
359518334Speter      /* See if we can split SET_SRC as it stands.  */
359618334Speter      split = find_split_point (&SET_SRC (x), insn);
359718334Speter      if (split && split != &SET_SRC (x))
359818334Speter	return split;
359918334Speter
360050397Sobrien      /* See if we can split SET_DEST as it stands.  */
360150397Sobrien      split = find_split_point (&SET_DEST (x), insn);
360250397Sobrien      if (split && split != &SET_DEST (x))
360350397Sobrien	return split;
360450397Sobrien
360518334Speter      /* See if this is a bitfield assignment with everything constant.  If
360618334Speter	 so, this is an IOR of an AND, so split it into that.  */
360718334Speter      if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
360818334Speter	  && (GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0)))
360918334Speter	      <= HOST_BITS_PER_WIDE_INT)
361018334Speter	  && GET_CODE (XEXP (SET_DEST (x), 1)) == CONST_INT
361118334Speter	  && GET_CODE (XEXP (SET_DEST (x), 2)) == CONST_INT
361218334Speter	  && GET_CODE (SET_SRC (x)) == CONST_INT
361318334Speter	  && ((INTVAL (XEXP (SET_DEST (x), 1))
361490075Sobrien	       + INTVAL (XEXP (SET_DEST (x), 2)))
361518334Speter	      <= GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0))))
361618334Speter	  && ! side_effects_p (XEXP (SET_DEST (x), 0)))
361718334Speter	{
361890075Sobrien	  HOST_WIDE_INT pos = INTVAL (XEXP (SET_DEST (x), 2));
361990075Sobrien	  unsigned HOST_WIDE_INT len = INTVAL (XEXP (SET_DEST (x), 1));
362090075Sobrien	  unsigned HOST_WIDE_INT src = INTVAL (SET_SRC (x));
362118334Speter	  rtx dest = XEXP (SET_DEST (x), 0);
362218334Speter	  enum machine_mode mode = GET_MODE (dest);
362318334Speter	  unsigned HOST_WIDE_INT mask = ((HOST_WIDE_INT) 1 << len) - 1;
3624169689Skan	  rtx or_mask;
362518334Speter
362618334Speter	  if (BITS_BIG_ENDIAN)
362718334Speter	    pos = GET_MODE_BITSIZE (mode) - len - pos;
362818334Speter
3629169689Skan	  or_mask = gen_int_mode (src << pos, mode);
363090075Sobrien	  if (src == mask)
363118334Speter	    SUBST (SET_SRC (x),
3632169689Skan		   simplify_gen_binary (IOR, mode, dest, or_mask));
363318334Speter	  else
3634169689Skan	    {
3635169689Skan	      rtx negmask = gen_int_mode (~(mask << pos), mode);
3636169689Skan	      SUBST (SET_SRC (x),
3637169689Skan		     simplify_gen_binary (IOR, mode,
3638169689Skan					  simplify_gen_binary (AND, mode,
3639169689Skan							       dest, negmask),
3640169689Skan					  or_mask));
3641169689Skan	    }
364218334Speter
364318334Speter	  SUBST (SET_DEST (x), dest);
364418334Speter
364518334Speter	  split = find_split_point (&SET_SRC (x), insn);
364618334Speter	  if (split && split != &SET_SRC (x))
364718334Speter	    return split;
364818334Speter	}
364918334Speter
365018334Speter      /* Otherwise, see if this is an operation that we can split into two.
365118334Speter	 If so, try to split that.  */
365218334Speter      code = GET_CODE (SET_SRC (x));
365318334Speter
365418334Speter      switch (code)
365518334Speter	{
365618334Speter	case AND:
365718334Speter	  /* If we are AND'ing with a large constant that is only a single
365818334Speter	     bit and the result is only being used in a context where we
3659117395Skan	     need to know if it is zero or nonzero, replace it with a bit
366018334Speter	     extraction.  This will avoid the large constant, which might
366118334Speter	     have taken more than one insn to make.  If the constant were
366218334Speter	     not a valid argument to the AND but took only one insn to make,
366318334Speter	     this is no worse, but if it took more than one insn, it will
366418334Speter	     be better.  */
366518334Speter
366618334Speter	  if (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
3667169689Skan	      && REG_P (XEXP (SET_SRC (x), 0))
366818334Speter	      && (pos = exact_log2 (INTVAL (XEXP (SET_SRC (x), 1)))) >= 7
3669169689Skan	      && REG_P (SET_DEST (x))
367090075Sobrien	      && (split = find_single_use (SET_DEST (x), insn, (rtx*) 0)) != 0
367118334Speter	      && (GET_CODE (*split) == EQ || GET_CODE (*split) == NE)
367218334Speter	      && XEXP (*split, 0) == SET_DEST (x)
367318334Speter	      && XEXP (*split, 1) == const0_rtx)
367418334Speter	    {
367550397Sobrien	      rtx extraction = make_extraction (GET_MODE (SET_DEST (x)),
367650397Sobrien						XEXP (SET_SRC (x), 0),
367750397Sobrien						pos, NULL_RTX, 1, 1, 0, 0);
367850397Sobrien	      if (extraction != 0)
367950397Sobrien		{
368050397Sobrien		  SUBST (SET_SRC (x), extraction);
368150397Sobrien		  return find_split_point (loc, insn);
368250397Sobrien		}
368350397Sobrien	    }
368450397Sobrien	  break;
368550397Sobrien
368650397Sobrien	case NE:
3687132718Skan	  /* If STORE_FLAG_VALUE is -1, this is (NE X 0) and only one bit of X
368890075Sobrien	     is known to be on, this can be converted into a NEG of a shift.  */
368950397Sobrien	  if (STORE_FLAG_VALUE == -1 && XEXP (SET_SRC (x), 1) == const0_rtx
369050397Sobrien	      && GET_MODE (SET_SRC (x)) == GET_MODE (XEXP (SET_SRC (x), 0))
369150397Sobrien	      && 1 <= (pos = exact_log2
369250397Sobrien		       (nonzero_bits (XEXP (SET_SRC (x), 0),
369350397Sobrien				      GET_MODE (XEXP (SET_SRC (x), 0))))))
369450397Sobrien	    {
369550397Sobrien	      enum machine_mode mode = GET_MODE (XEXP (SET_SRC (x), 0));
369650397Sobrien
369718334Speter	      SUBST (SET_SRC (x),
369890075Sobrien		     gen_rtx_NEG (mode,
369990075Sobrien				  gen_rtx_LSHIFTRT (mode,
370090075Sobrien						    XEXP (SET_SRC (x), 0),
370190075Sobrien						    GEN_INT (pos))));
370250397Sobrien
370350397Sobrien	      split = find_split_point (&SET_SRC (x), insn);
370450397Sobrien	      if (split && split != &SET_SRC (x))
370550397Sobrien		return split;
370618334Speter	    }
370718334Speter	  break;
370818334Speter
370918334Speter	case SIGN_EXTEND:
371018334Speter	  inner = XEXP (SET_SRC (x), 0);
371150397Sobrien
371250397Sobrien	  /* We can't optimize if either mode is a partial integer
371350397Sobrien	     mode as we don't know how many bits are significant
371450397Sobrien	     in those modes.  */
371550397Sobrien	  if (GET_MODE_CLASS (GET_MODE (inner)) == MODE_PARTIAL_INT
371650397Sobrien	      || GET_MODE_CLASS (GET_MODE (SET_SRC (x))) == MODE_PARTIAL_INT)
371750397Sobrien	    break;
371850397Sobrien
371918334Speter	  pos = 0;
372018334Speter	  len = GET_MODE_BITSIZE (GET_MODE (inner));
372118334Speter	  unsignedp = 0;
372218334Speter	  break;
372318334Speter
372418334Speter	case SIGN_EXTRACT:
372518334Speter	case ZERO_EXTRACT:
372618334Speter	  if (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
372718334Speter	      && GET_CODE (XEXP (SET_SRC (x), 2)) == CONST_INT)
372818334Speter	    {
372918334Speter	      inner = XEXP (SET_SRC (x), 0);
373018334Speter	      len = INTVAL (XEXP (SET_SRC (x), 1));
373118334Speter	      pos = INTVAL (XEXP (SET_SRC (x), 2));
373218334Speter
373318334Speter	      if (BITS_BIG_ENDIAN)
373418334Speter		pos = GET_MODE_BITSIZE (GET_MODE (inner)) - len - pos;
373518334Speter	      unsignedp = (code == ZERO_EXTRACT);
373618334Speter	    }
373718334Speter	  break;
373850397Sobrien
373950397Sobrien	default:
374050397Sobrien	  break;
374118334Speter	}
374218334Speter
374318334Speter      if (len && pos >= 0 && pos + len <= GET_MODE_BITSIZE (GET_MODE (inner)))
374418334Speter	{
374518334Speter	  enum machine_mode mode = GET_MODE (SET_SRC (x));
374618334Speter
374718334Speter	  /* For unsigned, we have a choice of a shift followed by an
374818334Speter	     AND or two shifts.  Use two shifts for field sizes where the
374918334Speter	     constant might be too large.  We assume here that we can
375018334Speter	     always at least get 8-bit constants in an AND insn, which is
375118334Speter	     true for every current RISC.  */
375218334Speter
375318334Speter	  if (unsignedp && len <= 8)
375418334Speter	    {
375518334Speter	      SUBST (SET_SRC (x),
375690075Sobrien		     gen_rtx_AND (mode,
375790075Sobrien				  gen_rtx_LSHIFTRT
3758169689Skan				  (mode, gen_lowpart (mode, inner),
375990075Sobrien				   GEN_INT (pos)),
376090075Sobrien				  GEN_INT (((HOST_WIDE_INT) 1 << len) - 1)));
376118334Speter
376218334Speter	      split = find_split_point (&SET_SRC (x), insn);
376318334Speter	      if (split && split != &SET_SRC (x))
376418334Speter		return split;
376518334Speter	    }
376618334Speter	  else
376718334Speter	    {
376818334Speter	      SUBST (SET_SRC (x),
376990075Sobrien		     gen_rtx_fmt_ee
377018334Speter		     (unsignedp ? LSHIFTRT : ASHIFTRT, mode,
377190075Sobrien		      gen_rtx_ASHIFT (mode,
3772169689Skan				      gen_lowpart (mode, inner),
377390075Sobrien				      GEN_INT (GET_MODE_BITSIZE (mode)
377490075Sobrien					       - len - pos)),
377518334Speter		      GEN_INT (GET_MODE_BITSIZE (mode) - len)));
377618334Speter
377718334Speter	      split = find_split_point (&SET_SRC (x), insn);
377818334Speter	      if (split && split != &SET_SRC (x))
377918334Speter		return split;
378018334Speter	    }
378118334Speter	}
378218334Speter
378318334Speter      /* See if this is a simple operation with a constant as the second
378418334Speter	 operand.  It might be that this constant is out of range and hence
378518334Speter	 could be used as a split point.  */
3786169689Skan      if (BINARY_P (SET_SRC (x))
378718334Speter	  && CONSTANT_P (XEXP (SET_SRC (x), 1))
3788169689Skan	  && (OBJECT_P (XEXP (SET_SRC (x), 0))
378918334Speter	      || (GET_CODE (XEXP (SET_SRC (x), 0)) == SUBREG
3790169689Skan		  && OBJECT_P (SUBREG_REG (XEXP (SET_SRC (x), 0))))))
379118334Speter	return &XEXP (SET_SRC (x), 1);
379218334Speter
379318334Speter      /* Finally, see if this is a simple operation with its first operand
379418334Speter	 not in a register.  The operation might require this operand in a
379518334Speter	 register, so return it as a split point.  We can always do this
379618334Speter	 because if the first operand were another operation, we would have
379718334Speter	 already found it as a split point.  */
3798169689Skan      if ((BINARY_P (SET_SRC (x)) || UNARY_P (SET_SRC (x)))
379918334Speter	  && ! register_operand (XEXP (SET_SRC (x), 0), VOIDmode))
380018334Speter	return &XEXP (SET_SRC (x), 0);
380118334Speter
380218334Speter      return 0;
380318334Speter
380418334Speter    case AND:
380518334Speter    case IOR:
380618334Speter      /* We write NOR as (and (not A) (not B)), but if we don't have a NOR,
380718334Speter	 it is better to write this as (not (ior A B)) so we can split it.
380818334Speter	 Similarly for IOR.  */
380918334Speter      if (GET_CODE (XEXP (x, 0)) == NOT && GET_CODE (XEXP (x, 1)) == NOT)
381018334Speter	{
381118334Speter	  SUBST (*loc,
381290075Sobrien		 gen_rtx_NOT (GET_MODE (x),
381390075Sobrien			      gen_rtx_fmt_ee (code == IOR ? AND : IOR,
381490075Sobrien					      GET_MODE (x),
381590075Sobrien					      XEXP (XEXP (x, 0), 0),
381690075Sobrien					      XEXP (XEXP (x, 1), 0))));
381718334Speter	  return find_split_point (loc, insn);
381818334Speter	}
381918334Speter
382018334Speter      /* Many RISC machines have a large set of logical insns.  If the
382118334Speter	 second operand is a NOT, put it first so we will try to split the
382218334Speter	 other operand first.  */
382318334Speter      if (GET_CODE (XEXP (x, 1)) == NOT)
382418334Speter	{
382518334Speter	  rtx tem = XEXP (x, 0);
382618334Speter	  SUBST (XEXP (x, 0), XEXP (x, 1));
382718334Speter	  SUBST (XEXP (x, 1), tem);
382818334Speter	}
382918334Speter      break;
383050397Sobrien
383150397Sobrien    default:
383250397Sobrien      break;
383318334Speter    }
383418334Speter
383518334Speter  /* Otherwise, select our actions depending on our rtx class.  */
383618334Speter  switch (GET_RTX_CLASS (code))
383718334Speter    {
3838169689Skan    case RTX_BITFIELD_OPS:		/* This is ZERO_EXTRACT and SIGN_EXTRACT.  */
3839169689Skan    case RTX_TERNARY:
384018334Speter      split = find_split_point (&XEXP (x, 2), insn);
384118334Speter      if (split)
384218334Speter	return split;
384350397Sobrien      /* ... fall through ...  */
3844169689Skan    case RTX_BIN_ARITH:
3845169689Skan    case RTX_COMM_ARITH:
3846169689Skan    case RTX_COMPARE:
3847169689Skan    case RTX_COMM_COMPARE:
384818334Speter      split = find_split_point (&XEXP (x, 1), insn);
384918334Speter      if (split)
385018334Speter	return split;
385150397Sobrien      /* ... fall through ...  */
3852169689Skan    case RTX_UNARY:
385318334Speter      /* Some machines have (and (shift ...) ...) insns.  If X is not
385418334Speter	 an AND, but XEXP (X, 0) is, use it as our split point.  */
385518334Speter      if (GET_CODE (x) != AND && GET_CODE (XEXP (x, 0)) == AND)
385618334Speter	return &XEXP (x, 0);
385718334Speter
385818334Speter      split = find_split_point (&XEXP (x, 0), insn);
385918334Speter      if (split)
386018334Speter	return split;
386118334Speter      return loc;
3862169689Skan
3863169689Skan    default:
3864169689Skan      /* Otherwise, we don't have a split point.  */
3865169689Skan      return 0;
386618334Speter    }
386718334Speter}
386818334Speter
386918334Speter/* Throughout X, replace FROM with TO, and return the result.
387018334Speter   The result is TO if X is FROM;
387118334Speter   otherwise the result is X, but its contents may have been modified.
387218334Speter   If they were modified, a record was made in undobuf so that
387318334Speter   undo_all will (among other things) return X to its original state.
387418334Speter
387518334Speter   If the number of changes necessary is too much to record to undo,
387618334Speter   the excess changes are not made, so the result is invalid.
387718334Speter   The changes already made can still be undone.
387818334Speter   undobuf.num_undo is incremented for such changes, so by testing that
387918334Speter   the caller can tell whether the result is valid.
388018334Speter
388118334Speter   `n_occurrences' is incremented each time FROM is replaced.
388290075Sobrien
3883117395Skan   IN_DEST is nonzero if we are processing the SET_DEST of a SET.
388418334Speter
3885117395Skan   UNIQUE_COPY is nonzero if each substitution must be unique.  We do this
3886117395Skan   by copying if `n_occurrences' is nonzero.  */
388718334Speter
388818334Speterstatic rtx
3889132718Skansubst (rtx x, rtx from, rtx to, int in_dest, int unique_copy)
389018334Speter{
389190075Sobrien  enum rtx_code code = GET_CODE (x);
389218334Speter  enum machine_mode op0_mode = VOIDmode;
389390075Sobrien  const char *fmt;
389490075Sobrien  int len, i;
389518334Speter  rtx new;
389618334Speter
389718334Speter/* Two expressions are equal if they are identical copies of a shared
389818334Speter   RTX or if they are both registers with the same register number
389918334Speter   and mode.  */
390018334Speter
390118334Speter#define COMBINE_RTX_EQUAL_P(X,Y)			\
390218334Speter  ((X) == (Y)						\
3903169689Skan   || (REG_P (X) && REG_P (Y)	\
390418334Speter       && REGNO (X) == REGNO (Y) && GET_MODE (X) == GET_MODE (Y)))
390518334Speter
390618334Speter  if (! in_dest && COMBINE_RTX_EQUAL_P (x, from))
390718334Speter    {
390818334Speter      n_occurrences++;
390918334Speter      return (unique_copy && n_occurrences > 1 ? copy_rtx (to) : to);
391018334Speter    }
391118334Speter
391218334Speter  /* If X and FROM are the same register but different modes, they will
391390075Sobrien     not have been seen as equal above.  However, flow.c will make a
391418334Speter     LOG_LINKS entry for that case.  If we do nothing, we will try to
391518334Speter     rerecognize our original insn and, when it succeeds, we will
391618334Speter     delete the feeding insn, which is incorrect.
391718334Speter
391818334Speter     So force this insn not to match in this (rare) case.  */
3919169689Skan  if (! in_dest && code == REG && REG_P (from)
392018334Speter      && REGNO (x) == REGNO (from))
392150397Sobrien    return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
392218334Speter
392318334Speter  /* If this is an object, we are done unless it is a MEM or LO_SUM, both
392418334Speter     of which may contain things that can be combined.  */
3925169689Skan  if (code != MEM && code != LO_SUM && OBJECT_P (x))
392618334Speter    return x;
392718334Speter
392818334Speter  /* It is possible to have a subexpression appear twice in the insn.
392918334Speter     Suppose that FROM is a register that appears within TO.
393018334Speter     Then, after that subexpression has been scanned once by `subst',
393118334Speter     the second time it is scanned, TO may be found.  If we were
393218334Speter     to scan TO here, we would find FROM within it and create a
393318334Speter     self-referent rtl structure which is completely wrong.  */
393418334Speter  if (COMBINE_RTX_EQUAL_P (x, to))
393518334Speter    return to;
393618334Speter
393750397Sobrien  /* Parallel asm_operands need special attention because all of the
393850397Sobrien     inputs are shared across the arms.  Furthermore, unsharing the
393950397Sobrien     rtl results in recognition failures.  Failure to handle this case
394050397Sobrien     specially can result in circular rtl.
394118334Speter
394250397Sobrien     Solve this by doing a normal pass across the first entry of the
394350397Sobrien     parallel, and only processing the SET_DESTs of the subsequent
394450397Sobrien     entries.  Ug.  */
394518334Speter
394650397Sobrien  if (code == PARALLEL
394750397Sobrien      && GET_CODE (XVECEXP (x, 0, 0)) == SET
394850397Sobrien      && GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS)
394950397Sobrien    {
395050397Sobrien      new = subst (XVECEXP (x, 0, 0), from, to, 0, unique_copy);
395118334Speter
395250397Sobrien      /* If this substitution failed, this whole thing fails.  */
395350397Sobrien      if (GET_CODE (new) == CLOBBER
395450397Sobrien	  && XEXP (new, 0) == const0_rtx)
395550397Sobrien	return new;
395650397Sobrien
395750397Sobrien      SUBST (XVECEXP (x, 0, 0), new);
395850397Sobrien
395950397Sobrien      for (i = XVECLEN (x, 0) - 1; i >= 1; i--)
396018334Speter	{
396150397Sobrien	  rtx dest = SET_DEST (XVECEXP (x, 0, i));
396290075Sobrien
3963169689Skan	  if (!REG_P (dest)
396450397Sobrien	      && GET_CODE (dest) != CC0
396550397Sobrien	      && GET_CODE (dest) != PC)
396618334Speter	    {
396750397Sobrien	      new = subst (dest, from, to, 0, unique_copy);
396818334Speter
396950397Sobrien	      /* If this substitution failed, this whole thing fails.  */
397050397Sobrien	      if (GET_CODE (new) == CLOBBER
397150397Sobrien		  && XEXP (new, 0) == const0_rtx)
397250397Sobrien		return new;
397318334Speter
397450397Sobrien	      SUBST (SET_DEST (XVECEXP (x, 0, i)), new);
397518334Speter	    }
397618334Speter	}
397750397Sobrien    }
397850397Sobrien  else
397950397Sobrien    {
398050397Sobrien      len = GET_RTX_LENGTH (code);
398150397Sobrien      fmt = GET_RTX_FORMAT (code);
398250397Sobrien
398350397Sobrien      /* We don't need to process a SET_DEST that is a register, CC0,
398450397Sobrien	 or PC, so set up to skip this common case.  All other cases
398550397Sobrien	 where we want to suppress replacing something inside a
398650397Sobrien	 SET_SRC are handled via the IN_DEST operand.  */
398750397Sobrien      if (code == SET
3988169689Skan	  && (REG_P (SET_DEST (x))
398950397Sobrien	      || GET_CODE (SET_DEST (x)) == CC0
399050397Sobrien	      || GET_CODE (SET_DEST (x)) == PC))
399150397Sobrien	fmt = "ie";
399250397Sobrien
399350397Sobrien      /* Get the mode of operand 0 in case X is now a SIGN_EXTEND of a
399450397Sobrien	 constant.  */
399550397Sobrien      if (fmt[0] == 'e')
399650397Sobrien	op0_mode = GET_MODE (XEXP (x, 0));
399750397Sobrien
399850397Sobrien      for (i = 0; i < len; i++)
399918334Speter	{
400050397Sobrien	  if (fmt[i] == 'E')
400118334Speter	    {
400290075Sobrien	      int j;
400350397Sobrien	      for (j = XVECLEN (x, i) - 1; j >= 0; j--)
400450397Sobrien		{
400550397Sobrien		  if (COMBINE_RTX_EQUAL_P (XVECEXP (x, i, j), from))
400650397Sobrien		    {
400750397Sobrien		      new = (unique_copy && n_occurrences
400850397Sobrien			     ? copy_rtx (to) : to);
400950397Sobrien		      n_occurrences++;
401050397Sobrien		    }
401150397Sobrien		  else
401250397Sobrien		    {
401350397Sobrien		      new = subst (XVECEXP (x, i, j), from, to, 0,
401450397Sobrien				   unique_copy);
401518334Speter
401650397Sobrien		      /* If this substitution failed, this whole thing
401750397Sobrien			 fails.  */
401850397Sobrien		      if (GET_CODE (new) == CLOBBER
401950397Sobrien			  && XEXP (new, 0) == const0_rtx)
402050397Sobrien			return new;
402150397Sobrien		    }
402250397Sobrien
402350397Sobrien		  SUBST (XVECEXP (x, i, j), new);
402450397Sobrien		}
402550397Sobrien	    }
402650397Sobrien	  else if (fmt[i] == 'e')
402750397Sobrien	    {
402890075Sobrien	      /* If this is a register being set, ignore it.  */
402990075Sobrien	      new = XEXP (x, i);
403090075Sobrien	      if (in_dest
403190075Sobrien		  && i == 0
4032146895Skan		  && (((code == SUBREG || code == ZERO_EXTRACT)
4033169689Skan		       && REG_P (new))
4034146895Skan		      || code == STRICT_LOW_PART))
403590075Sobrien		;
403690075Sobrien
403790075Sobrien	      else if (COMBINE_RTX_EQUAL_P (XEXP (x, i), from))
403850397Sobrien		{
403950397Sobrien		  /* In general, don't install a subreg involving two
404050397Sobrien		     modes not tieable.  It can worsen register
404150397Sobrien		     allocation, and can even make invalid reload
404250397Sobrien		     insns, since the reg inside may need to be copied
404350397Sobrien		     from in the outside mode, and that may be invalid
404450397Sobrien		     if it is an fp reg copied in integer mode.
404550397Sobrien
404650397Sobrien		     We allow two exceptions to this: It is valid if
404750397Sobrien		     it is inside another SUBREG and the mode of that
404850397Sobrien		     SUBREG and the mode of the inside of TO is
404950397Sobrien		     tieable and it is valid if X is a SET that copies
405050397Sobrien		     FROM to CC0.  */
405150397Sobrien
405250397Sobrien		  if (GET_CODE (to) == SUBREG
405350397Sobrien		      && ! MODES_TIEABLE_P (GET_MODE (to),
405450397Sobrien					    GET_MODE (SUBREG_REG (to)))
405550397Sobrien		      && ! (code == SUBREG
405650397Sobrien			    && MODES_TIEABLE_P (GET_MODE (x),
405750397Sobrien						GET_MODE (SUBREG_REG (to))))
405818334Speter#ifdef HAVE_cc0
405950397Sobrien		      && ! (code == SET && i == 1 && XEXP (x, 0) == cc0_rtx)
406018334Speter#endif
406150397Sobrien		      )
406250397Sobrien		    return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
406318334Speter
4064117395Skan#ifdef CANNOT_CHANGE_MODE_CLASS
406590075Sobrien		  if (code == SUBREG
4066169689Skan		      && REG_P (to)
406790075Sobrien		      && REGNO (to) < FIRST_PSEUDO_REGISTER
4068117395Skan		      && REG_CANNOT_CHANGE_MODE_P (REGNO (to),
4069117395Skan						   GET_MODE (to),
4070117395Skan						   GET_MODE (x)))
407190075Sobrien		    return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
407290075Sobrien#endif
407390075Sobrien
407450397Sobrien		  new = (unique_copy && n_occurrences ? copy_rtx (to) : to);
407550397Sobrien		  n_occurrences++;
407650397Sobrien		}
407750397Sobrien	      else
407850397Sobrien		/* If we are in a SET_DEST, suppress most cases unless we
407950397Sobrien		   have gone inside a MEM, in which case we want to
408050397Sobrien		   simplify the address.  We assume here that things that
408150397Sobrien		   are actually part of the destination have their inner
408290075Sobrien		   parts in the first expression.  This is true for SUBREG,
408350397Sobrien		   STRICT_LOW_PART, and ZERO_EXTRACT, which are the only
408450397Sobrien		   things aside from REG and MEM that should appear in a
408550397Sobrien		   SET_DEST.  */
408650397Sobrien		new = subst (XEXP (x, i), from, to,
408750397Sobrien			     (((in_dest
408850397Sobrien				&& (code == SUBREG || code == STRICT_LOW_PART
408950397Sobrien				    || code == ZERO_EXTRACT))
409050397Sobrien			       || code == SET)
409150397Sobrien			      && i == 0), unique_copy);
409218334Speter
409350397Sobrien	      /* If we found that we will have to reject this combination,
409450397Sobrien		 indicate that by returning the CLOBBER ourselves, rather than
409550397Sobrien		 an expression containing it.  This will speed things up as
409650397Sobrien		 well as prevent accidents where two CLOBBERs are considered
409750397Sobrien		 to be equal, thus producing an incorrect simplification.  */
409818334Speter
409950397Sobrien	      if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx)
410050397Sobrien		return new;
410118334Speter
4102132718Skan	      if (GET_CODE (x) == SUBREG
4103132718Skan		  && (GET_CODE (new) == CONST_INT
4104132718Skan		      || GET_CODE (new) == CONST_DOUBLE))
410596263Sobrien		{
4106102780Skan		  enum machine_mode mode = GET_MODE (x);
4107117395Skan
4108117395Skan		  x = simplify_subreg (GET_MODE (x), new,
410996263Sobrien				       GET_MODE (SUBREG_REG (x)),
411096263Sobrien				       SUBREG_BYTE (x));
411196263Sobrien		  if (! x)
4112102780Skan		    x = gen_rtx_CLOBBER (mode, const0_rtx);
411396263Sobrien		}
411496263Sobrien	      else if (GET_CODE (new) == CONST_INT
411596263Sobrien		       && GET_CODE (x) == ZERO_EXTEND)
411696263Sobrien		{
411796263Sobrien		  x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
411896263Sobrien						new, GET_MODE (XEXP (x, 0)));
4119169689Skan		  gcc_assert (x);
412096263Sobrien		}
412196263Sobrien	      else
412296263Sobrien		SUBST (XEXP (x, i), new);
412350397Sobrien	    }
412418334Speter	}
412518334Speter    }
412618334Speter
412718334Speter  /* Try to simplify X.  If the simplification changed the code, it is likely
412818334Speter     that further simplification will help, so loop, but limit the number
412918334Speter     of repetitions that will be performed.  */
413018334Speter
413118334Speter  for (i = 0; i < 4; i++)
413218334Speter    {
413318334Speter      /* If X is sufficiently simple, don't bother trying to do anything
413418334Speter	 with it.  */
413518334Speter      if (code != CONST_INT && code != REG && code != CLOBBER)
4136169689Skan	x = combine_simplify_rtx (x, op0_mode, in_dest);
413718334Speter
413818334Speter      if (GET_CODE (x) == code)
413918334Speter	break;
414018334Speter
414118334Speter      code = GET_CODE (x);
414218334Speter
414318334Speter      /* We no longer know the original mode of operand 0 since we
414418334Speter	 have changed the form of X)  */
414518334Speter      op0_mode = VOIDmode;
414618334Speter    }
414718334Speter
414818334Speter  return x;
414918334Speter}
415018334Speter
415118334Speter/* Simplify X, a piece of RTL.  We just operate on the expression at the
415218334Speter   outer level; call `subst' to simplify recursively.  Return the new
415318334Speter   expression.
415418334Speter
4155169689Skan   OP0_MODE is the original mode of XEXP (x, 0).  IN_DEST is nonzero
4156169689Skan   if we are inside a SET_DEST.  */
415718334Speter
415818334Speterstatic rtx
4159169689Skancombine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
416018334Speter{
416118334Speter  enum rtx_code code = GET_CODE (x);
416218334Speter  enum machine_mode mode = GET_MODE (x);
416318334Speter  rtx temp;
416418334Speter  int i;
416518334Speter
416618334Speter  /* If this is a commutative operation, put a constant last and a complex
416718334Speter     expression first.  We don't need to do this for comparisons here.  */
4168169689Skan  if (COMMUTATIVE_ARITH_P (x)
416990075Sobrien      && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
417018334Speter    {
417118334Speter      temp = XEXP (x, 0);
417218334Speter      SUBST (XEXP (x, 0), XEXP (x, 1));
417318334Speter      SUBST (XEXP (x, 1), temp);
417418334Speter    }
417518334Speter
417690075Sobrien  /* If this is a simple operation applied to an IF_THEN_ELSE, try
417718334Speter     applying it to the arms of the IF_THEN_ELSE.  This often simplifies
417818334Speter     things.  Check for cases where both arms are testing the same
417918334Speter     condition.
418018334Speter
418118334Speter     Don't do anything if all operands are very simple.  */
418218334Speter
4183169689Skan  if ((BINARY_P (x)
4184169689Skan       && ((!OBJECT_P (XEXP (x, 0))
418518334Speter	    && ! (GET_CODE (XEXP (x, 0)) == SUBREG
4186169689Skan		  && OBJECT_P (SUBREG_REG (XEXP (x, 0)))))
4187169689Skan	   || (!OBJECT_P (XEXP (x, 1))
418818334Speter	       && ! (GET_CODE (XEXP (x, 1)) == SUBREG
4189169689Skan		     && OBJECT_P (SUBREG_REG (XEXP (x, 1)))))))
4190169689Skan      || (UNARY_P (x)
4191169689Skan	  && (!OBJECT_P (XEXP (x, 0))
419218334Speter	       && ! (GET_CODE (XEXP (x, 0)) == SUBREG
4193169689Skan		     && OBJECT_P (SUBREG_REG (XEXP (x, 0)))))))
419418334Speter    {
419590075Sobrien      rtx cond, true_rtx, false_rtx;
419618334Speter
419790075Sobrien      cond = if_then_else_cond (x, &true_rtx, &false_rtx);
419850397Sobrien      if (cond != 0
419950397Sobrien	  /* If everything is a comparison, what we have is highly unlikely
420050397Sobrien	     to be simpler, so don't use it.  */
4201169689Skan	  && ! (COMPARISON_P (x)
4202169689Skan		&& (COMPARISON_P (true_rtx) || COMPARISON_P (false_rtx))))
420318334Speter	{
420418334Speter	  rtx cop1 = const0_rtx;
420518334Speter	  enum rtx_code cond_code = simplify_comparison (NE, &cond, &cop1);
420618334Speter
4207169689Skan	  if (cond_code == NE && COMPARISON_P (cond))
420818334Speter	    return x;
420918334Speter
421090075Sobrien	  /* Simplify the alternative arms; this may collapse the true and
4211132718Skan	     false arms to store-flag values.  Be careful to use copy_rtx
4212132718Skan	     here since true_rtx or false_rtx might share RTL with x as a
4213132718Skan	     result of the if_then_else_cond call above.  */
4214132718Skan	  true_rtx = subst (copy_rtx (true_rtx), pc_rtx, pc_rtx, 0, 0);
4215132718Skan	  false_rtx = subst (copy_rtx (false_rtx), pc_rtx, pc_rtx, 0, 0);
421618334Speter
421790075Sobrien	  /* If true_rtx and false_rtx are not general_operands, an if_then_else
421890075Sobrien	     is unlikely to be simpler.  */
421990075Sobrien	  if (general_operand (true_rtx, VOIDmode)
422090075Sobrien	      && general_operand (false_rtx, VOIDmode))
422190075Sobrien	    {
4222132718Skan	      enum rtx_code reversed;
4223132718Skan
422490075Sobrien	      /* Restarting if we generate a store-flag expression will cause
422590075Sobrien		 us to loop.  Just drop through in this case.  */
422618334Speter
422790075Sobrien	      /* If the result values are STORE_FLAG_VALUE and zero, we can
422890075Sobrien		 just make the comparison operation.  */
422990075Sobrien	      if (true_rtx == const_true_rtx && false_rtx == const0_rtx)
4230169689Skan		x = simplify_gen_relational (cond_code, mode, VOIDmode,
4231169689Skan					     cond, cop1);
423290075Sobrien	      else if (true_rtx == const0_rtx && false_rtx == const_true_rtx
4233132718Skan		       && ((reversed = reversed_comparison_code_parts
4234132718Skan					(cond_code, cond, cop1, NULL))
4235169689Skan			   != UNKNOWN))
4236169689Skan		x = simplify_gen_relational (reversed, mode, VOIDmode,
4237169689Skan					     cond, cop1);
423818334Speter
423990075Sobrien	      /* Likewise, we can make the negate of a comparison operation
424090075Sobrien		 if the result values are - STORE_FLAG_VALUE and zero.  */
424190075Sobrien	      else if (GET_CODE (true_rtx) == CONST_INT
424290075Sobrien		       && INTVAL (true_rtx) == - STORE_FLAG_VALUE
424390075Sobrien		       && false_rtx == const0_rtx)
424490075Sobrien		x = simplify_gen_unary (NEG, mode,
4245169689Skan					simplify_gen_relational (cond_code,
4246169689Skan								 mode, VOIDmode,
4247169689Skan								 cond, cop1),
424890075Sobrien					mode);
424990075Sobrien	      else if (GET_CODE (false_rtx) == CONST_INT
425090075Sobrien		       && INTVAL (false_rtx) == - STORE_FLAG_VALUE
4251132718Skan		       && true_rtx == const0_rtx
4252132718Skan		       && ((reversed = reversed_comparison_code_parts
4253132718Skan					(cond_code, cond, cop1, NULL))
4254169689Skan			   != UNKNOWN))
425590075Sobrien		x = simplify_gen_unary (NEG, mode,
4256169689Skan					simplify_gen_relational (reversed,
4257169689Skan								 mode, VOIDmode,
4258169689Skan								 cond, cop1),
425990075Sobrien					mode);
426090075Sobrien	      else
426190075Sobrien		return gen_rtx_IF_THEN_ELSE (mode,
4262169689Skan					     simplify_gen_relational (cond_code,
4263169689Skan								      mode,
4264169689Skan								      VOIDmode,
4265169689Skan								      cond,
4266169689Skan								      cop1),
426790075Sobrien					     true_rtx, false_rtx);
426818334Speter
426990075Sobrien	      code = GET_CODE (x);
427090075Sobrien	      op0_mode = VOIDmode;
427190075Sobrien	    }
427218334Speter	}
427318334Speter    }
427418334Speter
427518334Speter  /* Try to fold this expression in case we have constants that weren't
427618334Speter     present before.  */
427718334Speter  temp = 0;
427818334Speter  switch (GET_RTX_CLASS (code))
427918334Speter    {
4280169689Skan    case RTX_UNARY:
4281132718Skan      if (op0_mode == VOIDmode)
4282132718Skan	op0_mode = GET_MODE (XEXP (x, 0));
428318334Speter      temp = simplify_unary_operation (code, mode, XEXP (x, 0), op0_mode);
428418334Speter      break;
4285169689Skan    case RTX_COMPARE:
4286169689Skan    case RTX_COMM_COMPARE:
4287169689Skan      {
4288169689Skan	enum machine_mode cmp_mode = GET_MODE (XEXP (x, 0));
4289169689Skan	if (cmp_mode == VOIDmode)
4290169689Skan	  {
4291169689Skan	    cmp_mode = GET_MODE (XEXP (x, 1));
4292169689Skan	    if (cmp_mode == VOIDmode)
4293169689Skan	      cmp_mode = op0_mode;
4294169689Skan	  }
4295169689Skan	temp = simplify_relational_operation (code, mode, cmp_mode,
4296169689Skan					      XEXP (x, 0), XEXP (x, 1));
4297169689Skan      }
429818334Speter      break;
4299169689Skan    case RTX_COMM_ARITH:
4300169689Skan    case RTX_BIN_ARITH:
430118334Speter      temp = simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
430218334Speter      break;
4303169689Skan    case RTX_BITFIELD_OPS:
4304169689Skan    case RTX_TERNARY:
430518334Speter      temp = simplify_ternary_operation (code, mode, op0_mode, XEXP (x, 0),
430618334Speter					 XEXP (x, 1), XEXP (x, 2));
430718334Speter      break;
4308169689Skan    default:
4309169689Skan      break;
431018334Speter    }
431118334Speter
431218334Speter  if (temp)
431390075Sobrien    {
431490075Sobrien      x = temp;
431590075Sobrien      code = GET_CODE (temp);
431690075Sobrien      op0_mode = VOIDmode;
431790075Sobrien      mode = GET_MODE (temp);
431890075Sobrien    }
431918334Speter
432018334Speter  /* First see if we can apply the inverse distributive law.  */
432118334Speter  if (code == PLUS || code == MINUS
432218334Speter      || code == AND || code == IOR || code == XOR)
432318334Speter    {
432418334Speter      x = apply_distributive_law (x);
432518334Speter      code = GET_CODE (x);
432690075Sobrien      op0_mode = VOIDmode;
432718334Speter    }
432818334Speter
432918334Speter  /* If CODE is an associative operation not otherwise handled, see if we
433018334Speter     can associate some operands.  This can win if they are constants or
433190075Sobrien     if they are logically related (i.e. (a & b) & a).  */
433290075Sobrien  if ((code == PLUS || code == MINUS || code == MULT || code == DIV
433390075Sobrien       || code == AND || code == IOR || code == XOR
433418334Speter       || code == SMAX || code == SMIN || code == UMAX || code == UMIN)
433590075Sobrien      && ((INTEGRAL_MODE_P (mode) && code != DIV)
433690075Sobrien	  || (flag_unsafe_math_optimizations && FLOAT_MODE_P (mode))))
433718334Speter    {
433818334Speter      if (GET_CODE (XEXP (x, 0)) == code)
433918334Speter	{
434018334Speter	  rtx other = XEXP (XEXP (x, 0), 0);
434118334Speter	  rtx inner_op0 = XEXP (XEXP (x, 0), 1);
434218334Speter	  rtx inner_op1 = XEXP (x, 1);
434318334Speter	  rtx inner;
434490075Sobrien
434518334Speter	  /* Make sure we pass the constant operand if any as the second
434618334Speter	     one if this is a commutative operation.  */
4347169689Skan	  if (CONSTANT_P (inner_op0) && COMMUTATIVE_ARITH_P (x))
434818334Speter	    {
434918334Speter	      rtx tem = inner_op0;
435018334Speter	      inner_op0 = inner_op1;
435118334Speter	      inner_op1 = tem;
435218334Speter	    }
435318334Speter	  inner = simplify_binary_operation (code == MINUS ? PLUS
435418334Speter					     : code == DIV ? MULT
435518334Speter					     : code,
435618334Speter					     mode, inner_op0, inner_op1);
435718334Speter
435818334Speter	  /* For commutative operations, try the other pair if that one
435918334Speter	     didn't simplify.  */
4360169689Skan	  if (inner == 0 && COMMUTATIVE_ARITH_P (x))
436118334Speter	    {
436218334Speter	      other = XEXP (XEXP (x, 0), 1);
436318334Speter	      inner = simplify_binary_operation (code, mode,
436418334Speter						 XEXP (XEXP (x, 0), 0),
436518334Speter						 XEXP (x, 1));
436618334Speter	    }
436718334Speter
436818334Speter	  if (inner)
4369169689Skan	    return simplify_gen_binary (code, mode, other, inner);
437018334Speter	}
437118334Speter    }
437218334Speter
437318334Speter  /* A little bit of algebraic simplification here.  */
437418334Speter  switch (code)
437518334Speter    {
437618334Speter    case MEM:
437718334Speter      /* Ensure that our address has any ASHIFTs converted to MULT in case
437818334Speter	 address-recognizing predicates are called later.  */
437918334Speter      temp = make_compound_operation (XEXP (x, 0), MEM);
438018334Speter      SUBST (XEXP (x, 0), temp);
438118334Speter      break;
438218334Speter
438318334Speter    case SUBREG:
438490075Sobrien      if (op0_mode == VOIDmode)
438590075Sobrien	op0_mode = GET_MODE (SUBREG_REG (x));
438618334Speter
4387169689Skan      /* See if this can be moved to simplify_subreg.  */
438850397Sobrien      if (CONSTANT_P (SUBREG_REG (x))
4389117395Skan	  && subreg_lowpart_offset (mode, op0_mode) == SUBREG_BYTE (x)
4390169689Skan	     /* Don't call gen_lowpart if the inner mode
4391117395Skan		is VOIDmode and we cannot simplify it, as SUBREG without
4392117395Skan		inner mode is invalid.  */
4393117395Skan	  && (GET_MODE (SUBREG_REG (x)) != VOIDmode
4394117395Skan	      || gen_lowpart_common (mode, SUBREG_REG (x))))
4395169689Skan	return gen_lowpart (mode, SUBREG_REG (x));
439618334Speter
439790075Sobrien      if (GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_CC)
4398169689Skan	break;
439990075Sobrien      {
440090075Sobrien	rtx temp;
440190075Sobrien	temp = simplify_subreg (mode, SUBREG_REG (x), op0_mode,
440290075Sobrien				SUBREG_BYTE (x));
440390075Sobrien	if (temp)
440490075Sobrien	  return temp;
440590075Sobrien      }
440618334Speter
440796263Sobrien      /* Don't change the mode of the MEM if that would change the meaning
440896263Sobrien	 of the address.  */
4409169689Skan      if (MEM_P (SUBREG_REG (x))
441096263Sobrien	  && (MEM_VOLATILE_P (SUBREG_REG (x))
441196263Sobrien	      || mode_dependent_address_p (XEXP (SUBREG_REG (x), 0))))
441296263Sobrien	return gen_rtx_CLOBBER (mode, const0_rtx);
441396263Sobrien
441418334Speter      /* Note that we cannot do any narrowing for non-constants since
441518334Speter	 we might have been counting on using the fact that some bits were
441618334Speter	 zero.  We now do this in the SET.  */
441718334Speter
441818334Speter      break;
441918334Speter
442018334Speter    case NEG:
442118334Speter      temp = expand_compound_operation (XEXP (x, 0));
442218334Speter
442318334Speter      /* For C equal to the width of MODE minus 1, (neg (ashiftrt X C)) can be
442490075Sobrien	 replaced by (lshiftrt X C).  This will convert
442518334Speter	 (neg (sign_extract X 1 Y)) to (zero_extract X 1 Y).  */
442618334Speter
442718334Speter      if (GET_CODE (temp) == ASHIFTRT
442818334Speter	  && GET_CODE (XEXP (temp, 1)) == CONST_INT
442918334Speter	  && INTVAL (XEXP (temp, 1)) == GET_MODE_BITSIZE (mode) - 1)
4430169689Skan	return simplify_shift_const (NULL_RTX, LSHIFTRT, mode, XEXP (temp, 0),
443118334Speter				     INTVAL (XEXP (temp, 1)));
443218334Speter
443318334Speter      /* If X has only a single bit that might be nonzero, say, bit I, convert
443418334Speter	 (neg X) to (ashiftrt (ashift X C-I) C-I) where C is the bitsize of
443518334Speter	 MODE minus 1.  This will convert (neg (zero_extract X 1 Y)) to
443618334Speter	 (sign_extract X 1 Y).  But only do this if TEMP isn't a register
443718334Speter	 or a SUBREG of one since we'd be making the expression more
443818334Speter	 complex if it was just a register.  */
443918334Speter
4440169689Skan      if (!REG_P (temp)
444118334Speter	  && ! (GET_CODE (temp) == SUBREG
4442169689Skan		&& REG_P (SUBREG_REG (temp)))
444318334Speter	  && (i = exact_log2 (nonzero_bits (temp, mode))) >= 0)
444418334Speter	{
444518334Speter	  rtx temp1 = simplify_shift_const
444618334Speter	    (NULL_RTX, ASHIFTRT, mode,
444718334Speter	     simplify_shift_const (NULL_RTX, ASHIFT, mode, temp,
444818334Speter				   GET_MODE_BITSIZE (mode) - 1 - i),
444918334Speter	     GET_MODE_BITSIZE (mode) - 1 - i);
445018334Speter
445118334Speter	  /* If all we did was surround TEMP with the two shifts, we
445218334Speter	     haven't improved anything, so don't use it.  Otherwise,
445318334Speter	     we are better off with TEMP1.  */
445418334Speter	  if (GET_CODE (temp1) != ASHIFTRT
445518334Speter	      || GET_CODE (XEXP (temp1, 0)) != ASHIFT
445618334Speter	      || XEXP (XEXP (temp1, 0), 0) != temp)
445718334Speter	    return temp1;
445818334Speter	}
445918334Speter      break;
446018334Speter
446118334Speter    case TRUNCATE:
446250397Sobrien      /* We can't handle truncation to a partial integer mode here
446350397Sobrien	 because we don't know the real bitsize of the partial
446450397Sobrien	 integer mode.  */
446550397Sobrien      if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
446650397Sobrien	break;
446750397Sobrien
446850397Sobrien      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
446950397Sobrien	  && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
447050397Sobrien				    GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))))
447118334Speter	SUBST (XEXP (x, 0),
447218334Speter	       force_to_mode (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
4473169689Skan			      GET_MODE_MASK (mode), 0));
447450397Sobrien
4475169689Skan      /* Similarly to what we do in simplify-rtx.c, a truncate of a register
4476169689Skan	 whose value is a comparison can be replaced with a subreg if
4477169689Skan	 STORE_FLAG_VALUE permits.  */
447850397Sobrien      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
447990075Sobrien	  && ((HOST_WIDE_INT) STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
448050397Sobrien	  && (temp = get_last_value (XEXP (x, 0)))
4481169689Skan	  && COMPARISON_P (temp))
4482169689Skan	return gen_lowpart (mode, XEXP (x, 0));
448318334Speter      break;
448418334Speter
448518334Speter#ifdef HAVE_cc0
448618334Speter    case COMPARE:
448718334Speter      /* Convert (compare FOO (const_int 0)) to FOO unless we aren't
448818334Speter	 using cc0, in which case we want to leave it as a COMPARE
448918334Speter	 so we can distinguish it from a register-register-copy.  */
449018334Speter      if (XEXP (x, 1) == const0_rtx)
449118334Speter	return XEXP (x, 0);
449218334Speter
4493117395Skan      /* x - 0 is the same as x unless x's mode has signed zeros and
4494117395Skan	 allows rounding towards -infinity.  Under those conditions,
4495117395Skan	 0 - 0 is -0.  */
4496117395Skan      if (!(HONOR_SIGNED_ZEROS (GET_MODE (XEXP (x, 0)))
4497117395Skan	    && HONOR_SIGN_DEPENDENT_ROUNDING (GET_MODE (XEXP (x, 0))))
449818334Speter	  && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 0))))
449918334Speter	return XEXP (x, 0);
450018334Speter      break;
450118334Speter#endif
450218334Speter
450318334Speter    case CONST:
450418334Speter      /* (const (const X)) can become (const X).  Do it this way rather than
450518334Speter	 returning the inner CONST since CONST can be shared with a
450618334Speter	 REG_EQUAL note.  */
450718334Speter      if (GET_CODE (XEXP (x, 0)) == CONST)
450818334Speter	SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
450918334Speter      break;
451018334Speter
451118334Speter#ifdef HAVE_lo_sum
451218334Speter    case LO_SUM:
451318334Speter      /* Convert (lo_sum (high FOO) FOO) to FOO.  This is necessary so we
451418334Speter	 can add in an offset.  find_split_point will split this address up
451518334Speter	 again if it doesn't match.  */
451618334Speter      if (GET_CODE (XEXP (x, 0)) == HIGH
451718334Speter	  && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
451818334Speter	return XEXP (x, 1);
451918334Speter      break;
452018334Speter#endif
452118334Speter
452218334Speter    case PLUS:
452318334Speter      /* (plus (xor (and <foo> (const_int pow2 - 1)) <c>) <-c>)
452418334Speter	 when c is (const_int (pow2 + 1) / 2) is a sign extension of a
452518334Speter	 bit-field and can be replaced by either a sign_extend or a
452690075Sobrien	 sign_extract.  The `and' may be a zero_extend and the two
452790075Sobrien	 <c>, -<c> constants may be reversed.  */
452818334Speter      if (GET_CODE (XEXP (x, 0)) == XOR
452918334Speter	  && GET_CODE (XEXP (x, 1)) == CONST_INT
453018334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
453190075Sobrien	  && INTVAL (XEXP (x, 1)) == -INTVAL (XEXP (XEXP (x, 0), 1))
453290075Sobrien	  && ((i = exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) >= 0
453390075Sobrien	      || (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0)
453418334Speter	  && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
453518334Speter	  && ((GET_CODE (XEXP (XEXP (x, 0), 0)) == AND
453618334Speter	       && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
453718334Speter	       && (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))
453818334Speter		   == ((HOST_WIDE_INT) 1 << (i + 1)) - 1))
453918334Speter	      || (GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND
454018334Speter		  && (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)))
454190075Sobrien		      == (unsigned int) i + 1))))
454218334Speter	return simplify_shift_const
454318334Speter	  (NULL_RTX, ASHIFTRT, mode,
454418334Speter	   simplify_shift_const (NULL_RTX, ASHIFT, mode,
454518334Speter				 XEXP (XEXP (XEXP (x, 0), 0), 0),
454618334Speter				 GET_MODE_BITSIZE (mode) - (i + 1)),
454718334Speter	   GET_MODE_BITSIZE (mode) - (i + 1));
454818334Speter
454918334Speter      /* If only the low-order bit of X is possibly nonzero, (plus x -1)
455018334Speter	 can become (ashiftrt (ashift (xor x 1) C) C) where C is
455118334Speter	 the bitsize of the mode - 1.  This allows simplification of
455218334Speter	 "a = (b & 8) == 0;"  */
455318334Speter      if (XEXP (x, 1) == constm1_rtx
4554169689Skan	  && !REG_P (XEXP (x, 0))
4555132718Skan	  && ! (GET_CODE (XEXP (x, 0)) == SUBREG
4556169689Skan		&& REG_P (SUBREG_REG (XEXP (x, 0))))
455718334Speter	  && nonzero_bits (XEXP (x, 0), mode) == 1)
455818334Speter	return simplify_shift_const (NULL_RTX, ASHIFTRT, mode,
455918334Speter	   simplify_shift_const (NULL_RTX, ASHIFT, mode,
456090075Sobrien				 gen_rtx_XOR (mode, XEXP (x, 0), const1_rtx),
456118334Speter				 GET_MODE_BITSIZE (mode) - 1),
456218334Speter	   GET_MODE_BITSIZE (mode) - 1);
456318334Speter
456418334Speter      /* If we are adding two things that have no bits in common, convert
456518334Speter	 the addition into an IOR.  This will often be further simplified,
456618334Speter	 for example in cases like ((a & 1) + (a & 2)), which can
456718334Speter	 become a & 3.  */
456818334Speter
456918334Speter      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
457018334Speter	  && (nonzero_bits (XEXP (x, 0), mode)
457118334Speter	      & nonzero_bits (XEXP (x, 1), mode)) == 0)
457290075Sobrien	{
457390075Sobrien	  /* Try to simplify the expression further.  */
4574169689Skan	  rtx tor = simplify_gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1));
4575169689Skan	  temp = combine_simplify_rtx (tor, mode, in_dest);
457690075Sobrien
457790075Sobrien	  /* If we could, great.  If not, do not go ahead with the IOR
457890075Sobrien	     replacement, since PLUS appears in many special purpose
457990075Sobrien	     address arithmetic instructions.  */
458090075Sobrien	  if (GET_CODE (temp) != CLOBBER && temp != tor)
458190075Sobrien	    return temp;
458290075Sobrien	}
458318334Speter      break;
458418334Speter
458518334Speter    case MINUS:
458618334Speter      /* (minus <foo> (and <foo> (const_int -pow2))) becomes
458718334Speter	 (and <foo> (const_int pow2-1))  */
458818334Speter      if (GET_CODE (XEXP (x, 1)) == AND
458918334Speter	  && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
459090075Sobrien	  && exact_log2 (-INTVAL (XEXP (XEXP (x, 1), 1))) >= 0
459118334Speter	  && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
459218334Speter	return simplify_and_const_int (NULL_RTX, mode, XEXP (x, 0),
459390075Sobrien				       -INTVAL (XEXP (XEXP (x, 1), 1)) - 1);
459418334Speter      break;
459518334Speter
459618334Speter    case MULT:
459718334Speter      /* If we have (mult (plus A B) C), apply the distributive law and then
459818334Speter	 the inverse distributive law to see if things simplify.  This
459918334Speter	 occurs mostly in addresses, often when unrolling loops.  */
460018334Speter
460118334Speter      if (GET_CODE (XEXP (x, 0)) == PLUS)
460218334Speter	{
4603169689Skan	  rtx result = distribute_and_simplify_rtx (x, 0);
4604169689Skan	  if (result)
4605169689Skan	    return result;
4606169689Skan	}
460718334Speter
460890075Sobrien      /* Try simplify a*(b/c) as (a*b)/c.  */
460990075Sobrien      if (FLOAT_MODE_P (mode) && flag_unsafe_math_optimizations
461090075Sobrien	  && GET_CODE (XEXP (x, 0)) == DIV)
461190075Sobrien	{
461290075Sobrien	  rtx tem = simplify_binary_operation (MULT, mode,
461390075Sobrien					       XEXP (XEXP (x, 0), 0),
461490075Sobrien					       XEXP (x, 1));
461590075Sobrien	  if (tem)
4616169689Skan	    return simplify_gen_binary (DIV, mode, tem, XEXP (XEXP (x, 0), 1));
461790075Sobrien	}
461818334Speter      break;
461918334Speter
462018334Speter    case UDIV:
462118334Speter      /* If this is a divide by a power of two, treat it as a shift if
462218334Speter	 its first operand is a shift.  */
462318334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
462418334Speter	  && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0
462518334Speter	  && (GET_CODE (XEXP (x, 0)) == ASHIFT
462618334Speter	      || GET_CODE (XEXP (x, 0)) == LSHIFTRT
462718334Speter	      || GET_CODE (XEXP (x, 0)) == ASHIFTRT
462818334Speter	      || GET_CODE (XEXP (x, 0)) == ROTATE
462918334Speter	      || GET_CODE (XEXP (x, 0)) == ROTATERT))
463018334Speter	return simplify_shift_const (NULL_RTX, LSHIFTRT, mode, XEXP (x, 0), i);
463118334Speter      break;
463218334Speter
463318334Speter    case EQ:  case NE:
463418334Speter    case GT:  case GTU:  case GE:  case GEU:
463518334Speter    case LT:  case LTU:  case LE:  case LEU:
463690075Sobrien    case UNEQ:  case LTGT:
463790075Sobrien    case UNGT:  case UNGE:
463890075Sobrien    case UNLT:  case UNLE:
463990075Sobrien    case UNORDERED: case ORDERED:
464018334Speter      /* If the first operand is a condition code, we can't do anything
464118334Speter	 with it.  */
464218334Speter      if (GET_CODE (XEXP (x, 0)) == COMPARE
464318334Speter	  || (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_CC
4644132718Skan	      && ! CC0_P (XEXP (x, 0))))
464518334Speter	{
464618334Speter	  rtx op0 = XEXP (x, 0);
464718334Speter	  rtx op1 = XEXP (x, 1);
464818334Speter	  enum rtx_code new_code;
464918334Speter
465018334Speter	  if (GET_CODE (op0) == COMPARE)
465118334Speter	    op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);
465218334Speter
465318334Speter	  /* Simplify our comparison, if possible.  */
465418334Speter	  new_code = simplify_comparison (code, &op0, &op1);
465518334Speter
465618334Speter	  /* If STORE_FLAG_VALUE is 1, we can convert (ne x 0) to simply X
465718334Speter	     if only the low-order bit is possibly nonzero in X (such as when
465818334Speter	     X is a ZERO_EXTRACT of one bit).  Similarly, we can convert EQ to
465918334Speter	     (xor X 1) or (minus 1 X); we use the former.  Finally, if X is
466018334Speter	     known to be either 0 or -1, NE becomes a NEG and EQ becomes
466118334Speter	     (plus X 1).
466218334Speter
466318334Speter	     Remove any ZERO_EXTRACT we made when thinking this was a
466418334Speter	     comparison.  It may now be simpler to use, e.g., an AND.  If a
466518334Speter	     ZERO_EXTRACT is indeed appropriate, it will be placed back by
466618334Speter	     the call to make_compound_operation in the SET case.  */
466718334Speter
466850397Sobrien	  if (STORE_FLAG_VALUE == 1
466950397Sobrien	      && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
467090075Sobrien	      && op1 == const0_rtx
467190075Sobrien	      && mode == GET_MODE (op0)
467290075Sobrien	      && nonzero_bits (op0, mode) == 1)
4673169689Skan	    return gen_lowpart (mode,
4674169689Skan				expand_compound_operation (op0));
467518334Speter
467650397Sobrien	  else if (STORE_FLAG_VALUE == 1
467750397Sobrien		   && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
467818334Speter		   && op1 == const0_rtx
467990075Sobrien		   && mode == GET_MODE (op0)
468018334Speter		   && (num_sign_bit_copies (op0, mode)
468118334Speter		       == GET_MODE_BITSIZE (mode)))
468218334Speter	    {
468318334Speter	      op0 = expand_compound_operation (op0);
468490075Sobrien	      return simplify_gen_unary (NEG, mode,
4685169689Skan					 gen_lowpart (mode, op0),
468690075Sobrien					 mode);
468718334Speter	    }
468818334Speter
468950397Sobrien	  else if (STORE_FLAG_VALUE == 1
469050397Sobrien		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
469118334Speter		   && op1 == const0_rtx
469290075Sobrien		   && mode == GET_MODE (op0)
469318334Speter		   && nonzero_bits (op0, mode) == 1)
469418334Speter	    {
469518334Speter	      op0 = expand_compound_operation (op0);
4696169689Skan	      return simplify_gen_binary (XOR, mode,
4697169689Skan					  gen_lowpart (mode, op0),
4698169689Skan					  const1_rtx);
469918334Speter	    }
470018334Speter
470150397Sobrien	  else if (STORE_FLAG_VALUE == 1
470250397Sobrien		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
470318334Speter		   && op1 == const0_rtx
470490075Sobrien		   && mode == GET_MODE (op0)
470518334Speter		   && (num_sign_bit_copies (op0, mode)
470618334Speter		       == GET_MODE_BITSIZE (mode)))
470718334Speter	    {
470818334Speter	      op0 = expand_compound_operation (op0);
4709169689Skan	      return plus_constant (gen_lowpart (mode, op0), 1);
471018334Speter	    }
471118334Speter
471218334Speter	  /* If STORE_FLAG_VALUE is -1, we have cases similar to
471318334Speter	     those above.  */
471450397Sobrien	  if (STORE_FLAG_VALUE == -1
471550397Sobrien	      && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
471618334Speter	      && op1 == const0_rtx
471718334Speter	      && (num_sign_bit_copies (op0, mode)
471818334Speter		  == GET_MODE_BITSIZE (mode)))
4719169689Skan	    return gen_lowpart (mode,
4720169689Skan				expand_compound_operation (op0));
472118334Speter
472250397Sobrien	  else if (STORE_FLAG_VALUE == -1
472350397Sobrien		   && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
472418334Speter		   && op1 == const0_rtx
472590075Sobrien		   && mode == GET_MODE (op0)
472618334Speter		   && nonzero_bits (op0, mode) == 1)
472718334Speter	    {
472818334Speter	      op0 = expand_compound_operation (op0);
472990075Sobrien	      return simplify_gen_unary (NEG, mode,
4730169689Skan					 gen_lowpart (mode, op0),
473190075Sobrien					 mode);
473218334Speter	    }
473318334Speter
473450397Sobrien	  else if (STORE_FLAG_VALUE == -1
473550397Sobrien		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
473618334Speter		   && op1 == const0_rtx
473790075Sobrien		   && mode == GET_MODE (op0)
473818334Speter		   && (num_sign_bit_copies (op0, mode)
473918334Speter		       == GET_MODE_BITSIZE (mode)))
474018334Speter	    {
474118334Speter	      op0 = expand_compound_operation (op0);
474290075Sobrien	      return simplify_gen_unary (NOT, mode,
4743169689Skan					 gen_lowpart (mode, op0),
474490075Sobrien					 mode);
474518334Speter	    }
474618334Speter
474718334Speter	  /* If X is 0/1, (eq X 0) is X-1.  */
474850397Sobrien	  else if (STORE_FLAG_VALUE == -1
474950397Sobrien		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
475018334Speter		   && op1 == const0_rtx
475190075Sobrien		   && mode == GET_MODE (op0)
475218334Speter		   && nonzero_bits (op0, mode) == 1)
475318334Speter	    {
475418334Speter	      op0 = expand_compound_operation (op0);
4755169689Skan	      return plus_constant (gen_lowpart (mode, op0), -1);
475618334Speter	    }
475718334Speter
475818334Speter	  /* If STORE_FLAG_VALUE says to just test the sign bit and X has just
475918334Speter	     one bit that might be nonzero, we can convert (ne x 0) to
476018334Speter	     (ashift x c) where C puts the bit in the sign bit.  Remove any
476118334Speter	     AND with STORE_FLAG_VALUE when we are done, since we are only
476218334Speter	     going to test the sign bit.  */
476318334Speter	  if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
476418334Speter	      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
476550397Sobrien	      && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
4766132718Skan		  == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))
476718334Speter	      && op1 == const0_rtx
476818334Speter	      && mode == GET_MODE (op0)
476918334Speter	      && (i = exact_log2 (nonzero_bits (op0, mode))) >= 0)
477018334Speter	    {
477118334Speter	      x = simplify_shift_const (NULL_RTX, ASHIFT, mode,
477218334Speter					expand_compound_operation (op0),
477318334Speter					GET_MODE_BITSIZE (mode) - 1 - i);
477418334Speter	      if (GET_CODE (x) == AND && XEXP (x, 1) == const_true_rtx)
477518334Speter		return XEXP (x, 0);
477618334Speter	      else
477718334Speter		return x;
477818334Speter	    }
477918334Speter
478018334Speter	  /* If the code changed, return a whole new comparison.  */
478118334Speter	  if (new_code != code)
478290075Sobrien	    return gen_rtx_fmt_ee (new_code, mode, op0, op1);
478318334Speter
478490075Sobrien	  /* Otherwise, keep this operation, but maybe change its operands.
478518334Speter	     This also converts (ne (compare FOO BAR) 0) to (ne FOO BAR).  */
478618334Speter	  SUBST (XEXP (x, 0), op0);
478718334Speter	  SUBST (XEXP (x, 1), op1);
478818334Speter	}
478918334Speter      break;
479090075Sobrien
479118334Speter    case IF_THEN_ELSE:
479218334Speter      return simplify_if_then_else (x);
479318334Speter
479418334Speter    case ZERO_EXTRACT:
479518334Speter    case SIGN_EXTRACT:
479618334Speter    case ZERO_EXTEND:
479718334Speter    case SIGN_EXTEND:
479850397Sobrien      /* If we are processing SET_DEST, we are done.  */
479918334Speter      if (in_dest)
480018334Speter	return x;
480118334Speter
480218334Speter      return expand_compound_operation (x);
480318334Speter
480418334Speter    case SET:
480518334Speter      return simplify_set (x);
480618334Speter
480718334Speter    case AND:
480818334Speter    case IOR:
4809169689Skan      return simplify_logical (x);
481018334Speter
481118334Speter    case ASHIFT:
481218334Speter    case LSHIFTRT:
481318334Speter    case ASHIFTRT:
481418334Speter    case ROTATE:
481518334Speter    case ROTATERT:
481618334Speter      /* If this is a shift by a constant amount, simplify it.  */
481718334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
481890075Sobrien	return simplify_shift_const (x, code, mode, XEXP (x, 0),
481918334Speter				     INTVAL (XEXP (x, 1)));
482018334Speter
4821169689Skan      else if (SHIFT_COUNT_TRUNCATED && !REG_P (XEXP (x, 1)))
482218334Speter	SUBST (XEXP (x, 1),
4823117395Skan	       force_to_mode (XEXP (x, 1), GET_MODE (XEXP (x, 1)),
482490075Sobrien			      ((HOST_WIDE_INT) 1
482518334Speter			       << exact_log2 (GET_MODE_BITSIZE (GET_MODE (x))))
482618334Speter			      - 1,
4827169689Skan			      0));
482818334Speter      break;
482950397Sobrien
483050397Sobrien    default:
483150397Sobrien      break;
483218334Speter    }
483318334Speter
483418334Speter  return x;
483518334Speter}
483618334Speter
483718334Speter/* Simplify X, an IF_THEN_ELSE expression.  Return the new expression.  */
483818334Speter
483918334Speterstatic rtx
4840132718Skansimplify_if_then_else (rtx x)
484118334Speter{
484218334Speter  enum machine_mode mode = GET_MODE (x);
484318334Speter  rtx cond = XEXP (x, 0);
484490075Sobrien  rtx true_rtx = XEXP (x, 1);
484590075Sobrien  rtx false_rtx = XEXP (x, 2);
484618334Speter  enum rtx_code true_code = GET_CODE (cond);
4847169689Skan  int comparison_p = COMPARISON_P (cond);
484818334Speter  rtx temp;
484918334Speter  int i;
485090075Sobrien  enum rtx_code false_code;
485190075Sobrien  rtx reversed;
485218334Speter
485350397Sobrien  /* Simplify storing of the truth value.  */
485490075Sobrien  if (comparison_p && true_rtx == const_true_rtx && false_rtx == const0_rtx)
4855169689Skan    return simplify_gen_relational (true_code, mode, VOIDmode,
4856169689Skan				    XEXP (cond, 0), XEXP (cond, 1));
485790075Sobrien
485850397Sobrien  /* Also when the truth value has to be reversed.  */
485990075Sobrien  if (comparison_p
486090075Sobrien      && true_rtx == const0_rtx && false_rtx == const_true_rtx
4861169689Skan      && (reversed = reversed_comparison (cond, mode)))
486290075Sobrien    return reversed;
486318334Speter
486418334Speter  /* Sometimes we can simplify the arm of an IF_THEN_ELSE if a register used
486518334Speter     in it is being compared against certain values.  Get the true and false
486618334Speter     comparisons and see if that says anything about the value of each arm.  */
486718334Speter
486890075Sobrien  if (comparison_p
4869169689Skan      && ((false_code = reversed_comparison_code (cond, NULL))
487090075Sobrien	  != UNKNOWN)
4871169689Skan      && REG_P (XEXP (cond, 0)))
487218334Speter    {
487318334Speter      HOST_WIDE_INT nzb;
487418334Speter      rtx from = XEXP (cond, 0);
487518334Speter      rtx true_val = XEXP (cond, 1);
487618334Speter      rtx false_val = true_val;
487718334Speter      int swapped = 0;
487818334Speter
487918334Speter      /* If FALSE_CODE is EQ, swap the codes and arms.  */
488018334Speter
488118334Speter      if (false_code == EQ)
488218334Speter	{
488318334Speter	  swapped = 1, true_code = EQ, false_code = NE;
488490075Sobrien	  temp = true_rtx, true_rtx = false_rtx, false_rtx = temp;
488518334Speter	}
488618334Speter
488718334Speter      /* If we are comparing against zero and the expression being tested has
488818334Speter	 only a single bit that might be nonzero, that is its value when it is
488918334Speter	 not equal to zero.  Similarly if it is known to be -1 or 0.  */
489018334Speter
489118334Speter      if (true_code == EQ && true_val == const0_rtx
489218334Speter	  && exact_log2 (nzb = nonzero_bits (from, GET_MODE (from))) >= 0)
489318334Speter	false_code = EQ, false_val = GEN_INT (nzb);
489418334Speter      else if (true_code == EQ && true_val == const0_rtx
489518334Speter	       && (num_sign_bit_copies (from, GET_MODE (from))
489618334Speter		   == GET_MODE_BITSIZE (GET_MODE (from))))
489718334Speter	false_code = EQ, false_val = constm1_rtx;
489818334Speter
489918334Speter      /* Now simplify an arm if we know the value of the register in the
490018334Speter	 branch and it is used in the arm.  Be careful due to the potential
490118334Speter	 of locally-shared RTL.  */
490218334Speter
490390075Sobrien      if (reg_mentioned_p (from, true_rtx))
490490075Sobrien	true_rtx = subst (known_cond (copy_rtx (true_rtx), true_code,
490590075Sobrien				      from, true_val),
490618334Speter		      pc_rtx, pc_rtx, 0, 0);
490790075Sobrien      if (reg_mentioned_p (from, false_rtx))
490890075Sobrien	false_rtx = subst (known_cond (copy_rtx (false_rtx), false_code,
490918334Speter				   from, false_val),
491018334Speter		       pc_rtx, pc_rtx, 0, 0);
491118334Speter
491290075Sobrien      SUBST (XEXP (x, 1), swapped ? false_rtx : true_rtx);
491390075Sobrien      SUBST (XEXP (x, 2), swapped ? true_rtx : false_rtx);
491418334Speter
491590075Sobrien      true_rtx = XEXP (x, 1);
491690075Sobrien      false_rtx = XEXP (x, 2);
491790075Sobrien      true_code = GET_CODE (cond);
491818334Speter    }
491918334Speter
492018334Speter  /* If we have (if_then_else FOO (pc) (label_ref BAR)) and FOO can be
492118334Speter     reversed, do so to avoid needing two sets of patterns for
492218334Speter     subtract-and-branch insns.  Similarly if we have a constant in the true
492318334Speter     arm, the false arm is the same as the first operand of the comparison, or
492418334Speter     the false arm is more complicated than the true arm.  */
492518334Speter
492690075Sobrien  if (comparison_p
4927169689Skan      && reversed_comparison_code (cond, NULL) != UNKNOWN
492890075Sobrien      && (true_rtx == pc_rtx
492990075Sobrien	  || (CONSTANT_P (true_rtx)
493090075Sobrien	      && GET_CODE (false_rtx) != CONST_INT && false_rtx != pc_rtx)
493190075Sobrien	  || true_rtx == const0_rtx
4932169689Skan	  || (OBJECT_P (true_rtx) && !OBJECT_P (false_rtx))
4933169689Skan	  || (GET_CODE (true_rtx) == SUBREG && OBJECT_P (SUBREG_REG (true_rtx))
4934169689Skan	      && !OBJECT_P (false_rtx))
493590075Sobrien	  || reg_mentioned_p (true_rtx, false_rtx)
493690075Sobrien	  || rtx_equal_p (false_rtx, XEXP (cond, 0))))
493718334Speter    {
493890075Sobrien      true_code = reversed_comparison_code (cond, NULL);
4939169689Skan      SUBST (XEXP (x, 0), reversed_comparison (cond, GET_MODE (cond)));
494090075Sobrien      SUBST (XEXP (x, 1), false_rtx);
494190075Sobrien      SUBST (XEXP (x, 2), true_rtx);
494218334Speter
494390075Sobrien      temp = true_rtx, true_rtx = false_rtx, false_rtx = temp;
494490075Sobrien      cond = XEXP (x, 0);
494550397Sobrien
494650397Sobrien      /* It is possible that the conditional has been simplified out.  */
494750397Sobrien      true_code = GET_CODE (cond);
4948169689Skan      comparison_p = COMPARISON_P (cond);
494918334Speter    }
495018334Speter
495118334Speter  /* If the two arms are identical, we don't need the comparison.  */
495218334Speter
495390075Sobrien  if (rtx_equal_p (true_rtx, false_rtx) && ! side_effects_p (cond))
495490075Sobrien    return true_rtx;
495518334Speter
495650397Sobrien  /* Convert a == b ? b : a to "a".  */
495750397Sobrien  if (true_code == EQ && ! side_effects_p (cond)
4958117395Skan      && !HONOR_NANS (mode)
495990075Sobrien      && rtx_equal_p (XEXP (cond, 0), false_rtx)
496090075Sobrien      && rtx_equal_p (XEXP (cond, 1), true_rtx))
496190075Sobrien    return false_rtx;
496250397Sobrien  else if (true_code == NE && ! side_effects_p (cond)
4963117395Skan	   && !HONOR_NANS (mode)
496490075Sobrien	   && rtx_equal_p (XEXP (cond, 0), true_rtx)
496590075Sobrien	   && rtx_equal_p (XEXP (cond, 1), false_rtx))
496690075Sobrien    return true_rtx;
496750397Sobrien
496818334Speter  /* Look for cases where we have (abs x) or (neg (abs X)).  */
496918334Speter
497018334Speter  if (GET_MODE_CLASS (mode) == MODE_INT
497190075Sobrien      && GET_CODE (false_rtx) == NEG
497290075Sobrien      && rtx_equal_p (true_rtx, XEXP (false_rtx, 0))
497318334Speter      && comparison_p
497490075Sobrien      && rtx_equal_p (true_rtx, XEXP (cond, 0))
497590075Sobrien      && ! side_effects_p (true_rtx))
497618334Speter    switch (true_code)
497718334Speter      {
497818334Speter      case GT:
497918334Speter      case GE:
498090075Sobrien	return simplify_gen_unary (ABS, mode, true_rtx, mode);
498118334Speter      case LT:
498218334Speter      case LE:
498390075Sobrien	return
498490075Sobrien	  simplify_gen_unary (NEG, mode,
498590075Sobrien			      simplify_gen_unary (ABS, mode, true_rtx, mode),
498690075Sobrien			      mode);
498790075Sobrien      default:
498890075Sobrien	break;
498918334Speter      }
499018334Speter
499118334Speter  /* Look for MIN or MAX.  */
499218334Speter
499390075Sobrien  if ((! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
499418334Speter      && comparison_p
499590075Sobrien      && rtx_equal_p (XEXP (cond, 0), true_rtx)
499690075Sobrien      && rtx_equal_p (XEXP (cond, 1), false_rtx)
499718334Speter      && ! side_effects_p (cond))
499818334Speter    switch (true_code)
499918334Speter      {
500018334Speter      case GE:
500118334Speter      case GT:
5002169689Skan	return simplify_gen_binary (SMAX, mode, true_rtx, false_rtx);
500318334Speter      case LE:
500418334Speter      case LT:
5005169689Skan	return simplify_gen_binary (SMIN, mode, true_rtx, false_rtx);
500618334Speter      case GEU:
500718334Speter      case GTU:
5008169689Skan	return simplify_gen_binary (UMAX, mode, true_rtx, false_rtx);
500918334Speter      case LEU:
501018334Speter      case LTU:
5011169689Skan	return simplify_gen_binary (UMIN, mode, true_rtx, false_rtx);
501250397Sobrien      default:
501350397Sobrien	break;
501418334Speter      }
501590075Sobrien
501618334Speter  /* If we have (if_then_else COND (OP Z C1) Z) and OP is an identity when its
501718334Speter     second operand is zero, this can be done as (OP Z (mult COND C2)) where
501818334Speter     C2 = C1 * STORE_FLAG_VALUE. Similarly if OP has an outer ZERO_EXTEND or
501918334Speter     SIGN_EXTEND as long as Z is already extended (so we don't destroy it).
502018334Speter     We can do this kind of thing in some cases when STORE_FLAG_VALUE is
502150397Sobrien     neither 1 or -1, but it isn't worth checking for.  */
502218334Speter
502350397Sobrien  if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
5024117395Skan      && comparison_p
5025117395Skan      && GET_MODE_CLASS (mode) == MODE_INT
5026117395Skan      && ! side_effects_p (x))
502718334Speter    {
502890075Sobrien      rtx t = make_compound_operation (true_rtx, SET);
502990075Sobrien      rtx f = make_compound_operation (false_rtx, SET);
503018334Speter      rtx cond_op0 = XEXP (cond, 0);
503118334Speter      rtx cond_op1 = XEXP (cond, 1);
5032169689Skan      enum rtx_code op = UNKNOWN, extend_op = UNKNOWN;
503318334Speter      enum machine_mode m = mode;
503490075Sobrien      rtx z = 0, c1 = NULL_RTX;
503518334Speter
503618334Speter      if ((GET_CODE (t) == PLUS || GET_CODE (t) == MINUS
503718334Speter	   || GET_CODE (t) == IOR || GET_CODE (t) == XOR
503818334Speter	   || GET_CODE (t) == ASHIFT
503918334Speter	   || GET_CODE (t) == LSHIFTRT || GET_CODE (t) == ASHIFTRT)
504018334Speter	  && rtx_equal_p (XEXP (t, 0), f))
504118334Speter	c1 = XEXP (t, 1), op = GET_CODE (t), z = f;
504218334Speter
504318334Speter      /* If an identity-zero op is commutative, check whether there
504450397Sobrien	 would be a match if we swapped the operands.  */
504518334Speter      else if ((GET_CODE (t) == PLUS || GET_CODE (t) == IOR
504618334Speter		|| GET_CODE (t) == XOR)
504718334Speter	       && rtx_equal_p (XEXP (t, 1), f))
504818334Speter	c1 = XEXP (t, 0), op = GET_CODE (t), z = f;
504918334Speter      else if (GET_CODE (t) == SIGN_EXTEND
505018334Speter	       && (GET_CODE (XEXP (t, 0)) == PLUS
505118334Speter		   || GET_CODE (XEXP (t, 0)) == MINUS
505218334Speter		   || GET_CODE (XEXP (t, 0)) == IOR
505318334Speter		   || GET_CODE (XEXP (t, 0)) == XOR
505418334Speter		   || GET_CODE (XEXP (t, 0)) == ASHIFT
505518334Speter		   || GET_CODE (XEXP (t, 0)) == LSHIFTRT
505618334Speter		   || GET_CODE (XEXP (t, 0)) == ASHIFTRT)
505718334Speter	       && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG
505818334Speter	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 0))
505918334Speter	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f)
506018334Speter	       && (num_sign_bit_copies (f, GET_MODE (f))
5061117395Skan		   > (unsigned int)
5062117395Skan		     (GET_MODE_BITSIZE (mode)
506318334Speter		      - GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (t, 0), 0))))))
506418334Speter	{
506518334Speter	  c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0));
506618334Speter	  extend_op = SIGN_EXTEND;
506718334Speter	  m = GET_MODE (XEXP (t, 0));
506818334Speter	}
506918334Speter      else if (GET_CODE (t) == SIGN_EXTEND
507018334Speter	       && (GET_CODE (XEXP (t, 0)) == PLUS
507118334Speter		   || GET_CODE (XEXP (t, 0)) == IOR
507218334Speter		   || GET_CODE (XEXP (t, 0)) == XOR)
507318334Speter	       && GET_CODE (XEXP (XEXP (t, 0), 1)) == SUBREG
507418334Speter	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 1))
507518334Speter	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 1)), f)
507618334Speter	       && (num_sign_bit_copies (f, GET_MODE (f))
5077117395Skan		   > (unsigned int)
5078117395Skan		     (GET_MODE_BITSIZE (mode)
507918334Speter		      - GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (t, 0), 1))))))
508018334Speter	{
508118334Speter	  c1 = XEXP (XEXP (t, 0), 0); z = f; op = GET_CODE (XEXP (t, 0));
508218334Speter	  extend_op = SIGN_EXTEND;
508318334Speter	  m = GET_MODE (XEXP (t, 0));
508418334Speter	}
508518334Speter      else if (GET_CODE (t) == ZERO_EXTEND
508618334Speter	       && (GET_CODE (XEXP (t, 0)) == PLUS
508718334Speter		   || GET_CODE (XEXP (t, 0)) == MINUS
508818334Speter		   || GET_CODE (XEXP (t, 0)) == IOR
508918334Speter		   || GET_CODE (XEXP (t, 0)) == XOR
509018334Speter		   || GET_CODE (XEXP (t, 0)) == ASHIFT
509118334Speter		   || GET_CODE (XEXP (t, 0)) == LSHIFTRT
509218334Speter		   || GET_CODE (XEXP (t, 0)) == ASHIFTRT)
509318334Speter	       && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG
509418334Speter	       && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
509518334Speter	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 0))
509618334Speter	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f)
509718334Speter	       && ((nonzero_bits (f, GET_MODE (f))
509890075Sobrien		    & ~GET_MODE_MASK (GET_MODE (XEXP (XEXP (t, 0), 0))))
509918334Speter		   == 0))
510018334Speter	{
510118334Speter	  c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0));
510218334Speter	  extend_op = ZERO_EXTEND;
510318334Speter	  m = GET_MODE (XEXP (t, 0));
510418334Speter	}
510518334Speter      else if (GET_CODE (t) == ZERO_EXTEND
510618334Speter	       && (GET_CODE (XEXP (t, 0)) == PLUS
510718334Speter		   || GET_CODE (XEXP (t, 0)) == IOR
510818334Speter		   || GET_CODE (XEXP (t, 0)) == XOR)
510918334Speter	       && GET_CODE (XEXP (XEXP (t, 0), 1)) == SUBREG
511018334Speter	       && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
511118334Speter	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 1))
511218334Speter	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 1)), f)
511318334Speter	       && ((nonzero_bits (f, GET_MODE (f))
511490075Sobrien		    & ~GET_MODE_MASK (GET_MODE (XEXP (XEXP (t, 0), 1))))
511518334Speter		   == 0))
511618334Speter	{
511718334Speter	  c1 = XEXP (XEXP (t, 0), 0); z = f; op = GET_CODE (XEXP (t, 0));
511818334Speter	  extend_op = ZERO_EXTEND;
511918334Speter	  m = GET_MODE (XEXP (t, 0));
512018334Speter	}
512190075Sobrien
512218334Speter      if (z)
512318334Speter	{
5124169689Skan	  temp = subst (simplify_gen_relational (true_code, m, VOIDmode,
5125169689Skan						 cond_op0, cond_op1),
512618334Speter			pc_rtx, pc_rtx, 0, 0);
5127169689Skan	  temp = simplify_gen_binary (MULT, m, temp,
5128169689Skan				      simplify_gen_binary (MULT, m, c1,
5129169689Skan							   const_true_rtx));
513018334Speter	  temp = subst (temp, pc_rtx, pc_rtx, 0, 0);
5131169689Skan	  temp = simplify_gen_binary (op, m, gen_lowpart (m, z), temp);
513218334Speter
5133169689Skan	  if (extend_op != UNKNOWN)
513490075Sobrien	    temp = simplify_gen_unary (extend_op, mode, temp, m);
513518334Speter
513618334Speter	  return temp;
513718334Speter	}
513818334Speter    }
513918334Speter
514018334Speter  /* If we have (if_then_else (ne A 0) C1 0) and either A is known to be 0 or
514118334Speter     1 and C1 is a single bit or A is known to be 0 or -1 and C1 is the
514218334Speter     negation of a single bit, we can convert this operation to a shift.  We
514318334Speter     can actually do this more generally, but it doesn't seem worth it.  */
514418334Speter
514518334Speter  if (true_code == NE && XEXP (cond, 1) == const0_rtx
514690075Sobrien      && false_rtx == const0_rtx && GET_CODE (true_rtx) == CONST_INT
514718334Speter      && ((1 == nonzero_bits (XEXP (cond, 0), mode)
514890075Sobrien	   && (i = exact_log2 (INTVAL (true_rtx))) >= 0)
514918334Speter	  || ((num_sign_bit_copies (XEXP (cond, 0), mode)
515018334Speter	       == GET_MODE_BITSIZE (mode))
515190075Sobrien	      && (i = exact_log2 (-INTVAL (true_rtx))) >= 0)))
515218334Speter    return
515318334Speter      simplify_shift_const (NULL_RTX, ASHIFT, mode,
5154169689Skan			    gen_lowpart (mode, XEXP (cond, 0)), i);
515518334Speter
5156132718Skan  /* (IF_THEN_ELSE (NE REG 0) (0) (8)) is REG for nonzero_bits (REG) == 8.  */
5157132718Skan  if (true_code == NE && XEXP (cond, 1) == const0_rtx
5158132718Skan      && false_rtx == const0_rtx && GET_CODE (true_rtx) == CONST_INT
5159132718Skan      && GET_MODE (XEXP (cond, 0)) == mode
5160132718Skan      && (INTVAL (true_rtx) & GET_MODE_MASK (mode))
5161132718Skan	  == nonzero_bits (XEXP (cond, 0), mode)
5162132718Skan      && (i = exact_log2 (INTVAL (true_rtx) & GET_MODE_MASK (mode))) >= 0)
5163132718Skan    return XEXP (cond, 0);
5164132718Skan
516518334Speter  return x;
516618334Speter}
516718334Speter
516818334Speter/* Simplify X, a SET expression.  Return the new expression.  */
516918334Speter
517018334Speterstatic rtx
5171132718Skansimplify_set (rtx x)
517218334Speter{
517318334Speter  rtx src = SET_SRC (x);
517418334Speter  rtx dest = SET_DEST (x);
517518334Speter  enum machine_mode mode
517618334Speter    = GET_MODE (src) != VOIDmode ? GET_MODE (src) : GET_MODE (dest);
517718334Speter  rtx other_insn;
517818334Speter  rtx *cc_use;
517918334Speter
518018334Speter  /* (set (pc) (return)) gets written as (return).  */
518118334Speter  if (GET_CODE (dest) == PC && GET_CODE (src) == RETURN)
518218334Speter    return src;
518318334Speter
518418334Speter  /* Now that we know for sure which bits of SRC we are using, see if we can
518518334Speter     simplify the expression for the object knowing that we only need the
518618334Speter     low-order bits.  */
518718334Speter
5188117395Skan  if (GET_MODE_CLASS (mode) == MODE_INT
5189117395Skan      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
519090075Sobrien    {
5191169689Skan      src = force_to_mode (src, mode, ~(HOST_WIDE_INT) 0, 0);
519290075Sobrien      SUBST (SET_SRC (x), src);
519390075Sobrien    }
519418334Speter
519518334Speter  /* If we are setting CC0 or if the source is a COMPARE, look for the use of
519618334Speter     the comparison result and try to simplify it unless we already have used
519718334Speter     undobuf.other_insn.  */
5198117395Skan  if ((GET_MODE_CLASS (mode) == MODE_CC
5199117395Skan       || GET_CODE (src) == COMPARE
5200117395Skan       || CC0_P (dest))
520118334Speter      && (cc_use = find_single_use (dest, subst_insn, &other_insn)) != 0
520218334Speter      && (undobuf.other_insn == 0 || other_insn == undobuf.other_insn)
5203169689Skan      && COMPARISON_P (*cc_use)
520418334Speter      && rtx_equal_p (XEXP (*cc_use, 0), dest))
520518334Speter    {
520618334Speter      enum rtx_code old_code = GET_CODE (*cc_use);
520718334Speter      enum rtx_code new_code;
5208117395Skan      rtx op0, op1, tmp;
520918334Speter      int other_changed = 0;
521018334Speter      enum machine_mode compare_mode = GET_MODE (dest);
521118334Speter
521218334Speter      if (GET_CODE (src) == COMPARE)
521318334Speter	op0 = XEXP (src, 0), op1 = XEXP (src, 1);
521418334Speter      else
5215169689Skan	op0 = src, op1 = CONST0_RTX (GET_MODE (src));
521618334Speter
5217169689Skan      tmp = simplify_relational_operation (old_code, compare_mode, VOIDmode,
5218169689Skan					   op0, op1);
5219169689Skan      if (!tmp)
5220169689Skan	new_code = old_code;
5221169689Skan      else if (!CONSTANT_P (tmp))
5222169689Skan	{
5223169689Skan	  new_code = GET_CODE (tmp);
5224169689Skan	  op0 = XEXP (tmp, 0);
5225169689Skan	  op1 = XEXP (tmp, 1);
5226169689Skan	}
5227117395Skan      else
5228117395Skan	{
5229117395Skan	  rtx pat = PATTERN (other_insn);
5230117395Skan	  undobuf.other_insn = other_insn;
5231117395Skan	  SUBST (*cc_use, tmp);
5232117395Skan
5233117395Skan	  /* Attempt to simplify CC user.  */
5234117395Skan	  if (GET_CODE (pat) == SET)
5235117395Skan	    {
5236117395Skan	      rtx new = simplify_rtx (SET_SRC (pat));
5237117395Skan	      if (new != NULL_RTX)
5238117395Skan		SUBST (SET_SRC (pat), new);
5239117395Skan	    }
5240117395Skan
5241117395Skan	  /* Convert X into a no-op move.  */
5242117395Skan	  SUBST (SET_DEST (x), pc_rtx);
5243117395Skan	  SUBST (SET_SRC (x), pc_rtx);
5244117395Skan	  return x;
5245117395Skan	}
5246117395Skan
524718334Speter      /* Simplify our comparison, if possible.  */
5248169689Skan      new_code = simplify_comparison (new_code, &op0, &op1);
524918334Speter
5250132718Skan#ifdef SELECT_CC_MODE
525118334Speter      /* If this machine has CC modes other than CCmode, check to see if we
525218334Speter	 need to use a different CC mode here.  */
5253169689Skan      if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
5254169689Skan	compare_mode = GET_MODE (op0);
5255169689Skan      else
5256169689Skan	compare_mode = SELECT_CC_MODE (new_code, op0, op1);
525718334Speter
5258132718Skan#ifndef HAVE_cc0
525918334Speter      /* If the mode changed, we have to change SET_DEST, the mode in the
526018334Speter	 compare, and the mode in the place SET_DEST is used.  If SET_DEST is
526118334Speter	 a hard register, just build new versions with the proper mode.  If it
526218334Speter	 is a pseudo, we lose unless it is only time we set the pseudo, in
526318334Speter	 which case we can safely change its mode.  */
526418334Speter      if (compare_mode != GET_MODE (dest))
526518334Speter	{
5266169689Skan	  if (can_change_dest_mode (dest, 0, compare_mode))
526718334Speter	    {
5268169689Skan	      unsigned int regno = REGNO (dest);
5269169689Skan	      rtx new_dest;
527018334Speter
5271169689Skan	      if (regno < FIRST_PSEUDO_REGISTER)
5272169689Skan		new_dest = gen_rtx_REG (compare_mode, regno);
5273169689Skan	      else
5274169689Skan		{
5275169689Skan		  SUBST_MODE (regno_reg_rtx[regno], compare_mode);
5276169689Skan		  new_dest = regno_reg_rtx[regno];
5277169689Skan		}
5278169689Skan
527918334Speter	      SUBST (SET_DEST (x), new_dest);
528018334Speter	      SUBST (XEXP (*cc_use, 0), new_dest);
528118334Speter	      other_changed = 1;
528218334Speter
528318334Speter	      dest = new_dest;
528418334Speter	    }
528518334Speter	}
5286132718Skan#endif  /* cc0 */
5287132718Skan#endif  /* SELECT_CC_MODE */
528818334Speter
528918334Speter      /* If the code changed, we have to build a new comparison in
529018334Speter	 undobuf.other_insn.  */
529118334Speter      if (new_code != old_code)
529218334Speter	{
5293132718Skan	  int other_changed_previously = other_changed;
529418334Speter	  unsigned HOST_WIDE_INT mask;
529518334Speter
529690075Sobrien	  SUBST (*cc_use, gen_rtx_fmt_ee (new_code, GET_MODE (*cc_use),
529790075Sobrien					  dest, const0_rtx));
5298132718Skan	  other_changed = 1;
529918334Speter
530018334Speter	  /* If the only change we made was to change an EQ into an NE or
530118334Speter	     vice versa, OP0 has only one bit that might be nonzero, and OP1
530218334Speter	     is zero, check if changing the user of the condition code will
530318334Speter	     produce a valid insn.  If it won't, we can keep the original code
530418334Speter	     in that insn by surrounding our operation with an XOR.  */
530518334Speter
530618334Speter	  if (((old_code == NE && new_code == EQ)
530718334Speter	       || (old_code == EQ && new_code == NE))
5308132718Skan	      && ! other_changed_previously && op1 == const0_rtx
530918334Speter	      && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT
531018334Speter	      && exact_log2 (mask = nonzero_bits (op0, GET_MODE (op0))) >= 0)
531118334Speter	    {
531218334Speter	      rtx pat = PATTERN (other_insn), note = 0;
531318334Speter
531452284Sobrien	      if ((recog_for_combine (&pat, other_insn, &note) < 0
531518334Speter		   && ! check_asm_operands (pat)))
531618334Speter		{
531718334Speter		  PUT_CODE (*cc_use, old_code);
5318132718Skan		  other_changed = 0;
531918334Speter
5320169689Skan		  op0 = simplify_gen_binary (XOR, GET_MODE (op0),
5321169689Skan					     op0, GEN_INT (mask));
532218334Speter		}
532318334Speter	    }
532418334Speter	}
532518334Speter
532618334Speter      if (other_changed)
532718334Speter	undobuf.other_insn = other_insn;
532818334Speter
532918334Speter#ifdef HAVE_cc0
533018334Speter      /* If we are now comparing against zero, change our source if
533118334Speter	 needed.  If we do not use cc0, we always have a COMPARE.  */
533218334Speter      if (op1 == const0_rtx && dest == cc0_rtx)
533318334Speter	{
533418334Speter	  SUBST (SET_SRC (x), op0);
533518334Speter	  src = op0;
533618334Speter	}
533718334Speter      else
533818334Speter#endif
533918334Speter
534018334Speter      /* Otherwise, if we didn't previously have a COMPARE in the
534118334Speter	 correct mode, we need one.  */
534218334Speter      if (GET_CODE (src) != COMPARE || GET_MODE (src) != compare_mode)
534318334Speter	{
534490075Sobrien	  SUBST (SET_SRC (x), gen_rtx_COMPARE (compare_mode, op0, op1));
534518334Speter	  src = SET_SRC (x);
534618334Speter	}
5347169689Skan      else if (GET_MODE (op0) == compare_mode && op1 == const0_rtx)
5348169689Skan	{
5349171825Skan	  SUBST (SET_SRC (x), op0);
5350169689Skan	  src = SET_SRC (x);
5351169689Skan	}
5352171825Skan      /* Otherwise, update the COMPARE if needed.  */
5353171825Skan      else if (XEXP (src, 0) != op0 || XEXP (src, 1) != op1)
535418334Speter	{
5355171825Skan	  SUBST (SET_SRC (x), gen_rtx_COMPARE (compare_mode, op0, op1));
5356171825Skan	  src = SET_SRC (x);
535718334Speter	}
535818334Speter    }
535918334Speter  else
536018334Speter    {
536118334Speter      /* Get SET_SRC in a form where we have placed back any
536218334Speter	 compound expressions.  Then do the checks below.  */
536318334Speter      src = make_compound_operation (src, SET);
536418334Speter      SUBST (SET_SRC (x), src);
536518334Speter    }
536618334Speter
536718334Speter  /* If we have (set x (subreg:m1 (op:m2 ...) 0)) with OP being some operation,
536818334Speter     and X being a REG or (subreg (reg)), we may be able to convert this to
536990075Sobrien     (set (subreg:m2 x) (op)).
537018334Speter
537118334Speter     We can always do this if M1 is narrower than M2 because that means that
537218334Speter     we only care about the low bits of the result.
537318334Speter
537418334Speter     However, on machines without WORD_REGISTER_OPERATIONS defined, we cannot
537550397Sobrien     perform a narrower operation than requested since the high-order bits will
537618334Speter     be undefined.  On machine where it is defined, this transformation is safe
537718334Speter     as long as M1 and M2 have the same number of words.  */
537890075Sobrien
537918334Speter  if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)
5380169689Skan      && !OBJECT_P (SUBREG_REG (src))
538118334Speter      && (((GET_MODE_SIZE (GET_MODE (src)) + (UNITS_PER_WORD - 1))
538218334Speter	   / UNITS_PER_WORD)
538318334Speter	  == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
538418334Speter	       + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
538518334Speter#ifndef WORD_REGISTER_OPERATIONS
538618334Speter      && (GET_MODE_SIZE (GET_MODE (src))
5387169689Skan	< GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
538818334Speter#endif
5389117395Skan#ifdef CANNOT_CHANGE_MODE_CLASS
5390169689Skan      && ! (REG_P (dest) && REGNO (dest) < FIRST_PSEUDO_REGISTER
5391117395Skan	    && REG_CANNOT_CHANGE_MODE_P (REGNO (dest),
5392132718Skan					 GET_MODE (SUBREG_REG (src)),
5393117395Skan					 GET_MODE (src)))
539490075Sobrien#endif
5395169689Skan      && (REG_P (dest)
539618334Speter	  || (GET_CODE (dest) == SUBREG
5397169689Skan	      && REG_P (SUBREG_REG (dest)))))
539818334Speter    {
539918334Speter      SUBST (SET_DEST (x),
5400169689Skan	     gen_lowpart (GET_MODE (SUBREG_REG (src)),
540118334Speter				      dest));
540218334Speter      SUBST (SET_SRC (x), SUBREG_REG (src));
540318334Speter
540418334Speter      src = SET_SRC (x), dest = SET_DEST (x);
540518334Speter    }
540618334Speter
5407117395Skan#ifdef HAVE_cc0
5408117395Skan  /* If we have (set (cc0) (subreg ...)), we try to remove the subreg
5409117395Skan     in SRC.  */
5410117395Skan  if (dest == cc0_rtx
5411117395Skan      && GET_CODE (src) == SUBREG
5412117395Skan      && subreg_lowpart_p (src)
5413117395Skan      && (GET_MODE_BITSIZE (GET_MODE (src))
5414117395Skan	  < GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (src)))))
5415117395Skan    {
5416117395Skan      rtx inner = SUBREG_REG (src);
5417117395Skan      enum machine_mode inner_mode = GET_MODE (inner);
5418117395Skan
5419117395Skan      /* Here we make sure that we don't have a sign bit on.  */
5420117395Skan      if (GET_MODE_BITSIZE (inner_mode) <= HOST_BITS_PER_WIDE_INT
5421117395Skan	  && (nonzero_bits (inner, inner_mode)
5422117395Skan	      < ((unsigned HOST_WIDE_INT) 1
5423117395Skan		 << (GET_MODE_BITSIZE (GET_MODE (src)) - 1))))
5424117395Skan	{
5425117395Skan	  SUBST (SET_SRC (x), inner);
5426117395Skan	  src = SET_SRC (x);
5427117395Skan	}
5428117395Skan    }
5429117395Skan#endif
5430117395Skan
543118334Speter#ifdef LOAD_EXTEND_OP
543218334Speter  /* If we have (set FOO (subreg:M (mem:N BAR) 0)) with M wider than N, this
543318334Speter     would require a paradoxical subreg.  Replace the subreg with a
543450397Sobrien     zero_extend to avoid the reload that would otherwise be required.  */
543518334Speter
543618334Speter  if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)
5437169689Skan      && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (src))) != UNKNOWN
543890075Sobrien      && SUBREG_BYTE (src) == 0
543918334Speter      && (GET_MODE_SIZE (GET_MODE (src))
544018334Speter	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
5441169689Skan      && MEM_P (SUBREG_REG (src)))
544218334Speter    {
544318334Speter      SUBST (SET_SRC (x),
5444169689Skan	     gen_rtx_fmt_e (LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (src))),
5445169689Skan			    GET_MODE (src), SUBREG_REG (src)));
544618334Speter
544718334Speter      src = SET_SRC (x);
544818334Speter    }
544918334Speter#endif
545018334Speter
545118334Speter  /* If we don't have a conditional move, SET_SRC is an IF_THEN_ELSE, and we
545218334Speter     are comparing an item known to be 0 or -1 against 0, use a logical
545318334Speter     operation instead. Check for one of the arms being an IOR of the other
545418334Speter     arm with some value.  We compute three terms to be IOR'ed together.  In
545518334Speter     practice, at most two will be nonzero.  Then we do the IOR's.  */
545618334Speter
545718334Speter  if (GET_CODE (dest) != PC
545818334Speter      && GET_CODE (src) == IF_THEN_ELSE
545918334Speter      && GET_MODE_CLASS (GET_MODE (src)) == MODE_INT
546018334Speter      && (GET_CODE (XEXP (src, 0)) == EQ || GET_CODE (XEXP (src, 0)) == NE)
546118334Speter      && XEXP (XEXP (src, 0), 1) == const0_rtx
546218334Speter      && GET_MODE (src) == GET_MODE (XEXP (XEXP (src, 0), 0))
546318334Speter#ifdef HAVE_conditional_move
546418334Speter      && ! can_conditionally_move_p (GET_MODE (src))
546518334Speter#endif
546618334Speter      && (num_sign_bit_copies (XEXP (XEXP (src, 0), 0),
546718334Speter			       GET_MODE (XEXP (XEXP (src, 0), 0)))
546818334Speter	  == GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (src, 0), 0))))
546918334Speter      && ! side_effects_p (src))
547018334Speter    {
547190075Sobrien      rtx true_rtx = (GET_CODE (XEXP (src, 0)) == NE
547218334Speter		      ? XEXP (src, 1) : XEXP (src, 2));
547390075Sobrien      rtx false_rtx = (GET_CODE (XEXP (src, 0)) == NE
547418334Speter		   ? XEXP (src, 2) : XEXP (src, 1));
547518334Speter      rtx term1 = const0_rtx, term2, term3;
547618334Speter
547790075Sobrien      if (GET_CODE (true_rtx) == IOR
547890075Sobrien	  && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
5479132718Skan	term1 = false_rtx, true_rtx = XEXP (true_rtx, 1), false_rtx = const0_rtx;
548090075Sobrien      else if (GET_CODE (true_rtx) == IOR
548190075Sobrien	       && rtx_equal_p (XEXP (true_rtx, 1), false_rtx))
5482132718Skan	term1 = false_rtx, true_rtx = XEXP (true_rtx, 0), false_rtx = const0_rtx;
548390075Sobrien      else if (GET_CODE (false_rtx) == IOR
548490075Sobrien	       && rtx_equal_p (XEXP (false_rtx, 0), true_rtx))
5485132718Skan	term1 = true_rtx, false_rtx = XEXP (false_rtx, 1), true_rtx = const0_rtx;
548690075Sobrien      else if (GET_CODE (false_rtx) == IOR
548790075Sobrien	       && rtx_equal_p (XEXP (false_rtx, 1), true_rtx))
5488132718Skan	term1 = true_rtx, false_rtx = XEXP (false_rtx, 0), true_rtx = const0_rtx;
548918334Speter
5490169689Skan      term2 = simplify_gen_binary (AND, GET_MODE (src),
5491169689Skan				   XEXP (XEXP (src, 0), 0), true_rtx);
5492169689Skan      term3 = simplify_gen_binary (AND, GET_MODE (src),
5493169689Skan				   simplify_gen_unary (NOT, GET_MODE (src),
5494169689Skan						       XEXP (XEXP (src, 0), 0),
5495169689Skan						       GET_MODE (src)),
5496169689Skan				   false_rtx);
549718334Speter
549818334Speter      SUBST (SET_SRC (x),
5499169689Skan	     simplify_gen_binary (IOR, GET_MODE (src),
5500169689Skan				  simplify_gen_binary (IOR, GET_MODE (src),
5501169689Skan						       term1, term2),
5502169689Skan				  term3));
550318334Speter
550418334Speter      src = SET_SRC (x);
550518334Speter    }
550618334Speter
550718334Speter  /* If either SRC or DEST is a CLOBBER of (const_int 0), make this
550818334Speter     whole thing fail.  */
550918334Speter  if (GET_CODE (src) == CLOBBER && XEXP (src, 0) == const0_rtx)
551018334Speter    return src;
551118334Speter  else if (GET_CODE (dest) == CLOBBER && XEXP (dest, 0) == const0_rtx)
551218334Speter    return dest;
551318334Speter  else
551418334Speter    /* Convert this into a field assignment operation, if possible.  */
551518334Speter    return make_field_assignment (x);
551618334Speter}
551718334Speter
551818334Speter/* Simplify, X, and AND, IOR, or XOR operation, and return the simplified
5519169689Skan   result.  */
552018334Speter
552118334Speterstatic rtx
5522169689Skansimplify_logical (rtx x)
552318334Speter{
552418334Speter  enum machine_mode mode = GET_MODE (x);
552518334Speter  rtx op0 = XEXP (x, 0);
552618334Speter  rtx op1 = XEXP (x, 1);
552718334Speter
552818334Speter  switch (GET_CODE (x))
552918334Speter    {
553018334Speter    case AND:
553190075Sobrien      /* We can call simplify_and_const_int only if we don't lose
553290075Sobrien	 any (sign) bits when converting INTVAL (op1) to
553390075Sobrien	 "unsigned HOST_WIDE_INT".  */
553490075Sobrien      if (GET_CODE (op1) == CONST_INT
553590075Sobrien	  && (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
553690075Sobrien	      || INTVAL (op1) > 0))
553718334Speter	{
553818334Speter	  x = simplify_and_const_int (x, mode, op0, INTVAL (op1));
553918334Speter	  if (GET_CODE (x) != AND)
554018334Speter	    return x;
554118334Speter
5542169689Skan	  op0 = XEXP (x, 0);
5543169689Skan	  op1 = XEXP (x, 1);
554418334Speter	}
554518334Speter
5546169689Skan      /* If we have any of (and (ior A B) C) or (and (xor A B) C),
5547169689Skan	 apply the distributive law and then the inverse distributive
5548169689Skan	 law to see if things simplify.  */
554918334Speter      if (GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
555018334Speter	{
5551169689Skan	  rtx result = distribute_and_simplify_rtx (x, 0);
5552169689Skan	  if (result)
5553169689Skan	    return result;
555418334Speter	}
555518334Speter      if (GET_CODE (op1) == IOR || GET_CODE (op1) == XOR)
5556169689Skan	{
5557169689Skan	  rtx result = distribute_and_simplify_rtx (x, 1);
5558169689Skan	  if (result)
5559169689Skan	    return result;
5560169689Skan	}
556118334Speter      break;
556218334Speter
556318334Speter    case IOR:
556418334Speter      /* If we have (ior (and A B) C), apply the distributive law and then
556518334Speter	 the inverse distributive law to see if things simplify.  */
556618334Speter
556718334Speter      if (GET_CODE (op0) == AND)
556818334Speter	{
5569169689Skan	  rtx result = distribute_and_simplify_rtx (x, 0);
5570169689Skan	  if (result)
5571169689Skan	    return result;
557218334Speter	}
557318334Speter
557418334Speter      if (GET_CODE (op1) == AND)
557518334Speter	{
5576169689Skan	  rtx result = distribute_and_simplify_rtx (x, 1);
5577169689Skan	  if (result)
5578169689Skan	    return result;
557918334Speter	}
558018334Speter      break;
558118334Speter
558250397Sobrien    default:
5583169689Skan      gcc_unreachable ();
558418334Speter    }
558518334Speter
558618334Speter  return x;
558718334Speter}
558818334Speter
558918334Speter/* We consider ZERO_EXTRACT, SIGN_EXTRACT, and SIGN_EXTEND as "compound
559018334Speter   operations" because they can be replaced with two more basic operations.
559118334Speter   ZERO_EXTEND is also considered "compound" because it can be replaced with
559218334Speter   an AND operation, which is simpler, though only one operation.
559318334Speter
559418334Speter   The function expand_compound_operation is called with an rtx expression
559590075Sobrien   and will convert it to the appropriate shifts and AND operations,
559618334Speter   simplifying at each stage.
559718334Speter
559818334Speter   The function make_compound_operation is called to convert an expression
559918334Speter   consisting of shifts and ANDs into the equivalent compound expression.
560018334Speter   It is the inverse of this function, loosely speaking.  */
560118334Speter
560218334Speterstatic rtx
5603132718Skanexpand_compound_operation (rtx x)
560418334Speter{
560590075Sobrien  unsigned HOST_WIDE_INT pos = 0, len;
560618334Speter  int unsignedp = 0;
560790075Sobrien  unsigned int modewidth;
560818334Speter  rtx tem;
560918334Speter
561018334Speter  switch (GET_CODE (x))
561118334Speter    {
561218334Speter    case ZERO_EXTEND:
561318334Speter      unsignedp = 1;
561418334Speter    case SIGN_EXTEND:
561518334Speter      /* We can't necessarily use a const_int for a multiword mode;
561618334Speter	 it depends on implicitly extending the value.
561718334Speter	 Since we don't know the right way to extend it,
561818334Speter	 we can't tell whether the implicit way is right.
561918334Speter
562018334Speter	 Even for a mode that is no wider than a const_int,
562118334Speter	 we can't win, because we need to sign extend one of its bits through
562218334Speter	 the rest of it, and we don't know which bit.  */
562318334Speter      if (GET_CODE (XEXP (x, 0)) == CONST_INT)
562418334Speter	return x;
562518334Speter
562618334Speter      /* Return if (subreg:MODE FROM 0) is not a safe replacement for
562718334Speter	 (zero_extend:MODE FROM) or (sign_extend:MODE FROM).  It is for any MEM
562818334Speter	 because (SUBREG (MEM...)) is guaranteed to cause the MEM to be
562918334Speter	 reloaded. If not for that, MEM's would very rarely be safe.
563018334Speter
563118334Speter	 Reject MODEs bigger than a word, because we might not be able
563218334Speter	 to reference a two-register group starting with an arbitrary register
563318334Speter	 (and currently gen_lowpart might crash for a SUBREG).  */
563490075Sobrien
563518334Speter      if (GET_MODE_SIZE (GET_MODE (XEXP (x, 0))) > UNITS_PER_WORD)
563618334Speter	return x;
563718334Speter
5638117395Skan      /* Reject MODEs that aren't scalar integers because turning vector
5639117395Skan	 or complex modes into shifts causes problems.  */
5640117395Skan
5641117395Skan      if (! SCALAR_INT_MODE_P (GET_MODE (XEXP (x, 0))))
5642117395Skan	return x;
5643117395Skan
564418334Speter      len = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)));
564518334Speter      /* If the inner object has VOIDmode (the only way this can happen
5646117395Skan	 is if it is an ASM_OPERANDS), we can't do anything since we don't
564718334Speter	 know how much masking to do.  */
564818334Speter      if (len == 0)
564918334Speter	return x;
565018334Speter
565118334Speter      break;
565218334Speter
565318334Speter    case ZERO_EXTRACT:
565418334Speter      unsignedp = 1;
5655169689Skan
5656169689Skan      /* ... fall through ...  */
5657169689Skan
565818334Speter    case SIGN_EXTRACT:
565918334Speter      /* If the operand is a CLOBBER, just return it.  */
566018334Speter      if (GET_CODE (XEXP (x, 0)) == CLOBBER)
566118334Speter	return XEXP (x, 0);
566218334Speter
566318334Speter      if (GET_CODE (XEXP (x, 1)) != CONST_INT
566418334Speter	  || GET_CODE (XEXP (x, 2)) != CONST_INT
566518334Speter	  || GET_MODE (XEXP (x, 0)) == VOIDmode)
566618334Speter	return x;
566718334Speter
5668117395Skan      /* Reject MODEs that aren't scalar integers because turning vector
5669117395Skan	 or complex modes into shifts causes problems.  */
5670117395Skan
5671117395Skan      if (! SCALAR_INT_MODE_P (GET_MODE (XEXP (x, 0))))
5672117395Skan	return x;
5673117395Skan
567418334Speter      len = INTVAL (XEXP (x, 1));
567518334Speter      pos = INTVAL (XEXP (x, 2));
567618334Speter
5677169689Skan      /* This should stay within the object being extracted, fail otherwise.  */
567818334Speter      if (len + pos > GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))))
5679169689Skan	return x;
568018334Speter
568118334Speter      if (BITS_BIG_ENDIAN)
568218334Speter	pos = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - len - pos;
568318334Speter
568418334Speter      break;
568518334Speter
568618334Speter    default:
568718334Speter      return x;
568818334Speter    }
568990075Sobrien  /* Convert sign extension to zero extension, if we know that the high
569090075Sobrien     bit is not set, as this is easier to optimize.  It will be converted
569190075Sobrien     back to cheaper alternative in make_extraction.  */
569290075Sobrien  if (GET_CODE (x) == SIGN_EXTEND
569390075Sobrien      && (GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
569490075Sobrien	  && ((nonzero_bits (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
569590075Sobrien		& ~(((unsigned HOST_WIDE_INT)
569690075Sobrien		      GET_MODE_MASK (GET_MODE (XEXP (x, 0))))
569790075Sobrien		     >> 1))
569890075Sobrien	       == 0)))
569990075Sobrien    {
570090075Sobrien      rtx temp = gen_rtx_ZERO_EXTEND (GET_MODE (x), XEXP (x, 0));
5701132718Skan      rtx temp2 = expand_compound_operation (temp);
5702132718Skan
5703132718Skan      /* Make sure this is a profitable operation.  */
5704132718Skan      if (rtx_cost (x, SET) > rtx_cost (temp2, SET))
5705132718Skan       return temp2;
5706132718Skan      else if (rtx_cost (x, SET) > rtx_cost (temp, SET))
5707132718Skan       return temp;
5708132718Skan      else
5709132718Skan       return x;
571090075Sobrien    }
571118334Speter
571250397Sobrien  /* We can optimize some special cases of ZERO_EXTEND.  */
571350397Sobrien  if (GET_CODE (x) == ZERO_EXTEND)
571450397Sobrien    {
571550397Sobrien      /* (zero_extend:DI (truncate:SI foo:DI)) is just foo:DI if we
5716169689Skan	 know that the last value didn't have any inappropriate bits
5717169689Skan	 set.  */
571850397Sobrien      if (GET_CODE (XEXP (x, 0)) == TRUNCATE
571950397Sobrien	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == GET_MODE (x)
572050397Sobrien	  && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
572150397Sobrien	  && (nonzero_bits (XEXP (XEXP (x, 0), 0), GET_MODE (x))
572290075Sobrien	      & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
572350397Sobrien	return XEXP (XEXP (x, 0), 0);
572450397Sobrien
572550397Sobrien      /* Likewise for (zero_extend:DI (subreg:SI foo:DI 0)).  */
572650397Sobrien      if (GET_CODE (XEXP (x, 0)) == SUBREG
572750397Sobrien	  && GET_MODE (SUBREG_REG (XEXP (x, 0))) == GET_MODE (x)
572850397Sobrien	  && subreg_lowpart_p (XEXP (x, 0))
572950397Sobrien	  && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
573050397Sobrien	  && (nonzero_bits (SUBREG_REG (XEXP (x, 0)), GET_MODE (x))
573190075Sobrien	      & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
573250397Sobrien	return SUBREG_REG (XEXP (x, 0));
573350397Sobrien
573450397Sobrien      /* (zero_extend:DI (truncate:SI foo:DI)) is just foo:DI when foo
5735169689Skan	 is a comparison and STORE_FLAG_VALUE permits.  This is like
5736169689Skan	 the first case, but it works even when GET_MODE (x) is larger
5737169689Skan	 than HOST_WIDE_INT.  */
573850397Sobrien      if (GET_CODE (XEXP (x, 0)) == TRUNCATE
573950397Sobrien	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == GET_MODE (x)
5740169689Skan	  && COMPARISON_P (XEXP (XEXP (x, 0), 0))
574150397Sobrien	  && (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
574250397Sobrien	      <= HOST_BITS_PER_WIDE_INT)
574390075Sobrien	  && ((HOST_WIDE_INT) STORE_FLAG_VALUE
574490075Sobrien	      & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
574550397Sobrien	return XEXP (XEXP (x, 0), 0);
574650397Sobrien
574750397Sobrien      /* Likewise for (zero_extend:DI (subreg:SI foo:DI 0)).  */
574850397Sobrien      if (GET_CODE (XEXP (x, 0)) == SUBREG
574950397Sobrien	  && GET_MODE (SUBREG_REG (XEXP (x, 0))) == GET_MODE (x)
575050397Sobrien	  && subreg_lowpart_p (XEXP (x, 0))
5751169689Skan	  && COMPARISON_P (SUBREG_REG (XEXP (x, 0)))
575250397Sobrien	  && (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
575350397Sobrien	      <= HOST_BITS_PER_WIDE_INT)
575450397Sobrien	  && ((HOST_WIDE_INT) STORE_FLAG_VALUE
575590075Sobrien	      & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
575650397Sobrien	return SUBREG_REG (XEXP (x, 0));
575750397Sobrien
575850397Sobrien    }
575950397Sobrien
576018334Speter  /* If we reach here, we want to return a pair of shifts.  The inner
576118334Speter     shift is a left shift of BITSIZE - POS - LEN bits.  The outer
576218334Speter     shift is a right shift of BITSIZE - LEN bits.  It is arithmetic or
576318334Speter     logical depending on the value of UNSIGNEDP.
576418334Speter
576518334Speter     If this was a ZERO_EXTEND or ZERO_EXTRACT, this pair of shifts will be
576618334Speter     converted into an AND of a shift.
576718334Speter
576818334Speter     We must check for the case where the left shift would have a negative
576918334Speter     count.  This can happen in a case like (x >> 31) & 255 on machines
577018334Speter     that can't shift by a constant.  On those machines, we would first
577190075Sobrien     combine the shift with the AND to produce a variable-position
577218334Speter     extraction.  Then the constant of 31 would be substituted in to produce
577318334Speter     a such a position.  */
577418334Speter
577518334Speter  modewidth = GET_MODE_BITSIZE (GET_MODE (x));
577690075Sobrien  if (modewidth + len >= pos)
5777169689Skan    {
5778169689Skan      enum machine_mode mode = GET_MODE (x);
5779169689Skan      tem = gen_lowpart (mode, XEXP (x, 0));
5780169689Skan      if (!tem || GET_CODE (tem) == CLOBBER)
5781169689Skan	return x;
5782169689Skan      tem = simplify_shift_const (NULL_RTX, ASHIFT, mode,
5783169689Skan				  tem, modewidth - pos - len);
5784169689Skan      tem = simplify_shift_const (NULL_RTX, unsignedp ? LSHIFTRT : ASHIFTRT,
5785169689Skan				  mode, tem, modewidth - len);
5786169689Skan    }
578718334Speter  else if (unsignedp && len < HOST_BITS_PER_WIDE_INT)
578818334Speter    tem = simplify_and_const_int (NULL_RTX, GET_MODE (x),
578918334Speter				  simplify_shift_const (NULL_RTX, LSHIFTRT,
579018334Speter							GET_MODE (x),
579118334Speter							XEXP (x, 0), pos),
579218334Speter				  ((HOST_WIDE_INT) 1 << len) - 1);
579318334Speter  else
579418334Speter    /* Any other cases we can't handle.  */
579518334Speter    return x;
579618334Speter
579718334Speter  /* If we couldn't do this for some reason, return the original
579818334Speter     expression.  */
579918334Speter  if (GET_CODE (tem) == CLOBBER)
580018334Speter    return x;
580118334Speter
580218334Speter  return tem;
580318334Speter}
580418334Speter
580518334Speter/* X is a SET which contains an assignment of one object into
580618334Speter   a part of another (such as a bit-field assignment, STRICT_LOW_PART,
580718334Speter   or certain SUBREGS). If possible, convert it into a series of
580818334Speter   logical operations.
580918334Speter
581018334Speter   We half-heartedly support variable positions, but do not at all
581118334Speter   support variable lengths.  */
581218334Speter
581318334Speterstatic rtx
5814132718Skanexpand_field_assignment (rtx x)
581518334Speter{
581618334Speter  rtx inner;
581750397Sobrien  rtx pos;			/* Always counts from low bit.  */
581818334Speter  int len;
5819169689Skan  rtx mask, cleared, masked;
582018334Speter  enum machine_mode compute_mode;
582118334Speter
582218334Speter  /* Loop until we find something we can't simplify.  */
582318334Speter  while (1)
582418334Speter    {
582518334Speter      if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART
582618334Speter	  && GET_CODE (XEXP (SET_DEST (x), 0)) == SUBREG)
582718334Speter	{
582818334Speter	  inner = SUBREG_REG (XEXP (SET_DEST (x), 0));
582918334Speter	  len = GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0)));
583090075Sobrien	  pos = GEN_INT (subreg_lsb (XEXP (SET_DEST (x), 0)));
583118334Speter	}
583218334Speter      else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
583318334Speter	       && GET_CODE (XEXP (SET_DEST (x), 1)) == CONST_INT)
583418334Speter	{
583518334Speter	  inner = XEXP (SET_DEST (x), 0);
583618334Speter	  len = INTVAL (XEXP (SET_DEST (x), 1));
583718334Speter	  pos = XEXP (SET_DEST (x), 2);
583818334Speter
5839169689Skan	  /* A constant position should stay within the width of INNER.  */
584018334Speter	  if (GET_CODE (pos) == CONST_INT
584118334Speter	      && INTVAL (pos) + len > GET_MODE_BITSIZE (GET_MODE (inner)))
5842169689Skan	    break;
584318334Speter
584418334Speter	  if (BITS_BIG_ENDIAN)
584518334Speter	    {
584618334Speter	      if (GET_CODE (pos) == CONST_INT)
584718334Speter		pos = GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner)) - len
584818334Speter			       - INTVAL (pos));
584918334Speter	      else if (GET_CODE (pos) == MINUS
585018334Speter		       && GET_CODE (XEXP (pos, 1)) == CONST_INT
585118334Speter		       && (INTVAL (XEXP (pos, 1))
585218334Speter			   == GET_MODE_BITSIZE (GET_MODE (inner)) - len))
585318334Speter		/* If position is ADJUST - X, new position is X.  */
585418334Speter		pos = XEXP (pos, 0);
585518334Speter	      else
5856169689Skan		pos = simplify_gen_binary (MINUS, GET_MODE (pos),
5857169689Skan					   GEN_INT (GET_MODE_BITSIZE (
5858169689Skan						    GET_MODE (inner))
5859169689Skan						    - len),
5860169689Skan					   pos);
586118334Speter	    }
586218334Speter	}
586318334Speter
586418334Speter      /* A SUBREG between two modes that occupy the same numbers of words
586518334Speter	 can be done by moving the SUBREG to the source.  */
586618334Speter      else if (GET_CODE (SET_DEST (x)) == SUBREG
586790075Sobrien	       /* We need SUBREGs to compute nonzero_bits properly.  */
586890075Sobrien	       && nonzero_sign_valid
586918334Speter	       && (((GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
587018334Speter		     + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
587118334Speter		   == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x))))
587218334Speter			+ (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
587318334Speter	{
587450397Sobrien	  x = gen_rtx_SET (VOIDmode, SUBREG_REG (SET_DEST (x)),
5875169689Skan			   gen_lowpart
587690075Sobrien			   (GET_MODE (SUBREG_REG (SET_DEST (x))),
587790075Sobrien			    SET_SRC (x)));
587818334Speter	  continue;
587918334Speter	}
588018334Speter      else
588118334Speter	break;
588218334Speter
588318334Speter      while (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner))
588418334Speter	inner = SUBREG_REG (inner);
588518334Speter
588618334Speter      compute_mode = GET_MODE (inner);
588718334Speter
5888117395Skan      /* Don't attempt bitwise arithmetic on non scalar integer modes.  */
5889117395Skan      if (! SCALAR_INT_MODE_P (compute_mode))
589052284Sobrien	{
589152284Sobrien	  enum machine_mode imode;
589252284Sobrien
5893117395Skan	  /* Don't do anything for vector or complex integral types.  */
589452284Sobrien	  if (! FLOAT_MODE_P (compute_mode))
589552284Sobrien	    break;
589652284Sobrien
589752284Sobrien	  /* Try to find an integral mode to pun with.  */
589852284Sobrien	  imode = mode_for_size (GET_MODE_BITSIZE (compute_mode), MODE_INT, 0);
589952284Sobrien	  if (imode == BLKmode)
590052284Sobrien	    break;
590152284Sobrien
590252284Sobrien	  compute_mode = imode;
5903169689Skan	  inner = gen_lowpart (imode, inner);
590452284Sobrien	}
590552284Sobrien
590618334Speter      /* Compute a mask of LEN bits, if we can do this on the host machine.  */
5907169689Skan      if (len >= HOST_BITS_PER_WIDE_INT)
590818334Speter	break;
590918334Speter
591018334Speter      /* Now compute the equivalent expression.  Make a copy of INNER
591118334Speter	 for the SET_DEST in case it is a MEM into which we will substitute;
591218334Speter	 we don't want shared RTL in that case.  */
5913169689Skan      mask = GEN_INT (((HOST_WIDE_INT) 1 << len) - 1);
5914169689Skan      cleared = simplify_gen_binary (AND, compute_mode,
5915169689Skan				     simplify_gen_unary (NOT, compute_mode,
5916169689Skan				       simplify_gen_binary (ASHIFT,
5917169689Skan							    compute_mode,
5918169689Skan							    mask, pos),
5919169689Skan				       compute_mode),
5920169689Skan				     inner);
5921169689Skan      masked = simplify_gen_binary (ASHIFT, compute_mode,
5922169689Skan				    simplify_gen_binary (
5923169689Skan				      AND, compute_mode,
5924169689Skan				      gen_lowpart (compute_mode, SET_SRC (x)),
5925169689Skan				      mask),
5926169689Skan				    pos);
5927169689Skan
5928169689Skan      x = gen_rtx_SET (VOIDmode, copy_rtx (inner),
5929169689Skan		       simplify_gen_binary (IOR, compute_mode,
5930169689Skan					    cleared, masked));
593118334Speter    }
593218334Speter
593318334Speter  return x;
593418334Speter}
593518334Speter
593618334Speter/* Return an RTX for a reference to LEN bits of INNER.  If POS_RTX is nonzero,
593718334Speter   it is an RTX that represents a variable starting position; otherwise,
593818334Speter   POS is the (constant) starting bit position (counted from the LSB).
593918334Speter
5940117395Skan   UNSIGNEDP is nonzero for an unsigned reference and zero for a
594118334Speter   signed reference.
594218334Speter
5943117395Skan   IN_DEST is nonzero if this is a reference in the destination of a
5944117395Skan   SET.  This is used when a ZERO_ or SIGN_EXTRACT isn't needed.  If nonzero,
594518334Speter   a STRICT_LOW_PART will be used, if zero, ZERO_EXTEND or SIGN_EXTEND will
594618334Speter   be used.
594718334Speter
5948117395Skan   IN_COMPARE is nonzero if we are in a COMPARE.  This means that a
594918334Speter   ZERO_EXTRACT should be built even for bits starting at bit 0.
595018334Speter
595150397Sobrien   MODE is the desired mode of the result (if IN_DEST == 0).
595218334Speter
595350397Sobrien   The result is an RTX for the extraction or NULL_RTX if the target
595450397Sobrien   can't handle it.  */
595550397Sobrien
595618334Speterstatic rtx
5957132718Skanmake_extraction (enum machine_mode mode, rtx inner, HOST_WIDE_INT pos,
5958132718Skan		 rtx pos_rtx, unsigned HOST_WIDE_INT len, int unsignedp,
5959132718Skan		 int in_dest, int in_compare)
596018334Speter{
596118334Speter  /* This mode describes the size of the storage area
596218334Speter     to fetch the overall value from.  Within that, we
596318334Speter     ignore the POS lowest bits, etc.  */
596418334Speter  enum machine_mode is_mode = GET_MODE (inner);
596518334Speter  enum machine_mode inner_mode;
5966169689Skan  enum machine_mode wanted_inner_mode;
596750397Sobrien  enum machine_mode wanted_inner_reg_mode = word_mode;
596818334Speter  enum machine_mode pos_mode = word_mode;
596918334Speter  enum machine_mode extraction_mode = word_mode;
597018334Speter  enum machine_mode tmode = mode_for_size (len, MODE_INT, 1);
597118334Speter  rtx new = 0;
597218334Speter  rtx orig_pos_rtx = pos_rtx;
597390075Sobrien  HOST_WIDE_INT orig_pos;
597418334Speter
5975169689Skan  if (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner))
597618334Speter    {
597718334Speter      /* If going from (subreg:SI (mem:QI ...)) to (mem:QI ...),
597818334Speter	 consider just the QI as the memory to extract from.
597918334Speter	 The subreg adds or removes high bits; its mode is
598018334Speter	 irrelevant to the meaning of this extraction,
598118334Speter	 since POS and LEN count from the lsb.  */
5982169689Skan      if (MEM_P (SUBREG_REG (inner)))
598318334Speter	is_mode = GET_MODE (SUBREG_REG (inner));
598418334Speter      inner = SUBREG_REG (inner);
598518334Speter    }
5986117395Skan  else if (GET_CODE (inner) == ASHIFT
5987117395Skan	   && GET_CODE (XEXP (inner, 1)) == CONST_INT
5988117395Skan	   && pos_rtx == 0 && pos == 0
5989117395Skan	   && len > (unsigned HOST_WIDE_INT) INTVAL (XEXP (inner, 1)))
5990117395Skan    {
5991117395Skan      /* We're extracting the least significant bits of an rtx
5992117395Skan	 (ashift X (const_int C)), where LEN > C.  Extract the
5993117395Skan	 least significant (LEN - C) bits of X, giving an rtx
5994117395Skan	 whose mode is MODE, then shift it left C times.  */
5995117395Skan      new = make_extraction (mode, XEXP (inner, 0),
5996117395Skan			     0, 0, len - INTVAL (XEXP (inner, 1)),
5997117395Skan			     unsignedp, in_dest, in_compare);
5998117395Skan      if (new != 0)
5999117395Skan	return gen_rtx_ASHIFT (mode, new, XEXP (inner, 1));
6000117395Skan    }
600118334Speter
600218334Speter  inner_mode = GET_MODE (inner);
600318334Speter
600418334Speter  if (pos_rtx && GET_CODE (pos_rtx) == CONST_INT)
600518334Speter    pos = INTVAL (pos_rtx), pos_rtx = 0;
600618334Speter
600718334Speter  /* See if this can be done without an extraction.  We never can if the
600818334Speter     width of the field is not the same as that of some integer mode. For
600918334Speter     registers, we can only avoid the extraction if the position is at the
601018334Speter     low-order bit and this is either not in the destination or we have the
601118334Speter     appropriate STRICT_LOW_PART operation available.
601218334Speter
601318334Speter     For MEM, we can avoid an extract if the field starts on an appropriate
6014169689Skan     boundary and we can change the mode of the memory reference.  */
601518334Speter
601618334Speter  if (tmode != BLKmode
601750397Sobrien      && ((pos_rtx == 0 && (pos % BITS_PER_WORD) == 0
6018169689Skan	   && !MEM_P (inner)
6019169689Skan	   && (inner_mode == tmode
6020169689Skan	       || !REG_P (inner)
6021169689Skan	       || TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (tmode),
6022169689Skan					 GET_MODE_BITSIZE (inner_mode))
6023169689Skan	       || reg_truncated_to_mode (tmode, inner))
602418334Speter	   && (! in_dest
6025169689Skan	       || (REG_P (inner)
602690075Sobrien		   && have_insn_for (STRICT_LOW_PART, tmode))))
6027169689Skan	  || (MEM_P (inner) && pos_rtx == 0
602818334Speter	      && (pos
602918334Speter		  % (STRICT_ALIGNMENT ? GET_MODE_ALIGNMENT (tmode)
603018334Speter		     : BITS_PER_UNIT)) == 0
603118334Speter	      /* We can't do this if we are widening INNER_MODE (it
603218334Speter		 may not be aligned, for one thing).  */
603318334Speter	      && GET_MODE_BITSIZE (inner_mode) >= GET_MODE_BITSIZE (tmode)
603418334Speter	      && (inner_mode == tmode
603518334Speter		  || (! mode_dependent_address_p (XEXP (inner, 0))
603618334Speter		      && ! MEM_VOLATILE_P (inner))))))
603718334Speter    {
603818334Speter      /* If INNER is a MEM, make a new MEM that encompasses just the desired
603918334Speter	 field.  If the original and current mode are the same, we need not
604090075Sobrien	 adjust the offset.  Otherwise, we do if bytes big endian.
604118334Speter
604250397Sobrien	 If INNER is not a MEM, get a piece consisting of just the field
604350397Sobrien	 of interest (in this case POS % BITS_PER_WORD must be 0).  */
604418334Speter
6045169689Skan      if (MEM_P (inner))
604618334Speter	{
604790075Sobrien	  HOST_WIDE_INT offset;
604890075Sobrien
604918334Speter	  /* POS counts from lsb, but make OFFSET count in memory order.  */
605018334Speter	  if (BYTES_BIG_ENDIAN)
605118334Speter	    offset = (GET_MODE_BITSIZE (is_mode) - len - pos) / BITS_PER_UNIT;
605218334Speter	  else
605318334Speter	    offset = pos / BITS_PER_UNIT;
605418334Speter
605590075Sobrien	  new = adjust_address_nv (inner, tmode, offset);
605618334Speter	}
6057169689Skan      else if (REG_P (inner))
605818334Speter	{
605918334Speter	  if (tmode != inner_mode)
606090075Sobrien	    {
6061169689Skan	      /* We can't call gen_lowpart in a DEST since we
6062132718Skan		 always want a SUBREG (see below) and it would sometimes
6063132718Skan		 return a new hard register.  */
6064132718Skan	      if (pos || in_dest)
6065132718Skan		{
6066132718Skan		  HOST_WIDE_INT final_word = pos / BITS_PER_WORD;
606790075Sobrien
6068132718Skan		  if (WORDS_BIG_ENDIAN
6069132718Skan		      && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD)
6070132718Skan		    final_word = ((GET_MODE_SIZE (inner_mode)
6071132718Skan				   - GET_MODE_SIZE (tmode))
6072132718Skan				  / UNITS_PER_WORD) - final_word;
607390075Sobrien
6074132718Skan		  final_word *= UNITS_PER_WORD;
6075132718Skan		  if (BYTES_BIG_ENDIAN &&
6076132718Skan		      GET_MODE_SIZE (inner_mode) > GET_MODE_SIZE (tmode))
6077132718Skan		    final_word += (GET_MODE_SIZE (inner_mode)
6078132718Skan				   - GET_MODE_SIZE (tmode)) % UNITS_PER_WORD;
607990075Sobrien
6080132718Skan		  /* Avoid creating invalid subregs, for example when
6081132718Skan		     simplifying (x>>32)&255.  */
6082169689Skan		  if (!validate_subreg (tmode, inner_mode, inner, final_word))
6083132718Skan		    return NULL_RTX;
6084110611Skan
6085132718Skan		  new = gen_rtx_SUBREG (tmode, inner, final_word);
6086132718Skan		}
6087132718Skan	      else
6088169689Skan		new = gen_lowpart (tmode, inner);
608990075Sobrien	    }
609018334Speter	  else
609118334Speter	    new = inner;
609218334Speter	}
609318334Speter      else
609418334Speter	new = force_to_mode (inner, tmode,
609518334Speter			     len >= HOST_BITS_PER_WIDE_INT
609690075Sobrien			     ? ~(unsigned HOST_WIDE_INT) 0
609790075Sobrien			     : ((unsigned HOST_WIDE_INT) 1 << len) - 1,
6098169689Skan			     0);
609918334Speter
610090075Sobrien      /* If this extraction is going into the destination of a SET,
610118334Speter	 make a STRICT_LOW_PART unless we made a MEM.  */
610218334Speter
610318334Speter      if (in_dest)
6104169689Skan	return (MEM_P (new) ? new
610518334Speter		: (GET_CODE (new) != SUBREG
610650397Sobrien		   ? gen_rtx_CLOBBER (tmode, const0_rtx)
610790075Sobrien		   : gen_rtx_STRICT_LOW_PART (VOIDmode, new)));
610818334Speter
610990075Sobrien      if (mode == tmode)
611090075Sobrien	return new;
611190075Sobrien
611296263Sobrien      if (GET_CODE (new) == CONST_INT)
6113117395Skan	return gen_int_mode (INTVAL (new), mode);
611496263Sobrien
611590075Sobrien      /* If we know that no extraneous bits are set, and that the high
611690075Sobrien	 bit is not set, convert the extraction to the cheaper of
611790075Sobrien	 sign and zero extension, that are equivalent in these cases.  */
611890075Sobrien      if (flag_expensive_optimizations
611990075Sobrien	  && (GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT
612090075Sobrien	      && ((nonzero_bits (new, tmode)
612190075Sobrien		   & ~(((unsigned HOST_WIDE_INT)
612290075Sobrien			GET_MODE_MASK (tmode))
612390075Sobrien		       >> 1))
612490075Sobrien		  == 0)))
612590075Sobrien	{
612690075Sobrien	  rtx temp = gen_rtx_ZERO_EXTEND (mode, new);
612790075Sobrien	  rtx temp1 = gen_rtx_SIGN_EXTEND (mode, new);
612890075Sobrien
612990075Sobrien	  /* Prefer ZERO_EXTENSION, since it gives more information to
613090075Sobrien	     backends.  */
613190075Sobrien	  if (rtx_cost (temp, SET) <= rtx_cost (temp1, SET))
613290075Sobrien	    return temp;
613390075Sobrien	  return temp1;
613490075Sobrien	}
613590075Sobrien
613618334Speter      /* Otherwise, sign- or zero-extend unless we already are in the
613718334Speter	 proper mode.  */
613818334Speter
613990075Sobrien      return (gen_rtx_fmt_e (unsignedp ? ZERO_EXTEND : SIGN_EXTEND,
614090075Sobrien			     mode, new));
614118334Speter    }
614218334Speter
614318334Speter  /* Unless this is a COMPARE or we have a funny memory reference,
614418334Speter     don't do anything with zero-extending field extracts starting at
614518334Speter     the low-order bit since they are simple AND operations.  */
614618334Speter  if (pos_rtx == 0 && pos == 0 && ! in_dest
6147169689Skan      && ! in_compare && unsignedp)
614818334Speter    return 0;
614918334Speter
6150169689Skan  /* Unless INNER is not MEM, reject this if we would be spanning bytes or
6151169689Skan     if the position is not a constant and the length is not 1.  In all
6152169689Skan     other cases, we would only be going outside our object in cases when
6153169689Skan     an original shift would have been undefined.  */
6154169689Skan  if (MEM_P (inner)
615518334Speter      && ((pos_rtx == 0 && pos + len > GET_MODE_BITSIZE (is_mode))
615618334Speter	  || (pos_rtx != 0 && len != 1)))
615718334Speter    return 0;
615818334Speter
615950397Sobrien  /* Get the mode to use should INNER not be a MEM, the mode for the position,
616018334Speter     and the mode for the result.  */
616190075Sobrien  if (in_dest && mode_for_extraction (EP_insv, -1) != MAX_MACHINE_MODE)
616218334Speter    {
616390075Sobrien      wanted_inner_reg_mode = mode_for_extraction (EP_insv, 0);
616490075Sobrien      pos_mode = mode_for_extraction (EP_insv, 2);
616590075Sobrien      extraction_mode = mode_for_extraction (EP_insv, 3);
616618334Speter    }
616718334Speter
616890075Sobrien  if (! in_dest && unsignedp
616990075Sobrien      && mode_for_extraction (EP_extzv, -1) != MAX_MACHINE_MODE)
617018334Speter    {
617190075Sobrien      wanted_inner_reg_mode = mode_for_extraction (EP_extzv, 1);
617290075Sobrien      pos_mode = mode_for_extraction (EP_extzv, 3);
617390075Sobrien      extraction_mode = mode_for_extraction (EP_extzv, 0);
617418334Speter    }
617518334Speter
617690075Sobrien  if (! in_dest && ! unsignedp
617790075Sobrien      && mode_for_extraction (EP_extv, -1) != MAX_MACHINE_MODE)
617818334Speter    {
617990075Sobrien      wanted_inner_reg_mode = mode_for_extraction (EP_extv, 1);
618090075Sobrien      pos_mode = mode_for_extraction (EP_extv, 3);
618190075Sobrien      extraction_mode = mode_for_extraction (EP_extv, 0);
618218334Speter    }
618318334Speter
618418334Speter  /* Never narrow an object, since that might not be safe.  */
618518334Speter
618618334Speter  if (mode != VOIDmode
618718334Speter      && GET_MODE_SIZE (extraction_mode) < GET_MODE_SIZE (mode))
618818334Speter    extraction_mode = mode;
618918334Speter
619018334Speter  if (pos_rtx && GET_MODE (pos_rtx) != VOIDmode
619118334Speter      && GET_MODE_SIZE (pos_mode) < GET_MODE_SIZE (GET_MODE (pos_rtx)))
619218334Speter    pos_mode = GET_MODE (pos_rtx);
619318334Speter
6194169689Skan  /* If this is not from memory, the desired mode is the preferred mode
6195169689Skan     for an extraction pattern's first input operand, or word_mode if there
6196169689Skan     is none.  */
6197169689Skan  if (!MEM_P (inner))
619850397Sobrien    wanted_inner_mode = wanted_inner_reg_mode;
6199169689Skan  else
6200169689Skan    {
6201169689Skan      /* Be careful not to go beyond the extracted object and maintain the
6202169689Skan	 natural alignment of the memory.  */
6203169689Skan      wanted_inner_mode = smallest_mode_for_size (len, MODE_INT);
6204169689Skan      while (pos % GET_MODE_BITSIZE (wanted_inner_mode) + len
6205169689Skan	     > GET_MODE_BITSIZE (wanted_inner_mode))
6206169689Skan	{
6207169689Skan	  wanted_inner_mode = GET_MODE_WIDER_MODE (wanted_inner_mode);
6208169689Skan	  gcc_assert (wanted_inner_mode != VOIDmode);
6209169689Skan	}
621018334Speter
6211169689Skan      /* If we have to change the mode of memory and cannot, the desired mode
6212169689Skan	 is EXTRACTION_MODE.  */
6213169689Skan      if (inner_mode != wanted_inner_mode
6214169689Skan	  && (mode_dependent_address_p (XEXP (inner, 0))
6215169689Skan	      || MEM_VOLATILE_P (inner)
6216169689Skan	      || pos_rtx))
6217169689Skan	wanted_inner_mode = extraction_mode;
6218169689Skan    }
6219169689Skan
622018334Speter  orig_pos = pos;
622118334Speter
622218334Speter  if (BITS_BIG_ENDIAN)
622318334Speter    {
622450397Sobrien      /* POS is passed as if BITS_BIG_ENDIAN == 0, so we need to convert it to
622550397Sobrien	 BITS_BIG_ENDIAN style.  If position is constant, compute new
622650397Sobrien	 position.  Otherwise, build subtraction.
622750397Sobrien	 Note that POS is relative to the mode of the original argument.
622850397Sobrien	 If it's a MEM we need to recompute POS relative to that.
622950397Sobrien	 However, if we're extracting from (or inserting into) a register,
623050397Sobrien	 we want to recompute POS relative to wanted_inner_mode.  */
6231169689Skan      int width = (MEM_P (inner)
623250397Sobrien		   ? GET_MODE_BITSIZE (is_mode)
623350397Sobrien		   : GET_MODE_BITSIZE (wanted_inner_mode));
623450397Sobrien
623518334Speter      if (pos_rtx == 0)
623650397Sobrien	pos = width - len - pos;
623718334Speter      else
623818334Speter	pos_rtx
623990075Sobrien	  = gen_rtx_MINUS (GET_MODE (pos_rtx), GEN_INT (width - len), pos_rtx);
624050397Sobrien      /* POS may be less than 0 now, but we check for that below.
6241169689Skan	 Note that it can only be less than 0 if !MEM_P (inner).  */
624218334Speter    }
624318334Speter
6244169689Skan  /* If INNER has a wider mode, and this is a constant extraction, try to
6245169689Skan     make it smaller and adjust the byte to point to the byte containing
624618334Speter     the value.  */
624750397Sobrien  if (wanted_inner_mode != VOIDmode
6248169689Skan      && inner_mode != wanted_inner_mode
6249169689Skan      && ! pos_rtx
625050397Sobrien      && GET_MODE_SIZE (wanted_inner_mode) < GET_MODE_SIZE (is_mode)
6251169689Skan      && MEM_P (inner)
6252169689Skan      && ! mode_dependent_address_p (XEXP (inner, 0))
6253169689Skan      && ! MEM_VOLATILE_P (inner))
625418334Speter    {
625518334Speter      int offset = 0;
625618334Speter
625718334Speter      /* The computations below will be correct if the machine is big
625818334Speter	 endian in both bits and bytes or little endian in bits and bytes.
625918334Speter	 If it is mixed, we must adjust.  */
626090075Sobrien
626118334Speter      /* If bytes are big endian and we had a paradoxical SUBREG, we must
626250397Sobrien	 adjust OFFSET to compensate.  */
626318334Speter      if (BYTES_BIG_ENDIAN
626418334Speter	  && GET_MODE_SIZE (inner_mode) < GET_MODE_SIZE (is_mode))
626518334Speter	offset -= GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (inner_mode);
626618334Speter
6267169689Skan      /* We can now move to the desired byte.  */
6268169689Skan      offset += (pos / GET_MODE_BITSIZE (wanted_inner_mode))
6269169689Skan		* GET_MODE_SIZE (wanted_inner_mode);
6270169689Skan      pos %= GET_MODE_BITSIZE (wanted_inner_mode);
627118334Speter
627218334Speter      if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN
627350397Sobrien	  && is_mode != wanted_inner_mode)
627418334Speter	offset = (GET_MODE_SIZE (is_mode)
627550397Sobrien		  - GET_MODE_SIZE (wanted_inner_mode) - offset);
627618334Speter
6277169689Skan      inner = adjust_address_nv (inner, wanted_inner_mode, offset);
627818334Speter    }
627918334Speter
628050397Sobrien  /* If INNER is not memory, we can always get it into the proper mode.  If we
628150397Sobrien     are changing its mode, POS must be a constant and smaller than the size
628250397Sobrien     of the new mode.  */
6283169689Skan  else if (!MEM_P (inner))
628450397Sobrien    {
628550397Sobrien      if (GET_MODE (inner) != wanted_inner_mode
628650397Sobrien	  && (pos_rtx != 0
628750397Sobrien	      || orig_pos + len > GET_MODE_BITSIZE (wanted_inner_mode)))
628850397Sobrien	return 0;
628918334Speter
6290169689Skan      if (orig_pos < 0)
6291169689Skan	return 0;
6292169689Skan
629350397Sobrien      inner = force_to_mode (inner, wanted_inner_mode,
629450397Sobrien			     pos_rtx
629550397Sobrien			     || len + orig_pos >= HOST_BITS_PER_WIDE_INT
629690075Sobrien			     ? ~(unsigned HOST_WIDE_INT) 0
629790075Sobrien			     : ((((unsigned HOST_WIDE_INT) 1 << len) - 1)
629890075Sobrien				<< orig_pos),
6299169689Skan			     0);
630050397Sobrien    }
630150397Sobrien
630218334Speter  /* Adjust mode of POS_RTX, if needed.  If we want a wider mode, we
630318334Speter     have to zero extend.  Otherwise, we can just use a SUBREG.  */
630418334Speter  if (pos_rtx != 0
630518334Speter      && GET_MODE_SIZE (pos_mode) > GET_MODE_SIZE (GET_MODE (pos_rtx)))
630690075Sobrien    {
630790075Sobrien      rtx temp = gen_rtx_ZERO_EXTEND (pos_mode, pos_rtx);
630890075Sobrien
630990075Sobrien      /* If we know that no extraneous bits are set, and that the high
631090075Sobrien	 bit is not set, convert extraction to cheaper one - either
631190075Sobrien	 SIGN_EXTENSION or ZERO_EXTENSION, that are equivalent in these
631290075Sobrien	 cases.  */
631390075Sobrien      if (flag_expensive_optimizations
631490075Sobrien	  && (GET_MODE_BITSIZE (GET_MODE (pos_rtx)) <= HOST_BITS_PER_WIDE_INT
631590075Sobrien	      && ((nonzero_bits (pos_rtx, GET_MODE (pos_rtx))
631690075Sobrien		   & ~(((unsigned HOST_WIDE_INT)
631790075Sobrien			GET_MODE_MASK (GET_MODE (pos_rtx)))
631890075Sobrien		       >> 1))
631990075Sobrien		  == 0)))
632090075Sobrien	{
632190075Sobrien	  rtx temp1 = gen_rtx_SIGN_EXTEND (pos_mode, pos_rtx);
632290075Sobrien
632390075Sobrien	  /* Prefer ZERO_EXTENSION, since it gives more information to
632490075Sobrien	     backends.  */
632590075Sobrien	  if (rtx_cost (temp1, SET) < rtx_cost (temp, SET))
632690075Sobrien	    temp = temp1;
632790075Sobrien	}
632890075Sobrien      pos_rtx = temp;
632990075Sobrien    }
633018334Speter  else if (pos_rtx != 0
633118334Speter	   && GET_MODE_SIZE (pos_mode) < GET_MODE_SIZE (GET_MODE (pos_rtx)))
6332169689Skan    pos_rtx = gen_lowpart (pos_mode, pos_rtx);
633318334Speter
633418334Speter  /* Make POS_RTX unless we already have it and it is correct.  If we don't
633518334Speter     have a POS_RTX but we do have an ORIG_POS_RTX, the latter must
633650397Sobrien     be a CONST_INT.  */
633718334Speter  if (pos_rtx == 0 && orig_pos_rtx != 0 && INTVAL (orig_pos_rtx) == pos)
633818334Speter    pos_rtx = orig_pos_rtx;
633918334Speter
634018334Speter  else if (pos_rtx == 0)
634118334Speter    pos_rtx = GEN_INT (pos);
634218334Speter
634318334Speter  /* Make the required operation.  See if we can use existing rtx.  */
634490075Sobrien  new = gen_rtx_fmt_eee (unsignedp ? ZERO_EXTRACT : SIGN_EXTRACT,
634518334Speter			 extraction_mode, inner, GEN_INT (len), pos_rtx);
634618334Speter  if (! in_dest)
6347169689Skan    new = gen_lowpart (mode, new);
634818334Speter
634918334Speter  return new;
635018334Speter}
635118334Speter
635218334Speter/* See if X contains an ASHIFT of COUNT or more bits that can be commuted
635318334Speter   with any other operations in X.  Return X without that shift if so.  */
635418334Speter
635518334Speterstatic rtx
6356132718Skanextract_left_shift (rtx x, int count)
635718334Speter{
635818334Speter  enum rtx_code code = GET_CODE (x);
635918334Speter  enum machine_mode mode = GET_MODE (x);
636018334Speter  rtx tem;
636118334Speter
636218334Speter  switch (code)
636318334Speter    {
636418334Speter    case ASHIFT:
636518334Speter      /* This is the shift itself.  If it is wide enough, we will return
636618334Speter	 either the value being shifted if the shift count is equal to
636718334Speter	 COUNT or a shift for the difference.  */
636818334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
636918334Speter	  && INTVAL (XEXP (x, 1)) >= count)
637018334Speter	return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (x, 0),
637118334Speter				     INTVAL (XEXP (x, 1)) - count);
637218334Speter      break;
637318334Speter
637418334Speter    case NEG:  case NOT:
637518334Speter      if ((tem = extract_left_shift (XEXP (x, 0), count)) != 0)
637690075Sobrien	return simplify_gen_unary (code, mode, tem, mode);
637718334Speter
637818334Speter      break;
637918334Speter
638018334Speter    case PLUS:  case IOR:  case XOR:  case AND:
638118334Speter      /* If we can safely shift this constant and we find the inner shift,
638218334Speter	 make a new operation.  */
6383132718Skan      if (GET_CODE (XEXP (x, 1)) == CONST_INT
638450397Sobrien	  && (INTVAL (XEXP (x, 1)) & ((((HOST_WIDE_INT) 1 << count)) - 1)) == 0
638518334Speter	  && (tem = extract_left_shift (XEXP (x, 0), count)) != 0)
6386169689Skan	return simplify_gen_binary (code, mode, tem,
6387169689Skan				    GEN_INT (INTVAL (XEXP (x, 1)) >> count));
638818334Speter
638918334Speter      break;
639090075Sobrien
639150397Sobrien    default:
639250397Sobrien      break;
639318334Speter    }
639418334Speter
639518334Speter  return 0;
639618334Speter}
639718334Speter
639818334Speter/* Look at the expression rooted at X.  Look for expressions
639918334Speter   equivalent to ZERO_EXTRACT, SIGN_EXTRACT, ZERO_EXTEND, SIGN_EXTEND.
640018334Speter   Form these expressions.
640118334Speter
640218334Speter   Return the new rtx, usually just X.
640318334Speter
640490075Sobrien   Also, for machines like the VAX that don't have logical shift insns,
640518334Speter   try to convert logical to arithmetic shift operations in cases where
640618334Speter   they are equivalent.  This undoes the canonicalizations to logical
640718334Speter   shifts done elsewhere.
640818334Speter
640918334Speter   We try, as much as possible, to re-use rtl expressions to save memory.
641018334Speter
641118334Speter   IN_CODE says what kind of expression we are processing.  Normally, it is
641218334Speter   SET.  In a memory address (inside a MEM, PLUS or minus, the latter two
641318334Speter   being kludges), it is MEM.  When processing the arguments of a comparison
641418334Speter   or a COMPARE against zero, it is COMPARE.  */
641518334Speter
641618334Speterstatic rtx
6417132718Skanmake_compound_operation (rtx x, enum rtx_code in_code)
641818334Speter{
641918334Speter  enum rtx_code code = GET_CODE (x);
642018334Speter  enum machine_mode mode = GET_MODE (x);
642118334Speter  int mode_width = GET_MODE_BITSIZE (mode);
642218334Speter  rtx rhs, lhs;
642318334Speter  enum rtx_code next_code;
642418334Speter  int i;
642518334Speter  rtx new = 0;
642618334Speter  rtx tem;
642790075Sobrien  const char *fmt;
642818334Speter
642918334Speter  /* Select the code to be used in recursive calls.  Once we are inside an
643018334Speter     address, we stay there.  If we have a comparison, set to COMPARE,
643118334Speter     but once inside, go back to our default of SET.  */
643218334Speter
643318334Speter  next_code = (code == MEM || code == PLUS || code == MINUS ? MEM
6434169689Skan	       : ((code == COMPARE || COMPARISON_P (x))
643518334Speter		  && XEXP (x, 1) == const0_rtx) ? COMPARE
643618334Speter	       : in_code == COMPARE ? SET : in_code);
643718334Speter
643818334Speter  /* Process depending on the code of this operation.  If NEW is set
6439117395Skan     nonzero, it will be returned.  */
644018334Speter
644118334Speter  switch (code)
644218334Speter    {
644318334Speter    case ASHIFT:
644418334Speter      /* Convert shifts by constants into multiplications if inside
644518334Speter	 an address.  */
644618334Speter      if (in_code == MEM && GET_CODE (XEXP (x, 1)) == CONST_INT
644718334Speter	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
644818334Speter	  && INTVAL (XEXP (x, 1)) >= 0)
644918334Speter	{
645018334Speter	  new = make_compound_operation (XEXP (x, 0), next_code);
645190075Sobrien	  new = gen_rtx_MULT (mode, new,
645290075Sobrien			      GEN_INT ((HOST_WIDE_INT) 1
645390075Sobrien				       << INTVAL (XEXP (x, 1))));
645418334Speter	}
645518334Speter      break;
645618334Speter
645718334Speter    case AND:
645818334Speter      /* If the second operand is not a constant, we can't do anything
645918334Speter	 with it.  */
646018334Speter      if (GET_CODE (XEXP (x, 1)) != CONST_INT)
646118334Speter	break;
646218334Speter
646318334Speter      /* If the constant is a power of two minus one and the first operand
646418334Speter	 is a logical right shift, make an extraction.  */
646518334Speter      if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
646618334Speter	  && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
646718334Speter	{
646818334Speter	  new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
646918334Speter	  new = make_extraction (mode, new, 0, XEXP (XEXP (x, 0), 1), i, 1,
647018334Speter				 0, in_code == COMPARE);
647118334Speter	}
647218334Speter
647318334Speter      /* Same as previous, but for (subreg (lshiftrt ...)) in first op.  */
647418334Speter      else if (GET_CODE (XEXP (x, 0)) == SUBREG
647518334Speter	       && subreg_lowpart_p (XEXP (x, 0))
647618334Speter	       && GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT
647718334Speter	       && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
647818334Speter	{
647918334Speter	  new = make_compound_operation (XEXP (SUBREG_REG (XEXP (x, 0)), 0),
648018334Speter					 next_code);
648118334Speter	  new = make_extraction (GET_MODE (SUBREG_REG (XEXP (x, 0))), new, 0,
648218334Speter				 XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1,
648318334Speter				 0, in_code == COMPARE);
648418334Speter	}
648518334Speter      /* Same as previous, but for (xor/ior (lshiftrt...) (lshiftrt...)).  */
648618334Speter      else if ((GET_CODE (XEXP (x, 0)) == XOR
648718334Speter		|| GET_CODE (XEXP (x, 0)) == IOR)
648818334Speter	       && GET_CODE (XEXP (XEXP (x, 0), 0)) == LSHIFTRT
648918334Speter	       && GET_CODE (XEXP (XEXP (x, 0), 1)) == LSHIFTRT
649018334Speter	       && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
649118334Speter	{
649218334Speter	  /* Apply the distributive law, and then try to make extractions.  */
649390075Sobrien	  new = gen_rtx_fmt_ee (GET_CODE (XEXP (x, 0)), mode,
649490075Sobrien				gen_rtx_AND (mode, XEXP (XEXP (x, 0), 0),
649590075Sobrien					     XEXP (x, 1)),
649690075Sobrien				gen_rtx_AND (mode, XEXP (XEXP (x, 0), 1),
649790075Sobrien					     XEXP (x, 1)));
649818334Speter	  new = make_compound_operation (new, in_code);
649918334Speter	}
650018334Speter
650118334Speter      /* If we are have (and (rotate X C) M) and C is larger than the number
650218334Speter	 of bits in M, this is an extraction.  */
650318334Speter
650418334Speter      else if (GET_CODE (XEXP (x, 0)) == ROTATE
650518334Speter	       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
650618334Speter	       && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0
650718334Speter	       && i <= INTVAL (XEXP (XEXP (x, 0), 1)))
650818334Speter	{
650918334Speter	  new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
651018334Speter	  new = make_extraction (mode, new,
651118334Speter				 (GET_MODE_BITSIZE (mode)
651218334Speter				  - INTVAL (XEXP (XEXP (x, 0), 1))),
651318334Speter				 NULL_RTX, i, 1, 0, in_code == COMPARE);
651418334Speter	}
651518334Speter
651618334Speter      /* On machines without logical shifts, if the operand of the AND is
651718334Speter	 a logical shift and our mask turns off all the propagated sign
651818334Speter	 bits, we can replace the logical shift with an arithmetic shift.  */
651990075Sobrien      else if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
652090075Sobrien	       && !have_insn_for (LSHIFTRT, mode)
652190075Sobrien	       && have_insn_for (ASHIFTRT, mode)
652218334Speter	       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
652318334Speter	       && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
652418334Speter	       && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT
652518334Speter	       && mode_width <= HOST_BITS_PER_WIDE_INT)
652618334Speter	{
652718334Speter	  unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
652818334Speter
652918334Speter	  mask >>= INTVAL (XEXP (XEXP (x, 0), 1));
653018334Speter	  if ((INTVAL (XEXP (x, 1)) & ~mask) == 0)
653118334Speter	    SUBST (XEXP (x, 0),
653290075Sobrien		   gen_rtx_ASHIFTRT (mode,
653390075Sobrien				     make_compound_operation
653490075Sobrien				     (XEXP (XEXP (x, 0), 0), next_code),
653590075Sobrien				     XEXP (XEXP (x, 0), 1)));
653618334Speter	}
653718334Speter
653818334Speter      /* If the constant is one less than a power of two, this might be
653918334Speter	 representable by an extraction even if no shift is present.
654018334Speter	 If it doesn't end up being a ZERO_EXTEND, we will ignore it unless
654118334Speter	 we are in a COMPARE.  */
654218334Speter      else if ((i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
654318334Speter	new = make_extraction (mode,
654418334Speter			       make_compound_operation (XEXP (x, 0),
654518334Speter							next_code),
654618334Speter			       0, NULL_RTX, i, 1, 0, in_code == COMPARE);
654718334Speter
654818334Speter      /* If we are in a comparison and this is an AND with a power of two,
654918334Speter	 convert this into the appropriate bit extract.  */
655018334Speter      else if (in_code == COMPARE
655118334Speter	       && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0)
655218334Speter	new = make_extraction (mode,
655318334Speter			       make_compound_operation (XEXP (x, 0),
655418334Speter							next_code),
655518334Speter			       i, NULL_RTX, 1, 1, 0, 1);
655618334Speter
655718334Speter      break;
655818334Speter
655918334Speter    case LSHIFTRT:
656018334Speter      /* If the sign bit is known to be zero, replace this with an
656118334Speter	 arithmetic shift.  */
656290075Sobrien      if (have_insn_for (ASHIFTRT, mode)
656390075Sobrien	  && ! have_insn_for (LSHIFTRT, mode)
656418334Speter	  && mode_width <= HOST_BITS_PER_WIDE_INT
656518334Speter	  && (nonzero_bits (XEXP (x, 0), mode) & (1 << (mode_width - 1))) == 0)
656618334Speter	{
656790075Sobrien	  new = gen_rtx_ASHIFTRT (mode,
656890075Sobrien				  make_compound_operation (XEXP (x, 0),
656990075Sobrien							   next_code),
657090075Sobrien				  XEXP (x, 1));
657118334Speter	  break;
657218334Speter	}
657318334Speter
657450397Sobrien      /* ... fall through ...  */
657518334Speter
657618334Speter    case ASHIFTRT:
657718334Speter      lhs = XEXP (x, 0);
657818334Speter      rhs = XEXP (x, 1);
657918334Speter
658018334Speter      /* If we have (ashiftrt (ashift foo C1) C2) with C2 >= C1,
658118334Speter	 this is a SIGN_EXTRACT.  */
658218334Speter      if (GET_CODE (rhs) == CONST_INT
658318334Speter	  && GET_CODE (lhs) == ASHIFT
658418334Speter	  && GET_CODE (XEXP (lhs, 1)) == CONST_INT
658518334Speter	  && INTVAL (rhs) >= INTVAL (XEXP (lhs, 1)))
658618334Speter	{
658718334Speter	  new = make_compound_operation (XEXP (lhs, 0), next_code);
658818334Speter	  new = make_extraction (mode, new,
658918334Speter				 INTVAL (rhs) - INTVAL (XEXP (lhs, 1)),
659018334Speter				 NULL_RTX, mode_width - INTVAL (rhs),
659118334Speter				 code == LSHIFTRT, 0, in_code == COMPARE);
659290075Sobrien	  break;
659318334Speter	}
659418334Speter
659518334Speter      /* See if we have operations between an ASHIFTRT and an ASHIFT.
659618334Speter	 If so, try to merge the shifts into a SIGN_EXTEND.  We could
659718334Speter	 also do this for some cases of SIGN_EXTRACT, but it doesn't
659818334Speter	 seem worth the effort; the case checked for occurs on Alpha.  */
659990075Sobrien
6600169689Skan      if (!OBJECT_P (lhs)
660118334Speter	  && ! (GET_CODE (lhs) == SUBREG
6602169689Skan		&& (OBJECT_P (SUBREG_REG (lhs))))
660318334Speter	  && GET_CODE (rhs) == CONST_INT
660418334Speter	  && INTVAL (rhs) < HOST_BITS_PER_WIDE_INT
660518334Speter	  && (new = extract_left_shift (lhs, INTVAL (rhs))) != 0)
660618334Speter	new = make_extraction (mode, make_compound_operation (new, next_code),
660718334Speter			       0, NULL_RTX, mode_width - INTVAL (rhs),
660818334Speter			       code == LSHIFTRT, 0, in_code == COMPARE);
660990075Sobrien
661018334Speter      break;
661118334Speter
661218334Speter    case SUBREG:
661318334Speter      /* Call ourselves recursively on the inner expression.  If we are
661418334Speter	 narrowing the object and it has a different RTL code from
661518334Speter	 what it originally did, do this SUBREG as a force_to_mode.  */
661618334Speter
661718334Speter      tem = make_compound_operation (SUBREG_REG (x), in_code);
661818334Speter
6619169689Skan      {
6620169689Skan	rtx simplified;
6621169689Skan	simplified = simplify_subreg (GET_MODE (x), tem, GET_MODE (tem),
6622169689Skan				      SUBREG_BYTE (x));
662318334Speter
6624169689Skan	if (simplified)
6625169689Skan	  tem = simplified;
662650397Sobrien
6627169689Skan	if (GET_CODE (tem) != GET_CODE (SUBREG_REG (x))
6628169689Skan	    && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (tem))
6629169689Skan	    && subreg_lowpart_p (x))
6630169689Skan	  {
6631169689Skan	    rtx newer = force_to_mode (tem, mode, ~(HOST_WIDE_INT) 0,
6632169689Skan				       0);
6633169689Skan
6634169689Skan	    /* If we have something other than a SUBREG, we might have
6635169689Skan	       done an expansion, so rerun ourselves.  */
6636169689Skan	    if (GET_CODE (newer) != SUBREG)
6637169689Skan	      newer = make_compound_operation (newer, in_code);
6638169689Skan
6639169689Skan	    return newer;
6640169689Skan	  }
6641169689Skan
6642169689Skan	if (simplified)
664350397Sobrien	  return tem;
6644169689Skan      }
664550397Sobrien      break;
664690075Sobrien
664750397Sobrien    default:
664850397Sobrien      break;
664918334Speter    }
665018334Speter
665118334Speter  if (new)
665218334Speter    {
6653169689Skan      x = gen_lowpart (mode, new);
665418334Speter      code = GET_CODE (x);
665518334Speter    }
665618334Speter
665718334Speter  /* Now recursively process each operand of this operation.  */
665818334Speter  fmt = GET_RTX_FORMAT (code);
665918334Speter  for (i = 0; i < GET_RTX_LENGTH (code); i++)
666018334Speter    if (fmt[i] == 'e')
666118334Speter      {
666218334Speter	new = make_compound_operation (XEXP (x, i), next_code);
666318334Speter	SUBST (XEXP (x, i), new);
666418334Speter      }
666518334Speter
6666169689Skan  /* If this is a commutative operation, the changes to the operands
6667169689Skan     may have made it noncanonical.  */
6668169689Skan  if (COMMUTATIVE_ARITH_P (x)
6669169689Skan      && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
6670169689Skan    {
6671169689Skan      tem = XEXP (x, 0);
6672169689Skan      SUBST (XEXP (x, 0), XEXP (x, 1));
6673169689Skan      SUBST (XEXP (x, 1), tem);
6674169689Skan    }
6675169689Skan
667618334Speter  return x;
667718334Speter}
667818334Speter
667918334Speter/* Given M see if it is a value that would select a field of bits
668090075Sobrien   within an item, but not the entire word.  Return -1 if not.
668190075Sobrien   Otherwise, return the starting position of the field, where 0 is the
668290075Sobrien   low-order bit.
668318334Speter
668418334Speter   *PLEN is set to the length of the field.  */
668518334Speter
668618334Speterstatic int
6687132718Skanget_pos_from_mask (unsigned HOST_WIDE_INT m, unsigned HOST_WIDE_INT *plen)
668818334Speter{
668918334Speter  /* Get the bit number of the first 1 bit from the right, -1 if none.  */
669090075Sobrien  int pos = exact_log2 (m & -m);
6691169689Skan  int len = 0;
669218334Speter
6693169689Skan  if (pos >= 0)
6694169689Skan    /* Now shift off the low-order zero bits and see if we have a
6695169689Skan       power of two minus 1.  */
6696169689Skan    len = exact_log2 ((m >> pos) + 1);
669718334Speter
669890075Sobrien  if (len <= 0)
6699169689Skan    pos = -1;
670018334Speter
670190075Sobrien  *plen = len;
670218334Speter  return pos;
670318334Speter}
670418334Speter
6705169689Skan/* If X refers to a register that equals REG in value, replace these
6706169689Skan   references with REG.  */
6707169689Skanstatic rtx
6708169689Skancanon_reg_for_combine (rtx x, rtx reg)
6709169689Skan{
6710169689Skan  rtx op0, op1, op2;
6711169689Skan  const char *fmt;
6712169689Skan  int i;
6713169689Skan  bool copied;
6714169689Skan
6715169689Skan  enum rtx_code code = GET_CODE (x);
6716169689Skan  switch (GET_RTX_CLASS (code))
6717169689Skan    {
6718169689Skan    case RTX_UNARY:
6719169689Skan      op0 = canon_reg_for_combine (XEXP (x, 0), reg);
6720169689Skan      if (op0 != XEXP (x, 0))
6721169689Skan	return simplify_gen_unary (GET_CODE (x), GET_MODE (x), op0,
6722169689Skan				   GET_MODE (reg));
6723169689Skan      break;
6724169689Skan
6725169689Skan    case RTX_BIN_ARITH:
6726169689Skan    case RTX_COMM_ARITH:
6727169689Skan      op0 = canon_reg_for_combine (XEXP (x, 0), reg);
6728169689Skan      op1 = canon_reg_for_combine (XEXP (x, 1), reg);
6729169689Skan      if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
6730169689Skan	return simplify_gen_binary (GET_CODE (x), GET_MODE (x), op0, op1);
6731169689Skan      break;
6732169689Skan
6733169689Skan    case RTX_COMPARE:
6734169689Skan    case RTX_COMM_COMPARE:
6735169689Skan      op0 = canon_reg_for_combine (XEXP (x, 0), reg);
6736169689Skan      op1 = canon_reg_for_combine (XEXP (x, 1), reg);
6737169689Skan      if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
6738169689Skan	return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
6739169689Skan					GET_MODE (op0), op0, op1);
6740169689Skan      break;
6741169689Skan
6742169689Skan    case RTX_TERNARY:
6743169689Skan    case RTX_BITFIELD_OPS:
6744169689Skan      op0 = canon_reg_for_combine (XEXP (x, 0), reg);
6745169689Skan      op1 = canon_reg_for_combine (XEXP (x, 1), reg);
6746169689Skan      op2 = canon_reg_for_combine (XEXP (x, 2), reg);
6747169689Skan      if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1) || op2 != XEXP (x, 2))
6748169689Skan	return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
6749169689Skan				     GET_MODE (op0), op0, op1, op2);
6750169689Skan
6751169689Skan    case RTX_OBJ:
6752169689Skan      if (REG_P (x))
6753169689Skan	{
6754169689Skan	  if (rtx_equal_p (get_last_value (reg), x)
6755169689Skan	      || rtx_equal_p (reg, get_last_value (x)))
6756169689Skan	    return reg;
6757169689Skan	  else
6758169689Skan	    break;
6759169689Skan	}
6760169689Skan
6761169689Skan      /* fall through */
6762169689Skan
6763169689Skan    default:
6764169689Skan      fmt = GET_RTX_FORMAT (code);
6765169689Skan      copied = false;
6766169689Skan      for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
6767169689Skan	if (fmt[i] == 'e')
6768169689Skan	  {
6769169689Skan	    rtx op = canon_reg_for_combine (XEXP (x, i), reg);
6770169689Skan	    if (op != XEXP (x, i))
6771169689Skan	      {
6772169689Skan		if (!copied)
6773169689Skan		  {
6774169689Skan		    copied = true;
6775169689Skan		    x = copy_rtx (x);
6776169689Skan		  }
6777169689Skan		XEXP (x, i) = op;
6778169689Skan	      }
6779169689Skan	  }
6780169689Skan	else if (fmt[i] == 'E')
6781169689Skan	  {
6782169689Skan	    int j;
6783169689Skan	    for (j = 0; j < XVECLEN (x, i); j++)
6784169689Skan	      {
6785169689Skan		rtx op = canon_reg_for_combine (XVECEXP (x, i, j), reg);
6786169689Skan		if (op != XVECEXP (x, i, j))
6787169689Skan		  {
6788169689Skan		    if (!copied)
6789169689Skan		      {
6790169689Skan			copied = true;
6791169689Skan			x = copy_rtx (x);
6792169689Skan		      }
6793169689Skan		    XVECEXP (x, i, j) = op;
6794169689Skan		  }
6795169689Skan	      }
6796169689Skan	  }
6797169689Skan
6798169689Skan      break;
6799169689Skan    }
6800169689Skan
6801169689Skan  return x;
6802169689Skan}
6803169689Skan
6804169689Skan/* Return X converted to MODE.  If the value is already truncated to
6805169689Skan   MODE we can just return a subreg even though in the general case we
6806169689Skan   would need an explicit truncation.  */
6807169689Skan
6808169689Skanstatic rtx
6809169689Skangen_lowpart_or_truncate (enum machine_mode mode, rtx x)
6810169689Skan{
6811169689Skan  if (GET_MODE_SIZE (GET_MODE (x)) <= GET_MODE_SIZE (mode)
6812169689Skan      || TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
6813169689Skan				GET_MODE_BITSIZE (GET_MODE (x)))
6814169689Skan      || (REG_P (x) && reg_truncated_to_mode (mode, x)))
6815169689Skan    return gen_lowpart (mode, x);
6816169689Skan  else
6817169689Skan    return simplify_gen_unary (TRUNCATE, mode, x, GET_MODE (x));
6818169689Skan}
6819169689Skan
682018334Speter/* See if X can be simplified knowing that we will only refer to it in
682118334Speter   MODE and will only refer to those bits that are nonzero in MASK.
682218334Speter   If other bits are being computed or if masking operations are done
682318334Speter   that select a superset of the bits in MASK, they can sometimes be
682418334Speter   ignored.
682518334Speter
682618334Speter   Return a possibly simplified expression, but always convert X to
682718334Speter   MODE.  If X is a CONST_INT, AND the CONST_INT with MASK.
682818334Speter
682918334Speter   If JUST_SELECT is nonzero, don't optimize by noticing that bits in MASK
683018334Speter   are all off in X.  This is used when X will be complemented, by either
683118334Speter   NOT, NEG, or XOR.  */
683218334Speter
683318334Speterstatic rtx
6834132718Skanforce_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
6835169689Skan	       int just_select)
683618334Speter{
683718334Speter  enum rtx_code code = GET_CODE (x);
683818334Speter  int next_select = just_select || code == XOR || code == NOT || code == NEG;
683918334Speter  enum machine_mode op_mode;
684018334Speter  unsigned HOST_WIDE_INT fuller_mask, nonzero;
684118334Speter  rtx op0, op1, temp;
684218334Speter
684350397Sobrien  /* If this is a CALL or ASM_OPERANDS, don't do anything.  Some of the
684450397Sobrien     code below will do the wrong thing since the mode of such an
684590075Sobrien     expression is VOIDmode.
684650397Sobrien
684750397Sobrien     Also do nothing if X is a CLOBBER; this can happen if X was
6848169689Skan     the return value from a call to gen_lowpart.  */
684950397Sobrien  if (code == CALL || code == ASM_OPERANDS || code == CLOBBER)
685018334Speter    return x;
685118334Speter
685218334Speter  /* We want to perform the operation is its present mode unless we know
685318334Speter     that the operation is valid in MODE, in which case we do the operation
685418334Speter     in MODE.  */
685518334Speter  op_mode = ((GET_MODE_CLASS (mode) == GET_MODE_CLASS (GET_MODE (x))
685690075Sobrien	      && have_insn_for (code, mode))
685718334Speter	     ? mode : GET_MODE (x));
685818334Speter
685918334Speter  /* It is not valid to do a right-shift in a narrower mode
686018334Speter     than the one it came in with.  */
686118334Speter  if ((code == LSHIFTRT || code == ASHIFTRT)
686218334Speter      && GET_MODE_BITSIZE (mode) < GET_MODE_BITSIZE (GET_MODE (x)))
686318334Speter    op_mode = GET_MODE (x);
686418334Speter
686518334Speter  /* Truncate MASK to fit OP_MODE.  */
686618334Speter  if (op_mode)
686718334Speter    mask &= GET_MODE_MASK (op_mode);
686818334Speter
686918334Speter  /* When we have an arithmetic operation, or a shift whose count we
6870132718Skan     do not know, we need to assume that all bits up to the highest-order
687118334Speter     bit in MASK will be needed.  This is how we form such a mask.  */
6872132718Skan  if (mask & ((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)))
6873132718Skan    fuller_mask = ~(unsigned HOST_WIDE_INT) 0;
687418334Speter  else
6875132718Skan    fuller_mask = (((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1))
6876132718Skan		   - 1);
687718334Speter
687818334Speter  /* Determine what bits of X are guaranteed to be (non)zero.  */
687918334Speter  nonzero = nonzero_bits (x, mode);
688018334Speter
688118334Speter  /* If none of the bits in X are needed, return a zero.  */
6882169689Skan  if (!just_select && (nonzero & mask) == 0 && !side_effects_p (x))
6883117395Skan    x = const0_rtx;
688418334Speter
688518334Speter  /* If X is a CONST_INT, return a new one.  Do this here since the
688618334Speter     test below will fail.  */
688718334Speter  if (GET_CODE (x) == CONST_INT)
6888117395Skan    {
6889117395Skan      if (SCALAR_INT_MODE_P (mode))
6890169689Skan	return gen_int_mode (INTVAL (x) & mask, mode);
6891117395Skan      else
6892117395Skan	{
6893117395Skan	  x = GEN_INT (INTVAL (x) & mask);
6894117395Skan	  return gen_lowpart_common (mode, x);
6895117395Skan	}
6896117395Skan    }
689718334Speter
689818334Speter  /* If X is narrower than MODE and we want all the bits in X's mode, just
689918334Speter     get X in the proper mode.  */
690018334Speter  if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode)
690190075Sobrien      && (GET_MODE_MASK (GET_MODE (x)) & ~mask) == 0)
6902169689Skan    return gen_lowpart (mode, x);
690318334Speter
690418334Speter  switch (code)
690518334Speter    {
690618334Speter    case CLOBBER:
690718334Speter      /* If X is a (clobber (const_int)), return it since we know we are
690850397Sobrien	 generating something that won't match.  */
690918334Speter      return x;
691018334Speter
691118334Speter    case SIGN_EXTEND:
691218334Speter    case ZERO_EXTEND:
691318334Speter    case ZERO_EXTRACT:
691418334Speter    case SIGN_EXTRACT:
691518334Speter      x = expand_compound_operation (x);
691618334Speter      if (GET_CODE (x) != code)
6917169689Skan	return force_to_mode (x, mode, mask, next_select);
691818334Speter      break;
691918334Speter
692018334Speter    case SUBREG:
692118334Speter      if (subreg_lowpart_p (x)
692218334Speter	  /* We can ignore the effect of this SUBREG if it narrows the mode or
692318334Speter	     if the constant masks to zero all the bits the mode doesn't
692418334Speter	     have.  */
692518334Speter	  && ((GET_MODE_SIZE (GET_MODE (x))
692618334Speter	       < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
692718334Speter	      || (0 == (mask
692818334Speter			& GET_MODE_MASK (GET_MODE (x))
692990075Sobrien			& ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))))))
6930169689Skan	return force_to_mode (SUBREG_REG (x), mode, mask, next_select);
693118334Speter      break;
693218334Speter
693318334Speter    case AND:
693418334Speter      /* If this is an AND with a constant, convert it into an AND
693518334Speter	 whose constant is the AND of that constant with MASK.  If it
693618334Speter	 remains an AND of MASK, delete it since it is redundant.  */
693718334Speter
693818334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
693918334Speter	{
694018334Speter	  x = simplify_and_const_int (x, op_mode, XEXP (x, 0),
694118334Speter				      mask & INTVAL (XEXP (x, 1)));
694218334Speter
694318334Speter	  /* If X is still an AND, see if it is an AND with a mask that
694418334Speter	     is just some low-order bits.  If so, and it is MASK, we don't
694518334Speter	     need it.  */
694618334Speter
694718334Speter	  if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT
694890075Sobrien	      && ((INTVAL (XEXP (x, 1)) & GET_MODE_MASK (GET_MODE (x)))
6949117395Skan		  == mask))
695018334Speter	    x = XEXP (x, 0);
695118334Speter
695218334Speter	  /* If it remains an AND, try making another AND with the bits
695318334Speter	     in the mode mask that aren't in MASK turned on.  If the
695418334Speter	     constant in the AND is wide enough, this might make a
695518334Speter	     cheaper constant.  */
695618334Speter
695718334Speter	  if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT
695818334Speter	      && GET_MODE_MASK (GET_MODE (x)) != mask
695918334Speter	      && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
696018334Speter	    {
696118334Speter	      HOST_WIDE_INT cval = (INTVAL (XEXP (x, 1))
696290075Sobrien				    | (GET_MODE_MASK (GET_MODE (x)) & ~mask));
696318334Speter	      int width = GET_MODE_BITSIZE (GET_MODE (x));
696418334Speter	      rtx y;
696518334Speter
6966169689Skan	      /* If MODE is narrower than HOST_WIDE_INT and CVAL is a negative
696718334Speter		 number, sign extend it.  */
696818334Speter	      if (width > 0 && width < HOST_BITS_PER_WIDE_INT
696918334Speter		  && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
697018334Speter		cval |= (HOST_WIDE_INT) -1 << width;
697118334Speter
6972169689Skan	      y = simplify_gen_binary (AND, GET_MODE (x),
6973169689Skan				       XEXP (x, 0), GEN_INT (cval));
697418334Speter	      if (rtx_cost (y, SET) < rtx_cost (x, SET))
697518334Speter		x = y;
697618334Speter	    }
697718334Speter
697818334Speter	  break;
697918334Speter	}
698018334Speter
698118334Speter      goto binop;
698218334Speter
698318334Speter    case PLUS:
698418334Speter      /* In (and (plus FOO C1) M), if M is a mask that just turns off
698518334Speter	 low-order bits (as in an alignment operation) and FOO is already
698618334Speter	 aligned to that boundary, mask C1 to that boundary as well.
698718334Speter	 This may eliminate that PLUS and, later, the AND.  */
698818334Speter
698918334Speter      {
699090075Sobrien	unsigned int width = GET_MODE_BITSIZE (mode);
699118334Speter	unsigned HOST_WIDE_INT smask = mask;
699218334Speter
699318334Speter	/* If MODE is narrower than HOST_WIDE_INT and mask is a negative
699418334Speter	   number, sign extend it.  */
699518334Speter
699618334Speter	if (width < HOST_BITS_PER_WIDE_INT
699718334Speter	    && (smask & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
699818334Speter	  smask |= (HOST_WIDE_INT) -1 << width;
699918334Speter
700018334Speter	if (GET_CODE (XEXP (x, 1)) == CONST_INT
700196263Sobrien	    && exact_log2 (- smask) >= 0
700296263Sobrien	    && (nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0
700396263Sobrien	    && (INTVAL (XEXP (x, 1)) & ~smask) != 0)
700496263Sobrien	  return force_to_mode (plus_constant (XEXP (x, 0),
700596263Sobrien					       (INTVAL (XEXP (x, 1)) & smask)),
7006169689Skan				mode, smask, next_select);
700718334Speter      }
700818334Speter
700950397Sobrien      /* ... fall through ...  */
701018334Speter
701118334Speter    case MULT:
701218334Speter      /* For PLUS, MINUS and MULT, we need any bits less significant than the
701318334Speter	 most significant bit in MASK since carries from those bits will
701418334Speter	 affect the bits we are interested in.  */
701518334Speter      mask = fuller_mask;
701618334Speter      goto binop;
701718334Speter
701890075Sobrien    case MINUS:
701990075Sobrien      /* If X is (minus C Y) where C's least set bit is larger than any bit
702090075Sobrien	 in the mask, then we may replace with (neg Y).  */
702190075Sobrien      if (GET_CODE (XEXP (x, 0)) == CONST_INT
702290075Sobrien	  && (((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 0))
702390075Sobrien					& -INTVAL (XEXP (x, 0))))
702490075Sobrien	      > mask))
702590075Sobrien	{
702690075Sobrien	  x = simplify_gen_unary (NEG, GET_MODE (x), XEXP (x, 1),
702790075Sobrien				  GET_MODE (x));
7028169689Skan	  return force_to_mode (x, mode, mask, next_select);
702990075Sobrien	}
703090075Sobrien
7031110611Skan      /* Similarly, if C contains every bit in the fuller_mask, then we may
703290075Sobrien	 replace with (not Y).  */
703390075Sobrien      if (GET_CODE (XEXP (x, 0)) == CONST_INT
7034110611Skan	  && ((INTVAL (XEXP (x, 0)) | (HOST_WIDE_INT) fuller_mask)
703590075Sobrien	      == INTVAL (XEXP (x, 0))))
703690075Sobrien	{
703790075Sobrien	  x = simplify_gen_unary (NOT, GET_MODE (x),
703890075Sobrien				  XEXP (x, 1), GET_MODE (x));
7039169689Skan	  return force_to_mode (x, mode, mask, next_select);
704090075Sobrien	}
704190075Sobrien
704290075Sobrien      mask = fuller_mask;
704390075Sobrien      goto binop;
704490075Sobrien
704518334Speter    case IOR:
704618334Speter    case XOR:
704718334Speter      /* If X is (ior (lshiftrt FOO C1) C2), try to commute the IOR and
704818334Speter	 LSHIFTRT so we end up with an (and (lshiftrt (ior ...) ...) ...)
704918334Speter	 operation which may be a bitfield extraction.  Ensure that the
705018334Speter	 constant we form is not wider than the mode of X.  */
705118334Speter
705218334Speter      if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
705318334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
705418334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
705518334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT
705618334Speter	  && GET_CODE (XEXP (x, 1)) == CONST_INT
705718334Speter	  && ((INTVAL (XEXP (XEXP (x, 0), 1))
705818334Speter	       + floor_log2 (INTVAL (XEXP (x, 1))))
705918334Speter	      < GET_MODE_BITSIZE (GET_MODE (x)))
706018334Speter	  && (INTVAL (XEXP (x, 1))
706190075Sobrien	      & ~nonzero_bits (XEXP (x, 0), GET_MODE (x))) == 0)
706218334Speter	{
706318334Speter	  temp = GEN_INT ((INTVAL (XEXP (x, 1)) & mask)
706490075Sobrien			  << INTVAL (XEXP (XEXP (x, 0), 1)));
7065169689Skan	  temp = simplify_gen_binary (GET_CODE (x), GET_MODE (x),
7066169689Skan				      XEXP (XEXP (x, 0), 0), temp);
7067169689Skan	  x = simplify_gen_binary (LSHIFTRT, GET_MODE (x), temp,
7068169689Skan				   XEXP (XEXP (x, 0), 1));
7069169689Skan	  return force_to_mode (x, mode, mask, next_select);
707018334Speter	}
707118334Speter
707218334Speter    binop:
707318334Speter      /* For most binary operations, just propagate into the operation and
707490075Sobrien	 change the mode if we have an operation of that mode.  */
707518334Speter
7076169689Skan      op0 = gen_lowpart_or_truncate (op_mode,
707718334Speter				     force_to_mode (XEXP (x, 0), mode, mask,
7078169689Skan						    next_select));
7079169689Skan      op1 = gen_lowpart_or_truncate (op_mode,
708018334Speter				     force_to_mode (XEXP (x, 1), mode, mask,
7081169689Skan					next_select));
708218334Speter
708318334Speter      if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
7084169689Skan	x = simplify_gen_binary (code, op_mode, op0, op1);
708518334Speter      break;
708618334Speter
708718334Speter    case ASHIFT:
708818334Speter      /* For left shifts, do the same, but just for the first operand.
708918334Speter	 However, we cannot do anything with shifts where we cannot
709018334Speter	 guarantee that the counts are smaller than the size of the mode
709118334Speter	 because such a count will have a different meaning in a
709218334Speter	 wider mode.  */
709318334Speter
709418334Speter      if (! (GET_CODE (XEXP (x, 1)) == CONST_INT
709518334Speter	     && INTVAL (XEXP (x, 1)) >= 0
709618334Speter	     && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (mode))
709718334Speter	  && ! (GET_MODE (XEXP (x, 1)) != VOIDmode
709818334Speter		&& (nonzero_bits (XEXP (x, 1), GET_MODE (XEXP (x, 1)))
709918334Speter		    < (unsigned HOST_WIDE_INT) GET_MODE_BITSIZE (mode))))
710018334Speter	break;
710190075Sobrien
710218334Speter      /* If the shift count is a constant and we can do arithmetic in
710318334Speter	 the mode of the shift, refine which bits we need.  Otherwise, use the
710418334Speter	 conservative form of the mask.  */
710518334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
710618334Speter	  && INTVAL (XEXP (x, 1)) >= 0
710718334Speter	  && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (op_mode)
710818334Speter	  && GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT)
710918334Speter	mask >>= INTVAL (XEXP (x, 1));
711018334Speter      else
711118334Speter	mask = fuller_mask;
711218334Speter
7113169689Skan      op0 = gen_lowpart_or_truncate (op_mode,
711418334Speter				     force_to_mode (XEXP (x, 0), op_mode,
7115169689Skan						    mask, next_select));
711618334Speter
711718334Speter      if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0))
7118169689Skan	x = simplify_gen_binary (code, op_mode, op0, XEXP (x, 1));
711918334Speter      break;
712018334Speter
712118334Speter    case LSHIFTRT:
712218334Speter      /* Here we can only do something if the shift count is a constant,
712318334Speter	 this shift constant is valid for the host, and we can do arithmetic
712418334Speter	 in OP_MODE.  */
712518334Speter
712618334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
712718334Speter	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
712818334Speter	  && GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT)
712918334Speter	{
713018334Speter	  rtx inner = XEXP (x, 0);
713190075Sobrien	  unsigned HOST_WIDE_INT inner_mask;
713218334Speter
713318334Speter	  /* Select the mask of the bits we need for the shift operand.  */
713490075Sobrien	  inner_mask = mask << INTVAL (XEXP (x, 1));
713518334Speter
713618334Speter	  /* We can only change the mode of the shift if we can do arithmetic
713790075Sobrien	     in the mode of the shift and INNER_MASK is no wider than the
7138169689Skan	     width of X's mode.  */
7139169689Skan	  if ((inner_mask & ~GET_MODE_MASK (GET_MODE (x))) != 0)
714018334Speter	    op_mode = GET_MODE (x);
714118334Speter
7142169689Skan	  inner = force_to_mode (inner, op_mode, inner_mask, next_select);
714318334Speter
714418334Speter	  if (GET_MODE (x) != op_mode || inner != XEXP (x, 0))
7145169689Skan	    x = simplify_gen_binary (LSHIFTRT, op_mode, inner, XEXP (x, 1));
714618334Speter	}
714718334Speter
714818334Speter      /* If we have (and (lshiftrt FOO C1) C2) where the combination of the
714918334Speter	 shift and AND produces only copies of the sign bit (C2 is one less
715018334Speter	 than a power of two), we can do this with just a shift.  */
715118334Speter
715218334Speter      if (GET_CODE (x) == LSHIFTRT
715318334Speter	  && GET_CODE (XEXP (x, 1)) == CONST_INT
715490075Sobrien	  /* The shift puts one of the sign bit copies in the least significant
715590075Sobrien	     bit.  */
715618334Speter	  && ((INTVAL (XEXP (x, 1))
715718334Speter	       + num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0))))
715818334Speter	      >= GET_MODE_BITSIZE (GET_MODE (x)))
715918334Speter	  && exact_log2 (mask + 1) >= 0
716090075Sobrien	  /* Number of bits left after the shift must be more than the mask
716190075Sobrien	     needs.  */
716290075Sobrien	  && ((INTVAL (XEXP (x, 1)) + exact_log2 (mask + 1))
716390075Sobrien	      <= GET_MODE_BITSIZE (GET_MODE (x)))
716490075Sobrien	  /* Must be more sign bit copies than the mask needs.  */
716590075Sobrien	  && ((int) num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
716618334Speter	      >= exact_log2 (mask + 1)))
7167169689Skan	x = simplify_gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0),
7168169689Skan				 GEN_INT (GET_MODE_BITSIZE (GET_MODE (x))
7169169689Skan					  - exact_log2 (mask + 1)));
717018334Speter
717190075Sobrien      goto shiftrt;
717290075Sobrien
717318334Speter    case ASHIFTRT:
717418334Speter      /* If we are just looking for the sign bit, we don't need this shift at
717518334Speter	 all, even if it has a variable count.  */
717618334Speter      if (GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
717752284Sobrien	  && (mask == ((unsigned HOST_WIDE_INT) 1
717818334Speter		       << (GET_MODE_BITSIZE (GET_MODE (x)) - 1))))
7179169689Skan	return force_to_mode (XEXP (x, 0), mode, mask, next_select);
718018334Speter
718118334Speter      /* If this is a shift by a constant, get a mask that contains those bits
718218334Speter	 that are not copies of the sign bit.  We then have two cases:  If
718318334Speter	 MASK only includes those bits, this can be a logical shift, which may
718418334Speter	 allow simplifications.  If MASK is a single-bit field not within
718518334Speter	 those bits, we are requesting a copy of the sign bit and hence can
718618334Speter	 shift the sign bit to the appropriate location.  */
718718334Speter
718818334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) >= 0
718918334Speter	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
719018334Speter	{
7191169689Skan	  int i;
719218334Speter
719390075Sobrien	  /* If the considered data is wider than HOST_WIDE_INT, we can't
719418334Speter	     represent a mask for all its bits in a single scalar.
719518334Speter	     But we only care about the lower bits, so calculate these.  */
719618334Speter
719718334Speter	  if (GET_MODE_BITSIZE (GET_MODE (x)) > HOST_BITS_PER_WIDE_INT)
719818334Speter	    {
719990075Sobrien	      nonzero = ~(HOST_WIDE_INT) 0;
720018334Speter
720118334Speter	      /* GET_MODE_BITSIZE (GET_MODE (x)) - INTVAL (XEXP (x, 1))
720218334Speter		 is the number of bits a full-width mask would have set.
720318334Speter		 We need only shift if these are fewer than nonzero can
720418334Speter		 hold.  If not, we must keep all bits set in nonzero.  */
720518334Speter
720618334Speter	      if (GET_MODE_BITSIZE (GET_MODE (x)) - INTVAL (XEXP (x, 1))
720718334Speter		  < HOST_BITS_PER_WIDE_INT)
720818334Speter		nonzero >>= INTVAL (XEXP (x, 1))
720918334Speter			    + HOST_BITS_PER_WIDE_INT
721018334Speter			    - GET_MODE_BITSIZE (GET_MODE (x)) ;
721118334Speter	    }
721218334Speter	  else
721318334Speter	    {
721418334Speter	      nonzero = GET_MODE_MASK (GET_MODE (x));
721518334Speter	      nonzero >>= INTVAL (XEXP (x, 1));
721618334Speter	    }
721718334Speter
7218169689Skan	  if ((mask & ~nonzero) == 0)
721918334Speter	    {
7220169689Skan	      x = simplify_shift_const (NULL_RTX, LSHIFTRT, GET_MODE (x),
7221169689Skan					XEXP (x, 0), INTVAL (XEXP (x, 1)));
7222169689Skan	      if (GET_CODE (x) != ASHIFTRT)
7223169689Skan		return force_to_mode (x, mode, mask, next_select);
7224169689Skan	    }
7225169689Skan
7226169689Skan	  else if ((i = exact_log2 (mask)) >= 0)
7227169689Skan	    {
722818334Speter	      x = simplify_shift_const
7229169689Skan		  (NULL_RTX, LSHIFTRT, GET_MODE (x), XEXP (x, 0),
7230169689Skan		   GET_MODE_BITSIZE (GET_MODE (x)) - 1 - i);
723118334Speter
723218334Speter	      if (GET_CODE (x) != ASHIFTRT)
7233169689Skan		return force_to_mode (x, mode, mask, next_select);
723418334Speter	    }
723518334Speter	}
723618334Speter
7237117395Skan      /* If MASK is 1, convert this to an LSHIFTRT.  This can be done
723818334Speter	 even if the shift count isn't a constant.  */
723918334Speter      if (mask == 1)
7240169689Skan	x = simplify_gen_binary (LSHIFTRT, GET_MODE (x),
7241169689Skan				 XEXP (x, 0), XEXP (x, 1));
724218334Speter
724390075Sobrien    shiftrt:
724490075Sobrien
724590075Sobrien      /* If this is a zero- or sign-extension operation that just affects bits
724618334Speter	 we don't care about, remove it.  Be sure the call above returned
724718334Speter	 something that is still a shift.  */
724818334Speter
724918334Speter      if ((GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ASHIFTRT)
725018334Speter	  && GET_CODE (XEXP (x, 1)) == CONST_INT
725118334Speter	  && INTVAL (XEXP (x, 1)) >= 0
725218334Speter	  && (INTVAL (XEXP (x, 1))
725318334Speter	      <= GET_MODE_BITSIZE (GET_MODE (x)) - (floor_log2 (mask) + 1))
725418334Speter	  && GET_CODE (XEXP (x, 0)) == ASHIFT
7255132718Skan	  && XEXP (XEXP (x, 0), 1) == XEXP (x, 1))
725618334Speter	return force_to_mode (XEXP (XEXP (x, 0), 0), mode, mask,
7257169689Skan			      next_select);
725818334Speter
725918334Speter      break;
726018334Speter
726118334Speter    case ROTATE:
726218334Speter    case ROTATERT:
726318334Speter      /* If the shift count is constant and we can do computations
726418334Speter	 in the mode of X, compute where the bits we care about are.
726518334Speter	 Otherwise, we can't do anything.  Don't change the mode of
726618334Speter	 the shift or propagate MODE into the shift, though.  */
726718334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
726818334Speter	  && INTVAL (XEXP (x, 1)) >= 0)
726918334Speter	{
727018334Speter	  temp = simplify_binary_operation (code == ROTATE ? ROTATERT : ROTATE,
727118334Speter					    GET_MODE (x), GEN_INT (mask),
727218334Speter					    XEXP (x, 1));
7273132718Skan	  if (temp && GET_CODE (temp) == CONST_INT)
727418334Speter	    SUBST (XEXP (x, 0),
727518334Speter		   force_to_mode (XEXP (x, 0), GET_MODE (x),
7276169689Skan				  INTVAL (temp), next_select));
727718334Speter	}
727818334Speter      break;
727990075Sobrien
728018334Speter    case NEG:
728118334Speter      /* If we just want the low-order bit, the NEG isn't needed since it
728290075Sobrien	 won't change the low-order bit.  */
728318334Speter      if (mask == 1)
7284169689Skan	return force_to_mode (XEXP (x, 0), mode, mask, just_select);
728518334Speter
728618334Speter      /* We need any bits less significant than the most significant bit in
728718334Speter	 MASK since carries from those bits will affect the bits we are
728818334Speter	 interested in.  */
728918334Speter      mask = fuller_mask;
729018334Speter      goto unop;
729118334Speter
729218334Speter    case NOT:
729318334Speter      /* (not FOO) is (xor FOO CONST), so if FOO is an LSHIFTRT, we can do the
729418334Speter	 same as the XOR case above.  Ensure that the constant we form is not
729518334Speter	 wider than the mode of X.  */
729618334Speter
729718334Speter      if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
729818334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
729918334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
730018334Speter	  && (INTVAL (XEXP (XEXP (x, 0), 1)) + floor_log2 (mask)
730118334Speter	      < GET_MODE_BITSIZE (GET_MODE (x)))
730218334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT)
730318334Speter	{
7304117395Skan	  temp = gen_int_mode (mask << INTVAL (XEXP (XEXP (x, 0), 1)),
7305117395Skan			       GET_MODE (x));
7306169689Skan	  temp = simplify_gen_binary (XOR, GET_MODE (x),
7307169689Skan				      XEXP (XEXP (x, 0), 0), temp);
7308169689Skan	  x = simplify_gen_binary (LSHIFTRT, GET_MODE (x),
7309169689Skan				   temp, XEXP (XEXP (x, 0), 1));
731018334Speter
7311169689Skan	  return force_to_mode (x, mode, mask, next_select);
731218334Speter	}
731318334Speter
731450397Sobrien      /* (and (not FOO) CONST) is (not (or FOO (not CONST))), so we must
731550397Sobrien	 use the full mask inside the NOT.  */
731650397Sobrien      mask = fuller_mask;
731750397Sobrien
731818334Speter    unop:
7319169689Skan      op0 = gen_lowpart_or_truncate (op_mode,
732018334Speter				     force_to_mode (XEXP (x, 0), mode, mask,
7321169689Skan						    next_select));
732218334Speter      if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0))
732390075Sobrien	x = simplify_gen_unary (code, op_mode, op0, op_mode);
732418334Speter      break;
732518334Speter
732618334Speter    case NE:
732718334Speter      /* (and (ne FOO 0) CONST) can be (and FOO CONST) if CONST is included
732850397Sobrien	 in STORE_FLAG_VALUE and FOO has a single bit that might be nonzero,
732950397Sobrien	 which is equal to STORE_FLAG_VALUE.  */
733090075Sobrien      if ((mask & ~STORE_FLAG_VALUE) == 0 && XEXP (x, 1) == const0_rtx
7331169689Skan	  && GET_MODE (XEXP (x, 0)) == mode
733250397Sobrien	  && exact_log2 (nonzero_bits (XEXP (x, 0), mode)) >= 0
7333132718Skan	  && (nonzero_bits (XEXP (x, 0), mode)
7334132718Skan	      == (unsigned HOST_WIDE_INT) STORE_FLAG_VALUE))
7335169689Skan	return force_to_mode (XEXP (x, 0), mode, mask, next_select);
733618334Speter
733718334Speter      break;
733818334Speter
733918334Speter    case IF_THEN_ELSE:
734018334Speter      /* We have no way of knowing if the IF_THEN_ELSE can itself be
734118334Speter	 written in a narrower mode.  We play it safe and do not do so.  */
734218334Speter
734318334Speter      SUBST (XEXP (x, 1),
7344169689Skan	     gen_lowpart_or_truncate (GET_MODE (x),
734518334Speter				      force_to_mode (XEXP (x, 1), mode,
7346169689Skan						     mask, next_select)));
734718334Speter      SUBST (XEXP (x, 2),
7348169689Skan	     gen_lowpart_or_truncate (GET_MODE (x),
734918334Speter				      force_to_mode (XEXP (x, 2), mode,
7350169689Skan						     mask, next_select)));
735118334Speter      break;
735290075Sobrien
735350397Sobrien    default:
735450397Sobrien      break;
735518334Speter    }
735618334Speter
735718334Speter  /* Ensure we return a value of the proper mode.  */
7358169689Skan  return gen_lowpart_or_truncate (mode, x);
735918334Speter}
736018334Speter
736118334Speter/* Return nonzero if X is an expression that has one of two values depending on
736218334Speter   whether some other value is zero or nonzero.  In that case, we return the
736318334Speter   value that is being tested, *PTRUE is set to the value if the rtx being
736418334Speter   returned has a nonzero value, and *PFALSE is set to the other alternative.
736518334Speter
736618334Speter   If we return zero, we set *PTRUE and *PFALSE to X.  */
736718334Speter
736818334Speterstatic rtx
7369132718Skanif_then_else_cond (rtx x, rtx *ptrue, rtx *pfalse)
737018334Speter{
737118334Speter  enum machine_mode mode = GET_MODE (x);
737218334Speter  enum rtx_code code = GET_CODE (x);
737318334Speter  rtx cond0, cond1, true0, true1, false0, false1;
737418334Speter  unsigned HOST_WIDE_INT nz;
737518334Speter
737690075Sobrien  /* If we are comparing a value against zero, we are done.  */
737790075Sobrien  if ((code == NE || code == EQ)
7378132718Skan      && XEXP (x, 1) == const0_rtx)
737990075Sobrien    {
738090075Sobrien      *ptrue = (code == NE) ? const_true_rtx : const0_rtx;
738190075Sobrien      *pfalse = (code == NE) ? const0_rtx : const_true_rtx;
738290075Sobrien      return XEXP (x, 0);
738390075Sobrien    }
738490075Sobrien
738518334Speter  /* If this is a unary operation whose operand has one of two values, apply
738618334Speter     our opcode to compute those values.  */
7387169689Skan  else if (UNARY_P (x)
738890075Sobrien	   && (cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0)) != 0)
738918334Speter    {
739090075Sobrien      *ptrue = simplify_gen_unary (code, mode, true0, GET_MODE (XEXP (x, 0)));
739190075Sobrien      *pfalse = simplify_gen_unary (code, mode, false0,
739290075Sobrien				    GET_MODE (XEXP (x, 0)));
739318334Speter      return cond0;
739418334Speter    }
739518334Speter
739618334Speter  /* If this is a COMPARE, do nothing, since the IF_THEN_ELSE we would
739718334Speter     make can't possibly match and would suppress other optimizations.  */
739818334Speter  else if (code == COMPARE)
739918334Speter    ;
740018334Speter
740118334Speter  /* If this is a binary operation, see if either side has only one of two
740218334Speter     values.  If either one does or if both do and they are conditional on
740318334Speter     the same value, compute the new true and false values.  */
7404169689Skan  else if (BINARY_P (x))
740518334Speter    {
740618334Speter      cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0);
740718334Speter      cond1 = if_then_else_cond (XEXP (x, 1), &true1, &false1);
740818334Speter
740918334Speter      if ((cond0 != 0 || cond1 != 0)
741018334Speter	  && ! (cond0 != 0 && cond1 != 0 && ! rtx_equal_p (cond0, cond1)))
741118334Speter	{
741250397Sobrien	  /* If if_then_else_cond returned zero, then true/false are the
741350397Sobrien	     same rtl.  We must copy one of them to prevent invalid rtl
741450397Sobrien	     sharing.  */
741550397Sobrien	  if (cond0 == 0)
741650397Sobrien	    true0 = copy_rtx (true0);
741750397Sobrien	  else if (cond1 == 0)
741850397Sobrien	    true1 = copy_rtx (true1);
741950397Sobrien
7420169689Skan	  if (COMPARISON_P (x))
7421169689Skan	    {
7422169689Skan	      *ptrue = simplify_gen_relational (code, mode, VOIDmode,
7423169689Skan						true0, true1);
7424169689Skan	      *pfalse = simplify_gen_relational (code, mode, VOIDmode,
7425169689Skan						 false0, false1);
7426169689Skan	     }
7427169689Skan	  else
7428169689Skan	    {
7429169689Skan	      *ptrue = simplify_gen_binary (code, mode, true0, true1);
7430169689Skan	      *pfalse = simplify_gen_binary (code, mode, false0, false1);
7431169689Skan	    }
7432169689Skan
743318334Speter	  return cond0 ? cond0 : cond1;
743418334Speter	}
743518334Speter
743618334Speter      /* See if we have PLUS, IOR, XOR, MINUS or UMAX, where one of the
7437117395Skan	 operands is zero when the other is nonzero, and vice-versa,
743850397Sobrien	 and STORE_FLAG_VALUE is 1 or -1.  */
743918334Speter
744050397Sobrien      if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
744150397Sobrien	  && (code == PLUS || code == IOR || code == XOR || code == MINUS
744290075Sobrien	      || code == UMAX)
744318334Speter	  && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == MULT)
744418334Speter	{
744518334Speter	  rtx op0 = XEXP (XEXP (x, 0), 1);
744618334Speter	  rtx op1 = XEXP (XEXP (x, 1), 1);
744718334Speter
744818334Speter	  cond0 = XEXP (XEXP (x, 0), 0);
744918334Speter	  cond1 = XEXP (XEXP (x, 1), 0);
745018334Speter
7451169689Skan	  if (COMPARISON_P (cond0)
7452169689Skan	      && COMPARISON_P (cond1)
7453169689Skan	      && ((GET_CODE (cond0) == reversed_comparison_code (cond1, NULL)
745418334Speter		   && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0))
745518334Speter		   && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1)))
745618334Speter		  || ((swap_condition (GET_CODE (cond0))
7457169689Skan		       == reversed_comparison_code (cond1, NULL))
745818334Speter		      && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 1))
745918334Speter		      && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0))))
746018334Speter	      && ! side_effects_p (x))
746118334Speter	    {
7462169689Skan	      *ptrue = simplify_gen_binary (MULT, mode, op0, const_true_rtx);
7463169689Skan	      *pfalse = simplify_gen_binary (MULT, mode,
7464169689Skan					     (code == MINUS
7465169689Skan					      ? simplify_gen_unary (NEG, mode,
7466169689Skan								    op1, mode)
7467169689Skan					      : op1),
7468169689Skan					      const_true_rtx);
746918334Speter	      return cond0;
747018334Speter	    }
747118334Speter	}
747218334Speter
747390075Sobrien      /* Similarly for MULT, AND and UMIN, except that for these the result
747418334Speter	 is always zero.  */
747550397Sobrien      if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
747650397Sobrien	  && (code == MULT || code == AND || code == UMIN)
747718334Speter	  && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == MULT)
747818334Speter	{
747918334Speter	  cond0 = XEXP (XEXP (x, 0), 0);
748018334Speter	  cond1 = XEXP (XEXP (x, 1), 0);
748118334Speter
7482169689Skan	  if (COMPARISON_P (cond0)
7483169689Skan	      && COMPARISON_P (cond1)
7484169689Skan	      && ((GET_CODE (cond0) == reversed_comparison_code (cond1, NULL)
748518334Speter		   && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0))
748618334Speter		   && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1)))
748718334Speter		  || ((swap_condition (GET_CODE (cond0))
7488169689Skan		       == reversed_comparison_code (cond1, NULL))
748918334Speter		      && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 1))
749018334Speter		      && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0))))
749118334Speter	      && ! side_effects_p (x))
749218334Speter	    {
749318334Speter	      *ptrue = *pfalse = const0_rtx;
749418334Speter	      return cond0;
749518334Speter	    }
749618334Speter	}
749718334Speter    }
749818334Speter
749918334Speter  else if (code == IF_THEN_ELSE)
750018334Speter    {
750118334Speter      /* If we have IF_THEN_ELSE already, extract the condition and
750218334Speter	 canonicalize it if it is NE or EQ.  */
750318334Speter      cond0 = XEXP (x, 0);
750418334Speter      *ptrue = XEXP (x, 1), *pfalse = XEXP (x, 2);
750518334Speter      if (GET_CODE (cond0) == NE && XEXP (cond0, 1) == const0_rtx)
750618334Speter	return XEXP (cond0, 0);
750718334Speter      else if (GET_CODE (cond0) == EQ && XEXP (cond0, 1) == const0_rtx)
750818334Speter	{
750918334Speter	  *ptrue = XEXP (x, 2), *pfalse = XEXP (x, 1);
751018334Speter	  return XEXP (cond0, 0);
751118334Speter	}
751218334Speter      else
751318334Speter	return cond0;
751418334Speter    }
751518334Speter
751690075Sobrien  /* If X is a SUBREG, we can narrow both the true and false values
751790075Sobrien     if the inner expression, if there is a condition.  */
751890075Sobrien  else if (code == SUBREG
751918334Speter	   && 0 != (cond0 = if_then_else_cond (SUBREG_REG (x),
752018334Speter					       &true0, &false0)))
752118334Speter    {
7522132718Skan      true0 = simplify_gen_subreg (mode, true0,
7523132718Skan				   GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
7524132718Skan      false0 = simplify_gen_subreg (mode, false0,
752590075Sobrien				    GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
7526132718Skan      if (true0 && false0)
7527132718Skan	{
7528132718Skan	  *ptrue = true0;
7529132718Skan	  *pfalse = false0;
7530132718Skan	  return cond0;
7531132718Skan	}
753218334Speter    }
753318334Speter
753418334Speter  /* If X is a constant, this isn't special and will cause confusions
753518334Speter     if we treat it as such.  Likewise if it is equivalent to a constant.  */
753618334Speter  else if (CONSTANT_P (x)
753718334Speter	   || ((cond0 = get_last_value (x)) != 0 && CONSTANT_P (cond0)))
753818334Speter    ;
753918334Speter
754090075Sobrien  /* If we're in BImode, canonicalize on 0 and STORE_FLAG_VALUE, as that
754190075Sobrien     will be least confusing to the rest of the compiler.  */
754290075Sobrien  else if (mode == BImode)
754390075Sobrien    {
754490075Sobrien      *ptrue = GEN_INT (STORE_FLAG_VALUE), *pfalse = const0_rtx;
754590075Sobrien      return x;
754690075Sobrien    }
754790075Sobrien
754890075Sobrien  /* If X is known to be either 0 or -1, those are the true and
754918334Speter     false values when testing X.  */
755090075Sobrien  else if (x == constm1_rtx || x == const0_rtx
755190075Sobrien	   || (mode != VOIDmode
755290075Sobrien	       && num_sign_bit_copies (x, mode) == GET_MODE_BITSIZE (mode)))
755318334Speter    {
755418334Speter      *ptrue = constm1_rtx, *pfalse = const0_rtx;
755518334Speter      return x;
755618334Speter    }
755718334Speter
755818334Speter  /* Likewise for 0 or a single bit.  */
7559132718Skan  else if (SCALAR_INT_MODE_P (mode)
756090075Sobrien	   && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
756190075Sobrien	   && exact_log2 (nz = nonzero_bits (x, mode)) >= 0)
756218334Speter    {
7563117395Skan      *ptrue = gen_int_mode (nz, mode), *pfalse = const0_rtx;
756418334Speter      return x;
756518334Speter    }
756618334Speter
756718334Speter  /* Otherwise fail; show no condition with true and false values the same.  */
756818334Speter  *ptrue = *pfalse = x;
756918334Speter  return 0;
757018334Speter}
757118334Speter
757218334Speter/* Return the value of expression X given the fact that condition COND
757318334Speter   is known to be true when applied to REG as its first operand and VAL
757418334Speter   as its second.  X is known to not be shared and so can be modified in
757518334Speter   place.
757618334Speter
757718334Speter   We only handle the simplest cases, and specifically those cases that
757818334Speter   arise with IF_THEN_ELSE expressions.  */
757918334Speter
758018334Speterstatic rtx
7581132718Skanknown_cond (rtx x, enum rtx_code cond, rtx reg, rtx val)
758218334Speter{
758318334Speter  enum rtx_code code = GET_CODE (x);
758418334Speter  rtx temp;
758590075Sobrien  const char *fmt;
758618334Speter  int i, j;
758718334Speter
758818334Speter  if (side_effects_p (x))
758918334Speter    return x;
759018334Speter
759190075Sobrien  /* If either operand of the condition is a floating point value,
759290075Sobrien     then we have to avoid collapsing an EQ comparison.  */
759390075Sobrien  if (cond == EQ
759490075Sobrien      && rtx_equal_p (x, reg)
759590075Sobrien      && ! FLOAT_MODE_P (GET_MODE (x))
759690075Sobrien      && ! FLOAT_MODE_P (GET_MODE (val)))
759718334Speter    return val;
759818334Speter
759990075Sobrien  if (cond == UNEQ && rtx_equal_p (x, reg))
760090075Sobrien    return val;
760190075Sobrien
760218334Speter  /* If X is (abs REG) and we know something about REG's relationship
760318334Speter     with zero, we may be able to simplify this.  */
760418334Speter
760518334Speter  if (code == ABS && rtx_equal_p (XEXP (x, 0), reg) && val == const0_rtx)
760618334Speter    switch (cond)
760718334Speter      {
760818334Speter      case GE:  case GT:  case EQ:
760918334Speter	return XEXP (x, 0);
761018334Speter      case LT:  case LE:
761190075Sobrien	return simplify_gen_unary (NEG, GET_MODE (XEXP (x, 0)),
761290075Sobrien				   XEXP (x, 0),
761390075Sobrien				   GET_MODE (XEXP (x, 0)));
761450397Sobrien      default:
761550397Sobrien	break;
761618334Speter      }
761718334Speter
761818334Speter  /* The only other cases we handle are MIN, MAX, and comparisons if the
761918334Speter     operands are the same as REG and VAL.  */
762018334Speter
7621169689Skan  else if (COMPARISON_P (x) || COMMUTATIVE_ARITH_P (x))
762218334Speter    {
762318334Speter      if (rtx_equal_p (XEXP (x, 0), val))
762418334Speter	cond = swap_condition (cond), temp = val, val = reg, reg = temp;
762518334Speter
762618334Speter      if (rtx_equal_p (XEXP (x, 0), reg) && rtx_equal_p (XEXP (x, 1), val))
762718334Speter	{
7628169689Skan	  if (COMPARISON_P (x))
762990075Sobrien	    {
763090075Sobrien	      if (comparison_dominates_p (cond, code))
763190075Sobrien		return const_true_rtx;
763218334Speter
7633169689Skan	      code = reversed_comparison_code (x, NULL);
763490075Sobrien	      if (code != UNKNOWN
763590075Sobrien		  && comparison_dominates_p (cond, code))
763690075Sobrien		return const0_rtx;
763790075Sobrien	      else
763890075Sobrien		return x;
763990075Sobrien	    }
764018334Speter	  else if (code == SMAX || code == SMIN
764118334Speter		   || code == UMIN || code == UMAX)
764218334Speter	    {
764318334Speter	      int unsignedp = (code == UMIN || code == UMAX);
764418334Speter
764590075Sobrien	      /* Do not reverse the condition when it is NE or EQ.
764690075Sobrien		 This is because we cannot conclude anything about
764790075Sobrien		 the value of 'SMAX (x, y)' when x is not equal to y,
764890075Sobrien		 but we can when x equals y.  */
764990075Sobrien	      if ((code == SMAX || code == UMAX)
765090075Sobrien		  && ! (cond == EQ || cond == NE))
765118334Speter		cond = reverse_condition (cond);
765218334Speter
765318334Speter	      switch (cond)
765418334Speter		{
765518334Speter		case GE:   case GT:
765618334Speter		  return unsignedp ? x : XEXP (x, 1);
765718334Speter		case LE:   case LT:
765818334Speter		  return unsignedp ? x : XEXP (x, 0);
765918334Speter		case GEU:  case GTU:
766018334Speter		  return unsignedp ? XEXP (x, 1) : x;
766118334Speter		case LEU:  case LTU:
766218334Speter		  return unsignedp ? XEXP (x, 0) : x;
766350397Sobrien		default:
766450397Sobrien		  break;
766518334Speter		}
766618334Speter	    }
766718334Speter	}
766818334Speter    }
766996263Sobrien  else if (code == SUBREG)
767096263Sobrien    {
767196263Sobrien      enum machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
767296263Sobrien      rtx new, r = known_cond (SUBREG_REG (x), cond, reg, val);
767318334Speter
767496263Sobrien      if (SUBREG_REG (x) != r)
767596263Sobrien	{
767696263Sobrien	  /* We must simplify subreg here, before we lose track of the
767796263Sobrien	     original inner_mode.  */
767896263Sobrien	  new = simplify_subreg (GET_MODE (x), r,
767996263Sobrien				 inner_mode, SUBREG_BYTE (x));
768096263Sobrien	  if (new)
768196263Sobrien	    return new;
768296263Sobrien	  else
768396263Sobrien	    SUBST (SUBREG_REG (x), r);
768496263Sobrien	}
768596263Sobrien
768696263Sobrien      return x;
768796263Sobrien    }
768896263Sobrien  /* We don't have to handle SIGN_EXTEND here, because even in the
768996263Sobrien     case of replacing something with a modeless CONST_INT, a
769096263Sobrien     CONST_INT is already (supposed to be) a valid sign extension for
769196263Sobrien     its narrower mode, which implies it's already properly
769296263Sobrien     sign-extended for the wider mode.  Now, for ZERO_EXTEND, the
769396263Sobrien     story is different.  */
769496263Sobrien  else if (code == ZERO_EXTEND)
769596263Sobrien    {
769696263Sobrien      enum machine_mode inner_mode = GET_MODE (XEXP (x, 0));
769796263Sobrien      rtx new, r = known_cond (XEXP (x, 0), cond, reg, val);
769896263Sobrien
769996263Sobrien      if (XEXP (x, 0) != r)
770096263Sobrien	{
770196263Sobrien	  /* We must simplify the zero_extend here, before we lose
7702169689Skan	     track of the original inner_mode.  */
770396263Sobrien	  new = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
770496263Sobrien					  r, inner_mode);
770596263Sobrien	  if (new)
770696263Sobrien	    return new;
770796263Sobrien	  else
770896263Sobrien	    SUBST (XEXP (x, 0), r);
770996263Sobrien	}
771096263Sobrien
771196263Sobrien      return x;
771296263Sobrien    }
771396263Sobrien
771418334Speter  fmt = GET_RTX_FORMAT (code);
771518334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
771618334Speter    {
771718334Speter      if (fmt[i] == 'e')
771818334Speter	SUBST (XEXP (x, i), known_cond (XEXP (x, i), cond, reg, val));
771918334Speter      else if (fmt[i] == 'E')
772018334Speter	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
772118334Speter	  SUBST (XVECEXP (x, i, j), known_cond (XVECEXP (x, i, j),
772218334Speter						cond, reg, val));
772318334Speter    }
772418334Speter
772518334Speter  return x;
772618334Speter}
772718334Speter
772850397Sobrien/* See if X and Y are equal for the purposes of seeing if we can rewrite an
772950397Sobrien   assignment as a field assignment.  */
773050397Sobrien
773150397Sobrienstatic int
7732132718Skanrtx_equal_for_field_assignment_p (rtx x, rtx y)
773350397Sobrien{
773450397Sobrien  if (x == y || rtx_equal_p (x, y))
773550397Sobrien    return 1;
773650397Sobrien
773750397Sobrien  if (x == 0 || y == 0 || GET_MODE (x) != GET_MODE (y))
773850397Sobrien    return 0;
773950397Sobrien
774050397Sobrien  /* Check for a paradoxical SUBREG of a MEM compared with the MEM.
774150397Sobrien     Note that all SUBREGs of MEM are paradoxical; otherwise they
774250397Sobrien     would have been rewritten.  */
7743169689Skan  if (MEM_P (x) && GET_CODE (y) == SUBREG
7744169689Skan      && MEM_P (SUBREG_REG (y))
774550397Sobrien      && rtx_equal_p (SUBREG_REG (y),
7746169689Skan		      gen_lowpart (GET_MODE (SUBREG_REG (y)), x)))
774750397Sobrien    return 1;
774850397Sobrien
7749169689Skan  if (MEM_P (y) && GET_CODE (x) == SUBREG
7750169689Skan      && MEM_P (SUBREG_REG (x))
775150397Sobrien      && rtx_equal_p (SUBREG_REG (x),
7752169689Skan		      gen_lowpart (GET_MODE (SUBREG_REG (x)), y)))
775350397Sobrien    return 1;
775450397Sobrien
775550397Sobrien  /* We used to see if get_last_value of X and Y were the same but that's
775650397Sobrien     not correct.  In one direction, we'll cause the assignment to have
775750397Sobrien     the wrong destination and in the case, we'll import a register into this
775850397Sobrien     insn that might have already have been dead.   So fail if none of the
775950397Sobrien     above cases are true.  */
776050397Sobrien  return 0;
776150397Sobrien}
776250397Sobrien
776318334Speter/* See if X, a SET operation, can be rewritten as a bit-field assignment.
776418334Speter   Return that assignment if so.
776518334Speter
776618334Speter   We only handle the most common cases.  */
776718334Speter
776818334Speterstatic rtx
7769132718Skanmake_field_assignment (rtx x)
777018334Speter{
777118334Speter  rtx dest = SET_DEST (x);
777218334Speter  rtx src = SET_SRC (x);
777318334Speter  rtx assign;
777450397Sobrien  rtx rhs, lhs;
777518334Speter  HOST_WIDE_INT c1;
777690075Sobrien  HOST_WIDE_INT pos;
777790075Sobrien  unsigned HOST_WIDE_INT len;
777818334Speter  rtx other;
777918334Speter  enum machine_mode mode;
778018334Speter
778118334Speter  /* If SRC was (and (not (ashift (const_int 1) POS)) DEST), this is
778218334Speter     a clear of a one-bit field.  We will have changed it to
778318334Speter     (and (rotate (const_int -2) POS) DEST), so check for that.  Also check
778418334Speter     for a SUBREG.  */
778518334Speter
778618334Speter  if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == ROTATE
778718334Speter      && GET_CODE (XEXP (XEXP (src, 0), 0)) == CONST_INT
778818334Speter      && INTVAL (XEXP (XEXP (src, 0), 0)) == -2
778950397Sobrien      && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
779018334Speter    {
779118334Speter      assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1),
779218334Speter				1, 1, 1, 0);
779350397Sobrien      if (assign != 0)
779450397Sobrien	return gen_rtx_SET (VOIDmode, assign, const0_rtx);
779550397Sobrien      return x;
779618334Speter    }
779718334Speter
7798169689Skan  if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == SUBREG
7799169689Skan      && subreg_lowpart_p (XEXP (src, 0))
7800169689Skan      && (GET_MODE_SIZE (GET_MODE (XEXP (src, 0)))
7801169689Skan	  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (src, 0)))))
7802169689Skan      && GET_CODE (SUBREG_REG (XEXP (src, 0))) == ROTATE
7803169689Skan      && GET_CODE (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == CONST_INT
7804169689Skan      && INTVAL (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == -2
7805169689Skan      && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
780618334Speter    {
780718334Speter      assign = make_extraction (VOIDmode, dest, 0,
780818334Speter				XEXP (SUBREG_REG (XEXP (src, 0)), 1),
780918334Speter				1, 1, 1, 0);
781050397Sobrien      if (assign != 0)
781150397Sobrien	return gen_rtx_SET (VOIDmode, assign, const0_rtx);
781250397Sobrien      return x;
781318334Speter    }
781418334Speter
781550397Sobrien  /* If SRC is (ior (ashift (const_int 1) POS) DEST), this is a set of a
781618334Speter     one-bit field.  */
7817169689Skan  if (GET_CODE (src) == IOR && GET_CODE (XEXP (src, 0)) == ASHIFT
7818169689Skan      && XEXP (XEXP (src, 0), 0) == const1_rtx
7819169689Skan      && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
782018334Speter    {
782118334Speter      assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1),
782218334Speter				1, 1, 1, 0);
782350397Sobrien      if (assign != 0)
782450397Sobrien	return gen_rtx_SET (VOIDmode, assign, const1_rtx);
782550397Sobrien      return x;
782618334Speter    }
782718334Speter
7828169689Skan  /* If DEST is already a field assignment, i.e. ZERO_EXTRACT, and the
7829169689Skan     SRC is an AND with all bits of that field set, then we can discard
7830169689Skan     the AND.  */
7831169689Skan  if (GET_CODE (dest) == ZERO_EXTRACT
7832169689Skan      && GET_CODE (XEXP (dest, 1)) == CONST_INT
7833169689Skan      && GET_CODE (src) == AND
7834169689Skan      && GET_CODE (XEXP (src, 1)) == CONST_INT)
7835169689Skan    {
7836169689Skan      HOST_WIDE_INT width = INTVAL (XEXP (dest, 1));
7837169689Skan      unsigned HOST_WIDE_INT and_mask = INTVAL (XEXP (src, 1));
7838169689Skan      unsigned HOST_WIDE_INT ze_mask;
7839169689Skan
7840169689Skan      if (width >= HOST_BITS_PER_WIDE_INT)
7841169689Skan	ze_mask = -1;
7842169689Skan      else
7843169689Skan	ze_mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
7844169689Skan
7845169689Skan      /* Complete overlap.  We can remove the source AND.  */
7846169689Skan      if ((and_mask & ze_mask) == ze_mask)
7847169689Skan	return gen_rtx_SET (VOIDmode, dest, XEXP (src, 0));
7848169689Skan
7849169689Skan      /* Partial overlap.  We can reduce the source AND.  */
7850169689Skan      if ((and_mask & ze_mask) != and_mask)
7851169689Skan	{
7852169689Skan	  mode = GET_MODE (src);
7853169689Skan	  src = gen_rtx_AND (mode, XEXP (src, 0),
7854169689Skan			     gen_int_mode (and_mask & ze_mask, mode));
7855169689Skan	  return gen_rtx_SET (VOIDmode, dest, src);
7856169689Skan	}
7857169689Skan    }
7858169689Skan
785918334Speter  /* The other case we handle is assignments into a constant-position
786050397Sobrien     field.  They look like (ior/xor (and DEST C1) OTHER).  If C1 represents
786118334Speter     a mask that has all one bits except for a group of zero bits and
786218334Speter     OTHER is known to have zeros where C1 has ones, this is such an
786318334Speter     assignment.  Compute the position and length from C1.  Shift OTHER
786418334Speter     to the appropriate position, force it to the required mode, and
786518334Speter     make the extraction.  Check for the AND in both operands.  */
786618334Speter
786750397Sobrien  if (GET_CODE (src) != IOR && GET_CODE (src) != XOR)
786850397Sobrien    return x;
786950397Sobrien
787050397Sobrien  rhs = expand_compound_operation (XEXP (src, 0));
787150397Sobrien  lhs = expand_compound_operation (XEXP (src, 1));
787250397Sobrien
787350397Sobrien  if (GET_CODE (rhs) == AND
787450397Sobrien      && GET_CODE (XEXP (rhs, 1)) == CONST_INT
787550397Sobrien      && rtx_equal_for_field_assignment_p (XEXP (rhs, 0), dest))
787650397Sobrien    c1 = INTVAL (XEXP (rhs, 1)), other = lhs;
787750397Sobrien  else if (GET_CODE (lhs) == AND
787850397Sobrien	   && GET_CODE (XEXP (lhs, 1)) == CONST_INT
787950397Sobrien	   && rtx_equal_for_field_assignment_p (XEXP (lhs, 0), dest))
788050397Sobrien    c1 = INTVAL (XEXP (lhs, 1)), other = rhs;
788118334Speter  else
788218334Speter    return x;
788318334Speter
788490075Sobrien  pos = get_pos_from_mask ((~c1) & GET_MODE_MASK (GET_MODE (dest)), &len);
788518334Speter  if (pos < 0 || pos + len > GET_MODE_BITSIZE (GET_MODE (dest))
788650397Sobrien      || GET_MODE_BITSIZE (GET_MODE (dest)) > HOST_BITS_PER_WIDE_INT
788750397Sobrien      || (c1 & nonzero_bits (other, GET_MODE (dest))) != 0)
788818334Speter    return x;
788918334Speter
789018334Speter  assign = make_extraction (VOIDmode, dest, pos, NULL_RTX, len, 1, 1, 0);
789150397Sobrien  if (assign == 0)
789250397Sobrien    return x;
789318334Speter
789418334Speter  /* The mode to use for the source is the mode of the assignment, or of
789518334Speter     what is inside a possible STRICT_LOW_PART.  */
789690075Sobrien  mode = (GET_CODE (assign) == STRICT_LOW_PART
789718334Speter	  ? GET_MODE (XEXP (assign, 0)) : GET_MODE (assign));
789818334Speter
789918334Speter  /* Shift OTHER right POS places and make it the source, restricting it
790018334Speter     to the proper length and mode.  */
790118334Speter
7902169689Skan  src = canon_reg_for_combine (simplify_shift_const (NULL_RTX, LSHIFTRT,
7903169689Skan						     GET_MODE (src),
7904169689Skan						     other, pos),
7905169689Skan			       dest);
7906169689Skan  src = force_to_mode (src, mode,
790718334Speter		       GET_MODE_BITSIZE (mode) >= HOST_BITS_PER_WIDE_INT
790890075Sobrien		       ? ~(unsigned HOST_WIDE_INT) 0
790990075Sobrien		       : ((unsigned HOST_WIDE_INT) 1 << len) - 1,
7910169689Skan		       0);
791118334Speter
7912132718Skan  /* If SRC is masked by an AND that does not make a difference in
7913132718Skan     the value being stored, strip it.  */
7914132718Skan  if (GET_CODE (assign) == ZERO_EXTRACT
7915132718Skan      && GET_CODE (XEXP (assign, 1)) == CONST_INT
7916132718Skan      && INTVAL (XEXP (assign, 1)) < HOST_BITS_PER_WIDE_INT
7917132718Skan      && GET_CODE (src) == AND
7918132718Skan      && GET_CODE (XEXP (src, 1)) == CONST_INT
7919132718Skan      && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (src, 1))
7920132718Skan	  == ((unsigned HOST_WIDE_INT) 1 << INTVAL (XEXP (assign, 1))) - 1))
7921132718Skan    src = XEXP (src, 0);
7922132718Skan
792390075Sobrien  return gen_rtx_SET (VOIDmode, assign, src);
792418334Speter}
792518334Speter
792618334Speter/* See if X is of the form (+ (* a c) (* b c)) and convert to (* (+ a b) c)
792718334Speter   if so.  */
792818334Speter
792918334Speterstatic rtx
7930132718Skanapply_distributive_law (rtx x)
793118334Speter{
793218334Speter  enum rtx_code code = GET_CODE (x);
7933132718Skan  enum rtx_code inner_code;
793418334Speter  rtx lhs, rhs, other;
793518334Speter  rtx tem;
793618334Speter
7937132718Skan  /* Distributivity is not true for floating point as it can change the
7938132718Skan     value.  So we don't do it unless -funsafe-math-optimizations.  */
7939132718Skan  if (FLOAT_MODE_P (GET_MODE (x))
7940132718Skan      && ! flag_unsafe_math_optimizations)
794118334Speter    return x;
794218334Speter
794318334Speter  /* The outer operation can only be one of the following:  */
794418334Speter  if (code != IOR && code != AND && code != XOR
794518334Speter      && code != PLUS && code != MINUS)
794618334Speter    return x;
794718334Speter
7948132718Skan  lhs = XEXP (x, 0);
7949132718Skan  rhs = XEXP (x, 1);
795018334Speter
795150397Sobrien  /* If either operand is a primitive we can't do anything, so get out
795250397Sobrien     fast.  */
7953169689Skan  if (OBJECT_P (lhs) || OBJECT_P (rhs))
795418334Speter    return x;
795518334Speter
795618334Speter  lhs = expand_compound_operation (lhs);
795718334Speter  rhs = expand_compound_operation (rhs);
795818334Speter  inner_code = GET_CODE (lhs);
795918334Speter  if (inner_code != GET_CODE (rhs))
796018334Speter    return x;
796118334Speter
796218334Speter  /* See if the inner and outer operations distribute.  */
796318334Speter  switch (inner_code)
796418334Speter    {
796518334Speter    case LSHIFTRT:
796618334Speter    case ASHIFTRT:
796718334Speter    case AND:
796818334Speter    case IOR:
796918334Speter      /* These all distribute except over PLUS.  */
797018334Speter      if (code == PLUS || code == MINUS)
797118334Speter	return x;
797218334Speter      break;
797318334Speter
797418334Speter    case MULT:
797518334Speter      if (code != PLUS && code != MINUS)
797618334Speter	return x;
797718334Speter      break;
797818334Speter
797918334Speter    case ASHIFT:
798018334Speter      /* This is also a multiply, so it distributes over everything.  */
798118334Speter      break;
798218334Speter
798318334Speter    case SUBREG:
7984169689Skan      /* Non-paradoxical SUBREGs distributes over all operations,
7985169689Skan	 provided the inner modes and byte offsets are the same, this
7986169689Skan	 is an extraction of a low-order part, we don't convert an fp
7987169689Skan	 operation to int or vice versa, this is not a vector mode,
7988169689Skan	 and we would not be converting a single-word operation into a
7989169689Skan	 multi-word operation.  The latter test is not required, but
7990169689Skan	 it prevents generating unneeded multi-word operations.  Some
7991169689Skan	 of the previous tests are redundant given the latter test,
7992169689Skan	 but are retained because they are required for correctness.
799318334Speter
799418334Speter	 We produce the result slightly differently in this case.  */
799518334Speter
799618334Speter      if (GET_MODE (SUBREG_REG (lhs)) != GET_MODE (SUBREG_REG (rhs))
799790075Sobrien	  || SUBREG_BYTE (lhs) != SUBREG_BYTE (rhs)
799818334Speter	  || ! subreg_lowpart_p (lhs)
799918334Speter	  || (GET_MODE_CLASS (GET_MODE (lhs))
800018334Speter	      != GET_MODE_CLASS (GET_MODE (SUBREG_REG (lhs))))
800118334Speter	  || (GET_MODE_SIZE (GET_MODE (lhs))
800218334Speter	      > GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))))
8003169689Skan	  || VECTOR_MODE_P (GET_MODE (lhs))
8004169689Skan	  || GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))) > UNITS_PER_WORD
8005169689Skan	  /* Result might need to be truncated.  Don't change mode if
8006169689Skan	     explicit truncation is needed.  */
8007169689Skan	  || !TRULY_NOOP_TRUNCATION
8008169689Skan	       (GET_MODE_BITSIZE (GET_MODE (x)),
8009169689Skan		GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (lhs)))))
801018334Speter	return x;
801118334Speter
8012169689Skan      tem = simplify_gen_binary (code, GET_MODE (SUBREG_REG (lhs)),
8013169689Skan				 SUBREG_REG (lhs), SUBREG_REG (rhs));
8014169689Skan      return gen_lowpart (GET_MODE (x), tem);
801518334Speter
801618334Speter    default:
801718334Speter      return x;
801818334Speter    }
801918334Speter
802018334Speter  /* Set LHS and RHS to the inner operands (A and B in the example
802118334Speter     above) and set OTHER to the common operand (C in the example).
8022169689Skan     There is only one way to do this unless the inner operation is
802318334Speter     commutative.  */
8024169689Skan  if (COMMUTATIVE_ARITH_P (lhs)
802518334Speter      && rtx_equal_p (XEXP (lhs, 0), XEXP (rhs, 0)))
802618334Speter    other = XEXP (lhs, 0), lhs = XEXP (lhs, 1), rhs = XEXP (rhs, 1);
8027169689Skan  else if (COMMUTATIVE_ARITH_P (lhs)
802818334Speter	   && rtx_equal_p (XEXP (lhs, 0), XEXP (rhs, 1)))
802918334Speter    other = XEXP (lhs, 0), lhs = XEXP (lhs, 1), rhs = XEXP (rhs, 0);
8030169689Skan  else if (COMMUTATIVE_ARITH_P (lhs)
803118334Speter	   && rtx_equal_p (XEXP (lhs, 1), XEXP (rhs, 0)))
803218334Speter    other = XEXP (lhs, 1), lhs = XEXP (lhs, 0), rhs = XEXP (rhs, 1);
803318334Speter  else if (rtx_equal_p (XEXP (lhs, 1), XEXP (rhs, 1)))
803418334Speter    other = XEXP (lhs, 1), lhs = XEXP (lhs, 0), rhs = XEXP (rhs, 0);
803518334Speter  else
803618334Speter    return x;
803718334Speter
803818334Speter  /* Form the new inner operation, seeing if it simplifies first.  */
8039169689Skan  tem = simplify_gen_binary (code, GET_MODE (x), lhs, rhs);
804018334Speter
804118334Speter  /* There is one exception to the general way of distributing:
8042132718Skan     (a | c) ^ (b | c) -> (a ^ b) & ~c  */
804318334Speter  if (code == XOR && inner_code == IOR)
804418334Speter    {
804518334Speter      inner_code = AND;
804690075Sobrien      other = simplify_gen_unary (NOT, GET_MODE (x), other, GET_MODE (x));
804718334Speter    }
804818334Speter
804918334Speter  /* We may be able to continuing distributing the result, so call
805018334Speter     ourselves recursively on the inner operation before forming the
805118334Speter     outer operation, which we return.  */
8052169689Skan  return simplify_gen_binary (inner_code, GET_MODE (x),
8053169689Skan			      apply_distributive_law (tem), other);
805418334Speter}
805518334Speter
8056169689Skan/* See if X is of the form (* (+ A B) C), and if so convert to
8057169689Skan   (+ (* A C) (* B C)) and try to simplify.
805818334Speter
8059169689Skan   Most of the time, this results in no change.  However, if some of
8060169689Skan   the operands are the same or inverses of each other, simplifications
8061169689Skan   will result.
8062169689Skan
8063169689Skan   For example, (and (ior A B) (not B)) can occur as the result of
8064169689Skan   expanding a bit field assignment.  When we apply the distributive
8065169689Skan   law to this, we get (ior (and (A (not B))) (and (B (not B)))),
8066169689Skan   which then simplifies to (and (A (not B))).
8067169689Skan
8068169689Skan   Note that no checks happen on the validity of applying the inverse
8069169689Skan   distributive law.  This is pointless since we can do it in the
8070169689Skan   few places where this routine is called.
8071169689Skan
8072169689Skan   N is the index of the term that is decomposed (the arithmetic operation,
8073169689Skan   i.e. (+ A B) in the first example above).  !N is the index of the term that
8074169689Skan   is distributed, i.e. of C in the first example above.  */
807518334Speterstatic rtx
8076169689Skandistribute_and_simplify_rtx (rtx x, int n)
807718334Speter{
8078169689Skan  enum machine_mode mode;
8079169689Skan  enum rtx_code outer_code, inner_code;
8080169689Skan  rtx decomposed, distributed, inner_op0, inner_op1, new_op0, new_op1, tmp;
8081169689Skan
8082169689Skan  decomposed = XEXP (x, n);
8083169689Skan  if (!ARITHMETIC_P (decomposed))
8084169689Skan    return NULL_RTX;
8085169689Skan
8086169689Skan  mode = GET_MODE (x);
8087169689Skan  outer_code = GET_CODE (x);
8088169689Skan  distributed = XEXP (x, !n);
8089169689Skan
8090169689Skan  inner_code = GET_CODE (decomposed);
8091169689Skan  inner_op0 = XEXP (decomposed, 0);
8092169689Skan  inner_op1 = XEXP (decomposed, 1);
8093169689Skan
8094169689Skan  /* Special case (and (xor B C) (not A)), which is equivalent to
8095169689Skan     (xor (ior A B) (ior A C))  */
8096169689Skan  if (outer_code == AND && inner_code == XOR && GET_CODE (distributed) == NOT)
8097169689Skan    {
8098169689Skan      distributed = XEXP (distributed, 0);
8099169689Skan      outer_code = IOR;
8100169689Skan    }
8101169689Skan
8102169689Skan  if (n == 0)
8103169689Skan    {
8104169689Skan      /* Distribute the second term.  */
8105169689Skan      new_op0 = simplify_gen_binary (outer_code, mode, inner_op0, distributed);
8106169689Skan      new_op1 = simplify_gen_binary (outer_code, mode, inner_op1, distributed);
8107169689Skan    }
8108169689Skan  else
8109169689Skan    {
8110169689Skan      /* Distribute the first term.  */
8111169689Skan      new_op0 = simplify_gen_binary (outer_code, mode, distributed, inner_op0);
8112169689Skan      new_op1 = simplify_gen_binary (outer_code, mode, distributed, inner_op1);
8113169689Skan    }
8114169689Skan
8115169689Skan  tmp = apply_distributive_law (simplify_gen_binary (inner_code, mode,
8116169689Skan						     new_op0, new_op1));
8117169689Skan  if (GET_CODE (tmp) != outer_code
8118169689Skan      && rtx_cost (tmp, SET) < rtx_cost (x, SET))
8119169689Skan    return tmp;
8120169689Skan
8121169689Skan  return NULL_RTX;
8122169689Skan}
8123169689Skan
8124169689Skan/* Simplify a logical `and' of VAROP with the constant CONSTOP, to be done
8125169689Skan   in MODE.  Return an equivalent form, if different from (and VAROP
8126169689Skan   (const_int CONSTOP)).  Otherwise, return NULL_RTX.  */
8127169689Skan
8128169689Skanstatic rtx
8129169689Skansimplify_and_const_int_1 (enum machine_mode mode, rtx varop,
8130169689Skan			  unsigned HOST_WIDE_INT constop)
8131169689Skan{
813218334Speter  unsigned HOST_WIDE_INT nonzero;
8133169689Skan  unsigned HOST_WIDE_INT orig_constop;
8134169689Skan  rtx orig_varop;
813518334Speter  int i;
813618334Speter
8137169689Skan  orig_varop = varop;
8138169689Skan  orig_constop = constop;
8139169689Skan  if (GET_CODE (varop) == CLOBBER)
8140169689Skan    return NULL_RTX;
8141169689Skan
814218334Speter  /* Simplify VAROP knowing that we will be only looking at some of the
814396263Sobrien     bits in it.
814496263Sobrien
814596263Sobrien     Note by passing in CONSTOP, we guarantee that the bits not set in
814696263Sobrien     CONSTOP are not significant and will never be examined.  We must
814796263Sobrien     ensure that is the case by explicitly masking out those bits
814896263Sobrien     before returning.  */
8149169689Skan  varop = force_to_mode (varop, mode, constop, 0);
815018334Speter
815196263Sobrien  /* If VAROP is a CLOBBER, we will fail so return it.  */
815296263Sobrien  if (GET_CODE (varop) == CLOBBER)
815318334Speter    return varop;
815418334Speter
815596263Sobrien  /* If VAROP is a CONST_INT, then we need to apply the mask in CONSTOP
815696263Sobrien     to VAROP and return the new constant.  */
815796263Sobrien  if (GET_CODE (varop) == CONST_INT)
8158169689Skan    return gen_int_mode (INTVAL (varop) & constop, mode);
815996263Sobrien
816018334Speter  /* See what bits may be nonzero in VAROP.  Unlike the general case of
816118334Speter     a call to nonzero_bits, here we don't care about bits outside
816218334Speter     MODE.  */
816318334Speter
816418334Speter  nonzero = nonzero_bits (varop, mode) & GET_MODE_MASK (mode);
816518334Speter
816618334Speter  /* Turn off all bits in the constant that are known to already be zero.
816718334Speter     Thus, if the AND isn't needed at all, we will have CONSTOP == NONZERO_BITS
816818334Speter     which is tested below.  */
816918334Speter
817018334Speter  constop &= nonzero;
817118334Speter
817218334Speter  /* If we don't have any bits left, return zero.  */
817318334Speter  if (constop == 0)
817418334Speter    return const0_rtx;
817518334Speter
817618334Speter  /* If VAROP is a NEG of something known to be zero or 1 and CONSTOP is
8177117395Skan     a power of two, we can replace this with an ASHIFT.  */
817818334Speter  if (GET_CODE (varop) == NEG && nonzero_bits (XEXP (varop, 0), mode) == 1
817918334Speter      && (i = exact_log2 (constop)) >= 0)
818018334Speter    return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (varop, 0), i);
818190075Sobrien
818218334Speter  /* If VAROP is an IOR or XOR, apply the AND to both branches of the IOR
818318334Speter     or XOR, then try to apply the distributive law.  This may eliminate
818418334Speter     operations if either branch can be simplified because of the AND.
818518334Speter     It may also make some cases more complex, but those cases probably
818618334Speter     won't match a pattern either with or without this.  */
818718334Speter
818818334Speter  if (GET_CODE (varop) == IOR || GET_CODE (varop) == XOR)
818918334Speter    return
8190169689Skan      gen_lowpart
819118334Speter	(mode,
819218334Speter	 apply_distributive_law
8193169689Skan	 (simplify_gen_binary (GET_CODE (varop), GET_MODE (varop),
8194169689Skan			       simplify_and_const_int (NULL_RTX,
8195169689Skan						       GET_MODE (varop),
8196169689Skan						       XEXP (varop, 0),
8197169689Skan						       constop),
8198169689Skan			       simplify_and_const_int (NULL_RTX,
8199169689Skan						       GET_MODE (varop),
8200169689Skan						       XEXP (varop, 1),
8201169689Skan						       constop))));
820218334Speter
8203169689Skan  /* If VAROP is PLUS, and the constant is a mask of low bits, distribute
820490075Sobrien     the AND and see if one of the operands simplifies to zero.  If so, we
820590075Sobrien     may eliminate it.  */
820690075Sobrien
820790075Sobrien  if (GET_CODE (varop) == PLUS
820890075Sobrien      && exact_log2 (constop + 1) >= 0)
820990075Sobrien    {
821090075Sobrien      rtx o0, o1;
821190075Sobrien
821290075Sobrien      o0 = simplify_and_const_int (NULL_RTX, mode, XEXP (varop, 0), constop);
821390075Sobrien      o1 = simplify_and_const_int (NULL_RTX, mode, XEXP (varop, 1), constop);
821490075Sobrien      if (o0 == const0_rtx)
821590075Sobrien	return o1;
821690075Sobrien      if (o1 == const0_rtx)
821790075Sobrien	return o0;
821890075Sobrien    }
821990075Sobrien
8220169689Skan  /* Make a SUBREG if necessary.  If we can't make it, fail.  */
8221169689Skan  varop = gen_lowpart (mode, varop);
8222169689Skan  if (varop == NULL_RTX || GET_CODE (varop) == CLOBBER)
8223169689Skan    return NULL_RTX;
822418334Speter
822518334Speter  /* If we are only masking insignificant bits, return VAROP.  */
822618334Speter  if (constop == nonzero)
8227169689Skan    return varop;
822818334Speter
8229169689Skan  if (varop == orig_varop && constop == orig_constop)
8230169689Skan    return NULL_RTX;
823190075Sobrien
8232169689Skan  /* Otherwise, return an AND.  */
8233169689Skan  return simplify_gen_binary (AND, mode, varop, gen_int_mode (constop, mode));
823418334Speter}
8235117395Skan
8236117395Skan
8237169689Skan/* We have X, a logical `and' of VAROP with the constant CONSTOP, to be done
8238169689Skan   in MODE.
8239117395Skan
8240169689Skan   Return an equivalent form, if different from X.  Otherwise, return X.  If
8241169689Skan   X is zero, we are to always construct the equivalent form.  */
8242117395Skan
8243169689Skanstatic rtx
8244169689Skansimplify_and_const_int (rtx x, enum machine_mode mode, rtx varop,
8245169689Skan			unsigned HOST_WIDE_INT constop)
8246169689Skan{
8247169689Skan  rtx tem = simplify_and_const_int_1 (mode, varop, constop);
8248169689Skan  if (tem)
8249169689Skan    return tem;
8250117395Skan
8251169689Skan  if (!x)
8252169689Skan    x = simplify_gen_binary (AND, GET_MODE (varop), varop,
8253169689Skan			     gen_int_mode (constop, mode));
8254169689Skan  if (GET_MODE (x) != mode)
8255169689Skan    x = gen_lowpart (mode, x);
8256169689Skan  return x;
8257117395Skan}
8258169689Skan
8259169689Skan/* Given a REG, X, compute which bits in X can be nonzero.
826018334Speter   We don't care about bits outside of those defined in MODE.
826118334Speter
826218334Speter   For most X this is simply GET_MODE_MASK (GET_MODE (MODE)), but if X is
826318334Speter   a shift, AND, or zero_extract, we can do better.  */
826418334Speter
8265169689Skanstatic rtx
8266169689Skanreg_nonzero_bits_for_combine (rtx x, enum machine_mode mode,
8267169689Skan			      rtx known_x ATTRIBUTE_UNUSED,
8268169689Skan			      enum machine_mode known_mode ATTRIBUTE_UNUSED,
8269169689Skan			      unsigned HOST_WIDE_INT known_ret ATTRIBUTE_UNUSED,
8270169689Skan			      unsigned HOST_WIDE_INT *nonzero)
827118334Speter{
827218334Speter  rtx tem;
827318334Speter
8274169689Skan  /* If X is a register whose nonzero bits value is current, use it.
8275169689Skan     Otherwise, if X is a register whose value we can find, use that
8276169689Skan     value.  Otherwise, use the previously-computed global nonzero bits
8277169689Skan     for this register.  */
827818334Speter
8279169689Skan  if (reg_stat[REGNO (x)].last_set_value != 0
8280169689Skan      && (reg_stat[REGNO (x)].last_set_mode == mode
8281169689Skan	  || (GET_MODE_CLASS (reg_stat[REGNO (x)].last_set_mode) == MODE_INT
8282169689Skan	      && GET_MODE_CLASS (mode) == MODE_INT))
8283169689Skan      && (reg_stat[REGNO (x)].last_set_label == label_tick
8284169689Skan	  || (REGNO (x) >= FIRST_PSEUDO_REGISTER
8285169689Skan	      && REG_N_SETS (REGNO (x)) == 1
8286169689Skan	      && ! REGNO_REG_SET_P
8287169689Skan		 (ENTRY_BLOCK_PTR->next_bb->il.rtl->global_live_at_start,
8288169689Skan		  REGNO (x))))
8289169689Skan      && INSN_CUID (reg_stat[REGNO (x)].last_set) < subst_low_cuid)
829018334Speter    {
8291169689Skan      *nonzero &= reg_stat[REGNO (x)].last_set_nonzero_bits;
8292169689Skan      return NULL;
829318334Speter    }
829418334Speter
8295169689Skan  tem = get_last_value (x);
829618334Speter
8297169689Skan  if (tem)
829818334Speter    {
829918334Speter#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
8300169689Skan      /* If X is narrower than MODE and TEM is a non-negative
8301169689Skan	 constant that would appear negative in the mode of X,
8302169689Skan	 sign-extend it for use in reg_nonzero_bits because some
8303169689Skan	 machines (maybe most) will actually do the sign-extension
8304169689Skan	 and this is the conservative approach.
830518334Speter
8306169689Skan	 ??? For 2.5, try to tighten up the MD files in this regard
8307169689Skan	 instead of this kludge.  */
830818334Speter
8309169689Skan      if (GET_MODE_BITSIZE (GET_MODE (x)) < GET_MODE_BITSIZE (mode)
8310169689Skan	  && GET_CODE (tem) == CONST_INT
8311169689Skan	  && INTVAL (tem) > 0
8312169689Skan	  && 0 != (INTVAL (tem)
8313169689Skan		   & ((HOST_WIDE_INT) 1
8314169689Skan		      << (GET_MODE_BITSIZE (GET_MODE (x)) - 1))))
8315169689Skan	tem = GEN_INT (INTVAL (tem)
8316169689Skan		       | ((HOST_WIDE_INT) (-1)
8317169689Skan			  << GET_MODE_BITSIZE (GET_MODE (x))));
831818334Speter#endif
8319169689Skan      return tem;
832018334Speter    }
8321169689Skan  else if (nonzero_sign_valid && reg_stat[REGNO (x)].nonzero_bits)
8322117395Skan    {
8323169689Skan      unsigned HOST_WIDE_INT mask = reg_stat[REGNO (x)].nonzero_bits;
8324117395Skan
8325169689Skan      if (GET_MODE_BITSIZE (GET_MODE (x)) < GET_MODE_BITSIZE (mode))
8326169689Skan	/* We don't know anything about the upper bits.  */
8327169689Skan	mask |= GET_MODE_MASK (mode) ^ GET_MODE_MASK (GET_MODE (x));
8328169689Skan      *nonzero &= mask;
8329117395Skan    }
8330117395Skan
8331169689Skan  return NULL;
8332117395Skan}
8333117395Skan
833418334Speter/* Return the number of bits at the high-order end of X that are known to
833518334Speter   be equal to the sign bit.  X will be used in mode MODE; if MODE is
833618334Speter   VOIDmode, X will be used in its own mode.  The returned value  will always
833718334Speter   be between 1 and the number of bits in MODE.  */
833818334Speter
8339169689Skanstatic rtx
8340169689Skanreg_num_sign_bit_copies_for_combine (rtx x, enum machine_mode mode,
8341169689Skan				     rtx known_x ATTRIBUTE_UNUSED,
8342169689Skan				     enum machine_mode known_mode
8343169689Skan				     ATTRIBUTE_UNUSED,
8344169689Skan				     unsigned int known_ret ATTRIBUTE_UNUSED,
8345169689Skan				     unsigned int *result)
834618334Speter{
834718334Speter  rtx tem;
834818334Speter
8349169689Skan  if (reg_stat[REGNO (x)].last_set_value != 0
8350169689Skan      && reg_stat[REGNO (x)].last_set_mode == mode
8351169689Skan      && (reg_stat[REGNO (x)].last_set_label == label_tick
8352169689Skan	  || (REGNO (x) >= FIRST_PSEUDO_REGISTER
8353169689Skan	      && REG_N_SETS (REGNO (x)) == 1
8354169689Skan	      && ! REGNO_REG_SET_P
8355169689Skan		 (ENTRY_BLOCK_PTR->next_bb->il.rtl->global_live_at_start,
8356169689Skan		  REGNO (x))))
8357169689Skan      && INSN_CUID (reg_stat[REGNO (x)].last_set) < subst_low_cuid)
835890075Sobrien    {
8359169689Skan      *result = reg_stat[REGNO (x)].last_set_sign_bit_copies;
8360169689Skan      return NULL;
836190075Sobrien    }
836290075Sobrien
8363169689Skan  tem = get_last_value (x);
8364169689Skan  if (tem != 0)
8365169689Skan    return tem;
836618334Speter
8367169689Skan  if (nonzero_sign_valid && reg_stat[REGNO (x)].sign_bit_copies != 0
8368169689Skan      && GET_MODE_BITSIZE (GET_MODE (x)) == GET_MODE_BITSIZE (mode))
8369169689Skan    *result = reg_stat[REGNO (x)].sign_bit_copies;
837018334Speter
8371169689Skan  return NULL;
837218334Speter}
837318334Speter
837418334Speter/* Return the number of "extended" bits there are in X, when interpreted
837518334Speter   as a quantity in MODE whose signedness is indicated by UNSIGNEDP.  For
837618334Speter   unsigned quantities, this is the number of high-order zero bits.
837718334Speter   For signed quantities, this is the number of copies of the sign bit
837818334Speter   minus 1.  In both case, this function returns the number of "spare"
837918334Speter   bits.  For example, if two quantities for which this function returns
838018334Speter   at least 1 are added, the addition is known not to overflow.
838118334Speter
838218334Speter   This function will always return 0 unless called during combine, which
838318334Speter   implies that it must be called from a define_split.  */
838418334Speter
838590075Sobrienunsigned int
8386132718Skanextended_count (rtx x, enum machine_mode mode, int unsignedp)
838718334Speter{
838818334Speter  if (nonzero_sign_valid == 0)
838918334Speter    return 0;
839018334Speter
839118334Speter  return (unsignedp
839218334Speter	  ? (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
8393117395Skan	     ? (unsigned int) (GET_MODE_BITSIZE (mode) - 1
8394117395Skan			       - floor_log2 (nonzero_bits (x, mode)))
839590075Sobrien	     : 0)
839618334Speter	  : num_sign_bit_copies (x, mode) - 1);
839718334Speter}
839818334Speter
839918334Speter/* This function is called from `simplify_shift_const' to merge two
840018334Speter   outer operations.  Specifically, we have already found that we need
840118334Speter   to perform operation *POP0 with constant *PCONST0 at the outermost
840218334Speter   position.  We would now like to also perform OP1 with constant CONST1
840318334Speter   (with *POP0 being done last).
840418334Speter
840518334Speter   Return 1 if we can do the operation and update *POP0 and *PCONST0 with
840690075Sobrien   the resulting operation.  *PCOMP_P is set to 1 if we would need to
840718334Speter   complement the innermost operand, otherwise it is unchanged.
840818334Speter
840918334Speter   MODE is the mode in which the operation will be done.  No bits outside
841018334Speter   the width of this mode matter.  It is assumed that the width of this mode
841118334Speter   is smaller than or equal to HOST_BITS_PER_WIDE_INT.
841218334Speter
8413169689Skan   If *POP0 or OP1 are UNKNOWN, it means no operation is required.  Only NEG, PLUS,
841418334Speter   IOR, XOR, and AND are supported.  We may set *POP0 to SET if the proper
841518334Speter   result is simply *PCONST0.
841618334Speter
841718334Speter   If the resulting operation cannot be expressed as one operation, we
841818334Speter   return 0 and do not change *POP0, *PCONST0, and *PCOMP_P.  */
841918334Speter
842018334Speterstatic int
8421132718Skanmerge_outer_ops (enum rtx_code *pop0, HOST_WIDE_INT *pconst0, enum rtx_code op1, HOST_WIDE_INT const1, enum machine_mode mode, int *pcomp_p)
842218334Speter{
842318334Speter  enum rtx_code op0 = *pop0;
842418334Speter  HOST_WIDE_INT const0 = *pconst0;
842518334Speter
842618334Speter  const0 &= GET_MODE_MASK (mode);
842718334Speter  const1 &= GET_MODE_MASK (mode);
842818334Speter
842918334Speter  /* If OP0 is an AND, clear unimportant bits in CONST1.  */
843018334Speter  if (op0 == AND)
843118334Speter    const1 &= const0;
843218334Speter
8433169689Skan  /* If OP0 or OP1 is UNKNOWN, this is easy.  Similarly if they are the same or
843418334Speter     if OP0 is SET.  */
843518334Speter
8436169689Skan  if (op1 == UNKNOWN || op0 == SET)
843718334Speter    return 1;
843818334Speter
8439169689Skan  else if (op0 == UNKNOWN)
844018334Speter    op0 = op1, const0 = const1;
844118334Speter
844218334Speter  else if (op0 == op1)
844318334Speter    {
844418334Speter      switch (op0)
844518334Speter	{
844618334Speter	case AND:
844718334Speter	  const0 &= const1;
844818334Speter	  break;
844918334Speter	case IOR:
845018334Speter	  const0 |= const1;
845118334Speter	  break;
845218334Speter	case XOR:
845318334Speter	  const0 ^= const1;
845418334Speter	  break;
845518334Speter	case PLUS:
845618334Speter	  const0 += const1;
845718334Speter	  break;
845818334Speter	case NEG:
8459169689Skan	  op0 = UNKNOWN;
846018334Speter	  break;
846150397Sobrien	default:
846250397Sobrien	  break;
846318334Speter	}
846418334Speter    }
846518334Speter
846618334Speter  /* Otherwise, if either is a PLUS or NEG, we can't do anything.  */
846718334Speter  else if (op0 == PLUS || op1 == PLUS || op0 == NEG || op1 == NEG)
846818334Speter    return 0;
846918334Speter
847018334Speter  /* If the two constants aren't the same, we can't do anything.  The
847118334Speter     remaining six cases can all be done.  */
847218334Speter  else if (const0 != const1)
847318334Speter    return 0;
847418334Speter
847518334Speter  else
847618334Speter    switch (op0)
847718334Speter      {
847818334Speter      case IOR:
847918334Speter	if (op1 == AND)
848018334Speter	  /* (a & b) | b == b */
848118334Speter	  op0 = SET;
848218334Speter	else /* op1 == XOR */
848318334Speter	  /* (a ^ b) | b == a | b */
848450397Sobrien	  {;}
848518334Speter	break;
848618334Speter
848718334Speter      case XOR:
848818334Speter	if (op1 == AND)
848918334Speter	  /* (a & b) ^ b == (~a) & b */
849018334Speter	  op0 = AND, *pcomp_p = 1;
849118334Speter	else /* op1 == IOR */
849218334Speter	  /* (a | b) ^ b == a & ~b */
8493132718Skan	  op0 = AND, const0 = ~const0;
849418334Speter	break;
849518334Speter
849618334Speter      case AND:
849718334Speter	if (op1 == IOR)
849818334Speter	  /* (a | b) & b == b */
849918334Speter	op0 = SET;
850018334Speter	else /* op1 == XOR */
850118334Speter	  /* (a ^ b) & b) == (~a) & b */
850218334Speter	  *pcomp_p = 1;
850318334Speter	break;
850450397Sobrien      default:
850550397Sobrien	break;
850618334Speter      }
850718334Speter
850818334Speter  /* Check for NO-OP cases.  */
850918334Speter  const0 &= GET_MODE_MASK (mode);
851018334Speter  if (const0 == 0
851118334Speter      && (op0 == IOR || op0 == XOR || op0 == PLUS))
8512169689Skan    op0 = UNKNOWN;
851318334Speter  else if (const0 == 0 && op0 == AND)
851418334Speter    op0 = SET;
851552284Sobrien  else if ((unsigned HOST_WIDE_INT) const0 == GET_MODE_MASK (mode)
851652284Sobrien	   && op0 == AND)
8517169689Skan    op0 = UNKNOWN;
851818334Speter
851990075Sobrien  /* ??? Slightly redundant with the above mask, but not entirely.
852090075Sobrien     Moving this above means we'd have to sign-extend the mode mask
852190075Sobrien     for the final test.  */
852290075Sobrien  const0 = trunc_int_for_mode (const0, mode);
852318334Speter
852418334Speter  *pop0 = op0;
852518334Speter  *pconst0 = const0;
852618334Speter
852718334Speter  return 1;
852818334Speter}
852918334Speter
853018334Speter/* Simplify a shift of VAROP by COUNT bits.  CODE says what kind of shift.
8531169689Skan   The result of the shift is RESULT_MODE.  Return NULL_RTX if we cannot
8532169689Skan   simplify it.  Otherwise, return a simplified value.
853318334Speter
853418334Speter   The shift is normally computed in the widest mode we find in VAROP, as
853518334Speter   long as it isn't a different number of words than RESULT_MODE.  Exceptions
8536169689Skan   are ASHIFTRT and ROTATE, which are always done in their original mode.  */
853718334Speter
853818334Speterstatic rtx
8539169689Skansimplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
8540169689Skan			rtx varop, int orig_count)
854118334Speter{
854218334Speter  enum rtx_code orig_code = code;
8543169689Skan  rtx orig_varop = varop;
8544169689Skan  int count;
854518334Speter  enum machine_mode mode = result_mode;
854618334Speter  enum machine_mode shift_mode, tmode;
854790075Sobrien  unsigned int mode_words
854818334Speter    = (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
854918334Speter  /* We form (outer_op (code varop count) (outer_const)).  */
8550169689Skan  enum rtx_code outer_op = UNKNOWN;
855118334Speter  HOST_WIDE_INT outer_const = 0;
855218334Speter  int complement_p = 0;
8553169689Skan  rtx new, x;
855418334Speter
855590075Sobrien  /* Make sure and truncate the "natural" shift on the way in.  We don't
855690075Sobrien     want to do this inside the loop as it makes it more difficult to
855790075Sobrien     combine shifts.  */
855890075Sobrien  if (SHIFT_COUNT_TRUNCATED)
855990075Sobrien    orig_count &= GET_MODE_BITSIZE (mode) - 1;
856090075Sobrien
856118334Speter  /* If we were given an invalid count, don't do anything except exactly
856218334Speter     what was requested.  */
856318334Speter
856490075Sobrien  if (orig_count < 0 || orig_count >= (int) GET_MODE_BITSIZE (mode))
8565169689Skan    return NULL_RTX;
856618334Speter
856790075Sobrien  count = orig_count;
856890075Sobrien
856918334Speter  /* Unless one of the branches of the `if' in this loop does a `continue',
857018334Speter     we will `break' the loop after the `if'.  */
857118334Speter
857218334Speter  while (count != 0)
857318334Speter    {
8574169689Skan      /* If we have an operand of (clobber (const_int 0)), fail.  */
857518334Speter      if (GET_CODE (varop) == CLOBBER)
8576169689Skan	return NULL_RTX;
857718334Speter
857818334Speter      /* If we discovered we had to complement VAROP, leave.  Making a NOT
857918334Speter	 here would cause an infinite loop.  */
858018334Speter      if (complement_p)
858118334Speter	break;
858218334Speter
858318334Speter      /* Convert ROTATERT to ROTATE.  */
858418334Speter      if (code == ROTATERT)
8585117395Skan	{
8586117395Skan	  unsigned int bitsize = GET_MODE_BITSIZE (result_mode);;
8587117395Skan	  code = ROTATE;
8588117395Skan	  if (VECTOR_MODE_P (result_mode))
8589117395Skan	    count = bitsize / GET_MODE_NUNITS (result_mode) - count;
8590117395Skan	  else
8591117395Skan	    count = bitsize - count;
8592117395Skan	}
859318334Speter
859418334Speter      /* We need to determine what mode we will do the shift in.  If the
859518334Speter	 shift is a right shift or a ROTATE, we must always do it in the mode
859618334Speter	 it was originally done in.  Otherwise, we can do it in MODE, the
859750397Sobrien	 widest mode encountered.  */
859818334Speter      shift_mode
859918334Speter	= (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE
860018334Speter	   ? result_mode : mode);
860118334Speter
860218334Speter      /* Handle cases where the count is greater than the size of the mode
860318334Speter	 minus 1.  For ASHIFT, use the size minus one as the count (this can
860418334Speter	 occur when simplifying (lshiftrt (ashiftrt ..))).  For rotates,
860518334Speter	 take the count modulo the size.  For other shifts, the result is
860618334Speter	 zero.
860718334Speter
860818334Speter	 Since these shifts are being produced by the compiler by combining
860918334Speter	 multiple operations, each of which are defined, we know what the
861018334Speter	 result is supposed to be.  */
861190075Sobrien
8612169689Skan      if (count > (GET_MODE_BITSIZE (shift_mode) - 1))
861318334Speter	{
861418334Speter	  if (code == ASHIFTRT)
861518334Speter	    count = GET_MODE_BITSIZE (shift_mode) - 1;
861618334Speter	  else if (code == ROTATE || code == ROTATERT)
861718334Speter	    count %= GET_MODE_BITSIZE (shift_mode);
861818334Speter	  else
861918334Speter	    {
862018334Speter	      /* We can't simply return zero because there may be an
862118334Speter		 outer op.  */
862218334Speter	      varop = const0_rtx;
862318334Speter	      count = 0;
862418334Speter	      break;
862518334Speter	    }
862618334Speter	}
862718334Speter
862818334Speter      /* An arithmetic right shift of a quantity known to be -1 or 0
862918334Speter	 is a no-op.  */
863018334Speter      if (code == ASHIFTRT
863118334Speter	  && (num_sign_bit_copies (varop, shift_mode)
863218334Speter	      == GET_MODE_BITSIZE (shift_mode)))
863318334Speter	{
863418334Speter	  count = 0;
863518334Speter	  break;
863618334Speter	}
863718334Speter
863818334Speter      /* If we are doing an arithmetic right shift and discarding all but
863918334Speter	 the sign bit copies, this is equivalent to doing a shift by the
864018334Speter	 bitsize minus one.  Convert it into that shift because it will often
864118334Speter	 allow other simplifications.  */
864218334Speter
864318334Speter      if (code == ASHIFTRT
864418334Speter	  && (count + num_sign_bit_copies (varop, shift_mode)
864518334Speter	      >= GET_MODE_BITSIZE (shift_mode)))
864618334Speter	count = GET_MODE_BITSIZE (shift_mode) - 1;
864718334Speter
864818334Speter      /* We simplify the tests below and elsewhere by converting
864918334Speter	 ASHIFTRT to LSHIFTRT if we know the sign bit is clear.
8650117395Skan	 `make_compound_operation' will convert it to an ASHIFTRT for
8651117395Skan	 those machines (such as VAX) that don't have an LSHIFTRT.  */
865218334Speter      if (GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT
865318334Speter	  && code == ASHIFTRT
865418334Speter	  && ((nonzero_bits (varop, shift_mode)
865518334Speter	       & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (shift_mode) - 1)))
865618334Speter	      == 0))
865718334Speter	code = LSHIFTRT;
865818334Speter
8659169689Skan      if (((code == LSHIFTRT
8660169689Skan	    && GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT
8661169689Skan	    && !(nonzero_bits (varop, shift_mode) >> count))
8662169689Skan	   || (code == ASHIFT
8663169689Skan	       && GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT
8664169689Skan	       && !((nonzero_bits (varop, shift_mode) << count)
8665169689Skan		    & GET_MODE_MASK (shift_mode))))
8666169689Skan	  && !side_effects_p (varop))
8667132718Skan	varop = const0_rtx;
8668132718Skan
866918334Speter      switch (GET_CODE (varop))
867018334Speter	{
867118334Speter	case SIGN_EXTEND:
867218334Speter	case ZERO_EXTEND:
867318334Speter	case SIGN_EXTRACT:
867418334Speter	case ZERO_EXTRACT:
867518334Speter	  new = expand_compound_operation (varop);
867618334Speter	  if (new != varop)
867718334Speter	    {
867818334Speter	      varop = new;
867918334Speter	      continue;
868018334Speter	    }
868118334Speter	  break;
868218334Speter
868318334Speter	case MEM:
868418334Speter	  /* If we have (xshiftrt (mem ...) C) and C is MODE_WIDTH
868518334Speter	     minus the width of a smaller mode, we can do this with a
868618334Speter	     SIGN_EXTEND or ZERO_EXTEND from the narrower memory location.  */
868718334Speter	  if ((code == ASHIFTRT || code == LSHIFTRT)
868818334Speter	      && ! mode_dependent_address_p (XEXP (varop, 0))
868918334Speter	      && ! MEM_VOLATILE_P (varop)
869018334Speter	      && (tmode = mode_for_size (GET_MODE_BITSIZE (mode) - count,
869118334Speter					 MODE_INT, 1)) != BLKmode)
869218334Speter	    {
869390075Sobrien	      new = adjust_address_nv (varop, tmode,
869490075Sobrien				       BYTES_BIG_ENDIAN ? 0
869590075Sobrien				       : count / BITS_PER_UNIT);
869690075Sobrien
869790075Sobrien	      varop = gen_rtx_fmt_e (code == ASHIFTRT ? SIGN_EXTEND
869890075Sobrien				     : ZERO_EXTEND, mode, new);
869918334Speter	      count = 0;
870018334Speter	      continue;
870118334Speter	    }
870218334Speter	  break;
870318334Speter
870418334Speter	case SUBREG:
870518334Speter	  /* If VAROP is a SUBREG, strip it as long as the inner operand has
870618334Speter	     the same number of words as what we've seen so far.  Then store
870718334Speter	     the widest mode in MODE.  */
870818334Speter	  if (subreg_lowpart_p (varop)
870918334Speter	      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (varop)))
871018334Speter		  > GET_MODE_SIZE (GET_MODE (varop)))
8711117395Skan	      && (unsigned int) ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (varop)))
8712117395Skan				  + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
8713117395Skan		 == mode_words)
871418334Speter	    {
871518334Speter	      varop = SUBREG_REG (varop);
871618334Speter	      if (GET_MODE_SIZE (GET_MODE (varop)) > GET_MODE_SIZE (mode))
871718334Speter		mode = GET_MODE (varop);
871818334Speter	      continue;
871918334Speter	    }
872018334Speter	  break;
872118334Speter
872218334Speter	case MULT:
872318334Speter	  /* Some machines use MULT instead of ASHIFT because MULT
872418334Speter	     is cheaper.  But it is still better on those machines to
872518334Speter	     merge two shifts into one.  */
872618334Speter	  if (GET_CODE (XEXP (varop, 1)) == CONST_INT
872718334Speter	      && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
872818334Speter	    {
872990075Sobrien	      varop
8730169689Skan		= simplify_gen_binary (ASHIFT, GET_MODE (varop),
8731169689Skan				       XEXP (varop, 0),
8732169689Skan				       GEN_INT (exact_log2 (
8733169689Skan						INTVAL (XEXP (varop, 1)))));
873418334Speter	      continue;
873518334Speter	    }
873618334Speter	  break;
873718334Speter
873818334Speter	case UDIV:
873918334Speter	  /* Similar, for when divides are cheaper.  */
874018334Speter	  if (GET_CODE (XEXP (varop, 1)) == CONST_INT
874118334Speter	      && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
874218334Speter	    {
874390075Sobrien	      varop
8744169689Skan		= simplify_gen_binary (LSHIFTRT, GET_MODE (varop),
8745169689Skan				       XEXP (varop, 0),
8746169689Skan				       GEN_INT (exact_log2 (
8747169689Skan						INTVAL (XEXP (varop, 1)))));
874818334Speter	      continue;
874918334Speter	    }
875018334Speter	  break;
875118334Speter
875218334Speter	case ASHIFTRT:
875390075Sobrien	  /* If we are extracting just the sign bit of an arithmetic
875490075Sobrien	     right shift, that shift is not needed.  However, the sign
875590075Sobrien	     bit of a wider mode may be different from what would be
875690075Sobrien	     interpreted as the sign bit in a narrower mode, so, if
875790075Sobrien	     the result is narrower, don't discard the shift.  */
8758117395Skan	  if (code == LSHIFTRT
8759169689Skan	      && count == (GET_MODE_BITSIZE (result_mode) - 1)
876090075Sobrien	      && (GET_MODE_BITSIZE (result_mode)
876190075Sobrien		  >= GET_MODE_BITSIZE (GET_MODE (varop))))
876218334Speter	    {
876318334Speter	      varop = XEXP (varop, 0);
876418334Speter	      continue;
876518334Speter	    }
876618334Speter
876750397Sobrien	  /* ... fall through ...  */
876818334Speter
876918334Speter	case LSHIFTRT:
877018334Speter	case ASHIFT:
877118334Speter	case ROTATE:
877218334Speter	  /* Here we have two nested shifts.  The result is usually the
877318334Speter	     AND of a new shift with a mask.  We compute the result below.  */
877418334Speter	  if (GET_CODE (XEXP (varop, 1)) == CONST_INT
877518334Speter	      && INTVAL (XEXP (varop, 1)) >= 0
877618334Speter	      && INTVAL (XEXP (varop, 1)) < GET_MODE_BITSIZE (GET_MODE (varop))
877718334Speter	      && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT
8778169689Skan	      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
8779169689Skan	      && !VECTOR_MODE_P (result_mode))
878018334Speter	    {
878118334Speter	      enum rtx_code first_code = GET_CODE (varop);
878290075Sobrien	      unsigned int first_count = INTVAL (XEXP (varop, 1));
878318334Speter	      unsigned HOST_WIDE_INT mask;
878418334Speter	      rtx mask_rtx;
878518334Speter
878618334Speter	      /* We have one common special case.  We can't do any merging if
878718334Speter		 the inner code is an ASHIFTRT of a smaller mode.  However, if
878818334Speter		 we have (ashift:M1 (subreg:M1 (ashiftrt:M2 FOO C1) 0) C2)
878918334Speter		 with C2 == GET_MODE_BITSIZE (M1) - GET_MODE_BITSIZE (M2),
879018334Speter		 we can convert it to
879118334Speter		 (ashiftrt:M1 (ashift:M1 (and:M1 (subreg:M1 FOO 0 C2) C3) C1).
879218334Speter		 This simplifies certain SIGN_EXTEND operations.  */
879318334Speter	      if (code == ASHIFT && first_code == ASHIFTRT
8794169689Skan		  && count == (GET_MODE_BITSIZE (result_mode)
8795117395Skan			       - GET_MODE_BITSIZE (GET_MODE (varop))))
879618334Speter		{
879718334Speter		  /* C3 has the low-order C1 bits zero.  */
879890075Sobrien
879918334Speter		  mask = (GET_MODE_MASK (mode)
880090075Sobrien			  & ~(((HOST_WIDE_INT) 1 << first_count) - 1));
880118334Speter
880218334Speter		  varop = simplify_and_const_int (NULL_RTX, result_mode,
880318334Speter						  XEXP (varop, 0), mask);
880418334Speter		  varop = simplify_shift_const (NULL_RTX, ASHIFT, result_mode,
880518334Speter						varop, count);
880618334Speter		  count = first_count;
880718334Speter		  code = ASHIFTRT;
880818334Speter		  continue;
880918334Speter		}
881090075Sobrien
881118334Speter	      /* If this was (ashiftrt (ashift foo C1) C2) and FOO has more
881218334Speter		 than C1 high-order bits equal to the sign bit, we can convert
8813117395Skan		 this to either an ASHIFT or an ASHIFTRT depending on the
881490075Sobrien		 two counts.
881518334Speter
881618334Speter		 We cannot do this if VAROP's mode is not SHIFT_MODE.  */
881718334Speter
881818334Speter	      if (code == ASHIFTRT && first_code == ASHIFT
881918334Speter		  && GET_MODE (varop) == shift_mode
882018334Speter		  && (num_sign_bit_copies (XEXP (varop, 0), shift_mode)
882118334Speter		      > first_count))
882218334Speter		{
882318334Speter		  varop = XEXP (varop, 0);
8824169689Skan		  count -= first_count;
8825169689Skan		  if (count < 0)
8826169689Skan		    {
8827169689Skan		      count = -count;
8828169689Skan		      code = ASHIFT;
8829169689Skan		    }
883090075Sobrien
883118334Speter		  continue;
883218334Speter		}
883318334Speter
883418334Speter	      /* There are some cases we can't do.  If CODE is ASHIFTRT,
883518334Speter		 we can only do this if FIRST_CODE is also ASHIFTRT.
883618334Speter
883718334Speter		 We can't do the case when CODE is ROTATE and FIRST_CODE is
883818334Speter		 ASHIFTRT.
883918334Speter
884018334Speter		 If the mode of this shift is not the mode of the outer shift,
884118334Speter		 we can't do this if either shift is a right shift or ROTATE.
884218334Speter
884318334Speter		 Finally, we can't do any of these if the mode is too wide
884418334Speter		 unless the codes are the same.
884518334Speter
884618334Speter		 Handle the case where the shift codes are the same
884718334Speter		 first.  */
884818334Speter
884918334Speter	      if (code == first_code)
885018334Speter		{
885118334Speter		  if (GET_MODE (varop) != result_mode
885218334Speter		      && (code == ASHIFTRT || code == LSHIFTRT
885318334Speter			  || code == ROTATE))
885418334Speter		    break;
885518334Speter
885618334Speter		  count += first_count;
885718334Speter		  varop = XEXP (varop, 0);
885818334Speter		  continue;
885918334Speter		}
886018334Speter
886118334Speter	      if (code == ASHIFTRT
886218334Speter		  || (code == ROTATE && first_code == ASHIFTRT)
886318334Speter		  || GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT
886418334Speter		  || (GET_MODE (varop) != result_mode
886518334Speter		      && (first_code == ASHIFTRT || first_code == LSHIFTRT
886618334Speter			  || first_code == ROTATE
886718334Speter			  || code == ROTATE)))
886818334Speter		break;
886918334Speter
887018334Speter	      /* To compute the mask to apply after the shift, shift the
887190075Sobrien		 nonzero bits of the inner shift the same way the
887218334Speter		 outer shift will.  */
887318334Speter
887418334Speter	      mask_rtx = GEN_INT (nonzero_bits (varop, GET_MODE (varop)));
887518334Speter
887618334Speter	      mask_rtx
8877169689Skan		= simplify_const_binary_operation (code, result_mode, mask_rtx,
8878169689Skan						   GEN_INT (count));
887990075Sobrien
888018334Speter	      /* Give up if we can't compute an outer operation to use.  */
888118334Speter	      if (mask_rtx == 0
888218334Speter		  || GET_CODE (mask_rtx) != CONST_INT
888318334Speter		  || ! merge_outer_ops (&outer_op, &outer_const, AND,
888418334Speter					INTVAL (mask_rtx),
888518334Speter					result_mode, &complement_p))
888618334Speter		break;
888718334Speter
888818334Speter	      /* If the shifts are in the same direction, we add the
888918334Speter		 counts.  Otherwise, we subtract them.  */
889018334Speter	      if ((code == ASHIFTRT || code == LSHIFTRT)
889118334Speter		  == (first_code == ASHIFTRT || first_code == LSHIFTRT))
8892169689Skan		count += first_count;
889318334Speter	      else
8894169689Skan		count -= first_count;
889518334Speter
889690075Sobrien	      /* If COUNT is positive, the new shift is usually CODE,
889718334Speter		 except for the two exceptions below, in which case it is
889818334Speter		 FIRST_CODE.  If the count is negative, FIRST_CODE should
889918334Speter		 always be used  */
8900169689Skan	      if (count > 0
890118334Speter		  && ((first_code == ROTATE && code == ASHIFT)
890218334Speter		      || (first_code == ASHIFTRT && code == LSHIFTRT)))
8903169689Skan		code = first_code;
8904169689Skan	      else if (count < 0)
8905169689Skan		code = first_code, count = -count;
890618334Speter
890718334Speter	      varop = XEXP (varop, 0);
890818334Speter	      continue;
890918334Speter	    }
891018334Speter
891118334Speter	  /* If we have (A << B << C) for any shift, we can convert this to
891218334Speter	     (A << C << B).  This wins if A is a constant.  Only try this if
891318334Speter	     B is not a constant.  */
891418334Speter
891518334Speter	  else if (GET_CODE (varop) == code
8916169689Skan		   && GET_CODE (XEXP (varop, 0)) == CONST_INT
8917169689Skan		   && GET_CODE (XEXP (varop, 1)) != CONST_INT)
8918169689Skan	    {
8919169689Skan	      rtx new = simplify_const_binary_operation (code, mode,
892018334Speter							 XEXP (varop, 0),
8921169689Skan							 GEN_INT (count));
892290075Sobrien	      varop = gen_rtx_fmt_ee (code, mode, new, XEXP (varop, 1));
892318334Speter	      count = 0;
892418334Speter	      continue;
892518334Speter	    }
892618334Speter	  break;
892718334Speter
892818334Speter	case NOT:
892918334Speter	  /* Make this fit the case below.  */
893090075Sobrien	  varop = gen_rtx_XOR (mode, XEXP (varop, 0),
893190075Sobrien			       GEN_INT (GET_MODE_MASK (mode)));
893218334Speter	  continue;
893318334Speter
893418334Speter	case IOR:
893518334Speter	case AND:
893618334Speter	case XOR:
893718334Speter	  /* If we have (xshiftrt (ior (plus X (const_int -1)) X) C)
893818334Speter	     with C the size of VAROP - 1 and the shift is logical if
893918334Speter	     STORE_FLAG_VALUE is 1 and arithmetic if STORE_FLAG_VALUE is -1,
894018334Speter	     we have an (le X 0) operation.   If we have an arithmetic shift
894118334Speter	     and STORE_FLAG_VALUE is 1 or we have a logical shift with
894218334Speter	     STORE_FLAG_VALUE of -1, we have a (neg (le X 0)) operation.  */
894318334Speter
894418334Speter	  if (GET_CODE (varop) == IOR && GET_CODE (XEXP (varop, 0)) == PLUS
894518334Speter	      && XEXP (XEXP (varop, 0), 1) == constm1_rtx
894618334Speter	      && (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
894718334Speter	      && (code == LSHIFTRT || code == ASHIFTRT)
8948169689Skan	      && count == (GET_MODE_BITSIZE (GET_MODE (varop)) - 1)
894918334Speter	      && rtx_equal_p (XEXP (XEXP (varop, 0), 0), XEXP (varop, 1)))
895018334Speter	    {
895118334Speter	      count = 0;
895290075Sobrien	      varop = gen_rtx_LE (GET_MODE (varop), XEXP (varop, 1),
895390075Sobrien				  const0_rtx);
895418334Speter
895518334Speter	      if (STORE_FLAG_VALUE == 1 ? code == ASHIFTRT : code == LSHIFTRT)
895690075Sobrien		varop = gen_rtx_NEG (GET_MODE (varop), varop);
895718334Speter
895818334Speter	      continue;
895918334Speter	    }
896018334Speter
896118334Speter	  /* If we have (shift (logical)), move the logical to the outside
896218334Speter	     to allow it to possibly combine with another logical and the
896318334Speter	     shift to combine with another shift.  This also canonicalizes to
896418334Speter	     what a ZERO_EXTRACT looks like.  Also, some machines have
896518334Speter	     (and (shift)) insns.  */
896618334Speter
896718334Speter	  if (GET_CODE (XEXP (varop, 1)) == CONST_INT
8968169689Skan	      /* We can't do this if we have (ashiftrt (xor))  and the
8969169689Skan		 constant has its sign bit set in shift_mode.  */
8970169689Skan	      && !(code == ASHIFTRT && GET_CODE (varop) == XOR
8971169689Skan		   && 0 > trunc_int_for_mode (INTVAL (XEXP (varop, 1)),
8972169689Skan					      shift_mode))
8973169689Skan	      && (new = simplify_const_binary_operation (code, result_mode,
8974169689Skan							 XEXP (varop, 1),
8975169689Skan							 GEN_INT (count))) != 0
897690075Sobrien	      && GET_CODE (new) == CONST_INT
897718334Speter	      && merge_outer_ops (&outer_op, &outer_const, GET_CODE (varop),
897818334Speter				  INTVAL (new), result_mode, &complement_p))
897918334Speter	    {
898018334Speter	      varop = XEXP (varop, 0);
898118334Speter	      continue;
898218334Speter	    }
898318334Speter
898418334Speter	  /* If we can't do that, try to simplify the shift in each arm of the
898518334Speter	     logical expression, make a new logical expression, and apply
8986169689Skan	     the inverse distributive law.  This also can't be done
8987169689Skan	     for some (ashiftrt (xor)).  */
8988169689Skan	  if (GET_CODE (XEXP (varop, 1)) == CONST_INT
8989169689Skan	     && !(code == ASHIFTRT && GET_CODE (varop) == XOR
8990169689Skan		  && 0 > trunc_int_for_mode (INTVAL (XEXP (varop, 1)),
8991169689Skan					     shift_mode)))
8992169689Skan	    {
8993169689Skan	      rtx lhs = simplify_shift_const (NULL_RTX, code, shift_mode,
8994169689Skan					      XEXP (varop, 0), count);
8995169689Skan	      rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode,
8996169689Skan					      XEXP (varop, 1), count);
899718334Speter
8998169689Skan	      varop = simplify_gen_binary (GET_CODE (varop), shift_mode,
8999169689Skan					   lhs, rhs);
9000169689Skan	      varop = apply_distributive_law (varop);
900118334Speter
9002169689Skan	      count = 0;
9003169689Skan	      continue;
9004169689Skan	    }
900518334Speter	  break;
900618334Speter
900718334Speter	case EQ:
9008132718Skan	  /* Convert (lshiftrt (eq FOO 0) C) to (xor FOO 1) if STORE_FLAG_VALUE
900918334Speter	     says that the sign bit can be tested, FOO has mode MODE, C is
901018334Speter	     GET_MODE_BITSIZE (MODE) - 1, and FOO has only its low-order bit
901118334Speter	     that may be nonzero.  */
901218334Speter	  if (code == LSHIFTRT
901318334Speter	      && XEXP (varop, 1) == const0_rtx
901418334Speter	      && GET_MODE (XEXP (varop, 0)) == result_mode
9015169689Skan	      && count == (GET_MODE_BITSIZE (result_mode) - 1)
901618334Speter	      && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT
9017169689Skan	      && STORE_FLAG_VALUE == -1
901818334Speter	      && nonzero_bits (XEXP (varop, 0), result_mode) == 1
901918334Speter	      && merge_outer_ops (&outer_op, &outer_const, XOR,
902018334Speter				  (HOST_WIDE_INT) 1, result_mode,
902118334Speter				  &complement_p))
902218334Speter	    {
902318334Speter	      varop = XEXP (varop, 0);
902418334Speter	      count = 0;
902518334Speter	      continue;
902618334Speter	    }
902718334Speter	  break;
902818334Speter
902918334Speter	case NEG:
903018334Speter	  /* (lshiftrt (neg A) C) where A is either 0 or 1 and C is one less
903118334Speter	     than the number of bits in the mode is equivalent to A.  */
9032117395Skan	  if (code == LSHIFTRT
9033169689Skan	      && count == (GET_MODE_BITSIZE (result_mode) - 1)
903418334Speter	      && nonzero_bits (XEXP (varop, 0), result_mode) == 1)
903518334Speter	    {
903618334Speter	      varop = XEXP (varop, 0);
903718334Speter	      count = 0;
903818334Speter	      continue;
903918334Speter	    }
904018334Speter
904118334Speter	  /* NEG commutes with ASHIFT since it is multiplication.  Move the
904218334Speter	     NEG outside to allow shifts to combine.  */
904318334Speter	  if (code == ASHIFT
904418334Speter	      && merge_outer_ops (&outer_op, &outer_const, NEG,
904518334Speter				  (HOST_WIDE_INT) 0, result_mode,
904618334Speter				  &complement_p))
904718334Speter	    {
904818334Speter	      varop = XEXP (varop, 0);
904918334Speter	      continue;
905018334Speter	    }
905118334Speter	  break;
905218334Speter
905318334Speter	case PLUS:
905418334Speter	  /* (lshiftrt (plus A -1) C) where A is either 0 or 1 and C
905518334Speter	     is one less than the number of bits in the mode is
905618334Speter	     equivalent to (xor A 1).  */
9057117395Skan	  if (code == LSHIFTRT
9058169689Skan	      && count == (GET_MODE_BITSIZE (result_mode) - 1)
905918334Speter	      && XEXP (varop, 1) == constm1_rtx
906018334Speter	      && nonzero_bits (XEXP (varop, 0), result_mode) == 1
906118334Speter	      && merge_outer_ops (&outer_op, &outer_const, XOR,
906218334Speter				  (HOST_WIDE_INT) 1, result_mode,
906318334Speter				  &complement_p))
906418334Speter	    {
906518334Speter	      count = 0;
906618334Speter	      varop = XEXP (varop, 0);
906718334Speter	      continue;
906818334Speter	    }
906918334Speter
907018334Speter	  /* If we have (xshiftrt (plus FOO BAR) C), and the only bits
907118334Speter	     that might be nonzero in BAR are those being shifted out and those
907218334Speter	     bits are known zero in FOO, we can replace the PLUS with FOO.
907318334Speter	     Similarly in the other operand order.  This code occurs when
907418334Speter	     we are computing the size of a variable-size array.  */
907518334Speter
907618334Speter	  if ((code == ASHIFTRT || code == LSHIFTRT)
907718334Speter	      && count < HOST_BITS_PER_WIDE_INT
907818334Speter	      && nonzero_bits (XEXP (varop, 1), result_mode) >> count == 0
907918334Speter	      && (nonzero_bits (XEXP (varop, 1), result_mode)
908018334Speter		  & nonzero_bits (XEXP (varop, 0), result_mode)) == 0)
908118334Speter	    {
908218334Speter	      varop = XEXP (varop, 0);
908318334Speter	      continue;
908418334Speter	    }
908518334Speter	  else if ((code == ASHIFTRT || code == LSHIFTRT)
908618334Speter		   && count < HOST_BITS_PER_WIDE_INT
908718334Speter		   && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT
908818334Speter		   && 0 == (nonzero_bits (XEXP (varop, 0), result_mode)
908918334Speter			    >> count)
909018334Speter		   && 0 == (nonzero_bits (XEXP (varop, 0), result_mode)
909118334Speter			    & nonzero_bits (XEXP (varop, 1),
909218334Speter						 result_mode)))
909318334Speter	    {
909418334Speter	      varop = XEXP (varop, 1);
909518334Speter	      continue;
909618334Speter	    }
909718334Speter
909818334Speter	  /* (ashift (plus foo C) N) is (plus (ashift foo N) C').  */
909918334Speter	  if (code == ASHIFT
910018334Speter	      && GET_CODE (XEXP (varop, 1)) == CONST_INT
9101169689Skan	      && (new = simplify_const_binary_operation (ASHIFT, result_mode,
9102169689Skan							 XEXP (varop, 1),
9103169689Skan							 GEN_INT (count))) != 0
910490075Sobrien	      && GET_CODE (new) == CONST_INT
910518334Speter	      && merge_outer_ops (&outer_op, &outer_const, PLUS,
910618334Speter				  INTVAL (new), result_mode, &complement_p))
910718334Speter	    {
910818334Speter	      varop = XEXP (varop, 0);
910918334Speter	      continue;
911018334Speter	    }
9111169689Skan
9112169689Skan	  /* Check for 'PLUS signbit', which is the canonical form of 'XOR
9113169689Skan	     signbit', and attempt to change the PLUS to an XOR and move it to
9114169689Skan	     the outer operation as is done above in the AND/IOR/XOR case
9115169689Skan	     leg for shift(logical). See details in logical handling above
9116169689Skan	     for reasoning in doing so.  */
9117169689Skan	  if (code == LSHIFTRT
9118169689Skan	      && GET_CODE (XEXP (varop, 1)) == CONST_INT
9119169689Skan	      && mode_signbit_p (result_mode, XEXP (varop, 1))
9120169689Skan	      && (new = simplify_const_binary_operation (code, result_mode,
9121169689Skan							 XEXP (varop, 1),
9122169689Skan							 GEN_INT (count))) != 0
9123169689Skan	      && GET_CODE (new) == CONST_INT
9124169689Skan	      && merge_outer_ops (&outer_op, &outer_const, XOR,
9125169689Skan				  INTVAL (new), result_mode, &complement_p))
9126169689Skan	    {
9127169689Skan	      varop = XEXP (varop, 0);
9128169689Skan	      continue;
9129169689Skan	    }
9130169689Skan
913118334Speter	  break;
913218334Speter
913318334Speter	case MINUS:
913418334Speter	  /* If we have (xshiftrt (minus (ashiftrt X C)) X) C)
913518334Speter	     with C the size of VAROP - 1 and the shift is logical if
913618334Speter	     STORE_FLAG_VALUE is 1 and arithmetic if STORE_FLAG_VALUE is -1,
913718334Speter	     we have a (gt X 0) operation.  If the shift is arithmetic with
913818334Speter	     STORE_FLAG_VALUE of 1 or logical with STORE_FLAG_VALUE == -1,
913918334Speter	     we have a (neg (gt X 0)) operation.  */
914018334Speter
914150397Sobrien	  if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
914250397Sobrien	      && GET_CODE (XEXP (varop, 0)) == ASHIFTRT
9143169689Skan	      && count == (GET_MODE_BITSIZE (GET_MODE (varop)) - 1)
914418334Speter	      && (code == LSHIFTRT || code == ASHIFTRT)
914518334Speter	      && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT
9146169689Skan	      && INTVAL (XEXP (XEXP (varop, 0), 1)) == count
914718334Speter	      && rtx_equal_p (XEXP (XEXP (varop, 0), 0), XEXP (varop, 1)))
914818334Speter	    {
914918334Speter	      count = 0;
915090075Sobrien	      varop = gen_rtx_GT (GET_MODE (varop), XEXP (varop, 1),
915190075Sobrien				  const0_rtx);
915218334Speter
915318334Speter	      if (STORE_FLAG_VALUE == 1 ? code == ASHIFTRT : code == LSHIFTRT)
915490075Sobrien		varop = gen_rtx_NEG (GET_MODE (varop), varop);
915518334Speter
915618334Speter	      continue;
915718334Speter	    }
915818334Speter	  break;
915950397Sobrien
916050397Sobrien	case TRUNCATE:
916150397Sobrien	  /* Change (lshiftrt (truncate (lshiftrt))) to (truncate (lshiftrt))
916250397Sobrien	     if the truncate does not affect the value.  */
916350397Sobrien	  if (code == LSHIFTRT
916450397Sobrien	      && GET_CODE (XEXP (varop, 0)) == LSHIFTRT
916550397Sobrien	      && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT
916650397Sobrien	      && (INTVAL (XEXP (XEXP (varop, 0), 1))
916750397Sobrien		  >= (GET_MODE_BITSIZE (GET_MODE (XEXP (varop, 0)))
916850397Sobrien		      - GET_MODE_BITSIZE (GET_MODE (varop)))))
916950397Sobrien	    {
917050397Sobrien	      rtx varop_inner = XEXP (varop, 0);
917150397Sobrien
917290075Sobrien	      varop_inner
917390075Sobrien		= gen_rtx_LSHIFTRT (GET_MODE (varop_inner),
917490075Sobrien				    XEXP (varop_inner, 0),
917590075Sobrien				    GEN_INT
917690075Sobrien				    (count + INTVAL (XEXP (varop_inner, 1))));
917790075Sobrien	      varop = gen_rtx_TRUNCATE (GET_MODE (varop), varop_inner);
917850397Sobrien	      count = 0;
917950397Sobrien	      continue;
918050397Sobrien	    }
918150397Sobrien	  break;
918290075Sobrien
918350397Sobrien	default:
918450397Sobrien	  break;
918518334Speter	}
918618334Speter
918718334Speter      break;
918818334Speter    }
918918334Speter
919018334Speter  /* We need to determine what mode to do the shift in.  If the shift is
919118334Speter     a right shift or ROTATE, we must always do it in the mode it was
919218334Speter     originally done in.  Otherwise, we can do it in MODE, the widest mode
919318334Speter     encountered.  The code we care about is that of the shift that will
919418334Speter     actually be done, not the shift that was originally requested.  */
919518334Speter  shift_mode
919618334Speter    = (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE
919718334Speter       ? result_mode : mode);
919818334Speter
919918334Speter  /* We have now finished analyzing the shift.  The result should be
920018334Speter     a shift of type CODE with SHIFT_MODE shifting VAROP COUNT places.  If
9201169689Skan     OUTER_OP is non-UNKNOWN, it is an operation that needs to be applied
920218334Speter     to the result of the shift.  OUTER_CONST is the relevant constant,
9203169689Skan     but we must turn off all bits turned off in the shift.  */
920418334Speter
9205169689Skan  if (outer_op == UNKNOWN
9206169689Skan      && orig_code == code && orig_count == count
9207169689Skan      && varop == orig_varop
9208169689Skan      && shift_mode == GET_MODE (varop))
9209169689Skan    return NULL_RTX;
921018334Speter
9211169689Skan  /* Make a SUBREG if necessary.  If we can't make it, fail.  */
9212169689Skan  varop = gen_lowpart (shift_mode, varop);
9213169689Skan  if (varop == NULL_RTX || GET_CODE (varop) == CLOBBER)
9214169689Skan    return NULL_RTX;
921518334Speter
921618334Speter  /* If we have an outer operation and we just made a shift, it is
921718334Speter     possible that we could have simplified the shift were it not
921818334Speter     for the outer operation.  So try to do the simplification
921918334Speter     recursively.  */
922018334Speter
9221169689Skan  if (outer_op != UNKNOWN)
9222169689Skan    x = simplify_shift_const_1 (code, shift_mode, varop, count);
9223169689Skan  else
9224169689Skan    x = NULL_RTX;
922518334Speter
9226169689Skan  if (x == NULL_RTX)
9227169689Skan    x = simplify_gen_binary (code, shift_mode, varop, GEN_INT (count));
9228169689Skan
9229117395Skan  /* If we were doing an LSHIFTRT in a wider mode than it was originally,
923018334Speter     turn off all the bits that the shift would have turned off.  */
923118334Speter  if (orig_code == LSHIFTRT && result_mode != shift_mode)
923218334Speter    x = simplify_and_const_int (NULL_RTX, shift_mode, x,
923318334Speter				GET_MODE_MASK (result_mode) >> orig_count);
923490075Sobrien
923518334Speter  /* Do the remainder of the processing in RESULT_MODE.  */
9236169689Skan  x = gen_lowpart_or_truncate (result_mode, x);
923718334Speter
923818334Speter  /* If COMPLEMENT_P is set, we have to complement X before doing the outer
923918334Speter     operation.  */
924018334Speter  if (complement_p)
9241132718Skan    x = simplify_gen_unary (NOT, result_mode, x, result_mode);
924218334Speter
9243169689Skan  if (outer_op != UNKNOWN)
924418334Speter    {
924518334Speter      if (GET_MODE_BITSIZE (result_mode) < HOST_BITS_PER_WIDE_INT)
924690075Sobrien	outer_const = trunc_int_for_mode (outer_const, result_mode);
924718334Speter
924818334Speter      if (outer_op == AND)
924918334Speter	x = simplify_and_const_int (NULL_RTX, result_mode, x, outer_const);
925018334Speter      else if (outer_op == SET)
9251169689Skan	{
9252169689Skan	  /* This means that we have determined that the result is
9253169689Skan	     equivalent to a constant.  This should be rare.  */
9254169689Skan	  if (!side_effects_p (x))
9255169689Skan	    x = GEN_INT (outer_const);
9256169689Skan	}
9257169689Skan      else if (GET_RTX_CLASS (outer_op) == RTX_UNARY)
925890075Sobrien	x = simplify_gen_unary (outer_op, result_mode, x, result_mode);
925918334Speter      else
9260169689Skan	x = simplify_gen_binary (outer_op, result_mode, x,
9261169689Skan				 GEN_INT (outer_const));
926218334Speter    }
926318334Speter
926418334Speter  return x;
926590075Sobrien}
9266169689Skan
9267169689Skan/* Simplify a shift of VAROP by COUNT bits.  CODE says what kind of shift.
9268169689Skan   The result of the shift is RESULT_MODE.  If we cannot simplify it,
9269169689Skan   return X or, if it is NULL, synthesize the expression with
9270169689Skan   simplify_gen_binary.  Otherwise, return a simplified value.
9271169689Skan
9272169689Skan   The shift is normally computed in the widest mode we find in VAROP, as
9273169689Skan   long as it isn't a different number of words than RESULT_MODE.  Exceptions
9274169689Skan   are ASHIFTRT and ROTATE, which are always done in their original mode.  */
9275169689Skan
9276169689Skanstatic rtx
9277169689Skansimplify_shift_const (rtx x, enum rtx_code code, enum machine_mode result_mode,
9278169689Skan		      rtx varop, int count)
9279169689Skan{
9280169689Skan  rtx tem = simplify_shift_const_1 (code, result_mode, varop, count);
9281169689Skan  if (tem)
9282169689Skan    return tem;
9283169689Skan
9284169689Skan  if (!x)
9285169689Skan    x = simplify_gen_binary (code, GET_MODE (varop), varop, GEN_INT (count));
9286169689Skan  if (GET_MODE (x) != result_mode)
9287169689Skan    x = gen_lowpart (result_mode, x);
9288169689Skan  return x;
9289169689Skan}
9290169689Skan
929118334Speter
929218334Speter/* Like recog, but we receive the address of a pointer to a new pattern.
929318334Speter   We try to match the rtx that the pointer points to.
929418334Speter   If that fails, we may try to modify or replace the pattern,
929518334Speter   storing the replacement into the same pointer object.
929618334Speter
929718334Speter   Modifications include deletion or addition of CLOBBERs.
929818334Speter
929918334Speter   PNOTES is a pointer to a location where any REG_UNUSED notes added for
930018334Speter   the CLOBBERs are placed.
930118334Speter
930218334Speter   The value is the final insn code from the pattern ultimately matched,
930318334Speter   or -1.  */
930418334Speter
930518334Speterstatic int
9306132718Skanrecog_for_combine (rtx *pnewpat, rtx insn, rtx *pnotes)
930718334Speter{
930890075Sobrien  rtx pat = *pnewpat;
930918334Speter  int insn_code_number;
931018334Speter  int num_clobbers_to_add = 0;
931118334Speter  int i;
931218334Speter  rtx notes = 0;
9313132718Skan  rtx old_notes, old_pat;
931418334Speter
931518334Speter  /* If PAT is a PARALLEL, check to see if it contains the CLOBBER
931618334Speter     we use to indicate that something didn't match.  If we find such a
931718334Speter     thing, force rejection.  */
931818334Speter  if (GET_CODE (pat) == PARALLEL)
931918334Speter    for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
932018334Speter      if (GET_CODE (XVECEXP (pat, 0, i)) == CLOBBER
932118334Speter	  && XEXP (XVECEXP (pat, 0, i), 0) == const0_rtx)
932218334Speter	return -1;
932318334Speter
9324132718Skan  old_pat = PATTERN (insn);
9325132718Skan  old_notes = REG_NOTES (insn);
9326132718Skan  PATTERN (insn) = pat;
9327132718Skan  REG_NOTES (insn) = 0;
932890075Sobrien
9329132718Skan  insn_code_number = recog (pat, insn, &num_clobbers_to_add);
933018334Speter
933118334Speter  /* If it isn't, there is the possibility that we previously had an insn
933218334Speter     that clobbered some register as a side effect, but the combined
933318334Speter     insn doesn't need to do that.  So try once more without the clobbers
933418334Speter     unless this represents an ASM insn.  */
933518334Speter
933618334Speter  if (insn_code_number < 0 && ! check_asm_operands (pat)
933718334Speter      && GET_CODE (pat) == PARALLEL)
933818334Speter    {
933918334Speter      int pos;
934018334Speter
934118334Speter      for (pos = 0, i = 0; i < XVECLEN (pat, 0); i++)
934218334Speter	if (GET_CODE (XVECEXP (pat, 0, i)) != CLOBBER)
934318334Speter	  {
934418334Speter	    if (i != pos)
934518334Speter	      SUBST (XVECEXP (pat, 0, pos), XVECEXP (pat, 0, i));
934618334Speter	    pos++;
934718334Speter	  }
934818334Speter
934918334Speter      SUBST_INT (XVECLEN (pat, 0), pos);
935018334Speter
935118334Speter      if (pos == 1)
935218334Speter	pat = XVECEXP (pat, 0, 0);
935318334Speter
9354132718Skan      PATTERN (insn) = pat;
9355132718Skan      insn_code_number = recog (pat, insn, &num_clobbers_to_add);
935618334Speter    }
9357132718Skan  PATTERN (insn) = old_pat;
9358132718Skan  REG_NOTES (insn) = old_notes;
935918334Speter
936090075Sobrien  /* Recognize all noop sets, these will be killed by followup pass.  */
936190075Sobrien  if (insn_code_number < 0 && GET_CODE (pat) == SET && set_noop_p (pat))
936290075Sobrien    insn_code_number = NOOP_MOVE_INSN_CODE, num_clobbers_to_add = 0;
936390075Sobrien
936418334Speter  /* If we had any clobbers to add, make a new pattern than contains
936518334Speter     them.  Then check to make sure that all of them are dead.  */
936618334Speter  if (num_clobbers_to_add)
936718334Speter    {
936850397Sobrien      rtx newpat = gen_rtx_PARALLEL (VOIDmode,
936990075Sobrien				     rtvec_alloc (GET_CODE (pat) == PARALLEL
937090075Sobrien						  ? (XVECLEN (pat, 0)
937190075Sobrien						     + num_clobbers_to_add)
937290075Sobrien						  : num_clobbers_to_add + 1));
937318334Speter
937418334Speter      if (GET_CODE (pat) == PARALLEL)
937518334Speter	for (i = 0; i < XVECLEN (pat, 0); i++)
937618334Speter	  XVECEXP (newpat, 0, i) = XVECEXP (pat, 0, i);
937718334Speter      else
937818334Speter	XVECEXP (newpat, 0, 0) = pat;
937918334Speter
938018334Speter      add_clobbers (newpat, insn_code_number);
938118334Speter
938218334Speter      for (i = XVECLEN (newpat, 0) - num_clobbers_to_add;
938318334Speter	   i < XVECLEN (newpat, 0); i++)
938418334Speter	{
9385169689Skan	  if (REG_P (XEXP (XVECEXP (newpat, 0, i), 0))
938618334Speter	      && ! reg_dead_at_p (XEXP (XVECEXP (newpat, 0, i), 0), insn))
938718334Speter	    return -1;
938850397Sobrien	  notes = gen_rtx_EXPR_LIST (REG_UNUSED,
938950397Sobrien				     XEXP (XVECEXP (newpat, 0, i), 0), notes);
939018334Speter	}
939118334Speter      pat = newpat;
939218334Speter    }
939318334Speter
939418334Speter  *pnewpat = pat;
939518334Speter  *pnotes = notes;
939618334Speter
939718334Speter  return insn_code_number;
939818334Speter}
939918334Speter
9400169689Skan/* Like gen_lowpart_general but for use by combine.  In combine it
9401169689Skan   is not possible to create any new pseudoregs.  However, it is
9402169689Skan   safe to create invalid memory addresses, because combine will
9403169689Skan   try to recognize them and all they will do is make the combine
9404169689Skan   attempt fail.
940518334Speter
940618334Speter   If for some reason this cannot do its job, an rtx
940718334Speter   (clobber (const_int 0)) is returned.
940818334Speter   An insn containing that will not be recognized.  */
940918334Speter
941018334Speterstatic rtx
9411169689Skangen_lowpart_for_combine (enum machine_mode omode, rtx x)
941218334Speter{
9413169689Skan  enum machine_mode imode = GET_MODE (x);
9414169689Skan  unsigned int osize = GET_MODE_SIZE (omode);
9415169689Skan  unsigned int isize = GET_MODE_SIZE (imode);
941618334Speter  rtx result;
941718334Speter
9418169689Skan  if (omode == imode)
941918334Speter    return x;
942018334Speter
9421169689Skan  /* Return identity if this is a CONST or symbolic reference.  */
9422169689Skan  if (omode == Pmode
9423132718Skan      && (GET_CODE (x) == CONST
9424132718Skan	  || GET_CODE (x) == SYMBOL_REF
9425132718Skan	  || GET_CODE (x) == LABEL_REF))
9426132718Skan    return x;
9427132718Skan
942818334Speter  /* We can only support MODE being wider than a word if X is a
942918334Speter     constant integer or has a mode the same size.  */
9430169689Skan  if (GET_MODE_SIZE (omode) > UNITS_PER_WORD
9431169689Skan      && ! ((imode == VOIDmode
943218334Speter	     && (GET_CODE (x) == CONST_INT
943318334Speter		 || GET_CODE (x) == CONST_DOUBLE))
9434169689Skan	    || isize == osize))
9435169689Skan    goto fail;
943618334Speter
943718334Speter  /* X might be a paradoxical (subreg (mem)).  In that case, gen_lowpart
943818334Speter     won't know what to do.  So we will strip off the SUBREG here and
943918334Speter     process normally.  */
9440169689Skan  if (GET_CODE (x) == SUBREG && MEM_P (SUBREG_REG (x)))
944118334Speter    {
944218334Speter      x = SUBREG_REG (x);
9443169689Skan
9444169689Skan      /* For use in case we fall down into the address adjustments
9445169689Skan	 further below, we need to adjust the known mode and size of
9446169689Skan	 x; imode and isize, since we just adjusted x.  */
9447169689Skan      imode = GET_MODE (x);
9448169689Skan
9449169689Skan      if (imode == omode)
945018334Speter	return x;
9451169689Skan
9452169689Skan      isize = GET_MODE_SIZE (imode);
945318334Speter    }
945418334Speter
9455169689Skan  result = gen_lowpart_common (omode, x);
9456169689Skan
9457117395Skan#ifdef CANNOT_CHANGE_MODE_CLASS
9458146895Skan  if (result != 0 && GET_CODE (result) == SUBREG)
9459146895Skan    record_subregs_of_mode (result);
946090075Sobrien#endif
946118334Speter
946218334Speter  if (result)
946318334Speter    return result;
946418334Speter
9465169689Skan  if (MEM_P (x))
946618334Speter    {
946790075Sobrien      int offset = 0;
946818334Speter
946918334Speter      /* Refuse to work on a volatile memory ref or one with a mode-dependent
947018334Speter	 address.  */
947118334Speter      if (MEM_VOLATILE_P (x) || mode_dependent_address_p (XEXP (x, 0)))
9472169689Skan	goto fail;
947318334Speter
947418334Speter      /* If we want to refer to something bigger than the original memref,
9475169689Skan	 generate a paradoxical subreg instead.  That will force a reload
947618334Speter	 of the original memref X.  */
9477169689Skan      if (isize < osize)
9478169689Skan	return gen_rtx_SUBREG (omode, x, 0);
947918334Speter
948018334Speter      if (WORDS_BIG_ENDIAN)
9481169689Skan	offset = MAX (isize, UNITS_PER_WORD) - MAX (osize, UNITS_PER_WORD);
948290075Sobrien
9483169689Skan      /* Adjust the address so that the address-after-the-data is
9484169689Skan	 unchanged.  */
948518334Speter      if (BYTES_BIG_ENDIAN)
9486169689Skan	offset -= MIN (UNITS_PER_WORD, osize) - MIN (UNITS_PER_WORD, isize);
948790075Sobrien
9488169689Skan      return adjust_address_nv (x, omode, offset);
948918334Speter    }
949018334Speter
949118334Speter  /* If X is a comparison operator, rewrite it in a new mode.  This
949218334Speter     probably won't match, but may allow further simplifications.  */
9493169689Skan  else if (COMPARISON_P (x))
9494169689Skan    return gen_rtx_fmt_ee (GET_CODE (x), omode, XEXP (x, 0), XEXP (x, 1));
949518334Speter
949618334Speter  /* If we couldn't simplify X any other way, just enclose it in a
949718334Speter     SUBREG.  Normally, this SUBREG won't match, but some patterns may
949818334Speter     include an explicit SUBREG or we may simplify it further in combine.  */
949918334Speter  else
950018334Speter    {
950190075Sobrien      int offset = 0;
950290075Sobrien      rtx res;
950318334Speter
9504169689Skan      offset = subreg_lowpart_offset (omode, imode);
9505169689Skan      if (imode == VOIDmode)
9506117395Skan	{
9507169689Skan	  imode = int_mode_for_mode (omode);
9508169689Skan	  x = gen_lowpart_common (imode, x);
9509169689Skan	  if (x == NULL)
9510169689Skan	    goto fail;
9511117395Skan	}
9512169689Skan      res = simplify_gen_subreg (omode, x, imode, offset);
951390075Sobrien      if (res)
951490075Sobrien	return res;
951518334Speter    }
951618334Speter
9517169689Skan fail:
9518169689Skan  return gen_rtx_CLOBBER (imode, const0_rtx);
951918334Speter}
952018334Speter
952118334Speter/* Simplify a comparison between *POP0 and *POP1 where CODE is the
952218334Speter   comparison code that will be tested.
952318334Speter
952418334Speter   The result is a possibly different comparison code to use.  *POP0 and
952518334Speter   *POP1 may be updated.
952618334Speter
952718334Speter   It is possible that we might detect that a comparison is either always
952818334Speter   true or always false.  However, we do not perform general constant
952918334Speter   folding in combine, so this knowledge isn't useful.  Such tautologies
953018334Speter   should have been detected earlier.  Hence we ignore all such cases.  */
953118334Speter
953218334Speterstatic enum rtx_code
9533132718Skansimplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
953418334Speter{
953518334Speter  rtx op0 = *pop0;
953618334Speter  rtx op1 = *pop1;
953718334Speter  rtx tem, tem1;
953818334Speter  int i;
953918334Speter  enum machine_mode mode, tmode;
954018334Speter
954118334Speter  /* Try a few ways of applying the same transformation to both operands.  */
954218334Speter  while (1)
954318334Speter    {
954418334Speter#ifndef WORD_REGISTER_OPERATIONS
954518334Speter      /* The test below this one won't handle SIGN_EXTENDs on these machines,
954618334Speter	 so check specially.  */
954718334Speter      if (code != GTU && code != GEU && code != LTU && code != LEU
954818334Speter	  && GET_CODE (op0) == ASHIFTRT && GET_CODE (op1) == ASHIFTRT
954918334Speter	  && GET_CODE (XEXP (op0, 0)) == ASHIFT
955018334Speter	  && GET_CODE (XEXP (op1, 0)) == ASHIFT
955118334Speter	  && GET_CODE (XEXP (XEXP (op0, 0), 0)) == SUBREG
955218334Speter	  && GET_CODE (XEXP (XEXP (op1, 0), 0)) == SUBREG
955318334Speter	  && (GET_MODE (SUBREG_REG (XEXP (XEXP (op0, 0), 0)))
955418334Speter	      == GET_MODE (SUBREG_REG (XEXP (XEXP (op1, 0), 0))))
955518334Speter	  && GET_CODE (XEXP (op0, 1)) == CONST_INT
9556132718Skan	  && XEXP (op0, 1) == XEXP (op1, 1)
9557132718Skan	  && XEXP (op0, 1) == XEXP (XEXP (op0, 0), 1)
9558132718Skan	  && XEXP (op0, 1) == XEXP (XEXP (op1, 0), 1)
955918334Speter	  && (INTVAL (XEXP (op0, 1))
956018334Speter	      == (GET_MODE_BITSIZE (GET_MODE (op0))
956118334Speter		  - (GET_MODE_BITSIZE
956218334Speter		     (GET_MODE (SUBREG_REG (XEXP (XEXP (op0, 0), 0))))))))
956318334Speter	{
956418334Speter	  op0 = SUBREG_REG (XEXP (XEXP (op0, 0), 0));
956518334Speter	  op1 = SUBREG_REG (XEXP (XEXP (op1, 0), 0));
956618334Speter	}
956718334Speter#endif
956818334Speter
956918334Speter      /* If both operands are the same constant shift, see if we can ignore the
957018334Speter	 shift.  We can if the shift is a rotate or if the bits shifted out of
957118334Speter	 this shift are known to be zero for both inputs and if the type of
957218334Speter	 comparison is compatible with the shift.  */
957318334Speter      if (GET_CODE (op0) == GET_CODE (op1)
957418334Speter	  && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT
957518334Speter	  && ((GET_CODE (op0) == ROTATE && (code == NE || code == EQ))
957618334Speter	      || ((GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFT)
957718334Speter		  && (code != GT && code != LT && code != GE && code != LE))
957818334Speter	      || (GET_CODE (op0) == ASHIFTRT
957918334Speter		  && (code != GTU && code != LTU
958090075Sobrien		      && code != GEU && code != LEU)))
958118334Speter	  && GET_CODE (XEXP (op0, 1)) == CONST_INT
958218334Speter	  && INTVAL (XEXP (op0, 1)) >= 0
958318334Speter	  && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT
958418334Speter	  && XEXP (op0, 1) == XEXP (op1, 1))
958518334Speter	{
958618334Speter	  enum machine_mode mode = GET_MODE (op0);
958718334Speter	  unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
958818334Speter	  int shift_count = INTVAL (XEXP (op0, 1));
958918334Speter
959018334Speter	  if (GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFTRT)
959118334Speter	    mask &= (mask >> shift_count) << shift_count;
959218334Speter	  else if (GET_CODE (op0) == ASHIFT)
959318334Speter	    mask = (mask & (mask << shift_count)) >> shift_count;
959418334Speter
959590075Sobrien	  if ((nonzero_bits (XEXP (op0, 0), mode) & ~mask) == 0
959690075Sobrien	      && (nonzero_bits (XEXP (op1, 0), mode) & ~mask) == 0)
959718334Speter	    op0 = XEXP (op0, 0), op1 = XEXP (op1, 0);
959818334Speter	  else
959918334Speter	    break;
960018334Speter	}
960118334Speter
960218334Speter      /* If both operands are AND's of a paradoxical SUBREG by constant, the
960318334Speter	 SUBREGs are of the same mode, and, in both cases, the AND would
960418334Speter	 be redundant if the comparison was done in the narrower mode,
960518334Speter	 do the comparison in the narrower mode (e.g., we are AND'ing with 1
960618334Speter	 and the operand's possibly nonzero bits are 0xffffff01; in that case
960718334Speter	 if we only care about QImode, we don't need the AND).  This case
960818334Speter	 occurs if the output mode of an scc insn is not SImode and
960918334Speter	 STORE_FLAG_VALUE == 1 (e.g., the 386).
961018334Speter
961118334Speter	 Similarly, check for a case where the AND's are ZERO_EXTEND
961218334Speter	 operations from some narrower mode even though a SUBREG is not
961318334Speter	 present.  */
961418334Speter
961590075Sobrien      else if (GET_CODE (op0) == AND && GET_CODE (op1) == AND
961690075Sobrien	       && GET_CODE (XEXP (op0, 1)) == CONST_INT
961790075Sobrien	       && GET_CODE (XEXP (op1, 1)) == CONST_INT)
961818334Speter	{
961918334Speter	  rtx inner_op0 = XEXP (op0, 0);
962018334Speter	  rtx inner_op1 = XEXP (op1, 0);
962118334Speter	  HOST_WIDE_INT c0 = INTVAL (XEXP (op0, 1));
962218334Speter	  HOST_WIDE_INT c1 = INTVAL (XEXP (op1, 1));
962318334Speter	  int changed = 0;
962490075Sobrien
962518334Speter	  if (GET_CODE (inner_op0) == SUBREG && GET_CODE (inner_op1) == SUBREG
962618334Speter	      && (GET_MODE_SIZE (GET_MODE (inner_op0))
962718334Speter		  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner_op0))))
962818334Speter	      && (GET_MODE (SUBREG_REG (inner_op0))
962918334Speter		  == GET_MODE (SUBREG_REG (inner_op1)))
963050397Sobrien	      && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (inner_op0)))
963118334Speter		  <= HOST_BITS_PER_WIDE_INT)
963250397Sobrien	      && (0 == ((~c0) & nonzero_bits (SUBREG_REG (inner_op0),
963350397Sobrien					     GET_MODE (SUBREG_REG (inner_op0)))))
963450397Sobrien	      && (0 == ((~c1) & nonzero_bits (SUBREG_REG (inner_op1),
963550397Sobrien					     GET_MODE (SUBREG_REG (inner_op1))))))
963618334Speter	    {
963718334Speter	      op0 = SUBREG_REG (inner_op0);
963818334Speter	      op1 = SUBREG_REG (inner_op1);
963918334Speter
964018334Speter	      /* The resulting comparison is always unsigned since we masked
964150397Sobrien		 off the original sign bit.  */
964218334Speter	      code = unsigned_condition (code);
964318334Speter
964418334Speter	      changed = 1;
964518334Speter	    }
964618334Speter
964718334Speter	  else if (c0 == c1)
964818334Speter	    for (tmode = GET_CLASS_NARROWEST_MODE
964918334Speter		 (GET_MODE_CLASS (GET_MODE (op0)));
965018334Speter		 tmode != GET_MODE (op0); tmode = GET_MODE_WIDER_MODE (tmode))
965152284Sobrien	      if ((unsigned HOST_WIDE_INT) c0 == GET_MODE_MASK (tmode))
965218334Speter		{
9653169689Skan		  op0 = gen_lowpart (tmode, inner_op0);
9654169689Skan		  op1 = gen_lowpart (tmode, inner_op1);
965518334Speter		  code = unsigned_condition (code);
965618334Speter		  changed = 1;
965718334Speter		  break;
965818334Speter		}
965918334Speter
966018334Speter	  if (! changed)
966118334Speter	    break;
966218334Speter	}
966318334Speter
966418334Speter      /* If both operands are NOT, we can strip off the outer operation
966518334Speter	 and adjust the comparison code for swapped operands; similarly for
966618334Speter	 NEG, except that this must be an equality comparison.  */
966718334Speter      else if ((GET_CODE (op0) == NOT && GET_CODE (op1) == NOT)
966818334Speter	       || (GET_CODE (op0) == NEG && GET_CODE (op1) == NEG
966918334Speter		   && (code == EQ || code == NE)))
967018334Speter	op0 = XEXP (op0, 0), op1 = XEXP (op1, 0), code = swap_condition (code);
967118334Speter
967218334Speter      else
967318334Speter	break;
967418334Speter    }
967590075Sobrien
967618334Speter  /* If the first operand is a constant, swap the operands and adjust the
967750397Sobrien     comparison code appropriately, but don't do this if the second operand
967850397Sobrien     is already a constant integer.  */
967990075Sobrien  if (swap_commutative_operands_p (op0, op1))
968018334Speter    {
968118334Speter      tem = op0, op0 = op1, op1 = tem;
968218334Speter      code = swap_condition (code);
968318334Speter    }
968418334Speter
968518334Speter  /* We now enter a loop during which we will try to simplify the comparison.
968618334Speter     For the most part, we only are concerned with comparisons with zero,
968718334Speter     but some things may really be comparisons with zero but not start
968818334Speter     out looking that way.  */
968918334Speter
969018334Speter  while (GET_CODE (op1) == CONST_INT)
969118334Speter    {
969218334Speter      enum machine_mode mode = GET_MODE (op0);
969390075Sobrien      unsigned int mode_width = GET_MODE_BITSIZE (mode);
969418334Speter      unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
969518334Speter      int equality_comparison_p;
969618334Speter      int sign_bit_comparison_p;
969718334Speter      int unsigned_comparison_p;
969818334Speter      HOST_WIDE_INT const_op;
969918334Speter
970018334Speter      /* We only want to handle integral modes.  This catches VOIDmode,
970118334Speter	 CCmode, and the floating-point modes.  An exception is that we
970218334Speter	 can handle VOIDmode if OP0 is a COMPARE or a comparison
970318334Speter	 operation.  */
970418334Speter
970518334Speter      if (GET_MODE_CLASS (mode) != MODE_INT
970618334Speter	  && ! (mode == VOIDmode
9707169689Skan		&& (GET_CODE (op0) == COMPARE || COMPARISON_P (op0))))
970818334Speter	break;
970918334Speter
971018334Speter      /* Get the constant we are comparing against and turn off all bits
971118334Speter	 not on in our mode.  */
9712117395Skan      const_op = INTVAL (op1);
9713117395Skan      if (mode != VOIDmode)
9714117395Skan	const_op = trunc_int_for_mode (const_op, mode);
971590075Sobrien      op1 = GEN_INT (const_op);
971618334Speter
971718334Speter      /* If we are comparing against a constant power of two and the value
971818334Speter	 being compared can only have that single bit nonzero (e.g., it was
971918334Speter	 `and'ed with that bit), we can replace this with a comparison
972018334Speter	 with zero.  */
972118334Speter      if (const_op
972218334Speter	  && (code == EQ || code == NE || code == GE || code == GEU
972318334Speter	      || code == LT || code == LTU)
972418334Speter	  && mode_width <= HOST_BITS_PER_WIDE_INT
972518334Speter	  && exact_log2 (const_op) >= 0
972652284Sobrien	  && nonzero_bits (op0, mode) == (unsigned HOST_WIDE_INT) const_op)
972718334Speter	{
972818334Speter	  code = (code == EQ || code == GE || code == GEU ? NE : EQ);
972918334Speter	  op1 = const0_rtx, const_op = 0;
973018334Speter	}
973118334Speter
973218334Speter      /* Similarly, if we are comparing a value known to be either -1 or
973318334Speter	 0 with -1, change it to the opposite comparison against zero.  */
973418334Speter
973518334Speter      if (const_op == -1
973618334Speter	  && (code == EQ || code == NE || code == GT || code == LE
973718334Speter	      || code == GEU || code == LTU)
973818334Speter	  && num_sign_bit_copies (op0, mode) == mode_width)
973918334Speter	{
974018334Speter	  code = (code == EQ || code == LE || code == GEU ? NE : EQ);
974118334Speter	  op1 = const0_rtx, const_op = 0;
974218334Speter	}
974318334Speter
974418334Speter      /* Do some canonicalizations based on the comparison code.  We prefer
974590075Sobrien	 comparisons against zero and then prefer equality comparisons.
974618334Speter	 If we can reduce the size of a constant, we will do that too.  */
974718334Speter
974818334Speter      switch (code)
974918334Speter	{
975018334Speter	case LT:
975118334Speter	  /* < C is equivalent to <= (C - 1) */
975218334Speter	  if (const_op > 0)
975318334Speter	    {
975418334Speter	      const_op -= 1;
975518334Speter	      op1 = GEN_INT (const_op);
975618334Speter	      code = LE;
975718334Speter	      /* ... fall through to LE case below.  */
975818334Speter	    }
975918334Speter	  else
976018334Speter	    break;
976118334Speter
976218334Speter	case LE:
976318334Speter	  /* <= C is equivalent to < (C + 1); we do this for C < 0  */
976418334Speter	  if (const_op < 0)
976518334Speter	    {
976618334Speter	      const_op += 1;
976718334Speter	      op1 = GEN_INT (const_op);
976818334Speter	      code = LT;
976918334Speter	    }
977018334Speter
977118334Speter	  /* If we are doing a <= 0 comparison on a value known to have
977218334Speter	     a zero sign bit, we can replace this with == 0.  */
977318334Speter	  else if (const_op == 0
977418334Speter		   && mode_width <= HOST_BITS_PER_WIDE_INT
977518334Speter		   && (nonzero_bits (op0, mode)
977618334Speter		       & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0)
977718334Speter	    code = EQ;
977818334Speter	  break;
977918334Speter
978018334Speter	case GE:
978150397Sobrien	  /* >= C is equivalent to > (C - 1).  */
978218334Speter	  if (const_op > 0)
978318334Speter	    {
978418334Speter	      const_op -= 1;
978518334Speter	      op1 = GEN_INT (const_op);
978618334Speter	      code = GT;
978718334Speter	      /* ... fall through to GT below.  */
978818334Speter	    }
978918334Speter	  else
979018334Speter	    break;
979118334Speter
979218334Speter	case GT:
979390075Sobrien	  /* > C is equivalent to >= (C + 1); we do this for C < 0.  */
979418334Speter	  if (const_op < 0)
979518334Speter	    {
979618334Speter	      const_op += 1;
979718334Speter	      op1 = GEN_INT (const_op);
979818334Speter	      code = GE;
979918334Speter	    }
980018334Speter
980118334Speter	  /* If we are doing a > 0 comparison on a value known to have
980218334Speter	     a zero sign bit, we can replace this with != 0.  */
980318334Speter	  else if (const_op == 0
980418334Speter		   && mode_width <= HOST_BITS_PER_WIDE_INT
980518334Speter		   && (nonzero_bits (op0, mode)
980618334Speter		       & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0)
980718334Speter	    code = NE;
980818334Speter	  break;
980918334Speter
981018334Speter	case LTU:
981118334Speter	  /* < C is equivalent to <= (C - 1).  */
981218334Speter	  if (const_op > 0)
981318334Speter	    {
981418334Speter	      const_op -= 1;
981518334Speter	      op1 = GEN_INT (const_op);
981618334Speter	      code = LEU;
981750397Sobrien	      /* ... fall through ...  */
981818334Speter	    }
981918334Speter
982018334Speter	  /* (unsigned) < 0x80000000 is equivalent to >= 0.  */
982150397Sobrien	  else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
982250397Sobrien		   && (const_op == (HOST_WIDE_INT) 1 << (mode_width - 1)))
982318334Speter	    {
982418334Speter	      const_op = 0, op1 = const0_rtx;
982518334Speter	      code = GE;
982618334Speter	      break;
982718334Speter	    }
982818334Speter	  else
982918334Speter	    break;
983018334Speter
983118334Speter	case LEU:
983218334Speter	  /* unsigned <= 0 is equivalent to == 0 */
983318334Speter	  if (const_op == 0)
983418334Speter	    code = EQ;
983518334Speter
983650397Sobrien	  /* (unsigned) <= 0x7fffffff is equivalent to >= 0.  */
983750397Sobrien	  else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
983850397Sobrien		   && (const_op == ((HOST_WIDE_INT) 1 << (mode_width - 1)) - 1))
983918334Speter	    {
984018334Speter	      const_op = 0, op1 = const0_rtx;
984118334Speter	      code = GE;
984218334Speter	    }
984318334Speter	  break;
984418334Speter
984518334Speter	case GEU:
9846169689Skan	  /* >= C is equivalent to > (C - 1).  */
984718334Speter	  if (const_op > 1)
984818334Speter	    {
984918334Speter	      const_op -= 1;
985018334Speter	      op1 = GEN_INT (const_op);
985118334Speter	      code = GTU;
985250397Sobrien	      /* ... fall through ...  */
985318334Speter	    }
985418334Speter
985518334Speter	  /* (unsigned) >= 0x80000000 is equivalent to < 0.  */
985650397Sobrien	  else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
985750397Sobrien		   && (const_op == (HOST_WIDE_INT) 1 << (mode_width - 1)))
985818334Speter	    {
985918334Speter	      const_op = 0, op1 = const0_rtx;
986018334Speter	      code = LT;
986118334Speter	      break;
986218334Speter	    }
986318334Speter	  else
986418334Speter	    break;
986518334Speter
986618334Speter	case GTU:
986718334Speter	  /* unsigned > 0 is equivalent to != 0 */
986818334Speter	  if (const_op == 0)
986918334Speter	    code = NE;
987018334Speter
987118334Speter	  /* (unsigned) > 0x7fffffff is equivalent to < 0.  */
987250397Sobrien	  else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
9873132718Skan		   && (const_op == ((HOST_WIDE_INT) 1 << (mode_width - 1)) - 1))
987418334Speter	    {
987518334Speter	      const_op = 0, op1 = const0_rtx;
987618334Speter	      code = LT;
987718334Speter	    }
987818334Speter	  break;
987950397Sobrien
988050397Sobrien	default:
988150397Sobrien	  break;
988218334Speter	}
988318334Speter
988418334Speter      /* Compute some predicates to simplify code below.  */
988518334Speter
988618334Speter      equality_comparison_p = (code == EQ || code == NE);
988718334Speter      sign_bit_comparison_p = ((code == LT || code == GE) && const_op == 0);
988818334Speter      unsigned_comparison_p = (code == LTU || code == LEU || code == GTU
988990075Sobrien			       || code == GEU);
989018334Speter
989118334Speter      /* If this is a sign bit comparison and we can do arithmetic in
989218334Speter	 MODE, say that we will only be needing the sign bit of OP0.  */
989318334Speter      if (sign_bit_comparison_p
989418334Speter	  && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
989518334Speter	op0 = force_to_mode (op0, mode,
989618334Speter			     ((HOST_WIDE_INT) 1
989718334Speter			      << (GET_MODE_BITSIZE (mode) - 1)),
9898169689Skan			     0);
989918334Speter
990018334Speter      /* Now try cases based on the opcode of OP0.  If none of the cases
990118334Speter	 does a "continue", we exit this loop immediately after the
990218334Speter	 switch.  */
990318334Speter
990418334Speter      switch (GET_CODE (op0))
990518334Speter	{
990618334Speter	case ZERO_EXTRACT:
990718334Speter	  /* If we are extracting a single bit from a variable position in
990818334Speter	     a constant that has only a single bit set and are comparing it
990990075Sobrien	     with zero, we can convert this into an equality comparison
991050397Sobrien	     between the position and the location of the single bit.  */
9911132718Skan	  /* Except we can't if SHIFT_COUNT_TRUNCATED is set, since we might
9912132718Skan	     have already reduced the shift count modulo the word size.  */
9913132718Skan	  if (!SHIFT_COUNT_TRUNCATED
9914132718Skan	      && GET_CODE (XEXP (op0, 0)) == CONST_INT
991518334Speter	      && XEXP (op0, 1) == const1_rtx
991618334Speter	      && equality_comparison_p && const_op == 0
991750397Sobrien	      && (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0)
991818334Speter	    {
991950397Sobrien	      if (BITS_BIG_ENDIAN)
992052284Sobrien		{
992190075Sobrien		  enum machine_mode new_mode
992290075Sobrien		    = mode_for_extraction (EP_extzv, 1);
992390075Sobrien		  if (new_mode == MAX_MACHINE_MODE)
992490075Sobrien		    i = BITS_PER_WORD - 1 - i;
992590075Sobrien		  else
992690075Sobrien		    {
992790075Sobrien		      mode = new_mode;
992890075Sobrien		      i = (GET_MODE_BITSIZE (mode) - 1 - i);
992990075Sobrien		    }
993052284Sobrien		}
993118334Speter
993218334Speter	      op0 = XEXP (op0, 2);
993318334Speter	      op1 = GEN_INT (i);
993418334Speter	      const_op = i;
993518334Speter
993618334Speter	      /* Result is nonzero iff shift count is equal to I.  */
993718334Speter	      code = reverse_condition (code);
993818334Speter	      continue;
993918334Speter	    }
994018334Speter
994150397Sobrien	  /* ... fall through ...  */
994218334Speter
994318334Speter	case SIGN_EXTRACT:
994418334Speter	  tem = expand_compound_operation (op0);
994518334Speter	  if (tem != op0)
994618334Speter	    {
994718334Speter	      op0 = tem;
994818334Speter	      continue;
994918334Speter	    }
995018334Speter	  break;
995118334Speter
995218334Speter	case NOT:
995318334Speter	  /* If testing for equality, we can take the NOT of the constant.  */
995418334Speter	  if (equality_comparison_p
995518334Speter	      && (tem = simplify_unary_operation (NOT, mode, op1, mode)) != 0)
995618334Speter	    {
995718334Speter	      op0 = XEXP (op0, 0);
995818334Speter	      op1 = tem;
995918334Speter	      continue;
996018334Speter	    }
996118334Speter
996218334Speter	  /* If just looking at the sign bit, reverse the sense of the
996318334Speter	     comparison.  */
996418334Speter	  if (sign_bit_comparison_p)
996518334Speter	    {
996618334Speter	      op0 = XEXP (op0, 0);
996718334Speter	      code = (code == GE ? LT : GE);
996818334Speter	      continue;
996918334Speter	    }
997018334Speter	  break;
997118334Speter
997218334Speter	case NEG:
997318334Speter	  /* If testing for equality, we can take the NEG of the constant.  */
997418334Speter	  if (equality_comparison_p
997518334Speter	      && (tem = simplify_unary_operation (NEG, mode, op1, mode)) != 0)
997618334Speter	    {
997718334Speter	      op0 = XEXP (op0, 0);
997818334Speter	      op1 = tem;
997918334Speter	      continue;
998018334Speter	    }
998118334Speter
998218334Speter	  /* The remaining cases only apply to comparisons with zero.  */
998318334Speter	  if (const_op != 0)
998418334Speter	    break;
998518334Speter
998618334Speter	  /* When X is ABS or is known positive,
998718334Speter	     (neg X) is < 0 if and only if X != 0.  */
998818334Speter
998918334Speter	  if (sign_bit_comparison_p
999018334Speter	      && (GET_CODE (XEXP (op0, 0)) == ABS
999118334Speter		  || (mode_width <= HOST_BITS_PER_WIDE_INT
999218334Speter		      && (nonzero_bits (XEXP (op0, 0), mode)
999318334Speter			  & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0)))
999418334Speter	    {
999518334Speter	      op0 = XEXP (op0, 0);
999618334Speter	      code = (code == LT ? NE : EQ);
999718334Speter	      continue;
999818334Speter	    }
999918334Speter
1000018334Speter	  /* If we have NEG of something whose two high-order bits are the
1000150397Sobrien	     same, we know that "(-a) < 0" is equivalent to "a > 0".  */
1000218334Speter	  if (num_sign_bit_copies (op0, mode) >= 2)
1000318334Speter	    {
1000418334Speter	      op0 = XEXP (op0, 0);
1000518334Speter	      code = swap_condition (code);
1000618334Speter	      continue;
1000718334Speter	    }
1000818334Speter	  break;
1000918334Speter
1001018334Speter	case ROTATE:
1001118334Speter	  /* If we are testing equality and our count is a constant, we
1001218334Speter	     can perform the inverse operation on our RHS.  */
1001318334Speter	  if (equality_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT
1001418334Speter	      && (tem = simplify_binary_operation (ROTATERT, mode,
1001518334Speter						   op1, XEXP (op0, 1))) != 0)
1001618334Speter	    {
1001718334Speter	      op0 = XEXP (op0, 0);
1001818334Speter	      op1 = tem;
1001918334Speter	      continue;
1002018334Speter	    }
1002118334Speter
1002218334Speter	  /* If we are doing a < 0 or >= 0 comparison, it means we are testing
1002318334Speter	     a particular bit.  Convert it to an AND of a constant of that
1002418334Speter	     bit.  This will be converted into a ZERO_EXTRACT.  */
1002518334Speter	  if (const_op == 0 && sign_bit_comparison_p
1002618334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1002718334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT)
1002818334Speter	    {
1002918334Speter	      op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
1003018334Speter					    ((HOST_WIDE_INT) 1
1003118334Speter					     << (mode_width - 1
1003218334Speter						 - INTVAL (XEXP (op0, 1)))));
1003318334Speter	      code = (code == LT ? NE : EQ);
1003418334Speter	      continue;
1003518334Speter	    }
1003618334Speter
1003790075Sobrien	  /* Fall through.  */
1003818334Speter
1003918334Speter	case ABS:
1004018334Speter	  /* ABS is ignorable inside an equality comparison with zero.  */
1004118334Speter	  if (const_op == 0 && equality_comparison_p)
1004218334Speter	    {
1004318334Speter	      op0 = XEXP (op0, 0);
1004418334Speter	      continue;
1004518334Speter	    }
1004618334Speter	  break;
1004718334Speter
1004818334Speter	case SIGN_EXTEND:
10049169689Skan	  /* Can simplify (compare (zero/sign_extend FOO) CONST) to
10050169689Skan	     (compare FOO CONST) if CONST fits in FOO's mode and we
10051169689Skan	     are either testing inequality or have an unsigned
10052169689Skan	     comparison with ZERO_EXTEND or a signed comparison with
10053169689Skan	     SIGN_EXTEND.  But don't do it if we don't have a compare
10054169689Skan	     insn of the given mode, since we'd have to revert it
10055169689Skan	     later on, and then we wouldn't know whether to sign- or
10056169689Skan	     zero-extend.  */
10057169689Skan	  mode = GET_MODE (XEXP (op0, 0));
10058169689Skan	  if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT
10059169689Skan	      && ! unsigned_comparison_p
10060169689Skan	      && (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
1006118334Speter	      && ((unsigned HOST_WIDE_INT) const_op
1006252284Sobrien		  < (((unsigned HOST_WIDE_INT) 1
10063169689Skan		      << (GET_MODE_BITSIZE (mode) - 1))))
10064169689Skan	      && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1006518334Speter	    {
1006618334Speter	      op0 = XEXP (op0, 0);
1006718334Speter	      continue;
1006818334Speter	    }
1006918334Speter	  break;
1007018334Speter
1007118334Speter	case SUBREG:
10072146895Skan	  /* Check for the case where we are comparing A - C1 with C2, that is
1007318334Speter
10074146895Skan	       (subreg:MODE (plus (A) (-C1))) op (C2)
10075146895Skan
10076146895Skan	     with C1 a constant, and try to lift the SUBREG, i.e. to do the
10077146895Skan	     comparison in the wider mode.  One of the following two conditions
10078146895Skan	     must be true in order for this to be valid:
10079146895Skan
10080146895Skan	       1. The mode extension results in the same bit pattern being added
10081146895Skan		  on both sides and the comparison is equality or unsigned.  As
10082146895Skan		  C2 has been truncated to fit in MODE, the pattern can only be
10083146895Skan		  all 0s or all 1s.
10084146895Skan
10085146895Skan	       2. The mode extension results in the sign bit being copied on
10086146895Skan		  each side.
10087146895Skan
10088146895Skan	     The difficulty here is that we have predicates for A but not for
10089146895Skan	     (A - C1) so we need to check that C1 is within proper bounds so
10090146895Skan	     as to perturbate A as little as possible.  */
10091146895Skan
1009218334Speter	  if (mode_width <= HOST_BITS_PER_WIDE_INT
1009318334Speter	      && subreg_lowpart_p (op0)
10094146895Skan	      && GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) > mode_width
1009518334Speter	      && GET_CODE (SUBREG_REG (op0)) == PLUS
10096146895Skan	      && GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT)
1009718334Speter	    {
10098146895Skan	      enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
10099146895Skan	      rtx a = XEXP (SUBREG_REG (op0), 0);
10100146895Skan	      HOST_WIDE_INT c1 = -INTVAL (XEXP (SUBREG_REG (op0), 1));
10101146895Skan
10102146895Skan	      if ((c1 > 0
10103169689Skan		   && (unsigned HOST_WIDE_INT) c1
10104146895Skan		       < (unsigned HOST_WIDE_INT) 1 << (mode_width - 1)
10105146895Skan		   && (equality_comparison_p || unsigned_comparison_p)
10106146895Skan		   /* (A - C1) zero-extends if it is positive and sign-extends
10107146895Skan		      if it is negative, C2 both zero- and sign-extends.  */
10108146895Skan		   && ((0 == (nonzero_bits (a, inner_mode)
10109146895Skan			      & ~GET_MODE_MASK (mode))
10110146895Skan			&& const_op >= 0)
10111146895Skan		       /* (A - C1) sign-extends if it is positive and 1-extends
10112146895Skan			  if it is negative, C2 both sign- and 1-extends.  */
10113146895Skan		       || (num_sign_bit_copies (a, inner_mode)
10114146895Skan			   > (unsigned int) (GET_MODE_BITSIZE (inner_mode)
10115146895Skan					     - mode_width)
10116146895Skan			   && const_op < 0)))
10117146895Skan		  || ((unsigned HOST_WIDE_INT) c1
10118146895Skan		       < (unsigned HOST_WIDE_INT) 1 << (mode_width - 2)
10119146895Skan		      /* (A - C1) always sign-extends, like C2.  */
10120146895Skan		      && num_sign_bit_copies (a, inner_mode)
10121146895Skan			 > (unsigned int) (GET_MODE_BITSIZE (inner_mode)
10122161651Skan					   - (mode_width - 1))))
10123146895Skan		{
10124146895Skan		  op0 = SUBREG_REG (op0);
10125146895Skan		  continue;
10126169689Skan		}
1012718334Speter	    }
1012818334Speter
1012918334Speter	  /* If the inner mode is narrower and we are extracting the low part,
1013018334Speter	     we can treat the SUBREG as if it were a ZERO_EXTEND.  */
1013118334Speter	  if (subreg_lowpart_p (op0)
1013218334Speter	      && GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) < mode_width)
1013318334Speter	    /* Fall through */ ;
1013418334Speter	  else
1013518334Speter	    break;
1013618334Speter
1013750397Sobrien	  /* ... fall through ...  */
1013818334Speter
1013918334Speter	case ZERO_EXTEND:
10140169689Skan	  mode = GET_MODE (XEXP (op0, 0));
10141169689Skan	  if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT
10142169689Skan	      && (unsigned_comparison_p || equality_comparison_p)
10143169689Skan	      && (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
10144169689Skan	      && ((unsigned HOST_WIDE_INT) const_op < GET_MODE_MASK (mode))
10145169689Skan	      && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1014618334Speter	    {
1014718334Speter	      op0 = XEXP (op0, 0);
1014818334Speter	      continue;
1014918334Speter	    }
1015018334Speter	  break;
1015118334Speter
1015218334Speter	case PLUS:
1015318334Speter	  /* (eq (plus X A) B) -> (eq X (minus B A)).  We can only do
1015418334Speter	     this for equality comparisons due to pathological cases involving
1015518334Speter	     overflows.  */
1015618334Speter	  if (equality_comparison_p
1015718334Speter	      && 0 != (tem = simplify_binary_operation (MINUS, mode,
1015818334Speter							op1, XEXP (op0, 1))))
1015918334Speter	    {
1016018334Speter	      op0 = XEXP (op0, 0);
1016118334Speter	      op1 = tem;
1016218334Speter	      continue;
1016318334Speter	    }
1016418334Speter
1016518334Speter	  /* (plus (abs X) (const_int -1)) is < 0 if and only if X == 0.  */
1016618334Speter	  if (const_op == 0 && XEXP (op0, 1) == constm1_rtx
1016718334Speter	      && GET_CODE (XEXP (op0, 0)) == ABS && sign_bit_comparison_p)
1016818334Speter	    {
1016918334Speter	      op0 = XEXP (XEXP (op0, 0), 0);
1017018334Speter	      code = (code == LT ? EQ : NE);
1017118334Speter	      continue;
1017218334Speter	    }
1017318334Speter	  break;
1017418334Speter
1017518334Speter	case MINUS:
1017690075Sobrien	  /* We used to optimize signed comparisons against zero, but that
1017790075Sobrien	     was incorrect.  Unsigned comparisons against zero (GTU, LEU)
1017890075Sobrien	     arrive here as equality comparisons, or (GEU, LTU) are
1017990075Sobrien	     optimized away.  No need to special-case them.  */
1018090075Sobrien
1018118334Speter	  /* (eq (minus A B) C) -> (eq A (plus B C)) or
1018218334Speter	     (eq B (minus A C)), whichever simplifies.  We can only do
1018318334Speter	     this for equality comparisons due to pathological cases involving
1018418334Speter	     overflows.  */
1018518334Speter	  if (equality_comparison_p
1018618334Speter	      && 0 != (tem = simplify_binary_operation (PLUS, mode,
1018718334Speter							XEXP (op0, 1), op1)))
1018818334Speter	    {
1018918334Speter	      op0 = XEXP (op0, 0);
1019018334Speter	      op1 = tem;
1019118334Speter	      continue;
1019218334Speter	    }
1019318334Speter
1019418334Speter	  if (equality_comparison_p
1019518334Speter	      && 0 != (tem = simplify_binary_operation (MINUS, mode,
1019618334Speter							XEXP (op0, 0), op1)))
1019718334Speter	    {
1019818334Speter	      op0 = XEXP (op0, 1);
1019918334Speter	      op1 = tem;
1020018334Speter	      continue;
1020118334Speter	    }
1020218334Speter
1020318334Speter	  /* The sign bit of (minus (ashiftrt X C) X), where C is the number
1020418334Speter	     of bits in X minus 1, is one iff X > 0.  */
1020518334Speter	  if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 0)) == ASHIFTRT
1020618334Speter	      && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
10207117395Skan	      && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (op0, 0), 1))
10208117395Skan		 == mode_width - 1
1020918334Speter	      && rtx_equal_p (XEXP (XEXP (op0, 0), 0), XEXP (op0, 1)))
1021018334Speter	    {
1021118334Speter	      op0 = XEXP (op0, 1);
1021218334Speter	      code = (code == GE ? LE : GT);
1021318334Speter	      continue;
1021418334Speter	    }
1021518334Speter	  break;
1021618334Speter
1021718334Speter	case XOR:
1021818334Speter	  /* (eq (xor A B) C) -> (eq A (xor B C)).  This is a simplification
1021918334Speter	     if C is zero or B is a constant.  */
1022018334Speter	  if (equality_comparison_p
1022118334Speter	      && 0 != (tem = simplify_binary_operation (XOR, mode,
1022218334Speter							XEXP (op0, 1), op1)))
1022318334Speter	    {
1022418334Speter	      op0 = XEXP (op0, 0);
1022518334Speter	      op1 = tem;
1022618334Speter	      continue;
1022718334Speter	    }
1022818334Speter	  break;
1022918334Speter
1023018334Speter	case EQ:  case NE:
1023190075Sobrien	case UNEQ:  case LTGT:
1023290075Sobrien	case LT:  case LTU:  case UNLT:  case LE:  case LEU:  case UNLE:
1023390075Sobrien	case GT:  case GTU:  case UNGT:  case GE:  case GEU:  case UNGE:
10234169689Skan	case UNORDERED: case ORDERED:
1023518334Speter	  /* We can't do anything if OP0 is a condition code value, rather
1023618334Speter	     than an actual data value.  */
1023718334Speter	  if (const_op != 0
10238132718Skan	      || CC0_P (XEXP (op0, 0))
1023918334Speter	      || GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC)
1024018334Speter	    break;
1024118334Speter
1024218334Speter	  /* Get the two operands being compared.  */
1024318334Speter	  if (GET_CODE (XEXP (op0, 0)) == COMPARE)
1024418334Speter	    tem = XEXP (XEXP (op0, 0), 0), tem1 = XEXP (XEXP (op0, 0), 1);
1024518334Speter	  else
1024618334Speter	    tem = XEXP (op0, 0), tem1 = XEXP (op0, 1);
1024718334Speter
1024818334Speter	  /* Check for the cases where we simply want the result of the
1024918334Speter	     earlier test or the opposite of that result.  */
1025090075Sobrien	  if (code == NE || code == EQ
1025118334Speter	      || (GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT
1025218334Speter		  && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
1025318334Speter		  && (STORE_FLAG_VALUE
1025418334Speter		      & (((HOST_WIDE_INT) 1
1025518334Speter			  << (GET_MODE_BITSIZE (GET_MODE (op0)) - 1))))
1025690075Sobrien		  && (code == LT || code == GE)))
1025718334Speter	    {
1025890075Sobrien	      enum rtx_code new_code;
1025990075Sobrien	      if (code == LT || code == NE)
1026090075Sobrien		new_code = GET_CODE (op0);
1026190075Sobrien	      else
10262169689Skan		new_code = reversed_comparison_code (op0, NULL);
1026390075Sobrien
1026490075Sobrien	      if (new_code != UNKNOWN)
1026590075Sobrien		{
1026690075Sobrien		  code = new_code;
1026790075Sobrien		  op0 = tem;
1026890075Sobrien		  op1 = tem1;
1026990075Sobrien		  continue;
1027090075Sobrien		}
1027118334Speter	    }
1027218334Speter	  break;
1027318334Speter
1027418334Speter	case IOR:
10275117395Skan	  /* The sign bit of (ior (plus X (const_int -1)) X) is nonzero
1027618334Speter	     iff X <= 0.  */
1027718334Speter	  if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 0)) == PLUS
1027818334Speter	      && XEXP (XEXP (op0, 0), 1) == constm1_rtx
1027918334Speter	      && rtx_equal_p (XEXP (XEXP (op0, 0), 0), XEXP (op0, 1)))
1028018334Speter	    {
1028118334Speter	      op0 = XEXP (op0, 1);
1028218334Speter	      code = (code == GE ? GT : LE);
1028318334Speter	      continue;
1028418334Speter	    }
1028518334Speter	  break;
1028618334Speter
1028718334Speter	case AND:
1028818334Speter	  /* Convert (and (xshift 1 X) Y) to (and (lshiftrt Y X) 1).  This
1028918334Speter	     will be converted to a ZERO_EXTRACT later.  */
1029018334Speter	  if (const_op == 0 && equality_comparison_p
1029118334Speter	      && GET_CODE (XEXP (op0, 0)) == ASHIFT
1029218334Speter	      && XEXP (XEXP (op0, 0), 0) == const1_rtx)
1029318334Speter	    {
1029418334Speter	      op0 = simplify_and_const_int
10295169689Skan		(NULL_RTX, mode, gen_rtx_LSHIFTRT (mode,
10296169689Skan						   XEXP (op0, 1),
10297169689Skan						   XEXP (XEXP (op0, 0), 1)),
1029818334Speter		 (HOST_WIDE_INT) 1);
1029918334Speter	      continue;
1030018334Speter	    }
1030118334Speter
1030218334Speter	  /* If we are comparing (and (lshiftrt X C1) C2) for equality with
1030318334Speter	     zero and X is a comparison and C1 and C2 describe only bits set
1030418334Speter	     in STORE_FLAG_VALUE, we can compare with X.  */
1030518334Speter	  if (const_op == 0 && equality_comparison_p
1030618334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT
1030718334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1030818334Speter	      && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
1030918334Speter	      && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
1031018334Speter	      && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
1031118334Speter	      && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT)
1031218334Speter	    {
1031318334Speter	      mask = ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode))
1031418334Speter		      << INTVAL (XEXP (XEXP (op0, 0), 1)));
1031590075Sobrien	      if ((~STORE_FLAG_VALUE & mask) == 0
10316169689Skan		  && (COMPARISON_P (XEXP (XEXP (op0, 0), 0))
1031718334Speter		      || ((tem = get_last_value (XEXP (XEXP (op0, 0), 0))) != 0
10318169689Skan			  && COMPARISON_P (tem))))
1031918334Speter		{
1032018334Speter		  op0 = XEXP (XEXP (op0, 0), 0);
1032118334Speter		  continue;
1032218334Speter		}
1032318334Speter	    }
1032418334Speter
1032518334Speter	  /* If we are doing an equality comparison of an AND of a bit equal
1032618334Speter	     to the sign bit, replace this with a LT or GE comparison of
1032718334Speter	     the underlying value.  */
1032818334Speter	  if (equality_comparison_p
1032918334Speter	      && const_op == 0
1033018334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1033118334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT
1033218334Speter	      && ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode))
1033352284Sobrien		  == (unsigned HOST_WIDE_INT) 1 << (mode_width - 1)))
1033418334Speter	    {
1033518334Speter	      op0 = XEXP (op0, 0);
1033618334Speter	      code = (code == EQ ? GE : LT);
1033718334Speter	      continue;
1033818334Speter	    }
1033918334Speter
1034018334Speter	  /* If this AND operation is really a ZERO_EXTEND from a narrower
1034118334Speter	     mode, the constant fits within that mode, and this is either an
1034218334Speter	     equality or unsigned comparison, try to do this comparison in
10343169689Skan	     the narrower mode.
10344169689Skan
10345169689Skan	     Note that in:
10346169689Skan
10347169689Skan	     (ne:DI (and:DI (reg:DI 4) (const_int 0xffffffff)) (const_int 0))
10348169689Skan	     -> (ne:DI (reg:SI 4) (const_int 0))
10349169689Skan
10350169689Skan	     unless TRULY_NOOP_TRUNCATION allows it or the register is
10351169689Skan	     known to hold a value of the required mode the
10352169689Skan	     transformation is invalid.  */
1035318334Speter	  if ((equality_comparison_p || unsigned_comparison_p)
1035418334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1035518334Speter	      && (i = exact_log2 ((INTVAL (XEXP (op0, 1))
1035618334Speter				   & GET_MODE_MASK (mode))
1035718334Speter				  + 1)) >= 0
1035818334Speter	      && const_op >> i == 0
10359169689Skan	      && (tmode = mode_for_size (i, MODE_INT, 1)) != BLKmode
10360169689Skan	      && (TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (tmode),
10361169689Skan					 GET_MODE_BITSIZE (GET_MODE (op0)))
10362169689Skan		  || (REG_P (XEXP (op0, 0))
10363169689Skan		      && reg_truncated_to_mode (tmode, XEXP (op0, 0)))))
1036418334Speter	    {
10365169689Skan	      op0 = gen_lowpart (tmode, XEXP (op0, 0));
1036618334Speter	      continue;
1036718334Speter	    }
1036850397Sobrien
10369132718Skan	  /* If this is (and:M1 (subreg:M2 X 0) (const_int C1)) where C1
10370132718Skan	     fits in both M1 and M2 and the SUBREG is either paradoxical
10371132718Skan	     or represents the low part, permute the SUBREG and the AND
10372132718Skan	     and try again.  */
10373132718Skan	  if (GET_CODE (XEXP (op0, 0)) == SUBREG)
10374132718Skan	    {
10375132718Skan	      unsigned HOST_WIDE_INT c1;
10376132718Skan	      tmode = GET_MODE (SUBREG_REG (XEXP (op0, 0)));
10377117395Skan	      /* Require an integral mode, to avoid creating something like
10378117395Skan		 (AND:SF ...).  */
10379132718Skan	      if (SCALAR_INT_MODE_P (tmode)
10380132718Skan		  /* It is unsafe to commute the AND into the SUBREG if the
10381132718Skan		     SUBREG is paradoxical and WORD_REGISTER_OPERATIONS is
10382132718Skan		     not defined.  As originally written the upper bits
10383132718Skan		     have a defined value due to the AND operation.
10384132718Skan		     However, if we commute the AND inside the SUBREG then
10385132718Skan		     they no longer have defined values and the meaning of
10386132718Skan		     the code has been changed.  */
10387132718Skan		  && (0
1038850397Sobrien#ifdef WORD_REGISTER_OPERATIONS
10389132718Skan		      || (mode_width > GET_MODE_BITSIZE (tmode)
10390132718Skan			  && mode_width <= BITS_PER_WORD)
1039150397Sobrien#endif
10392132718Skan		      || (mode_width <= GET_MODE_BITSIZE (tmode)
10393132718Skan			  && subreg_lowpart_p (XEXP (op0, 0))))
10394132718Skan		  && GET_CODE (XEXP (op0, 1)) == CONST_INT
10395132718Skan		  && mode_width <= HOST_BITS_PER_WIDE_INT
10396132718Skan		  && GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT
10397132718Skan		  && ((c1 = INTVAL (XEXP (op0, 1))) & ~mask) == 0
10398132718Skan		  && (c1 & ~GET_MODE_MASK (tmode)) == 0
10399132718Skan		  && c1 != mask
10400132718Skan		  && c1 != GET_MODE_MASK (tmode))
10401132718Skan		{
10402169689Skan		  op0 = simplify_gen_binary (AND, tmode,
10403169689Skan					     SUBREG_REG (XEXP (op0, 0)),
10404169689Skan					     gen_int_mode (c1, tmode));
10405169689Skan		  op0 = gen_lowpart (mode, op0);
10406132718Skan		  continue;
10407132718Skan		}
10408132718Skan	    }
1040990075Sobrien
10410132718Skan	  /* Convert (ne (and (not X) 1) 0) to (eq (and X 1) 0).  */
10411132718Skan	  if (const_op == 0 && equality_comparison_p
10412132718Skan	      && XEXP (op0, 1) == const1_rtx
10413132718Skan	      && GET_CODE (XEXP (op0, 0)) == NOT)
1041450397Sobrien	    {
10415132718Skan	      op0 = simplify_and_const_int
10416132718Skan		(NULL_RTX, mode, XEXP (XEXP (op0, 0), 0), (HOST_WIDE_INT) 1);
10417132718Skan	      code = (code == NE ? EQ : NE);
1041850397Sobrien	      continue;
1041950397Sobrien	    }
1042050397Sobrien
1042190075Sobrien	  /* Convert (ne (and (lshiftrt (not X)) 1) 0) to
10422132718Skan	     (eq (and (lshiftrt X) 1) 0).
10423132718Skan	     Also handle the case where (not X) is expressed using xor.  */
1042490075Sobrien	  if (const_op == 0 && equality_comparison_p
1042590075Sobrien	      && XEXP (op0, 1) == const1_rtx
10426132718Skan	      && GET_CODE (XEXP (op0, 0)) == LSHIFTRT)
1042790075Sobrien	    {
10428132718Skan	      rtx shift_op = XEXP (XEXP (op0, 0), 0);
10429132718Skan	      rtx shift_count = XEXP (XEXP (op0, 0), 1);
10430132718Skan
10431132718Skan	      if (GET_CODE (shift_op) == NOT
10432132718Skan		  || (GET_CODE (shift_op) == XOR
10433132718Skan		      && GET_CODE (XEXP (shift_op, 1)) == CONST_INT
10434132718Skan		      && GET_CODE (shift_count) == CONST_INT
10435132718Skan		      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
10436132718Skan		      && (INTVAL (XEXP (shift_op, 1))
10437132718Skan			  == (HOST_WIDE_INT) 1 << INTVAL (shift_count))))
10438132718Skan		{
10439132718Skan		  op0 = simplify_and_const_int
10440132718Skan		    (NULL_RTX, mode,
10441132718Skan		     gen_rtx_LSHIFTRT (mode, XEXP (shift_op, 0), shift_count),
10442132718Skan		     (HOST_WIDE_INT) 1);
10443132718Skan		  code = (code == NE ? EQ : NE);
10444132718Skan		  continue;
10445132718Skan		}
1044690075Sobrien	    }
1044718334Speter	  break;
1044818334Speter
1044918334Speter	case ASHIFT:
1045018334Speter	  /* If we have (compare (ashift FOO N) (const_int C)) and
1045118334Speter	     the high order N bits of FOO (N+1 if an inequality comparison)
1045218334Speter	     are known to be zero, we can do this by comparing FOO with C
1045318334Speter	     shifted right N bits so long as the low-order N bits of C are
1045418334Speter	     zero.  */
1045518334Speter	  if (GET_CODE (XEXP (op0, 1)) == CONST_INT
1045618334Speter	      && INTVAL (XEXP (op0, 1)) >= 0
1045718334Speter	      && ((INTVAL (XEXP (op0, 1)) + ! equality_comparison_p)
1045818334Speter		  < HOST_BITS_PER_WIDE_INT)
1045918334Speter	      && ((const_op
1046018334Speter		   & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0)
1046118334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT
1046218334Speter	      && (nonzero_bits (XEXP (op0, 0), mode)
1046390075Sobrien		  & ~(mask >> (INTVAL (XEXP (op0, 1))
1046490075Sobrien			       + ! equality_comparison_p))) == 0)
1046518334Speter	    {
1046690075Sobrien	      /* We must perform a logical shift, not an arithmetic one,
1046790075Sobrien		 as we want the top N bits of C to be zero.  */
1046890075Sobrien	      unsigned HOST_WIDE_INT temp = const_op & GET_MODE_MASK (mode);
1046990075Sobrien
1047090075Sobrien	      temp >>= INTVAL (XEXP (op0, 1));
10471117395Skan	      op1 = gen_int_mode (temp, mode);
1047218334Speter	      op0 = XEXP (op0, 0);
1047318334Speter	      continue;
1047418334Speter	    }
1047518334Speter
1047618334Speter	  /* If we are doing a sign bit comparison, it means we are testing
1047718334Speter	     a particular bit.  Convert it to the appropriate AND.  */
1047818334Speter	  if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT
1047918334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT)
1048018334Speter	    {
1048118334Speter	      op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
1048218334Speter					    ((HOST_WIDE_INT) 1
1048318334Speter					     << (mode_width - 1
1048418334Speter						 - INTVAL (XEXP (op0, 1)))));
1048518334Speter	      code = (code == LT ? NE : EQ);
1048618334Speter	      continue;
1048718334Speter	    }
1048818334Speter
1048918334Speter	  /* If this an equality comparison with zero and we are shifting
1049018334Speter	     the low bit to the sign bit, we can convert this to an AND of the
1049118334Speter	     low-order bit.  */
1049218334Speter	  if (const_op == 0 && equality_comparison_p
1049318334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
10494117395Skan	      && (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1))
10495117395Skan		 == mode_width - 1)
1049618334Speter	    {
1049718334Speter	      op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
1049818334Speter					    (HOST_WIDE_INT) 1);
1049918334Speter	      continue;
1050018334Speter	    }
1050118334Speter	  break;
1050218334Speter
1050318334Speter	case ASHIFTRT:
1050418334Speter	  /* If this is an equality comparison with zero, we can do this
1050518334Speter	     as a logical shift, which might be much simpler.  */
1050618334Speter	  if (equality_comparison_p && const_op == 0
1050718334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT)
1050818334Speter	    {
1050918334Speter	      op0 = simplify_shift_const (NULL_RTX, LSHIFTRT, mode,
1051018334Speter					  XEXP (op0, 0),
1051118334Speter					  INTVAL (XEXP (op0, 1)));
1051218334Speter	      continue;
1051318334Speter	    }
1051418334Speter
1051518334Speter	  /* If OP0 is a sign extension and CODE is not an unsigned comparison,
1051618334Speter	     do the comparison in a narrower mode.  */
1051718334Speter	  if (! unsigned_comparison_p
1051818334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1051918334Speter	      && GET_CODE (XEXP (op0, 0)) == ASHIFT
1052018334Speter	      && XEXP (op0, 1) == XEXP (XEXP (op0, 0), 1)
1052118334Speter	      && (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)),
1052218334Speter					 MODE_INT, 1)) != BLKmode
1052396263Sobrien	      && (((unsigned HOST_WIDE_INT) const_op
1052496263Sobrien		   + (GET_MODE_MASK (tmode) >> 1) + 1)
1052596263Sobrien		  <= GET_MODE_MASK (tmode)))
1052618334Speter	    {
10527169689Skan	      op0 = gen_lowpart (tmode, XEXP (XEXP (op0, 0), 0));
1052818334Speter	      continue;
1052918334Speter	    }
1053018334Speter
1053190075Sobrien	  /* Likewise if OP0 is a PLUS of a sign extension with a
1053290075Sobrien	     constant, which is usually represented with the PLUS
1053390075Sobrien	     between the shifts.  */
1053490075Sobrien	  if (! unsigned_comparison_p
1053590075Sobrien	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1053690075Sobrien	      && GET_CODE (XEXP (op0, 0)) == PLUS
1053790075Sobrien	      && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
1053890075Sobrien	      && GET_CODE (XEXP (XEXP (op0, 0), 0)) == ASHIFT
1053990075Sobrien	      && XEXP (op0, 1) == XEXP (XEXP (XEXP (op0, 0), 0), 1)
1054090075Sobrien	      && (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)),
1054190075Sobrien					 MODE_INT, 1)) != BLKmode
1054296263Sobrien	      && (((unsigned HOST_WIDE_INT) const_op
1054396263Sobrien		   + (GET_MODE_MASK (tmode) >> 1) + 1)
1054496263Sobrien		  <= GET_MODE_MASK (tmode)))
1054590075Sobrien	    {
1054690075Sobrien	      rtx inner = XEXP (XEXP (XEXP (op0, 0), 0), 0);
1054790075Sobrien	      rtx add_const = XEXP (XEXP (op0, 0), 1);
10548169689Skan	      rtx new_const = simplify_gen_binary (ASHIFTRT, GET_MODE (op0),
10549169689Skan						   add_const, XEXP (op0, 1));
1055090075Sobrien
10551169689Skan	      op0 = simplify_gen_binary (PLUS, tmode,
10552169689Skan					 gen_lowpart (tmode, inner),
10553169689Skan					 new_const);
1055490075Sobrien	      continue;
1055590075Sobrien	    }
1055690075Sobrien
1055750397Sobrien	  /* ... fall through ...  */
1055818334Speter	case LSHIFTRT:
1055918334Speter	  /* If we have (compare (xshiftrt FOO N) (const_int C)) and
1056018334Speter	     the low order N bits of FOO are known to be zero, we can do this
1056118334Speter	     by comparing FOO with C shifted left N bits so long as no
1056218334Speter	     overflow occurs.  */
1056318334Speter	  if (GET_CODE (XEXP (op0, 1)) == CONST_INT
1056418334Speter	      && INTVAL (XEXP (op0, 1)) >= 0
1056518334Speter	      && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT
1056618334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT
1056718334Speter	      && (nonzero_bits (XEXP (op0, 0), mode)
1056818334Speter		  & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0
1056996263Sobrien	      && (((unsigned HOST_WIDE_INT) const_op
1057096263Sobrien		   + (GET_CODE (op0) != LSHIFTRT
1057196263Sobrien		      ? ((GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1)) >> 1)
1057296263Sobrien			 + 1)
1057396263Sobrien		      : 0))
1057496263Sobrien		  <= GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1))))
1057518334Speter	    {
1057696263Sobrien	      /* If the shift was logical, then we must make the condition
1057796263Sobrien		 unsigned.  */
1057896263Sobrien	      if (GET_CODE (op0) == LSHIFTRT)
1057996263Sobrien		code = unsigned_condition (code);
1058096263Sobrien
1058118334Speter	      const_op <<= INTVAL (XEXP (op0, 1));
1058218334Speter	      op1 = GEN_INT (const_op);
1058318334Speter	      op0 = XEXP (op0, 0);
1058418334Speter	      continue;
1058518334Speter	    }
1058618334Speter
1058718334Speter	  /* If we are using this shift to extract just the sign bit, we
1058818334Speter	     can replace this with an LT or GE comparison.  */
1058918334Speter	  if (const_op == 0
1059018334Speter	      && (equality_comparison_p || sign_bit_comparison_p)
1059118334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
10592117395Skan	      && (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1))
10593117395Skan		 == mode_width - 1)
1059418334Speter	    {
1059518334Speter	      op0 = XEXP (op0, 0);
1059618334Speter	      code = (code == NE || code == GT ? LT : GE);
1059718334Speter	      continue;
1059818334Speter	    }
1059918334Speter	  break;
1060090075Sobrien
1060150397Sobrien	default:
1060250397Sobrien	  break;
1060318334Speter	}
1060418334Speter
1060518334Speter      break;
1060618334Speter    }
1060718334Speter
1060818334Speter  /* Now make any compound operations involved in this comparison.  Then,
1060950397Sobrien     check for an outmost SUBREG on OP0 that is not doing anything or is
1061096263Sobrien     paradoxical.  The latter transformation must only be performed when
1061196263Sobrien     it is known that the "extra" bits will be the same in op0 and op1 or
1061296263Sobrien     that they don't matter.  There are three cases to consider:
1061318334Speter
1061496263Sobrien     1. SUBREG_REG (op0) is a register.  In this case the bits are don't
1061596263Sobrien     care bits and we can assume they have any convenient value.  So
1061696263Sobrien     making the transformation is safe.
1061796263Sobrien
1061896263Sobrien     2. SUBREG_REG (op0) is a memory and LOAD_EXTEND_OP is not defined.
1061996263Sobrien     In this case the upper bits of op0 are undefined.  We should not make
1062096263Sobrien     the simplification in that case as we do not know the contents of
1062196263Sobrien     those bits.
1062296263Sobrien
1062396263Sobrien     3. SUBREG_REG (op0) is a memory and LOAD_EXTEND_OP is defined and not
10624169689Skan     UNKNOWN.  In that case we know those bits are zeros or ones.  We must
1062596263Sobrien     also be sure that they are the same as the upper bits of op1.
1062696263Sobrien
1062796263Sobrien     We can never remove a SUBREG for a non-equality comparison because
1062896263Sobrien     the sign bit is in a different place in the underlying object.  */
1062996263Sobrien
1063018334Speter  op0 = make_compound_operation (op0, op1 == const0_rtx ? COMPARE : SET);
1063118334Speter  op1 = make_compound_operation (op1, SET);
1063218334Speter
1063318334Speter  if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0)
1063418334Speter      && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
1063590075Sobrien      && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT
1063696263Sobrien      && (code == NE || code == EQ))
1063718334Speter    {
1063896263Sobrien      if (GET_MODE_SIZE (GET_MODE (op0))
1063996263Sobrien	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))
1064096263Sobrien	{
10641132718Skan	  /* For paradoxical subregs, allow case 1 as above.  Case 3 isn't
10642132718Skan	     implemented.  */
10643169689Skan	  if (REG_P (SUBREG_REG (op0)))
10644132718Skan	    {
10645132718Skan	      op0 = SUBREG_REG (op0);
10646169689Skan	      op1 = gen_lowpart (GET_MODE (op0), op1);
10647132718Skan	    }
1064896263Sobrien	}
1064996263Sobrien      else if ((GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
1065096263Sobrien		<= HOST_BITS_PER_WIDE_INT)
1065196263Sobrien	       && (nonzero_bits (SUBREG_REG (op0),
1065296263Sobrien				 GET_MODE (SUBREG_REG (op0)))
1065396263Sobrien		   & ~GET_MODE_MASK (GET_MODE (op0))) == 0)
1065496263Sobrien	{
10655169689Skan	  tem = gen_lowpart (GET_MODE (SUBREG_REG (op0)), op1);
1065696263Sobrien
1065796263Sobrien	  if ((nonzero_bits (tem, GET_MODE (SUBREG_REG (op0)))
1065896263Sobrien	       & ~GET_MODE_MASK (GET_MODE (op0))) == 0)
1065996263Sobrien	    op0 = SUBREG_REG (op0), op1 = tem;
1066096263Sobrien	}
1066118334Speter    }
1066218334Speter
1066318334Speter  /* We now do the opposite procedure: Some machines don't have compare
1066418334Speter     insns in all modes.  If OP0's mode is an integer mode smaller than a
1066518334Speter     word and we can't do a compare in that mode, see if there is a larger
1066618334Speter     mode for which we can do the compare.  There are a number of cases in
1066718334Speter     which we can use the wider mode.  */
1066818334Speter
1066918334Speter  mode = GET_MODE (op0);
1067018334Speter  if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT
1067118334Speter      && GET_MODE_SIZE (mode) < UNITS_PER_WORD
1067290075Sobrien      && ! have_insn_for (COMPARE, mode))
1067318334Speter    for (tmode = GET_MODE_WIDER_MODE (mode);
1067418334Speter	 (tmode != VOIDmode
1067518334Speter	  && GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT);
1067618334Speter	 tmode = GET_MODE_WIDER_MODE (tmode))
1067790075Sobrien      if (have_insn_for (COMPARE, tmode))
1067818334Speter	{
1067996263Sobrien	  int zero_extended;
1068096263Sobrien
1068118334Speter	  /* If the only nonzero bits in OP0 and OP1 are those in the
1068218334Speter	     narrower mode and this is an equality or unsigned comparison,
1068318334Speter	     we can use the wider mode.  Similarly for sign-extended
1068418334Speter	     values, in which case it is true for all comparisons.  */
1068596263Sobrien	  zero_extended = ((code == EQ || code == NE
1068696263Sobrien			    || code == GEU || code == GTU
1068796263Sobrien			    || code == LEU || code == LTU)
1068896263Sobrien			   && (nonzero_bits (op0, tmode)
1068996263Sobrien			       & ~GET_MODE_MASK (mode)) == 0
1069096263Sobrien			   && ((GET_CODE (op1) == CONST_INT
1069196263Sobrien				|| (nonzero_bits (op1, tmode)
1069296263Sobrien				    & ~GET_MODE_MASK (mode)) == 0)));
1069396263Sobrien
1069496263Sobrien	  if (zero_extended
1069518334Speter	      || ((num_sign_bit_copies (op0, tmode)
10696117395Skan		   > (unsigned int) (GET_MODE_BITSIZE (tmode)
10697117395Skan				     - GET_MODE_BITSIZE (mode)))
1069818334Speter		  && (num_sign_bit_copies (op1, tmode)
10699117395Skan		      > (unsigned int) (GET_MODE_BITSIZE (tmode)
10700117395Skan					- GET_MODE_BITSIZE (mode)))))
1070118334Speter	    {
1070290075Sobrien	      /* If OP0 is an AND and we don't have an AND in MODE either,
1070390075Sobrien		 make a new AND in the proper mode.  */
1070490075Sobrien	      if (GET_CODE (op0) == AND
1070590075Sobrien		  && !have_insn_for (AND, mode))
10706169689Skan		op0 = simplify_gen_binary (AND, tmode,
10707169689Skan					   gen_lowpart (tmode,
10708169689Skan							XEXP (op0, 0)),
10709169689Skan					   gen_lowpart (tmode,
10710169689Skan							XEXP (op0, 1)));
1071190075Sobrien
10712169689Skan	      op0 = gen_lowpart (tmode, op0);
1071396263Sobrien	      if (zero_extended && GET_CODE (op1) == CONST_INT)
1071496263Sobrien		op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (mode));
10715169689Skan	      op1 = gen_lowpart (tmode, op1);
1071618334Speter	      break;
1071718334Speter	    }
1071818334Speter
1071918334Speter	  /* If this is a test for negative, we can make an explicit
1072018334Speter	     test of the sign bit.  */
1072118334Speter
1072218334Speter	  if (op1 == const0_rtx && (code == LT || code == GE)
1072318334Speter	      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
1072418334Speter	    {
10725169689Skan	      op0 = simplify_gen_binary (AND, tmode,
10726169689Skan					 gen_lowpart (tmode, op0),
10727169689Skan					 GEN_INT ((HOST_WIDE_INT) 1
10728169689Skan						  << (GET_MODE_BITSIZE (mode)
10729169689Skan						      - 1)));
1073018334Speter	      code = (code == LT) ? NE : EQ;
1073118334Speter	      break;
1073218334Speter	    }
1073318334Speter	}
1073418334Speter
1073518334Speter#ifdef CANONICALIZE_COMPARISON
1073618334Speter  /* If this machine only supports a subset of valid comparisons, see if we
1073718334Speter     can convert an unsupported one into a supported one.  */
1073818334Speter  CANONICALIZE_COMPARISON (code, op0, op1);
1073918334Speter#endif
1074018334Speter
1074118334Speter  *pop0 = op0;
1074218334Speter  *pop1 = op1;
1074318334Speter
1074418334Speter  return code;
1074518334Speter}
1074618334Speter
10747146895Skan/* Utility function for record_value_for_reg.  Count number of
10748146895Skan   rtxs in X.  */
10749146895Skanstatic int
10750146895Skancount_rtxs (rtx x)
10751146895Skan{
10752146895Skan  enum rtx_code code = GET_CODE (x);
10753146895Skan  const char *fmt;
10754146895Skan  int i, ret = 1;
10755146895Skan
10756146895Skan  if (GET_RTX_CLASS (code) == '2'
10757146895Skan      || GET_RTX_CLASS (code) == 'c')
10758146895Skan    {
10759146895Skan      rtx x0 = XEXP (x, 0);
10760146895Skan      rtx x1 = XEXP (x, 1);
10761146895Skan
10762146895Skan      if (x0 == x1)
10763146895Skan	return 1 + 2 * count_rtxs (x0);
10764146895Skan
10765146895Skan      if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
10766146895Skan	   || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
10767146895Skan	  && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
10768146895Skan	return 2 + 2 * count_rtxs (x0)
10769146895Skan	       + count_rtxs (x == XEXP (x1, 0)
10770146895Skan			     ? XEXP (x1, 1) : XEXP (x1, 0));
10771146895Skan
10772146895Skan      if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
10773146895Skan	   || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
10774146895Skan	  && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
10775146895Skan	return 2 + 2 * count_rtxs (x1)
10776146895Skan	       + count_rtxs (x == XEXP (x0, 0)
10777146895Skan			     ? XEXP (x0, 1) : XEXP (x0, 0));
10778146895Skan    }
10779146895Skan
10780146895Skan  fmt = GET_RTX_FORMAT (code);
10781146895Skan  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
10782146895Skan    if (fmt[i] == 'e')
10783146895Skan      ret += count_rtxs (XEXP (x, i));
10784146895Skan
10785146895Skan  return ret;
10786146895Skan}
10787146895Skan
1078818334Speter/* Utility function for following routine.  Called when X is part of a value
10789169689Skan   being stored into last_set_value.  Sets last_set_table_tick
1079018334Speter   for each register mentioned.  Similar to mention_regs in cse.c  */
1079118334Speter
1079218334Speterstatic void
10793132718Skanupdate_table_tick (rtx x)
1079418334Speter{
1079590075Sobrien  enum rtx_code code = GET_CODE (x);
1079690075Sobrien  const char *fmt = GET_RTX_FORMAT (code);
1079790075Sobrien  int i;
1079818334Speter
1079918334Speter  if (code == REG)
1080018334Speter    {
1080190075Sobrien      unsigned int regno = REGNO (x);
1080290075Sobrien      unsigned int endregno
1080390075Sobrien	= regno + (regno < FIRST_PSEUDO_REGISTER
10804169689Skan		   ? hard_regno_nregs[regno][GET_MODE (x)] : 1);
1080590075Sobrien      unsigned int r;
1080618334Speter
1080790075Sobrien      for (r = regno; r < endregno; r++)
10808169689Skan	reg_stat[r].last_set_table_tick = label_tick;
1080918334Speter
1081018334Speter      return;
1081118334Speter    }
1081290075Sobrien
1081318334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1081418334Speter    /* Note that we can't have an "E" in values stored; see
1081518334Speter       get_last_value_validate.  */
1081618334Speter    if (fmt[i] == 'e')
10817117395Skan      {
10818117395Skan	/* Check for identical subexpressions.  If x contains
10819117395Skan	   identical subexpression we only have to traverse one of
10820117395Skan	   them.  */
10821169689Skan	if (i == 0 && ARITHMETIC_P (x))
10822117395Skan	  {
10823117395Skan	    /* Note that at this point x1 has already been
10824117395Skan	       processed.  */
10825117395Skan	    rtx x0 = XEXP (x, 0);
10826117395Skan	    rtx x1 = XEXP (x, 1);
10827117395Skan
10828117395Skan	    /* If x0 and x1 are identical then there is no need to
10829117395Skan	       process x0.  */
10830117395Skan	    if (x0 == x1)
10831117395Skan	      break;
10832117395Skan
10833117395Skan	    /* If x0 is identical to a subexpression of x1 then while
10834117395Skan	       processing x1, x0 has already been processed.  Thus we
10835117395Skan	       are done with x.  */
10836169689Skan	    if (ARITHMETIC_P (x1)
10837117395Skan		&& (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
10838117395Skan	      break;
10839117395Skan
10840117395Skan	    /* If x1 is identical to a subexpression of x0 then we
10841117395Skan	       still have to process the rest of x0.  */
10842169689Skan	    if (ARITHMETIC_P (x0)
10843117395Skan		&& (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
10844117395Skan	      {
10845117395Skan		update_table_tick (XEXP (x0, x1 == XEXP (x0, 0) ? 1 : 0));
10846117395Skan		break;
10847117395Skan	      }
10848117395Skan	  }
10849132718Skan
10850117395Skan	update_table_tick (XEXP (x, i));
10851117395Skan      }
1085218334Speter}
1085318334Speter
1085418334Speter/* Record that REG is set to VALUE in insn INSN.  If VALUE is zero, we
1085518334Speter   are saying that the register is clobbered and we no longer know its
10856169689Skan   value.  If INSN is zero, don't update reg_stat[].last_set; this is
10857169689Skan   only permitted with VALUE also zero and is used to invalidate the
10858169689Skan   register.  */
1085918334Speter
1086018334Speterstatic void
10861132718Skanrecord_value_for_reg (rtx reg, rtx insn, rtx value)
1086218334Speter{
1086390075Sobrien  unsigned int regno = REGNO (reg);
1086490075Sobrien  unsigned int endregno
1086590075Sobrien    = regno + (regno < FIRST_PSEUDO_REGISTER
10866169689Skan	       ? hard_regno_nregs[regno][GET_MODE (reg)] : 1);
1086790075Sobrien  unsigned int i;
1086818334Speter
1086918334Speter  /* If VALUE contains REG and we have a previous value for REG, substitute
1087018334Speter     the previous value.  */
1087118334Speter  if (value && insn && reg_overlap_mentioned_p (reg, value))
1087218334Speter    {
1087318334Speter      rtx tem;
1087418334Speter
1087518334Speter      /* Set things up so get_last_value is allowed to see anything set up to
1087618334Speter	 our insn.  */
1087718334Speter      subst_low_cuid = INSN_CUID (insn);
1087890075Sobrien      tem = get_last_value (reg);
1087918334Speter
1088090075Sobrien      /* If TEM is simply a binary operation with two CLOBBERs as operands,
1088190075Sobrien	 it isn't going to be useful and will take a lot of time to process,
1088290075Sobrien	 so just use the CLOBBER.  */
1088390075Sobrien
1088418334Speter      if (tem)
1088590075Sobrien	{
10886169689Skan	  if (ARITHMETIC_P (tem)
1088790075Sobrien	      && GET_CODE (XEXP (tem, 0)) == CLOBBER
1088890075Sobrien	      && GET_CODE (XEXP (tem, 1)) == CLOBBER)
1088990075Sobrien	    tem = XEXP (tem, 0);
10890146895Skan	  else if (count_occurrences (value, reg, 1) >= 2)
10891146895Skan	    {
10892146895Skan	      /* If there are two or more occurrences of REG in VALUE,
10893146895Skan		 prevent the value from growing too much.  */
10894146895Skan	      if (count_rtxs (tem) > MAX_LAST_VALUE_RTL)
10895146895Skan		tem = gen_rtx_CLOBBER (GET_MODE (tem), const0_rtx);
10896146895Skan	    }
1089790075Sobrien
1089890075Sobrien	  value = replace_rtx (copy_rtx (value), reg, tem);
1089990075Sobrien	}
1090018334Speter    }
1090118334Speter
1090218334Speter  /* For each register modified, show we don't know its value, that
1090318334Speter     we don't know about its bitwise content, that its value has been
1090418334Speter     updated, and that we don't know the location of the death of the
1090518334Speter     register.  */
1090690075Sobrien  for (i = regno; i < endregno; i++)
1090718334Speter    {
1090818334Speter      if (insn)
10909169689Skan	reg_stat[i].last_set = insn;
1091090075Sobrien
10911169689Skan      reg_stat[i].last_set_value = 0;
10912169689Skan      reg_stat[i].last_set_mode = 0;
10913169689Skan      reg_stat[i].last_set_nonzero_bits = 0;
10914169689Skan      reg_stat[i].last_set_sign_bit_copies = 0;
10915169689Skan      reg_stat[i].last_death = 0;
10916169689Skan      reg_stat[i].truncated_to_mode = 0;
1091718334Speter    }
1091818334Speter
1091918334Speter  /* Mark registers that are being referenced in this value.  */
1092018334Speter  if (value)
1092118334Speter    update_table_tick (value);
1092218334Speter
1092318334Speter  /* Now update the status of each register being set.
1092418334Speter     If someone is using this register in this block, set this register
1092518334Speter     to invalid since we will get confused between the two lives in this
1092618334Speter     basic block.  This makes using this register always invalid.  In cse, we
1092718334Speter     scan the table to invalidate all entries using this register, but this
1092818334Speter     is too much work for us.  */
1092918334Speter
1093018334Speter  for (i = regno; i < endregno; i++)
1093118334Speter    {
10932169689Skan      reg_stat[i].last_set_label = label_tick;
10933169689Skan      if (!insn || (value && reg_stat[i].last_set_table_tick == label_tick))
10934169689Skan	reg_stat[i].last_set_invalid = 1;
1093518334Speter      else
10936169689Skan	reg_stat[i].last_set_invalid = 0;
1093718334Speter    }
1093818334Speter
1093918334Speter  /* The value being assigned might refer to X (like in "x++;").  In that
1094018334Speter     case, we must replace it with (clobber (const_int 0)) to prevent
1094118334Speter     infinite loops.  */
1094250397Sobrien  if (value && ! get_last_value_validate (&value, insn,
10943169689Skan					  reg_stat[regno].last_set_label, 0))
1094418334Speter    {
1094518334Speter      value = copy_rtx (value);
1094650397Sobrien      if (! get_last_value_validate (&value, insn,
10947169689Skan				     reg_stat[regno].last_set_label, 1))
1094818334Speter	value = 0;
1094918334Speter    }
1095018334Speter
1095118334Speter  /* For the main register being modified, update the value, the mode, the
1095218334Speter     nonzero bits, and the number of sign bit copies.  */
1095318334Speter
10954169689Skan  reg_stat[regno].last_set_value = value;
1095518334Speter
1095618334Speter  if (value)
1095718334Speter    {
1095896263Sobrien      enum machine_mode mode = GET_MODE (reg);
1095918334Speter      subst_low_cuid = INSN_CUID (insn);
10960169689Skan      reg_stat[regno].last_set_mode = mode;
1096196263Sobrien      if (GET_MODE_CLASS (mode) == MODE_INT
1096296263Sobrien	  && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
1096396263Sobrien	mode = nonzero_bits_mode;
10964169689Skan      reg_stat[regno].last_set_nonzero_bits = nonzero_bits (value, mode);
10965169689Skan      reg_stat[regno].last_set_sign_bit_copies
1096618334Speter	= num_sign_bit_copies (value, GET_MODE (reg));
1096718334Speter    }
1096818334Speter}
1096918334Speter
1097018334Speter/* Called via note_stores from record_dead_and_set_regs to handle one
1097190075Sobrien   SET or CLOBBER in an insn.  DATA is the instruction in which the
1097290075Sobrien   set is occurring.  */
1097318334Speter
1097418334Speterstatic void
10975132718Skanrecord_dead_and_set_regs_1 (rtx dest, rtx setter, void *data)
1097618334Speter{
1097790075Sobrien  rtx record_dead_insn = (rtx) data;
1097890075Sobrien
1097918334Speter  if (GET_CODE (dest) == SUBREG)
1098018334Speter    dest = SUBREG_REG (dest);
1098118334Speter
10982169689Skan  if (!record_dead_insn)
1098318334Speter    {
10984169689Skan      if (REG_P (dest))
10985169689Skan	record_value_for_reg (dest, NULL_RTX, NULL_RTX);
10986169689Skan      return;
10987169689Skan    }
10988169689Skan
10989169689Skan  if (REG_P (dest))
10990169689Skan    {
1099118334Speter      /* If we are setting the whole register, we know its value.  Otherwise
1099218334Speter	 show that we don't know the value.  We can handle SUBREG in
1099318334Speter	 some cases.  */
1099418334Speter      if (GET_CODE (setter) == SET && dest == SET_DEST (setter))
1099518334Speter	record_value_for_reg (dest, record_dead_insn, SET_SRC (setter));
1099618334Speter      else if (GET_CODE (setter) == SET
1099718334Speter	       && GET_CODE (SET_DEST (setter)) == SUBREG
1099818334Speter	       && SUBREG_REG (SET_DEST (setter)) == dest
1099918334Speter	       && GET_MODE_BITSIZE (GET_MODE (dest)) <= BITS_PER_WORD
1100018334Speter	       && subreg_lowpart_p (SET_DEST (setter)))
1100118334Speter	record_value_for_reg (dest, record_dead_insn,
11002169689Skan			      gen_lowpart (GET_MODE (dest),
1100318334Speter						       SET_SRC (setter)));
1100418334Speter      else
1100518334Speter	record_value_for_reg (dest, record_dead_insn, NULL_RTX);
1100618334Speter    }
11007169689Skan  else if (MEM_P (dest)
1100818334Speter	   /* Ignore pushes, they clobber nothing.  */
1100918334Speter	   && ! push_operand (dest, GET_MODE (dest)))
1101018334Speter    mem_last_set = INSN_CUID (record_dead_insn);
1101118334Speter}
1101218334Speter
1101318334Speter/* Update the records of when each REG was most recently set or killed
1101418334Speter   for the things done by INSN.  This is the last thing done in processing
1101518334Speter   INSN in the combiner loop.
1101618334Speter
11017169689Skan   We update reg_stat[], in particular fields last_set, last_set_value,
11018169689Skan   last_set_mode, last_set_nonzero_bits, last_set_sign_bit_copies,
11019169689Skan   last_death, and also the similar information mem_last_set (which insn
11020169689Skan   most recently modified memory) and last_call_cuid (which insn was the
11021169689Skan   most recent subroutine call).  */
1102218334Speter
1102318334Speterstatic void
11024132718Skanrecord_dead_and_set_regs (rtx insn)
1102518334Speter{
1102690075Sobrien  rtx link;
1102790075Sobrien  unsigned int i;
1102818334Speter
1102918334Speter  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1103018334Speter    {
1103118334Speter      if (REG_NOTE_KIND (link) == REG_DEAD
11032169689Skan	  && REG_P (XEXP (link, 0)))
1103318334Speter	{
1103490075Sobrien	  unsigned int regno = REGNO (XEXP (link, 0));
1103590075Sobrien	  unsigned int endregno
1103618334Speter	    = regno + (regno < FIRST_PSEUDO_REGISTER
11037169689Skan		       ? hard_regno_nregs[regno][GET_MODE (XEXP (link, 0))]
1103818334Speter		       : 1);
1103918334Speter
1104018334Speter	  for (i = regno; i < endregno; i++)
11041169689Skan	    reg_stat[i].last_death = insn;
1104218334Speter	}
1104318334Speter      else if (REG_NOTE_KIND (link) == REG_INC)
1104418334Speter	record_value_for_reg (XEXP (link, 0), insn, NULL_RTX);
1104518334Speter    }
1104618334Speter
11047169689Skan  if (CALL_P (insn))
1104818334Speter    {
1104918334Speter      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1105090075Sobrien	if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
1105118334Speter	  {
11052169689Skan	    reg_stat[i].last_set_value = 0;
11053169689Skan	    reg_stat[i].last_set_mode = 0;
11054169689Skan	    reg_stat[i].last_set_nonzero_bits = 0;
11055169689Skan	    reg_stat[i].last_set_sign_bit_copies = 0;
11056169689Skan	    reg_stat[i].last_death = 0;
11057169689Skan	    reg_stat[i].truncated_to_mode = 0;
1105818334Speter	  }
1105918334Speter
1106018334Speter      last_call_cuid = mem_last_set = INSN_CUID (insn);
1106190075Sobrien
11062169689Skan      /* We can't combine into a call pattern.  Remember, though, that
11063169689Skan	 the return value register is set at this CUID.  We could
11064169689Skan	 still replace a register with the return value from the
11065169689Skan	 wrong subroutine call!  */
11066169689Skan      note_stores (PATTERN (insn), record_dead_and_set_regs_1, NULL_RTX);
1106718334Speter    }
11068169689Skan  else
11069169689Skan    note_stores (PATTERN (insn), record_dead_and_set_regs_1, insn);
1107018334Speter}
1107190075Sobrien
1107290075Sobrien/* If a SUBREG has the promoted bit set, it is in fact a property of the
1107390075Sobrien   register present in the SUBREG, so for each such SUBREG go back and
1107490075Sobrien   adjust nonzero and sign bit information of the registers that are
1107590075Sobrien   known to have some zero/sign bits set.
1107690075Sobrien
1107790075Sobrien   This is needed because when combine blows the SUBREGs away, the
1107890075Sobrien   information on zero/sign bits is lost and further combines can be
1107990075Sobrien   missed because of that.  */
1108090075Sobrien
1108190075Sobrienstatic void
11082132718Skanrecord_promoted_value (rtx insn, rtx subreg)
1108390075Sobrien{
1108490075Sobrien  rtx links, set;
1108590075Sobrien  unsigned int regno = REGNO (SUBREG_REG (subreg));
1108690075Sobrien  enum machine_mode mode = GET_MODE (subreg);
1108790075Sobrien
1108890075Sobrien  if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
1108990075Sobrien    return;
1109090075Sobrien
1109190075Sobrien  for (links = LOG_LINKS (insn); links;)
1109290075Sobrien    {
1109390075Sobrien      insn = XEXP (links, 0);
1109490075Sobrien      set = single_set (insn);
1109590075Sobrien
11096169689Skan      if (! set || !REG_P (SET_DEST (set))
1109790075Sobrien	  || REGNO (SET_DEST (set)) != regno
1109890075Sobrien	  || GET_MODE (SET_DEST (set)) != GET_MODE (SUBREG_REG (subreg)))
1109990075Sobrien	{
1110090075Sobrien	  links = XEXP (links, 1);
1110190075Sobrien	  continue;
1110290075Sobrien	}
1110390075Sobrien
11104169689Skan      if (reg_stat[regno].last_set == insn)
1110590075Sobrien	{
11106117395Skan	  if (SUBREG_PROMOTED_UNSIGNED_P (subreg) > 0)
11107169689Skan	    reg_stat[regno].last_set_nonzero_bits &= GET_MODE_MASK (mode);
1110890075Sobrien	}
1110990075Sobrien
11110169689Skan      if (REG_P (SET_SRC (set)))
1111190075Sobrien	{
1111290075Sobrien	  regno = REGNO (SET_SRC (set));
1111390075Sobrien	  links = LOG_LINKS (insn);
1111490075Sobrien	}
1111590075Sobrien      else
1111690075Sobrien	break;
1111790075Sobrien    }
1111890075Sobrien}
1111990075Sobrien
11120169689Skan/* Check if X, a register, is known to contain a value already
11121169689Skan   truncated to MODE.  In this case we can use a subreg to refer to
11122169689Skan   the truncated value even though in the generic case we would need
11123169689Skan   an explicit truncation.  */
1112490075Sobrien
11125169689Skanstatic bool
11126169689Skanreg_truncated_to_mode (enum machine_mode mode, rtx x)
11127169689Skan{
11128169689Skan  enum machine_mode truncated = reg_stat[REGNO (x)].truncated_to_mode;
11129169689Skan
11130169689Skan  if (truncated == 0 || reg_stat[REGNO (x)].truncation_label != label_tick)
11131169689Skan    return false;
11132169689Skan  if (GET_MODE_SIZE (truncated) <= GET_MODE_SIZE (mode))
11133169689Skan    return true;
11134169689Skan  if (TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
11135169689Skan			     GET_MODE_BITSIZE (truncated)))
11136169689Skan    return true;
11137169689Skan  return false;
11138169689Skan}
11139169689Skan
11140169689Skan/* X is a REG or a SUBREG.  If X is some sort of a truncation record
11141169689Skan   it.  For non-TRULY_NOOP_TRUNCATION targets we might be able to turn
11142169689Skan   a truncate into a subreg using this information.  */
11143169689Skan
1114490075Sobrienstatic void
11145169689Skanrecord_truncated_value (rtx x)
1114690075Sobrien{
11147169689Skan  enum machine_mode truncated_mode;
11148169689Skan
11149169689Skan  if (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x)))
11150169689Skan    {
11151169689Skan      enum machine_mode original_mode = GET_MODE (SUBREG_REG (x));
11152169689Skan      truncated_mode = GET_MODE (x);
11153169689Skan
11154169689Skan      if (GET_MODE_SIZE (original_mode) <= GET_MODE_SIZE (truncated_mode))
11155169689Skan	return;
11156169689Skan
11157169689Skan      if (TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (truncated_mode),
11158169689Skan				 GET_MODE_BITSIZE (original_mode)))
11159169689Skan	return;
11160169689Skan
11161169689Skan      x = SUBREG_REG (x);
11162169689Skan    }
11163169689Skan  /* ??? For hard-regs we now record everything.  We might be able to
11164169689Skan     optimize this using last_set_mode.  */
11165169689Skan  else if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
11166169689Skan    truncated_mode = GET_MODE (x);
1116790075Sobrien  else
11168169689Skan    return;
11169169689Skan
11170169689Skan  if (reg_stat[REGNO (x)].truncated_to_mode == 0
11171169689Skan      || reg_stat[REGNO (x)].truncation_label < label_tick
11172169689Skan      || (GET_MODE_SIZE (truncated_mode)
11173169689Skan	  < GET_MODE_SIZE (reg_stat[REGNO (x)].truncated_to_mode)))
1117490075Sobrien    {
11175169689Skan      reg_stat[REGNO (x)].truncated_to_mode = truncated_mode;
11176169689Skan      reg_stat[REGNO (x)].truncation_label = label_tick;
11177169689Skan    }
11178169689Skan}
11179169689Skan
11180169689Skan/* Scan X for promoted SUBREGs and truncated REGs.  For each one
11181169689Skan   found, note what it implies to the registers used in it.  */
11182169689Skan
11183169689Skanstatic void
11184169689Skancheck_conversions (rtx insn, rtx x)
11185169689Skan{
11186169689Skan  if (GET_CODE (x) == SUBREG || REG_P (x))
11187169689Skan    {
11188169689Skan      if (GET_CODE (x) == SUBREG
11189169689Skan	  && SUBREG_PROMOTED_VAR_P (x)
11190169689Skan	  && REG_P (SUBREG_REG (x)))
11191169689Skan	record_promoted_value (insn, x);
11192169689Skan
11193169689Skan      record_truncated_value (x);
11194169689Skan    }
11195169689Skan  else
11196169689Skan    {
1119790075Sobrien      const char *format = GET_RTX_FORMAT (GET_CODE (x));
1119890075Sobrien      int i, j;
1119990075Sobrien
1120090075Sobrien      for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
1120190075Sobrien	switch (format[i])
1120290075Sobrien	  {
1120390075Sobrien	  case 'e':
11204169689Skan	    check_conversions (insn, XEXP (x, i));
1120590075Sobrien	    break;
1120690075Sobrien	  case 'V':
1120790075Sobrien	  case 'E':
1120890075Sobrien	    if (XVEC (x, i) != 0)
1120990075Sobrien	      for (j = 0; j < XVECLEN (x, i); j++)
11210169689Skan		check_conversions (insn, XVECEXP (x, i, j));
1121190075Sobrien	    break;
1121290075Sobrien	  }
1121390075Sobrien    }
1121490075Sobrien}
1121518334Speter
1121618334Speter/* Utility routine for the following function.  Verify that all the registers
1121718334Speter   mentioned in *LOC are valid when *LOC was part of a value set when
1121818334Speter   label_tick == TICK.  Return 0 if some are not.
1121918334Speter
11220117395Skan   If REPLACE is nonzero, replace the invalid reference with
1122118334Speter   (clobber (const_int 0)) and return 1.  This replacement is useful because
1122218334Speter   we often can get useful information about the form of a value (e.g., if
1122318334Speter   it was produced by a shift that always produces -1 or 0) even though
1122418334Speter   we don't know exactly what registers it was produced from.  */
1122518334Speter
1122618334Speterstatic int
11227132718Skanget_last_value_validate (rtx *loc, rtx insn, int tick, int replace)
1122818334Speter{
1122918334Speter  rtx x = *loc;
1123090075Sobrien  const char *fmt = GET_RTX_FORMAT (GET_CODE (x));
1123118334Speter  int len = GET_RTX_LENGTH (GET_CODE (x));
1123218334Speter  int i;
1123318334Speter
11234169689Skan  if (REG_P (x))
1123518334Speter    {
1123690075Sobrien      unsigned int regno = REGNO (x);
1123790075Sobrien      unsigned int endregno
1123890075Sobrien	= regno + (regno < FIRST_PSEUDO_REGISTER
11239169689Skan		   ? hard_regno_nregs[regno][GET_MODE (x)] : 1);
1124090075Sobrien      unsigned int j;
1124118334Speter
1124218334Speter      for (j = regno; j < endregno; j++)
11243169689Skan	if (reg_stat[j].last_set_invalid
1124490075Sobrien	    /* If this is a pseudo-register that was only set once and not
1124590075Sobrien	       live at the beginning of the function, it is always valid.  */
1124690075Sobrien	    || (! (regno >= FIRST_PSEUDO_REGISTER
1124790075Sobrien		   && REG_N_SETS (regno) == 1
1124890075Sobrien		   && (! REGNO_REG_SET_P
11249169689Skan		       (ENTRY_BLOCK_PTR->next_bb->il.rtl->global_live_at_start,
11250169689Skan			regno)))
11251169689Skan		&& reg_stat[j].last_set_label > tick))
1125218334Speter	  {
1125318334Speter	    if (replace)
1125450397Sobrien	      *loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
1125518334Speter	    return replace;
1125618334Speter	  }
1125718334Speter
1125818334Speter      return 1;
1125918334Speter    }
1126050397Sobrien  /* If this is a memory reference, make sure that there were
1126150397Sobrien     no stores after it that might have clobbered the value.  We don't
1126250397Sobrien     have alias info, so we assume any store invalidates it.  */
11263169689Skan  else if (MEM_P (x) && !MEM_READONLY_P (x)
1126450397Sobrien	   && INSN_CUID (insn) <= mem_last_set)
1126550397Sobrien    {
1126650397Sobrien      if (replace)
1126750397Sobrien	*loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
1126850397Sobrien      return replace;
1126950397Sobrien    }
1127018334Speter
1127118334Speter  for (i = 0; i < len; i++)
11272117395Skan    {
11273117395Skan      if (fmt[i] == 'e')
11274117395Skan	{
11275117395Skan	  /* Check for identical subexpressions.  If x contains
11276117395Skan	     identical subexpression we only have to traverse one of
11277117395Skan	     them.  */
11278169689Skan	  if (i == 1 && ARITHMETIC_P (x))
11279117395Skan	    {
11280117395Skan	      /* Note that at this point x0 has already been checked
11281117395Skan		 and found valid.  */
11282117395Skan	      rtx x0 = XEXP (x, 0);
11283117395Skan	      rtx x1 = XEXP (x, 1);
1128418334Speter
11285117395Skan	      /* If x0 and x1 are identical then x is also valid.  */
11286117395Skan	      if (x0 == x1)
11287117395Skan		return 1;
11288117395Skan
11289117395Skan	      /* If x1 is identical to a subexpression of x0 then
11290117395Skan		 while checking x0, x1 has already been checked.  Thus
11291117395Skan		 it is valid and so as x.  */
11292169689Skan	      if (ARITHMETIC_P (x0)
11293117395Skan		  && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
11294117395Skan		return 1;
11295117395Skan
11296117395Skan	      /* If x0 is identical to a subexpression of x1 then x is
11297117395Skan		 valid iff the rest of x1 is valid.  */
11298169689Skan	      if (ARITHMETIC_P (x1)
11299117395Skan		  && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
11300117395Skan		return
11301117395Skan		  get_last_value_validate (&XEXP (x1,
11302117395Skan						  x0 == XEXP (x1, 0) ? 1 : 0),
11303117395Skan					   insn, tick, replace);
11304117395Skan	    }
11305117395Skan
11306117395Skan	  if (get_last_value_validate (&XEXP (x, i), insn, tick,
11307117395Skan				       replace) == 0)
11308117395Skan	    return 0;
11309117395Skan	}
11310117395Skan      /* Don't bother with these.  They shouldn't occur anyway.  */
11311117395Skan      else if (fmt[i] == 'E')
11312117395Skan	return 0;
11313117395Skan    }
11314117395Skan
1131518334Speter  /* If we haven't found a reason for it to be invalid, it is valid.  */
1131618334Speter  return 1;
1131718334Speter}
1131818334Speter
1131918334Speter/* Get the last value assigned to X, if known.  Some registers
1132018334Speter   in the value may be replaced with (clobber (const_int 0)) if their value
1132118334Speter   is known longer known reliably.  */
1132218334Speter
1132318334Speterstatic rtx
11324132718Skanget_last_value (rtx x)
1132518334Speter{
1132690075Sobrien  unsigned int regno;
1132718334Speter  rtx value;
1132818334Speter
1132918334Speter  /* If this is a non-paradoxical SUBREG, get the value of its operand and
1133018334Speter     then convert it to the desired mode.  If this is a paradoxical SUBREG,
1133150397Sobrien     we cannot predict what values the "extra" bits might have.  */
1133218334Speter  if (GET_CODE (x) == SUBREG
1133318334Speter      && subreg_lowpart_p (x)
1133418334Speter      && (GET_MODE_SIZE (GET_MODE (x))
1133518334Speter	  <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
1133618334Speter      && (value = get_last_value (SUBREG_REG (x))) != 0)
11337169689Skan    return gen_lowpart (GET_MODE (x), value);
1133818334Speter
11339169689Skan  if (!REG_P (x))
1134018334Speter    return 0;
1134118334Speter
1134218334Speter  regno = REGNO (x);
11343169689Skan  value = reg_stat[regno].last_set_value;
1134418334Speter
1134590075Sobrien  /* If we don't have a value, or if it isn't for this basic block and
1134690075Sobrien     it's either a hard register, set more than once, or it's a live
1134790075Sobrien     at the beginning of the function, return 0.
1134818334Speter
1134990075Sobrien     Because if it's not live at the beginning of the function then the reg
1135090075Sobrien     is always set before being used (is never used without being set).
1135190075Sobrien     And, if it's set only once, and it's always set before use, then all
1135290075Sobrien     uses must have the same last value, even if it's not from this basic
1135390075Sobrien     block.  */
1135490075Sobrien
1135518334Speter  if (value == 0
11356169689Skan      || (reg_stat[regno].last_set_label != label_tick
1135790075Sobrien	  && (regno < FIRST_PSEUDO_REGISTER
1135890075Sobrien	      || REG_N_SETS (regno) != 1
1135990075Sobrien	      || (REGNO_REG_SET_P
11360169689Skan		  (ENTRY_BLOCK_PTR->next_bb->il.rtl->global_live_at_start,
11361169689Skan		   regno)))))
1136218334Speter    return 0;
1136318334Speter
1136418334Speter  /* If the value was set in a later insn than the ones we are processing,
1136552750Sobrien     we can't use it even if the register was only set once.  */
11366169689Skan  if (INSN_CUID (reg_stat[regno].last_set) >= subst_low_cuid)
1136752750Sobrien    return 0;
1136818334Speter
1136918334Speter  /* If the value has all its registers valid, return it.  */
11370169689Skan  if (get_last_value_validate (&value, reg_stat[regno].last_set,
11371169689Skan			       reg_stat[regno].last_set_label, 0))
1137218334Speter    return value;
1137318334Speter
1137418334Speter  /* Otherwise, make a copy and replace any invalid register with
1137518334Speter     (clobber (const_int 0)).  If that fails for some reason, return 0.  */
1137618334Speter
1137718334Speter  value = copy_rtx (value);
11378169689Skan  if (get_last_value_validate (&value, reg_stat[regno].last_set,
11379169689Skan			       reg_stat[regno].last_set_label, 1))
1138018334Speter    return value;
1138118334Speter
1138218334Speter  return 0;
1138318334Speter}
1138418334Speter
1138518334Speter/* Return nonzero if expression X refers to a REG or to memory
1138618334Speter   that is set in an instruction more recent than FROM_CUID.  */
1138718334Speter
1138818334Speterstatic int
11389132718Skanuse_crosses_set_p (rtx x, int from_cuid)
1139018334Speter{
1139190075Sobrien  const char *fmt;
1139290075Sobrien  int i;
1139390075Sobrien  enum rtx_code code = GET_CODE (x);
1139418334Speter
1139518334Speter  if (code == REG)
1139618334Speter    {
1139790075Sobrien      unsigned int regno = REGNO (x);
1139890075Sobrien      unsigned endreg = regno + (regno < FIRST_PSEUDO_REGISTER
11399169689Skan				 ? hard_regno_nregs[regno][GET_MODE (x)] : 1);
1140090075Sobrien
1140118334Speter#ifdef PUSH_ROUNDING
1140218334Speter      /* Don't allow uses of the stack pointer to be moved,
1140318334Speter	 because we don't know whether the move crosses a push insn.  */
1140490075Sobrien      if (regno == STACK_POINTER_REGNUM && PUSH_ARGS)
1140518334Speter	return 1;
1140618334Speter#endif
1140790075Sobrien      for (; regno < endreg; regno++)
11408169689Skan	if (reg_stat[regno].last_set
11409169689Skan	    && INSN_CUID (reg_stat[regno].last_set) > from_cuid)
1141018334Speter	  return 1;
1141118334Speter      return 0;
1141218334Speter    }
1141318334Speter
1141418334Speter  if (code == MEM && mem_last_set > from_cuid)
1141518334Speter    return 1;
1141618334Speter
1141718334Speter  fmt = GET_RTX_FORMAT (code);
1141818334Speter
1141918334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1142018334Speter    {
1142118334Speter      if (fmt[i] == 'E')
1142218334Speter	{
1142390075Sobrien	  int j;
1142418334Speter	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1142518334Speter	    if (use_crosses_set_p (XVECEXP (x, i, j), from_cuid))
1142618334Speter	      return 1;
1142718334Speter	}
1142818334Speter      else if (fmt[i] == 'e'
1142918334Speter	       && use_crosses_set_p (XEXP (x, i), from_cuid))
1143018334Speter	return 1;
1143118334Speter    }
1143218334Speter  return 0;
1143318334Speter}
1143418334Speter
1143518334Speter/* Define three variables used for communication between the following
1143618334Speter   routines.  */
1143718334Speter
1143890075Sobrienstatic unsigned int reg_dead_regno, reg_dead_endregno;
1143918334Speterstatic int reg_dead_flag;
1144018334Speter
1144118334Speter/* Function called via note_stores from reg_dead_at_p.
1144218334Speter
1144390075Sobrien   If DEST is within [reg_dead_regno, reg_dead_endregno), set
1144418334Speter   reg_dead_flag to 1 if X is a CLOBBER and to -1 it is a SET.  */
1144518334Speter
1144618334Speterstatic void
11447132718Skanreg_dead_at_p_1 (rtx dest, rtx x, void *data ATTRIBUTE_UNUSED)
1144818334Speter{
1144990075Sobrien  unsigned int regno, endregno;
1145018334Speter
11451169689Skan  if (!REG_P (dest))
1145218334Speter    return;
1145318334Speter
1145418334Speter  regno = REGNO (dest);
1145590075Sobrien  endregno = regno + (regno < FIRST_PSEUDO_REGISTER
11456169689Skan		      ? hard_regno_nregs[regno][GET_MODE (dest)] : 1);
1145718334Speter
1145818334Speter  if (reg_dead_endregno > regno && reg_dead_regno < endregno)
1145918334Speter    reg_dead_flag = (GET_CODE (x) == CLOBBER) ? 1 : -1;
1146018334Speter}
1146118334Speter
11462117395Skan/* Return nonzero if REG is known to be dead at INSN.
1146318334Speter
1146418334Speter   We scan backwards from INSN.  If we hit a REG_DEAD note or a CLOBBER
1146518334Speter   referencing REG, it is dead.  If we hit a SET referencing REG, it is
1146618334Speter   live.  Otherwise, see if it is live or dead at the start of the basic
1146718334Speter   block we are in.  Hard regs marked as being live in NEWPAT_USED_REGS
1146818334Speter   must be assumed to be always live.  */
1146918334Speter
1147018334Speterstatic int
11471132718Skanreg_dead_at_p (rtx reg, rtx insn)
1147218334Speter{
11473117395Skan  basic_block block;
1147490075Sobrien  unsigned int i;
1147518334Speter
1147618334Speter  /* Set variables for reg_dead_at_p_1.  */
1147718334Speter  reg_dead_regno = REGNO (reg);
1147818334Speter  reg_dead_endregno = reg_dead_regno + (reg_dead_regno < FIRST_PSEUDO_REGISTER
11479169689Skan					? hard_regno_nregs[reg_dead_regno]
11480169689Skan							  [GET_MODE (reg)]
1148118334Speter					: 1);
1148218334Speter
1148318334Speter  reg_dead_flag = 0;
1148418334Speter
11485169689Skan  /* Check that reg isn't mentioned in NEWPAT_USED_REGS.  For fixed registers
11486169689Skan     we allow the machine description to decide whether use-and-clobber
11487169689Skan     patterns are OK.  */
1148818334Speter  if (reg_dead_regno < FIRST_PSEUDO_REGISTER)
1148918334Speter    {
1149018334Speter      for (i = reg_dead_regno; i < reg_dead_endregno; i++)
11491169689Skan	if (!fixed_regs[i] && TEST_HARD_REG_BIT (newpat_used_regs, i))
1149218334Speter	  return 0;
1149318334Speter    }
1149418334Speter
1149518334Speter  /* Scan backwards until we find a REG_DEAD note, SET, CLOBBER, label, or
1149618334Speter     beginning of function.  */
11497169689Skan  for (; insn && !LABEL_P (insn) && !BARRIER_P (insn);
1149818334Speter       insn = prev_nonnote_insn (insn))
1149918334Speter    {
1150090075Sobrien      note_stores (PATTERN (insn), reg_dead_at_p_1, NULL);
1150118334Speter      if (reg_dead_flag)
1150218334Speter	return reg_dead_flag == 1 ? 1 : 0;
1150318334Speter
1150418334Speter      if (find_regno_note (insn, REG_DEAD, reg_dead_regno))
1150518334Speter	return 1;
1150618334Speter    }
1150718334Speter
11508117395Skan  /* Get the basic block that we were in.  */
1150918334Speter  if (insn == 0)
11510117395Skan    block = ENTRY_BLOCK_PTR->next_bb;
1151118334Speter  else
1151218334Speter    {
11513117395Skan      FOR_EACH_BB (block)
11514132718Skan	if (insn == BB_HEAD (block))
1151518334Speter	  break;
1151618334Speter
11517117395Skan      if (block == EXIT_BLOCK_PTR)
1151818334Speter	return 0;
1151918334Speter    }
1152018334Speter
1152118334Speter  for (i = reg_dead_regno; i < reg_dead_endregno; i++)
11522169689Skan    if (REGNO_REG_SET_P (block->il.rtl->global_live_at_start, i))
1152318334Speter      return 0;
1152418334Speter
1152518334Speter  return 1;
1152618334Speter}
1152718334Speter
1152818334Speter/* Note hard registers in X that are used.  This code is similar to
1152918334Speter   that in flow.c, but much simpler since we don't care about pseudos.  */
1153018334Speter
1153118334Speterstatic void
11532132718Skanmark_used_regs_combine (rtx x)
1153318334Speter{
1153490075Sobrien  RTX_CODE code = GET_CODE (x);
1153590075Sobrien  unsigned int regno;
1153618334Speter  int i;
1153718334Speter
1153818334Speter  switch (code)
1153918334Speter    {
1154018334Speter    case LABEL_REF:
1154118334Speter    case SYMBOL_REF:
1154218334Speter    case CONST_INT:
1154318334Speter    case CONST:
1154418334Speter    case CONST_DOUBLE:
1154596263Sobrien    case CONST_VECTOR:
1154618334Speter    case PC:
1154718334Speter    case ADDR_VEC:
1154818334Speter    case ADDR_DIFF_VEC:
1154918334Speter    case ASM_INPUT:
1155018334Speter#ifdef HAVE_cc0
1155118334Speter    /* CC0 must die in the insn after it is set, so we don't need to take
1155218334Speter       special note of it here.  */
1155318334Speter    case CC0:
1155418334Speter#endif
1155518334Speter      return;
1155618334Speter
1155718334Speter    case CLOBBER:
1155818334Speter      /* If we are clobbering a MEM, mark any hard registers inside the
1155918334Speter	 address as used.  */
11560169689Skan      if (MEM_P (XEXP (x, 0)))
1156118334Speter	mark_used_regs_combine (XEXP (XEXP (x, 0), 0));
1156218334Speter      return;
1156318334Speter
1156418334Speter    case REG:
1156518334Speter      regno = REGNO (x);
1156618334Speter      /* A hard reg in a wide mode may really be multiple registers.
1156718334Speter	 If so, mark all of them just like the first.  */
1156818334Speter      if (regno < FIRST_PSEUDO_REGISTER)
1156918334Speter	{
1157090075Sobrien	  unsigned int endregno, r;
1157190075Sobrien
11572117395Skan	  /* None of this applies to the stack, frame or arg pointers.  */
1157318334Speter	  if (regno == STACK_POINTER_REGNUM
1157418334Speter#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
1157518334Speter	      || regno == HARD_FRAME_POINTER_REGNUM
1157618334Speter#endif
1157718334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
1157818334Speter	      || (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
1157918334Speter#endif
1158018334Speter	      || regno == FRAME_POINTER_REGNUM)
1158118334Speter	    return;
1158218334Speter
11583169689Skan	  endregno = regno + hard_regno_nregs[regno][GET_MODE (x)];
1158490075Sobrien	  for (r = regno; r < endregno; r++)
1158590075Sobrien	    SET_HARD_REG_BIT (newpat_used_regs, r);
1158618334Speter	}
1158718334Speter      return;
1158818334Speter
1158918334Speter    case SET:
1159018334Speter      {
1159118334Speter	/* If setting a MEM, or a SUBREG of a MEM, then note any hard regs in
1159218334Speter	   the address.  */
1159390075Sobrien	rtx testreg = SET_DEST (x);
1159418334Speter
1159518334Speter	while (GET_CODE (testreg) == SUBREG
1159618334Speter	       || GET_CODE (testreg) == ZERO_EXTRACT
1159718334Speter	       || GET_CODE (testreg) == STRICT_LOW_PART)
1159818334Speter	  testreg = XEXP (testreg, 0);
1159918334Speter
11600169689Skan	if (MEM_P (testreg))
1160118334Speter	  mark_used_regs_combine (XEXP (testreg, 0));
1160218334Speter
1160318334Speter	mark_used_regs_combine (SET_SRC (x));
1160418334Speter      }
1160550397Sobrien      return;
1160650397Sobrien
1160750397Sobrien    default:
1160850397Sobrien      break;
1160918334Speter    }
1161018334Speter
1161118334Speter  /* Recursively scan the operands of this expression.  */
1161218334Speter
1161318334Speter  {
1161490075Sobrien    const char *fmt = GET_RTX_FORMAT (code);
1161518334Speter
1161618334Speter    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1161718334Speter      {
1161890075Sobrien	if (fmt[i] == 'e')
1161918334Speter	  mark_used_regs_combine (XEXP (x, i));
1162090075Sobrien	else if (fmt[i] == 'E')
1162190075Sobrien	  {
1162290075Sobrien	    int j;
1162318334Speter
1162490075Sobrien	    for (j = 0; j < XVECLEN (x, i); j++)
1162590075Sobrien	      mark_used_regs_combine (XVECEXP (x, i, j));
1162690075Sobrien	  }
1162718334Speter      }
1162818334Speter  }
1162918334Speter}
1163018334Speter
1163118334Speter/* Remove register number REGNO from the dead registers list of INSN.
1163218334Speter
1163318334Speter   Return the note used to record the death, if there was one.  */
1163418334Speter
1163518334Speterrtx
11636132718Skanremove_death (unsigned int regno, rtx insn)
1163718334Speter{
1163890075Sobrien  rtx note = find_regno_note (insn, REG_DEAD, regno);
1163918334Speter
1164018334Speter  if (note)
1164118334Speter    {
1164250397Sobrien      REG_N_DEATHS (regno)--;
1164318334Speter      remove_note (insn, note);
1164418334Speter    }
1164518334Speter
1164618334Speter  return note;
1164718334Speter}
1164818334Speter
1164918334Speter/* For each register (hardware or pseudo) used within expression X, if its
1165018334Speter   death is in an instruction with cuid between FROM_CUID (inclusive) and
1165118334Speter   TO_INSN (exclusive), put a REG_DEAD note for that register in the
1165290075Sobrien   list headed by PNOTES.
1165318334Speter
1165450397Sobrien   That said, don't move registers killed by maybe_kill_insn.
1165550397Sobrien
1165618334Speter   This is done when X is being merged by combination into TO_INSN.  These
1165718334Speter   notes will then be distributed as needed.  */
1165818334Speter
1165918334Speterstatic void
11660132718Skanmove_deaths (rtx x, rtx maybe_kill_insn, int from_cuid, rtx to_insn,
11661132718Skan	     rtx *pnotes)
1166218334Speter{
1166390075Sobrien  const char *fmt;
1166490075Sobrien  int len, i;
1166590075Sobrien  enum rtx_code code = GET_CODE (x);
1166618334Speter
1166718334Speter  if (code == REG)
1166818334Speter    {
1166990075Sobrien      unsigned int regno = REGNO (x);
11670169689Skan      rtx where_dead = reg_stat[regno].last_death;
1167190075Sobrien      rtx before_dead, after_dead;
1167218334Speter
11673117395Skan      /* Don't move the register if it gets killed in between from and to.  */
1167450397Sobrien      if (maybe_kill_insn && reg_set_p (x, maybe_kill_insn)
1167590075Sobrien	  && ! reg_referenced_p (x, maybe_kill_insn))
1167650397Sobrien	return;
1167750397Sobrien
1167818334Speter      /* WHERE_DEAD could be a USE insn made by combine, so first we
1167918334Speter	 make sure that we have insns with valid INSN_CUID values.  */
1168018334Speter      before_dead = where_dead;
1168118334Speter      while (before_dead && INSN_UID (before_dead) > max_uid_cuid)
1168218334Speter	before_dead = PREV_INSN (before_dead);
1168390075Sobrien
1168418334Speter      after_dead = where_dead;
1168518334Speter      while (after_dead && INSN_UID (after_dead) > max_uid_cuid)
1168618334Speter	after_dead = NEXT_INSN (after_dead);
1168718334Speter
1168818334Speter      if (before_dead && after_dead
1168918334Speter	  && INSN_CUID (before_dead) >= from_cuid
1169018334Speter	  && (INSN_CUID (after_dead) < INSN_CUID (to_insn)
1169118334Speter	      || (where_dead != after_dead
1169218334Speter		  && INSN_CUID (after_dead) == INSN_CUID (to_insn))))
1169318334Speter	{
1169418334Speter	  rtx note = remove_death (regno, where_dead);
1169518334Speter
1169618334Speter	  /* It is possible for the call above to return 0.  This can occur
11697169689Skan	     when last_death points to I2 or I1 that we combined with.
1169818334Speter	     In that case make a new note.
1169918334Speter
1170018334Speter	     We must also check for the case where X is a hard register
1170118334Speter	     and NOTE is a death note for a range of hard registers
1170218334Speter	     including X.  In that case, we must put REG_DEAD notes for
1170318334Speter	     the remaining registers in place of NOTE.  */
1170418334Speter
1170518334Speter	  if (note != 0 && regno < FIRST_PSEUDO_REGISTER
1170618334Speter	      && (GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
1170750397Sobrien		  > GET_MODE_SIZE (GET_MODE (x))))
1170818334Speter	    {
1170990075Sobrien	      unsigned int deadregno = REGNO (XEXP (note, 0));
1171090075Sobrien	      unsigned int deadend
11711169689Skan		= (deadregno + hard_regno_nregs[deadregno]
11712169689Skan					       [GET_MODE (XEXP (note, 0))]);
1171390075Sobrien	      unsigned int ourend
11714169689Skan		= regno + hard_regno_nregs[regno][GET_MODE (x)];
1171590075Sobrien	      unsigned int i;
1171618334Speter
1171718334Speter	      for (i = deadregno; i < deadend; i++)
1171818334Speter		if (i < regno || i >= ourend)
1171918334Speter		  REG_NOTES (where_dead)
1172050397Sobrien		    = gen_rtx_EXPR_LIST (REG_DEAD,
11721117395Skan					 regno_reg_rtx[i],
1172250397Sobrien					 REG_NOTES (where_dead));
1172318334Speter	    }
1172490075Sobrien
1172550397Sobrien	  /* If we didn't find any note, or if we found a REG_DEAD note that
1172650397Sobrien	     covers only part of the given reg, and we have a multi-reg hard
1172718334Speter	     register, then to be safe we must check for REG_DEAD notes
1172818334Speter	     for each register other than the first.  They could have
1172918334Speter	     their own REG_DEAD notes lying around.  */
1173050397Sobrien	  else if ((note == 0
1173150397Sobrien		    || (note != 0
1173250397Sobrien			&& (GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
1173350397Sobrien			    < GET_MODE_SIZE (GET_MODE (x)))))
1173450397Sobrien		   && regno < FIRST_PSEUDO_REGISTER
11735169689Skan		   && hard_regno_nregs[regno][GET_MODE (x)] > 1)
1173618334Speter	    {
1173790075Sobrien	      unsigned int ourend
11738169689Skan		= regno + hard_regno_nregs[regno][GET_MODE (x)];
1173990075Sobrien	      unsigned int i, offset;
1174018334Speter	      rtx oldnotes = 0;
1174118334Speter
1174250397Sobrien	      if (note)
11743169689Skan		offset = hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))];
1174450397Sobrien	      else
1174550397Sobrien		offset = 1;
1174650397Sobrien
1174750397Sobrien	      for (i = regno + offset; i < ourend; i++)
11748117395Skan		move_deaths (regno_reg_rtx[i],
1174950397Sobrien			     maybe_kill_insn, from_cuid, to_insn, &oldnotes);
1175018334Speter	    }
1175118334Speter
1175218334Speter	  if (note != 0 && GET_MODE (XEXP (note, 0)) == GET_MODE (x))
1175318334Speter	    {
1175418334Speter	      XEXP (note, 1) = *pnotes;
1175518334Speter	      *pnotes = note;
1175618334Speter	    }
1175718334Speter	  else
1175850397Sobrien	    *pnotes = gen_rtx_EXPR_LIST (REG_DEAD, x, *pnotes);
1175918334Speter
1176050397Sobrien	  REG_N_DEATHS (regno)++;
1176118334Speter	}
1176218334Speter
1176318334Speter      return;
1176418334Speter    }
1176518334Speter
1176618334Speter  else if (GET_CODE (x) == SET)
1176718334Speter    {
1176818334Speter      rtx dest = SET_DEST (x);
1176918334Speter
1177050397Sobrien      move_deaths (SET_SRC (x), maybe_kill_insn, from_cuid, to_insn, pnotes);
1177118334Speter
1177218334Speter      /* In the case of a ZERO_EXTRACT, a STRICT_LOW_PART, or a SUBREG
1177318334Speter	 that accesses one word of a multi-word item, some
1177418334Speter	 piece of everything register in the expression is used by
1177518334Speter	 this insn, so remove any old death.  */
1177690075Sobrien      /* ??? So why do we test for equality of the sizes?  */
1177718334Speter
1177818334Speter      if (GET_CODE (dest) == ZERO_EXTRACT
1177918334Speter	  || GET_CODE (dest) == STRICT_LOW_PART
1178018334Speter	  || (GET_CODE (dest) == SUBREG
1178118334Speter	      && (((GET_MODE_SIZE (GET_MODE (dest))
1178218334Speter		    + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
1178318334Speter		  == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
1178418334Speter		       + UNITS_PER_WORD - 1) / UNITS_PER_WORD))))
1178518334Speter	{
1178650397Sobrien	  move_deaths (dest, maybe_kill_insn, from_cuid, to_insn, pnotes);
1178718334Speter	  return;
1178818334Speter	}
1178918334Speter
1179018334Speter      /* If this is some other SUBREG, we know it replaces the entire
1179118334Speter	 value, so use that as the destination.  */
1179218334Speter      if (GET_CODE (dest) == SUBREG)
1179318334Speter	dest = SUBREG_REG (dest);
1179418334Speter
1179518334Speter      /* If this is a MEM, adjust deaths of anything used in the address.
1179618334Speter	 For a REG (the only other possibility), the entire value is
1179718334Speter	 being replaced so the old value is not used in this insn.  */
1179818334Speter
11799169689Skan      if (MEM_P (dest))
1180050397Sobrien	move_deaths (XEXP (dest, 0), maybe_kill_insn, from_cuid,
1180150397Sobrien		     to_insn, pnotes);
1180218334Speter      return;
1180318334Speter    }
1180418334Speter
1180518334Speter  else if (GET_CODE (x) == CLOBBER)
1180618334Speter    return;
1180718334Speter
1180818334Speter  len = GET_RTX_LENGTH (code);
1180918334Speter  fmt = GET_RTX_FORMAT (code);
1181018334Speter
1181118334Speter  for (i = 0; i < len; i++)
1181218334Speter    {
1181318334Speter      if (fmt[i] == 'E')
1181418334Speter	{
1181590075Sobrien	  int j;
1181618334Speter	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1181750397Sobrien	    move_deaths (XVECEXP (x, i, j), maybe_kill_insn, from_cuid,
1181850397Sobrien			 to_insn, pnotes);
1181918334Speter	}
1182018334Speter      else if (fmt[i] == 'e')
1182150397Sobrien	move_deaths (XEXP (x, i), maybe_kill_insn, from_cuid, to_insn, pnotes);
1182218334Speter    }
1182318334Speter}
1182418334Speter
1182518334Speter/* Return 1 if X is the target of a bit-field assignment in BODY, the
1182618334Speter   pattern of an insn.  X must be a REG.  */
1182718334Speter
1182818334Speterstatic int
11829132718Skanreg_bitfield_target_p (rtx x, rtx body)
1183018334Speter{
1183118334Speter  int i;
1183218334Speter
1183318334Speter  if (GET_CODE (body) == SET)
1183418334Speter    {
1183518334Speter      rtx dest = SET_DEST (body);
1183618334Speter      rtx target;
1183790075Sobrien      unsigned int regno, tregno, endregno, endtregno;
1183818334Speter
1183918334Speter      if (GET_CODE (dest) == ZERO_EXTRACT)
1184018334Speter	target = XEXP (dest, 0);
1184118334Speter      else if (GET_CODE (dest) == STRICT_LOW_PART)
1184218334Speter	target = SUBREG_REG (XEXP (dest, 0));
1184318334Speter      else
1184418334Speter	return 0;
1184518334Speter
1184618334Speter      if (GET_CODE (target) == SUBREG)
1184718334Speter	target = SUBREG_REG (target);
1184818334Speter
11849169689Skan      if (!REG_P (target))
1185018334Speter	return 0;
1185118334Speter
1185218334Speter      tregno = REGNO (target), regno = REGNO (x);
1185318334Speter      if (tregno >= FIRST_PSEUDO_REGISTER || regno >= FIRST_PSEUDO_REGISTER)
1185418334Speter	return target == x;
1185518334Speter
11856169689Skan      endtregno = tregno + hard_regno_nregs[tregno][GET_MODE (target)];
11857169689Skan      endregno = regno + hard_regno_nregs[regno][GET_MODE (x)];
1185818334Speter
1185918334Speter      return endregno > tregno && regno < endtregno;
1186018334Speter    }
1186118334Speter
1186218334Speter  else if (GET_CODE (body) == PARALLEL)
1186318334Speter    for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
1186418334Speter      if (reg_bitfield_target_p (x, XVECEXP (body, 0, i)))
1186518334Speter	return 1;
1186618334Speter
1186718334Speter  return 0;
1186890075Sobrien}
1186918334Speter
1187018334Speter/* Given a chain of REG_NOTES originally from FROM_INSN, try to place them
1187118334Speter   as appropriate.  I3 and I2 are the insns resulting from the combination
1187218334Speter   insns including FROM (I2 may be zero).
1187318334Speter
11874169689Skan   ELIM_I2 and ELIM_I1 are either zero or registers that we know will
11875169689Skan   not need REG_DEAD notes because they are being substituted for.  This
11876169689Skan   saves searching in the most common cases.
11877169689Skan
1187818334Speter   Each note in the list is either ignored or placed on some insns, depending
1187918334Speter   on the type of note.  */
1188018334Speter
1188118334Speterstatic void
11882169689Skandistribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
11883169689Skan		  rtx elim_i1)
1188418334Speter{
1188518334Speter  rtx note, next_note;
1188618334Speter  rtx tem;
1188718334Speter
1188818334Speter  for (note = notes; note; note = next_note)
1188918334Speter    {
1189018334Speter      rtx place = 0, place2 = 0;
1189118334Speter
1189218334Speter      next_note = XEXP (note, 1);
1189318334Speter      switch (REG_NOTE_KIND (note))
1189418334Speter	{
1189550397Sobrien	case REG_BR_PROB:
1189690075Sobrien	case REG_BR_PRED:
1189750397Sobrien	  /* Doesn't matter much where we put this, as long as it's somewhere.
1189850397Sobrien	     It is preferable to keep these notes on branches, which is most
1189950397Sobrien	     likely to be i3.  */
1190050397Sobrien	  place = i3;
1190150397Sobrien	  break;
1190250397Sobrien
11903132718Skan	case REG_VALUE_PROFILE:
11904132718Skan	  /* Just get rid of this note, as it is unused later anyway.  */
11905132718Skan	  break;
11906132718Skan
1190790075Sobrien	case REG_NON_LOCAL_GOTO:
11908169689Skan	  if (JUMP_P (i3))
1190990075Sobrien	    place = i3;
1191090075Sobrien	  else
11911169689Skan	    {
11912169689Skan	      gcc_assert (i2 && JUMP_P (i2));
11913169689Skan	      place = i2;
11914169689Skan	    }
1191590075Sobrien	  break;
1191690075Sobrien
1191752284Sobrien	case REG_EH_REGION:
1191890075Sobrien	  /* These notes must remain with the call or trapping instruction.  */
11919169689Skan	  if (CALL_P (i3))
1192052284Sobrien	    place = i3;
11921169689Skan	  else if (i2 && CALL_P (i2))
1192252284Sobrien	    place = i2;
11923169689Skan	  else
1192490075Sobrien	    {
11925169689Skan	      gcc_assert (flag_non_call_exceptions);
1192690075Sobrien	      if (may_trap_p (i3))
1192790075Sobrien		place = i3;
1192890075Sobrien	      else if (i2 && may_trap_p (i2))
1192990075Sobrien		place = i2;
1193090075Sobrien	      /* ??? Otherwise assume we've combined things such that we
1193190075Sobrien		 can now prove that the instructions can't trap.  Drop the
1193290075Sobrien		 note in this case.  */
1193390075Sobrien	    }
1193452284Sobrien	  break;
1193552284Sobrien
1193690075Sobrien	case REG_NORETURN:
1193790075Sobrien	case REG_SETJMP:
1193890075Sobrien	  /* These notes must remain with the call.  It should not be
1193990075Sobrien	     possible for both I2 and I3 to be a call.  */
11940169689Skan	  if (CALL_P (i3))
1194190075Sobrien	    place = i3;
1194290075Sobrien	  else
11943169689Skan	    {
11944169689Skan	      gcc_assert (i2 && CALL_P (i2));
11945169689Skan	      place = i2;
11946169689Skan	    }
1194790075Sobrien	  break;
1194890075Sobrien
1194918334Speter	case REG_UNUSED:
1195018334Speter	  /* Any clobbers for i3 may still exist, and so we must process
1195118334Speter	     REG_UNUSED notes from that insn.
1195218334Speter
1195318334Speter	     Any clobbers from i2 or i1 can only exist if they were added by
1195418334Speter	     recog_for_combine.  In that case, recog_for_combine created the
1195518334Speter	     necessary REG_UNUSED notes.  Trying to keep any original
1195618334Speter	     REG_UNUSED notes from these insns can cause incorrect output
1195718334Speter	     if it is for the same register as the original i3 dest.
1195818334Speter	     In that case, we will notice that the register is set in i3,
1195918334Speter	     and then add a REG_UNUSED note for the destination of i3, which
1196018334Speter	     is wrong.  However, it is possible to have REG_UNUSED notes from
1196118334Speter	     i2 or i1 for register which were both used and clobbered, so
1196218334Speter	     we keep notes from i2 or i1 if they will turn into REG_DEAD
1196318334Speter	     notes.  */
1196418334Speter
1196518334Speter	  /* If this register is set or clobbered in I3, put the note there
1196618334Speter	     unless there is one already.  */
1196718334Speter	  if (reg_set_p (XEXP (note, 0), PATTERN (i3)))
1196818334Speter	    {
1196918334Speter	      if (from_insn != i3)
1197018334Speter		break;
1197118334Speter
11972169689Skan	      if (! (REG_P (XEXP (note, 0))
1197318334Speter		     ? find_regno_note (i3, REG_UNUSED, REGNO (XEXP (note, 0)))
1197418334Speter		     : find_reg_note (i3, REG_UNUSED, XEXP (note, 0))))
1197518334Speter		place = i3;
1197618334Speter	    }
1197718334Speter	  /* Otherwise, if this register is used by I3, then this register
1197818334Speter	     now dies here, so we must put a REG_DEAD note here unless there
1197918334Speter	     is one already.  */
1198018334Speter	  else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3))
11981169689Skan		   && ! (REG_P (XEXP (note, 0))
1198290075Sobrien			 ? find_regno_note (i3, REG_DEAD,
1198390075Sobrien					    REGNO (XEXP (note, 0)))
1198418334Speter			 : find_reg_note (i3, REG_DEAD, XEXP (note, 0))))
1198518334Speter	    {
1198618334Speter	      PUT_REG_NOTE_KIND (note, REG_DEAD);
1198718334Speter	      place = i3;
1198818334Speter	    }
1198918334Speter	  break;
1199018334Speter
1199118334Speter	case REG_EQUAL:
1199218334Speter	case REG_EQUIV:
1199350397Sobrien	case REG_NOALIAS:
1199418334Speter	  /* These notes say something about results of an insn.  We can
1199518334Speter	     only support them if they used to be on I3 in which case they
1199618334Speter	     remain on I3.  Otherwise they are ignored.
1199718334Speter
1199818334Speter	     If the note refers to an expression that is not a constant, we
1199918334Speter	     must also ignore the note since we cannot tell whether the
1200018334Speter	     equivalence is still true.  It might be possible to do
1200118334Speter	     slightly better than this (we only have a problem if I2DEST
1200218334Speter	     or I1DEST is present in the expression), but it doesn't
1200318334Speter	     seem worth the trouble.  */
1200418334Speter
1200518334Speter	  if (from_insn == i3
1200618334Speter	      && (XEXP (note, 0) == 0 || CONSTANT_P (XEXP (note, 0))))
1200718334Speter	    place = i3;
1200818334Speter	  break;
1200918334Speter
1201018334Speter	case REG_INC:
1201118334Speter	case REG_NO_CONFLICT:
1201218334Speter	  /* These notes say something about how a register is used.  They must
1201318334Speter	     be present on any use of the register in I2 or I3.  */
1201418334Speter	  if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3)))
1201518334Speter	    place = i3;
1201618334Speter
1201718334Speter	  if (i2 && reg_mentioned_p (XEXP (note, 0), PATTERN (i2)))
1201818334Speter	    {
1201918334Speter	      if (place)
1202018334Speter		place2 = i2;
1202118334Speter	      else
1202218334Speter		place = i2;
1202318334Speter	    }
1202418334Speter	  break;
1202518334Speter
1202652284Sobrien	case REG_LABEL:
1202752284Sobrien	  /* This can show up in several ways -- either directly in the
1202852284Sobrien	     pattern, or hidden off in the constant pool with (or without?)
1202952284Sobrien	     a REG_EQUAL note.  */
1203052284Sobrien	  /* ??? Ignore the without-reg_equal-note problem for now.  */
1203152284Sobrien	  if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3))
1203252284Sobrien	      || ((tem = find_reg_note (i3, REG_EQUAL, NULL_RTX))
1203352284Sobrien		  && GET_CODE (XEXP (tem, 0)) == LABEL_REF
1203452284Sobrien		  && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0)))
1203552284Sobrien	    place = i3;
1203652284Sobrien
1203752284Sobrien	  if (i2
1203852284Sobrien	      && (reg_mentioned_p (XEXP (note, 0), PATTERN (i2))
1203990075Sobrien		  || ((tem = find_reg_note (i2, REG_EQUAL, NULL_RTX))
1204052284Sobrien		      && GET_CODE (XEXP (tem, 0)) == LABEL_REF
1204152284Sobrien		      && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0))))
1204252284Sobrien	    {
1204352284Sobrien	      if (place)
1204452284Sobrien		place2 = i2;
1204552284Sobrien	      else
1204652284Sobrien		place = i2;
1204752284Sobrien	    }
1204890075Sobrien
12049169689Skan	  /* Don't attach REG_LABEL note to a JUMP_INSN.  Add
12050169689Skan	     a JUMP_LABEL instead or decrement LABEL_NUSES.  */
12051169689Skan	  if (place && JUMP_P (place))
1205290075Sobrien	    {
12053169689Skan	      rtx label = JUMP_LABEL (place);
12054169689Skan
12055169689Skan	      if (!label)
12056169689Skan		JUMP_LABEL (place) = XEXP (note, 0);
12057169689Skan	      else
12058169689Skan		{
12059169689Skan		  gcc_assert (label == XEXP (note, 0));
12060169689Skan		  if (LABEL_P (label))
12061169689Skan		    LABEL_NUSES (label)--;
12062169689Skan		}
1206390075Sobrien	      place = 0;
1206490075Sobrien	    }
12065169689Skan	  if (place2 && JUMP_P (place2))
1206690075Sobrien	    {
12067169689Skan	      rtx label = JUMP_LABEL (place2);
12068169689Skan
12069169689Skan	      if (!label)
12070169689Skan		JUMP_LABEL (place2) = XEXP (note, 0);
12071169689Skan	      else
12072169689Skan		{
12073169689Skan		  gcc_assert (label == XEXP (note, 0));
12074169689Skan		  if (LABEL_P (label))
12075169689Skan		    LABEL_NUSES (label)--;
12076169689Skan		}
1207790075Sobrien	      place2 = 0;
1207890075Sobrien	    }
1207952284Sobrien	  break;
1208052284Sobrien
1208190075Sobrien	case REG_NONNEG:
12082132718Skan	  /* This note says something about the value of a register prior
1208390075Sobrien	     to the execution of an insn.  It is too much trouble to see
1208490075Sobrien	     if the note is still correct in all situations.  It is better
1208590075Sobrien	     to simply delete it.  */
1208618334Speter	  break;
1208718334Speter
1208818334Speter	case REG_RETVAL:
1208918334Speter	  /* If the insn previously containing this note still exists,
1209018334Speter	     put it back where it was.  Otherwise move it to the previous
1209118334Speter	     insn.  Adjust the corresponding REG_LIBCALL note.  */
12092169689Skan	  if (!NOTE_P (from_insn))
1209318334Speter	    place = from_insn;
1209418334Speter	  else
1209518334Speter	    {
1209618334Speter	      tem = find_reg_note (XEXP (note, 0), REG_LIBCALL, NULL_RTX);
1209718334Speter	      place = prev_real_insn (from_insn);
1209818334Speter	      if (tem && place)
1209918334Speter		XEXP (tem, 0) = place;
1210090075Sobrien	      /* If we're deleting the last remaining instruction of a
1210190075Sobrien		 libcall sequence, don't add the notes.  */
1210290075Sobrien	      else if (XEXP (note, 0) == from_insn)
1210390075Sobrien		tem = place = 0;
12104132718Skan	      /* Don't add the dangling REG_RETVAL note.  */
12105132718Skan	      else if (! tem)
12106132718Skan		place = 0;
1210718334Speter	    }
1210818334Speter	  break;
1210918334Speter
1211018334Speter	case REG_LIBCALL:
1211118334Speter	  /* This is handled similarly to REG_RETVAL.  */
12112169689Skan	  if (!NOTE_P (from_insn))
1211318334Speter	    place = from_insn;
1211418334Speter	  else
1211518334Speter	    {
1211618334Speter	      tem = find_reg_note (XEXP (note, 0), REG_RETVAL, NULL_RTX);
1211718334Speter	      place = next_real_insn (from_insn);
1211818334Speter	      if (tem && place)
1211918334Speter		XEXP (tem, 0) = place;
1212090075Sobrien	      /* If we're deleting the last remaining instruction of a
1212190075Sobrien		 libcall sequence, don't add the notes.  */
1212290075Sobrien	      else if (XEXP (note, 0) == from_insn)
1212390075Sobrien		tem = place = 0;
12124132718Skan	      /* Don't add the dangling REG_LIBCALL note.  */
12125132718Skan	      else if (! tem)
12126132718Skan		place = 0;
1212718334Speter	    }
1212818334Speter	  break;
1212918334Speter
1213018334Speter	case REG_DEAD:
12131169689Skan	  /* If we replaced the right hand side of FROM_INSN with a
12132169689Skan	     REG_EQUAL note, the original use of the dying register
12133169689Skan	     will not have been combined into I3 and I2.  In such cases,
12134169689Skan	     FROM_INSN is guaranteed to be the first of the combined
12135169689Skan	     instructions, so we simply need to search back before
12136169689Skan	     FROM_INSN for the previous use or set of this register,
12137169689Skan	     then alter the notes there appropriately.
12138169689Skan
12139169689Skan	     If the register is used as an input in I3, it dies there.
12140117395Skan	     Similarly for I2, if it is nonzero and adjacent to I3.
1214118334Speter
1214218334Speter	     If the register is not used as an input in either I3 or I2
1214318334Speter	     and it is not one of the registers we were supposed to eliminate,
1214418334Speter	     there are two possibilities.  We might have a non-adjacent I2
1214518334Speter	     or we might have somehow eliminated an additional register
1214618334Speter	     from a computation.  For example, we might have had A & B where
1214718334Speter	     we discover that B will always be zero.  In this case we will
1214818334Speter	     eliminate the reference to A.
1214918334Speter
1215018334Speter	     In both cases, we must search to see if we can find a previous
1215118334Speter	     use of A and put the death note there.  */
1215218334Speter
1215318334Speter	  if (from_insn
12154169689Skan	      && from_insn == i2mod
12155169689Skan	      && !reg_overlap_mentioned_p (XEXP (note, 0), i2mod_new_rhs))
12156169689Skan	    tem = from_insn;
12157169689Skan	  else
12158169689Skan	    {
12159169689Skan	      if (from_insn
12160169689Skan		  && CALL_P (from_insn)
12161169689Skan		  && find_reg_fusage (from_insn, USE, XEXP (note, 0)))
12162169689Skan		place = from_insn;
12163169689Skan	      else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)))
12164169689Skan		place = i3;
12165169689Skan	      else if (i2 != 0 && next_nonnote_insn (i2) == i3
12166169689Skan		       && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
12167169689Skan		place = i2;
12168169689Skan	      else if ((rtx_equal_p (XEXP (note, 0), elim_i2)
12169169689Skan			&& !(i2mod
12170169689Skan			     && reg_overlap_mentioned_p (XEXP (note, 0),
12171169689Skan							 i2mod_old_rhs)))
12172169689Skan		       || rtx_equal_p (XEXP (note, 0), elim_i1))
12173169689Skan		break;
12174169689Skan	      tem = i3;
12175169689Skan	    }
1217618334Speter
1217718334Speter	  if (place == 0)
1217818334Speter	    {
12179117395Skan	      basic_block bb = this_basic_block;
1218090075Sobrien
12181169689Skan	      for (tem = PREV_INSN (tem); place == 0; tem = PREV_INSN (tem))
1218218334Speter		{
1218390075Sobrien		  if (! INSN_P (tem))
1218490075Sobrien		    {
12185132718Skan		      if (tem == BB_HEAD (bb))
1218690075Sobrien			break;
1218790075Sobrien		      continue;
1218890075Sobrien		    }
1218990075Sobrien
1219018334Speter		  /* If the register is being set at TEM, see if that is all
1219118334Speter		     TEM is doing.  If so, delete TEM.  Otherwise, make this
12192169689Skan		     into a REG_UNUSED note instead. Don't delete sets to
12193132718Skan		     global register vars.  */
12194132718Skan		  if ((REGNO (XEXP (note, 0)) >= FIRST_PSEUDO_REGISTER
12195132718Skan		       || !global_regs[REGNO (XEXP (note, 0))])
12196132718Skan		      && reg_set_p (XEXP (note, 0), PATTERN (tem)))
1219718334Speter		    {
1219818334Speter		      rtx set = single_set (tem);
1219950397Sobrien		      rtx inner_dest = 0;
1220052284Sobrien#ifdef HAVE_cc0
1220152284Sobrien		      rtx cc0_setter = NULL_RTX;
1220252284Sobrien#endif
1220318334Speter
1220450397Sobrien		      if (set != 0)
1220550397Sobrien			for (inner_dest = SET_DEST (set);
1220690075Sobrien			     (GET_CODE (inner_dest) == STRICT_LOW_PART
1220790075Sobrien			      || GET_CODE (inner_dest) == SUBREG
1220890075Sobrien			      || GET_CODE (inner_dest) == ZERO_EXTRACT);
1220950397Sobrien			     inner_dest = XEXP (inner_dest, 0))
1221050397Sobrien			  ;
1221150397Sobrien
1221218334Speter		      /* Verify that it was the set, and not a clobber that
1221390075Sobrien			 modified the register.
1221418334Speter
1221552284Sobrien			 CC0 targets must be careful to maintain setter/user
1221652284Sobrien			 pairs.  If we cannot delete the setter due to side
1221752284Sobrien			 effects, mark the user with an UNUSED note instead
1221852284Sobrien			 of deleting it.  */
1221952284Sobrien
1222018334Speter		      if (set != 0 && ! side_effects_p (SET_SRC (set))
1222152284Sobrien			  && rtx_equal_p (XEXP (note, 0), inner_dest)
1222252284Sobrien#ifdef HAVE_cc0
1222352284Sobrien			  && (! reg_mentioned_p (cc0_rtx, SET_SRC (set))
1222452284Sobrien			      || ((cc0_setter = prev_cc0_setter (tem)) != NULL
1222552284Sobrien				  && sets_cc0_p (PATTERN (cc0_setter)) > 0))
1222652284Sobrien#endif
1222752284Sobrien			  )
1222818334Speter			{
1222918334Speter			  /* Move the notes and links of TEM elsewhere.
1223090075Sobrien			     This might delete other dead insns recursively.
1223118334Speter			     First set the pattern to something that won't use
1223218334Speter			     any register.  */
12233132718Skan			  rtx old_notes = REG_NOTES (tem);
1223418334Speter
1223518334Speter			  PATTERN (tem) = pc_rtx;
12236132718Skan			  REG_NOTES (tem) = NULL;
1223718334Speter
12238169689Skan			  distribute_notes (old_notes, tem, tem, NULL_RTX,
12239169689Skan					    NULL_RTX, NULL_RTX);
1224018334Speter			  distribute_links (LOG_LINKS (tem));
1224118334Speter
12242169689Skan			  SET_INSN_DELETED (tem);
1224352284Sobrien
1224452284Sobrien#ifdef HAVE_cc0
1224552284Sobrien			  /* Delete the setter too.  */
1224652284Sobrien			  if (cc0_setter)
1224752284Sobrien			    {
1224852284Sobrien			      PATTERN (cc0_setter) = pc_rtx;
12249132718Skan			      old_notes = REG_NOTES (cc0_setter);
12250132718Skan			      REG_NOTES (cc0_setter) = NULL;
1225152284Sobrien
12252132718Skan			      distribute_notes (old_notes, cc0_setter,
12253169689Skan						cc0_setter, NULL_RTX,
12254169689Skan						NULL_RTX, NULL_RTX);
1225552284Sobrien			      distribute_links (LOG_LINKS (cc0_setter));
1225652284Sobrien
12257169689Skan			      SET_INSN_DELETED (cc0_setter);
1225852284Sobrien			    }
1225952284Sobrien#endif
1226018334Speter			}
1226118334Speter		      else
1226218334Speter			{
1226318334Speter			  PUT_REG_NOTE_KIND (note, REG_UNUSED);
1226490075Sobrien
1226518334Speter			  /*  If there isn't already a REG_UNUSED note, put one
12266169689Skan			      here.  Do not place a REG_DEAD note, even if
12267169689Skan			      the register is also used here; that would not
12268169689Skan			      match the algorithm used in lifetime analysis
12269169689Skan			      and can cause the consistency check in the
12270169689Skan			      scheduler to fail.  */
1227118334Speter			  if (! find_regno_note (tem, REG_UNUSED,
1227218334Speter						 REGNO (XEXP (note, 0))))
1227318334Speter			    place = tem;
1227418334Speter			  break;
1227590075Sobrien			}
1227690075Sobrien		    }
1227790075Sobrien		  else if (reg_referenced_p (XEXP (note, 0), PATTERN (tem))
12278169689Skan			   || (CALL_P (tem)
1227990075Sobrien			       && find_reg_fusage (tem, USE, XEXP (note, 0))))
1228090075Sobrien		    {
1228190075Sobrien		      place = tem;
1228218334Speter
1228390075Sobrien		      /* If we are doing a 3->2 combination, and we have a
1228490075Sobrien			 register which formerly died in i3 and was not used
1228590075Sobrien			 by i2, which now no longer dies in i3 and is used in
1228690075Sobrien			 i2 but does not die in i2, and place is between i2
1228790075Sobrien			 and i3, then we may need to move a link from place to
1228890075Sobrien			 i2.  */
1228990075Sobrien		      if (i2 && INSN_UID (place) <= max_uid_cuid
1229090075Sobrien			  && INSN_CUID (place) > INSN_CUID (i2)
1229190075Sobrien			  && from_insn
1229290075Sobrien			  && INSN_CUID (from_insn) > INSN_CUID (i2)
1229390075Sobrien			  && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
1229490075Sobrien			{
1229590075Sobrien			  rtx links = LOG_LINKS (place);
1229690075Sobrien			  LOG_LINKS (place) = 0;
1229790075Sobrien			  distribute_links (links);
1229890075Sobrien			}
1229990075Sobrien		      break;
1230090075Sobrien		    }
1230190075Sobrien
12302132718Skan		  if (tem == BB_HEAD (bb))
1230318334Speter		    break;
1230418334Speter		}
1230590075Sobrien
1230690075Sobrien	      /* We haven't found an insn for the death note and it
1230790075Sobrien		 is still a REG_DEAD note, but we have hit the beginning
1230890075Sobrien		 of the block.  If the existing life info says the reg
1230990075Sobrien		 was dead, there's nothing left to do.  Otherwise, we'll
1231090075Sobrien		 need to do a global life update after combine.  */
1231190075Sobrien	      if (REG_NOTE_KIND (note) == REG_DEAD && place == 0
12312169689Skan		  && REGNO_REG_SET_P (bb->il.rtl->global_live_at_start,
1231390075Sobrien				      REGNO (XEXP (note, 0))))
12314132718Skan		SET_BIT (refresh_blocks, this_basic_block->index);
1231518334Speter	    }
1231618334Speter
1231718334Speter	  /* If the register is set or already dead at PLACE, we needn't do
1231850397Sobrien	     anything with this note if it is still a REG_DEAD note.
12319169689Skan	     We check here if it is set at all, not if is it totally replaced,
1232050397Sobrien	     which is what `dead_or_set_p' checks, so also check for it being
1232150397Sobrien	     set partially.  */
1232218334Speter
1232318334Speter	  if (place && REG_NOTE_KIND (note) == REG_DEAD)
1232418334Speter	    {
1232590075Sobrien	      unsigned int regno = REGNO (XEXP (note, 0));
1232618334Speter
1232790075Sobrien	      /* Similarly, if the instruction on which we want to place
1232890075Sobrien		 the note is a noop, we'll need do a global live update
1232990075Sobrien		 after we remove them in delete_noop_moves.  */
1233090075Sobrien	      if (noop_move_p (place))
12331132718Skan		SET_BIT (refresh_blocks, this_basic_block->index);
1233290075Sobrien
1233318334Speter	      if (dead_or_set_p (place, XEXP (note, 0))
1233418334Speter		  || reg_bitfield_target_p (XEXP (note, 0), PATTERN (place)))
1233518334Speter		{
1233618334Speter		  /* Unless the register previously died in PLACE, clear
12337169689Skan		     last_death.  [I no longer understand why this is
1233818334Speter		     being done.] */
12339169689Skan		  if (reg_stat[regno].last_death != place)
12340169689Skan		    reg_stat[regno].last_death = 0;
1234118334Speter		  place = 0;
1234218334Speter		}
1234318334Speter	      else
12344169689Skan		reg_stat[regno].last_death = place;
1234518334Speter
1234618334Speter	      /* If this is a death note for a hard reg that is occupying
1234718334Speter		 multiple registers, ensure that we are still using all
1234818334Speter		 parts of the object.  If we find a piece of the object
1234990075Sobrien		 that is unused, we must arrange for an appropriate REG_DEAD
1235090075Sobrien		 note to be added for it.  However, we can't just emit a USE
1235190075Sobrien		 and tag the note to it, since the register might actually
1235290075Sobrien		 be dead; so we recourse, and the recursive call then finds
1235390075Sobrien		 the previous insn that used this register.  */
1235418334Speter
1235518334Speter	      if (place && regno < FIRST_PSEUDO_REGISTER
12356169689Skan		  && hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))] > 1)
1235718334Speter		{
1235890075Sobrien		  unsigned int endregno
12359169689Skan		    = regno + hard_regno_nregs[regno]
12360169689Skan					      [GET_MODE (XEXP (note, 0))];
1236118334Speter		  int all_used = 1;
1236290075Sobrien		  unsigned int i;
1236318334Speter
1236418334Speter		  for (i = regno; i < endregno; i++)
1236590075Sobrien		    if ((! refers_to_regno_p (i, i + 1, PATTERN (place), 0)
1236690075Sobrien			 && ! find_regno_fusage (place, USE, i))
1236790075Sobrien			|| dead_or_set_regno_p (place, i))
1236890075Sobrien		      all_used = 0;
1236918334Speter
1237018334Speter		  if (! all_used)
1237118334Speter		    {
1237218334Speter		      /* Put only REG_DEAD notes for pieces that are
1237390075Sobrien			 not already dead or set.  */
1237418334Speter
1237590075Sobrien		      for (i = regno; i < endregno;
12376169689Skan			   i += hard_regno_nregs[i][reg_raw_mode[i]])
1237718334Speter			{
12378117395Skan			  rtx piece = regno_reg_rtx[i];
12379117395Skan			  basic_block bb = this_basic_block;
1238018334Speter
1238190075Sobrien			  if (! dead_or_set_p (place, piece)
1238218334Speter			      && ! reg_bitfield_target_p (piece,
1238318334Speter							  PATTERN (place)))
1238490075Sobrien			    {
1238590075Sobrien			      rtx new_note
1238690075Sobrien				= gen_rtx_EXPR_LIST (REG_DEAD, piece, NULL_RTX);
1238790075Sobrien
1238890075Sobrien			      distribute_notes (new_note, place, place,
12389169689Skan						NULL_RTX, NULL_RTX, NULL_RTX);
1239090075Sobrien			    }
1239190075Sobrien			  else if (! refers_to_regno_p (i, i + 1,
1239290075Sobrien							PATTERN (place), 0)
1239390075Sobrien				   && ! find_regno_fusage (place, USE, i))
1239490075Sobrien			    for (tem = PREV_INSN (place); ;
1239590075Sobrien				 tem = PREV_INSN (tem))
1239690075Sobrien			      {
1239790075Sobrien				if (! INSN_P (tem))
1239890075Sobrien				  {
12399132718Skan				    if (tem == BB_HEAD (bb))
1240090075Sobrien				      {
1240190075Sobrien					SET_BIT (refresh_blocks,
12402117395Skan						 this_basic_block->index);
1240390075Sobrien					break;
1240490075Sobrien				      }
1240590075Sobrien				    continue;
1240690075Sobrien				  }
1240790075Sobrien				if (dead_or_set_p (tem, piece)
1240890075Sobrien				    || reg_bitfield_target_p (piece,
1240990075Sobrien							      PATTERN (tem)))
1241090075Sobrien				  {
1241190075Sobrien				    REG_NOTES (tem)
1241290075Sobrien				      = gen_rtx_EXPR_LIST (REG_UNUSED, piece,
1241390075Sobrien							   REG_NOTES (tem));
1241490075Sobrien				    break;
1241590075Sobrien				  }
1241690075Sobrien			      }
1241790075Sobrien
1241818334Speter			}
1241918334Speter
1242018334Speter		      place = 0;
1242118334Speter		    }
1242218334Speter		}
1242318334Speter	    }
1242418334Speter	  break;
1242518334Speter
1242618334Speter	default:
1242718334Speter	  /* Any other notes should not be present at this point in the
1242818334Speter	     compilation.  */
12429169689Skan	  gcc_unreachable ();
1243018334Speter	}
1243118334Speter
1243218334Speter      if (place)
1243318334Speter	{
1243418334Speter	  XEXP (note, 1) = REG_NOTES (place);
1243518334Speter	  REG_NOTES (place) = note;
1243618334Speter	}
1243718334Speter      else if ((REG_NOTE_KIND (note) == REG_DEAD
1243818334Speter		|| REG_NOTE_KIND (note) == REG_UNUSED)
12439169689Skan	       && REG_P (XEXP (note, 0)))
1244050397Sobrien	REG_N_DEATHS (REGNO (XEXP (note, 0)))--;
1244118334Speter
1244218334Speter      if (place2)
1244318334Speter	{
1244418334Speter	  if ((REG_NOTE_KIND (note) == REG_DEAD
1244518334Speter	       || REG_NOTE_KIND (note) == REG_UNUSED)
12446169689Skan	      && REG_P (XEXP (note, 0)))
1244750397Sobrien	    REG_N_DEATHS (REGNO (XEXP (note, 0)))++;
1244818334Speter
1244950397Sobrien	  REG_NOTES (place2) = gen_rtx_fmt_ee (GET_CODE (note),
12450222207Sbenl					       GET_MODE (note),
1245150397Sobrien					       XEXP (note, 0),
1245250397Sobrien					       REG_NOTES (place2));
1245318334Speter	}
1245418334Speter    }
1245518334Speter}
1245618334Speter
1245718334Speter/* Similarly to above, distribute the LOG_LINKS that used to be present on
12458122180Skan   I3, I2, and I1 to new locations.  This is also called to add a link
12459122180Skan   pointing at I3 when I3's destination is changed.  */
1246018334Speter
1246118334Speterstatic void
12462132718Skandistribute_links (rtx links)
1246318334Speter{
1246418334Speter  rtx link, next_link;
1246518334Speter
1246618334Speter  for (link = links; link; link = next_link)
1246718334Speter    {
1246818334Speter      rtx place = 0;
1246918334Speter      rtx insn;
1247018334Speter      rtx set, reg;
1247118334Speter
1247218334Speter      next_link = XEXP (link, 1);
1247318334Speter
1247418334Speter      /* If the insn that this link points to is a NOTE or isn't a single
1247518334Speter	 set, ignore it.  In the latter case, it isn't clear what we
1247690075Sobrien	 can do other than ignore the link, since we can't tell which
1247718334Speter	 register it was for.  Such links wouldn't be used by combine
1247818334Speter	 anyway.
1247918334Speter
1248018334Speter	 It is not possible for the destination of the target of the link to
1248118334Speter	 have been changed by combine.  The only potential of this is if we
1248218334Speter	 replace I3, I2, and I1 by I3 and I2.  But in that case the
1248318334Speter	 destination of I2 also remains unchanged.  */
1248418334Speter
12485169689Skan      if (NOTE_P (XEXP (link, 0))
1248618334Speter	  || (set = single_set (XEXP (link, 0))) == 0)
1248718334Speter	continue;
1248818334Speter
1248918334Speter      reg = SET_DEST (set);
1249018334Speter      while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT
1249118334Speter	     || GET_CODE (reg) == STRICT_LOW_PART)
1249218334Speter	reg = XEXP (reg, 0);
1249318334Speter
1249418334Speter      /* A LOG_LINK is defined as being placed on the first insn that uses
1249518334Speter	 a register and points to the insn that sets the register.  Start
1249618334Speter	 searching at the next insn after the target of the link and stop
1249718334Speter	 when we reach a set of the register or the end of the basic block.
1249818334Speter
1249918334Speter	 Note that this correctly handles the link that used to point from
1250018334Speter	 I3 to I2.  Also note that not much searching is typically done here
1250118334Speter	 since most links don't point very far away.  */
1250218334Speter
1250318334Speter      for (insn = NEXT_INSN (XEXP (link, 0));
12504117395Skan	   (insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR
12505132718Skan		     || BB_HEAD (this_basic_block->next_bb) != insn));
1250618334Speter	   insn = NEXT_INSN (insn))
1250790075Sobrien	if (INSN_P (insn) && reg_overlap_mentioned_p (reg, PATTERN (insn)))
1250818334Speter	  {
1250918334Speter	    if (reg_referenced_p (reg, PATTERN (insn)))
1251018334Speter	      place = insn;
1251118334Speter	    break;
1251218334Speter	  }
12513169689Skan	else if (CALL_P (insn)
1251490075Sobrien		 && find_reg_fusage (insn, USE, reg))
1251518334Speter	  {
1251618334Speter	    place = insn;
1251718334Speter	    break;
1251818334Speter	  }
12519132718Skan	else if (INSN_P (insn) && reg_set_p (reg, insn))
12520132718Skan	  break;
1252118334Speter
1252218334Speter      /* If we found a place to put the link, place it there unless there
1252318334Speter	 is already a link to the same insn as LINK at that point.  */
1252418334Speter
1252518334Speter      if (place)
1252618334Speter	{
1252718334Speter	  rtx link2;
1252818334Speter
1252918334Speter	  for (link2 = LOG_LINKS (place); link2; link2 = XEXP (link2, 1))
1253018334Speter	    if (XEXP (link2, 0) == XEXP (link, 0))
1253118334Speter	      break;
1253218334Speter
1253318334Speter	  if (link2 == 0)
1253418334Speter	    {
1253518334Speter	      XEXP (link, 1) = LOG_LINKS (place);
1253618334Speter	      LOG_LINKS (place) = link;
1253718334Speter
1253818334Speter	      /* Set added_links_insn to the earliest insn we added a
1253918334Speter		 link to.  */
1254090075Sobrien	      if (added_links_insn == 0
1254118334Speter		  || INSN_CUID (added_links_insn) > INSN_CUID (place))
1254218334Speter		added_links_insn = place;
1254318334Speter	    }
1254418334Speter	}
1254518334Speter    }
1254618334Speter}
1254718334Speter
12548169689Skan/* Subroutine of unmentioned_reg_p and callback from for_each_rtx.
12549169689Skan   Check whether the expression pointer to by LOC is a register or
12550169689Skan   memory, and if so return 1 if it isn't mentioned in the rtx EXPR.
12551169689Skan   Otherwise return zero.  */
12552169689Skan
12553169689Skanstatic int
12554169689Skanunmentioned_reg_p_1 (rtx *loc, void *expr)
12555169689Skan{
12556169689Skan  rtx x = *loc;
12557169689Skan
12558169689Skan  if (x != NULL_RTX
12559169689Skan      && (REG_P (x) || MEM_P (x))
12560169689Skan      && ! reg_mentioned_p (x, (rtx) expr))
12561169689Skan    return 1;
12562169689Skan  return 0;
12563169689Skan}
12564169689Skan
12565169689Skan/* Check for any register or memory mentioned in EQUIV that is not
12566169689Skan   mentioned in EXPR.  This is used to restrict EQUIV to "specializations"
12567169689Skan   of EXPR where some registers may have been replaced by constants.  */
12568169689Skan
12569169689Skanstatic bool
12570169689Skanunmentioned_reg_p (rtx equiv, rtx expr)
12571169689Skan{
12572169689Skan  return for_each_rtx (&equiv, unmentioned_reg_p_1, expr);
12573169689Skan}
12574169689Skan
1257550397Sobrien/* Compute INSN_CUID for INSN, which is an insn made by combine.  */
1257650397Sobrien
1257750397Sobrienstatic int
12578132718Skaninsn_cuid (rtx insn)
1257950397Sobrien{
1258050397Sobrien  while (insn != 0 && INSN_UID (insn) > max_uid_cuid
12581169689Skan	 && NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE)
1258250397Sobrien    insn = NEXT_INSN (insn);
1258350397Sobrien
12584169689Skan  gcc_assert (INSN_UID (insn) <= max_uid_cuid);
1258550397Sobrien
1258650397Sobrien  return INSN_CUID (insn);
1258750397Sobrien}
1258850397Sobrien
1258918334Spetervoid
12590132718Skandump_combine_stats (FILE *file)
1259118334Speter{
12592169689Skan  fprintf
1259318334Speter    (file,
1259418334Speter     ";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n",
1259518334Speter     combine_attempts, combine_merges, combine_extras, combine_successes);
1259618334Speter}
1259718334Speter
1259818334Spetervoid
12599132718Skandump_combine_total_stats (FILE *file)
1260018334Speter{
12601169689Skan  fprintf
1260218334Speter    (file,
1260318334Speter     "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n",
1260418334Speter     total_attempts, total_merges, total_extras, total_successes);
1260518334Speter}
12606169689Skan
12607169689Skan
12608169689Skanstatic bool
12609169689Skangate_handle_combine (void)
12610169689Skan{
12611169689Skan  return (optimize > 0);
12612169689Skan}
12613169689Skan
12614169689Skan/* Try combining insns through substitution.  */
12615169689Skanstatic unsigned int
12616169689Skanrest_of_handle_combine (void)
12617169689Skan{
12618169689Skan  int rebuild_jump_labels_after_combine
12619169689Skan    = combine_instructions (get_insns (), max_reg_num ());
12620169689Skan
12621169689Skan  /* Combining insns may have turned an indirect jump into a
12622169689Skan     direct jump.  Rebuild the JUMP_LABEL fields of jumping
12623169689Skan     instructions.  */
12624169689Skan  if (rebuild_jump_labels_after_combine)
12625169689Skan    {
12626169689Skan      timevar_push (TV_JUMP);
12627169689Skan      rebuild_jump_labels (get_insns ());
12628169689Skan      timevar_pop (TV_JUMP);
12629169689Skan
12630169689Skan      delete_dead_jumptables ();
12631169689Skan      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
12632169689Skan    }
12633169689Skan  return 0;
12634169689Skan}
12635169689Skan
12636169689Skanstruct tree_opt_pass pass_combine =
12637169689Skan{
12638169689Skan  "combine",                            /* name */
12639169689Skan  gate_handle_combine,                  /* gate */
12640169689Skan  rest_of_handle_combine,               /* execute */
12641169689Skan  NULL,                                 /* sub */
12642169689Skan  NULL,                                 /* next */
12643169689Skan  0,                                    /* static_pass_number */
12644169689Skan  TV_COMBINE,                           /* tv_id */
12645169689Skan  0,                                    /* properties_required */
12646169689Skan  0,                                    /* properties_provided */
12647169689Skan  0,                                    /* properties_destroyed */
12648169689Skan  0,                                    /* todo_flags_start */
12649169689Skan  TODO_dump_func |
12650169689Skan  TODO_ggc_collect,                     /* todo_flags_finish */
12651169689Skan  'c'                                   /* letter */
12652169689Skan};
12653169689Skan
12654