combine.c revision 117395
118334Speter/* Optimize by combining instructions for GNU compiler.
272562Sobrien   Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3117395Skan   1999, 2000, 2001, 2002, 2003 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
1990075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
2090075Sobrien02111-1307, 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
5618334Speter   - reg_n_refs is not adjusted in the rare case when a register is
5718334Speter     no longer required in a computation
5818334Speter   - there are extremely rare cases (see distribute_regnotes) when a
5918334Speter     REG_DEAD note is lost
6018334Speter   - a LOG_LINKS entry that refers to an insn with multiple SETs may be
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"
7990075Sobrien#include "rtl.h"
8090075Sobrien#include "tm_p.h"
8118334Speter#include "flags.h"
8218334Speter#include "regs.h"
8318334Speter#include "hard-reg-set.h"
8418334Speter#include "basic-block.h"
8518334Speter#include "insn-config.h"
8690075Sobrien#include "function.h"
8790075Sobrien/* Include expr.h after insn-config.h so we get HAVE_conditional_move.  */
8850397Sobrien#include "expr.h"
8918334Speter#include "insn-attr.h"
9018334Speter#include "recog.h"
9118334Speter#include "real.h"
9250397Sobrien#include "toplev.h"
9318334Speter
9418334Speter/* It is not safe to use ordinary gen_lowpart in combine.
9518334Speter   Use gen_lowpart_for_combine instead.  See comments there.  */
9618334Speter#define gen_lowpart dont_use_gen_lowpart_you_dummy
9718334Speter
9818334Speter/* Number of attempts to combine instructions in this function.  */
9918334Speter
10018334Speterstatic int combine_attempts;
10118334Speter
10218334Speter/* Number of attempts that got as far as substitution in this function.  */
10318334Speter
10418334Speterstatic int combine_merges;
10518334Speter
10618334Speter/* Number of instructions combined with added SETs in this function.  */
10718334Speter
10818334Speterstatic int combine_extras;
10918334Speter
11018334Speter/* Number of instructions combined in this function.  */
11118334Speter
11218334Speterstatic int combine_successes;
11318334Speter
11418334Speter/* Totals over entire compilation.  */
11518334Speter
11618334Speterstatic int total_attempts, total_merges, total_extras, total_successes;
11718334Speter
11818334Speter
11918334Speter/* Vector mapping INSN_UIDs to cuids.
12018334Speter   The cuids are like uids but increase monotonically always.
12118334Speter   Combine always uses cuids so that it can compare them.
12218334Speter   But actually renumbering the uids, which we used to do,
12318334Speter   proves to be a bad idea because it makes it hard to compare
12418334Speter   the dumps produced by earlier passes with those from later passes.  */
12518334Speter
12618334Speterstatic int *uid_cuid;
12718334Speterstatic int max_uid_cuid;
12818334Speter
12918334Speter/* Get the cuid of an insn.  */
13018334Speter
13150397Sobrien#define INSN_CUID(INSN) \
13250397Sobrien(INSN_UID (INSN) > max_uid_cuid ? insn_cuid (INSN) : uid_cuid[INSN_UID (INSN)])
13318334Speter
13490075Sobrien/* In case BITS_PER_WORD == HOST_BITS_PER_WIDE_INT, shifting by
13590075Sobrien   BITS_PER_WORD would invoke undefined behavior.  Work around it.  */
13690075Sobrien
13790075Sobrien#define UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD(val) \
13890075Sobrien  (((unsigned HOST_WIDE_INT) (val) << (BITS_PER_WORD - 1)) << 1)
13990075Sobrien
140117395Skan#define nonzero_bits(X, M) \
141117395Skan  cached_nonzero_bits (X, M, NULL_RTX, VOIDmode, 0)
142117395Skan
143117395Skan#define num_sign_bit_copies(X, M) \
144117395Skan  cached_num_sign_bit_copies (X, M, NULL_RTX, VOIDmode, 0)
145117395Skan
14618334Speter/* Maximum register number, which is the size of the tables below.  */
14718334Speter
14890075Sobrienstatic unsigned int combine_max_regno;
14918334Speter
15018334Speter/* Record last point of death of (hard or pseudo) register n.  */
15118334Speter
15218334Speterstatic rtx *reg_last_death;
15318334Speter
15418334Speter/* Record last point of modification of (hard or pseudo) register n.  */
15518334Speter
15618334Speterstatic rtx *reg_last_set;
15718334Speter
15818334Speter/* Record the cuid of the last insn that invalidated memory
15918334Speter   (anything that writes memory, and subroutine calls, but not pushes).  */
16018334Speter
16118334Speterstatic int mem_last_set;
16218334Speter
16318334Speter/* Record the cuid of the last CALL_INSN
16418334Speter   so we can tell whether a potential combination crosses any calls.  */
16518334Speter
16618334Speterstatic int last_call_cuid;
16718334Speter
16818334Speter/* When `subst' is called, this is the insn that is being modified
16918334Speter   (by combining in a previous insn).  The PATTERN of this insn
17018334Speter   is still the old pattern partially modified and it should not be
17118334Speter   looked at, but this may be used to examine the successors of the insn
17218334Speter   to judge whether a simplification is valid.  */
17318334Speter
17418334Speterstatic rtx subst_insn;
17518334Speter
17618334Speter/* This is an insn that belongs before subst_insn, but is not currently
17718334Speter   on the insn chain.  */
17818334Speter
17918334Speterstatic rtx subst_prev_insn;
18018334Speter
18118334Speter/* This is the lowest CUID that `subst' is currently dealing with.
18218334Speter   get_last_value will not return a value if the register was set at or
18318334Speter   after this CUID.  If not for this mechanism, we could get confused if
18418334Speter   I2 or I1 in try_combine were an insn that used the old value of a register
18518334Speter   to obtain a new value.  In that case, we might erroneously get the
18618334Speter   new value of the register when we wanted the old one.  */
18718334Speter
18818334Speterstatic int subst_low_cuid;
18918334Speter
19018334Speter/* This contains any hard registers that are used in newpat; reg_dead_at_p
19118334Speter   must consider all these registers to be always live.  */
19218334Speter
19318334Speterstatic HARD_REG_SET newpat_used_regs;
19418334Speter
19518334Speter/* This is an insn to which a LOG_LINKS entry has been added.  If this
19618334Speter   insn is the earlier than I2 or I3, combine should rescan starting at
19718334Speter   that location.  */
19818334Speter
19918334Speterstatic rtx added_links_insn;
20018334Speter
201117395Skan/* Basic block in which we are performing combines.  */
202117395Skanstatic basic_block this_basic_block;
20390075Sobrien
20490075Sobrien/* A bitmap indicating which blocks had registers go dead at entry.
20590075Sobrien   After combine, we'll need to re-do global life analysis with
20690075Sobrien   those blocks as starting points.  */
20790075Sobrienstatic sbitmap refresh_blocks;
20890075Sobrienstatic int need_refresh;
20918334Speter
21018334Speter/* The next group of arrays allows the recording of the last value assigned
211117395Skan   to (hard or pseudo) register n.  We use this information to see if an
21218334Speter   operation being processed is redundant given a prior operation performed
21318334Speter   on the register.  For example, an `and' with a constant is redundant if
21418334Speter   all the zero bits are already known to be turned off.
21518334Speter
21618334Speter   We use an approach similar to that used by cse, but change it in the
21718334Speter   following ways:
21818334Speter
21918334Speter   (1) We do not want to reinitialize at each label.
22018334Speter   (2) It is useful, but not critical, to know the actual value assigned
22118334Speter       to a register.  Often just its form is helpful.
22218334Speter
22318334Speter   Therefore, we maintain the following arrays:
22418334Speter
22518334Speter   reg_last_set_value		the last value assigned
22618334Speter   reg_last_set_label		records the value of label_tick when the
22718334Speter				register was assigned
22818334Speter   reg_last_set_table_tick	records the value of label_tick when a
22918334Speter				value using the register is assigned
230117395Skan   reg_last_set_invalid		set to nonzero when it is not valid
23118334Speter				to use the value of this register in some
23218334Speter				register's value
23318334Speter
23418334Speter   To understand the usage of these tables, it is important to understand
23518334Speter   the distinction between the value in reg_last_set_value being valid
23618334Speter   and the register being validly contained in some other expression in the
23718334Speter   table.
23818334Speter
239117395Skan   Entry I in reg_last_set_value is valid if it is nonzero, and either
24018334Speter   reg_n_sets[i] is 1 or reg_last_set_label[i] == label_tick.
24118334Speter
24218334Speter   Register I may validly appear in any expression returned for the value
24318334Speter   of another register if reg_n_sets[i] is 1.  It may also appear in the
24418334Speter   value for register J if reg_last_set_label[i] < reg_last_set_label[j] or
24518334Speter   reg_last_set_invalid[j] is zero.
24618334Speter
24718334Speter   If an expression is found in the table containing a register which may
24818334Speter   not validly appear in an expression, the register is replaced by
24918334Speter   something that won't match, (clobber (const_int 0)).
25018334Speter
251117395Skan   reg_last_set_invalid[i] is set nonzero when register I is being assigned
25218334Speter   to and reg_last_set_table_tick[i] == label_tick.  */
25318334Speter
25450397Sobrien/* Record last value assigned to (hard or pseudo) register n.  */
25518334Speter
25618334Speterstatic rtx *reg_last_set_value;
25718334Speter
25818334Speter/* Record the value of label_tick when the value for register n is placed in
25918334Speter   reg_last_set_value[n].  */
26018334Speter
26118334Speterstatic int *reg_last_set_label;
26218334Speter
26318334Speter/* Record the value of label_tick when an expression involving register n
26450397Sobrien   is placed in reg_last_set_value.  */
26518334Speter
26618334Speterstatic int *reg_last_set_table_tick;
26718334Speter
268117395Skan/* Set nonzero if references to register n in expressions should not be
26918334Speter   used.  */
27018334Speter
27118334Speterstatic char *reg_last_set_invalid;
27218334Speter
27350397Sobrien/* Incremented for each label.  */
27418334Speter
27518334Speterstatic int label_tick;
27618334Speter
27718334Speter/* Some registers that are set more than once and used in more than one
27818334Speter   basic block are nevertheless always set in similar ways.  For example,
27918334Speter   a QImode register may be loaded from memory in two places on a machine
28018334Speter   where byte loads zero extend.
28118334Speter
28218334Speter   We record in the following array what we know about the nonzero
28318334Speter   bits of a register, specifically which bits are known to be zero.
28418334Speter
28518334Speter   If an entry is zero, it means that we don't know anything special.  */
28618334Speter
28718334Speterstatic unsigned HOST_WIDE_INT *reg_nonzero_bits;
28818334Speter
28918334Speter/* Mode used to compute significance in reg_nonzero_bits.  It is the largest
29018334Speter   integer mode that can fit in HOST_BITS_PER_WIDE_INT.  */
29118334Speter
29218334Speterstatic enum machine_mode nonzero_bits_mode;
29318334Speter
29418334Speter/* Nonzero if we know that a register has some leading bits that are always
29518334Speter   equal to the sign bit.  */
29618334Speter
29790075Sobrienstatic unsigned char *reg_sign_bit_copies;
29818334Speter
29918334Speter/* Nonzero when reg_nonzero_bits and reg_sign_bit_copies can be safely used.
30018334Speter   It is zero while computing them and after combine has completed.  This
30118334Speter   former test prevents propagating values based on previously set values,
30218334Speter   which can be incorrect if a variable is modified in a loop.  */
30318334Speter
30418334Speterstatic int nonzero_sign_valid;
30518334Speter
30618334Speter/* These arrays are maintained in parallel with reg_last_set_value
30718334Speter   and are used to store the mode in which the register was last set,
30818334Speter   the bits that were known to be zero when it was last set, and the
30918334Speter   number of sign bits copies it was known to have when it was last set.  */
31018334Speter
31118334Speterstatic enum machine_mode *reg_last_set_mode;
31218334Speterstatic unsigned HOST_WIDE_INT *reg_last_set_nonzero_bits;
31318334Speterstatic char *reg_last_set_sign_bit_copies;
31418334Speter
31518334Speter/* Record one modification to rtl structure
31618334Speter   to be undone by storing old_contents into *where.
31718334Speter   is_int is 1 if the contents are an int.  */
31818334Speter
31918334Speterstruct undo
32018334Speter{
32150397Sobrien  struct undo *next;
32218334Speter  int is_int;
323117395Skan  union {rtx r; int i;} old_contents;
324117395Skan  union {rtx *r; int *i;} where;
32518334Speter};
32618334Speter
32718334Speter/* Record a bunch of changes to be undone, up to MAX_UNDO of them.
32818334Speter   num_undo says how many are currently recorded.
32918334Speter
33018334Speter   other_insn is nonzero if we have modified some other insn in the process
33190075Sobrien   of working on subst_insn.  It must be verified too.  */
33218334Speter
33318334Speterstruct undobuf
33418334Speter{
33550397Sobrien  struct undo *undos;
33650397Sobrien  struct undo *frees;
33718334Speter  rtx other_insn;
33818334Speter};
33918334Speter
34018334Speterstatic struct undobuf undobuf;
34118334Speter
34290075Sobrien/* Number of times the pseudo being substituted for
34390075Sobrien   was found and replaced.  */
34490075Sobrien
34590075Sobrienstatic int n_occurrences;
34690075Sobrien
34790075Sobrienstatic void do_SUBST			PARAMS ((rtx *, rtx));
348117395Skanstatic void do_SUBST_INT		PARAMS ((int *, int));
34990075Sobrienstatic void init_reg_last_arrays	PARAMS ((void));
35090075Sobrienstatic void setup_incoming_promotions   PARAMS ((void));
35190075Sobrienstatic void set_nonzero_bits_and_sign_copies  PARAMS ((rtx, rtx, void *));
35290075Sobrienstatic int cant_combine_insn_p	PARAMS ((rtx));
35390075Sobrienstatic int can_combine_p	PARAMS ((rtx, rtx, rtx, rtx, rtx *, rtx *));
35490075Sobrienstatic int sets_function_arg_p	PARAMS ((rtx));
35590075Sobrienstatic int combinable_i3pat	PARAMS ((rtx, rtx *, rtx, rtx, int, rtx *));
35690075Sobrienstatic int contains_muldiv	PARAMS ((rtx));
35790075Sobrienstatic rtx try_combine		PARAMS ((rtx, rtx, rtx, int *));
35890075Sobrienstatic void undo_all		PARAMS ((void));
35990075Sobrienstatic void undo_commit		PARAMS ((void));
36090075Sobrienstatic rtx *find_split_point	PARAMS ((rtx *, rtx));
36190075Sobrienstatic rtx subst		PARAMS ((rtx, rtx, rtx, int, int));
36290075Sobrienstatic rtx combine_simplify_rtx	PARAMS ((rtx, enum machine_mode, int, int));
36390075Sobrienstatic rtx simplify_if_then_else  PARAMS ((rtx));
36490075Sobrienstatic rtx simplify_set		PARAMS ((rtx));
36590075Sobrienstatic rtx simplify_logical	PARAMS ((rtx, int));
36690075Sobrienstatic rtx expand_compound_operation  PARAMS ((rtx));
36790075Sobrienstatic rtx expand_field_assignment  PARAMS ((rtx));
36890075Sobrienstatic rtx make_extraction	PARAMS ((enum machine_mode, rtx, HOST_WIDE_INT,
36990075Sobrien					 rtx, unsigned HOST_WIDE_INT, int,
37090075Sobrien					 int, int));
37190075Sobrienstatic rtx extract_left_shift	PARAMS ((rtx, int));
37290075Sobrienstatic rtx make_compound_operation  PARAMS ((rtx, enum rtx_code));
37390075Sobrienstatic int get_pos_from_mask	PARAMS ((unsigned HOST_WIDE_INT,
37490075Sobrien					 unsigned HOST_WIDE_INT *));
37590075Sobrienstatic rtx force_to_mode	PARAMS ((rtx, enum machine_mode,
37690075Sobrien					 unsigned HOST_WIDE_INT, rtx, int));
37790075Sobrienstatic rtx if_then_else_cond	PARAMS ((rtx, rtx *, rtx *));
37890075Sobrienstatic rtx known_cond		PARAMS ((rtx, enum rtx_code, rtx, rtx));
37990075Sobrienstatic int rtx_equal_for_field_assignment_p PARAMS ((rtx, rtx));
38090075Sobrienstatic rtx make_field_assignment  PARAMS ((rtx));
38190075Sobrienstatic rtx apply_distributive_law  PARAMS ((rtx));
38290075Sobrienstatic rtx simplify_and_const_int  PARAMS ((rtx, enum machine_mode, rtx,
38390075Sobrien					    unsigned HOST_WIDE_INT));
384117395Skanstatic unsigned HOST_WIDE_INT cached_nonzero_bits
385117395Skan				PARAMS ((rtx, enum machine_mode, rtx,
386117395Skan					 enum machine_mode,
387117395Skan					 unsigned HOST_WIDE_INT));
388117395Skanstatic unsigned HOST_WIDE_INT nonzero_bits1
389117395Skan				PARAMS ((rtx, enum machine_mode, rtx,
390117395Skan					 enum machine_mode,
391117395Skan					 unsigned HOST_WIDE_INT));
392117395Skanstatic unsigned int cached_num_sign_bit_copies
393117395Skan				PARAMS ((rtx, enum machine_mode, rtx,
394117395Skan					 enum machine_mode, unsigned int));
395117395Skanstatic unsigned int num_sign_bit_copies1
396117395Skan				PARAMS ((rtx, enum machine_mode, rtx,
397117395Skan					 enum machine_mode, unsigned int));
39890075Sobrienstatic int merge_outer_ops	PARAMS ((enum rtx_code *, HOST_WIDE_INT *,
39990075Sobrien					 enum rtx_code, HOST_WIDE_INT,
40090075Sobrien					 enum machine_mode, int *));
40190075Sobrienstatic rtx simplify_shift_const	PARAMS ((rtx, enum rtx_code, enum machine_mode,
40290075Sobrien					 rtx, int));
40390075Sobrienstatic int recog_for_combine	PARAMS ((rtx *, rtx, rtx *));
40490075Sobrienstatic rtx gen_lowpart_for_combine  PARAMS ((enum machine_mode, rtx));
40590075Sobrienstatic rtx gen_binary		PARAMS ((enum rtx_code, enum machine_mode,
40690075Sobrien					 rtx, rtx));
40790075Sobrienstatic enum rtx_code simplify_comparison  PARAMS ((enum rtx_code, rtx *, rtx *));
40890075Sobrienstatic void update_table_tick	PARAMS ((rtx));
40990075Sobrienstatic void record_value_for_reg  PARAMS ((rtx, rtx, rtx));
41090075Sobrienstatic void check_promoted_subreg PARAMS ((rtx, rtx));
41190075Sobrienstatic void record_dead_and_set_regs_1  PARAMS ((rtx, rtx, void *));
41290075Sobrienstatic void record_dead_and_set_regs  PARAMS ((rtx));
41390075Sobrienstatic int get_last_value_validate  PARAMS ((rtx *, rtx, int, int));
41490075Sobrienstatic rtx get_last_value	PARAMS ((rtx));
41590075Sobrienstatic int use_crosses_set_p	PARAMS ((rtx, int));
41690075Sobrienstatic void reg_dead_at_p_1	PARAMS ((rtx, rtx, void *));
41790075Sobrienstatic int reg_dead_at_p	PARAMS ((rtx, rtx));
41890075Sobrienstatic void move_deaths		PARAMS ((rtx, rtx, int, rtx, rtx *));
41990075Sobrienstatic int reg_bitfield_target_p  PARAMS ((rtx, rtx));
42090075Sobrienstatic void distribute_notes	PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
42190075Sobrienstatic void distribute_links	PARAMS ((rtx));
42290075Sobrienstatic void mark_used_regs_combine PARAMS ((rtx));
42390075Sobrienstatic int insn_cuid		PARAMS ((rtx));
42490075Sobrienstatic void record_promoted_value PARAMS ((rtx, rtx));
42590075Sobrienstatic rtx reversed_comparison  PARAMS ((rtx, enum machine_mode, rtx, rtx));
42690075Sobrienstatic enum rtx_code combine_reversed_comparison_code PARAMS ((rtx));
42790075Sobrien
42818334Speter/* Substitute NEWVAL, an rtx expression, into INTO, a place in some
42918334Speter   insn.  The substitution can be undone by undo_all.  If INTO is already
43018334Speter   set to NEWVAL, do not record this change.  Because computing NEWVAL might
43118334Speter   also call SUBST, we have to compute it before we put anything into
43218334Speter   the undo table.  */
43318334Speter
43490075Sobrienstatic void
43590075Sobriendo_SUBST (into, newval)
43690075Sobrien     rtx *into, newval;
43790075Sobrien{
43890075Sobrien  struct undo *buf;
43990075Sobrien  rtx oldval = *into;
44018334Speter
44190075Sobrien  if (oldval == newval)
44290075Sobrien    return;
44390075Sobrien
44496263Sobrien  /* We'd like to catch as many invalid transformations here as
44596263Sobrien     possible.  Unfortunately, there are way too many mode changes
44696263Sobrien     that are perfectly valid, so we'd waste too much effort for
44796263Sobrien     little gain doing the checks here.  Focus on catching invalid
44896263Sobrien     transformations involving integer constants.  */
44996263Sobrien  if (GET_MODE_CLASS (GET_MODE (oldval)) == MODE_INT
45096263Sobrien      && GET_CODE (newval) == CONST_INT)
45196263Sobrien    {
45296263Sobrien      /* Sanity check that we're replacing oldval with a CONST_INT
45396263Sobrien	 that is a valid sign-extension for the original mode.  */
45496263Sobrien      if (INTVAL (newval) != trunc_int_for_mode (INTVAL (newval),
45596263Sobrien						 GET_MODE (oldval)))
45696263Sobrien	abort ();
45796263Sobrien
45896263Sobrien      /* Replacing the operand of a SUBREG or a ZERO_EXTEND with a
45996263Sobrien	 CONST_INT is not valid, because after the replacement, the
46096263Sobrien	 original mode would be gone.  Unfortunately, we can't tell
46196263Sobrien	 when do_SUBST is called to replace the operand thereof, so we
46296263Sobrien	 perform this test on oldval instead, checking whether an
46396263Sobrien	 invalid replacement took place before we got here.  */
46496263Sobrien      if ((GET_CODE (oldval) == SUBREG
46596263Sobrien	   && GET_CODE (SUBREG_REG (oldval)) == CONST_INT)
46696263Sobrien	  || (GET_CODE (oldval) == ZERO_EXTEND
46796263Sobrien	      && GET_CODE (XEXP (oldval, 0)) == CONST_INT))
46896263Sobrien	abort ();
46996263Sobrien     }
47096263Sobrien
47190075Sobrien  if (undobuf.frees)
47290075Sobrien    buf = undobuf.frees, undobuf.frees = buf->next;
47390075Sobrien  else
47490075Sobrien    buf = (struct undo *) xmalloc (sizeof (struct undo));
47590075Sobrien
47690075Sobrien  buf->is_int = 0;
47790075Sobrien  buf->where.r = into;
47890075Sobrien  buf->old_contents.r = oldval;
47990075Sobrien  *into = newval;
48090075Sobrien
48190075Sobrien  buf->next = undobuf.undos, undobuf.undos = buf;
48290075Sobrien}
48390075Sobrien
48490075Sobrien#define SUBST(INTO, NEWVAL)	do_SUBST(&(INTO), (NEWVAL))
48590075Sobrien
48650397Sobrien/* Similar to SUBST, but NEWVAL is an int expression.  Note that substitution
48750397Sobrien   for the value of a HOST_WIDE_INT value (including CONST_INT) is
48850397Sobrien   not safe.  */
48918334Speter
49090075Sobrienstatic void
49190075Sobriendo_SUBST_INT (into, newval)
492117395Skan     int *into, newval;
49390075Sobrien{
49490075Sobrien  struct undo *buf;
495117395Skan  int oldval = *into;
49618334Speter
49790075Sobrien  if (oldval == newval)
49890075Sobrien    return;
49918334Speter
50090075Sobrien  if (undobuf.frees)
50190075Sobrien    buf = undobuf.frees, undobuf.frees = buf->next;
50290075Sobrien  else
50390075Sobrien    buf = (struct undo *) xmalloc (sizeof (struct undo));
50418334Speter
50590075Sobrien  buf->is_int = 1;
50690075Sobrien  buf->where.i = into;
50790075Sobrien  buf->old_contents.i = oldval;
50890075Sobrien  *into = newval;
50990075Sobrien
51090075Sobrien  buf->next = undobuf.undos, undobuf.undos = buf;
51190075Sobrien}
51290075Sobrien
51390075Sobrien#define SUBST_INT(INTO, NEWVAL)  do_SUBST_INT(&(INTO), (NEWVAL))
51418334Speter
51518334Speter/* Main entry point for combiner.  F is the first insn of the function.
51690075Sobrien   NREGS is the first unused pseudo-reg number.
51718334Speter
518117395Skan   Return nonzero if the combiner has turned an indirect jump
51990075Sobrien   instruction into a direct jump.  */
52090075Sobrienint
52118334Spetercombine_instructions (f, nregs)
52218334Speter     rtx f;
52390075Sobrien     unsigned int nregs;
52418334Speter{
52590075Sobrien  rtx insn, next;
52650397Sobrien#ifdef HAVE_cc0
52790075Sobrien  rtx prev;
52850397Sobrien#endif
52990075Sobrien  int i;
53090075Sobrien  rtx links, nextlinks;
53118334Speter
53290075Sobrien  int new_direct_jump_p = 0;
53390075Sobrien
53418334Speter  combine_attempts = 0;
53518334Speter  combine_merges = 0;
53618334Speter  combine_extras = 0;
53718334Speter  combine_successes = 0;
53818334Speter
53918334Speter  combine_max_regno = nregs;
54018334Speter
54190075Sobrien  reg_nonzero_bits = ((unsigned HOST_WIDE_INT *)
54290075Sobrien		      xcalloc (nregs, sizeof (unsigned HOST_WIDE_INT)));
54390075Sobrien  reg_sign_bit_copies
54490075Sobrien    = (unsigned char *) xcalloc (nregs, sizeof (unsigned char));
54518334Speter
54690075Sobrien  reg_last_death = (rtx *) xmalloc (nregs * sizeof (rtx));
54790075Sobrien  reg_last_set = (rtx *) xmalloc (nregs * sizeof (rtx));
54890075Sobrien  reg_last_set_value = (rtx *) xmalloc (nregs * sizeof (rtx));
54990075Sobrien  reg_last_set_table_tick = (int *) xmalloc (nregs * sizeof (int));
55090075Sobrien  reg_last_set_label = (int *) xmalloc (nregs * sizeof (int));
55190075Sobrien  reg_last_set_invalid = (char *) xmalloc (nregs * sizeof (char));
55218334Speter  reg_last_set_mode
55390075Sobrien    = (enum machine_mode *) xmalloc (nregs * sizeof (enum machine_mode));
55418334Speter  reg_last_set_nonzero_bits
55590075Sobrien    = (unsigned HOST_WIDE_INT *) xmalloc (nregs * sizeof (HOST_WIDE_INT));
55618334Speter  reg_last_set_sign_bit_copies
55790075Sobrien    = (char *) xmalloc (nregs * sizeof (char));
55818334Speter
55918334Speter  init_reg_last_arrays ();
56018334Speter
56118334Speter  init_recog_no_volatile ();
56218334Speter
56318334Speter  /* Compute maximum uid value so uid_cuid can be allocated.  */
56418334Speter
56518334Speter  for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
56618334Speter    if (INSN_UID (insn) > i)
56718334Speter      i = INSN_UID (insn);
56818334Speter
56990075Sobrien  uid_cuid = (int *) xmalloc ((i + 1) * sizeof (int));
57018334Speter  max_uid_cuid = i;
57118334Speter
57218334Speter  nonzero_bits_mode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
57318334Speter
57418334Speter  /* Don't use reg_nonzero_bits when computing it.  This can cause problems
57518334Speter     when, for example, we have j <<= 1 in a loop.  */
57618334Speter
57718334Speter  nonzero_sign_valid = 0;
57818334Speter
57918334Speter  /* Compute the mapping from uids to cuids.
58018334Speter     Cuids are numbers assigned to insns, like uids,
58190075Sobrien     except that cuids increase monotonically through the code.
58218334Speter
58318334Speter     Scan all SETs and see if we can deduce anything about what
58418334Speter     bits are known to be zero for some registers and how many copies
58518334Speter     of the sign bit are known to exist for those registers.
58618334Speter
58718334Speter     Also set any known values so that we can use it while searching
58818334Speter     for what bits are known to be set.  */
58918334Speter
59018334Speter  label_tick = 1;
59118334Speter
59218334Speter  /* We need to initialize it here, because record_dead_and_set_regs may call
59318334Speter     get_last_value.  */
59418334Speter  subst_prev_insn = NULL_RTX;
59518334Speter
59618334Speter  setup_incoming_promotions ();
59718334Speter
598117395Skan  refresh_blocks = sbitmap_alloc (last_basic_block);
59990075Sobrien  sbitmap_zero (refresh_blocks);
60090075Sobrien  need_refresh = 0;
60190075Sobrien
60218334Speter  for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
60318334Speter    {
60418334Speter      uid_cuid[INSN_UID (insn)] = ++i;
60518334Speter      subst_low_cuid = i;
60618334Speter      subst_insn = insn;
60718334Speter
60890075Sobrien      if (INSN_P (insn))
60918334Speter	{
61090075Sobrien	  note_stores (PATTERN (insn), set_nonzero_bits_and_sign_copies,
61190075Sobrien		       NULL);
61218334Speter	  record_dead_and_set_regs (insn);
61350397Sobrien
61450397Sobrien#ifdef AUTO_INC_DEC
61550397Sobrien	  for (links = REG_NOTES (insn); links; links = XEXP (links, 1))
61650397Sobrien	    if (REG_NOTE_KIND (links) == REG_INC)
61790075Sobrien	      set_nonzero_bits_and_sign_copies (XEXP (links, 0), NULL_RTX,
61890075Sobrien						NULL);
61950397Sobrien#endif
62018334Speter	}
62118334Speter
62218334Speter      if (GET_CODE (insn) == CODE_LABEL)
62318334Speter	label_tick++;
62418334Speter    }
62518334Speter
62618334Speter  nonzero_sign_valid = 1;
62718334Speter
62818334Speter  /* Now scan all the insns in forward order.  */
62918334Speter
63018334Speter  label_tick = 1;
63118334Speter  last_call_cuid = 0;
63218334Speter  mem_last_set = 0;
63318334Speter  init_reg_last_arrays ();
63418334Speter  setup_incoming_promotions ();
63518334Speter
636117395Skan  FOR_EACH_BB (this_basic_block)
63718334Speter    {
638117395Skan      for (insn = this_basic_block->head;
639117395Skan           insn != NEXT_INSN (this_basic_block->end);
640117395Skan	   insn = next ? next : NEXT_INSN (insn))
641117395Skan	{
642117395Skan	  next = 0;
64318334Speter
644117395Skan	  if (GET_CODE (insn) == CODE_LABEL)
645117395Skan	    label_tick++;
64618334Speter
647117395Skan	  else if (INSN_P (insn))
648117395Skan	    {
649117395Skan	      /* See if we know about function return values before this
650117395Skan		 insn based upon SUBREG flags.  */
651117395Skan	      check_promoted_subreg (insn, PATTERN (insn));
65218334Speter
653117395Skan	      /* Try this insn with each insn it links back to.  */
65490075Sobrien
655117395Skan	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
656117395Skan		if ((next = try_combine (insn, XEXP (links, 0),
657117395Skan					 NULL_RTX, &new_direct_jump_p)) != 0)
658117395Skan		  goto retry;
65918334Speter
660117395Skan	      /* Try each sequence of three linked insns ending with this one.  */
66118334Speter
662117395Skan	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
663117395Skan		{
664117395Skan		  rtx link = XEXP (links, 0);
66518334Speter
666117395Skan		  /* If the linked insn has been replaced by a note, then there
667117395Skan		     is no point in pursuing this chain any further.  */
668117395Skan		  if (GET_CODE (link) == NOTE)
669117395Skan		    continue;
67018334Speter
671117395Skan		  for (nextlinks = LOG_LINKS (link);
672117395Skan		       nextlinks;
673117395Skan		       nextlinks = XEXP (nextlinks, 1))
674117395Skan		    if ((next = try_combine (insn, link,
675117395Skan					     XEXP (nextlinks, 0),
676117395Skan					     &new_direct_jump_p)) != 0)
677117395Skan		      goto retry;
678117395Skan		}
67990075Sobrien
68018334Speter#ifdef HAVE_cc0
681117395Skan	      /* Try to combine a jump insn that uses CC0
682117395Skan		 with a preceding insn that sets CC0, and maybe with its
683117395Skan		 logical predecessor as well.
684117395Skan		 This is how we make decrement-and-branch insns.
685117395Skan		 We need this special code because data flow connections
686117395Skan		 via CC0 do not get entered in LOG_LINKS.  */
68718334Speter
688117395Skan	      if (GET_CODE (insn) == JUMP_INSN
689117395Skan		  && (prev = prev_nonnote_insn (insn)) != 0
690117395Skan		  && GET_CODE (prev) == INSN
691117395Skan		  && sets_cc0_p (PATTERN (prev)))
692117395Skan		{
693117395Skan		  if ((next = try_combine (insn, prev,
694117395Skan					   NULL_RTX, &new_direct_jump_p)) != 0)
695117395Skan		    goto retry;
69618334Speter
697117395Skan		  for (nextlinks = LOG_LINKS (prev); nextlinks;
698117395Skan		       nextlinks = XEXP (nextlinks, 1))
699117395Skan		    if ((next = try_combine (insn, prev,
700117395Skan					     XEXP (nextlinks, 0),
701117395Skan					     &new_direct_jump_p)) != 0)
702117395Skan		      goto retry;
703117395Skan		}
70418334Speter
705117395Skan	      /* Do the same for an insn that explicitly references CC0.  */
706117395Skan	      if (GET_CODE (insn) == INSN
707117395Skan		  && (prev = prev_nonnote_insn (insn)) != 0
708117395Skan		  && GET_CODE (prev) == INSN
709117395Skan		  && sets_cc0_p (PATTERN (prev))
710117395Skan		  && GET_CODE (PATTERN (insn)) == SET
711117395Skan		  && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (insn))))
712117395Skan		{
713117395Skan		  if ((next = try_combine (insn, prev,
714117395Skan					   NULL_RTX, &new_direct_jump_p)) != 0)
715117395Skan		    goto retry;
71618334Speter
717117395Skan		  for (nextlinks = LOG_LINKS (prev); nextlinks;
718117395Skan		       nextlinks = XEXP (nextlinks, 1))
719117395Skan		    if ((next = try_combine (insn, prev,
720117395Skan					     XEXP (nextlinks, 0),
721117395Skan					     &new_direct_jump_p)) != 0)
722117395Skan		      goto retry;
723117395Skan		}
724117395Skan
725117395Skan	      /* Finally, see if any of the insns that this insn links to
726117395Skan		 explicitly references CC0.  If so, try this insn, that insn,
727117395Skan		 and its predecessor if it sets CC0.  */
728117395Skan	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
729117395Skan		if (GET_CODE (XEXP (links, 0)) == INSN
730117395Skan		    && GET_CODE (PATTERN (XEXP (links, 0))) == SET
731117395Skan		    && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (XEXP (links, 0))))
732117395Skan		    && (prev = prev_nonnote_insn (XEXP (links, 0))) != 0
733117395Skan		    && GET_CODE (prev) == INSN
734117395Skan		    && sets_cc0_p (PATTERN (prev))
735117395Skan		    && (next = try_combine (insn, XEXP (links, 0),
736117395Skan					    prev, &new_direct_jump_p)) != 0)
73718334Speter		  goto retry;
73818334Speter#endif
73918334Speter
740117395Skan	      /* Try combining an insn with two different insns whose results it
741117395Skan		 uses.  */
742117395Skan	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
743117395Skan		for (nextlinks = XEXP (links, 1); nextlinks;
744117395Skan		     nextlinks = XEXP (nextlinks, 1))
745117395Skan		  if ((next = try_combine (insn, XEXP (links, 0),
746117395Skan					   XEXP (nextlinks, 0),
747117395Skan					   &new_direct_jump_p)) != 0)
748117395Skan		    goto retry;
74918334Speter
750117395Skan	      if (GET_CODE (insn) != NOTE)
751117395Skan		record_dead_and_set_regs (insn);
75218334Speter
753117395Skan	    retry:
754117395Skan	      ;
755117395Skan	    }
75618334Speter	}
75718334Speter    }
758117395Skan  clear_bb_flags ();
75918334Speter
760117395Skan  EXECUTE_IF_SET_IN_SBITMAP (refresh_blocks, 0, i,
761117395Skan			     BASIC_BLOCK (i)->flags |= BB_DIRTY);
762117395Skan  new_direct_jump_p |= purge_all_dead_edges (0);
76390075Sobrien  delete_noop_moves (f);
76490075Sobrien
765117395Skan  update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
766117395Skan				    PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
767117395Skan				    | PROP_KILL_DEAD_CODE);
76890075Sobrien
76990075Sobrien  /* Clean up.  */
77090075Sobrien  sbitmap_free (refresh_blocks);
77190075Sobrien  free (reg_nonzero_bits);
77290075Sobrien  free (reg_sign_bit_copies);
77390075Sobrien  free (reg_last_death);
77490075Sobrien  free (reg_last_set);
77590075Sobrien  free (reg_last_set_value);
77690075Sobrien  free (reg_last_set_table_tick);
77790075Sobrien  free (reg_last_set_label);
77890075Sobrien  free (reg_last_set_invalid);
77990075Sobrien  free (reg_last_set_mode);
78090075Sobrien  free (reg_last_set_nonzero_bits);
78190075Sobrien  free (reg_last_set_sign_bit_copies);
78290075Sobrien  free (uid_cuid);
78390075Sobrien
78490075Sobrien  {
78590075Sobrien    struct undo *undo, *next;
78690075Sobrien    for (undo = undobuf.frees; undo; undo = next)
78790075Sobrien      {
78890075Sobrien	next = undo->next;
78990075Sobrien	free (undo);
79090075Sobrien      }
79190075Sobrien    undobuf.frees = 0;
79290075Sobrien  }
79390075Sobrien
79418334Speter  total_attempts += combine_attempts;
79518334Speter  total_merges += combine_merges;
79618334Speter  total_extras += combine_extras;
79718334Speter  total_successes += combine_successes;
79818334Speter
79918334Speter  nonzero_sign_valid = 0;
80052284Sobrien
80152284Sobrien  /* Make recognizer allow volatile MEMs again.  */
80252284Sobrien  init_recog ();
80390075Sobrien
80490075Sobrien  return new_direct_jump_p;
80518334Speter}
80618334Speter
80718334Speter/* Wipe the reg_last_xxx arrays in preparation for another pass.  */
80818334Speter
80918334Speterstatic void
81018334Speterinit_reg_last_arrays ()
81118334Speter{
81290075Sobrien  unsigned int nregs = combine_max_regno;
81318334Speter
81490075Sobrien  memset ((char *) reg_last_death, 0, nregs * sizeof (rtx));
81590075Sobrien  memset ((char *) reg_last_set, 0, nregs * sizeof (rtx));
81690075Sobrien  memset ((char *) reg_last_set_value, 0, nregs * sizeof (rtx));
81790075Sobrien  memset ((char *) reg_last_set_table_tick, 0, nregs * sizeof (int));
81890075Sobrien  memset ((char *) reg_last_set_label, 0, nregs * sizeof (int));
81990075Sobrien  memset (reg_last_set_invalid, 0, nregs * sizeof (char));
82090075Sobrien  memset ((char *) reg_last_set_mode, 0, nregs * sizeof (enum machine_mode));
82190075Sobrien  memset ((char *) reg_last_set_nonzero_bits, 0, nregs * sizeof (HOST_WIDE_INT));
82290075Sobrien  memset (reg_last_set_sign_bit_copies, 0, nregs * sizeof (char));
82318334Speter}
82418334Speter
82518334Speter/* Set up any promoted values for incoming argument registers.  */
82618334Speter
82718334Speterstatic void
82818334Spetersetup_incoming_promotions ()
82918334Speter{
83018334Speter#ifdef PROMOTE_FUNCTION_ARGS
83190075Sobrien  unsigned int regno;
83218334Speter  rtx reg;
83318334Speter  enum machine_mode mode;
83418334Speter  int unsignedp;
83518334Speter  rtx first = get_insns ();
83618334Speter
83790075Sobrien#ifndef OUTGOING_REGNO
83890075Sobrien#define OUTGOING_REGNO(N) N
83990075Sobrien#endif
84018334Speter  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
84190075Sobrien    /* Check whether this register can hold an incoming pointer
84290075Sobrien       argument.  FUNCTION_ARG_REGNO_P tests outgoing register
84390075Sobrien       numbers, so translate if necessary due to register windows.  */
84490075Sobrien    if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (regno))
84518334Speter	&& (reg = promoted_input_arg (regno, &mode, &unsignedp)) != 0)
84650397Sobrien      {
84750397Sobrien	record_value_for_reg
84850397Sobrien	  (reg, first, gen_rtx_fmt_e ((unsignedp ? ZERO_EXTEND
84950397Sobrien				       : SIGN_EXTEND),
85050397Sobrien				      GET_MODE (reg),
85150397Sobrien				      gen_rtx_CLOBBER (mode, const0_rtx)));
85250397Sobrien      }
85318334Speter#endif
85418334Speter}
85518334Speter
85650397Sobrien/* Called via note_stores.  If X is a pseudo that is narrower than
85750397Sobrien   HOST_BITS_PER_WIDE_INT and is being set, record what bits are known zero.
85818334Speter
85918334Speter   If we are setting only a portion of X and we can't figure out what
86018334Speter   portion, assume all bits will be used since we don't know what will
86118334Speter   be happening.
86218334Speter
86318334Speter   Similarly, set how many bits of X are known to be copies of the sign bit
86490075Sobrien   at all locations in the function.  This is the smallest number implied
86518334Speter   by any set of X.  */
86618334Speter
86718334Speterstatic void
86890075Sobrienset_nonzero_bits_and_sign_copies (x, set, data)
86918334Speter     rtx x;
87018334Speter     rtx set;
87190075Sobrien     void *data ATTRIBUTE_UNUSED;
87218334Speter{
87390075Sobrien  unsigned int num;
87418334Speter
87518334Speter  if (GET_CODE (x) == REG
87618334Speter      && REGNO (x) >= FIRST_PSEUDO_REGISTER
87718334Speter      /* If this register is undefined at the start of the file, we can't
87818334Speter	 say what its contents were.  */
879117395Skan      && ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, REGNO (x))
88018334Speter      && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
88118334Speter    {
88250397Sobrien      if (set == 0 || GET_CODE (set) == CLOBBER)
88318334Speter	{
88418334Speter	  reg_nonzero_bits[REGNO (x)] = GET_MODE_MASK (GET_MODE (x));
88550397Sobrien	  reg_sign_bit_copies[REGNO (x)] = 1;
88618334Speter	  return;
88718334Speter	}
88818334Speter
88918334Speter      /* If this is a complex assignment, see if we can convert it into a
89018334Speter	 simple assignment.  */
89118334Speter      set = expand_field_assignment (set);
89218334Speter
89318334Speter      /* If this is a simple assignment, or we have a paradoxical SUBREG,
89418334Speter	 set what we know about X.  */
89518334Speter
89618334Speter      if (SET_DEST (set) == x
89718334Speter	  || (GET_CODE (SET_DEST (set)) == SUBREG
89818334Speter	      && (GET_MODE_SIZE (GET_MODE (SET_DEST (set)))
89918334Speter		  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (set)))))
90018334Speter	      && SUBREG_REG (SET_DEST (set)) == x))
90118334Speter	{
90218334Speter	  rtx src = SET_SRC (set);
90318334Speter
90418334Speter#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
90518334Speter	  /* If X is narrower than a word and SRC is a non-negative
90618334Speter	     constant that would appear negative in the mode of X,
90718334Speter	     sign-extend it for use in reg_nonzero_bits because some
90818334Speter	     machines (maybe most) will actually do the sign-extension
90990075Sobrien	     and this is the conservative approach.
91018334Speter
91118334Speter	     ??? For 2.5, try to tighten up the MD files in this regard
91218334Speter	     instead of this kludge.  */
91318334Speter
91418334Speter	  if (GET_MODE_BITSIZE (GET_MODE (x)) < BITS_PER_WORD
91518334Speter	      && GET_CODE (src) == CONST_INT
91618334Speter	      && INTVAL (src) > 0
91718334Speter	      && 0 != (INTVAL (src)
91818334Speter		       & ((HOST_WIDE_INT) 1
91918334Speter			  << (GET_MODE_BITSIZE (GET_MODE (x)) - 1))))
92018334Speter	    src = GEN_INT (INTVAL (src)
92118334Speter			   | ((HOST_WIDE_INT) (-1)
92218334Speter			      << GET_MODE_BITSIZE (GET_MODE (x))));
92318334Speter#endif
92418334Speter
92596263Sobrien	  /* Don't call nonzero_bits if it cannot change anything.  */
92696263Sobrien	  if (reg_nonzero_bits[REGNO (x)] != ~(unsigned HOST_WIDE_INT) 0)
92796263Sobrien	    reg_nonzero_bits[REGNO (x)]
92896263Sobrien	      |= nonzero_bits (src, nonzero_bits_mode);
92918334Speter	  num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
93018334Speter	  if (reg_sign_bit_copies[REGNO (x)] == 0
93118334Speter	      || reg_sign_bit_copies[REGNO (x)] > num)
93218334Speter	    reg_sign_bit_copies[REGNO (x)] = num;
93318334Speter	}
93418334Speter      else
93518334Speter	{
93618334Speter	  reg_nonzero_bits[REGNO (x)] = GET_MODE_MASK (GET_MODE (x));
93750397Sobrien	  reg_sign_bit_copies[REGNO (x)] = 1;
93818334Speter	}
93918334Speter    }
94018334Speter}
94118334Speter
94218334Speter/* See if INSN can be combined into I3.  PRED and SUCC are optionally
94318334Speter   insns that were previously combined into I3 or that will be combined
94418334Speter   into the merger of INSN and I3.
94518334Speter
94618334Speter   Return 0 if the combination is not allowed for any reason.
94718334Speter
94890075Sobrien   If the combination is allowed, *PDEST will be set to the single
94918334Speter   destination of INSN and *PSRC to the single source, and this function
95018334Speter   will return 1.  */
95118334Speter
95218334Speterstatic int
95318334Spetercan_combine_p (insn, i3, pred, succ, pdest, psrc)
95418334Speter     rtx insn;
95518334Speter     rtx i3;
95652284Sobrien     rtx pred ATTRIBUTE_UNUSED;
95752284Sobrien     rtx succ;
95818334Speter     rtx *pdest, *psrc;
95918334Speter{
96018334Speter  int i;
96118334Speter  rtx set = 0, src, dest;
96250397Sobrien  rtx p;
96350397Sobrien#ifdef AUTO_INC_DEC
96450397Sobrien  rtx link;
96550397Sobrien#endif
96618334Speter  int all_adjacent = (succ ? (next_active_insn (insn) == succ
96718334Speter			      && next_active_insn (succ) == i3)
96818334Speter		      : next_active_insn (insn) == i3);
96918334Speter
97018334Speter  /* Can combine only if previous insn is a SET of a REG, a SUBREG or CC0.
97190075Sobrien     or a PARALLEL consisting of such a SET and CLOBBERs.
97218334Speter
97318334Speter     If INSN has CLOBBER parallel parts, ignore them for our processing.
97418334Speter     By definition, these happen during the execution of the insn.  When it
97518334Speter     is merged with another insn, all bets are off.  If they are, in fact,
97618334Speter     needed and aren't also supplied in I3, they may be added by
97790075Sobrien     recog_for_combine.  Otherwise, it won't match.
97818334Speter
97918334Speter     We can also ignore a SET whose SET_DEST is mentioned in a REG_UNUSED
98018334Speter     note.
98118334Speter
98290075Sobrien     Get the source and destination of INSN.  If more than one, can't
98318334Speter     combine.  */
98490075Sobrien
98518334Speter  if (GET_CODE (PATTERN (insn)) == SET)
98618334Speter    set = PATTERN (insn);
98718334Speter  else if (GET_CODE (PATTERN (insn)) == PARALLEL
98818334Speter	   && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
98918334Speter    {
99018334Speter      for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
99118334Speter	{
99218334Speter	  rtx elt = XVECEXP (PATTERN (insn), 0, i);
99318334Speter
99418334Speter	  switch (GET_CODE (elt))
99518334Speter	    {
99650397Sobrien	    /* This is important to combine floating point insns
99750397Sobrien	       for the SH4 port.  */
99850397Sobrien	    case USE:
99950397Sobrien	      /* Combining an isolated USE doesn't make sense.
100090075Sobrien		 We depend here on combinable_i3pat to reject them.  */
100150397Sobrien	      /* The code below this loop only verifies that the inputs of
100250397Sobrien		 the SET in INSN do not change.  We call reg_set_between_p
100390075Sobrien		 to verify that the REG in the USE does not change between
100450397Sobrien		 I3 and INSN.
100550397Sobrien		 If the USE in INSN was for a pseudo register, the matching
100650397Sobrien		 insn pattern will likely match any register; combining this
100750397Sobrien		 with any other USE would only be safe if we knew that the
100850397Sobrien		 used registers have identical values, or if there was
100950397Sobrien		 something to tell them apart, e.g. different modes.  For
101090075Sobrien		 now, we forgo such complicated tests and simply disallow
101150397Sobrien		 combining of USES of pseudo registers with any other USE.  */
101250397Sobrien	      if (GET_CODE (XEXP (elt, 0)) == REG
101350397Sobrien		  && GET_CODE (PATTERN (i3)) == PARALLEL)
101450397Sobrien		{
101550397Sobrien		  rtx i3pat = PATTERN (i3);
101650397Sobrien		  int i = XVECLEN (i3pat, 0) - 1;
101790075Sobrien		  unsigned int regno = REGNO (XEXP (elt, 0));
101890075Sobrien
101950397Sobrien		  do
102050397Sobrien		    {
102150397Sobrien		      rtx i3elt = XVECEXP (i3pat, 0, i);
102290075Sobrien
102350397Sobrien		      if (GET_CODE (i3elt) == USE
102450397Sobrien			  && GET_CODE (XEXP (i3elt, 0)) == REG
102550397Sobrien			  && (REGNO (XEXP (i3elt, 0)) == regno
102650397Sobrien			      ? reg_set_between_p (XEXP (elt, 0),
102750397Sobrien						   PREV_INSN (insn), i3)
102850397Sobrien			      : regno >= FIRST_PSEUDO_REGISTER))
102950397Sobrien			return 0;
103050397Sobrien		    }
103150397Sobrien		  while (--i >= 0);
103250397Sobrien		}
103350397Sobrien	      break;
103450397Sobrien
103518334Speter	      /* We can ignore CLOBBERs.  */
103618334Speter	    case CLOBBER:
103718334Speter	      break;
103818334Speter
103918334Speter	    case SET:
104018334Speter	      /* Ignore SETs whose result isn't used but not those that
104118334Speter		 have side-effects.  */
104218334Speter	      if (find_reg_note (insn, REG_UNUSED, SET_DEST (elt))
104318334Speter		  && ! side_effects_p (elt))
104418334Speter		break;
104518334Speter
104618334Speter	      /* If we have already found a SET, this is a second one and
104718334Speter		 so we cannot combine with this insn.  */
104818334Speter	      if (set)
104918334Speter		return 0;
105018334Speter
105118334Speter	      set = elt;
105218334Speter	      break;
105318334Speter
105418334Speter	    default:
105518334Speter	      /* Anything else means we can't combine.  */
105618334Speter	      return 0;
105718334Speter	    }
105818334Speter	}
105918334Speter
106018334Speter      if (set == 0
106118334Speter	  /* If SET_SRC is an ASM_OPERANDS we can't throw away these CLOBBERs,
106218334Speter	     so don't do anything with it.  */
106318334Speter	  || GET_CODE (SET_SRC (set)) == ASM_OPERANDS)
106418334Speter	return 0;
106518334Speter    }
106618334Speter  else
106718334Speter    return 0;
106818334Speter
106918334Speter  if (set == 0)
107018334Speter    return 0;
107118334Speter
107218334Speter  set = expand_field_assignment (set);
107318334Speter  src = SET_SRC (set), dest = SET_DEST (set);
107418334Speter
107518334Speter  /* Don't eliminate a store in the stack pointer.  */
107618334Speter  if (dest == stack_pointer_rtx
107718334Speter      /* If we couldn't eliminate a field assignment, we can't combine.  */
107818334Speter      || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == STRICT_LOW_PART
107918334Speter      /* Don't combine with an insn that sets a register to itself if it has
108018334Speter	 a REG_EQUAL note.  This may be part of a REG_NO_CONFLICT sequence.  */
108118334Speter      || (rtx_equal_p (src, dest) && find_reg_note (insn, REG_EQUAL, NULL_RTX))
108290075Sobrien      /* Can't merge an ASM_OPERANDS.  */
108390075Sobrien      || GET_CODE (src) == ASM_OPERANDS
108418334Speter      /* Can't merge a function call.  */
108518334Speter      || GET_CODE (src) == CALL
108618334Speter      /* Don't eliminate a function call argument.  */
108718334Speter      || (GET_CODE (i3) == CALL_INSN
108818334Speter	  && (find_reg_fusage (i3, USE, dest)
108918334Speter	      || (GET_CODE (dest) == REG
109018334Speter		  && REGNO (dest) < FIRST_PSEUDO_REGISTER
109118334Speter		  && global_regs[REGNO (dest)])))
109218334Speter      /* Don't substitute into an incremented register.  */
109318334Speter      || FIND_REG_INC_NOTE (i3, dest)
109418334Speter      || (succ && FIND_REG_INC_NOTE (succ, dest))
109552284Sobrien#if 0
109618334Speter      /* Don't combine the end of a libcall into anything.  */
109752284Sobrien      /* ??? This gives worse code, and appears to be unnecessary, since no
109852284Sobrien	 pass after flow uses REG_LIBCALL/REG_RETVAL notes.  Local-alloc does
109952284Sobrien	 use REG_RETVAL notes for noconflict blocks, but other code here
110052284Sobrien	 makes sure that those insns don't disappear.  */
110118334Speter      || find_reg_note (insn, REG_RETVAL, NULL_RTX)
110252284Sobrien#endif
110318334Speter      /* Make sure that DEST is not used after SUCC but before I3.  */
110418334Speter      || (succ && ! all_adjacent
110518334Speter	  && reg_used_between_p (dest, succ, i3))
110618334Speter      /* Make sure that the value that is to be substituted for the register
110718334Speter	 does not use any registers whose values alter in between.  However,
110818334Speter	 If the insns are adjacent, a use can't cross a set even though we
110918334Speter	 think it might (this can happen for a sequence of insns each setting
111018334Speter	 the same destination; reg_last_set of that register might point to
111118334Speter	 a NOTE).  If INSN has a REG_EQUIV note, the register is always
111218334Speter	 equivalent to the memory so the substitution is valid even if there
111318334Speter	 are intervening stores.  Also, don't move a volatile asm or
111418334Speter	 UNSPEC_VOLATILE across any other insns.  */
111518334Speter      || (! all_adjacent
111618334Speter	  && (((GET_CODE (src) != MEM
111718334Speter		|| ! find_reg_note (insn, REG_EQUIV, src))
111818334Speter	       && use_crosses_set_p (src, INSN_CUID (insn)))
111918334Speter	      || (GET_CODE (src) == ASM_OPERANDS && MEM_VOLATILE_P (src))
112018334Speter	      || GET_CODE (src) == UNSPEC_VOLATILE))
112118334Speter      /* If there is a REG_NO_CONFLICT note for DEST in I3 or SUCC, we get
112218334Speter	 better register allocation by not doing the combine.  */
112318334Speter      || find_reg_note (i3, REG_NO_CONFLICT, dest)
112418334Speter      || (succ && find_reg_note (succ, REG_NO_CONFLICT, dest))
112518334Speter      /* Don't combine across a CALL_INSN, because that would possibly
112618334Speter	 change whether the life span of some REGs crosses calls or not,
112718334Speter	 and it is a pain to update that information.
112818334Speter	 Exception: if source is a constant, moving it later can't hurt.
112918334Speter	 Accept that special case, because it helps -fforce-addr a lot.  */
113018334Speter      || (INSN_CUID (insn) < last_call_cuid && ! CONSTANT_P (src)))
113118334Speter    return 0;
113218334Speter
113318334Speter  /* DEST must either be a REG or CC0.  */
113418334Speter  if (GET_CODE (dest) == REG)
113518334Speter    {
113618334Speter      /* If register alignment is being enforced for multi-word items in all
113718334Speter	 cases except for parameters, it is possible to have a register copy
113818334Speter	 insn referencing a hard register that is not allowed to contain the
113918334Speter	 mode being copied and which would not be valid as an operand of most
114018334Speter	 insns.  Eliminate this problem by not combining with such an insn.
114118334Speter
114218334Speter	 Also, on some machines we don't want to extend the life of a hard
114390075Sobrien	 register.  */
114418334Speter
114518334Speter      if (GET_CODE (src) == REG
114618334Speter	  && ((REGNO (dest) < FIRST_PSEUDO_REGISTER
114718334Speter	       && ! HARD_REGNO_MODE_OK (REGNO (dest), GET_MODE (dest)))
114818334Speter	      /* Don't extend the life of a hard register unless it is
114918334Speter		 user variable (if we have few registers) or it can't
115018334Speter		 fit into the desired register (meaning something special
115150397Sobrien		 is going on).
115250397Sobrien		 Also avoid substituting a return register into I3, because
115350397Sobrien		 reload can't handle a conflict with constraints of other
115450397Sobrien		 inputs.  */
115518334Speter	      || (REGNO (src) < FIRST_PSEUDO_REGISTER
115690075Sobrien		  && ! HARD_REGNO_MODE_OK (REGNO (src), GET_MODE (src)))))
115718334Speter	return 0;
115818334Speter    }
115918334Speter  else if (GET_CODE (dest) != CC0)
116018334Speter    return 0;
116118334Speter
116218334Speter  /* Don't substitute for a register intended as a clobberable operand.
116318334Speter     Similarly, don't substitute an expression containing a register that
116418334Speter     will be clobbered in I3.  */
116518334Speter  if (GET_CODE (PATTERN (i3)) == PARALLEL)
116618334Speter    for (i = XVECLEN (PATTERN (i3), 0) - 1; i >= 0; i--)
116718334Speter      if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER
116818334Speter	  && (reg_overlap_mentioned_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0),
116918334Speter				       src)
117018334Speter	      || rtx_equal_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0), dest)))
117118334Speter	return 0;
117218334Speter
117318334Speter  /* If INSN contains anything volatile, or is an `asm' (whether volatile
117450397Sobrien     or not), reject, unless nothing volatile comes between it and I3 */
117518334Speter
117618334Speter  if (GET_CODE (src) == ASM_OPERANDS || volatile_refs_p (src))
117750397Sobrien    {
117850397Sobrien      /* Make sure succ doesn't contain a volatile reference.  */
117950397Sobrien      if (succ != 0 && volatile_refs_p (PATTERN (succ)))
118050397Sobrien        return 0;
118190075Sobrien
118250397Sobrien      for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p))
118390075Sobrien        if (INSN_P (p) && p != succ && volatile_refs_p (PATTERN (p)))
118490075Sobrien	  return 0;
118550397Sobrien    }
118618334Speter
118750397Sobrien  /* If INSN is an asm, and DEST is a hard register, reject, since it has
118850397Sobrien     to be an explicit register variable, and was chosen for a reason.  */
118950397Sobrien
119050397Sobrien  if (GET_CODE (src) == ASM_OPERANDS
119150397Sobrien      && GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER)
119250397Sobrien    return 0;
119350397Sobrien
119418334Speter  /* If there are any volatile insns between INSN and I3, reject, because
119518334Speter     they might affect machine state.  */
119618334Speter
119718334Speter  for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p))
119890075Sobrien    if (INSN_P (p) && p != succ && volatile_insn_p (PATTERN (p)))
119918334Speter      return 0;
120018334Speter
120118334Speter  /* If INSN or I2 contains an autoincrement or autodecrement,
120218334Speter     make sure that register is not used between there and I3,
120318334Speter     and not already used in I3 either.
120418334Speter     Also insist that I3 not be a jump; if it were one
120518334Speter     and the incremented register were spilled, we would lose.  */
120618334Speter
120718334Speter#ifdef AUTO_INC_DEC
120818334Speter  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
120918334Speter    if (REG_NOTE_KIND (link) == REG_INC
121018334Speter	&& (GET_CODE (i3) == JUMP_INSN
121118334Speter	    || reg_used_between_p (XEXP (link, 0), insn, i3)
121218334Speter	    || reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i3))))
121318334Speter      return 0;
121418334Speter#endif
121518334Speter
121618334Speter#ifdef HAVE_cc0
121718334Speter  /* Don't combine an insn that follows a CC0-setting insn.
121818334Speter     An insn that uses CC0 must not be separated from the one that sets it.
121918334Speter     We do, however, allow I2 to follow a CC0-setting insn if that insn
122018334Speter     is passed as I1; in that case it will be deleted also.
122118334Speter     We also allow combining in this case if all the insns are adjacent
122218334Speter     because that would leave the two CC0 insns adjacent as well.
122318334Speter     It would be more logical to test whether CC0 occurs inside I1 or I2,
122418334Speter     but that would be much slower, and this ought to be equivalent.  */
122518334Speter
122618334Speter  p = prev_nonnote_insn (insn);
122718334Speter  if (p && p != pred && GET_CODE (p) == INSN && sets_cc0_p (PATTERN (p))
122818334Speter      && ! all_adjacent)
122918334Speter    return 0;
123018334Speter#endif
123118334Speter
123218334Speter  /* If we get here, we have passed all the tests and the combination is
123318334Speter     to be allowed.  */
123418334Speter
123518334Speter  *pdest = dest;
123618334Speter  *psrc = src;
123718334Speter
123818334Speter  return 1;
123918334Speter}
124018334Speter
124150397Sobrien/* Check if PAT is an insn - or a part of it - used to set up an
124250397Sobrien   argument for a function in a hard register.  */
124350397Sobrien
124450397Sobrienstatic int
124550397Sobriensets_function_arg_p (pat)
124650397Sobrien     rtx pat;
124750397Sobrien{
124850397Sobrien  int i;
124950397Sobrien  rtx inner_dest;
125050397Sobrien
125150397Sobrien  switch (GET_CODE (pat))
125250397Sobrien    {
125350397Sobrien    case INSN:
125450397Sobrien      return sets_function_arg_p (PATTERN (pat));
125550397Sobrien
125650397Sobrien    case PARALLEL:
125750397Sobrien      for (i = XVECLEN (pat, 0); --i >= 0;)
125850397Sobrien	if (sets_function_arg_p (XVECEXP (pat, 0, i)))
125950397Sobrien	  return 1;
126050397Sobrien
126150397Sobrien      break;
126250397Sobrien
126350397Sobrien    case SET:
126450397Sobrien      inner_dest = SET_DEST (pat);
126550397Sobrien      while (GET_CODE (inner_dest) == STRICT_LOW_PART
126650397Sobrien	     || GET_CODE (inner_dest) == SUBREG
126750397Sobrien	     || GET_CODE (inner_dest) == ZERO_EXTRACT)
126850397Sobrien	inner_dest = XEXP (inner_dest, 0);
126950397Sobrien
127050397Sobrien      return (GET_CODE (inner_dest) == REG
127150397Sobrien	      && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER
127250397Sobrien	      && FUNCTION_ARG_REGNO_P (REGNO (inner_dest)));
127350397Sobrien
127450397Sobrien    default:
127550397Sobrien      break;
127650397Sobrien    }
127750397Sobrien
127850397Sobrien  return 0;
127950397Sobrien}
128050397Sobrien
128118334Speter/* LOC is the location within I3 that contains its pattern or the component
128218334Speter   of a PARALLEL of the pattern.  We validate that it is valid for combining.
128318334Speter
128418334Speter   One problem is if I3 modifies its output, as opposed to replacing it
128518334Speter   entirely, we can't allow the output to contain I2DEST or I1DEST as doing
128618334Speter   so would produce an insn that is not equivalent to the original insns.
128718334Speter
128818334Speter   Consider:
128918334Speter
129018334Speter         (set (reg:DI 101) (reg:DI 100))
129118334Speter	 (set (subreg:SI (reg:DI 101) 0) <foo>)
129218334Speter
129318334Speter   This is NOT equivalent to:
129418334Speter
129518334Speter         (parallel [(set (subreg:SI (reg:DI 100) 0) <foo>)
129690075Sobrien		    (set (reg:DI 101) (reg:DI 100))])
129718334Speter
129818334Speter   Not only does this modify 100 (in which case it might still be valid
129990075Sobrien   if 100 were dead in I2), it sets 101 to the ORIGINAL value of 100.
130018334Speter
130118334Speter   We can also run into a problem if I2 sets a register that I1
130218334Speter   uses and I1 gets directly substituted into I3 (not via I2).  In that
130318334Speter   case, we would be getting the wrong value of I2DEST into I3, so we
130418334Speter   must reject the combination.  This case occurs when I2 and I1 both
130518334Speter   feed into I3, rather than when I1 feeds into I2, which feeds into I3.
1306117395Skan   If I1_NOT_IN_SRC is nonzero, it means that finding I1 in the source
130718334Speter   of a SET must prevent combination from occurring.
130818334Speter
130918334Speter   Before doing the above check, we first try to expand a field assignment
131018334Speter   into a set of logical operations.
131118334Speter
1312117395Skan   If PI3_DEST_KILLED is nonzero, it is a pointer to a location in which
131318334Speter   we place a register that is both set and used within I3.  If more than one
131418334Speter   such register is detected, we fail.
131518334Speter
131618334Speter   Return 1 if the combination is valid, zero otherwise.  */
131718334Speter
131818334Speterstatic int
131918334Spetercombinable_i3pat (i3, loc, i2dest, i1dest, i1_not_in_src, pi3dest_killed)
132018334Speter     rtx i3;
132118334Speter     rtx *loc;
132218334Speter     rtx i2dest;
132318334Speter     rtx i1dest;
132418334Speter     int i1_not_in_src;
132518334Speter     rtx *pi3dest_killed;
132618334Speter{
132718334Speter  rtx x = *loc;
132818334Speter
132918334Speter  if (GET_CODE (x) == SET)
133018334Speter    {
133118334Speter      rtx set = expand_field_assignment (x);
133218334Speter      rtx dest = SET_DEST (set);
133318334Speter      rtx src = SET_SRC (set);
133450397Sobrien      rtx inner_dest = dest;
133590075Sobrien
133650397Sobrien#if 0
133750397Sobrien      rtx inner_src = src;
133850397Sobrien#endif
133918334Speter
134018334Speter      SUBST (*loc, set);
134118334Speter
134218334Speter      while (GET_CODE (inner_dest) == STRICT_LOW_PART
134318334Speter	     || GET_CODE (inner_dest) == SUBREG
134418334Speter	     || GET_CODE (inner_dest) == ZERO_EXTRACT)
134518334Speter	inner_dest = XEXP (inner_dest, 0);
134618334Speter
134718334Speter  /* We probably don't need this any more now that LIMIT_RELOAD_CLASS
134818334Speter     was added.  */
134918334Speter#if 0
135018334Speter      while (GET_CODE (inner_src) == STRICT_LOW_PART
135118334Speter	     || GET_CODE (inner_src) == SUBREG
135218334Speter	     || GET_CODE (inner_src) == ZERO_EXTRACT)
135318334Speter	inner_src = XEXP (inner_src, 0);
135418334Speter
135518334Speter      /* If it is better that two different modes keep two different pseudos,
135618334Speter	 avoid combining them.  This avoids producing the following pattern
135718334Speter	 on a 386:
135818334Speter	  (set (subreg:SI (reg/v:QI 21) 0)
135918334Speter	       (lshiftrt:SI (reg/v:SI 20)
136018334Speter	           (const_int 24)))
136118334Speter	 If that were made, reload could not handle the pair of
136218334Speter	 reg 20/21, since it would try to get any GENERAL_REGS
136318334Speter	 but some of them don't handle QImode.  */
136418334Speter
136518334Speter      if (rtx_equal_p (inner_src, i2dest)
136618334Speter	  && GET_CODE (inner_dest) == REG
136718334Speter	  && ! MODES_TIEABLE_P (GET_MODE (i2dest), GET_MODE (inner_dest)))
136818334Speter	return 0;
136918334Speter#endif
137018334Speter
137118334Speter      /* Check for the case where I3 modifies its output, as
137218334Speter	 discussed above.  */
137318334Speter      if ((inner_dest != dest
137418334Speter	   && (reg_overlap_mentioned_p (i2dest, inner_dest)
137518334Speter	       || (i1dest && reg_overlap_mentioned_p (i1dest, inner_dest))))
137650397Sobrien
137790075Sobrien	  /* This is the same test done in can_combine_p except we can't test
137890075Sobrien	     all_adjacent; we don't have to, since this instruction will stay
137990075Sobrien	     in place, thus we are not considering increasing the lifetime of
138090075Sobrien	     INNER_DEST.
138150397Sobrien
138250397Sobrien	     Also, if this insn sets a function argument, combining it with
138350397Sobrien	     something that might need a spill could clobber a previous
138450397Sobrien	     function argument; the all_adjacent test in can_combine_p also
138550397Sobrien	     checks this; here, we do a more specific test for this case.  */
138690075Sobrien
138718334Speter	  || (GET_CODE (inner_dest) == REG
138818334Speter	      && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER
138918334Speter	      && (! HARD_REGNO_MODE_OK (REGNO (inner_dest),
139090075Sobrien					GET_MODE (inner_dest))))
139118334Speter	  || (i1_not_in_src && reg_overlap_mentioned_p (i1dest, src)))
139218334Speter	return 0;
139318334Speter
139418334Speter      /* If DEST is used in I3, it is being killed in this insn,
139590075Sobrien	 so record that for later.
139618334Speter	 Never add REG_DEAD notes for the FRAME_POINTER_REGNUM or the
139718334Speter	 STACK_POINTER_REGNUM, since these are always considered to be
139818334Speter	 live.  Similarly for ARG_POINTER_REGNUM if it is fixed.  */
139918334Speter      if (pi3dest_killed && GET_CODE (dest) == REG
140018334Speter	  && reg_referenced_p (dest, PATTERN (i3))
140118334Speter	  && REGNO (dest) != FRAME_POINTER_REGNUM
140218334Speter#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
140318334Speter	  && REGNO (dest) != HARD_FRAME_POINTER_REGNUM
140418334Speter#endif
140518334Speter#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
140618334Speter	  && (REGNO (dest) != ARG_POINTER_REGNUM
140718334Speter	      || ! fixed_regs [REGNO (dest)])
140818334Speter#endif
140918334Speter	  && REGNO (dest) != STACK_POINTER_REGNUM)
141018334Speter	{
141118334Speter	  if (*pi3dest_killed)
141218334Speter	    return 0;
141318334Speter
141418334Speter	  *pi3dest_killed = dest;
141518334Speter	}
141618334Speter    }
141718334Speter
141818334Speter  else if (GET_CODE (x) == PARALLEL)
141918334Speter    {
142018334Speter      int i;
142118334Speter
142218334Speter      for (i = 0; i < XVECLEN (x, 0); i++)
142318334Speter	if (! combinable_i3pat (i3, &XVECEXP (x, 0, i), i2dest, i1dest,
142418334Speter				i1_not_in_src, pi3dest_killed))
142518334Speter	  return 0;
142618334Speter    }
142718334Speter
142818334Speter  return 1;
142918334Speter}
143018334Speter
143190075Sobrien/* Return 1 if X is an arithmetic expression that contains a multiplication
143290075Sobrien   and division.  We don't count multiplications by powers of two here.  */
143390075Sobrien
143490075Sobrienstatic int
143590075Sobriencontains_muldiv (x)
143690075Sobrien     rtx x;
143790075Sobrien{
143890075Sobrien  switch (GET_CODE (x))
143990075Sobrien    {
144090075Sobrien    case MOD:  case DIV:  case UMOD:  case UDIV:
144190075Sobrien      return 1;
144290075Sobrien
144390075Sobrien    case MULT:
144490075Sobrien      return ! (GET_CODE (XEXP (x, 1)) == CONST_INT
144590075Sobrien		&& exact_log2 (INTVAL (XEXP (x, 1))) >= 0);
144690075Sobrien    default:
144790075Sobrien      switch (GET_RTX_CLASS (GET_CODE (x)))
144890075Sobrien	{
144990075Sobrien	case 'c':  case '<':  case '2':
145090075Sobrien	  return contains_muldiv (XEXP (x, 0))
145190075Sobrien	    || contains_muldiv (XEXP (x, 1));
145290075Sobrien
145390075Sobrien	case '1':
145490075Sobrien	  return contains_muldiv (XEXP (x, 0));
145590075Sobrien
145690075Sobrien	default:
145790075Sobrien	  return 0;
145890075Sobrien	}
145990075Sobrien    }
146090075Sobrien}
146190075Sobrien
146270635Sobrien/* Determine whether INSN can be used in a combination.  Return nonzero if
146370635Sobrien   not.  This is used in try_combine to detect early some cases where we
146470635Sobrien   can't perform combinations.  */
146570635Sobrien
146670635Sobrienstatic int
146770635Sobriencant_combine_insn_p (insn)
146870635Sobrien     rtx insn;
146970635Sobrien{
147070635Sobrien  rtx set;
147170635Sobrien  rtx src, dest;
147290075Sobrien
147370635Sobrien  /* If this isn't really an insn, we can't do anything.
147470635Sobrien     This can occur when flow deletes an insn that it has merged into an
147570635Sobrien     auto-increment address.  */
147690075Sobrien  if (! INSN_P (insn))
147770635Sobrien    return 1;
147870635Sobrien
147970635Sobrien  /* Never combine loads and stores involving hard regs.  The register
148070635Sobrien     allocator can usually handle such reg-reg moves by tying.  If we allow
148170635Sobrien     the combiner to make substitutions of hard regs, we risk aborting in
148270635Sobrien     reload on machines that have SMALL_REGISTER_CLASSES.
148370635Sobrien     As an exception, we allow combinations involving fixed regs; these are
148470635Sobrien     not available to the register allocator so there's no risk involved.  */
148570635Sobrien
148670635Sobrien  set = single_set (insn);
148770635Sobrien  if (! set)
148870635Sobrien    return 0;
148970635Sobrien  src = SET_SRC (set);
149070635Sobrien  dest = SET_DEST (set);
149170635Sobrien  if (GET_CODE (src) == SUBREG)
149270635Sobrien    src = SUBREG_REG (src);
149370635Sobrien  if (GET_CODE (dest) == SUBREG)
149470635Sobrien    dest = SUBREG_REG (dest);
149570635Sobrien  if (REG_P (src) && REG_P (dest)
149670635Sobrien      && ((REGNO (src) < FIRST_PSEUDO_REGISTER
149770635Sobrien	   && ! fixed_regs[REGNO (src)])
149870635Sobrien	  || (REGNO (dest) < FIRST_PSEUDO_REGISTER
149970635Sobrien	      && ! fixed_regs[REGNO (dest)])))
150070635Sobrien    return 1;
150170635Sobrien
150270635Sobrien  return 0;
150370635Sobrien}
150470635Sobrien
150518334Speter/* Try to combine the insns I1 and I2 into I3.
150618334Speter   Here I1 and I2 appear earlier than I3.
150718334Speter   I1 can be zero; then we combine just I2 into I3.
150890075Sobrien
150990075Sobrien   If we are combining three insns and the resulting insn is not recognized,
151018334Speter   try splitting it into two insns.  If that happens, I2 and I3 are retained
151118334Speter   and I1 is pseudo-deleted by turning it into a NOTE.  Otherwise, I1 and I2
151218334Speter   are pseudo-deleted.
151318334Speter
151490075Sobrien   Return 0 if the combination does not work.  Then nothing is changed.
151518334Speter   If we did the combination, return the insn at which combine should
151690075Sobrien   resume scanning.
151718334Speter
1518117395Skan   Set NEW_DIRECT_JUMP_P to a nonzero value if try_combine creates a
151990075Sobrien   new direct jump instruction.  */
152090075Sobrien
152118334Speterstatic rtx
152290075Sobrientry_combine (i3, i2, i1, new_direct_jump_p)
152390075Sobrien     rtx i3, i2, i1;
152490075Sobrien     int *new_direct_jump_p;
152518334Speter{
152690075Sobrien  /* New patterns for I3 and I2, respectively.  */
152718334Speter  rtx newpat, newi2pat = 0;
152896263Sobrien  int substed_i2 = 0, substed_i1 = 0;
152918334Speter  /* Indicates need to preserve SET in I1 or I2 in I3 if it is not dead.  */
153018334Speter  int added_sets_1, added_sets_2;
153118334Speter  /* Total number of SETs to put into I3.  */
153218334Speter  int total_sets;
153318334Speter  /* Nonzero is I2's body now appears in I3.  */
153418334Speter  int i2_is_used;
153518334Speter  /* INSN_CODEs for new I3, new I2, and user of condition code.  */
153690075Sobrien  int insn_code_number, i2_code_number = 0, other_code_number = 0;
153718334Speter  /* Contains I3 if the destination of I3 is used in its source, which means
153818334Speter     that the old life of I3 is being killed.  If that usage is placed into
153918334Speter     I2 and not in I3, a REG_DEAD note must be made.  */
154018334Speter  rtx i3dest_killed = 0;
154118334Speter  /* SET_DEST and SET_SRC of I2 and I1.  */
154218334Speter  rtx i2dest, i2src, i1dest = 0, i1src = 0;
154318334Speter  /* PATTERN (I2), or a copy of it in certain cases.  */
154418334Speter  rtx i2pat;
154518334Speter  /* Indicates if I2DEST or I1DEST is in I2SRC or I1_SRC.  */
154618334Speter  int i2dest_in_i2src = 0, i1dest_in_i1src = 0, i2dest_in_i1src = 0;
154718334Speter  int i1_feeds_i3 = 0;
154818334Speter  /* Notes that must be added to REG_NOTES in I3 and I2.  */
154918334Speter  rtx new_i3_notes, new_i2_notes;
155018334Speter  /* Notes that we substituted I3 into I2 instead of the normal case.  */
155118334Speter  int i3_subst_into_i2 = 0;
155218334Speter  /* Notes that I1, I2 or I3 is a MULT operation.  */
155318334Speter  int have_mult = 0;
155418334Speter
155518334Speter  int maxreg;
155618334Speter  rtx temp;
155790075Sobrien  rtx link;
155818334Speter  int i;
155918334Speter
156070635Sobrien  /* Exit early if one of the insns involved can't be used for
156170635Sobrien     combinations.  */
156270635Sobrien  if (cant_combine_insn_p (i3)
156370635Sobrien      || cant_combine_insn_p (i2)
156470635Sobrien      || (i1 && cant_combine_insn_p (i1))
156570635Sobrien      /* We also can't do anything if I3 has a
156670635Sobrien	 REG_LIBCALL note since we don't want to disrupt the contiguity of a
156770635Sobrien	 libcall.  */
156852284Sobrien#if 0
156952284Sobrien      /* ??? This gives worse code, and appears to be unnecessary, since no
157052284Sobrien	 pass after flow uses REG_LIBCALL/REG_RETVAL notes.  */
157152284Sobrien      || find_reg_note (i3, REG_LIBCALL, NULL_RTX)
157252284Sobrien#endif
157370635Sobrien      )
157418334Speter    return 0;
157518334Speter
157618334Speter  combine_attempts++;
157718334Speter  undobuf.other_insn = 0;
157818334Speter
157918334Speter  /* Reset the hard register usage information.  */
158018334Speter  CLEAR_HARD_REG_SET (newpat_used_regs);
158118334Speter
158218334Speter  /* If I1 and I2 both feed I3, they can be in any order.  To simplify the
158318334Speter     code below, set I1 to be the earlier of the two insns.  */
158418334Speter  if (i1 && INSN_CUID (i1) > INSN_CUID (i2))
158518334Speter    temp = i1, i1 = i2, i2 = temp;
158618334Speter
158718334Speter  added_links_insn = 0;
158818334Speter
158918334Speter  /* First check for one important special-case that the code below will
159090075Sobrien     not handle.  Namely, the case where I1 is zero, I2 is a PARALLEL
159118334Speter     and I3 is a SET whose SET_SRC is a SET_DEST in I2.  In that case,
159218334Speter     we may be able to replace that destination with the destination of I3.
159318334Speter     This occurs in the common code where we compute both a quotient and
159418334Speter     remainder into a structure, in which case we want to do the computation
159518334Speter     directly into the structure to avoid register-register copies.
159618334Speter
159790075Sobrien     Note that this case handles both multiple sets in I2 and also
159890075Sobrien     cases where I2 has a number of CLOBBER or PARALLELs.
159990075Sobrien
160018334Speter     We make very conservative checks below and only try to handle the
160118334Speter     most common cases of this.  For example, we only handle the case
160218334Speter     where I2 and I3 are adjacent to avoid making difficult register
160318334Speter     usage tests.  */
160418334Speter
160518334Speter  if (i1 == 0 && GET_CODE (i3) == INSN && GET_CODE (PATTERN (i3)) == SET
160618334Speter      && GET_CODE (SET_SRC (PATTERN (i3))) == REG
160718334Speter      && REGNO (SET_SRC (PATTERN (i3))) >= FIRST_PSEUDO_REGISTER
160818334Speter      && find_reg_note (i3, REG_DEAD, SET_SRC (PATTERN (i3)))
160918334Speter      && GET_CODE (PATTERN (i2)) == PARALLEL
161018334Speter      && ! side_effects_p (SET_DEST (PATTERN (i3)))
161118334Speter      /* If the dest of I3 is a ZERO_EXTRACT or STRICT_LOW_PART, the code
161218334Speter	 below would need to check what is inside (and reg_overlap_mentioned_p
161318334Speter	 doesn't support those codes anyway).  Don't allow those destinations;
161418334Speter	 the resulting insn isn't likely to be recognized anyway.  */
161518334Speter      && GET_CODE (SET_DEST (PATTERN (i3))) != ZERO_EXTRACT
161618334Speter      && GET_CODE (SET_DEST (PATTERN (i3))) != STRICT_LOW_PART
161718334Speter      && ! reg_overlap_mentioned_p (SET_SRC (PATTERN (i3)),
161818334Speter				    SET_DEST (PATTERN (i3)))
161918334Speter      && next_real_insn (i2) == i3)
162018334Speter    {
162118334Speter      rtx p2 = PATTERN (i2);
162218334Speter
162318334Speter      /* Make sure that the destination of I3,
162418334Speter	 which we are going to substitute into one output of I2,
162518334Speter	 is not used within another output of I2.  We must avoid making this:
162618334Speter	 (parallel [(set (mem (reg 69)) ...)
162718334Speter		    (set (reg 69) ...)])
162818334Speter	 which is not well-defined as to order of actions.
162918334Speter	 (Besides, reload can't handle output reloads for this.)
163018334Speter
163118334Speter	 The problem can also happen if the dest of I3 is a memory ref,
163218334Speter	 if another dest in I2 is an indirect memory ref.  */
163318334Speter      for (i = 0; i < XVECLEN (p2, 0); i++)
163450397Sobrien	if ((GET_CODE (XVECEXP (p2, 0, i)) == SET
163550397Sobrien	     || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER)
163618334Speter	    && reg_overlap_mentioned_p (SET_DEST (PATTERN (i3)),
163718334Speter					SET_DEST (XVECEXP (p2, 0, i))))
163818334Speter	  break;
163918334Speter
164018334Speter      if (i == XVECLEN (p2, 0))
164118334Speter	for (i = 0; i < XVECLEN (p2, 0); i++)
164290075Sobrien	  if ((GET_CODE (XVECEXP (p2, 0, i)) == SET
164390075Sobrien	       || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER)
164490075Sobrien	      && SET_DEST (XVECEXP (p2, 0, i)) == SET_SRC (PATTERN (i3)))
164518334Speter	    {
164618334Speter	      combine_merges++;
164718334Speter
164818334Speter	      subst_insn = i3;
164918334Speter	      subst_low_cuid = INSN_CUID (i2);
165018334Speter
165118334Speter	      added_sets_2 = added_sets_1 = 0;
165218334Speter	      i2dest = SET_SRC (PATTERN (i3));
165318334Speter
165418334Speter	      /* Replace the dest in I2 with our dest and make the resulting
165518334Speter		 insn the new pattern for I3.  Then skip to where we
165618334Speter		 validate the pattern.  Everything was set up above.  */
165790075Sobrien	      SUBST (SET_DEST (XVECEXP (p2, 0, i)),
165818334Speter		     SET_DEST (PATTERN (i3)));
165918334Speter
166018334Speter	      newpat = p2;
166118334Speter	      i3_subst_into_i2 = 1;
166218334Speter	      goto validate_replacement;
166318334Speter	    }
166418334Speter    }
166518334Speter
166690075Sobrien  /* If I2 is setting a double-word pseudo to a constant and I3 is setting
166790075Sobrien     one of those words to another constant, merge them by making a new
166890075Sobrien     constant.  */
166990075Sobrien  if (i1 == 0
167090075Sobrien      && (temp = single_set (i2)) != 0
167190075Sobrien      && (GET_CODE (SET_SRC (temp)) == CONST_INT
167290075Sobrien	  || GET_CODE (SET_SRC (temp)) == CONST_DOUBLE)
167390075Sobrien      && GET_CODE (SET_DEST (temp)) == REG
167490075Sobrien      && GET_MODE_CLASS (GET_MODE (SET_DEST (temp))) == MODE_INT
167590075Sobrien      && GET_MODE_SIZE (GET_MODE (SET_DEST (temp))) == 2 * UNITS_PER_WORD
167690075Sobrien      && GET_CODE (PATTERN (i3)) == SET
167790075Sobrien      && GET_CODE (SET_DEST (PATTERN (i3))) == SUBREG
167890075Sobrien      && SUBREG_REG (SET_DEST (PATTERN (i3))) == SET_DEST (temp)
167990075Sobrien      && GET_MODE_CLASS (GET_MODE (SET_DEST (PATTERN (i3)))) == MODE_INT
168090075Sobrien      && GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (i3)))) == UNITS_PER_WORD
168190075Sobrien      && GET_CODE (SET_SRC (PATTERN (i3))) == CONST_INT)
168290075Sobrien    {
168390075Sobrien      HOST_WIDE_INT lo, hi;
168490075Sobrien
168590075Sobrien      if (GET_CODE (SET_SRC (temp)) == CONST_INT)
168690075Sobrien	lo = INTVAL (SET_SRC (temp)), hi = lo < 0 ? -1 : 0;
168790075Sobrien      else
168890075Sobrien	{
168990075Sobrien	  lo = CONST_DOUBLE_LOW (SET_SRC (temp));
169090075Sobrien	  hi = CONST_DOUBLE_HIGH (SET_SRC (temp));
169190075Sobrien	}
169290075Sobrien
169390075Sobrien      if (subreg_lowpart_p (SET_DEST (PATTERN (i3))))
169490075Sobrien	{
169590075Sobrien	  /* We don't handle the case of the target word being wider
169690075Sobrien	     than a host wide int.  */
169790075Sobrien	  if (HOST_BITS_PER_WIDE_INT < BITS_PER_WORD)
169890075Sobrien	    abort ();
169990075Sobrien
170090075Sobrien	  lo &= ~(UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD (1) - 1);
170190075Sobrien	  lo |= (INTVAL (SET_SRC (PATTERN (i3)))
170290075Sobrien		 & (UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD (1) - 1));
170390075Sobrien	}
170490075Sobrien      else if (HOST_BITS_PER_WIDE_INT == BITS_PER_WORD)
170590075Sobrien	hi = INTVAL (SET_SRC (PATTERN (i3)));
170690075Sobrien      else if (HOST_BITS_PER_WIDE_INT >= 2 * BITS_PER_WORD)
170790075Sobrien	{
170890075Sobrien	  int sign = -(int) ((unsigned HOST_WIDE_INT) lo
170990075Sobrien			     >> (HOST_BITS_PER_WIDE_INT - 1));
171090075Sobrien
171190075Sobrien	  lo &= ~ (UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD
171290075Sobrien		   (UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD (1) - 1));
171390075Sobrien	  lo |= (UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD
171490075Sobrien		 (INTVAL (SET_SRC (PATTERN (i3)))));
171590075Sobrien	  if (hi == sign)
171690075Sobrien	    hi = lo < 0 ? -1 : 0;
171790075Sobrien	}
171890075Sobrien      else
171990075Sobrien	/* We don't handle the case of the higher word not fitting
172090075Sobrien	   entirely in either hi or lo.  */
172190075Sobrien	abort ();
172290075Sobrien
172390075Sobrien      combine_merges++;
172490075Sobrien      subst_insn = i3;
172590075Sobrien      subst_low_cuid = INSN_CUID (i2);
172690075Sobrien      added_sets_2 = added_sets_1 = 0;
172790075Sobrien      i2dest = SET_DEST (temp);
172890075Sobrien
172990075Sobrien      SUBST (SET_SRC (temp),
173090075Sobrien	     immed_double_const (lo, hi, GET_MODE (SET_DEST (temp))));
173190075Sobrien
173290075Sobrien      newpat = PATTERN (i2);
173390075Sobrien      goto validate_replacement;
173490075Sobrien    }
173590075Sobrien
173618334Speter#ifndef HAVE_cc0
173718334Speter  /* If we have no I1 and I2 looks like:
173818334Speter	(parallel [(set (reg:CC X) (compare:CC OP (const_int 0)))
173918334Speter		   (set Y OP)])
174018334Speter     make up a dummy I1 that is
174118334Speter	(set Y OP)
174218334Speter     and change I2 to be
174318334Speter        (set (reg:CC X) (compare:CC Y (const_int 0)))
174418334Speter
174518334Speter     (We can ignore any trailing CLOBBERs.)
174618334Speter
174718334Speter     This undoes a previous combination and allows us to match a branch-and-
174818334Speter     decrement insn.  */
174918334Speter
175018334Speter  if (i1 == 0 && GET_CODE (PATTERN (i2)) == PARALLEL
175118334Speter      && XVECLEN (PATTERN (i2), 0) >= 2
175218334Speter      && GET_CODE (XVECEXP (PATTERN (i2), 0, 0)) == SET
175318334Speter      && (GET_MODE_CLASS (GET_MODE (SET_DEST (XVECEXP (PATTERN (i2), 0, 0))))
175418334Speter	  == MODE_CC)
175518334Speter      && GET_CODE (SET_SRC (XVECEXP (PATTERN (i2), 0, 0))) == COMPARE
175618334Speter      && XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 1) == const0_rtx
175718334Speter      && GET_CODE (XVECEXP (PATTERN (i2), 0, 1)) == SET
175818334Speter      && GET_CODE (SET_DEST (XVECEXP (PATTERN (i2), 0, 1))) == REG
175918334Speter      && rtx_equal_p (XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 0),
176018334Speter		      SET_SRC (XVECEXP (PATTERN (i2), 0, 1))))
176118334Speter    {
176290075Sobrien      for (i = XVECLEN (PATTERN (i2), 0) - 1; i >= 2; i--)
176318334Speter	if (GET_CODE (XVECEXP (PATTERN (i2), 0, i)) != CLOBBER)
176418334Speter	  break;
176518334Speter
176618334Speter      if (i == 1)
176718334Speter	{
176818334Speter	  /* We make I1 with the same INSN_UID as I2.  This gives it
176918334Speter	     the same INSN_CUID for value tracking.  Our fake I1 will
177018334Speter	     never appear in the insn stream so giving it the same INSN_UID
177118334Speter	     as I2 will not cause a problem.  */
177218334Speter
177318334Speter	  subst_prev_insn = i1
177450397Sobrien	    = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2,
1775117395Skan			    BLOCK_FOR_INSN (i2), INSN_SCOPE (i2),
177650397Sobrien			    XVECEXP (PATTERN (i2), 0, 1), -1, NULL_RTX,
177750397Sobrien			    NULL_RTX);
177818334Speter
177918334Speter	  SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0));
178018334Speter	  SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),
178118334Speter		 SET_DEST (PATTERN (i1)));
178218334Speter	}
178318334Speter    }
178418334Speter#endif
178518334Speter
178618334Speter  /* Verify that I2 and I1 are valid for combining.  */
178718334Speter  if (! can_combine_p (i2, i3, i1, NULL_RTX, &i2dest, &i2src)
178818334Speter      || (i1 && ! can_combine_p (i1, i3, NULL_RTX, i2, &i1dest, &i1src)))
178918334Speter    {
179018334Speter      undo_all ();
179118334Speter      return 0;
179218334Speter    }
179318334Speter
179418334Speter  /* Record whether I2DEST is used in I2SRC and similarly for the other
179518334Speter     cases.  Knowing this will help in register status updating below.  */
179618334Speter  i2dest_in_i2src = reg_overlap_mentioned_p (i2dest, i2src);
179718334Speter  i1dest_in_i1src = i1 && reg_overlap_mentioned_p (i1dest, i1src);
179818334Speter  i2dest_in_i1src = i1 && reg_overlap_mentioned_p (i2dest, i1src);
179918334Speter
180018334Speter  /* See if I1 directly feeds into I3.  It does if I1DEST is not used
180118334Speter     in I2SRC.  */
180218334Speter  i1_feeds_i3 = i1 && ! reg_overlap_mentioned_p (i1dest, i2src);
180318334Speter
180418334Speter  /* Ensure that I3's pattern can be the destination of combines.  */
180518334Speter  if (! combinable_i3pat (i3, &PATTERN (i3), i2dest, i1dest,
180618334Speter			  i1 && i2dest_in_i1src && i1_feeds_i3,
180718334Speter			  &i3dest_killed))
180818334Speter    {
180918334Speter      undo_all ();
181018334Speter      return 0;
181118334Speter    }
181218334Speter
181318334Speter  /* See if any of the insns is a MULT operation.  Unless one is, we will
181418334Speter     reject a combination that is, since it must be slower.  Be conservative
181518334Speter     here.  */
181618334Speter  if (GET_CODE (i2src) == MULT
181718334Speter      || (i1 != 0 && GET_CODE (i1src) == MULT)
181818334Speter      || (GET_CODE (PATTERN (i3)) == SET
181918334Speter	  && GET_CODE (SET_SRC (PATTERN (i3))) == MULT))
182018334Speter    have_mult = 1;
182118334Speter
182218334Speter  /* If I3 has an inc, then give up if I1 or I2 uses the reg that is inc'd.
182318334Speter     We used to do this EXCEPT in one case: I3 has a post-inc in an
182418334Speter     output operand.  However, that exception can give rise to insns like
182590075Sobrien	mov r3,(r3)+
182618334Speter     which is a famous insn on the PDP-11 where the value of r3 used as the
182718334Speter     source was model-dependent.  Avoid this sort of thing.  */
182818334Speter
182918334Speter#if 0
183018334Speter  if (!(GET_CODE (PATTERN (i3)) == SET
183118334Speter	&& GET_CODE (SET_SRC (PATTERN (i3))) == REG
183218334Speter	&& GET_CODE (SET_DEST (PATTERN (i3))) == MEM
183318334Speter	&& (GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_INC
183418334Speter	    || GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_DEC)))
183518334Speter    /* It's not the exception.  */
183618334Speter#endif
183718334Speter#ifdef AUTO_INC_DEC
183818334Speter    for (link = REG_NOTES (i3); link; link = XEXP (link, 1))
183918334Speter      if (REG_NOTE_KIND (link) == REG_INC
184018334Speter	  && (reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i2))
184118334Speter	      || (i1 != 0
184218334Speter		  && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i1)))))
184318334Speter	{
184418334Speter	  undo_all ();
184518334Speter	  return 0;
184618334Speter	}
184718334Speter#endif
184818334Speter
184918334Speter  /* See if the SETs in I1 or I2 need to be kept around in the merged
185018334Speter     instruction: whenever the value set there is still needed past I3.
185118334Speter     For the SETs in I2, this is easy: we see if I2DEST dies or is set in I3.
185218334Speter
185318334Speter     For the SET in I1, we have two cases:  If I1 and I2 independently
185418334Speter     feed into I3, the set in I1 needs to be kept around if I1DEST dies
185518334Speter     or is set in I3.  Otherwise (if I1 feeds I2 which feeds I3), the set
185618334Speter     in I1 needs to be kept around unless I1DEST dies or is set in either
185718334Speter     I2 or I3.  We can distinguish these cases by seeing if I2SRC mentions
185818334Speter     I1DEST.  If so, we know I1 feeds into I2.  */
185918334Speter
186018334Speter  added_sets_2 = ! dead_or_set_p (i3, i2dest);
186118334Speter
186218334Speter  added_sets_1
186318334Speter    = i1 && ! (i1_feeds_i3 ? dead_or_set_p (i3, i1dest)
186418334Speter	       : (dead_or_set_p (i3, i1dest) || dead_or_set_p (i2, i1dest)));
186518334Speter
186618334Speter  /* If the set in I2 needs to be kept around, we must make a copy of
186718334Speter     PATTERN (I2), so that when we substitute I1SRC for I1DEST in
186818334Speter     PATTERN (I2), we are only substituting for the original I1DEST, not into
186918334Speter     an already-substituted copy.  This also prevents making self-referential
187018334Speter     rtx.  If I2 is a PARALLEL, we just need the piece that assigns I2SRC to
187118334Speter     I2DEST.  */
187218334Speter
187318334Speter  i2pat = (GET_CODE (PATTERN (i2)) == PARALLEL
187450397Sobrien	   ? gen_rtx_SET (VOIDmode, i2dest, i2src)
187518334Speter	   : PATTERN (i2));
187618334Speter
187718334Speter  if (added_sets_2)
187818334Speter    i2pat = copy_rtx (i2pat);
187918334Speter
188018334Speter  combine_merges++;
188118334Speter
188218334Speter  /* Substitute in the latest insn for the regs set by the earlier ones.  */
188318334Speter
188418334Speter  maxreg = max_reg_num ();
188518334Speter
188618334Speter  subst_insn = i3;
188718334Speter
188818334Speter  /* It is possible that the source of I2 or I1 may be performing an
188918334Speter     unneeded operation, such as a ZERO_EXTEND of something that is known
189018334Speter     to have the high part zero.  Handle that case by letting subst look at
189118334Speter     the innermost one of them.
189218334Speter
189318334Speter     Another way to do this would be to have a function that tries to
189418334Speter     simplify a single insn instead of merging two or more insns.  We don't
189518334Speter     do this because of the potential of infinite loops and because
189618334Speter     of the potential extra memory required.  However, doing it the way
189718334Speter     we are is a bit of a kludge and doesn't catch all cases.
189818334Speter
189918334Speter     But only do this if -fexpensive-optimizations since it slows things down
190018334Speter     and doesn't usually win.  */
190118334Speter
190218334Speter  if (flag_expensive_optimizations)
190318334Speter    {
190418334Speter      /* Pass pc_rtx so no substitutions are done, just simplifications.
190518334Speter	 The cases that we are interested in here do not involve the few
190618334Speter	 cases were is_replaced is checked.  */
190718334Speter      if (i1)
190818334Speter	{
190918334Speter	  subst_low_cuid = INSN_CUID (i1);
191018334Speter	  i1src = subst (i1src, pc_rtx, pc_rtx, 0, 0);
191118334Speter	}
191218334Speter      else
191318334Speter	{
191418334Speter	  subst_low_cuid = INSN_CUID (i2);
191518334Speter	  i2src = subst (i2src, pc_rtx, pc_rtx, 0, 0);
191618334Speter	}
191718334Speter    }
191818334Speter
191918334Speter#ifndef HAVE_cc0
192018334Speter  /* Many machines that don't use CC0 have insns that can both perform an
192118334Speter     arithmetic operation and set the condition code.  These operations will
192218334Speter     be represented as a PARALLEL with the first element of the vector
192318334Speter     being a COMPARE of an arithmetic operation with the constant zero.
192418334Speter     The second element of the vector will set some pseudo to the result
192518334Speter     of the same arithmetic operation.  If we simplify the COMPARE, we won't
192618334Speter     match such a pattern and so will generate an extra insn.   Here we test
192718334Speter     for this case, where both the comparison and the operation result are
192818334Speter     needed, and make the PARALLEL by just replacing I2DEST in I3SRC with
192918334Speter     I2SRC.  Later we will make the PARALLEL that contains I2.  */
193018334Speter
193118334Speter  if (i1 == 0 && added_sets_2 && GET_CODE (PATTERN (i3)) == SET
193218334Speter      && GET_CODE (SET_SRC (PATTERN (i3))) == COMPARE
193318334Speter      && XEXP (SET_SRC (PATTERN (i3)), 1) == const0_rtx
193418334Speter      && rtx_equal_p (XEXP (SET_SRC (PATTERN (i3)), 0), i2dest))
193518334Speter    {
193650397Sobrien#ifdef EXTRA_CC_MODES
193718334Speter      rtx *cc_use;
193818334Speter      enum machine_mode compare_mode;
193950397Sobrien#endif
194018334Speter
194118334Speter      newpat = PATTERN (i3);
194218334Speter      SUBST (XEXP (SET_SRC (newpat), 0), i2src);
194318334Speter
194418334Speter      i2_is_used = 1;
194518334Speter
194618334Speter#ifdef EXTRA_CC_MODES
194718334Speter      /* See if a COMPARE with the operand we substituted in should be done
194818334Speter	 with the mode that is currently being used.  If not, do the same
194918334Speter	 processing we do in `subst' for a SET; namely, if the destination
195018334Speter	 is used only once, try to replace it with a register of the proper
195118334Speter	 mode and also replace the COMPARE.  */
195218334Speter      if (undobuf.other_insn == 0
195318334Speter	  && (cc_use = find_single_use (SET_DEST (newpat), i3,
195418334Speter					&undobuf.other_insn))
195518334Speter	  && ((compare_mode = SELECT_CC_MODE (GET_CODE (*cc_use),
195618334Speter					      i2src, const0_rtx))
195718334Speter	      != GET_MODE (SET_DEST (newpat))))
195818334Speter	{
195990075Sobrien	  unsigned int regno = REGNO (SET_DEST (newpat));
196050397Sobrien	  rtx new_dest = gen_rtx_REG (compare_mode, regno);
196118334Speter
196218334Speter	  if (regno < FIRST_PSEUDO_REGISTER
196350397Sobrien	      || (REG_N_SETS (regno) == 1 && ! added_sets_2
196418334Speter		  && ! REG_USERVAR_P (SET_DEST (newpat))))
196518334Speter	    {
196618334Speter	      if (regno >= FIRST_PSEUDO_REGISTER)
196718334Speter		SUBST (regno_reg_rtx[regno], new_dest);
196818334Speter
196918334Speter	      SUBST (SET_DEST (newpat), new_dest);
197018334Speter	      SUBST (XEXP (*cc_use, 0), new_dest);
197118334Speter	      SUBST (SET_SRC (newpat),
197290075Sobrien		     gen_rtx_COMPARE (compare_mode, i2src, const0_rtx));
197318334Speter	    }
197418334Speter	  else
197518334Speter	    undobuf.other_insn = 0;
197618334Speter	}
197790075Sobrien#endif
197818334Speter    }
197918334Speter  else
198018334Speter#endif
198118334Speter    {
198218334Speter      n_occurrences = 0;		/* `subst' counts here */
198318334Speter
198418334Speter      /* If I1 feeds into I2 (not into I3) and I1DEST is in I1SRC, we
198518334Speter	 need to make a unique copy of I2SRC each time we substitute it
198618334Speter	 to avoid self-referential rtl.  */
198718334Speter
198818334Speter      subst_low_cuid = INSN_CUID (i2);
198918334Speter      newpat = subst (PATTERN (i3), i2dest, i2src, 0,
199018334Speter		      ! i1_feeds_i3 && i1dest_in_i1src);
199196263Sobrien      substed_i2 = 1;
199218334Speter
199318334Speter      /* Record whether i2's body now appears within i3's body.  */
199418334Speter      i2_is_used = n_occurrences;
199518334Speter    }
199618334Speter
199718334Speter  /* If we already got a failure, don't try to do more.  Otherwise,
199818334Speter     try to substitute in I1 if we have it.  */
199918334Speter
200018334Speter  if (i1 && GET_CODE (newpat) != CLOBBER)
200118334Speter    {
200218334Speter      /* Before we can do this substitution, we must redo the test done
200318334Speter	 above (see detailed comments there) that ensures  that I1DEST
200450397Sobrien	 isn't mentioned in any SETs in NEWPAT that are field assignments.  */
200518334Speter
200618334Speter      if (! combinable_i3pat (NULL_RTX, &newpat, i1dest, NULL_RTX,
200790075Sobrien			      0, (rtx*) 0))
200818334Speter	{
200918334Speter	  undo_all ();
201018334Speter	  return 0;
201118334Speter	}
201218334Speter
201318334Speter      n_occurrences = 0;
201418334Speter      subst_low_cuid = INSN_CUID (i1);
201518334Speter      newpat = subst (newpat, i1dest, i1src, 0, 0);
201696263Sobrien      substed_i1 = 1;
201718334Speter    }
201818334Speter
201918334Speter  /* Fail if an autoincrement side-effect has been duplicated.  Be careful
202018334Speter     to count all the ways that I2SRC and I1SRC can be used.  */
202118334Speter  if ((FIND_REG_INC_NOTE (i2, NULL_RTX) != 0
202218334Speter       && i2_is_used + added_sets_2 > 1)
202318334Speter      || (i1 != 0 && FIND_REG_INC_NOTE (i1, NULL_RTX) != 0
202418334Speter	  && (n_occurrences + added_sets_1 + (added_sets_2 && ! i1_feeds_i3)
202518334Speter	      > 1))
202618334Speter      /* Fail if we tried to make a new register (we used to abort, but there's
202718334Speter	 really no reason to).  */
202818334Speter      || max_reg_num () != maxreg
202918334Speter      /* Fail if we couldn't do something and have a CLOBBER.  */
203018334Speter      || GET_CODE (newpat) == CLOBBER
203118334Speter      /* Fail if this new pattern is a MULT and we didn't have one before
203218334Speter	 at the outer level.  */
203318334Speter      || (GET_CODE (newpat) == SET && GET_CODE (SET_SRC (newpat)) == MULT
203418334Speter	  && ! have_mult))
203518334Speter    {
203618334Speter      undo_all ();
203718334Speter      return 0;
203818334Speter    }
203918334Speter
204018334Speter  /* If the actions of the earlier insns must be kept
204118334Speter     in addition to substituting them into the latest one,
204218334Speter     we must make a new PARALLEL for the latest insn
204318334Speter     to hold additional the SETs.  */
204418334Speter
204518334Speter  if (added_sets_1 || added_sets_2)
204618334Speter    {
204718334Speter      combine_extras++;
204818334Speter
204918334Speter      if (GET_CODE (newpat) == PARALLEL)
205018334Speter	{
205118334Speter	  rtvec old = XVEC (newpat, 0);
205218334Speter	  total_sets = XVECLEN (newpat, 0) + added_sets_1 + added_sets_2;
205350397Sobrien	  newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets));
205490075Sobrien	  memcpy (XVEC (newpat, 0)->elem, &old->elem[0],
205590075Sobrien		  sizeof (old->elem[0]) * old->num_elem);
205618334Speter	}
205718334Speter      else
205818334Speter	{
205918334Speter	  rtx old = newpat;
206018334Speter	  total_sets = 1 + added_sets_1 + added_sets_2;
206150397Sobrien	  newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets));
206218334Speter	  XVECEXP (newpat, 0, 0) = old;
206318334Speter	}
206418334Speter
206590075Sobrien      if (added_sets_1)
206690075Sobrien	XVECEXP (newpat, 0, --total_sets)
206790075Sobrien	  = (GET_CODE (PATTERN (i1)) == PARALLEL
206890075Sobrien	     ? gen_rtx_SET (VOIDmode, i1dest, i1src) : PATTERN (i1));
206918334Speter
207090075Sobrien      if (added_sets_2)
207118334Speter	{
207218334Speter	  /* If there is no I1, use I2's body as is.  We used to also not do
207318334Speter	     the subst call below if I2 was substituted into I3,
207418334Speter	     but that could lose a simplification.  */
207518334Speter	  if (i1 == 0)
207618334Speter	    XVECEXP (newpat, 0, --total_sets) = i2pat;
207718334Speter	  else
207818334Speter	    /* See comment where i2pat is assigned.  */
207918334Speter	    XVECEXP (newpat, 0, --total_sets)
208018334Speter	      = subst (i2pat, i1dest, i1src, 0, 0);
208118334Speter	}
208218334Speter    }
208318334Speter
208418334Speter  /* We come here when we are replacing a destination in I2 with the
208518334Speter     destination of I3.  */
208618334Speter validate_replacement:
208718334Speter
208818334Speter  /* Note which hard regs this insn has as inputs.  */
208918334Speter  mark_used_regs_combine (newpat);
209018334Speter
209118334Speter  /* Is the result of combination a valid instruction?  */
209252284Sobrien  insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
209318334Speter
209418334Speter  /* If the result isn't valid, see if it is a PARALLEL of two SETs where
209518334Speter     the second SET's destination is a register that is unused.  In that case,
209618334Speter     we just need the first SET.   This can occur when simplifying a divmod
209718334Speter     insn.  We *must* test for this case here because the code below that
209818334Speter     splits two independent SETs doesn't handle this case correctly when it
209918334Speter     updates the register status.  Also check the case where the first
210018334Speter     SET's destination is unused.  That would not cause incorrect code, but
210118334Speter     does cause an unneeded insn to remain.  */
210218334Speter
210318334Speter  if (insn_code_number < 0 && GET_CODE (newpat) == PARALLEL
210418334Speter      && XVECLEN (newpat, 0) == 2
210518334Speter      && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
210618334Speter      && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
210718334Speter      && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == REG
210818334Speter      && find_reg_note (i3, REG_UNUSED, SET_DEST (XVECEXP (newpat, 0, 1)))
210918334Speter      && ! side_effects_p (SET_SRC (XVECEXP (newpat, 0, 1)))
211018334Speter      && asm_noperands (newpat) < 0)
211118334Speter    {
211218334Speter      newpat = XVECEXP (newpat, 0, 0);
211352284Sobrien      insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
211418334Speter    }
211518334Speter
211618334Speter  else if (insn_code_number < 0 && GET_CODE (newpat) == PARALLEL
211718334Speter	   && XVECLEN (newpat, 0) == 2
211818334Speter	   && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
211918334Speter	   && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
212018334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) == REG
212118334Speter	   && find_reg_note (i3, REG_UNUSED, SET_DEST (XVECEXP (newpat, 0, 0)))
212218334Speter	   && ! side_effects_p (SET_SRC (XVECEXP (newpat, 0, 0)))
212318334Speter	   && asm_noperands (newpat) < 0)
212418334Speter    {
212518334Speter      newpat = XVECEXP (newpat, 0, 1);
212652284Sobrien      insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
212718334Speter    }
212818334Speter
212918334Speter  /* If we were combining three insns and the result is a simple SET
213018334Speter     with no ASM_OPERANDS that wasn't recognized, try to split it into two
213190075Sobrien     insns.  There are two ways to do this.  It can be split using a
213218334Speter     machine-specific method (like when you have an addition of a large
213318334Speter     constant) or by combine in the function find_split_point.  */
213418334Speter
213518334Speter  if (i1 && insn_code_number < 0 && GET_CODE (newpat) == SET
213618334Speter      && asm_noperands (newpat) < 0)
213718334Speter    {
213818334Speter      rtx m_split, *split;
213918334Speter      rtx ni2dest = i2dest;
214018334Speter
214118334Speter      /* See if the MD file can split NEWPAT.  If it can't, see if letting it
214218334Speter	 use I2DEST as a scratch register will help.  In the latter case,
214318334Speter	 convert I2DEST to the mode of the source of NEWPAT if we can.  */
214418334Speter
214518334Speter      m_split = split_insns (newpat, i3);
214618334Speter
214718334Speter      /* We can only use I2DEST as a scratch reg if it doesn't overlap any
214818334Speter	 inputs of NEWPAT.  */
214918334Speter
215018334Speter      /* ??? If I2DEST is not safe, and I1DEST exists, then it would be
215118334Speter	 possible to try that as a scratch reg.  This would require adding
215218334Speter	 more code to make it work though.  */
215318334Speter
215418334Speter      if (m_split == 0 && ! reg_overlap_mentioned_p (ni2dest, newpat))
215518334Speter	{
215618334Speter	  /* If I2DEST is a hard register or the only use of a pseudo,
215718334Speter	     we can change its mode.  */
215818334Speter	  if (GET_MODE (SET_DEST (newpat)) != GET_MODE (i2dest)
215918334Speter	      && GET_MODE (SET_DEST (newpat)) != VOIDmode
216018334Speter	      && GET_CODE (i2dest) == REG
216118334Speter	      && (REGNO (i2dest) < FIRST_PSEUDO_REGISTER
216250397Sobrien		  || (REG_N_SETS (REGNO (i2dest)) == 1 && ! added_sets_2
216318334Speter		      && ! REG_USERVAR_P (i2dest))))
216450397Sobrien	    ni2dest = gen_rtx_REG (GET_MODE (SET_DEST (newpat)),
216590075Sobrien				   REGNO (i2dest));
216618334Speter
216790075Sobrien	  m_split = split_insns (gen_rtx_PARALLEL
216890075Sobrien				 (VOIDmode,
216990075Sobrien				  gen_rtvec (2, newpat,
217090075Sobrien					     gen_rtx_CLOBBER (VOIDmode,
217190075Sobrien							      ni2dest))),
217290075Sobrien				 i3);
217390075Sobrien	  /* If the split with the mode-changed register didn't work, try
217490075Sobrien	     the original register.  */
217590075Sobrien	  if (! m_split && ni2dest != i2dest)
217690075Sobrien	    {
217790075Sobrien	      ni2dest = i2dest;
217890075Sobrien	      m_split = split_insns (gen_rtx_PARALLEL
217990075Sobrien				     (VOIDmode,
218090075Sobrien				      gen_rtvec (2, newpat,
218190075Sobrien						 gen_rtx_CLOBBER (VOIDmode,
218290075Sobrien								  i2dest))),
218390075Sobrien				     i3);
218490075Sobrien	    }
218518334Speter	}
218618334Speter
2187117395Skan      if (m_split && NEXT_INSN (m_split) == NULL_RTX)
218818334Speter	{
2189117395Skan	  m_split = PATTERN (m_split);
219090075Sobrien	  insn_code_number = recog_for_combine (&m_split, i3, &new_i3_notes);
219190075Sobrien	  if (insn_code_number >= 0)
219290075Sobrien	    newpat = m_split;
219390075Sobrien	}
2194117395Skan      else if (m_split && NEXT_INSN (NEXT_INSN (m_split)) == NULL_RTX
219590075Sobrien	       && (next_real_insn (i2) == i3
2196117395Skan		   || ! use_crosses_set_p (PATTERN (m_split), INSN_CUID (i2))))
219790075Sobrien	{
219818334Speter	  rtx i2set, i3set;
2199117395Skan	  rtx newi3pat = PATTERN (NEXT_INSN (m_split));
2200117395Skan	  newi2pat = PATTERN (m_split);
220118334Speter
2202117395Skan	  i3set = single_set (NEXT_INSN (m_split));
2203117395Skan	  i2set = single_set (m_split);
220418334Speter
220518334Speter	  /* In case we changed the mode of I2DEST, replace it in the
220618334Speter	     pseudo-register table here.  We can't do it above in case this
220718334Speter	     code doesn't get executed and we do a split the other way.  */
220818334Speter
220918334Speter	  if (REGNO (i2dest) >= FIRST_PSEUDO_REGISTER)
221018334Speter	    SUBST (regno_reg_rtx[REGNO (i2dest)], ni2dest);
221118334Speter
221252284Sobrien	  i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
221318334Speter
221418334Speter	  /* If I2 or I3 has multiple SETs, we won't know how to track
221550397Sobrien	     register status, so don't use these insns.  If I2's destination
221650397Sobrien	     is used between I2 and I3, we also can't use these insns.  */
221718334Speter
221850397Sobrien	  if (i2_code_number >= 0 && i2set && i3set
221950397Sobrien	      && (next_real_insn (i2) == i3
222050397Sobrien		  || ! reg_used_between_p (SET_DEST (i2set), i2, i3)))
222152284Sobrien	    insn_code_number = recog_for_combine (&newi3pat, i3,
222252284Sobrien						  &new_i3_notes);
222318334Speter	  if (insn_code_number >= 0)
222418334Speter	    newpat = newi3pat;
222518334Speter
222618334Speter	  /* It is possible that both insns now set the destination of I3.
222718334Speter	     If so, we must show an extra use of it.  */
222818334Speter
222950397Sobrien	  if (insn_code_number >= 0)
223050397Sobrien	    {
223150397Sobrien	      rtx new_i3_dest = SET_DEST (i3set);
223250397Sobrien	      rtx new_i2_dest = SET_DEST (i2set);
223350397Sobrien
223450397Sobrien	      while (GET_CODE (new_i3_dest) == ZERO_EXTRACT
223550397Sobrien		     || GET_CODE (new_i3_dest) == STRICT_LOW_PART
223650397Sobrien		     || GET_CODE (new_i3_dest) == SUBREG)
223750397Sobrien		new_i3_dest = XEXP (new_i3_dest, 0);
223850397Sobrien
223950397Sobrien	      while (GET_CODE (new_i2_dest) == ZERO_EXTRACT
224050397Sobrien		     || GET_CODE (new_i2_dest) == STRICT_LOW_PART
224150397Sobrien		     || GET_CODE (new_i2_dest) == SUBREG)
224250397Sobrien		new_i2_dest = XEXP (new_i2_dest, 0);
224350397Sobrien
224450397Sobrien	      if (GET_CODE (new_i3_dest) == REG
224550397Sobrien		  && GET_CODE (new_i2_dest) == REG
224650397Sobrien		  && REGNO (new_i3_dest) == REGNO (new_i2_dest))
224750397Sobrien		REG_N_SETS (REGNO (new_i2_dest))++;
224850397Sobrien	    }
224918334Speter	}
225018334Speter
225118334Speter      /* If we can split it and use I2DEST, go ahead and see if that
225218334Speter	 helps things be recognized.  Verify that none of the registers
225318334Speter	 are set between I2 and I3.  */
225418334Speter      if (insn_code_number < 0 && (split = find_split_point (&newpat, i3)) != 0
225518334Speter#ifdef HAVE_cc0
225618334Speter	  && GET_CODE (i2dest) == REG
225718334Speter#endif
225818334Speter	  /* We need I2DEST in the proper mode.  If it is a hard register
225918334Speter	     or the only use of a pseudo, we can change its mode.  */
226018334Speter	  && (GET_MODE (*split) == GET_MODE (i2dest)
226118334Speter	      || GET_MODE (*split) == VOIDmode
226218334Speter	      || REGNO (i2dest) < FIRST_PSEUDO_REGISTER
226350397Sobrien	      || (REG_N_SETS (REGNO (i2dest)) == 1 && ! added_sets_2
226418334Speter		  && ! REG_USERVAR_P (i2dest)))
226518334Speter	  && (next_real_insn (i2) == i3
226618334Speter	      || ! use_crosses_set_p (*split, INSN_CUID (i2)))
226718334Speter	  /* We can't overwrite I2DEST if its value is still used by
226818334Speter	     NEWPAT.  */
226918334Speter	  && ! reg_referenced_p (i2dest, newpat))
227018334Speter	{
227118334Speter	  rtx newdest = i2dest;
227218334Speter	  enum rtx_code split_code = GET_CODE (*split);
227318334Speter	  enum machine_mode split_mode = GET_MODE (*split);
227418334Speter
227518334Speter	  /* Get NEWDEST as a register in the proper mode.  We have already
227618334Speter	     validated that we can do this.  */
227718334Speter	  if (GET_MODE (i2dest) != split_mode && split_mode != VOIDmode)
227818334Speter	    {
227950397Sobrien	      newdest = gen_rtx_REG (split_mode, REGNO (i2dest));
228018334Speter
228118334Speter	      if (REGNO (i2dest) >= FIRST_PSEUDO_REGISTER)
228218334Speter		SUBST (regno_reg_rtx[REGNO (i2dest)], newdest);
228318334Speter	    }
228418334Speter
228518334Speter	  /* If *SPLIT is a (mult FOO (const_int pow2)), convert it to
228618334Speter	     an ASHIFT.  This can occur if it was inside a PLUS and hence
228718334Speter	     appeared to be a memory address.  This is a kludge.  */
228818334Speter	  if (split_code == MULT
228918334Speter	      && GET_CODE (XEXP (*split, 1)) == CONST_INT
229090075Sobrien	      && INTVAL (XEXP (*split, 1)) > 0
229118334Speter	      && (i = exact_log2 (INTVAL (XEXP (*split, 1)))) >= 0)
229218334Speter	    {
229390075Sobrien	      SUBST (*split, gen_rtx_ASHIFT (split_mode,
229490075Sobrien					     XEXP (*split, 0), GEN_INT (i)));
229518334Speter	      /* Update split_code because we may not have a multiply
229618334Speter		 anymore.  */
229718334Speter	      split_code = GET_CODE (*split);
229818334Speter	    }
229918334Speter
230018334Speter#ifdef INSN_SCHEDULING
230118334Speter	  /* If *SPLIT is a paradoxical SUBREG, when we split it, it should
230218334Speter	     be written as a ZERO_EXTEND.  */
230318334Speter	  if (split_code == SUBREG && GET_CODE (SUBREG_REG (*split)) == MEM)
2304117395Skan	    {
2305117395Skan#ifdef LOAD_EXTEND_OP
2306117395Skan	      /* Or as a SIGN_EXTEND if LOAD_EXTEND_OP says that that's
2307117395Skan		 what it really is.  */
2308117395Skan	      if (LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (*split)))
2309117395Skan		  == SIGN_EXTEND)
2310117395Skan		SUBST (*split, gen_rtx_SIGN_EXTEND (split_mode,
2311117395Skan						    SUBREG_REG (*split)));
2312117395Skan	      else
231318334Speter#endif
2314117395Skan		SUBST (*split, gen_rtx_ZERO_EXTEND (split_mode,
2315117395Skan						    SUBREG_REG (*split)));
2316117395Skan	    }
2317117395Skan#endif
231818334Speter
231990075Sobrien	  newi2pat = gen_rtx_SET (VOIDmode, newdest, *split);
232018334Speter	  SUBST (*split, newdest);
232152284Sobrien	  i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
232218334Speter
232318334Speter	  /* If the split point was a MULT and we didn't have one before,
232418334Speter	     don't use one now.  */
232518334Speter	  if (i2_code_number >= 0 && ! (split_code == MULT && ! have_mult))
232652284Sobrien	    insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
232718334Speter	}
232818334Speter    }
232918334Speter
233018334Speter  /* Check for a case where we loaded from memory in a narrow mode and
233118334Speter     then sign extended it, but we need both registers.  In that case,
233218334Speter     we have a PARALLEL with both loads from the same memory location.
233318334Speter     We can split this into a load from memory followed by a register-register
233418334Speter     copy.  This saves at least one insn, more if register allocation can
233518334Speter     eliminate the copy.
233618334Speter
2337117395Skan     We cannot do this if the destination of the first assignment is a
2338117395Skan     condition code register or cc0.  We eliminate this case by making sure
2339117395Skan     the SET_DEST and SET_SRC have the same mode.
2340117395Skan
234118334Speter     We cannot do this if the destination of the second assignment is
234218334Speter     a register that we have already assumed is zero-extended.  Similarly
234318334Speter     for a SUBREG of such a register.  */
234418334Speter
234518334Speter  else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0
234618334Speter	   && GET_CODE (newpat) == PARALLEL
234718334Speter	   && XVECLEN (newpat, 0) == 2
234818334Speter	   && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
234918334Speter	   && GET_CODE (SET_SRC (XVECEXP (newpat, 0, 0))) == SIGN_EXTEND
2350117395Skan	   && (GET_MODE (SET_DEST (XVECEXP (newpat, 0, 0)))
2351117395Skan	       == GET_MODE (SET_SRC (XVECEXP (newpat, 0, 0))))
235218334Speter	   && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
235318334Speter	   && rtx_equal_p (SET_SRC (XVECEXP (newpat, 0, 1)),
235418334Speter			   XEXP (SET_SRC (XVECEXP (newpat, 0, 0)), 0))
235518334Speter	   && ! use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)),
235618334Speter				   INSN_CUID (i2))
235718334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT
235818334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
235918334Speter	   && ! (temp = SET_DEST (XVECEXP (newpat, 0, 1)),
236018334Speter		 (GET_CODE (temp) == REG
236118334Speter		  && reg_nonzero_bits[REGNO (temp)] != 0
236218334Speter		  && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
236318334Speter		  && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
236418334Speter		  && (reg_nonzero_bits[REGNO (temp)]
236518334Speter		      != GET_MODE_MASK (word_mode))))
236618334Speter	   && ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == SUBREG
236718334Speter		 && (temp = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1))),
236818334Speter		     (GET_CODE (temp) == REG
236918334Speter		      && reg_nonzero_bits[REGNO (temp)] != 0
237018334Speter		      && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
237118334Speter		      && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
237218334Speter		      && (reg_nonzero_bits[REGNO (temp)]
237318334Speter			  != GET_MODE_MASK (word_mode)))))
237418334Speter	   && ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1)),
237518334Speter					 SET_SRC (XVECEXP (newpat, 0, 1)))
237618334Speter	   && ! find_reg_note (i3, REG_UNUSED,
237718334Speter			       SET_DEST (XVECEXP (newpat, 0, 0))))
237818334Speter    {
237918334Speter      rtx ni2dest;
238018334Speter
238118334Speter      newi2pat = XVECEXP (newpat, 0, 0);
238218334Speter      ni2dest = SET_DEST (XVECEXP (newpat, 0, 0));
238318334Speter      newpat = XVECEXP (newpat, 0, 1);
238418334Speter      SUBST (SET_SRC (newpat),
238518334Speter	     gen_lowpart_for_combine (GET_MODE (SET_SRC (newpat)), ni2dest));
238652284Sobrien      i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
238718334Speter
238818334Speter      if (i2_code_number >= 0)
238952284Sobrien	insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
239018334Speter
239118334Speter      if (insn_code_number >= 0)
239218334Speter	{
239318334Speter	  rtx insn;
239418334Speter	  rtx link;
239518334Speter
239618334Speter	  /* If we will be able to accept this, we have made a change to the
239718334Speter	     destination of I3.  This can invalidate a LOG_LINKS pointing
239818334Speter	     to I3.  No other part of combine.c makes such a transformation.
239918334Speter
240018334Speter	     The new I3 will have a destination that was previously the
240118334Speter	     destination of I1 or I2 and which was used in i2 or I3.  Call
240218334Speter	     distribute_links to make a LOG_LINK from the next use of
240318334Speter	     that destination.  */
240418334Speter
240518334Speter	  PATTERN (i3) = newpat;
240650397Sobrien	  distribute_links (gen_rtx_INSN_LIST (VOIDmode, i3, NULL_RTX));
240718334Speter
240818334Speter	  /* I3 now uses what used to be its destination and which is
240918334Speter	     now I2's destination.  That means we need a LOG_LINK from
241018334Speter	     I3 to I2.  But we used to have one, so we still will.
241118334Speter
241218334Speter	     However, some later insn might be using I2's dest and have
241318334Speter	     a LOG_LINK pointing at I3.  We must remove this link.
241418334Speter	     The simplest way to remove the link is to point it at I1,
241518334Speter	     which we know will be a NOTE.  */
241618334Speter
241718334Speter	  for (insn = NEXT_INSN (i3);
2418117395Skan	       insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR
2419117395Skan			|| insn != this_basic_block->next_bb->head);
242018334Speter	       insn = NEXT_INSN (insn))
242118334Speter	    {
242290075Sobrien	      if (INSN_P (insn) && reg_referenced_p (ni2dest, PATTERN (insn)))
242318334Speter		{
242418334Speter		  for (link = LOG_LINKS (insn); link;
242518334Speter		       link = XEXP (link, 1))
242618334Speter		    if (XEXP (link, 0) == i3)
242718334Speter		      XEXP (link, 0) = i1;
242818334Speter
242918334Speter		  break;
243018334Speter		}
243118334Speter	    }
243218334Speter	}
243318334Speter    }
243490075Sobrien
243518334Speter  /* Similarly, check for a case where we have a PARALLEL of two independent
243618334Speter     SETs but we started with three insns.  In this case, we can do the sets
243718334Speter     as two separate insns.  This case occurs when some SET allows two
243818334Speter     other insns to combine, but the destination of that SET is still live.  */
243918334Speter
244018334Speter  else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0
244118334Speter	   && GET_CODE (newpat) == PARALLEL
244218334Speter	   && XVECLEN (newpat, 0) == 2
244318334Speter	   && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
244418334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != ZERO_EXTRACT
244518334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != STRICT_LOW_PART
244618334Speter	   && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
244718334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT
244818334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
244918334Speter	   && ! use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)),
245018334Speter				   INSN_CUID (i2))
245118334Speter	   /* Don't pass sets with (USE (MEM ...)) dests to the following.  */
245218334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != USE
245318334Speter	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != USE
245418334Speter	   && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 1)),
245518334Speter				  XVECEXP (newpat, 0, 0))
245618334Speter	   && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 0)),
245790075Sobrien				  XVECEXP (newpat, 0, 1))
245890075Sobrien	   && ! (contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 0)))
245990075Sobrien		 && contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 1)))))
246018334Speter    {
246150397Sobrien      /* Normally, it doesn't matter which of the two is done first,
246250397Sobrien	 but it does if one references cc0.  In that case, it has to
246350397Sobrien	 be first.  */
246450397Sobrien#ifdef HAVE_cc0
246550397Sobrien      if (reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0)))
246650397Sobrien	{
246750397Sobrien	  newi2pat = XVECEXP (newpat, 0, 0);
246850397Sobrien	  newpat = XVECEXP (newpat, 0, 1);
246950397Sobrien	}
247050397Sobrien      else
247150397Sobrien#endif
247250397Sobrien	{
247350397Sobrien	  newi2pat = XVECEXP (newpat, 0, 1);
247450397Sobrien	  newpat = XVECEXP (newpat, 0, 0);
247550397Sobrien	}
247618334Speter
247752284Sobrien      i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
247818334Speter
247918334Speter      if (i2_code_number >= 0)
248052284Sobrien	insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
248118334Speter    }
248218334Speter
248318334Speter  /* If it still isn't recognized, fail and change things back the way they
248418334Speter     were.  */
248518334Speter  if ((insn_code_number < 0
248618334Speter       /* Is the result a reasonable ASM_OPERANDS?  */
248718334Speter       && (! check_asm_operands (newpat) || added_sets_1 || added_sets_2)))
248818334Speter    {
248918334Speter      undo_all ();
249018334Speter      return 0;
249118334Speter    }
249218334Speter
249318334Speter  /* If we had to change another insn, make sure it is valid also.  */
249418334Speter  if (undobuf.other_insn)
249518334Speter    {
249618334Speter      rtx other_pat = PATTERN (undobuf.other_insn);
249718334Speter      rtx new_other_notes;
249818334Speter      rtx note, next;
249918334Speter
250018334Speter      CLEAR_HARD_REG_SET (newpat_used_regs);
250118334Speter
250252284Sobrien      other_code_number = recog_for_combine (&other_pat, undobuf.other_insn,
250352284Sobrien					     &new_other_notes);
250418334Speter
250518334Speter      if (other_code_number < 0 && ! check_asm_operands (other_pat))
250618334Speter	{
250718334Speter	  undo_all ();
250818334Speter	  return 0;
250918334Speter	}
251018334Speter
251118334Speter      PATTERN (undobuf.other_insn) = other_pat;
251218334Speter
251318334Speter      /* If any of the notes in OTHER_INSN were REG_UNUSED, ensure that they
251418334Speter	 are still valid.  Then add any non-duplicate notes added by
251518334Speter	 recog_for_combine.  */
251618334Speter      for (note = REG_NOTES (undobuf.other_insn); note; note = next)
251718334Speter	{
251818334Speter	  next = XEXP (note, 1);
251918334Speter
252018334Speter	  if (REG_NOTE_KIND (note) == REG_UNUSED
252118334Speter	      && ! reg_set_p (XEXP (note, 0), PATTERN (undobuf.other_insn)))
252218334Speter	    {
252318334Speter	      if (GET_CODE (XEXP (note, 0)) == REG)
252450397Sobrien		REG_N_DEATHS (REGNO (XEXP (note, 0)))--;
252518334Speter
252618334Speter	      remove_note (undobuf.other_insn, note);
252718334Speter	    }
252818334Speter	}
252918334Speter
253018334Speter      for (note = new_other_notes; note; note = XEXP (note, 1))
253118334Speter	if (GET_CODE (XEXP (note, 0)) == REG)
253250397Sobrien	  REG_N_DEATHS (REGNO (XEXP (note, 0)))++;
253318334Speter
253418334Speter      distribute_notes (new_other_notes, undobuf.other_insn,
253518334Speter			undobuf.other_insn, NULL_RTX, NULL_RTX, NULL_RTX);
253618334Speter    }
253790075Sobrien#ifdef HAVE_cc0
253890075Sobrien  /* If I2 is the setter CC0 and I3 is the user CC0 then check whether
253990075Sobrien     they are adjacent to each other or not.  */
254090075Sobrien  {
254190075Sobrien    rtx p = prev_nonnote_insn (i3);
254290075Sobrien    if (p && p != i2 && GET_CODE (p) == INSN && newi2pat
254390075Sobrien	&& sets_cc0_p (newi2pat))
254490075Sobrien      {
254590075Sobrien	undo_all ();
254690075Sobrien	return 0;
254790075Sobrien      }
254890075Sobrien  }
254990075Sobrien#endif
255018334Speter
255190075Sobrien  /* We now know that we can do this combination.  Merge the insns and
255218334Speter     update the status of registers and LOG_LINKS.  */
255318334Speter
255418334Speter  {
255518334Speter    rtx i3notes, i2notes, i1notes = 0;
255618334Speter    rtx i3links, i2links, i1links = 0;
255718334Speter    rtx midnotes = 0;
255890075Sobrien    unsigned int regno;
255950397Sobrien    /* Compute which registers we expect to eliminate.  newi2pat may be setting
256050397Sobrien       either i3dest or i2dest, so we must check it.  Also, i1dest may be the
256150397Sobrien       same as i3dest, in which case newi2pat may be setting i1dest.  */
256250397Sobrien    rtx elim_i2 = ((newi2pat && reg_set_p (i2dest, newi2pat))
256350397Sobrien		   || i2dest_in_i2src || i2dest_in_i1src
256418334Speter		   ? 0 : i2dest);
256550397Sobrien    rtx elim_i1 = (i1 == 0 || i1dest_in_i1src
256650397Sobrien		   || (newi2pat && reg_set_p (i1dest, newi2pat))
256750397Sobrien		   ? 0 : i1dest);
256818334Speter
256918334Speter    /* Get the old REG_NOTES and LOG_LINKS from all our insns and
257018334Speter       clear them.  */
257118334Speter    i3notes = REG_NOTES (i3), i3links = LOG_LINKS (i3);
257218334Speter    i2notes = REG_NOTES (i2), i2links = LOG_LINKS (i2);
257318334Speter    if (i1)
257418334Speter      i1notes = REG_NOTES (i1), i1links = LOG_LINKS (i1);
257518334Speter
257618334Speter    /* Ensure that we do not have something that should not be shared but
257718334Speter       occurs multiple times in the new insns.  Check this by first
257818334Speter       resetting all the `used' flags and then copying anything is shared.  */
257918334Speter
258018334Speter    reset_used_flags (i3notes);
258118334Speter    reset_used_flags (i2notes);
258218334Speter    reset_used_flags (i1notes);
258318334Speter    reset_used_flags (newpat);
258418334Speter    reset_used_flags (newi2pat);
258518334Speter    if (undobuf.other_insn)
258618334Speter      reset_used_flags (PATTERN (undobuf.other_insn));
258718334Speter
258818334Speter    i3notes = copy_rtx_if_shared (i3notes);
258918334Speter    i2notes = copy_rtx_if_shared (i2notes);
259018334Speter    i1notes = copy_rtx_if_shared (i1notes);
259118334Speter    newpat = copy_rtx_if_shared (newpat);
259218334Speter    newi2pat = copy_rtx_if_shared (newi2pat);
259318334Speter    if (undobuf.other_insn)
259418334Speter      reset_used_flags (PATTERN (undobuf.other_insn));
259518334Speter
259618334Speter    INSN_CODE (i3) = insn_code_number;
259718334Speter    PATTERN (i3) = newpat;
259896263Sobrien
259996263Sobrien    if (GET_CODE (i3) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (i3))
260096263Sobrien      {
260196263Sobrien	rtx call_usage = CALL_INSN_FUNCTION_USAGE (i3);
260296263Sobrien
260396263Sobrien	reset_used_flags (call_usage);
260496263Sobrien	call_usage = copy_rtx (call_usage);
260596263Sobrien
260696263Sobrien	if (substed_i2)
260796263Sobrien	  replace_rtx (call_usage, i2dest, i2src);
260896263Sobrien
260996263Sobrien	if (substed_i1)
261096263Sobrien	  replace_rtx (call_usage, i1dest, i1src);
261196263Sobrien
261296263Sobrien	CALL_INSN_FUNCTION_USAGE (i3) = call_usage;
261396263Sobrien      }
261496263Sobrien
261518334Speter    if (undobuf.other_insn)
261618334Speter      INSN_CODE (undobuf.other_insn) = other_code_number;
261718334Speter
261818334Speter    /* We had one special case above where I2 had more than one set and
261918334Speter       we replaced a destination of one of those sets with the destination
262018334Speter       of I3.  In that case, we have to update LOG_LINKS of insns later
262118334Speter       in this basic block.  Note that this (expensive) case is rare.
262218334Speter
262318334Speter       Also, in this case, we must pretend that all REG_NOTEs for I2
262418334Speter       actually came from I3, so that REG_UNUSED notes from I2 will be
262518334Speter       properly handled.  */
262618334Speter
262718334Speter    if (i3_subst_into_i2)
262818334Speter      {
262918334Speter	for (i = 0; i < XVECLEN (PATTERN (i2), 0); i++)
263090075Sobrien	  if (GET_CODE (XVECEXP (PATTERN (i2), 0, i)) != USE
263190075Sobrien	      && GET_CODE (SET_DEST (XVECEXP (PATTERN (i2), 0, i))) == REG
263218334Speter	      && SET_DEST (XVECEXP (PATTERN (i2), 0, i)) != i2dest
263318334Speter	      && ! find_reg_note (i2, REG_UNUSED,
263418334Speter				  SET_DEST (XVECEXP (PATTERN (i2), 0, i))))
263518334Speter	    for (temp = NEXT_INSN (i2);
2636117395Skan		 temp && (this_basic_block->next_bb == EXIT_BLOCK_PTR
2637117395Skan			  || this_basic_block->head != temp);
263818334Speter		 temp = NEXT_INSN (temp))
263990075Sobrien	      if (temp != i3 && INSN_P (temp))
264018334Speter		for (link = LOG_LINKS (temp); link; link = XEXP (link, 1))
264118334Speter		  if (XEXP (link, 0) == i2)
264218334Speter		    XEXP (link, 0) = i3;
264318334Speter
264418334Speter	if (i3notes)
264518334Speter	  {
264618334Speter	    rtx link = i3notes;
264718334Speter	    while (XEXP (link, 1))
264818334Speter	      link = XEXP (link, 1);
264918334Speter	    XEXP (link, 1) = i2notes;
265018334Speter	  }
265118334Speter	else
265218334Speter	  i3notes = i2notes;
265318334Speter	i2notes = 0;
265418334Speter      }
265518334Speter
265618334Speter    LOG_LINKS (i3) = 0;
265718334Speter    REG_NOTES (i3) = 0;
265818334Speter    LOG_LINKS (i2) = 0;
265918334Speter    REG_NOTES (i2) = 0;
266018334Speter
266118334Speter    if (newi2pat)
266218334Speter      {
266318334Speter	INSN_CODE (i2) = i2_code_number;
266418334Speter	PATTERN (i2) = newi2pat;
266518334Speter      }
266618334Speter    else
266718334Speter      {
266818334Speter	PUT_CODE (i2, NOTE);
266918334Speter	NOTE_LINE_NUMBER (i2) = NOTE_INSN_DELETED;
267018334Speter	NOTE_SOURCE_FILE (i2) = 0;
267118334Speter      }
267218334Speter
267318334Speter    if (i1)
267418334Speter      {
267518334Speter	LOG_LINKS (i1) = 0;
267618334Speter	REG_NOTES (i1) = 0;
267718334Speter	PUT_CODE (i1, NOTE);
267818334Speter	NOTE_LINE_NUMBER (i1) = NOTE_INSN_DELETED;
267918334Speter	NOTE_SOURCE_FILE (i1) = 0;
268018334Speter      }
268118334Speter
268218334Speter    /* Get death notes for everything that is now used in either I3 or
268390075Sobrien       I2 and used to die in a previous insn.  If we built two new
268450397Sobrien       patterns, move from I1 to I2 then I2 to I3 so that we get the
268550397Sobrien       proper movement on registers that I2 modifies.  */
268618334Speter
268718334Speter    if (newi2pat)
268850397Sobrien      {
268950397Sobrien	move_deaths (newi2pat, NULL_RTX, INSN_CUID (i1), i2, &midnotes);
269050397Sobrien	move_deaths (newpat, newi2pat, INSN_CUID (i1), i3, &midnotes);
269150397Sobrien      }
269250397Sobrien    else
269350397Sobrien      move_deaths (newpat, NULL_RTX, i1 ? INSN_CUID (i1) : INSN_CUID (i2),
269450397Sobrien		   i3, &midnotes);
269518334Speter
269618334Speter    /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3.  */
269718334Speter    if (i3notes)
269818334Speter      distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL_RTX,
269918334Speter			elim_i2, elim_i1);
270018334Speter    if (i2notes)
270118334Speter      distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL_RTX,
270218334Speter			elim_i2, elim_i1);
270318334Speter    if (i1notes)
270418334Speter      distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL_RTX,
270518334Speter			elim_i2, elim_i1);
270618334Speter    if (midnotes)
270718334Speter      distribute_notes (midnotes, NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
270818334Speter			elim_i2, elim_i1);
270918334Speter
271018334Speter    /* Distribute any notes added to I2 or I3 by recog_for_combine.  We
271118334Speter       know these are REG_UNUSED and want them to go to the desired insn,
271290075Sobrien       so we always pass it as i3.  We have not counted the notes in
271318334Speter       reg_n_deaths yet, so we need to do so now.  */
271418334Speter
271518334Speter    if (newi2pat && new_i2_notes)
271618334Speter      {
271718334Speter	for (temp = new_i2_notes; temp; temp = XEXP (temp, 1))
271818334Speter	  if (GET_CODE (XEXP (temp, 0)) == REG)
271950397Sobrien	    REG_N_DEATHS (REGNO (XEXP (temp, 0)))++;
272090075Sobrien
272118334Speter	distribute_notes (new_i2_notes, i2, i2, NULL_RTX, NULL_RTX, NULL_RTX);
272218334Speter      }
272318334Speter
272418334Speter    if (new_i3_notes)
272518334Speter      {
272618334Speter	for (temp = new_i3_notes; temp; temp = XEXP (temp, 1))
272718334Speter	  if (GET_CODE (XEXP (temp, 0)) == REG)
272850397Sobrien	    REG_N_DEATHS (REGNO (XEXP (temp, 0)))++;
272990075Sobrien
273018334Speter	distribute_notes (new_i3_notes, i3, i3, NULL_RTX, NULL_RTX, NULL_RTX);
273118334Speter      }
273218334Speter
273318334Speter    /* If I3DEST was used in I3SRC, it really died in I3.  We may need to
273450397Sobrien       put a REG_DEAD note for it somewhere.  If NEWI2PAT exists and sets
273550397Sobrien       I3DEST, the death must be somewhere before I2, not I3.  If we passed I3
273650397Sobrien       in that case, it might delete I2.  Similarly for I2 and I1.
273718334Speter       Show an additional death due to the REG_DEAD note we make here.  If
273818334Speter       we discard it in distribute_notes, we will decrement it again.  */
273918334Speter
274018334Speter    if (i3dest_killed)
274118334Speter      {
274218334Speter	if (GET_CODE (i3dest_killed) == REG)
274350397Sobrien	  REG_N_DEATHS (REGNO (i3dest_killed))++;
274418334Speter
274550397Sobrien	if (newi2pat && reg_set_p (i3dest_killed, newi2pat))
274650397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed,
274750397Sobrien					       NULL_RTX),
274850397Sobrien			    NULL_RTX, i2, NULL_RTX, elim_i2, elim_i1);
274950397Sobrien	else
275050397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed,
275150397Sobrien					       NULL_RTX),
275250397Sobrien			    NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
275350397Sobrien			    elim_i2, elim_i1);
275418334Speter      }
275518334Speter
275618334Speter    if (i2dest_in_i2src)
275718334Speter      {
275818334Speter	if (GET_CODE (i2dest) == REG)
275950397Sobrien	  REG_N_DEATHS (REGNO (i2dest))++;
276018334Speter
276118334Speter	if (newi2pat && reg_set_p (i2dest, newi2pat))
276250397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX),
276318334Speter			    NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX);
276418334Speter	else
276550397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX),
276618334Speter			    NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
276718334Speter			    NULL_RTX, NULL_RTX);
276818334Speter      }
276918334Speter
277018334Speter    if (i1dest_in_i1src)
277118334Speter      {
277218334Speter	if (GET_CODE (i1dest) == REG)
277350397Sobrien	  REG_N_DEATHS (REGNO (i1dest))++;
277418334Speter
277518334Speter	if (newi2pat && reg_set_p (i1dest, newi2pat))
277650397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX),
277718334Speter			    NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX);
277818334Speter	else
277950397Sobrien	  distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX),
278018334Speter			    NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
278118334Speter			    NULL_RTX, NULL_RTX);
278218334Speter      }
278318334Speter
278418334Speter    distribute_links (i3links);
278518334Speter    distribute_links (i2links);
278618334Speter    distribute_links (i1links);
278718334Speter
278818334Speter    if (GET_CODE (i2dest) == REG)
278918334Speter      {
279018334Speter	rtx link;
279118334Speter	rtx i2_insn = 0, i2_val = 0, set;
279218334Speter
279318334Speter	/* The insn that used to set this register doesn't exist, and
279418334Speter	   this life of the register may not exist either.  See if one of
279590075Sobrien	   I3's links points to an insn that sets I2DEST.  If it does,
279618334Speter	   that is now the last known value for I2DEST. If we don't update
279718334Speter	   this and I2 set the register to a value that depended on its old
279818334Speter	   contents, we will get confused.  If this insn is used, thing
279918334Speter	   will be set correctly in combine_instructions.  */
280018334Speter
280118334Speter	for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
280218334Speter	  if ((set = single_set (XEXP (link, 0))) != 0
280318334Speter	      && rtx_equal_p (i2dest, SET_DEST (set)))
280418334Speter	    i2_insn = XEXP (link, 0), i2_val = SET_SRC (set);
280518334Speter
280618334Speter	record_value_for_reg (i2dest, i2_insn, i2_val);
280718334Speter
280818334Speter	/* If the reg formerly set in I2 died only once and that was in I3,
280918334Speter	   zero its use count so it won't make `reload' do any work.  */
281050397Sobrien	if (! added_sets_2
281150397Sobrien	    && (newi2pat == 0 || ! reg_mentioned_p (i2dest, newi2pat))
281250397Sobrien	    && ! i2dest_in_i2src)
281318334Speter	  {
281418334Speter	    regno = REGNO (i2dest);
281550397Sobrien	    REG_N_SETS (regno)--;
281618334Speter	  }
281718334Speter      }
281818334Speter
281918334Speter    if (i1 && GET_CODE (i1dest) == REG)
282018334Speter      {
282118334Speter	rtx link;
282218334Speter	rtx i1_insn = 0, i1_val = 0, set;
282318334Speter
282418334Speter	for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
282518334Speter	  if ((set = single_set (XEXP (link, 0))) != 0
282618334Speter	      && rtx_equal_p (i1dest, SET_DEST (set)))
282718334Speter	    i1_insn = XEXP (link, 0), i1_val = SET_SRC (set);
282818334Speter
282918334Speter	record_value_for_reg (i1dest, i1_insn, i1_val);
283018334Speter
283118334Speter	regno = REGNO (i1dest);
283218334Speter	if (! added_sets_1 && ! i1dest_in_i1src)
283390075Sobrien	  REG_N_SETS (regno)--;
283418334Speter      }
283518334Speter
283618334Speter    /* Update reg_nonzero_bits et al for any changes that may have been made
283790075Sobrien       to this insn.  The order of set_nonzero_bits_and_sign_copies() is
283890075Sobrien       important.  Because newi2pat can affect nonzero_bits of newpat */
283918334Speter    if (newi2pat)
284090075Sobrien      note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
284190075Sobrien    note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
284218334Speter
284390075Sobrien    /* Set new_direct_jump_p if a new return or simple jump instruction
284490075Sobrien       has been created.
284590075Sobrien
284690075Sobrien       If I3 is now an unconditional jump, ensure that it has a
284718334Speter       BARRIER following it since it may have initially been a
284818334Speter       conditional jump.  It may also be the last nonnote insn.  */
284918334Speter
2850117395Skan    if (returnjump_p (i3) || any_uncondjump_p (i3))
285190075Sobrien      {
285290075Sobrien	*new_direct_jump_p = 1;
285390075Sobrien
285490075Sobrien	if ((temp = next_nonnote_insn (i3)) == NULL_RTX
285590075Sobrien	    || GET_CODE (temp) != BARRIER)
285690075Sobrien	  emit_barrier_after (i3);
285790075Sobrien      }
2858117395Skan
2859117395Skan    if (undobuf.other_insn != NULL_RTX
2860117395Skan	&& (returnjump_p (undobuf.other_insn)
2861117395Skan	    || any_uncondjump_p (undobuf.other_insn)))
2862117395Skan      {
2863117395Skan	*new_direct_jump_p = 1;
2864117395Skan
2865117395Skan	if ((temp = next_nonnote_insn (undobuf.other_insn)) == NULL_RTX
2866117395Skan	    || GET_CODE (temp) != BARRIER)
2867117395Skan	  emit_barrier_after (undobuf.other_insn);
2868117395Skan      }
2869117395Skan
287090075Sobrien    /* An NOOP jump does not need barrier, but it does need cleaning up
287190075Sobrien       of CFG.  */
287290075Sobrien    if (GET_CODE (newpat) == SET
287390075Sobrien	&& SET_SRC (newpat) == pc_rtx
287490075Sobrien	&& SET_DEST (newpat) == pc_rtx)
287590075Sobrien      *new_direct_jump_p = 1;
287618334Speter  }
287718334Speter
287818334Speter  combine_successes++;
287990075Sobrien  undo_commit ();
288018334Speter
288118334Speter  /* Clear this here, so that subsequent get_last_value calls are not
288218334Speter     affected.  */
288318334Speter  subst_prev_insn = NULL_RTX;
288418334Speter
288518334Speter  if (added_links_insn
288618334Speter      && (newi2pat == 0 || INSN_CUID (added_links_insn) < INSN_CUID (i2))
288718334Speter      && INSN_CUID (added_links_insn) < INSN_CUID (i3))
288818334Speter    return added_links_insn;
288918334Speter  else
289018334Speter    return newi2pat ? i2 : i3;
289118334Speter}
289218334Speter
289318334Speter/* Undo all the modifications recorded in undobuf.  */
289418334Speter
289518334Speterstatic void
289618334Speterundo_all ()
289718334Speter{
289850397Sobrien  struct undo *undo, *next;
289950397Sobrien
290050397Sobrien  for (undo = undobuf.undos; undo; undo = next)
290118334Speter    {
290250397Sobrien      next = undo->next;
290350397Sobrien      if (undo->is_int)
290450397Sobrien	*undo->where.i = undo->old_contents.i;
290518334Speter      else
290650397Sobrien	*undo->where.r = undo->old_contents.r;
290750397Sobrien
290850397Sobrien      undo->next = undobuf.frees;
290950397Sobrien      undobuf.frees = undo;
291018334Speter    }
291118334Speter
291290075Sobrien  undobuf.undos = 0;
291318334Speter
291418334Speter  /* Clear this here, so that subsequent get_last_value calls are not
291518334Speter     affected.  */
291618334Speter  subst_prev_insn = NULL_RTX;
291718334Speter}
291890075Sobrien
291990075Sobrien/* We've committed to accepting the changes we made.  Move all
292090075Sobrien   of the undos to the free list.  */
292190075Sobrien
292290075Sobrienstatic void
292390075Sobrienundo_commit ()
292490075Sobrien{
292590075Sobrien  struct undo *undo, *next;
292690075Sobrien
292790075Sobrien  for (undo = undobuf.undos; undo; undo = next)
292890075Sobrien    {
292990075Sobrien      next = undo->next;
293090075Sobrien      undo->next = undobuf.frees;
293190075Sobrien      undobuf.frees = undo;
293290075Sobrien    }
293390075Sobrien  undobuf.undos = 0;
293490075Sobrien}
293590075Sobrien
293618334Speter
293718334Speter/* Find the innermost point within the rtx at LOC, possibly LOC itself,
293818334Speter   where we have an arithmetic expression and return that point.  LOC will
293918334Speter   be inside INSN.
294018334Speter
294118334Speter   try_combine will call this function to see if an insn can be split into
294218334Speter   two insns.  */
294318334Speter
294418334Speterstatic rtx *
294518334Speterfind_split_point (loc, insn)
294618334Speter     rtx *loc;
294718334Speter     rtx insn;
294818334Speter{
294918334Speter  rtx x = *loc;
295018334Speter  enum rtx_code code = GET_CODE (x);
295118334Speter  rtx *split;
295290075Sobrien  unsigned HOST_WIDE_INT len = 0;
295390075Sobrien  HOST_WIDE_INT pos = 0;
295490075Sobrien  int unsignedp = 0;
295590075Sobrien  rtx inner = NULL_RTX;
295618334Speter
295718334Speter  /* First special-case some codes.  */
295818334Speter  switch (code)
295918334Speter    {
296018334Speter    case SUBREG:
296118334Speter#ifdef INSN_SCHEDULING
296218334Speter      /* If we are making a paradoxical SUBREG invalid, it becomes a split
296318334Speter	 point.  */
296418334Speter      if (GET_CODE (SUBREG_REG (x)) == MEM)
296518334Speter	return loc;
296618334Speter#endif
296718334Speter      return find_split_point (&SUBREG_REG (x), insn);
296818334Speter
296918334Speter    case MEM:
297018334Speter#ifdef HAVE_lo_sum
297118334Speter      /* If we have (mem (const ..)) or (mem (symbol_ref ...)), split it
297218334Speter	 using LO_SUM and HIGH.  */
297318334Speter      if (GET_CODE (XEXP (x, 0)) == CONST
297418334Speter	  || GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
297518334Speter	{
297618334Speter	  SUBST (XEXP (x, 0),
297790075Sobrien		 gen_rtx_LO_SUM (Pmode,
297890075Sobrien				 gen_rtx_HIGH (Pmode, XEXP (x, 0)),
297990075Sobrien				 XEXP (x, 0)));
298018334Speter	  return &XEXP (XEXP (x, 0), 0);
298118334Speter	}
298218334Speter#endif
298318334Speter
298418334Speter      /* If we have a PLUS whose second operand is a constant and the
298518334Speter	 address is not valid, perhaps will can split it up using
298618334Speter	 the machine-specific way to split large constants.  We use
298718334Speter	 the first pseudo-reg (one of the virtual regs) as a placeholder;
298818334Speter	 it will not remain in the result.  */
298918334Speter      if (GET_CODE (XEXP (x, 0)) == PLUS
299018334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
299118334Speter	  && ! memory_address_p (GET_MODE (x), XEXP (x, 0)))
299218334Speter	{
299318334Speter	  rtx reg = regno_reg_rtx[FIRST_PSEUDO_REGISTER];
299450397Sobrien	  rtx seq = split_insns (gen_rtx_SET (VOIDmode, reg, XEXP (x, 0)),
299518334Speter				 subst_insn);
299618334Speter
299718334Speter	  /* This should have produced two insns, each of which sets our
299818334Speter	     placeholder.  If the source of the second is a valid address,
299918334Speter	     we can make put both sources together and make a split point
300018334Speter	     in the middle.  */
300118334Speter
3002117395Skan	  if (seq
3003117395Skan	      && NEXT_INSN (seq) != NULL_RTX
3004117395Skan	      && NEXT_INSN (NEXT_INSN (seq)) == NULL_RTX
3005117395Skan	      && GET_CODE (seq) == INSN
3006117395Skan	      && GET_CODE (PATTERN (seq)) == SET
3007117395Skan	      && SET_DEST (PATTERN (seq)) == reg
300818334Speter	      && ! reg_mentioned_p (reg,
3009117395Skan				    SET_SRC (PATTERN (seq)))
3010117395Skan	      && GET_CODE (NEXT_INSN (seq)) == INSN
3011117395Skan	      && GET_CODE (PATTERN (NEXT_INSN (seq))) == SET
3012117395Skan	      && SET_DEST (PATTERN (NEXT_INSN (seq))) == reg
301318334Speter	      && memory_address_p (GET_MODE (x),
3014117395Skan				   SET_SRC (PATTERN (NEXT_INSN (seq)))))
301518334Speter	    {
3016117395Skan	      rtx src1 = SET_SRC (PATTERN (seq));
3017117395Skan	      rtx src2 = SET_SRC (PATTERN (NEXT_INSN (seq)));
301818334Speter
301918334Speter	      /* Replace the placeholder in SRC2 with SRC1.  If we can
302018334Speter		 find where in SRC2 it was placed, that can become our
302118334Speter		 split point and we can replace this address with SRC2.
302218334Speter		 Just try two obvious places.  */
302318334Speter
302418334Speter	      src2 = replace_rtx (src2, reg, src1);
302518334Speter	      split = 0;
302618334Speter	      if (XEXP (src2, 0) == src1)
302718334Speter		split = &XEXP (src2, 0);
302818334Speter	      else if (GET_RTX_FORMAT (GET_CODE (XEXP (src2, 0)))[0] == 'e'
302918334Speter		       && XEXP (XEXP (src2, 0), 0) == src1)
303018334Speter		split = &XEXP (XEXP (src2, 0), 0);
303118334Speter
303218334Speter	      if (split)
303318334Speter		{
303418334Speter		  SUBST (XEXP (x, 0), src2);
303518334Speter		  return split;
303618334Speter		}
303718334Speter	    }
303890075Sobrien
303918334Speter	  /* If that didn't work, perhaps the first operand is complex and
304018334Speter	     needs to be computed separately, so make a split point there.
304118334Speter	     This will occur on machines that just support REG + CONST
304218334Speter	     and have a constant moved through some previous computation.  */
304318334Speter
304418334Speter	  else if (GET_RTX_CLASS (GET_CODE (XEXP (XEXP (x, 0), 0))) != 'o'
304518334Speter		   && ! (GET_CODE (XEXP (XEXP (x, 0), 0)) == SUBREG
304618334Speter			 && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (XEXP (x, 0), 0))))
304718334Speter			     == 'o')))
304818334Speter	    return &XEXP (XEXP (x, 0), 0);
304918334Speter	}
305018334Speter      break;
305118334Speter
305218334Speter    case SET:
305318334Speter#ifdef HAVE_cc0
305418334Speter      /* If SET_DEST is CC0 and SET_SRC is not an operand, a COMPARE, or a
305518334Speter	 ZERO_EXTRACT, the most likely reason why this doesn't match is that
305618334Speter	 we need to put the operand into a register.  So split at that
305718334Speter	 point.  */
305818334Speter
305918334Speter      if (SET_DEST (x) == cc0_rtx
306018334Speter	  && GET_CODE (SET_SRC (x)) != COMPARE
306118334Speter	  && GET_CODE (SET_SRC (x)) != ZERO_EXTRACT
306218334Speter	  && GET_RTX_CLASS (GET_CODE (SET_SRC (x))) != 'o'
306318334Speter	  && ! (GET_CODE (SET_SRC (x)) == SUBREG
306418334Speter		&& GET_RTX_CLASS (GET_CODE (SUBREG_REG (SET_SRC (x)))) == 'o'))
306518334Speter	return &SET_SRC (x);
306618334Speter#endif
306718334Speter
306818334Speter      /* See if we can split SET_SRC as it stands.  */
306918334Speter      split = find_split_point (&SET_SRC (x), insn);
307018334Speter      if (split && split != &SET_SRC (x))
307118334Speter	return split;
307218334Speter
307350397Sobrien      /* See if we can split SET_DEST as it stands.  */
307450397Sobrien      split = find_split_point (&SET_DEST (x), insn);
307550397Sobrien      if (split && split != &SET_DEST (x))
307650397Sobrien	return split;
307750397Sobrien
307818334Speter      /* See if this is a bitfield assignment with everything constant.  If
307918334Speter	 so, this is an IOR of an AND, so split it into that.  */
308018334Speter      if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
308118334Speter	  && (GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0)))
308218334Speter	      <= HOST_BITS_PER_WIDE_INT)
308318334Speter	  && GET_CODE (XEXP (SET_DEST (x), 1)) == CONST_INT
308418334Speter	  && GET_CODE (XEXP (SET_DEST (x), 2)) == CONST_INT
308518334Speter	  && GET_CODE (SET_SRC (x)) == CONST_INT
308618334Speter	  && ((INTVAL (XEXP (SET_DEST (x), 1))
308790075Sobrien	       + INTVAL (XEXP (SET_DEST (x), 2)))
308818334Speter	      <= GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0))))
308918334Speter	  && ! side_effects_p (XEXP (SET_DEST (x), 0)))
309018334Speter	{
309190075Sobrien	  HOST_WIDE_INT pos = INTVAL (XEXP (SET_DEST (x), 2));
309290075Sobrien	  unsigned HOST_WIDE_INT len = INTVAL (XEXP (SET_DEST (x), 1));
309390075Sobrien	  unsigned HOST_WIDE_INT src = INTVAL (SET_SRC (x));
309418334Speter	  rtx dest = XEXP (SET_DEST (x), 0);
309518334Speter	  enum machine_mode mode = GET_MODE (dest);
309618334Speter	  unsigned HOST_WIDE_INT mask = ((HOST_WIDE_INT) 1 << len) - 1;
309718334Speter
309818334Speter	  if (BITS_BIG_ENDIAN)
309918334Speter	    pos = GET_MODE_BITSIZE (mode) - len - pos;
310018334Speter
310190075Sobrien	  if (src == mask)
310218334Speter	    SUBST (SET_SRC (x),
310318334Speter		   gen_binary (IOR, mode, dest, GEN_INT (src << pos)));
310418334Speter	  else
310518334Speter	    SUBST (SET_SRC (x),
310618334Speter		   gen_binary (IOR, mode,
310790075Sobrien			       gen_binary (AND, mode, dest,
3108117395Skan					   gen_int_mode (~(mask << pos),
3109117395Skan							 mode)),
311018334Speter			       GEN_INT (src << pos)));
311118334Speter
311218334Speter	  SUBST (SET_DEST (x), dest);
311318334Speter
311418334Speter	  split = find_split_point (&SET_SRC (x), insn);
311518334Speter	  if (split && split != &SET_SRC (x))
311618334Speter	    return split;
311718334Speter	}
311818334Speter
311918334Speter      /* Otherwise, see if this is an operation that we can split into two.
312018334Speter	 If so, try to split that.  */
312118334Speter      code = GET_CODE (SET_SRC (x));
312218334Speter
312318334Speter      switch (code)
312418334Speter	{
312518334Speter	case AND:
312618334Speter	  /* If we are AND'ing with a large constant that is only a single
312718334Speter	     bit and the result is only being used in a context where we
3128117395Skan	     need to know if it is zero or nonzero, replace it with a bit
312918334Speter	     extraction.  This will avoid the large constant, which might
313018334Speter	     have taken more than one insn to make.  If the constant were
313118334Speter	     not a valid argument to the AND but took only one insn to make,
313218334Speter	     this is no worse, but if it took more than one insn, it will
313318334Speter	     be better.  */
313418334Speter
313518334Speter	  if (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
313618334Speter	      && GET_CODE (XEXP (SET_SRC (x), 0)) == REG
313718334Speter	      && (pos = exact_log2 (INTVAL (XEXP (SET_SRC (x), 1)))) >= 7
313818334Speter	      && GET_CODE (SET_DEST (x)) == REG
313990075Sobrien	      && (split = find_single_use (SET_DEST (x), insn, (rtx*) 0)) != 0
314018334Speter	      && (GET_CODE (*split) == EQ || GET_CODE (*split) == NE)
314118334Speter	      && XEXP (*split, 0) == SET_DEST (x)
314218334Speter	      && XEXP (*split, 1) == const0_rtx)
314318334Speter	    {
314450397Sobrien	      rtx extraction = make_extraction (GET_MODE (SET_DEST (x)),
314550397Sobrien						XEXP (SET_SRC (x), 0),
314650397Sobrien						pos, NULL_RTX, 1, 1, 0, 0);
314750397Sobrien	      if (extraction != 0)
314850397Sobrien		{
314950397Sobrien		  SUBST (SET_SRC (x), extraction);
315050397Sobrien		  return find_split_point (loc, insn);
315150397Sobrien		}
315250397Sobrien	    }
315350397Sobrien	  break;
315450397Sobrien
315550397Sobrien	case NE:
315650397Sobrien	  /* if STORE_FLAG_VALUE is -1, this is (NE X 0) and only one bit of X
315790075Sobrien	     is known to be on, this can be converted into a NEG of a shift.  */
315850397Sobrien	  if (STORE_FLAG_VALUE == -1 && XEXP (SET_SRC (x), 1) == const0_rtx
315950397Sobrien	      && GET_MODE (SET_SRC (x)) == GET_MODE (XEXP (SET_SRC (x), 0))
316050397Sobrien	      && 1 <= (pos = exact_log2
316150397Sobrien		       (nonzero_bits (XEXP (SET_SRC (x), 0),
316250397Sobrien				      GET_MODE (XEXP (SET_SRC (x), 0))))))
316350397Sobrien	    {
316450397Sobrien	      enum machine_mode mode = GET_MODE (XEXP (SET_SRC (x), 0));
316550397Sobrien
316618334Speter	      SUBST (SET_SRC (x),
316790075Sobrien		     gen_rtx_NEG (mode,
316890075Sobrien				  gen_rtx_LSHIFTRT (mode,
316990075Sobrien						    XEXP (SET_SRC (x), 0),
317090075Sobrien						    GEN_INT (pos))));
317150397Sobrien
317250397Sobrien	      split = find_split_point (&SET_SRC (x), insn);
317350397Sobrien	      if (split && split != &SET_SRC (x))
317450397Sobrien		return split;
317518334Speter	    }
317618334Speter	  break;
317718334Speter
317818334Speter	case SIGN_EXTEND:
317918334Speter	  inner = XEXP (SET_SRC (x), 0);
318050397Sobrien
318150397Sobrien	  /* We can't optimize if either mode is a partial integer
318250397Sobrien	     mode as we don't know how many bits are significant
318350397Sobrien	     in those modes.  */
318450397Sobrien	  if (GET_MODE_CLASS (GET_MODE (inner)) == MODE_PARTIAL_INT
318550397Sobrien	      || GET_MODE_CLASS (GET_MODE (SET_SRC (x))) == MODE_PARTIAL_INT)
318650397Sobrien	    break;
318750397Sobrien
318818334Speter	  pos = 0;
318918334Speter	  len = GET_MODE_BITSIZE (GET_MODE (inner));
319018334Speter	  unsignedp = 0;
319118334Speter	  break;
319218334Speter
319318334Speter	case SIGN_EXTRACT:
319418334Speter	case ZERO_EXTRACT:
319518334Speter	  if (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
319618334Speter	      && GET_CODE (XEXP (SET_SRC (x), 2)) == CONST_INT)
319718334Speter	    {
319818334Speter	      inner = XEXP (SET_SRC (x), 0);
319918334Speter	      len = INTVAL (XEXP (SET_SRC (x), 1));
320018334Speter	      pos = INTVAL (XEXP (SET_SRC (x), 2));
320118334Speter
320218334Speter	      if (BITS_BIG_ENDIAN)
320318334Speter		pos = GET_MODE_BITSIZE (GET_MODE (inner)) - len - pos;
320418334Speter	      unsignedp = (code == ZERO_EXTRACT);
320518334Speter	    }
320618334Speter	  break;
320750397Sobrien
320850397Sobrien	default:
320950397Sobrien	  break;
321018334Speter	}
321118334Speter
321218334Speter      if (len && pos >= 0 && pos + len <= GET_MODE_BITSIZE (GET_MODE (inner)))
321318334Speter	{
321418334Speter	  enum machine_mode mode = GET_MODE (SET_SRC (x));
321518334Speter
321618334Speter	  /* For unsigned, we have a choice of a shift followed by an
321718334Speter	     AND or two shifts.  Use two shifts for field sizes where the
321818334Speter	     constant might be too large.  We assume here that we can
321918334Speter	     always at least get 8-bit constants in an AND insn, which is
322018334Speter	     true for every current RISC.  */
322118334Speter
322218334Speter	  if (unsignedp && len <= 8)
322318334Speter	    {
322418334Speter	      SUBST (SET_SRC (x),
322590075Sobrien		     gen_rtx_AND (mode,
322690075Sobrien				  gen_rtx_LSHIFTRT
322790075Sobrien				  (mode, gen_lowpart_for_combine (mode, inner),
322890075Sobrien				   GEN_INT (pos)),
322990075Sobrien				  GEN_INT (((HOST_WIDE_INT) 1 << len) - 1)));
323018334Speter
323118334Speter	      split = find_split_point (&SET_SRC (x), insn);
323218334Speter	      if (split && split != &SET_SRC (x))
323318334Speter		return split;
323418334Speter	    }
323518334Speter	  else
323618334Speter	    {
323718334Speter	      SUBST (SET_SRC (x),
323890075Sobrien		     gen_rtx_fmt_ee
323918334Speter		     (unsignedp ? LSHIFTRT : ASHIFTRT, mode,
324090075Sobrien		      gen_rtx_ASHIFT (mode,
324190075Sobrien				      gen_lowpart_for_combine (mode, inner),
324290075Sobrien				      GEN_INT (GET_MODE_BITSIZE (mode)
324390075Sobrien					       - len - pos)),
324418334Speter		      GEN_INT (GET_MODE_BITSIZE (mode) - len)));
324518334Speter
324618334Speter	      split = find_split_point (&SET_SRC (x), insn);
324718334Speter	      if (split && split != &SET_SRC (x))
324818334Speter		return split;
324918334Speter	    }
325018334Speter	}
325118334Speter
325218334Speter      /* See if this is a simple operation with a constant as the second
325318334Speter	 operand.  It might be that this constant is out of range and hence
325418334Speter	 could be used as a split point.  */
325518334Speter      if ((GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '2'
325618334Speter	   || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == 'c'
325718334Speter	   || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '<')
325818334Speter	  && CONSTANT_P (XEXP (SET_SRC (x), 1))
325918334Speter	  && (GET_RTX_CLASS (GET_CODE (XEXP (SET_SRC (x), 0))) == 'o'
326018334Speter	      || (GET_CODE (XEXP (SET_SRC (x), 0)) == SUBREG
326118334Speter		  && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (SET_SRC (x), 0))))
326218334Speter		      == 'o'))))
326318334Speter	return &XEXP (SET_SRC (x), 1);
326418334Speter
326518334Speter      /* Finally, see if this is a simple operation with its first operand
326618334Speter	 not in a register.  The operation might require this operand in a
326718334Speter	 register, so return it as a split point.  We can always do this
326818334Speter	 because if the first operand were another operation, we would have
326918334Speter	 already found it as a split point.  */
327018334Speter      if ((GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '2'
327118334Speter	   || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == 'c'
327218334Speter	   || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '<'
327318334Speter	   || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '1')
327418334Speter	  && ! register_operand (XEXP (SET_SRC (x), 0), VOIDmode))
327518334Speter	return &XEXP (SET_SRC (x), 0);
327618334Speter
327718334Speter      return 0;
327818334Speter
327918334Speter    case AND:
328018334Speter    case IOR:
328118334Speter      /* We write NOR as (and (not A) (not B)), but if we don't have a NOR,
328218334Speter	 it is better to write this as (not (ior A B)) so we can split it.
328318334Speter	 Similarly for IOR.  */
328418334Speter      if (GET_CODE (XEXP (x, 0)) == NOT && GET_CODE (XEXP (x, 1)) == NOT)
328518334Speter	{
328618334Speter	  SUBST (*loc,
328790075Sobrien		 gen_rtx_NOT (GET_MODE (x),
328890075Sobrien			      gen_rtx_fmt_ee (code == IOR ? AND : IOR,
328990075Sobrien					      GET_MODE (x),
329090075Sobrien					      XEXP (XEXP (x, 0), 0),
329190075Sobrien					      XEXP (XEXP (x, 1), 0))));
329218334Speter	  return find_split_point (loc, insn);
329318334Speter	}
329418334Speter
329518334Speter      /* Many RISC machines have a large set of logical insns.  If the
329618334Speter	 second operand is a NOT, put it first so we will try to split the
329718334Speter	 other operand first.  */
329818334Speter      if (GET_CODE (XEXP (x, 1)) == NOT)
329918334Speter	{
330018334Speter	  rtx tem = XEXP (x, 0);
330118334Speter	  SUBST (XEXP (x, 0), XEXP (x, 1));
330218334Speter	  SUBST (XEXP (x, 1), tem);
330318334Speter	}
330418334Speter      break;
330550397Sobrien
330650397Sobrien    default:
330750397Sobrien      break;
330818334Speter    }
330918334Speter
331018334Speter  /* Otherwise, select our actions depending on our rtx class.  */
331118334Speter  switch (GET_RTX_CLASS (code))
331218334Speter    {
331318334Speter    case 'b':			/* This is ZERO_EXTRACT and SIGN_EXTRACT.  */
331418334Speter    case '3':
331518334Speter      split = find_split_point (&XEXP (x, 2), insn);
331618334Speter      if (split)
331718334Speter	return split;
331850397Sobrien      /* ... fall through ...  */
331918334Speter    case '2':
332018334Speter    case 'c':
332118334Speter    case '<':
332218334Speter      split = find_split_point (&XEXP (x, 1), insn);
332318334Speter      if (split)
332418334Speter	return split;
332550397Sobrien      /* ... fall through ...  */
332618334Speter    case '1':
332718334Speter      /* Some machines have (and (shift ...) ...) insns.  If X is not
332818334Speter	 an AND, but XEXP (X, 0) is, use it as our split point.  */
332918334Speter      if (GET_CODE (x) != AND && GET_CODE (XEXP (x, 0)) == AND)
333018334Speter	return &XEXP (x, 0);
333118334Speter
333218334Speter      split = find_split_point (&XEXP (x, 0), insn);
333318334Speter      if (split)
333418334Speter	return split;
333518334Speter      return loc;
333618334Speter    }
333718334Speter
333818334Speter  /* Otherwise, we don't have a split point.  */
333918334Speter  return 0;
334018334Speter}
334118334Speter
334218334Speter/* Throughout X, replace FROM with TO, and return the result.
334318334Speter   The result is TO if X is FROM;
334418334Speter   otherwise the result is X, but its contents may have been modified.
334518334Speter   If they were modified, a record was made in undobuf so that
334618334Speter   undo_all will (among other things) return X to its original state.
334718334Speter
334818334Speter   If the number of changes necessary is too much to record to undo,
334918334Speter   the excess changes are not made, so the result is invalid.
335018334Speter   The changes already made can still be undone.
335118334Speter   undobuf.num_undo is incremented for such changes, so by testing that
335218334Speter   the caller can tell whether the result is valid.
335318334Speter
335418334Speter   `n_occurrences' is incremented each time FROM is replaced.
335590075Sobrien
3356117395Skan   IN_DEST is nonzero if we are processing the SET_DEST of a SET.
335718334Speter
3358117395Skan   UNIQUE_COPY is nonzero if each substitution must be unique.  We do this
3359117395Skan   by copying if `n_occurrences' is nonzero.  */
336018334Speter
336118334Speterstatic rtx
336218334Spetersubst (x, from, to, in_dest, unique_copy)
336390075Sobrien     rtx x, from, to;
336418334Speter     int in_dest;
336518334Speter     int unique_copy;
336618334Speter{
336790075Sobrien  enum rtx_code code = GET_CODE (x);
336818334Speter  enum machine_mode op0_mode = VOIDmode;
336990075Sobrien  const char *fmt;
337090075Sobrien  int len, i;
337118334Speter  rtx new;
337218334Speter
337318334Speter/* Two expressions are equal if they are identical copies of a shared
337418334Speter   RTX or if they are both registers with the same register number
337518334Speter   and mode.  */
337618334Speter
337718334Speter#define COMBINE_RTX_EQUAL_P(X,Y)			\
337818334Speter  ((X) == (Y)						\
337918334Speter   || (GET_CODE (X) == REG && GET_CODE (Y) == REG	\
338018334Speter       && REGNO (X) == REGNO (Y) && GET_MODE (X) == GET_MODE (Y)))
338118334Speter
338218334Speter  if (! in_dest && COMBINE_RTX_EQUAL_P (x, from))
338318334Speter    {
338418334Speter      n_occurrences++;
338518334Speter      return (unique_copy && n_occurrences > 1 ? copy_rtx (to) : to);
338618334Speter    }
338718334Speter
338818334Speter  /* If X and FROM are the same register but different modes, they will
338990075Sobrien     not have been seen as equal above.  However, flow.c will make a
339018334Speter     LOG_LINKS entry for that case.  If we do nothing, we will try to
339118334Speter     rerecognize our original insn and, when it succeeds, we will
339218334Speter     delete the feeding insn, which is incorrect.
339318334Speter
339418334Speter     So force this insn not to match in this (rare) case.  */
339518334Speter  if (! in_dest && code == REG && GET_CODE (from) == REG
339618334Speter      && REGNO (x) == REGNO (from))
339750397Sobrien    return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
339818334Speter
339918334Speter  /* If this is an object, we are done unless it is a MEM or LO_SUM, both
340018334Speter     of which may contain things that can be combined.  */
340118334Speter  if (code != MEM && code != LO_SUM && GET_RTX_CLASS (code) == 'o')
340218334Speter    return x;
340318334Speter
340418334Speter  /* It is possible to have a subexpression appear twice in the insn.
340518334Speter     Suppose that FROM is a register that appears within TO.
340618334Speter     Then, after that subexpression has been scanned once by `subst',
340718334Speter     the second time it is scanned, TO may be found.  If we were
340818334Speter     to scan TO here, we would find FROM within it and create a
340918334Speter     self-referent rtl structure which is completely wrong.  */
341018334Speter  if (COMBINE_RTX_EQUAL_P (x, to))
341118334Speter    return to;
341218334Speter
341350397Sobrien  /* Parallel asm_operands need special attention because all of the
341450397Sobrien     inputs are shared across the arms.  Furthermore, unsharing the
341550397Sobrien     rtl results in recognition failures.  Failure to handle this case
341650397Sobrien     specially can result in circular rtl.
341718334Speter
341850397Sobrien     Solve this by doing a normal pass across the first entry of the
341950397Sobrien     parallel, and only processing the SET_DESTs of the subsequent
342050397Sobrien     entries.  Ug.  */
342118334Speter
342250397Sobrien  if (code == PARALLEL
342350397Sobrien      && GET_CODE (XVECEXP (x, 0, 0)) == SET
342450397Sobrien      && GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS)
342550397Sobrien    {
342650397Sobrien      new = subst (XVECEXP (x, 0, 0), from, to, 0, unique_copy);
342718334Speter
342850397Sobrien      /* If this substitution failed, this whole thing fails.  */
342950397Sobrien      if (GET_CODE (new) == CLOBBER
343050397Sobrien	  && XEXP (new, 0) == const0_rtx)
343150397Sobrien	return new;
343250397Sobrien
343350397Sobrien      SUBST (XVECEXP (x, 0, 0), new);
343450397Sobrien
343550397Sobrien      for (i = XVECLEN (x, 0) - 1; i >= 1; i--)
343618334Speter	{
343750397Sobrien	  rtx dest = SET_DEST (XVECEXP (x, 0, i));
343890075Sobrien
343950397Sobrien	  if (GET_CODE (dest) != REG
344050397Sobrien	      && GET_CODE (dest) != CC0
344150397Sobrien	      && GET_CODE (dest) != PC)
344218334Speter	    {
344350397Sobrien	      new = subst (dest, from, to, 0, unique_copy);
344418334Speter
344550397Sobrien	      /* If this substitution failed, this whole thing fails.  */
344650397Sobrien	      if (GET_CODE (new) == CLOBBER
344750397Sobrien		  && XEXP (new, 0) == const0_rtx)
344850397Sobrien		return new;
344918334Speter
345050397Sobrien	      SUBST (SET_DEST (XVECEXP (x, 0, i)), new);
345118334Speter	    }
345218334Speter	}
345350397Sobrien    }
345450397Sobrien  else
345550397Sobrien    {
345650397Sobrien      len = GET_RTX_LENGTH (code);
345750397Sobrien      fmt = GET_RTX_FORMAT (code);
345850397Sobrien
345950397Sobrien      /* We don't need to process a SET_DEST that is a register, CC0,
346050397Sobrien	 or PC, so set up to skip this common case.  All other cases
346150397Sobrien	 where we want to suppress replacing something inside a
346250397Sobrien	 SET_SRC are handled via the IN_DEST operand.  */
346350397Sobrien      if (code == SET
346450397Sobrien	  && (GET_CODE (SET_DEST (x)) == REG
346550397Sobrien	      || GET_CODE (SET_DEST (x)) == CC0
346650397Sobrien	      || GET_CODE (SET_DEST (x)) == PC))
346750397Sobrien	fmt = "ie";
346850397Sobrien
346950397Sobrien      /* Get the mode of operand 0 in case X is now a SIGN_EXTEND of a
347050397Sobrien	 constant.  */
347150397Sobrien      if (fmt[0] == 'e')
347250397Sobrien	op0_mode = GET_MODE (XEXP (x, 0));
347350397Sobrien
347450397Sobrien      for (i = 0; i < len; i++)
347518334Speter	{
347650397Sobrien	  if (fmt[i] == 'E')
347718334Speter	    {
347890075Sobrien	      int j;
347950397Sobrien	      for (j = XVECLEN (x, i) - 1; j >= 0; j--)
348050397Sobrien		{
348150397Sobrien		  if (COMBINE_RTX_EQUAL_P (XVECEXP (x, i, j), from))
348250397Sobrien		    {
348350397Sobrien		      new = (unique_copy && n_occurrences
348450397Sobrien			     ? copy_rtx (to) : to);
348550397Sobrien		      n_occurrences++;
348650397Sobrien		    }
348750397Sobrien		  else
348850397Sobrien		    {
348950397Sobrien		      new = subst (XVECEXP (x, i, j), from, to, 0,
349050397Sobrien				   unique_copy);
349118334Speter
349250397Sobrien		      /* If this substitution failed, this whole thing
349350397Sobrien			 fails.  */
349450397Sobrien		      if (GET_CODE (new) == CLOBBER
349550397Sobrien			  && XEXP (new, 0) == const0_rtx)
349650397Sobrien			return new;
349750397Sobrien		    }
349850397Sobrien
349950397Sobrien		  SUBST (XVECEXP (x, i, j), new);
350050397Sobrien		}
350150397Sobrien	    }
350250397Sobrien	  else if (fmt[i] == 'e')
350350397Sobrien	    {
350490075Sobrien	      /* If this is a register being set, ignore it.  */
350590075Sobrien	      new = XEXP (x, i);
350690075Sobrien	      if (in_dest
350790075Sobrien		  && (code == SUBREG || code == STRICT_LOW_PART
350890075Sobrien		      || code == ZERO_EXTRACT)
350990075Sobrien		  && i == 0
351090075Sobrien		  && GET_CODE (new) == REG)
351190075Sobrien		;
351290075Sobrien
351390075Sobrien	      else if (COMBINE_RTX_EQUAL_P (XEXP (x, i), from))
351450397Sobrien		{
351550397Sobrien		  /* In general, don't install a subreg involving two
351650397Sobrien		     modes not tieable.  It can worsen register
351750397Sobrien		     allocation, and can even make invalid reload
351850397Sobrien		     insns, since the reg inside may need to be copied
351950397Sobrien		     from in the outside mode, and that may be invalid
352050397Sobrien		     if it is an fp reg copied in integer mode.
352150397Sobrien
352250397Sobrien		     We allow two exceptions to this: It is valid if
352350397Sobrien		     it is inside another SUBREG and the mode of that
352450397Sobrien		     SUBREG and the mode of the inside of TO is
352550397Sobrien		     tieable and it is valid if X is a SET that copies
352650397Sobrien		     FROM to CC0.  */
352750397Sobrien
352850397Sobrien		  if (GET_CODE (to) == SUBREG
352950397Sobrien		      && ! MODES_TIEABLE_P (GET_MODE (to),
353050397Sobrien					    GET_MODE (SUBREG_REG (to)))
353150397Sobrien		      && ! (code == SUBREG
353250397Sobrien			    && MODES_TIEABLE_P (GET_MODE (x),
353350397Sobrien						GET_MODE (SUBREG_REG (to))))
353418334Speter#ifdef HAVE_cc0
353550397Sobrien		      && ! (code == SET && i == 1 && XEXP (x, 0) == cc0_rtx)
353618334Speter#endif
353750397Sobrien		      )
353850397Sobrien		    return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
353918334Speter
3540117395Skan#ifdef CANNOT_CHANGE_MODE_CLASS
354190075Sobrien		  if (code == SUBREG
354290075Sobrien		      && GET_CODE (to) == REG
354390075Sobrien		      && REGNO (to) < FIRST_PSEUDO_REGISTER
3544117395Skan		      && REG_CANNOT_CHANGE_MODE_P (REGNO (to),
3545117395Skan						   GET_MODE (to),
3546117395Skan						   GET_MODE (x)))
354790075Sobrien		    return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
354890075Sobrien#endif
354990075Sobrien
355050397Sobrien		  new = (unique_copy && n_occurrences ? copy_rtx (to) : to);
355150397Sobrien		  n_occurrences++;
355250397Sobrien		}
355350397Sobrien	      else
355450397Sobrien		/* If we are in a SET_DEST, suppress most cases unless we
355550397Sobrien		   have gone inside a MEM, in which case we want to
355650397Sobrien		   simplify the address.  We assume here that things that
355750397Sobrien		   are actually part of the destination have their inner
355890075Sobrien		   parts in the first expression.  This is true for SUBREG,
355950397Sobrien		   STRICT_LOW_PART, and ZERO_EXTRACT, which are the only
356050397Sobrien		   things aside from REG and MEM that should appear in a
356150397Sobrien		   SET_DEST.  */
356250397Sobrien		new = subst (XEXP (x, i), from, to,
356350397Sobrien			     (((in_dest
356450397Sobrien				&& (code == SUBREG || code == STRICT_LOW_PART
356550397Sobrien				    || code == ZERO_EXTRACT))
356650397Sobrien			       || code == SET)
356750397Sobrien			      && i == 0), unique_copy);
356818334Speter
356950397Sobrien	      /* If we found that we will have to reject this combination,
357050397Sobrien		 indicate that by returning the CLOBBER ourselves, rather than
357150397Sobrien		 an expression containing it.  This will speed things up as
357250397Sobrien		 well as prevent accidents where two CLOBBERs are considered
357350397Sobrien		 to be equal, thus producing an incorrect simplification.  */
357418334Speter
357550397Sobrien	      if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx)
357650397Sobrien		return new;
357718334Speter
357896263Sobrien	      if (GET_CODE (new) == CONST_INT && GET_CODE (x) == SUBREG)
357996263Sobrien		{
3580102780Skan		  enum machine_mode mode = GET_MODE (x);
3581117395Skan
3582117395Skan		  x = simplify_subreg (GET_MODE (x), new,
358396263Sobrien				       GET_MODE (SUBREG_REG (x)),
358496263Sobrien				       SUBREG_BYTE (x));
358596263Sobrien		  if (! x)
3586102780Skan		    x = gen_rtx_CLOBBER (mode, const0_rtx);
358796263Sobrien		}
358896263Sobrien	      else if (GET_CODE (new) == CONST_INT
358996263Sobrien		       && GET_CODE (x) == ZERO_EXTEND)
359096263Sobrien		{
359196263Sobrien		  x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
359296263Sobrien						new, GET_MODE (XEXP (x, 0)));
359396263Sobrien		  if (! x)
359496263Sobrien		    abort ();
359596263Sobrien		}
359696263Sobrien	      else
359796263Sobrien		SUBST (XEXP (x, i), new);
359850397Sobrien	    }
359918334Speter	}
360018334Speter    }
360118334Speter
360218334Speter  /* Try to simplify X.  If the simplification changed the code, it is likely
360318334Speter     that further simplification will help, so loop, but limit the number
360418334Speter     of repetitions that will be performed.  */
360518334Speter
360618334Speter  for (i = 0; i < 4; i++)
360718334Speter    {
360818334Speter      /* If X is sufficiently simple, don't bother trying to do anything
360918334Speter	 with it.  */
361018334Speter      if (code != CONST_INT && code != REG && code != CLOBBER)
361190075Sobrien	x = combine_simplify_rtx (x, op0_mode, i == 3, in_dest);
361218334Speter
361318334Speter      if (GET_CODE (x) == code)
361418334Speter	break;
361518334Speter
361618334Speter      code = GET_CODE (x);
361718334Speter
361818334Speter      /* We no longer know the original mode of operand 0 since we
361918334Speter	 have changed the form of X)  */
362018334Speter      op0_mode = VOIDmode;
362118334Speter    }
362218334Speter
362318334Speter  return x;
362418334Speter}
362518334Speter
362618334Speter/* Simplify X, a piece of RTL.  We just operate on the expression at the
362718334Speter   outer level; call `subst' to simplify recursively.  Return the new
362818334Speter   expression.
362918334Speter
363018334Speter   OP0_MODE is the original mode of XEXP (x, 0); LAST is nonzero if this
363118334Speter   will be the iteration even if an expression with a code different from
363218334Speter   X is returned; IN_DEST is nonzero if we are inside a SET_DEST.  */
363318334Speter
363418334Speterstatic rtx
363590075Sobriencombine_simplify_rtx (x, op0_mode, last, in_dest)
363618334Speter     rtx x;
363718334Speter     enum machine_mode op0_mode;
363818334Speter     int last;
363918334Speter     int in_dest;
364018334Speter{
364118334Speter  enum rtx_code code = GET_CODE (x);
364218334Speter  enum machine_mode mode = GET_MODE (x);
364318334Speter  rtx temp;
364490075Sobrien  rtx reversed;
364518334Speter  int i;
364618334Speter
364718334Speter  /* If this is a commutative operation, put a constant last and a complex
364818334Speter     expression first.  We don't need to do this for comparisons here.  */
364918334Speter  if (GET_RTX_CLASS (code) == 'c'
365090075Sobrien      && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
365118334Speter    {
365218334Speter      temp = XEXP (x, 0);
365318334Speter      SUBST (XEXP (x, 0), XEXP (x, 1));
365418334Speter      SUBST (XEXP (x, 1), temp);
365518334Speter    }
365618334Speter
365718334Speter  /* If this is a PLUS, MINUS, or MULT, and the first operand is the
365818334Speter     sign extension of a PLUS with a constant, reverse the order of the sign
365918334Speter     extension and the addition. Note that this not the same as the original
366018334Speter     code, but overflow is undefined for signed values.  Also note that the
366118334Speter     PLUS will have been partially moved "inside" the sign-extension, so that
366218334Speter     the first operand of X will really look like:
366318334Speter         (ashiftrt (plus (ashift A C4) C5) C4).
366418334Speter     We convert this to
366518334Speter         (plus (ashiftrt (ashift A C4) C2) C4)
366618334Speter     and replace the first operand of X with that expression.  Later parts
366718334Speter     of this function may simplify the expression further.
366818334Speter
366918334Speter     For example, if we start with (mult (sign_extend (plus A C1)) C2),
367018334Speter     we swap the SIGN_EXTEND and PLUS.  Later code will apply the
367118334Speter     distributive law to produce (plus (mult (sign_extend X) C1) C3).
367218334Speter
367318334Speter     We do this to simplify address expressions.  */
367418334Speter
367518334Speter  if ((code == PLUS || code == MINUS || code == MULT)
367618334Speter      && GET_CODE (XEXP (x, 0)) == ASHIFTRT
367718334Speter      && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS
367818334Speter      && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ASHIFT
367918334Speter      && GET_CODE (XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 1)) == CONST_INT
368018334Speter      && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
368118334Speter      && XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 1) == XEXP (XEXP (x, 0), 1)
368218334Speter      && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
368318334Speter      && (temp = simplify_binary_operation (ASHIFTRT, mode,
368418334Speter					    XEXP (XEXP (XEXP (x, 0), 0), 1),
368518334Speter					    XEXP (XEXP (x, 0), 1))) != 0)
368618334Speter    {
368718334Speter      rtx new
368818334Speter	= simplify_shift_const (NULL_RTX, ASHIFT, mode,
368918334Speter				XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 0),
369018334Speter				INTVAL (XEXP (XEXP (x, 0), 1)));
369118334Speter
369218334Speter      new = simplify_shift_const (NULL_RTX, ASHIFTRT, mode, new,
369318334Speter				  INTVAL (XEXP (XEXP (x, 0), 1)));
369418334Speter
369518334Speter      SUBST (XEXP (x, 0), gen_binary (PLUS, mode, new, temp));
369618334Speter    }
369718334Speter
369890075Sobrien  /* If this is a simple operation applied to an IF_THEN_ELSE, try
369918334Speter     applying it to the arms of the IF_THEN_ELSE.  This often simplifies
370018334Speter     things.  Check for cases where both arms are testing the same
370118334Speter     condition.
370218334Speter
370318334Speter     Don't do anything if all operands are very simple.  */
370418334Speter
370518334Speter  if (((GET_RTX_CLASS (code) == '2' || GET_RTX_CLASS (code) == 'c'
370618334Speter	|| GET_RTX_CLASS (code) == '<')
370718334Speter       && ((GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) != 'o'
370818334Speter	    && ! (GET_CODE (XEXP (x, 0)) == SUBREG
370918334Speter		  && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0))))
371018334Speter		      == 'o')))
371118334Speter	   || (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) != 'o'
371218334Speter	       && ! (GET_CODE (XEXP (x, 1)) == SUBREG
371318334Speter		     && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 1))))
371418334Speter			 == 'o')))))
371518334Speter      || (GET_RTX_CLASS (code) == '1'
371618334Speter	  && ((GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) != 'o'
371718334Speter	       && ! (GET_CODE (XEXP (x, 0)) == SUBREG
371818334Speter		     && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0))))
371918334Speter			 == 'o'))))))
372018334Speter    {
372190075Sobrien      rtx cond, true_rtx, false_rtx;
372218334Speter
372390075Sobrien      cond = if_then_else_cond (x, &true_rtx, &false_rtx);
372450397Sobrien      if (cond != 0
372550397Sobrien	  /* If everything is a comparison, what we have is highly unlikely
372650397Sobrien	     to be simpler, so don't use it.  */
372750397Sobrien	  && ! (GET_RTX_CLASS (code) == '<'
372890075Sobrien		&& (GET_RTX_CLASS (GET_CODE (true_rtx)) == '<'
372990075Sobrien		    || GET_RTX_CLASS (GET_CODE (false_rtx)) == '<')))
373018334Speter	{
373118334Speter	  rtx cop1 = const0_rtx;
373218334Speter	  enum rtx_code cond_code = simplify_comparison (NE, &cond, &cop1);
373318334Speter
373418334Speter	  if (cond_code == NE && GET_RTX_CLASS (GET_CODE (cond)) == '<')
373518334Speter	    return x;
373618334Speter
373790075Sobrien	  /* Simplify the alternative arms; this may collapse the true and
373818334Speter	     false arms to store-flag values.  */
373990075Sobrien	  true_rtx = subst (true_rtx, pc_rtx, pc_rtx, 0, 0);
374090075Sobrien	  false_rtx = subst (false_rtx, pc_rtx, pc_rtx, 0, 0);
374118334Speter
374290075Sobrien	  /* If true_rtx and false_rtx are not general_operands, an if_then_else
374390075Sobrien	     is unlikely to be simpler.  */
374490075Sobrien	  if (general_operand (true_rtx, VOIDmode)
374590075Sobrien	      && general_operand (false_rtx, VOIDmode))
374690075Sobrien	    {
374790075Sobrien	      /* Restarting if we generate a store-flag expression will cause
374890075Sobrien		 us to loop.  Just drop through in this case.  */
374918334Speter
375090075Sobrien	      /* If the result values are STORE_FLAG_VALUE and zero, we can
375190075Sobrien		 just make the comparison operation.  */
375290075Sobrien	      if (true_rtx == const_true_rtx && false_rtx == const0_rtx)
375390075Sobrien		x = gen_binary (cond_code, mode, cond, cop1);
375490075Sobrien	      else if (true_rtx == const0_rtx && false_rtx == const_true_rtx
375590075Sobrien		       && reverse_condition (cond_code) != UNKNOWN)
375690075Sobrien		x = gen_binary (reverse_condition (cond_code),
375790075Sobrien				mode, cond, cop1);
375818334Speter
375990075Sobrien	      /* Likewise, we can make the negate of a comparison operation
376090075Sobrien		 if the result values are - STORE_FLAG_VALUE and zero.  */
376190075Sobrien	      else if (GET_CODE (true_rtx) == CONST_INT
376290075Sobrien		       && INTVAL (true_rtx) == - STORE_FLAG_VALUE
376390075Sobrien		       && false_rtx == const0_rtx)
376490075Sobrien		x = simplify_gen_unary (NEG, mode,
376590075Sobrien					gen_binary (cond_code, mode, cond,
376690075Sobrien						    cop1),
376790075Sobrien					mode);
376890075Sobrien	      else if (GET_CODE (false_rtx) == CONST_INT
376990075Sobrien		       && INTVAL (false_rtx) == - STORE_FLAG_VALUE
377090075Sobrien		       && true_rtx == const0_rtx)
377190075Sobrien		x = simplify_gen_unary (NEG, mode,
377290075Sobrien					gen_binary (reverse_condition
377390075Sobrien						    (cond_code),
377490075Sobrien						    mode, cond, cop1),
377590075Sobrien					mode);
377690075Sobrien	      else
377790075Sobrien		return gen_rtx_IF_THEN_ELSE (mode,
377890075Sobrien					     gen_binary (cond_code, VOIDmode,
377990075Sobrien							 cond, cop1),
378090075Sobrien					     true_rtx, false_rtx);
378118334Speter
378290075Sobrien	      code = GET_CODE (x);
378390075Sobrien	      op0_mode = VOIDmode;
378490075Sobrien	    }
378518334Speter	}
378618334Speter    }
378718334Speter
378818334Speter  /* Try to fold this expression in case we have constants that weren't
378918334Speter     present before.  */
379018334Speter  temp = 0;
379118334Speter  switch (GET_RTX_CLASS (code))
379218334Speter    {
379318334Speter    case '1':
379418334Speter      temp = simplify_unary_operation (code, mode, XEXP (x, 0), op0_mode);
379518334Speter      break;
379618334Speter    case '<':
379790075Sobrien      {
379890075Sobrien	enum machine_mode cmp_mode = GET_MODE (XEXP (x, 0));
379990075Sobrien	if (cmp_mode == VOIDmode)
380090075Sobrien	  {
380190075Sobrien	    cmp_mode = GET_MODE (XEXP (x, 1));
380290075Sobrien	    if (cmp_mode == VOIDmode)
380390075Sobrien	      cmp_mode = op0_mode;
380490075Sobrien	  }
380590075Sobrien	temp = simplify_relational_operation (code, cmp_mode,
380690075Sobrien					      XEXP (x, 0), XEXP (x, 1));
380790075Sobrien      }
380818334Speter#ifdef FLOAT_STORE_FLAG_VALUE
380990075Sobrien      if (temp != 0 && GET_MODE_CLASS (mode) == MODE_FLOAT)
381090075Sobrien	{
381190075Sobrien	  if (temp == const0_rtx)
381290075Sobrien	    temp = CONST0_RTX (mode);
381390075Sobrien	  else
3814117395Skan	    temp = CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE (mode),
3815117395Skan						 mode);
381690075Sobrien	}
381718334Speter#endif
381818334Speter      break;
381918334Speter    case 'c':
382018334Speter    case '2':
382118334Speter      temp = simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
382218334Speter      break;
382318334Speter    case 'b':
382418334Speter    case '3':
382518334Speter      temp = simplify_ternary_operation (code, mode, op0_mode, XEXP (x, 0),
382618334Speter					 XEXP (x, 1), XEXP (x, 2));
382718334Speter      break;
382818334Speter    }
382918334Speter
383018334Speter  if (temp)
383190075Sobrien    {
383290075Sobrien      x = temp;
383390075Sobrien      code = GET_CODE (temp);
383490075Sobrien      op0_mode = VOIDmode;
383590075Sobrien      mode = GET_MODE (temp);
383690075Sobrien    }
383718334Speter
383818334Speter  /* First see if we can apply the inverse distributive law.  */
383918334Speter  if (code == PLUS || code == MINUS
384018334Speter      || code == AND || code == IOR || code == XOR)
384118334Speter    {
384218334Speter      x = apply_distributive_law (x);
384318334Speter      code = GET_CODE (x);
384490075Sobrien      op0_mode = VOIDmode;
384518334Speter    }
384618334Speter
384718334Speter  /* If CODE is an associative operation not otherwise handled, see if we
384818334Speter     can associate some operands.  This can win if they are constants or
384990075Sobrien     if they are logically related (i.e. (a & b) & a).  */
385090075Sobrien  if ((code == PLUS || code == MINUS || code == MULT || code == DIV
385190075Sobrien       || code == AND || code == IOR || code == XOR
385218334Speter       || code == SMAX || code == SMIN || code == UMAX || code == UMIN)
385390075Sobrien      && ((INTEGRAL_MODE_P (mode) && code != DIV)
385490075Sobrien	  || (flag_unsafe_math_optimizations && FLOAT_MODE_P (mode))))
385518334Speter    {
385618334Speter      if (GET_CODE (XEXP (x, 0)) == code)
385718334Speter	{
385818334Speter	  rtx other = XEXP (XEXP (x, 0), 0);
385918334Speter	  rtx inner_op0 = XEXP (XEXP (x, 0), 1);
386018334Speter	  rtx inner_op1 = XEXP (x, 1);
386118334Speter	  rtx inner;
386290075Sobrien
386318334Speter	  /* Make sure we pass the constant operand if any as the second
386418334Speter	     one if this is a commutative operation.  */
386518334Speter	  if (CONSTANT_P (inner_op0) && GET_RTX_CLASS (code) == 'c')
386618334Speter	    {
386718334Speter	      rtx tem = inner_op0;
386818334Speter	      inner_op0 = inner_op1;
386918334Speter	      inner_op1 = tem;
387018334Speter	    }
387118334Speter	  inner = simplify_binary_operation (code == MINUS ? PLUS
387218334Speter					     : code == DIV ? MULT
387318334Speter					     : code,
387418334Speter					     mode, inner_op0, inner_op1);
387518334Speter
387618334Speter	  /* For commutative operations, try the other pair if that one
387718334Speter	     didn't simplify.  */
387818334Speter	  if (inner == 0 && GET_RTX_CLASS (code) == 'c')
387918334Speter	    {
388018334Speter	      other = XEXP (XEXP (x, 0), 1);
388118334Speter	      inner = simplify_binary_operation (code, mode,
388218334Speter						 XEXP (XEXP (x, 0), 0),
388318334Speter						 XEXP (x, 1));
388418334Speter	    }
388518334Speter
388618334Speter	  if (inner)
388718334Speter	    return gen_binary (code, mode, other, inner);
388818334Speter	}
388918334Speter    }
389018334Speter
389118334Speter  /* A little bit of algebraic simplification here.  */
389218334Speter  switch (code)
389318334Speter    {
389418334Speter    case MEM:
389518334Speter      /* Ensure that our address has any ASHIFTs converted to MULT in case
389618334Speter	 address-recognizing predicates are called later.  */
389718334Speter      temp = make_compound_operation (XEXP (x, 0), MEM);
389818334Speter      SUBST (XEXP (x, 0), temp);
389918334Speter      break;
390018334Speter
390118334Speter    case SUBREG:
390290075Sobrien      if (op0_mode == VOIDmode)
390390075Sobrien	op0_mode = GET_MODE (SUBREG_REG (x));
390418334Speter
390590075Sobrien      /* simplify_subreg can't use gen_lowpart_for_combine.  */
390650397Sobrien      if (CONSTANT_P (SUBREG_REG (x))
3907117395Skan	  && subreg_lowpart_offset (mode, op0_mode) == SUBREG_BYTE (x)
3908117395Skan	     /* Don't call gen_lowpart_for_combine if the inner mode
3909117395Skan		is VOIDmode and we cannot simplify it, as SUBREG without
3910117395Skan		inner mode is invalid.  */
3911117395Skan	  && (GET_MODE (SUBREG_REG (x)) != VOIDmode
3912117395Skan	      || gen_lowpart_common (mode, SUBREG_REG (x))))
391318334Speter	return gen_lowpart_for_combine (mode, SUBREG_REG (x));
391418334Speter
391590075Sobrien      if (GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_CC)
391690075Sobrien        break;
391790075Sobrien      {
391890075Sobrien	rtx temp;
391990075Sobrien	temp = simplify_subreg (mode, SUBREG_REG (x), op0_mode,
392090075Sobrien				SUBREG_BYTE (x));
392190075Sobrien	if (temp)
392290075Sobrien	  return temp;
392390075Sobrien      }
392418334Speter
392596263Sobrien      /* Don't change the mode of the MEM if that would change the meaning
392696263Sobrien	 of the address.  */
392796263Sobrien      if (GET_CODE (SUBREG_REG (x)) == MEM
392896263Sobrien	  && (MEM_VOLATILE_P (SUBREG_REG (x))
392996263Sobrien	      || mode_dependent_address_p (XEXP (SUBREG_REG (x), 0))))
393096263Sobrien	return gen_rtx_CLOBBER (mode, const0_rtx);
393196263Sobrien
393218334Speter      /* Note that we cannot do any narrowing for non-constants since
393318334Speter	 we might have been counting on using the fact that some bits were
393418334Speter	 zero.  We now do this in the SET.  */
393518334Speter
393618334Speter      break;
393718334Speter
393818334Speter    case NOT:
393918334Speter      /* (not (plus X -1)) can become (neg X).  */
394018334Speter      if (GET_CODE (XEXP (x, 0)) == PLUS
394118334Speter	  && XEXP (XEXP (x, 0), 1) == constm1_rtx)
394290075Sobrien	return gen_rtx_NEG (mode, XEXP (XEXP (x, 0), 0));
394318334Speter
394418334Speter      /* Similarly, (not (neg X)) is (plus X -1).  */
394518334Speter      if (GET_CODE (XEXP (x, 0)) == NEG)
394690075Sobrien	return gen_rtx_PLUS (mode, XEXP (XEXP (x, 0), 0), constm1_rtx);
394718334Speter
394890075Sobrien      /* (not (xor X C)) for C constant is (xor X D) with D = ~C.  */
394918334Speter      if (GET_CODE (XEXP (x, 0)) == XOR
395018334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
395118334Speter	  && (temp = simplify_unary_operation (NOT, mode,
395218334Speter					       XEXP (XEXP (x, 0), 1),
395318334Speter					       mode)) != 0)
395418334Speter	return gen_binary (XOR, mode, XEXP (XEXP (x, 0), 0), temp);
395590075Sobrien
395618334Speter      /* (not (ashift 1 X)) is (rotate ~1 X).  We used to do this for operands
395718334Speter	 other than 1, but that is not valid.  We could do a similar
395818334Speter	 simplification for (not (lshiftrt C X)) where C is just the sign bit,
395918334Speter	 but this doesn't seem common enough to bother with.  */
396018334Speter      if (GET_CODE (XEXP (x, 0)) == ASHIFT
396118334Speter	  && XEXP (XEXP (x, 0), 0) == const1_rtx)
396290075Sobrien	return gen_rtx_ROTATE (mode, simplify_gen_unary (NOT, mode,
396390075Sobrien							 const1_rtx, mode),
396450397Sobrien			       XEXP (XEXP (x, 0), 1));
396590075Sobrien
396618334Speter      if (GET_CODE (XEXP (x, 0)) == SUBREG
396718334Speter	  && subreg_lowpart_p (XEXP (x, 0))
396818334Speter	  && (GET_MODE_SIZE (GET_MODE (XEXP (x, 0)))
396918334Speter	      < GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (x, 0)))))
397018334Speter	  && GET_CODE (SUBREG_REG (XEXP (x, 0))) == ASHIFT
397118334Speter	  && XEXP (SUBREG_REG (XEXP (x, 0)), 0) == const1_rtx)
397218334Speter	{
397318334Speter	  enum machine_mode inner_mode = GET_MODE (SUBREG_REG (XEXP (x, 0)));
397418334Speter
397550397Sobrien	  x = gen_rtx_ROTATE (inner_mode,
397690075Sobrien			      simplify_gen_unary (NOT, inner_mode, const1_rtx,
397790075Sobrien						  inner_mode),
397850397Sobrien			      XEXP (SUBREG_REG (XEXP (x, 0)), 1));
397918334Speter	  return gen_lowpart_for_combine (mode, x);
398018334Speter	}
398190075Sobrien
398250397Sobrien      /* If STORE_FLAG_VALUE is -1, (not (comparison foo bar)) can be done by
398350397Sobrien	 reversing the comparison code if valid.  */
398450397Sobrien      if (STORE_FLAG_VALUE == -1
398550397Sobrien	  && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
398690075Sobrien	  && (reversed = reversed_comparison (x, mode, XEXP (XEXP (x, 0), 0),
398790075Sobrien					      XEXP (XEXP (x, 0), 1))))
398890075Sobrien	return reversed;
398918334Speter
399090075Sobrien      /* (not (ashiftrt foo C)) where C is the number of bits in FOO minus 1
399190075Sobrien	 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1, so we can
399250397Sobrien	 perform the above simplification.  */
399318334Speter
399450397Sobrien      if (STORE_FLAG_VALUE == -1
399518334Speter	  && GET_CODE (XEXP (x, 0)) == ASHIFTRT
399618334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
399718334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) == GET_MODE_BITSIZE (mode) - 1)
399890075Sobrien	return gen_rtx_GE (mode, XEXP (XEXP (x, 0), 0), const0_rtx);
399918334Speter
400018334Speter      /* Apply De Morgan's laws to reduce number of patterns for machines
400190075Sobrien	 with negating logical insns (and-not, nand, etc.).  If result has
400290075Sobrien	 only one NOT, put it first, since that is how the patterns are
400390075Sobrien	 coded.  */
400418334Speter
400518334Speter      if (GET_CODE (XEXP (x, 0)) == IOR || GET_CODE (XEXP (x, 0)) == AND)
400690075Sobrien	{
400790075Sobrien	  rtx in1 = XEXP (XEXP (x, 0), 0), in2 = XEXP (XEXP (x, 0), 1);
400890075Sobrien	  enum machine_mode op_mode;
400918334Speter
401090075Sobrien	  op_mode = GET_MODE (in1);
401190075Sobrien	  in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
401218334Speter
401390075Sobrien	  op_mode = GET_MODE (in2);
401490075Sobrien	  if (op_mode == VOIDmode)
401590075Sobrien	    op_mode = mode;
401690075Sobrien	  in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
401718334Speter
401890075Sobrien	  if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
401990075Sobrien	    {
402090075Sobrien	      rtx tem = in2;
402190075Sobrien	      in2 = in1; in1 = tem;
402290075Sobrien	    }
402318334Speter
402490075Sobrien	  return gen_rtx_fmt_ee (GET_CODE (XEXP (x, 0)) == IOR ? AND : IOR,
402518334Speter				 mode, in1, in2);
402690075Sobrien	}
402718334Speter      break;
402818334Speter
402918334Speter    case NEG:
403018334Speter      /* (neg (plus X 1)) can become (not X).  */
403118334Speter      if (GET_CODE (XEXP (x, 0)) == PLUS
403218334Speter	  && XEXP (XEXP (x, 0), 1) == const1_rtx)
403390075Sobrien	return gen_rtx_NOT (mode, XEXP (XEXP (x, 0), 0));
403418334Speter
403518334Speter      /* Similarly, (neg (not X)) is (plus X 1).  */
403618334Speter      if (GET_CODE (XEXP (x, 0)) == NOT)
403718334Speter	return plus_constant (XEXP (XEXP (x, 0), 0), 1);
403818334Speter
4039117395Skan      /* (neg (minus X Y)) can become (minus Y X).  This transformation
4040117395Skan	 isn't safe for modes with signed zeros, since if X and Y are
4041117395Skan	 both +0, (minus Y X) is the same as (minus X Y).  If the rounding
4042117395Skan	 mode is towards +infinity (or -infinity) then the two expressions
4043117395Skan	 will be rounded differently.  */
404418334Speter      if (GET_CODE (XEXP (x, 0)) == MINUS
4045117395Skan	  && !HONOR_SIGNED_ZEROS (mode)
4046117395Skan	  && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
404718334Speter	return gen_binary (MINUS, mode, XEXP (XEXP (x, 0), 1),
404818334Speter			   XEXP (XEXP (x, 0), 0));
404918334Speter
4050117395Skan      /* (neg (plus A B)) is canonicalized to (minus (neg A) B).  */
4051117395Skan      if (GET_CODE (XEXP (x, 0)) == PLUS
4052117395Skan	  && !HONOR_SIGNED_ZEROS (mode)
4053117395Skan	  && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
4054117395Skan	{
4055117395Skan	  temp = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 0), 0), mode);
4056117395Skan	  temp = combine_simplify_rtx (temp, mode, last, in_dest);
4057117395Skan	  return gen_binary (MINUS, mode, temp, XEXP (XEXP (x, 0), 1));
4058117395Skan	}
4059117395Skan
4060117395Skan      /* (neg (mult A B)) becomes (mult (neg A) B).
4061117395Skan         This works even for floating-point values.  */
4062117395Skan      if (GET_CODE (XEXP (x, 0)) == MULT)
4063117395Skan	{
4064117395Skan	  temp = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 0), 0), mode);
4065117395Skan	  return gen_binary (MULT, mode, temp, XEXP (XEXP (x, 0), 1));
4066117395Skan	}
4067117395Skan
406850397Sobrien      /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1.  */
406918334Speter      if (GET_CODE (XEXP (x, 0)) == XOR && XEXP (XEXP (x, 0), 1) == const1_rtx
407018334Speter	  && nonzero_bits (XEXP (XEXP (x, 0), 0), mode) == 1)
407118334Speter	return gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0), constm1_rtx);
407218334Speter
407318334Speter      /* NEG commutes with ASHIFT since it is multiplication.  Only do this
407418334Speter	 if we can then eliminate the NEG (e.g.,
407518334Speter	 if the operand is a constant).  */
407618334Speter
407718334Speter      if (GET_CODE (XEXP (x, 0)) == ASHIFT)
407818334Speter	{
407918334Speter	  temp = simplify_unary_operation (NEG, mode,
408018334Speter					   XEXP (XEXP (x, 0), 0), mode);
408118334Speter	  if (temp)
408290075Sobrien	    return gen_binary (ASHIFT, mode, temp, XEXP (XEXP (x, 0), 1));
408318334Speter	}
408418334Speter
408518334Speter      temp = expand_compound_operation (XEXP (x, 0));
408618334Speter
408718334Speter      /* For C equal to the width of MODE minus 1, (neg (ashiftrt X C)) can be
408890075Sobrien	 replaced by (lshiftrt X C).  This will convert
408918334Speter	 (neg (sign_extract X 1 Y)) to (zero_extract X 1 Y).  */
409018334Speter
409118334Speter      if (GET_CODE (temp) == ASHIFTRT
409218334Speter	  && GET_CODE (XEXP (temp, 1)) == CONST_INT
409318334Speter	  && INTVAL (XEXP (temp, 1)) == GET_MODE_BITSIZE (mode) - 1)
409418334Speter	return simplify_shift_const (temp, LSHIFTRT, mode, XEXP (temp, 0),
409518334Speter				     INTVAL (XEXP (temp, 1)));
409618334Speter
409718334Speter      /* If X has only a single bit that might be nonzero, say, bit I, convert
409818334Speter	 (neg X) to (ashiftrt (ashift X C-I) C-I) where C is the bitsize of
409918334Speter	 MODE minus 1.  This will convert (neg (zero_extract X 1 Y)) to
410018334Speter	 (sign_extract X 1 Y).  But only do this if TEMP isn't a register
410118334Speter	 or a SUBREG of one since we'd be making the expression more
410218334Speter	 complex if it was just a register.  */
410318334Speter
410418334Speter      if (GET_CODE (temp) != REG
410518334Speter	  && ! (GET_CODE (temp) == SUBREG
410618334Speter		&& GET_CODE (SUBREG_REG (temp)) == REG)
410718334Speter	  && (i = exact_log2 (nonzero_bits (temp, mode))) >= 0)
410818334Speter	{
410918334Speter	  rtx temp1 = simplify_shift_const
411018334Speter	    (NULL_RTX, ASHIFTRT, mode,
411118334Speter	     simplify_shift_const (NULL_RTX, ASHIFT, mode, temp,
411218334Speter				   GET_MODE_BITSIZE (mode) - 1 - i),
411318334Speter	     GET_MODE_BITSIZE (mode) - 1 - i);
411418334Speter
411518334Speter	  /* If all we did was surround TEMP with the two shifts, we
411618334Speter	     haven't improved anything, so don't use it.  Otherwise,
411718334Speter	     we are better off with TEMP1.  */
411818334Speter	  if (GET_CODE (temp1) != ASHIFTRT
411918334Speter	      || GET_CODE (XEXP (temp1, 0)) != ASHIFT
412018334Speter	      || XEXP (XEXP (temp1, 0), 0) != temp)
412118334Speter	    return temp1;
412218334Speter	}
412318334Speter      break;
412418334Speter
412518334Speter    case TRUNCATE:
412650397Sobrien      /* We can't handle truncation to a partial integer mode here
412750397Sobrien	 because we don't know the real bitsize of the partial
412850397Sobrien	 integer mode.  */
412950397Sobrien      if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
413050397Sobrien	break;
413150397Sobrien
413250397Sobrien      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
413350397Sobrien	  && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
413450397Sobrien				    GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))))
413518334Speter	SUBST (XEXP (x, 0),
413618334Speter	       force_to_mode (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
413718334Speter			      GET_MODE_MASK (mode), NULL_RTX, 0));
413850397Sobrien
413950397Sobrien      /* (truncate:SI ({sign,zero}_extend:DI foo:SI)) == foo:SI.  */
414050397Sobrien      if ((GET_CODE (XEXP (x, 0)) == SIGN_EXTEND
414150397Sobrien	   || GET_CODE (XEXP (x, 0)) == ZERO_EXTEND)
414250397Sobrien	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode)
414350397Sobrien	return XEXP (XEXP (x, 0), 0);
414450397Sobrien
414550397Sobrien      /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is
414650397Sobrien	 (OP:SI foo:SI) if OP is NEG or ABS.  */
414750397Sobrien      if ((GET_CODE (XEXP (x, 0)) == ABS
414850397Sobrien	   || GET_CODE (XEXP (x, 0)) == NEG)
414950397Sobrien	  && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SIGN_EXTEND
415050397Sobrien	      || GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND)
415150397Sobrien	  && GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == mode)
415290075Sobrien	return simplify_gen_unary (GET_CODE (XEXP (x, 0)), mode,
415390075Sobrien				   XEXP (XEXP (XEXP (x, 0), 0), 0), mode);
415450397Sobrien
415550397Sobrien      /* (truncate:SI (subreg:DI (truncate:SI X) 0)) is
415650397Sobrien	 (truncate:SI x).  */
415750397Sobrien      if (GET_CODE (XEXP (x, 0)) == SUBREG
415850397Sobrien	  && GET_CODE (SUBREG_REG (XEXP (x, 0))) == TRUNCATE
415950397Sobrien	  && subreg_lowpart_p (XEXP (x, 0)))
416050397Sobrien	return SUBREG_REG (XEXP (x, 0));
416150397Sobrien
416250397Sobrien      /* If we know that the value is already truncated, we can
416390075Sobrien         replace the TRUNCATE with a SUBREG if TRULY_NOOP_TRUNCATION
416490075Sobrien         is nonzero for the corresponding modes.  But don't do this
416590075Sobrien         for an (LSHIFTRT (MULT ...)) since this will cause problems
416690075Sobrien         with the umulXi3_highpart patterns.  */
416752284Sobrien      if (TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
416852284Sobrien				 GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))))
416952284Sobrien	  && num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
4170117395Skan	     >= (unsigned int) (GET_MODE_BITSIZE (mode) + 1)
417190075Sobrien	  && ! (GET_CODE (XEXP (x, 0)) == LSHIFTRT
417290075Sobrien		&& GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT))
417350397Sobrien	return gen_lowpart_for_combine (mode, XEXP (x, 0));
417450397Sobrien
417550397Sobrien      /* A truncate of a comparison can be replaced with a subreg if
417650397Sobrien         STORE_FLAG_VALUE permits.  This is like the previous test,
417750397Sobrien         but it works even if the comparison is done in a mode larger
417850397Sobrien         than HOST_BITS_PER_WIDE_INT.  */
417950397Sobrien      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
418050397Sobrien	  && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
418190075Sobrien	  && ((HOST_WIDE_INT) STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0)
418250397Sobrien	return gen_lowpart_for_combine (mode, XEXP (x, 0));
418350397Sobrien
418450397Sobrien      /* Similarly, a truncate of a register whose value is a
418550397Sobrien         comparison can be replaced with a subreg if STORE_FLAG_VALUE
418650397Sobrien         permits.  */
418750397Sobrien      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
418890075Sobrien	  && ((HOST_WIDE_INT) STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
418950397Sobrien	  && (temp = get_last_value (XEXP (x, 0)))
419050397Sobrien	  && GET_RTX_CLASS (GET_CODE (temp)) == '<')
419150397Sobrien	return gen_lowpart_for_combine (mode, XEXP (x, 0));
419250397Sobrien
419318334Speter      break;
419418334Speter
419518334Speter    case FLOAT_TRUNCATE:
419618334Speter      /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF.  */
419718334Speter      if (GET_CODE (XEXP (x, 0)) == FLOAT_EXTEND
419818334Speter	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode)
419990075Sobrien	return XEXP (XEXP (x, 0), 0);
420018334Speter
420118334Speter      /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
420218334Speter	 (OP:SF foo:SF) if OP is NEG or ABS.  */
420318334Speter      if ((GET_CODE (XEXP (x, 0)) == ABS
420418334Speter	   || GET_CODE (XEXP (x, 0)) == NEG)
420518334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == FLOAT_EXTEND
420618334Speter	  && GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == mode)
420790075Sobrien	return simplify_gen_unary (GET_CODE (XEXP (x, 0)), mode,
420890075Sobrien				   XEXP (XEXP (XEXP (x, 0), 0), 0), mode);
420918334Speter
421018334Speter      /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
421118334Speter	 is (float_truncate:SF x).  */
421218334Speter      if (GET_CODE (XEXP (x, 0)) == SUBREG
421318334Speter	  && subreg_lowpart_p (XEXP (x, 0))
421418334Speter	  && GET_CODE (SUBREG_REG (XEXP (x, 0))) == FLOAT_TRUNCATE)
421518334Speter	return SUBREG_REG (XEXP (x, 0));
421690075Sobrien      break;
421718334Speter
421818334Speter#ifdef HAVE_cc0
421918334Speter    case COMPARE:
422018334Speter      /* Convert (compare FOO (const_int 0)) to FOO unless we aren't
422118334Speter	 using cc0, in which case we want to leave it as a COMPARE
422218334Speter	 so we can distinguish it from a register-register-copy.  */
422318334Speter      if (XEXP (x, 1) == const0_rtx)
422418334Speter	return XEXP (x, 0);
422518334Speter
4226117395Skan      /* x - 0 is the same as x unless x's mode has signed zeros and
4227117395Skan	 allows rounding towards -infinity.  Under those conditions,
4228117395Skan	 0 - 0 is -0.  */
4229117395Skan      if (!(HONOR_SIGNED_ZEROS (GET_MODE (XEXP (x, 0)))
4230117395Skan	    && HONOR_SIGN_DEPENDENT_ROUNDING (GET_MODE (XEXP (x, 0))))
423118334Speter	  && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 0))))
423218334Speter	return XEXP (x, 0);
423318334Speter      break;
423418334Speter#endif
423518334Speter
423618334Speter    case CONST:
423718334Speter      /* (const (const X)) can become (const X).  Do it this way rather than
423818334Speter	 returning the inner CONST since CONST can be shared with a
423918334Speter	 REG_EQUAL note.  */
424018334Speter      if (GET_CODE (XEXP (x, 0)) == CONST)
424118334Speter	SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
424218334Speter      break;
424318334Speter
424418334Speter#ifdef HAVE_lo_sum
424518334Speter    case LO_SUM:
424618334Speter      /* Convert (lo_sum (high FOO) FOO) to FOO.  This is necessary so we
424718334Speter	 can add in an offset.  find_split_point will split this address up
424818334Speter	 again if it doesn't match.  */
424918334Speter      if (GET_CODE (XEXP (x, 0)) == HIGH
425018334Speter	  && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
425118334Speter	return XEXP (x, 1);
425218334Speter      break;
425318334Speter#endif
425418334Speter
425518334Speter    case PLUS:
4256117395Skan      /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)).
4257117395Skan       */
4258117395Skan      if (GET_CODE (XEXP (x, 0)) == MULT
4259117395Skan	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == NEG)
4260117395Skan	{
4261117395Skan	  rtx in1, in2;
4262117395Skan
4263117395Skan	  in1 = XEXP (XEXP (XEXP (x, 0), 0), 0);
4264117395Skan	  in2 = XEXP (XEXP (x, 0), 1);
4265117395Skan	  return gen_binary (MINUS, mode, XEXP (x, 1),
4266117395Skan			     gen_binary (MULT, mode, in1, in2));
4267117395Skan	}
4268117395Skan
426918334Speter      /* If we have (plus (plus (A const) B)), associate it so that CONST is
427018334Speter	 outermost.  That's because that's the way indexed addresses are
427118334Speter	 supposed to appear.  This code used to check many more cases, but
427218334Speter	 they are now checked elsewhere.  */
427318334Speter      if (GET_CODE (XEXP (x, 0)) == PLUS
427418334Speter	  && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
427518334Speter	return gen_binary (PLUS, mode,
427618334Speter			   gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0),
427718334Speter				       XEXP (x, 1)),
427818334Speter			   XEXP (XEXP (x, 0), 1));
427918334Speter
428018334Speter      /* (plus (xor (and <foo> (const_int pow2 - 1)) <c>) <-c>)
428118334Speter	 when c is (const_int (pow2 + 1) / 2) is a sign extension of a
428218334Speter	 bit-field and can be replaced by either a sign_extend or a
428390075Sobrien	 sign_extract.  The `and' may be a zero_extend and the two
428490075Sobrien	 <c>, -<c> constants may be reversed.  */
428518334Speter      if (GET_CODE (XEXP (x, 0)) == XOR
428618334Speter	  && GET_CODE (XEXP (x, 1)) == CONST_INT
428718334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
428890075Sobrien	  && INTVAL (XEXP (x, 1)) == -INTVAL (XEXP (XEXP (x, 0), 1))
428990075Sobrien	  && ((i = exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) >= 0
429090075Sobrien	      || (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0)
429118334Speter	  && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
429218334Speter	  && ((GET_CODE (XEXP (XEXP (x, 0), 0)) == AND
429318334Speter	       && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
429418334Speter	       && (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))
429518334Speter		   == ((HOST_WIDE_INT) 1 << (i + 1)) - 1))
429618334Speter	      || (GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND
429718334Speter		  && (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)))
429890075Sobrien		      == (unsigned int) i + 1))))
429918334Speter	return simplify_shift_const
430018334Speter	  (NULL_RTX, ASHIFTRT, mode,
430118334Speter	   simplify_shift_const (NULL_RTX, ASHIFT, mode,
430218334Speter				 XEXP (XEXP (XEXP (x, 0), 0), 0),
430318334Speter				 GET_MODE_BITSIZE (mode) - (i + 1)),
430418334Speter	   GET_MODE_BITSIZE (mode) - (i + 1));
430518334Speter
430618334Speter      /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
430718334Speter	 C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
430818334Speter	 is 1.  This produces better code than the alternative immediately
430918334Speter	 below.  */
431018334Speter      if (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
431118334Speter	  && ((STORE_FLAG_VALUE == -1 && XEXP (x, 1) == const1_rtx)
431290075Sobrien	      || (STORE_FLAG_VALUE == 1 && XEXP (x, 1) == constm1_rtx))
431390075Sobrien	  && (reversed = reversed_comparison (XEXP (x, 0), mode,
431490075Sobrien					      XEXP (XEXP (x, 0), 0),
431590075Sobrien					      XEXP (XEXP (x, 0), 1))))
431618334Speter	return
431790075Sobrien	  simplify_gen_unary (NEG, mode, reversed, mode);
431818334Speter
431918334Speter      /* If only the low-order bit of X is possibly nonzero, (plus x -1)
432018334Speter	 can become (ashiftrt (ashift (xor x 1) C) C) where C is
432118334Speter	 the bitsize of the mode - 1.  This allows simplification of
432218334Speter	 "a = (b & 8) == 0;"  */
432318334Speter      if (XEXP (x, 1) == constm1_rtx
432418334Speter	  && GET_CODE (XEXP (x, 0)) != REG
432518334Speter	  && ! (GET_CODE (XEXP (x,0)) == SUBREG
432618334Speter		&& GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG)
432718334Speter	  && nonzero_bits (XEXP (x, 0), mode) == 1)
432818334Speter	return simplify_shift_const (NULL_RTX, ASHIFTRT, mode,
432918334Speter	   simplify_shift_const (NULL_RTX, ASHIFT, mode,
433090075Sobrien				 gen_rtx_XOR (mode, XEXP (x, 0), const1_rtx),
433118334Speter				 GET_MODE_BITSIZE (mode) - 1),
433218334Speter	   GET_MODE_BITSIZE (mode) - 1);
433318334Speter
433418334Speter      /* If we are adding two things that have no bits in common, convert
433518334Speter	 the addition into an IOR.  This will often be further simplified,
433618334Speter	 for example in cases like ((a & 1) + (a & 2)), which can
433718334Speter	 become a & 3.  */
433818334Speter
433918334Speter      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
434018334Speter	  && (nonzero_bits (XEXP (x, 0), mode)
434118334Speter	      & nonzero_bits (XEXP (x, 1), mode)) == 0)
434290075Sobrien	{
434390075Sobrien	  /* Try to simplify the expression further.  */
434490075Sobrien	  rtx tor = gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1));
434590075Sobrien	  temp = combine_simplify_rtx (tor, mode, last, in_dest);
434690075Sobrien
434790075Sobrien	  /* If we could, great.  If not, do not go ahead with the IOR
434890075Sobrien	     replacement, since PLUS appears in many special purpose
434990075Sobrien	     address arithmetic instructions.  */
435090075Sobrien	  if (GET_CODE (temp) != CLOBBER && temp != tor)
435190075Sobrien	    return temp;
435290075Sobrien	}
435318334Speter      break;
435418334Speter
435518334Speter    case MINUS:
435650397Sobrien      /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
435750397Sobrien	 by reversing the comparison code if valid.  */
435850397Sobrien      if (STORE_FLAG_VALUE == 1
435950397Sobrien	  && XEXP (x, 0) == const1_rtx
436018334Speter	  && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<'
436190075Sobrien	  && (reversed = reversed_comparison (XEXP (x, 1), mode,
436290075Sobrien					      XEXP (XEXP (x, 1), 0),
436390075Sobrien					      XEXP (XEXP (x, 1), 1))))
436490075Sobrien	return reversed;
436518334Speter
436618334Speter      /* (minus <foo> (and <foo> (const_int -pow2))) becomes
436718334Speter	 (and <foo> (const_int pow2-1))  */
436818334Speter      if (GET_CODE (XEXP (x, 1)) == AND
436918334Speter	  && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
437090075Sobrien	  && exact_log2 (-INTVAL (XEXP (XEXP (x, 1), 1))) >= 0
437118334Speter	  && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
437218334Speter	return simplify_and_const_int (NULL_RTX, mode, XEXP (x, 0),
437390075Sobrien				       -INTVAL (XEXP (XEXP (x, 1), 1)) - 1);
437418334Speter
4375117395Skan      /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A).
4376117395Skan       */
4377117395Skan      if (GET_CODE (XEXP (x, 1)) == MULT
4378117395Skan	  && GET_CODE (XEXP (XEXP (x, 1), 0)) == NEG)
4379117395Skan	{
4380117395Skan	  rtx in1, in2;
4381117395Skan
4382117395Skan	  in1 = XEXP (XEXP (XEXP (x, 1), 0), 0);
4383117395Skan	  in2 = XEXP (XEXP (x, 1), 1);
4384117395Skan	  return gen_binary (PLUS, mode, gen_binary (MULT, mode, in1, in2),
4385117395Skan			     XEXP (x, 0));
4386117395Skan	}
4387117395Skan
4388117395Skan       /* Canonicalize (minus (neg A) (mult B C)) to
4389117395Skan	  (minus (mult (neg B) C) A). */
4390117395Skan      if (GET_CODE (XEXP (x, 1)) == MULT
4391117395Skan	  && GET_CODE (XEXP (x, 0)) == NEG)
4392117395Skan	{
4393117395Skan	  rtx in1, in2;
4394117395Skan
4395117395Skan	  in1 = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 1), 0), mode);
4396117395Skan	  in2 = XEXP (XEXP (x, 1), 1);
4397117395Skan	  return gen_binary (MINUS, mode, gen_binary (MULT, mode, in1, in2),
4398117395Skan			     XEXP (XEXP (x, 0), 0));
4399117395Skan	}
4400117395Skan
440118334Speter      /* Canonicalize (minus A (plus B C)) to (minus (minus A B) C) for
440218334Speter	 integers.  */
440318334Speter      if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode))
440418334Speter	return gen_binary (MINUS, mode,
440518334Speter			   gen_binary (MINUS, mode, XEXP (x, 0),
440618334Speter				       XEXP (XEXP (x, 1), 0)),
440718334Speter			   XEXP (XEXP (x, 1), 1));
440818334Speter      break;
440918334Speter
441018334Speter    case MULT:
441118334Speter      /* If we have (mult (plus A B) C), apply the distributive law and then
441218334Speter	 the inverse distributive law to see if things simplify.  This
441318334Speter	 occurs mostly in addresses, often when unrolling loops.  */
441418334Speter
441518334Speter      if (GET_CODE (XEXP (x, 0)) == PLUS)
441618334Speter	{
441718334Speter	  x = apply_distributive_law
441818334Speter	    (gen_binary (PLUS, mode,
441918334Speter			 gen_binary (MULT, mode,
442018334Speter				     XEXP (XEXP (x, 0), 0), XEXP (x, 1)),
442118334Speter			 gen_binary (MULT, mode,
442270635Sobrien				     XEXP (XEXP (x, 0), 1),
442370635Sobrien				     copy_rtx (XEXP (x, 1)))));
442418334Speter
442518334Speter	  if (GET_CODE (x) != MULT)
442618334Speter	    return x;
442718334Speter	}
442890075Sobrien      /* Try simplify a*(b/c) as (a*b)/c.  */
442990075Sobrien      if (FLOAT_MODE_P (mode) && flag_unsafe_math_optimizations
443090075Sobrien	  && GET_CODE (XEXP (x, 0)) == DIV)
443190075Sobrien	{
443290075Sobrien	  rtx tem = simplify_binary_operation (MULT, mode,
443390075Sobrien					       XEXP (XEXP (x, 0), 0),
443490075Sobrien					       XEXP (x, 1));
443590075Sobrien	  if (tem)
443690075Sobrien	    return gen_binary (DIV, mode, tem, XEXP (XEXP (x, 0), 1));
443790075Sobrien	}
443818334Speter      break;
443918334Speter
444018334Speter    case UDIV:
444118334Speter      /* If this is a divide by a power of two, treat it as a shift if
444218334Speter	 its first operand is a shift.  */
444318334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
444418334Speter	  && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0
444518334Speter	  && (GET_CODE (XEXP (x, 0)) == ASHIFT
444618334Speter	      || GET_CODE (XEXP (x, 0)) == LSHIFTRT
444718334Speter	      || GET_CODE (XEXP (x, 0)) == ASHIFTRT
444818334Speter	      || GET_CODE (XEXP (x, 0)) == ROTATE
444918334Speter	      || GET_CODE (XEXP (x, 0)) == ROTATERT))
445018334Speter	return simplify_shift_const (NULL_RTX, LSHIFTRT, mode, XEXP (x, 0), i);
445118334Speter      break;
445218334Speter
445318334Speter    case EQ:  case NE:
445418334Speter    case GT:  case GTU:  case GE:  case GEU:
445518334Speter    case LT:  case LTU:  case LE:  case LEU:
445690075Sobrien    case UNEQ:  case LTGT:
445790075Sobrien    case UNGT:  case UNGE:
445890075Sobrien    case UNLT:  case UNLE:
445990075Sobrien    case UNORDERED: case ORDERED:
446018334Speter      /* If the first operand is a condition code, we can't do anything
446118334Speter	 with it.  */
446218334Speter      if (GET_CODE (XEXP (x, 0)) == COMPARE
446318334Speter	  || (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_CC
446418334Speter#ifdef HAVE_cc0
446518334Speter	      && XEXP (x, 0) != cc0_rtx
446618334Speter#endif
446790075Sobrien	      ))
446818334Speter	{
446918334Speter	  rtx op0 = XEXP (x, 0);
447018334Speter	  rtx op1 = XEXP (x, 1);
447118334Speter	  enum rtx_code new_code;
447218334Speter
447318334Speter	  if (GET_CODE (op0) == COMPARE)
447418334Speter	    op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);
447518334Speter
447618334Speter	  /* Simplify our comparison, if possible.  */
447718334Speter	  new_code = simplify_comparison (code, &op0, &op1);
447818334Speter
447918334Speter	  /* If STORE_FLAG_VALUE is 1, we can convert (ne x 0) to simply X
448018334Speter	     if only the low-order bit is possibly nonzero in X (such as when
448118334Speter	     X is a ZERO_EXTRACT of one bit).  Similarly, we can convert EQ to
448218334Speter	     (xor X 1) or (minus 1 X); we use the former.  Finally, if X is
448318334Speter	     known to be either 0 or -1, NE becomes a NEG and EQ becomes
448418334Speter	     (plus X 1).
448518334Speter
448618334Speter	     Remove any ZERO_EXTRACT we made when thinking this was a
448718334Speter	     comparison.  It may now be simpler to use, e.g., an AND.  If a
448818334Speter	     ZERO_EXTRACT is indeed appropriate, it will be placed back by
448918334Speter	     the call to make_compound_operation in the SET case.  */
449018334Speter
449150397Sobrien	  if (STORE_FLAG_VALUE == 1
449250397Sobrien	      && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
449390075Sobrien	      && op1 == const0_rtx
449490075Sobrien	      && mode == GET_MODE (op0)
449590075Sobrien	      && nonzero_bits (op0, mode) == 1)
449618334Speter	    return gen_lowpart_for_combine (mode,
449718334Speter					    expand_compound_operation (op0));
449818334Speter
449950397Sobrien	  else if (STORE_FLAG_VALUE == 1
450050397Sobrien		   && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
450118334Speter		   && op1 == const0_rtx
450290075Sobrien		   && mode == GET_MODE (op0)
450318334Speter		   && (num_sign_bit_copies (op0, mode)
450418334Speter		       == GET_MODE_BITSIZE (mode)))
450518334Speter	    {
450618334Speter	      op0 = expand_compound_operation (op0);
450790075Sobrien	      return simplify_gen_unary (NEG, mode,
450890075Sobrien					 gen_lowpart_for_combine (mode, op0),
450990075Sobrien					 mode);
451018334Speter	    }
451118334Speter
451250397Sobrien	  else if (STORE_FLAG_VALUE == 1
451350397Sobrien		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
451418334Speter		   && op1 == const0_rtx
451590075Sobrien		   && mode == GET_MODE (op0)
451618334Speter		   && nonzero_bits (op0, mode) == 1)
451718334Speter	    {
451818334Speter	      op0 = expand_compound_operation (op0);
451918334Speter	      return gen_binary (XOR, mode,
452018334Speter				 gen_lowpart_for_combine (mode, op0),
452118334Speter				 const1_rtx);
452218334Speter	    }
452318334Speter
452450397Sobrien	  else if (STORE_FLAG_VALUE == 1
452550397Sobrien		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
452618334Speter		   && op1 == const0_rtx
452790075Sobrien		   && mode == GET_MODE (op0)
452818334Speter		   && (num_sign_bit_copies (op0, mode)
452918334Speter		       == GET_MODE_BITSIZE (mode)))
453018334Speter	    {
453118334Speter	      op0 = expand_compound_operation (op0);
453218334Speter	      return plus_constant (gen_lowpart_for_combine (mode, op0), 1);
453318334Speter	    }
453418334Speter
453518334Speter	  /* If STORE_FLAG_VALUE is -1, we have cases similar to
453618334Speter	     those above.  */
453750397Sobrien	  if (STORE_FLAG_VALUE == -1
453850397Sobrien	      && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
453918334Speter	      && op1 == const0_rtx
454018334Speter	      && (num_sign_bit_copies (op0, mode)
454118334Speter		  == GET_MODE_BITSIZE (mode)))
454218334Speter	    return gen_lowpart_for_combine (mode,
454318334Speter					    expand_compound_operation (op0));
454418334Speter
454550397Sobrien	  else if (STORE_FLAG_VALUE == -1
454650397Sobrien		   && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
454718334Speter		   && op1 == const0_rtx
454890075Sobrien		   && mode == GET_MODE (op0)
454918334Speter		   && nonzero_bits (op0, mode) == 1)
455018334Speter	    {
455118334Speter	      op0 = expand_compound_operation (op0);
455290075Sobrien	      return simplify_gen_unary (NEG, mode,
455390075Sobrien					 gen_lowpart_for_combine (mode, op0),
455490075Sobrien					 mode);
455518334Speter	    }
455618334Speter
455750397Sobrien	  else if (STORE_FLAG_VALUE == -1
455850397Sobrien		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
455918334Speter		   && op1 == const0_rtx
456090075Sobrien		   && mode == GET_MODE (op0)
456118334Speter		   && (num_sign_bit_copies (op0, mode)
456218334Speter		       == GET_MODE_BITSIZE (mode)))
456318334Speter	    {
456418334Speter	      op0 = expand_compound_operation (op0);
456590075Sobrien	      return simplify_gen_unary (NOT, mode,
456690075Sobrien					 gen_lowpart_for_combine (mode, op0),
456790075Sobrien					 mode);
456818334Speter	    }
456918334Speter
457018334Speter	  /* If X is 0/1, (eq X 0) is X-1.  */
457150397Sobrien	  else if (STORE_FLAG_VALUE == -1
457250397Sobrien		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
457318334Speter		   && op1 == const0_rtx
457490075Sobrien		   && mode == GET_MODE (op0)
457518334Speter		   && nonzero_bits (op0, mode) == 1)
457618334Speter	    {
457718334Speter	      op0 = expand_compound_operation (op0);
457818334Speter	      return plus_constant (gen_lowpart_for_combine (mode, op0), -1);
457918334Speter	    }
458018334Speter
458118334Speter	  /* If STORE_FLAG_VALUE says to just test the sign bit and X has just
458218334Speter	     one bit that might be nonzero, we can convert (ne x 0) to
458318334Speter	     (ashift x c) where C puts the bit in the sign bit.  Remove any
458418334Speter	     AND with STORE_FLAG_VALUE when we are done, since we are only
458518334Speter	     going to test the sign bit.  */
458618334Speter	  if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
458718334Speter	      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
458850397Sobrien	      && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
458952284Sobrien		  == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE(mode)-1))
459018334Speter	      && op1 == const0_rtx
459118334Speter	      && mode == GET_MODE (op0)
459218334Speter	      && (i = exact_log2 (nonzero_bits (op0, mode))) >= 0)
459318334Speter	    {
459418334Speter	      x = simplify_shift_const (NULL_RTX, ASHIFT, mode,
459518334Speter					expand_compound_operation (op0),
459618334Speter					GET_MODE_BITSIZE (mode) - 1 - i);
459718334Speter	      if (GET_CODE (x) == AND && XEXP (x, 1) == const_true_rtx)
459818334Speter		return XEXP (x, 0);
459918334Speter	      else
460018334Speter		return x;
460118334Speter	    }
460218334Speter
460318334Speter	  /* If the code changed, return a whole new comparison.  */
460418334Speter	  if (new_code != code)
460590075Sobrien	    return gen_rtx_fmt_ee (new_code, mode, op0, op1);
460618334Speter
460790075Sobrien	  /* Otherwise, keep this operation, but maybe change its operands.
460818334Speter	     This also converts (ne (compare FOO BAR) 0) to (ne FOO BAR).  */
460918334Speter	  SUBST (XEXP (x, 0), op0);
461018334Speter	  SUBST (XEXP (x, 1), op1);
461118334Speter	}
461218334Speter      break;
461390075Sobrien
461418334Speter    case IF_THEN_ELSE:
461518334Speter      return simplify_if_then_else (x);
461618334Speter
461718334Speter    case ZERO_EXTRACT:
461818334Speter    case SIGN_EXTRACT:
461918334Speter    case ZERO_EXTEND:
462018334Speter    case SIGN_EXTEND:
462150397Sobrien      /* If we are processing SET_DEST, we are done.  */
462218334Speter      if (in_dest)
462318334Speter	return x;
462418334Speter
462518334Speter      return expand_compound_operation (x);
462618334Speter
462718334Speter    case SET:
462818334Speter      return simplify_set (x);
462918334Speter
463018334Speter    case AND:
463118334Speter    case IOR:
463218334Speter    case XOR:
463318334Speter      return simplify_logical (x, last);
463418334Speter
463590075Sobrien    case ABS:
463618334Speter      /* (abs (neg <foo>)) -> (abs <foo>) */
463718334Speter      if (GET_CODE (XEXP (x, 0)) == NEG)
463818334Speter	SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
463918334Speter
464050397Sobrien      /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
464150397Sobrien         do nothing.  */
464250397Sobrien      if (GET_MODE (XEXP (x, 0)) == VOIDmode)
464350397Sobrien	break;
464450397Sobrien
464518334Speter      /* If operand is something known to be positive, ignore the ABS.  */
464618334Speter      if (GET_CODE (XEXP (x, 0)) == FFS || GET_CODE (XEXP (x, 0)) == ABS
464718334Speter	  || ((GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
464818334Speter	       <= HOST_BITS_PER_WIDE_INT)
464918334Speter	      && ((nonzero_bits (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
465018334Speter		   & ((HOST_WIDE_INT) 1
465118334Speter		      << (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - 1)))
465218334Speter		  == 0)))
465318334Speter	return XEXP (x, 0);
465418334Speter
465518334Speter      /* If operand is known to be only -1 or 0, convert ABS to NEG.  */
465618334Speter      if (num_sign_bit_copies (XEXP (x, 0), mode) == GET_MODE_BITSIZE (mode))
465790075Sobrien	return gen_rtx_NEG (mode, XEXP (x, 0));
465818334Speter
465918334Speter      break;
466018334Speter
466118334Speter    case FFS:
466218334Speter      /* (ffs (*_extend <X>)) = (ffs <X>) */
466318334Speter      if (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND
466418334Speter	  || GET_CODE (XEXP (x, 0)) == ZERO_EXTEND)
466518334Speter	SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
466618334Speter      break;
466718334Speter
466818334Speter    case FLOAT:
466918334Speter      /* (float (sign_extend <X>)) = (float <X>).  */
467018334Speter      if (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)
467118334Speter	SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
467218334Speter      break;
467318334Speter
467418334Speter    case ASHIFT:
467518334Speter    case LSHIFTRT:
467618334Speter    case ASHIFTRT:
467718334Speter    case ROTATE:
467818334Speter    case ROTATERT:
467918334Speter      /* If this is a shift by a constant amount, simplify it.  */
468018334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
468190075Sobrien	return simplify_shift_const (x, code, mode, XEXP (x, 0),
468218334Speter				     INTVAL (XEXP (x, 1)));
468318334Speter
468418334Speter#ifdef SHIFT_COUNT_TRUNCATED
468518334Speter      else if (SHIFT_COUNT_TRUNCATED && GET_CODE (XEXP (x, 1)) != REG)
468618334Speter	SUBST (XEXP (x, 1),
4687117395Skan	       force_to_mode (XEXP (x, 1), GET_MODE (XEXP (x, 1)),
468890075Sobrien			      ((HOST_WIDE_INT) 1
468918334Speter			       << exact_log2 (GET_MODE_BITSIZE (GET_MODE (x))))
469018334Speter			      - 1,
469118334Speter			      NULL_RTX, 0));
469218334Speter#endif
469318334Speter
469418334Speter      break;
469550397Sobrien
469690075Sobrien    case VEC_SELECT:
469790075Sobrien      {
469890075Sobrien	rtx op0 = XEXP (x, 0);
469990075Sobrien	rtx op1 = XEXP (x, 1);
470090075Sobrien	int len;
470190075Sobrien
470290075Sobrien	if (GET_CODE (op1) != PARALLEL)
470390075Sobrien	  abort ();
470490075Sobrien	len = XVECLEN (op1, 0);
470590075Sobrien	if (len == 1
470690075Sobrien	    && GET_CODE (XVECEXP (op1, 0, 0)) == CONST_INT
470790075Sobrien	    && GET_CODE (op0) == VEC_CONCAT)
470890075Sobrien	  {
470990075Sobrien	    int offset = INTVAL (XVECEXP (op1, 0, 0)) * GET_MODE_SIZE (GET_MODE (x));
471090075Sobrien
471190075Sobrien	    /* Try to find the element in the VEC_CONCAT.  */
471290075Sobrien	    for (;;)
471390075Sobrien	      {
471490075Sobrien		if (GET_MODE (op0) == GET_MODE (x))
471590075Sobrien		  return op0;
471690075Sobrien		if (GET_CODE (op0) == VEC_CONCAT)
471790075Sobrien		  {
471890075Sobrien		    HOST_WIDE_INT op0_size = GET_MODE_SIZE (GET_MODE (XEXP (op0, 0)));
471990075Sobrien		    if (op0_size < offset)
472090075Sobrien		      op0 = XEXP (op0, 0);
472190075Sobrien		    else
472290075Sobrien		      {
472390075Sobrien			offset -= op0_size;
472490075Sobrien			op0 = XEXP (op0, 1);
472590075Sobrien		      }
472690075Sobrien		  }
472790075Sobrien		else
472890075Sobrien		  break;
472990075Sobrien	      }
473090075Sobrien	  }
473190075Sobrien      }
473290075Sobrien
473390075Sobrien      break;
473490075Sobrien
473550397Sobrien    default:
473650397Sobrien      break;
473718334Speter    }
473818334Speter
473918334Speter  return x;
474018334Speter}
474118334Speter
474218334Speter/* Simplify X, an IF_THEN_ELSE expression.  Return the new expression.  */
474318334Speter
474418334Speterstatic rtx
474518334Spetersimplify_if_then_else (x)
474618334Speter     rtx x;
474718334Speter{
474818334Speter  enum machine_mode mode = GET_MODE (x);
474918334Speter  rtx cond = XEXP (x, 0);
475090075Sobrien  rtx true_rtx = XEXP (x, 1);
475190075Sobrien  rtx false_rtx = XEXP (x, 2);
475218334Speter  enum rtx_code true_code = GET_CODE (cond);
475318334Speter  int comparison_p = GET_RTX_CLASS (true_code) == '<';
475418334Speter  rtx temp;
475518334Speter  int i;
475690075Sobrien  enum rtx_code false_code;
475790075Sobrien  rtx reversed;
475818334Speter
475950397Sobrien  /* Simplify storing of the truth value.  */
476090075Sobrien  if (comparison_p && true_rtx == const_true_rtx && false_rtx == const0_rtx)
476118334Speter    return gen_binary (true_code, mode, XEXP (cond, 0), XEXP (cond, 1));
476290075Sobrien
476350397Sobrien  /* Also when the truth value has to be reversed.  */
476490075Sobrien  if (comparison_p
476590075Sobrien      && true_rtx == const0_rtx && false_rtx == const_true_rtx
476690075Sobrien      && (reversed = reversed_comparison (cond, mode, XEXP (cond, 0),
476790075Sobrien					  XEXP (cond, 1))))
476890075Sobrien    return reversed;
476918334Speter
477018334Speter  /* Sometimes we can simplify the arm of an IF_THEN_ELSE if a register used
477118334Speter     in it is being compared against certain values.  Get the true and false
477218334Speter     comparisons and see if that says anything about the value of each arm.  */
477318334Speter
477490075Sobrien  if (comparison_p
477590075Sobrien      && ((false_code = combine_reversed_comparison_code (cond))
477690075Sobrien	  != UNKNOWN)
477718334Speter      && GET_CODE (XEXP (cond, 0)) == REG)
477818334Speter    {
477918334Speter      HOST_WIDE_INT nzb;
478018334Speter      rtx from = XEXP (cond, 0);
478118334Speter      rtx true_val = XEXP (cond, 1);
478218334Speter      rtx false_val = true_val;
478318334Speter      int swapped = 0;
478418334Speter
478518334Speter      /* If FALSE_CODE is EQ, swap the codes and arms.  */
478618334Speter
478718334Speter      if (false_code == EQ)
478818334Speter	{
478918334Speter	  swapped = 1, true_code = EQ, false_code = NE;
479090075Sobrien	  temp = true_rtx, true_rtx = false_rtx, false_rtx = temp;
479118334Speter	}
479218334Speter
479318334Speter      /* If we are comparing against zero and the expression being tested has
479418334Speter	 only a single bit that might be nonzero, that is its value when it is
479518334Speter	 not equal to zero.  Similarly if it is known to be -1 or 0.  */
479618334Speter
479718334Speter      if (true_code == EQ && true_val == const0_rtx
479818334Speter	  && exact_log2 (nzb = nonzero_bits (from, GET_MODE (from))) >= 0)
479918334Speter	false_code = EQ, false_val = GEN_INT (nzb);
480018334Speter      else if (true_code == EQ && true_val == const0_rtx
480118334Speter	       && (num_sign_bit_copies (from, GET_MODE (from))
480218334Speter		   == GET_MODE_BITSIZE (GET_MODE (from))))
480318334Speter	false_code = EQ, false_val = constm1_rtx;
480418334Speter
480518334Speter      /* Now simplify an arm if we know the value of the register in the
480618334Speter	 branch and it is used in the arm.  Be careful due to the potential
480718334Speter	 of locally-shared RTL.  */
480818334Speter
480990075Sobrien      if (reg_mentioned_p (from, true_rtx))
481090075Sobrien	true_rtx = subst (known_cond (copy_rtx (true_rtx), true_code,
481190075Sobrien				      from, true_val),
481218334Speter		      pc_rtx, pc_rtx, 0, 0);
481390075Sobrien      if (reg_mentioned_p (from, false_rtx))
481490075Sobrien	false_rtx = subst (known_cond (copy_rtx (false_rtx), false_code,
481518334Speter				   from, false_val),
481618334Speter		       pc_rtx, pc_rtx, 0, 0);
481718334Speter
481890075Sobrien      SUBST (XEXP (x, 1), swapped ? false_rtx : true_rtx);
481990075Sobrien      SUBST (XEXP (x, 2), swapped ? true_rtx : false_rtx);
482018334Speter
482190075Sobrien      true_rtx = XEXP (x, 1);
482290075Sobrien      false_rtx = XEXP (x, 2);
482390075Sobrien      true_code = GET_CODE (cond);
482418334Speter    }
482518334Speter
482618334Speter  /* If we have (if_then_else FOO (pc) (label_ref BAR)) and FOO can be
482718334Speter     reversed, do so to avoid needing two sets of patterns for
482818334Speter     subtract-and-branch insns.  Similarly if we have a constant in the true
482918334Speter     arm, the false arm is the same as the first operand of the comparison, or
483018334Speter     the false arm is more complicated than the true arm.  */
483118334Speter
483290075Sobrien  if (comparison_p
483390075Sobrien      && combine_reversed_comparison_code (cond) != UNKNOWN
483490075Sobrien      && (true_rtx == pc_rtx
483590075Sobrien	  || (CONSTANT_P (true_rtx)
483690075Sobrien	      && GET_CODE (false_rtx) != CONST_INT && false_rtx != pc_rtx)
483790075Sobrien	  || true_rtx == const0_rtx
483890075Sobrien	  || (GET_RTX_CLASS (GET_CODE (true_rtx)) == 'o'
483990075Sobrien	      && GET_RTX_CLASS (GET_CODE (false_rtx)) != 'o')
484090075Sobrien	  || (GET_CODE (true_rtx) == SUBREG
484190075Sobrien	      && GET_RTX_CLASS (GET_CODE (SUBREG_REG (true_rtx))) == 'o'
484290075Sobrien	      && GET_RTX_CLASS (GET_CODE (false_rtx)) != 'o')
484390075Sobrien	  || reg_mentioned_p (true_rtx, false_rtx)
484490075Sobrien	  || rtx_equal_p (false_rtx, XEXP (cond, 0))))
484518334Speter    {
484690075Sobrien      true_code = reversed_comparison_code (cond, NULL);
484718334Speter      SUBST (XEXP (x, 0),
484890075Sobrien	     reversed_comparison (cond, GET_MODE (cond), XEXP (cond, 0),
484990075Sobrien				  XEXP (cond, 1)));
485018334Speter
485190075Sobrien      SUBST (XEXP (x, 1), false_rtx);
485290075Sobrien      SUBST (XEXP (x, 2), true_rtx);
485318334Speter
485490075Sobrien      temp = true_rtx, true_rtx = false_rtx, false_rtx = temp;
485590075Sobrien      cond = XEXP (x, 0);
485650397Sobrien
485750397Sobrien      /* It is possible that the conditional has been simplified out.  */
485850397Sobrien      true_code = GET_CODE (cond);
485950397Sobrien      comparison_p = GET_RTX_CLASS (true_code) == '<';
486018334Speter    }
486118334Speter
486218334Speter  /* If the two arms are identical, we don't need the comparison.  */
486318334Speter
486490075Sobrien  if (rtx_equal_p (true_rtx, false_rtx) && ! side_effects_p (cond))
486590075Sobrien    return true_rtx;
486618334Speter
486750397Sobrien  /* Convert a == b ? b : a to "a".  */
486850397Sobrien  if (true_code == EQ && ! side_effects_p (cond)
4869117395Skan      && !HONOR_NANS (mode)
487090075Sobrien      && rtx_equal_p (XEXP (cond, 0), false_rtx)
487190075Sobrien      && rtx_equal_p (XEXP (cond, 1), true_rtx))
487290075Sobrien    return false_rtx;
487350397Sobrien  else if (true_code == NE && ! side_effects_p (cond)
4874117395Skan	   && !HONOR_NANS (mode)
487590075Sobrien	   && rtx_equal_p (XEXP (cond, 0), true_rtx)
487690075Sobrien	   && rtx_equal_p (XEXP (cond, 1), false_rtx))
487790075Sobrien    return true_rtx;
487850397Sobrien
487918334Speter  /* Look for cases where we have (abs x) or (neg (abs X)).  */
488018334Speter
488118334Speter  if (GET_MODE_CLASS (mode) == MODE_INT
488290075Sobrien      && GET_CODE (false_rtx) == NEG
488390075Sobrien      && rtx_equal_p (true_rtx, XEXP (false_rtx, 0))
488418334Speter      && comparison_p
488590075Sobrien      && rtx_equal_p (true_rtx, XEXP (cond, 0))
488690075Sobrien      && ! side_effects_p (true_rtx))
488718334Speter    switch (true_code)
488818334Speter      {
488918334Speter      case GT:
489018334Speter      case GE:
489190075Sobrien	return simplify_gen_unary (ABS, mode, true_rtx, mode);
489218334Speter      case LT:
489318334Speter      case LE:
489490075Sobrien	return
489590075Sobrien	  simplify_gen_unary (NEG, mode,
489690075Sobrien			      simplify_gen_unary (ABS, mode, true_rtx, mode),
489790075Sobrien			      mode);
489890075Sobrien      default:
489990075Sobrien	break;
490018334Speter      }
490118334Speter
490218334Speter  /* Look for MIN or MAX.  */
490318334Speter
490490075Sobrien  if ((! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
490518334Speter      && comparison_p
490690075Sobrien      && rtx_equal_p (XEXP (cond, 0), true_rtx)
490790075Sobrien      && rtx_equal_p (XEXP (cond, 1), false_rtx)
490818334Speter      && ! side_effects_p (cond))
490918334Speter    switch (true_code)
491018334Speter      {
491118334Speter      case GE:
491218334Speter      case GT:
491390075Sobrien	return gen_binary (SMAX, mode, true_rtx, false_rtx);
491418334Speter      case LE:
491518334Speter      case LT:
491690075Sobrien	return gen_binary (SMIN, mode, true_rtx, false_rtx);
491718334Speter      case GEU:
491818334Speter      case GTU:
491990075Sobrien	return gen_binary (UMAX, mode, true_rtx, false_rtx);
492018334Speter      case LEU:
492118334Speter      case LTU:
492290075Sobrien	return gen_binary (UMIN, mode, true_rtx, false_rtx);
492350397Sobrien      default:
492450397Sobrien	break;
492518334Speter      }
492690075Sobrien
492718334Speter  /* If we have (if_then_else COND (OP Z C1) Z) and OP is an identity when its
492818334Speter     second operand is zero, this can be done as (OP Z (mult COND C2)) where
492918334Speter     C2 = C1 * STORE_FLAG_VALUE. Similarly if OP has an outer ZERO_EXTEND or
493018334Speter     SIGN_EXTEND as long as Z is already extended (so we don't destroy it).
493118334Speter     We can do this kind of thing in some cases when STORE_FLAG_VALUE is
493250397Sobrien     neither 1 or -1, but it isn't worth checking for.  */
493318334Speter
493450397Sobrien  if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
4935117395Skan      && comparison_p
4936117395Skan      && GET_MODE_CLASS (mode) == MODE_INT
4937117395Skan      && ! side_effects_p (x))
493818334Speter    {
493990075Sobrien      rtx t = make_compound_operation (true_rtx, SET);
494090075Sobrien      rtx f = make_compound_operation (false_rtx, SET);
494118334Speter      rtx cond_op0 = XEXP (cond, 0);
494218334Speter      rtx cond_op1 = XEXP (cond, 1);
494390075Sobrien      enum rtx_code op = NIL, extend_op = NIL;
494418334Speter      enum machine_mode m = mode;
494590075Sobrien      rtx z = 0, c1 = NULL_RTX;
494618334Speter
494718334Speter      if ((GET_CODE (t) == PLUS || GET_CODE (t) == MINUS
494818334Speter	   || GET_CODE (t) == IOR || GET_CODE (t) == XOR
494918334Speter	   || GET_CODE (t) == ASHIFT
495018334Speter	   || GET_CODE (t) == LSHIFTRT || GET_CODE (t) == ASHIFTRT)
495118334Speter	  && rtx_equal_p (XEXP (t, 0), f))
495218334Speter	c1 = XEXP (t, 1), op = GET_CODE (t), z = f;
495318334Speter
495418334Speter      /* If an identity-zero op is commutative, check whether there
495550397Sobrien	 would be a match if we swapped the operands.  */
495618334Speter      else if ((GET_CODE (t) == PLUS || GET_CODE (t) == IOR
495718334Speter		|| GET_CODE (t) == XOR)
495818334Speter	       && rtx_equal_p (XEXP (t, 1), f))
495918334Speter	c1 = XEXP (t, 0), op = GET_CODE (t), z = f;
496018334Speter      else if (GET_CODE (t) == SIGN_EXTEND
496118334Speter	       && (GET_CODE (XEXP (t, 0)) == PLUS
496218334Speter		   || GET_CODE (XEXP (t, 0)) == MINUS
496318334Speter		   || GET_CODE (XEXP (t, 0)) == IOR
496418334Speter		   || GET_CODE (XEXP (t, 0)) == XOR
496518334Speter		   || GET_CODE (XEXP (t, 0)) == ASHIFT
496618334Speter		   || GET_CODE (XEXP (t, 0)) == LSHIFTRT
496718334Speter		   || GET_CODE (XEXP (t, 0)) == ASHIFTRT)
496818334Speter	       && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG
496918334Speter	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 0))
497018334Speter	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f)
497118334Speter	       && (num_sign_bit_copies (f, GET_MODE (f))
4972117395Skan		   > (unsigned int)
4973117395Skan		     (GET_MODE_BITSIZE (mode)
497418334Speter		      - GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (t, 0), 0))))))
497518334Speter	{
497618334Speter	  c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0));
497718334Speter	  extend_op = SIGN_EXTEND;
497818334Speter	  m = GET_MODE (XEXP (t, 0));
497918334Speter	}
498018334Speter      else if (GET_CODE (t) == SIGN_EXTEND
498118334Speter	       && (GET_CODE (XEXP (t, 0)) == PLUS
498218334Speter		   || GET_CODE (XEXP (t, 0)) == IOR
498318334Speter		   || GET_CODE (XEXP (t, 0)) == XOR)
498418334Speter	       && GET_CODE (XEXP (XEXP (t, 0), 1)) == SUBREG
498518334Speter	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 1))
498618334Speter	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 1)), f)
498718334Speter	       && (num_sign_bit_copies (f, GET_MODE (f))
4988117395Skan		   > (unsigned int)
4989117395Skan		     (GET_MODE_BITSIZE (mode)
499018334Speter		      - GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (t, 0), 1))))))
499118334Speter	{
499218334Speter	  c1 = XEXP (XEXP (t, 0), 0); z = f; op = GET_CODE (XEXP (t, 0));
499318334Speter	  extend_op = SIGN_EXTEND;
499418334Speter	  m = GET_MODE (XEXP (t, 0));
499518334Speter	}
499618334Speter      else if (GET_CODE (t) == ZERO_EXTEND
499718334Speter	       && (GET_CODE (XEXP (t, 0)) == PLUS
499818334Speter		   || GET_CODE (XEXP (t, 0)) == MINUS
499918334Speter		   || GET_CODE (XEXP (t, 0)) == IOR
500018334Speter		   || GET_CODE (XEXP (t, 0)) == XOR
500118334Speter		   || GET_CODE (XEXP (t, 0)) == ASHIFT
500218334Speter		   || GET_CODE (XEXP (t, 0)) == LSHIFTRT
500318334Speter		   || GET_CODE (XEXP (t, 0)) == ASHIFTRT)
500418334Speter	       && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG
500518334Speter	       && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
500618334Speter	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 0))
500718334Speter	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f)
500818334Speter	       && ((nonzero_bits (f, GET_MODE (f))
500990075Sobrien		    & ~GET_MODE_MASK (GET_MODE (XEXP (XEXP (t, 0), 0))))
501018334Speter		   == 0))
501118334Speter	{
501218334Speter	  c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0));
501318334Speter	  extend_op = ZERO_EXTEND;
501418334Speter	  m = GET_MODE (XEXP (t, 0));
501518334Speter	}
501618334Speter      else if (GET_CODE (t) == ZERO_EXTEND
501718334Speter	       && (GET_CODE (XEXP (t, 0)) == PLUS
501818334Speter		   || GET_CODE (XEXP (t, 0)) == IOR
501918334Speter		   || GET_CODE (XEXP (t, 0)) == XOR)
502018334Speter	       && GET_CODE (XEXP (XEXP (t, 0), 1)) == SUBREG
502118334Speter	       && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
502218334Speter	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 1))
502318334Speter	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 1)), f)
502418334Speter	       && ((nonzero_bits (f, GET_MODE (f))
502590075Sobrien		    & ~GET_MODE_MASK (GET_MODE (XEXP (XEXP (t, 0), 1))))
502618334Speter		   == 0))
502718334Speter	{
502818334Speter	  c1 = XEXP (XEXP (t, 0), 0); z = f; op = GET_CODE (XEXP (t, 0));
502918334Speter	  extend_op = ZERO_EXTEND;
503018334Speter	  m = GET_MODE (XEXP (t, 0));
503118334Speter	}
503290075Sobrien
503318334Speter      if (z)
503418334Speter	{
503518334Speter	  temp = subst (gen_binary (true_code, m, cond_op0, cond_op1),
503618334Speter			pc_rtx, pc_rtx, 0, 0);
503718334Speter	  temp = gen_binary (MULT, m, temp,
503818334Speter			     gen_binary (MULT, m, c1, const_true_rtx));
503918334Speter	  temp = subst (temp, pc_rtx, pc_rtx, 0, 0);
504018334Speter	  temp = gen_binary (op, m, gen_lowpart_for_combine (m, z), temp);
504118334Speter
504218334Speter	  if (extend_op != NIL)
504390075Sobrien	    temp = simplify_gen_unary (extend_op, mode, temp, m);
504418334Speter
504518334Speter	  return temp;
504618334Speter	}
504718334Speter    }
504818334Speter
504918334Speter  /* If we have (if_then_else (ne A 0) C1 0) and either A is known to be 0 or
505018334Speter     1 and C1 is a single bit or A is known to be 0 or -1 and C1 is the
505118334Speter     negation of a single bit, we can convert this operation to a shift.  We
505218334Speter     can actually do this more generally, but it doesn't seem worth it.  */
505318334Speter
505418334Speter  if (true_code == NE && XEXP (cond, 1) == const0_rtx
505590075Sobrien      && false_rtx == const0_rtx && GET_CODE (true_rtx) == CONST_INT
505618334Speter      && ((1 == nonzero_bits (XEXP (cond, 0), mode)
505790075Sobrien	   && (i = exact_log2 (INTVAL (true_rtx))) >= 0)
505818334Speter	  || ((num_sign_bit_copies (XEXP (cond, 0), mode)
505918334Speter	       == GET_MODE_BITSIZE (mode))
506090075Sobrien	      && (i = exact_log2 (-INTVAL (true_rtx))) >= 0)))
506118334Speter    return
506218334Speter      simplify_shift_const (NULL_RTX, ASHIFT, mode,
506318334Speter			    gen_lowpart_for_combine (mode, XEXP (cond, 0)), i);
506418334Speter
506518334Speter  return x;
506618334Speter}
506718334Speter
506818334Speter/* Simplify X, a SET expression.  Return the new expression.  */
506918334Speter
507018334Speterstatic rtx
507118334Spetersimplify_set (x)
507218334Speter     rtx x;
507318334Speter{
507418334Speter  rtx src = SET_SRC (x);
507518334Speter  rtx dest = SET_DEST (x);
507618334Speter  enum machine_mode mode
507718334Speter    = GET_MODE (src) != VOIDmode ? GET_MODE (src) : GET_MODE (dest);
507818334Speter  rtx other_insn;
507918334Speter  rtx *cc_use;
508018334Speter
508118334Speter  /* (set (pc) (return)) gets written as (return).  */
508218334Speter  if (GET_CODE (dest) == PC && GET_CODE (src) == RETURN)
508318334Speter    return src;
508418334Speter
508518334Speter  /* Now that we know for sure which bits of SRC we are using, see if we can
508618334Speter     simplify the expression for the object knowing that we only need the
508718334Speter     low-order bits.  */
508818334Speter
5089117395Skan  if (GET_MODE_CLASS (mode) == MODE_INT
5090117395Skan      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
509190075Sobrien    {
509290075Sobrien      src = force_to_mode (src, mode, ~(HOST_WIDE_INT) 0, NULL_RTX, 0);
509390075Sobrien      SUBST (SET_SRC (x), src);
509490075Sobrien    }
509518334Speter
509618334Speter  /* If we are setting CC0 or if the source is a COMPARE, look for the use of
509718334Speter     the comparison result and try to simplify it unless we already have used
509818334Speter     undobuf.other_insn.  */
5099117395Skan  if ((GET_MODE_CLASS (mode) == MODE_CC
5100117395Skan       || GET_CODE (src) == COMPARE
5101117395Skan       || CC0_P (dest))
510218334Speter      && (cc_use = find_single_use (dest, subst_insn, &other_insn)) != 0
510318334Speter      && (undobuf.other_insn == 0 || other_insn == undobuf.other_insn)
510418334Speter      && GET_RTX_CLASS (GET_CODE (*cc_use)) == '<'
510518334Speter      && rtx_equal_p (XEXP (*cc_use, 0), dest))
510618334Speter    {
510718334Speter      enum rtx_code old_code = GET_CODE (*cc_use);
510818334Speter      enum rtx_code new_code;
5109117395Skan      rtx op0, op1, tmp;
511018334Speter      int other_changed = 0;
511118334Speter      enum machine_mode compare_mode = GET_MODE (dest);
5112117395Skan      enum machine_mode tmp_mode;
511318334Speter
511418334Speter      if (GET_CODE (src) == COMPARE)
511518334Speter	op0 = XEXP (src, 0), op1 = XEXP (src, 1);
511618334Speter      else
511718334Speter	op0 = src, op1 = const0_rtx;
511818334Speter
5119117395Skan      /* Check whether the comparison is known at compile time.  */
5120117395Skan      if (GET_MODE (op0) != VOIDmode)
5121117395Skan	tmp_mode = GET_MODE (op0);
5122117395Skan      else if (GET_MODE (op1) != VOIDmode)
5123117395Skan	tmp_mode = GET_MODE (op1);
5124117395Skan      else
5125117395Skan	tmp_mode = compare_mode;
5126117395Skan      tmp = simplify_relational_operation (old_code, tmp_mode, op0, op1);
5127117395Skan      if (tmp != NULL_RTX)
5128117395Skan	{
5129117395Skan	  rtx pat = PATTERN (other_insn);
5130117395Skan	  undobuf.other_insn = other_insn;
5131117395Skan	  SUBST (*cc_use, tmp);
5132117395Skan
5133117395Skan	  /* Attempt to simplify CC user.  */
5134117395Skan	  if (GET_CODE (pat) == SET)
5135117395Skan	    {
5136117395Skan	      rtx new = simplify_rtx (SET_SRC (pat));
5137117395Skan	      if (new != NULL_RTX)
5138117395Skan		SUBST (SET_SRC (pat), new);
5139117395Skan	    }
5140117395Skan
5141117395Skan	  /* Convert X into a no-op move.  */
5142117395Skan	  SUBST (SET_DEST (x), pc_rtx);
5143117395Skan	  SUBST (SET_SRC (x), pc_rtx);
5144117395Skan	  return x;
5145117395Skan	}
5146117395Skan
514718334Speter      /* Simplify our comparison, if possible.  */
514818334Speter      new_code = simplify_comparison (old_code, &op0, &op1);
514918334Speter
515018334Speter#ifdef EXTRA_CC_MODES
515118334Speter      /* If this machine has CC modes other than CCmode, check to see if we
515218334Speter	 need to use a different CC mode here.  */
515318334Speter      compare_mode = SELECT_CC_MODE (new_code, op0, op1);
515418334Speter#endif /* EXTRA_CC_MODES */
515518334Speter
515618334Speter#if !defined (HAVE_cc0) && defined (EXTRA_CC_MODES)
515718334Speter      /* If the mode changed, we have to change SET_DEST, the mode in the
515818334Speter	 compare, and the mode in the place SET_DEST is used.  If SET_DEST is
515918334Speter	 a hard register, just build new versions with the proper mode.  If it
516018334Speter	 is a pseudo, we lose unless it is only time we set the pseudo, in
516118334Speter	 which case we can safely change its mode.  */
516218334Speter      if (compare_mode != GET_MODE (dest))
516318334Speter	{
516490075Sobrien	  unsigned int regno = REGNO (dest);
516550397Sobrien	  rtx new_dest = gen_rtx_REG (compare_mode, regno);
516618334Speter
516718334Speter	  if (regno < FIRST_PSEUDO_REGISTER
516850397Sobrien	      || (REG_N_SETS (regno) == 1 && ! REG_USERVAR_P (dest)))
516918334Speter	    {
517018334Speter	      if (regno >= FIRST_PSEUDO_REGISTER)
517118334Speter		SUBST (regno_reg_rtx[regno], new_dest);
517218334Speter
517318334Speter	      SUBST (SET_DEST (x), new_dest);
517418334Speter	      SUBST (XEXP (*cc_use, 0), new_dest);
517518334Speter	      other_changed = 1;
517618334Speter
517718334Speter	      dest = new_dest;
517818334Speter	    }
517918334Speter	}
518018334Speter#endif
518118334Speter
518218334Speter      /* If the code changed, we have to build a new comparison in
518318334Speter	 undobuf.other_insn.  */
518418334Speter      if (new_code != old_code)
518518334Speter	{
518618334Speter	  unsigned HOST_WIDE_INT mask;
518718334Speter
518890075Sobrien	  SUBST (*cc_use, gen_rtx_fmt_ee (new_code, GET_MODE (*cc_use),
518990075Sobrien					  dest, const0_rtx));
519018334Speter
519118334Speter	  /* If the only change we made was to change an EQ into an NE or
519218334Speter	     vice versa, OP0 has only one bit that might be nonzero, and OP1
519318334Speter	     is zero, check if changing the user of the condition code will
519418334Speter	     produce a valid insn.  If it won't, we can keep the original code
519518334Speter	     in that insn by surrounding our operation with an XOR.  */
519618334Speter
519718334Speter	  if (((old_code == NE && new_code == EQ)
519818334Speter	       || (old_code == EQ && new_code == NE))
519918334Speter	      && ! other_changed && op1 == const0_rtx
520018334Speter	      && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT
520118334Speter	      && exact_log2 (mask = nonzero_bits (op0, GET_MODE (op0))) >= 0)
520218334Speter	    {
520318334Speter	      rtx pat = PATTERN (other_insn), note = 0;
520418334Speter
520552284Sobrien	      if ((recog_for_combine (&pat, other_insn, &note) < 0
520618334Speter		   && ! check_asm_operands (pat)))
520718334Speter		{
520818334Speter		  PUT_CODE (*cc_use, old_code);
520918334Speter		  other_insn = 0;
521018334Speter
521118334Speter		  op0 = gen_binary (XOR, GET_MODE (op0), op0, GEN_INT (mask));
521218334Speter		}
521318334Speter	    }
521418334Speter
521518334Speter	  other_changed = 1;
521618334Speter	}
521718334Speter
521818334Speter      if (other_changed)
521918334Speter	undobuf.other_insn = other_insn;
522018334Speter
522118334Speter#ifdef HAVE_cc0
522218334Speter      /* If we are now comparing against zero, change our source if
522318334Speter	 needed.  If we do not use cc0, we always have a COMPARE.  */
522418334Speter      if (op1 == const0_rtx && dest == cc0_rtx)
522518334Speter	{
522618334Speter	  SUBST (SET_SRC (x), op0);
522718334Speter	  src = op0;
522818334Speter	}
522918334Speter      else
523018334Speter#endif
523118334Speter
523218334Speter      /* Otherwise, if we didn't previously have a COMPARE in the
523318334Speter	 correct mode, we need one.  */
523418334Speter      if (GET_CODE (src) != COMPARE || GET_MODE (src) != compare_mode)
523518334Speter	{
523690075Sobrien	  SUBST (SET_SRC (x), gen_rtx_COMPARE (compare_mode, op0, op1));
523718334Speter	  src = SET_SRC (x);
523818334Speter	}
523918334Speter      else
524018334Speter	{
524118334Speter	  /* Otherwise, update the COMPARE if needed.  */
524218334Speter	  SUBST (XEXP (src, 0), op0);
524318334Speter	  SUBST (XEXP (src, 1), op1);
524418334Speter	}
524518334Speter    }
524618334Speter  else
524718334Speter    {
524818334Speter      /* Get SET_SRC in a form where we have placed back any
524918334Speter	 compound expressions.  Then do the checks below.  */
525018334Speter      src = make_compound_operation (src, SET);
525118334Speter      SUBST (SET_SRC (x), src);
525218334Speter    }
525318334Speter
525418334Speter  /* If we have (set x (subreg:m1 (op:m2 ...) 0)) with OP being some operation,
525518334Speter     and X being a REG or (subreg (reg)), we may be able to convert this to
525690075Sobrien     (set (subreg:m2 x) (op)).
525718334Speter
525818334Speter     We can always do this if M1 is narrower than M2 because that means that
525918334Speter     we only care about the low bits of the result.
526018334Speter
526118334Speter     However, on machines without WORD_REGISTER_OPERATIONS defined, we cannot
526250397Sobrien     perform a narrower operation than requested since the high-order bits will
526318334Speter     be undefined.  On machine where it is defined, this transformation is safe
526418334Speter     as long as M1 and M2 have the same number of words.  */
526590075Sobrien
526618334Speter  if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)
526718334Speter      && GET_RTX_CLASS (GET_CODE (SUBREG_REG (src))) != 'o'
526818334Speter      && (((GET_MODE_SIZE (GET_MODE (src)) + (UNITS_PER_WORD - 1))
526918334Speter	   / UNITS_PER_WORD)
527018334Speter	  == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
527118334Speter	       + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
527218334Speter#ifndef WORD_REGISTER_OPERATIONS
527318334Speter      && (GET_MODE_SIZE (GET_MODE (src))
527418334Speter	  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
527518334Speter#endif
5276117395Skan#ifdef CANNOT_CHANGE_MODE_CLASS
527718334Speter      && ! (GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER
5278117395Skan	    && REG_CANNOT_CHANGE_MODE_P (REGNO (dest),
5279117395Skan					 GET_MODE (SUBREG_REG (src)),
5280117395Skan					 GET_MODE (src)))
528190075Sobrien#endif
528218334Speter      && (GET_CODE (dest) == REG
528318334Speter	  || (GET_CODE (dest) == SUBREG
528418334Speter	      && GET_CODE (SUBREG_REG (dest)) == REG)))
528518334Speter    {
528618334Speter      SUBST (SET_DEST (x),
528718334Speter	     gen_lowpart_for_combine (GET_MODE (SUBREG_REG (src)),
528818334Speter				      dest));
528918334Speter      SUBST (SET_SRC (x), SUBREG_REG (src));
529018334Speter
529118334Speter      src = SET_SRC (x), dest = SET_DEST (x);
529218334Speter    }
529318334Speter
5294117395Skan#ifdef HAVE_cc0
5295117395Skan  /* If we have (set (cc0) (subreg ...)), we try to remove the subreg
5296117395Skan     in SRC.  */
5297117395Skan  if (dest == cc0_rtx
5298117395Skan      && GET_CODE (src) == SUBREG
5299117395Skan      && subreg_lowpart_p (src)
5300117395Skan      && (GET_MODE_BITSIZE (GET_MODE (src))
5301117395Skan	  < GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (src)))))
5302117395Skan    {
5303117395Skan      rtx inner = SUBREG_REG (src);
5304117395Skan      enum machine_mode inner_mode = GET_MODE (inner);
5305117395Skan
5306117395Skan      /* Here we make sure that we don't have a sign bit on.  */
5307117395Skan      if (GET_MODE_BITSIZE (inner_mode) <= HOST_BITS_PER_WIDE_INT
5308117395Skan	  && (nonzero_bits (inner, inner_mode)
5309117395Skan	      < ((unsigned HOST_WIDE_INT) 1
5310117395Skan		 << (GET_MODE_BITSIZE (GET_MODE (src)) - 1))))
5311117395Skan	{
5312117395Skan	  SUBST (SET_SRC (x), inner);
5313117395Skan	  src = SET_SRC (x);
5314117395Skan	}
5315117395Skan    }
5316117395Skan#endif
5317117395Skan
531818334Speter#ifdef LOAD_EXTEND_OP
531918334Speter  /* If we have (set FOO (subreg:M (mem:N BAR) 0)) with M wider than N, this
532018334Speter     would require a paradoxical subreg.  Replace the subreg with a
532150397Sobrien     zero_extend to avoid the reload that would otherwise be required.  */
532218334Speter
532318334Speter  if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)
532418334Speter      && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (src))) != NIL
532590075Sobrien      && SUBREG_BYTE (src) == 0
532618334Speter      && (GET_MODE_SIZE (GET_MODE (src))
532718334Speter	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
532818334Speter      && GET_CODE (SUBREG_REG (src)) == MEM)
532918334Speter    {
533018334Speter      SUBST (SET_SRC (x),
533190075Sobrien	     gen_rtx (LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (src))),
533290075Sobrien		      GET_MODE (src), SUBREG_REG (src)));
533318334Speter
533418334Speter      src = SET_SRC (x);
533518334Speter    }
533618334Speter#endif
533718334Speter
533818334Speter  /* If we don't have a conditional move, SET_SRC is an IF_THEN_ELSE, and we
533918334Speter     are comparing an item known to be 0 or -1 against 0, use a logical
534018334Speter     operation instead. Check for one of the arms being an IOR of the other
534118334Speter     arm with some value.  We compute three terms to be IOR'ed together.  In
534218334Speter     practice, at most two will be nonzero.  Then we do the IOR's.  */
534318334Speter
534418334Speter  if (GET_CODE (dest) != PC
534518334Speter      && GET_CODE (src) == IF_THEN_ELSE
534618334Speter      && GET_MODE_CLASS (GET_MODE (src)) == MODE_INT
534718334Speter      && (GET_CODE (XEXP (src, 0)) == EQ || GET_CODE (XEXP (src, 0)) == NE)
534818334Speter      && XEXP (XEXP (src, 0), 1) == const0_rtx
534918334Speter      && GET_MODE (src) == GET_MODE (XEXP (XEXP (src, 0), 0))
535018334Speter#ifdef HAVE_conditional_move
535118334Speter      && ! can_conditionally_move_p (GET_MODE (src))
535218334Speter#endif
535318334Speter      && (num_sign_bit_copies (XEXP (XEXP (src, 0), 0),
535418334Speter			       GET_MODE (XEXP (XEXP (src, 0), 0)))
535518334Speter	  == GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (src, 0), 0))))
535618334Speter      && ! side_effects_p (src))
535718334Speter    {
535890075Sobrien      rtx true_rtx = (GET_CODE (XEXP (src, 0)) == NE
535918334Speter		      ? XEXP (src, 1) : XEXP (src, 2));
536090075Sobrien      rtx false_rtx = (GET_CODE (XEXP (src, 0)) == NE
536118334Speter		   ? XEXP (src, 2) : XEXP (src, 1));
536218334Speter      rtx term1 = const0_rtx, term2, term3;
536318334Speter
536490075Sobrien      if (GET_CODE (true_rtx) == IOR
536590075Sobrien	  && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
536690075Sobrien	term1 = false_rtx, true_rtx = XEXP(true_rtx, 1), false_rtx = const0_rtx;
536790075Sobrien      else if (GET_CODE (true_rtx) == IOR
536890075Sobrien	       && rtx_equal_p (XEXP (true_rtx, 1), false_rtx))
536990075Sobrien	term1 = false_rtx, true_rtx = XEXP(true_rtx, 0), false_rtx = const0_rtx;
537090075Sobrien      else if (GET_CODE (false_rtx) == IOR
537190075Sobrien	       && rtx_equal_p (XEXP (false_rtx, 0), true_rtx))
537290075Sobrien	term1 = true_rtx, false_rtx = XEXP(false_rtx, 1), true_rtx = const0_rtx;
537390075Sobrien      else if (GET_CODE (false_rtx) == IOR
537490075Sobrien	       && rtx_equal_p (XEXP (false_rtx, 1), true_rtx))
537590075Sobrien	term1 = true_rtx, false_rtx = XEXP(false_rtx, 0), true_rtx = const0_rtx;
537618334Speter
537790075Sobrien      term2 = gen_binary (AND, GET_MODE (src),
537890075Sobrien			  XEXP (XEXP (src, 0), 0), true_rtx);
537918334Speter      term3 = gen_binary (AND, GET_MODE (src),
538090075Sobrien			  simplify_gen_unary (NOT, GET_MODE (src),
538190075Sobrien					      XEXP (XEXP (src, 0), 0),
538290075Sobrien					      GET_MODE (src)),
538390075Sobrien			  false_rtx);
538418334Speter
538518334Speter      SUBST (SET_SRC (x),
538618334Speter	     gen_binary (IOR, GET_MODE (src),
538718334Speter			 gen_binary (IOR, GET_MODE (src), term1, term2),
538818334Speter			 term3));
538918334Speter
539018334Speter      src = SET_SRC (x);
539118334Speter    }
539218334Speter
539318334Speter  /* If either SRC or DEST is a CLOBBER of (const_int 0), make this
539418334Speter     whole thing fail.  */
539518334Speter  if (GET_CODE (src) == CLOBBER && XEXP (src, 0) == const0_rtx)
539618334Speter    return src;
539718334Speter  else if (GET_CODE (dest) == CLOBBER && XEXP (dest, 0) == const0_rtx)
539818334Speter    return dest;
539918334Speter  else
540018334Speter    /* Convert this into a field assignment operation, if possible.  */
540118334Speter    return make_field_assignment (x);
540218334Speter}
540318334Speter
540418334Speter/* Simplify, X, and AND, IOR, or XOR operation, and return the simplified
540518334Speter   result.  LAST is nonzero if this is the last retry.  */
540618334Speter
540718334Speterstatic rtx
540818334Spetersimplify_logical (x, last)
540918334Speter     rtx x;
541018334Speter     int last;
541118334Speter{
541218334Speter  enum machine_mode mode = GET_MODE (x);
541318334Speter  rtx op0 = XEXP (x, 0);
541418334Speter  rtx op1 = XEXP (x, 1);
541590075Sobrien  rtx reversed;
541618334Speter
541718334Speter  switch (GET_CODE (x))
541818334Speter    {
541918334Speter    case AND:
542090075Sobrien      /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
542118334Speter	 insn (and may simplify more).  */
542218334Speter      if (GET_CODE (op0) == XOR
542318334Speter	  && rtx_equal_p (XEXP (op0, 0), op1)
542418334Speter	  && ! side_effects_p (op1))
542518334Speter	x = gen_binary (AND, mode,
542690075Sobrien			simplify_gen_unary (NOT, mode, XEXP (op0, 1), mode),
542790075Sobrien			op1);
542818334Speter
542918334Speter      if (GET_CODE (op0) == XOR
543018334Speter	  && rtx_equal_p (XEXP (op0, 1), op1)
543118334Speter	  && ! side_effects_p (op1))
543218334Speter	x = gen_binary (AND, mode,
543390075Sobrien			simplify_gen_unary (NOT, mode, XEXP (op0, 0), mode),
543490075Sobrien			op1);
543518334Speter
543690075Sobrien      /* Similarly for (~(A ^ B)) & A.  */
543718334Speter      if (GET_CODE (op0) == NOT
543818334Speter	  && GET_CODE (XEXP (op0, 0)) == XOR
543918334Speter	  && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
544018334Speter	  && ! side_effects_p (op1))
544118334Speter	x = gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
544218334Speter
544318334Speter      if (GET_CODE (op0) == NOT
544418334Speter	  && GET_CODE (XEXP (op0, 0)) == XOR
544518334Speter	  && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
544618334Speter	  && ! side_effects_p (op1))
544718334Speter	x = gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
544818334Speter
544990075Sobrien      /* We can call simplify_and_const_int only if we don't lose
545090075Sobrien	 any (sign) bits when converting INTVAL (op1) to
545190075Sobrien	 "unsigned HOST_WIDE_INT".  */
545290075Sobrien      if (GET_CODE (op1) == CONST_INT
545390075Sobrien	  && (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
545490075Sobrien	      || INTVAL (op1) > 0))
545518334Speter	{
545618334Speter	  x = simplify_and_const_int (x, mode, op0, INTVAL (op1));
545718334Speter
545818334Speter	  /* If we have (ior (and (X C1) C2)) and the next restart would be
545918334Speter	     the last, simplify this by making C1 as small as possible
546050397Sobrien	     and then exit.  */
546118334Speter	  if (last
546218334Speter	      && GET_CODE (x) == IOR && GET_CODE (op0) == AND
546318334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
546418334Speter	      && GET_CODE (op1) == CONST_INT)
546518334Speter	    return gen_binary (IOR, mode,
546618334Speter			       gen_binary (AND, mode, XEXP (op0, 0),
546718334Speter					   GEN_INT (INTVAL (XEXP (op0, 1))
546890075Sobrien						    & ~INTVAL (op1))), op1);
546918334Speter
547018334Speter	  if (GET_CODE (x) != AND)
547118334Speter	    return x;
547218334Speter
547390075Sobrien	  if (GET_RTX_CLASS (GET_CODE (x)) == 'c'
547418334Speter	      || GET_RTX_CLASS (GET_CODE (x)) == '2')
547518334Speter	    op0 = XEXP (x, 0), op1 = XEXP (x, 1);
547618334Speter	}
547718334Speter
547818334Speter      /* Convert (A | B) & A to A.  */
547918334Speter      if (GET_CODE (op0) == IOR
548018334Speter	  && (rtx_equal_p (XEXP (op0, 0), op1)
548118334Speter	      || rtx_equal_p (XEXP (op0, 1), op1))
548218334Speter	  && ! side_effects_p (XEXP (op0, 0))
548318334Speter	  && ! side_effects_p (XEXP (op0, 1)))
548418334Speter	return op1;
548518334Speter
548618334Speter      /* In the following group of tests (and those in case IOR below),
548718334Speter	 we start with some combination of logical operations and apply
548818334Speter	 the distributive law followed by the inverse distributive law.
548918334Speter	 Most of the time, this results in no change.  However, if some of
549018334Speter	 the operands are the same or inverses of each other, simplifications
549118334Speter	 will result.
549218334Speter
549318334Speter	 For example, (and (ior A B) (not B)) can occur as the result of
549418334Speter	 expanding a bit field assignment.  When we apply the distributive
549518334Speter	 law to this, we get (ior (and (A (not B))) (and (B (not B)))),
549690075Sobrien	 which then simplifies to (and (A (not B))).
549718334Speter
549818334Speter	 If we have (and (ior A B) C), apply the distributive law and then
549918334Speter	 the inverse distributive law to see if things simplify.  */
550018334Speter
550118334Speter      if (GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
550218334Speter	{
550318334Speter	  x = apply_distributive_law
550418334Speter	    (gen_binary (GET_CODE (op0), mode,
550518334Speter			 gen_binary (AND, mode, XEXP (op0, 0), op1),
550670635Sobrien			 gen_binary (AND, mode, XEXP (op0, 1),
550770635Sobrien				     copy_rtx (op1))));
550818334Speter	  if (GET_CODE (x) != AND)
550918334Speter	    return x;
551018334Speter	}
551118334Speter
551218334Speter      if (GET_CODE (op1) == IOR || GET_CODE (op1) == XOR)
551318334Speter	return apply_distributive_law
551418334Speter	  (gen_binary (GET_CODE (op1), mode,
551518334Speter		       gen_binary (AND, mode, XEXP (op1, 0), op0),
551670635Sobrien		       gen_binary (AND, mode, XEXP (op1, 1),
551770635Sobrien				   copy_rtx (op0))));
551818334Speter
551918334Speter      /* Similarly, taking advantage of the fact that
552018334Speter	 (and (not A) (xor B C)) == (xor (ior A B) (ior A C))  */
552118334Speter
552218334Speter      if (GET_CODE (op0) == NOT && GET_CODE (op1) == XOR)
552318334Speter	return apply_distributive_law
552418334Speter	  (gen_binary (XOR, mode,
552518334Speter		       gen_binary (IOR, mode, XEXP (op0, 0), XEXP (op1, 0)),
552670635Sobrien		       gen_binary (IOR, mode, copy_rtx (XEXP (op0, 0)),
552770635Sobrien				   XEXP (op1, 1))));
552890075Sobrien
552918334Speter      else if (GET_CODE (op1) == NOT && GET_CODE (op0) == XOR)
553018334Speter	return apply_distributive_law
553118334Speter	  (gen_binary (XOR, mode,
553218334Speter		       gen_binary (IOR, mode, XEXP (op1, 0), XEXP (op0, 0)),
553370635Sobrien		       gen_binary (IOR, mode, copy_rtx (XEXP (op1, 0)), XEXP (op0, 1))));
553418334Speter      break;
553518334Speter
553618334Speter    case IOR:
553718334Speter      /* (ior A C) is C if all bits of A that might be nonzero are on in C.  */
553818334Speter      if (GET_CODE (op1) == CONST_INT
553918334Speter	  && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
554090075Sobrien	  && (nonzero_bits (op0, mode) & ~INTVAL (op1)) == 0)
554118334Speter	return op1;
554218334Speter
554318334Speter      /* Convert (A & B) | A to A.  */
554418334Speter      if (GET_CODE (op0) == AND
554518334Speter	  && (rtx_equal_p (XEXP (op0, 0), op1)
554618334Speter	      || rtx_equal_p (XEXP (op0, 1), op1))
554718334Speter	  && ! side_effects_p (XEXP (op0, 0))
554818334Speter	  && ! side_effects_p (XEXP (op0, 1)))
554918334Speter	return op1;
555018334Speter
555118334Speter      /* If we have (ior (and A B) C), apply the distributive law and then
555218334Speter	 the inverse distributive law to see if things simplify.  */
555318334Speter
555418334Speter      if (GET_CODE (op0) == AND)
555518334Speter	{
555618334Speter	  x = apply_distributive_law
555718334Speter	    (gen_binary (AND, mode,
555818334Speter			 gen_binary (IOR, mode, XEXP (op0, 0), op1),
555970635Sobrien			 gen_binary (IOR, mode, XEXP (op0, 1),
556070635Sobrien				     copy_rtx (op1))));
556118334Speter
556218334Speter	  if (GET_CODE (x) != IOR)
556318334Speter	    return x;
556418334Speter	}
556518334Speter
556618334Speter      if (GET_CODE (op1) == AND)
556718334Speter	{
556818334Speter	  x = apply_distributive_law
556918334Speter	    (gen_binary (AND, mode,
557018334Speter			 gen_binary (IOR, mode, XEXP (op1, 0), op0),
557170635Sobrien			 gen_binary (IOR, mode, XEXP (op1, 1),
557270635Sobrien				     copy_rtx (op0))));
557318334Speter
557418334Speter	  if (GET_CODE (x) != IOR)
557518334Speter	    return x;
557618334Speter	}
557718334Speter
557818334Speter      /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
557918334Speter	 mode size to (rotate A CX).  */
558018334Speter
558118334Speter      if (((GET_CODE (op0) == ASHIFT && GET_CODE (op1) == LSHIFTRT)
558218334Speter	   || (GET_CODE (op1) == ASHIFT && GET_CODE (op0) == LSHIFTRT))
558318334Speter	  && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
558418334Speter	  && GET_CODE (XEXP (op0, 1)) == CONST_INT
558518334Speter	  && GET_CODE (XEXP (op1, 1)) == CONST_INT
558618334Speter	  && (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1))
558718334Speter	      == GET_MODE_BITSIZE (mode)))
558850397Sobrien	return gen_rtx_ROTATE (mode, XEXP (op0, 0),
558950397Sobrien			       (GET_CODE (op0) == ASHIFT
559050397Sobrien				? XEXP (op0, 1) : XEXP (op1, 1)));
559118334Speter
559218334Speter      /* If OP0 is (ashiftrt (plus ...) C), it might actually be
559318334Speter	 a (sign_extend (plus ...)).  If so, OP1 is a CONST_INT, and the PLUS
559418334Speter	 does not affect any of the bits in OP1, it can really be done
559518334Speter	 as a PLUS and we can associate.  We do this by seeing if OP1
559618334Speter	 can be safely shifted left C bits.  */
559718334Speter      if (GET_CODE (op1) == CONST_INT && GET_CODE (op0) == ASHIFTRT
559818334Speter	  && GET_CODE (XEXP (op0, 0)) == PLUS
559918334Speter	  && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
560018334Speter	  && GET_CODE (XEXP (op0, 1)) == CONST_INT
560118334Speter	  && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
560218334Speter	{
560318334Speter	  int count = INTVAL (XEXP (op0, 1));
560418334Speter	  HOST_WIDE_INT mask = INTVAL (op1) << count;
560518334Speter
560618334Speter	  if (mask >> count == INTVAL (op1)
560718334Speter	      && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
560818334Speter	    {
560918334Speter	      SUBST (XEXP (XEXP (op0, 0), 1),
561018334Speter		     GEN_INT (INTVAL (XEXP (XEXP (op0, 0), 1)) | mask));
561118334Speter	      return op0;
561218334Speter	    }
561318334Speter	}
561418334Speter      break;
561518334Speter
561618334Speter    case XOR:
561790075Sobrien      /* If we are XORing two things that have no bits in common,
561890075Sobrien	 convert them into an IOR.  This helps to detect rotation encoded
561990075Sobrien	 using those methods and possibly other simplifications.  */
562090075Sobrien
562190075Sobrien      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
562290075Sobrien	  && (nonzero_bits (op0, mode)
562390075Sobrien	      & nonzero_bits (op1, mode)) == 0)
562490075Sobrien	return (gen_binary (IOR, mode, op0, op1));
562590075Sobrien
562618334Speter      /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
562718334Speter	 Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
562818334Speter	 (NOT y).  */
562918334Speter      {
563018334Speter	int num_negated = 0;
563118334Speter
563218334Speter	if (GET_CODE (op0) == NOT)
563318334Speter	  num_negated++, op0 = XEXP (op0, 0);
563418334Speter	if (GET_CODE (op1) == NOT)
563518334Speter	  num_negated++, op1 = XEXP (op1, 0);
563618334Speter
563718334Speter	if (num_negated == 2)
563818334Speter	  {
563918334Speter	    SUBST (XEXP (x, 0), op0);
564018334Speter	    SUBST (XEXP (x, 1), op1);
564118334Speter	  }
564218334Speter	else if (num_negated == 1)
564390075Sobrien	  return
564490075Sobrien	    simplify_gen_unary (NOT, mode, gen_binary (XOR, mode, op0, op1),
564590075Sobrien				mode);
564618334Speter      }
564718334Speter
564818334Speter      /* Convert (xor (and A B) B) to (and (not A) B).  The latter may
564918334Speter	 correspond to a machine insn or result in further simplifications
565018334Speter	 if B is a constant.  */
565118334Speter
565218334Speter      if (GET_CODE (op0) == AND
565318334Speter	  && rtx_equal_p (XEXP (op0, 1), op1)
565418334Speter	  && ! side_effects_p (op1))
565518334Speter	return gen_binary (AND, mode,
565690075Sobrien			   simplify_gen_unary (NOT, mode, XEXP (op0, 0), mode),
565718334Speter			   op1);
565818334Speter
565918334Speter      else if (GET_CODE (op0) == AND
566018334Speter	       && rtx_equal_p (XEXP (op0, 0), op1)
566118334Speter	       && ! side_effects_p (op1))
566218334Speter	return gen_binary (AND, mode,
566390075Sobrien			   simplify_gen_unary (NOT, mode, XEXP (op0, 1), mode),
566418334Speter			   op1);
566518334Speter
566618334Speter      /* (xor (comparison foo bar) (const_int 1)) can become the reversed
566750397Sobrien	 comparison if STORE_FLAG_VALUE is 1.  */
566850397Sobrien      if (STORE_FLAG_VALUE == 1
566950397Sobrien	  && op1 == const1_rtx
567018334Speter	  && GET_RTX_CLASS (GET_CODE (op0)) == '<'
567190075Sobrien	  && (reversed = reversed_comparison (op0, mode, XEXP (op0, 0),
567290075Sobrien					      XEXP (op0, 1))))
567390075Sobrien	return reversed;
567418334Speter
567518334Speter      /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
567618334Speter	 is (lt foo (const_int 0)), so we can perform the above
567750397Sobrien	 simplification if STORE_FLAG_VALUE is 1.  */
567818334Speter
567950397Sobrien      if (STORE_FLAG_VALUE == 1
568050397Sobrien	  && op1 == const1_rtx
568118334Speter	  && GET_CODE (op0) == LSHIFTRT
568218334Speter	  && GET_CODE (XEXP (op0, 1)) == CONST_INT
568318334Speter	  && INTVAL (XEXP (op0, 1)) == GET_MODE_BITSIZE (mode) - 1)
568490075Sobrien	return gen_rtx_GE (mode, XEXP (op0, 0), const0_rtx);
568518334Speter
568618334Speter      /* (xor (comparison foo bar) (const_int sign-bit))
568718334Speter	 when STORE_FLAG_VALUE is the sign bit.  */
568818334Speter      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
568950397Sobrien	  && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
569052284Sobrien	      == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))
569118334Speter	  && op1 == const_true_rtx
569218334Speter	  && GET_RTX_CLASS (GET_CODE (op0)) == '<'
569390075Sobrien	  && (reversed = reversed_comparison (op0, mode, XEXP (op0, 0),
569490075Sobrien					      XEXP (op0, 1))))
569590075Sobrien	return reversed;
569690075Sobrien
569718334Speter      break;
569850397Sobrien
569950397Sobrien    default:
570050397Sobrien      abort ();
570118334Speter    }
570218334Speter
570318334Speter  return x;
570418334Speter}
570518334Speter
570618334Speter/* We consider ZERO_EXTRACT, SIGN_EXTRACT, and SIGN_EXTEND as "compound
570718334Speter   operations" because they can be replaced with two more basic operations.
570818334Speter   ZERO_EXTEND is also considered "compound" because it can be replaced with
570918334Speter   an AND operation, which is simpler, though only one operation.
571018334Speter
571118334Speter   The function expand_compound_operation is called with an rtx expression
571290075Sobrien   and will convert it to the appropriate shifts and AND operations,
571318334Speter   simplifying at each stage.
571418334Speter
571518334Speter   The function make_compound_operation is called to convert an expression
571618334Speter   consisting of shifts and ANDs into the equivalent compound expression.
571718334Speter   It is the inverse of this function, loosely speaking.  */
571818334Speter
571918334Speterstatic rtx
572018334Speterexpand_compound_operation (x)
572118334Speter     rtx x;
572218334Speter{
572390075Sobrien  unsigned HOST_WIDE_INT pos = 0, len;
572418334Speter  int unsignedp = 0;
572590075Sobrien  unsigned int modewidth;
572618334Speter  rtx tem;
572718334Speter
572818334Speter  switch (GET_CODE (x))
572918334Speter    {
573018334Speter    case ZERO_EXTEND:
573118334Speter      unsignedp = 1;
573218334Speter    case SIGN_EXTEND:
573318334Speter      /* We can't necessarily use a const_int for a multiword mode;
573418334Speter	 it depends on implicitly extending the value.
573518334Speter	 Since we don't know the right way to extend it,
573618334Speter	 we can't tell whether the implicit way is right.
573718334Speter
573818334Speter	 Even for a mode that is no wider than a const_int,
573918334Speter	 we can't win, because we need to sign extend one of its bits through
574018334Speter	 the rest of it, and we don't know which bit.  */
574118334Speter      if (GET_CODE (XEXP (x, 0)) == CONST_INT)
574218334Speter	return x;
574318334Speter
574418334Speter      /* Return if (subreg:MODE FROM 0) is not a safe replacement for
574518334Speter	 (zero_extend:MODE FROM) or (sign_extend:MODE FROM).  It is for any MEM
574618334Speter	 because (SUBREG (MEM...)) is guaranteed to cause the MEM to be
574718334Speter	 reloaded. If not for that, MEM's would very rarely be safe.
574818334Speter
574918334Speter	 Reject MODEs bigger than a word, because we might not be able
575018334Speter	 to reference a two-register group starting with an arbitrary register
575118334Speter	 (and currently gen_lowpart might crash for a SUBREG).  */
575290075Sobrien
575318334Speter      if (GET_MODE_SIZE (GET_MODE (XEXP (x, 0))) > UNITS_PER_WORD)
575418334Speter	return x;
575518334Speter
5756117395Skan      /* Reject MODEs that aren't scalar integers because turning vector
5757117395Skan	 or complex modes into shifts causes problems.  */
5758117395Skan
5759117395Skan      if (! SCALAR_INT_MODE_P (GET_MODE (XEXP (x, 0))))
5760117395Skan	return x;
5761117395Skan
576218334Speter      len = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)));
576318334Speter      /* If the inner object has VOIDmode (the only way this can happen
5764117395Skan	 is if it is an ASM_OPERANDS), we can't do anything since we don't
576518334Speter	 know how much masking to do.  */
576618334Speter      if (len == 0)
576718334Speter	return x;
576818334Speter
576918334Speter      break;
577018334Speter
577118334Speter    case ZERO_EXTRACT:
577218334Speter      unsignedp = 1;
577318334Speter    case SIGN_EXTRACT:
577418334Speter      /* If the operand is a CLOBBER, just return it.  */
577518334Speter      if (GET_CODE (XEXP (x, 0)) == CLOBBER)
577618334Speter	return XEXP (x, 0);
577718334Speter
577818334Speter      if (GET_CODE (XEXP (x, 1)) != CONST_INT
577918334Speter	  || GET_CODE (XEXP (x, 2)) != CONST_INT
578018334Speter	  || GET_MODE (XEXP (x, 0)) == VOIDmode)
578118334Speter	return x;
578218334Speter
5783117395Skan      /* Reject MODEs that aren't scalar integers because turning vector
5784117395Skan	 or complex modes into shifts causes problems.  */
5785117395Skan
5786117395Skan      if (! SCALAR_INT_MODE_P (GET_MODE (XEXP (x, 0))))
5787117395Skan	return x;
5788117395Skan
578918334Speter      len = INTVAL (XEXP (x, 1));
579018334Speter      pos = INTVAL (XEXP (x, 2));
579118334Speter
579218334Speter      /* If this goes outside the object being extracted, replace the object
579318334Speter	 with a (use (mem ...)) construct that only combine understands
579418334Speter	 and is used only for this purpose.  */
579518334Speter      if (len + pos > GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))))
579650397Sobrien	SUBST (XEXP (x, 0), gen_rtx_USE (GET_MODE (x), XEXP (x, 0)));
579718334Speter
579818334Speter      if (BITS_BIG_ENDIAN)
579918334Speter	pos = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - len - pos;
580018334Speter
580118334Speter      break;
580218334Speter
580318334Speter    default:
580418334Speter      return x;
580518334Speter    }
580690075Sobrien  /* Convert sign extension to zero extension, if we know that the high
580790075Sobrien     bit is not set, as this is easier to optimize.  It will be converted
580890075Sobrien     back to cheaper alternative in make_extraction.  */
580990075Sobrien  if (GET_CODE (x) == SIGN_EXTEND
581090075Sobrien      && (GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
581190075Sobrien	  && ((nonzero_bits (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
581290075Sobrien		& ~(((unsigned HOST_WIDE_INT)
581390075Sobrien		      GET_MODE_MASK (GET_MODE (XEXP (x, 0))))
581490075Sobrien		     >> 1))
581590075Sobrien	       == 0)))
581690075Sobrien    {
581790075Sobrien      rtx temp = gen_rtx_ZERO_EXTEND (GET_MODE (x), XEXP (x, 0));
581890075Sobrien      return expand_compound_operation (temp);
581990075Sobrien    }
582018334Speter
582150397Sobrien  /* We can optimize some special cases of ZERO_EXTEND.  */
582250397Sobrien  if (GET_CODE (x) == ZERO_EXTEND)
582350397Sobrien    {
582450397Sobrien      /* (zero_extend:DI (truncate:SI foo:DI)) is just foo:DI if we
582550397Sobrien         know that the last value didn't have any inappropriate bits
582650397Sobrien         set.  */
582750397Sobrien      if (GET_CODE (XEXP (x, 0)) == TRUNCATE
582850397Sobrien	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == GET_MODE (x)
582950397Sobrien	  && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
583050397Sobrien	  && (nonzero_bits (XEXP (XEXP (x, 0), 0), GET_MODE (x))
583190075Sobrien	      & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
583250397Sobrien	return XEXP (XEXP (x, 0), 0);
583350397Sobrien
583450397Sobrien      /* Likewise for (zero_extend:DI (subreg:SI foo:DI 0)).  */
583550397Sobrien      if (GET_CODE (XEXP (x, 0)) == SUBREG
583650397Sobrien	  && GET_MODE (SUBREG_REG (XEXP (x, 0))) == GET_MODE (x)
583750397Sobrien	  && subreg_lowpart_p (XEXP (x, 0))
583850397Sobrien	  && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
583950397Sobrien	  && (nonzero_bits (SUBREG_REG (XEXP (x, 0)), GET_MODE (x))
584090075Sobrien	      & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
584150397Sobrien	return SUBREG_REG (XEXP (x, 0));
584250397Sobrien
584350397Sobrien      /* (zero_extend:DI (truncate:SI foo:DI)) is just foo:DI when foo
584450397Sobrien         is a comparison and STORE_FLAG_VALUE permits.  This is like
584550397Sobrien         the first case, but it works even when GET_MODE (x) is larger
584650397Sobrien         than HOST_WIDE_INT.  */
584750397Sobrien      if (GET_CODE (XEXP (x, 0)) == TRUNCATE
584850397Sobrien	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == GET_MODE (x)
584950397Sobrien	  && GET_RTX_CLASS (GET_CODE (XEXP (XEXP (x, 0), 0))) == '<'
585050397Sobrien	  && (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
585150397Sobrien	      <= HOST_BITS_PER_WIDE_INT)
585290075Sobrien	  && ((HOST_WIDE_INT) STORE_FLAG_VALUE
585390075Sobrien	      & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
585450397Sobrien	return XEXP (XEXP (x, 0), 0);
585550397Sobrien
585650397Sobrien      /* Likewise for (zero_extend:DI (subreg:SI foo:DI 0)).  */
585750397Sobrien      if (GET_CODE (XEXP (x, 0)) == SUBREG
585850397Sobrien	  && GET_MODE (SUBREG_REG (XEXP (x, 0))) == GET_MODE (x)
585950397Sobrien	  && subreg_lowpart_p (XEXP (x, 0))
586050397Sobrien	  && GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0)))) == '<'
586150397Sobrien	  && (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
586250397Sobrien	      <= HOST_BITS_PER_WIDE_INT)
586350397Sobrien	  && ((HOST_WIDE_INT) STORE_FLAG_VALUE
586490075Sobrien	      & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
586550397Sobrien	return SUBREG_REG (XEXP (x, 0));
586650397Sobrien
586750397Sobrien    }
586850397Sobrien
586918334Speter  /* If we reach here, we want to return a pair of shifts.  The inner
587018334Speter     shift is a left shift of BITSIZE - POS - LEN bits.  The outer
587118334Speter     shift is a right shift of BITSIZE - LEN bits.  It is arithmetic or
587218334Speter     logical depending on the value of UNSIGNEDP.
587318334Speter
587418334Speter     If this was a ZERO_EXTEND or ZERO_EXTRACT, this pair of shifts will be
587518334Speter     converted into an AND of a shift.
587618334Speter
587718334Speter     We must check for the case where the left shift would have a negative
587818334Speter     count.  This can happen in a case like (x >> 31) & 255 on machines
587918334Speter     that can't shift by a constant.  On those machines, we would first
588090075Sobrien     combine the shift with the AND to produce a variable-position
588118334Speter     extraction.  Then the constant of 31 would be substituted in to produce
588218334Speter     a such a position.  */
588318334Speter
588418334Speter  modewidth = GET_MODE_BITSIZE (GET_MODE (x));
588590075Sobrien  if (modewidth + len >= pos)
588618334Speter    tem = simplify_shift_const (NULL_RTX, unsignedp ? LSHIFTRT : ASHIFTRT,
588718334Speter				GET_MODE (x),
588818334Speter				simplify_shift_const (NULL_RTX, ASHIFT,
588918334Speter						      GET_MODE (x),
589018334Speter						      XEXP (x, 0),
589118334Speter						      modewidth - pos - len),
589218334Speter				modewidth - len);
589318334Speter
589418334Speter  else if (unsignedp && len < HOST_BITS_PER_WIDE_INT)
589518334Speter    tem = simplify_and_const_int (NULL_RTX, GET_MODE (x),
589618334Speter				  simplify_shift_const (NULL_RTX, LSHIFTRT,
589718334Speter							GET_MODE (x),
589818334Speter							XEXP (x, 0), pos),
589918334Speter				  ((HOST_WIDE_INT) 1 << len) - 1);
590018334Speter  else
590118334Speter    /* Any other cases we can't handle.  */
590218334Speter    return x;
590318334Speter
590418334Speter  /* If we couldn't do this for some reason, return the original
590518334Speter     expression.  */
590618334Speter  if (GET_CODE (tem) == CLOBBER)
590718334Speter    return x;
590818334Speter
590918334Speter  return tem;
591018334Speter}
591118334Speter
591218334Speter/* X is a SET which contains an assignment of one object into
591318334Speter   a part of another (such as a bit-field assignment, STRICT_LOW_PART,
591418334Speter   or certain SUBREGS). If possible, convert it into a series of
591518334Speter   logical operations.
591618334Speter
591718334Speter   We half-heartedly support variable positions, but do not at all
591818334Speter   support variable lengths.  */
591918334Speter
592018334Speterstatic rtx
592118334Speterexpand_field_assignment (x)
592218334Speter     rtx x;
592318334Speter{
592418334Speter  rtx inner;
592550397Sobrien  rtx pos;			/* Always counts from low bit.  */
592618334Speter  int len;
592718334Speter  rtx mask;
592818334Speter  enum machine_mode compute_mode;
592918334Speter
593018334Speter  /* Loop until we find something we can't simplify.  */
593118334Speter  while (1)
593218334Speter    {
593318334Speter      if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART
593418334Speter	  && GET_CODE (XEXP (SET_DEST (x), 0)) == SUBREG)
593518334Speter	{
593618334Speter	  inner = SUBREG_REG (XEXP (SET_DEST (x), 0));
593718334Speter	  len = GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0)));
593890075Sobrien	  pos = GEN_INT (subreg_lsb (XEXP (SET_DEST (x), 0)));
593918334Speter	}
594018334Speter      else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
594118334Speter	       && GET_CODE (XEXP (SET_DEST (x), 1)) == CONST_INT)
594218334Speter	{
594318334Speter	  inner = XEXP (SET_DEST (x), 0);
594418334Speter	  len = INTVAL (XEXP (SET_DEST (x), 1));
594518334Speter	  pos = XEXP (SET_DEST (x), 2);
594618334Speter
594718334Speter	  /* If the position is constant and spans the width of INNER,
594818334Speter	     surround INNER  with a USE to indicate this.  */
594918334Speter	  if (GET_CODE (pos) == CONST_INT
595018334Speter	      && INTVAL (pos) + len > GET_MODE_BITSIZE (GET_MODE (inner)))
595150397Sobrien	    inner = gen_rtx_USE (GET_MODE (SET_DEST (x)), inner);
595218334Speter
595318334Speter	  if (BITS_BIG_ENDIAN)
595418334Speter	    {
595518334Speter	      if (GET_CODE (pos) == CONST_INT)
595618334Speter		pos = GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner)) - len
595718334Speter			       - INTVAL (pos));
595818334Speter	      else if (GET_CODE (pos) == MINUS
595918334Speter		       && GET_CODE (XEXP (pos, 1)) == CONST_INT
596018334Speter		       && (INTVAL (XEXP (pos, 1))
596118334Speter			   == GET_MODE_BITSIZE (GET_MODE (inner)) - len))
596218334Speter		/* If position is ADJUST - X, new position is X.  */
596318334Speter		pos = XEXP (pos, 0);
596418334Speter	      else
596518334Speter		pos = gen_binary (MINUS, GET_MODE (pos),
596618334Speter				  GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner))
596718334Speter					   - len),
596818334Speter				  pos);
596918334Speter	    }
597018334Speter	}
597118334Speter
597218334Speter      /* A SUBREG between two modes that occupy the same numbers of words
597318334Speter	 can be done by moving the SUBREG to the source.  */
597418334Speter      else if (GET_CODE (SET_DEST (x)) == SUBREG
597590075Sobrien	       /* We need SUBREGs to compute nonzero_bits properly.  */
597690075Sobrien	       && nonzero_sign_valid
597718334Speter	       && (((GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
597818334Speter		     + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
597918334Speter		   == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x))))
598018334Speter			+ (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
598118334Speter	{
598250397Sobrien	  x = gen_rtx_SET (VOIDmode, SUBREG_REG (SET_DEST (x)),
598390075Sobrien			   gen_lowpart_for_combine
598490075Sobrien			   (GET_MODE (SUBREG_REG (SET_DEST (x))),
598590075Sobrien			    SET_SRC (x)));
598618334Speter	  continue;
598718334Speter	}
598818334Speter      else
598918334Speter	break;
599018334Speter
599118334Speter      while (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner))
599218334Speter	inner = SUBREG_REG (inner);
599318334Speter
599418334Speter      compute_mode = GET_MODE (inner);
599518334Speter
5996117395Skan      /* Don't attempt bitwise arithmetic on non scalar integer modes.  */
5997117395Skan      if (! SCALAR_INT_MODE_P (compute_mode))
599852284Sobrien	{
599952284Sobrien	  enum machine_mode imode;
600052284Sobrien
6001117395Skan	  /* Don't do anything for vector or complex integral types.  */
600252284Sobrien	  if (! FLOAT_MODE_P (compute_mode))
600352284Sobrien	    break;
600452284Sobrien
600552284Sobrien	  /* Try to find an integral mode to pun with.  */
600652284Sobrien	  imode = mode_for_size (GET_MODE_BITSIZE (compute_mode), MODE_INT, 0);
600752284Sobrien	  if (imode == BLKmode)
600852284Sobrien	    break;
600952284Sobrien
601052284Sobrien	  compute_mode = imode;
601152284Sobrien	  inner = gen_lowpart_for_combine (imode, inner);
601252284Sobrien	}
601352284Sobrien
601418334Speter      /* Compute a mask of LEN bits, if we can do this on the host machine.  */
601518334Speter      if (len < HOST_BITS_PER_WIDE_INT)
601618334Speter	mask = GEN_INT (((HOST_WIDE_INT) 1 << len) - 1);
601718334Speter      else
601818334Speter	break;
601918334Speter
602018334Speter      /* Now compute the equivalent expression.  Make a copy of INNER
602118334Speter	 for the SET_DEST in case it is a MEM into which we will substitute;
602218334Speter	 we don't want shared RTL in that case.  */
602390075Sobrien      x = gen_rtx_SET
602490075Sobrien	(VOIDmode, copy_rtx (inner),
602590075Sobrien	 gen_binary (IOR, compute_mode,
602690075Sobrien		     gen_binary (AND, compute_mode,
602790075Sobrien				 simplify_gen_unary (NOT, compute_mode,
602890075Sobrien						     gen_binary (ASHIFT,
602990075Sobrien								 compute_mode,
603090075Sobrien								 mask, pos),
603190075Sobrien						     compute_mode),
603290075Sobrien				 inner),
603390075Sobrien		     gen_binary (ASHIFT, compute_mode,
603490075Sobrien				 gen_binary (AND, compute_mode,
603590075Sobrien					     gen_lowpart_for_combine
603690075Sobrien					     (compute_mode, SET_SRC (x)),
603790075Sobrien					     mask),
603890075Sobrien				 pos)));
603918334Speter    }
604018334Speter
604118334Speter  return x;
604218334Speter}
604318334Speter
604418334Speter/* Return an RTX for a reference to LEN bits of INNER.  If POS_RTX is nonzero,
604518334Speter   it is an RTX that represents a variable starting position; otherwise,
604618334Speter   POS is the (constant) starting bit position (counted from the LSB).
604718334Speter
604818334Speter   INNER may be a USE.  This will occur when we started with a bitfield
604918334Speter   that went outside the boundary of the object in memory, which is
605018334Speter   allowed on most machines.  To isolate this case, we produce a USE
605118334Speter   whose mode is wide enough and surround the MEM with it.  The only
605218334Speter   code that understands the USE is this routine.  If it is not removed,
605318334Speter   it will cause the resulting insn not to match.
605418334Speter
6055117395Skan   UNSIGNEDP is nonzero for an unsigned reference and zero for a
605618334Speter   signed reference.
605718334Speter
6058117395Skan   IN_DEST is nonzero if this is a reference in the destination of a
6059117395Skan   SET.  This is used when a ZERO_ or SIGN_EXTRACT isn't needed.  If nonzero,
606018334Speter   a STRICT_LOW_PART will be used, if zero, ZERO_EXTEND or SIGN_EXTEND will
606118334Speter   be used.
606218334Speter
6063117395Skan   IN_COMPARE is nonzero if we are in a COMPARE.  This means that a
606418334Speter   ZERO_EXTRACT should be built even for bits starting at bit 0.
606518334Speter
606650397Sobrien   MODE is the desired mode of the result (if IN_DEST == 0).
606718334Speter
606850397Sobrien   The result is an RTX for the extraction or NULL_RTX if the target
606950397Sobrien   can't handle it.  */
607050397Sobrien
607118334Speterstatic rtx
607218334Spetermake_extraction (mode, inner, pos, pos_rtx, len,
607318334Speter		 unsignedp, in_dest, in_compare)
607418334Speter     enum machine_mode mode;
607518334Speter     rtx inner;
607690075Sobrien     HOST_WIDE_INT pos;
607718334Speter     rtx pos_rtx;
607890075Sobrien     unsigned HOST_WIDE_INT len;
607918334Speter     int unsignedp;
608018334Speter     int in_dest, in_compare;
608118334Speter{
608218334Speter  /* This mode describes the size of the storage area
608318334Speter     to fetch the overall value from.  Within that, we
608418334Speter     ignore the POS lowest bits, etc.  */
608518334Speter  enum machine_mode is_mode = GET_MODE (inner);
608618334Speter  enum machine_mode inner_mode;
608750397Sobrien  enum machine_mode wanted_inner_mode = byte_mode;
608850397Sobrien  enum machine_mode wanted_inner_reg_mode = word_mode;
608918334Speter  enum machine_mode pos_mode = word_mode;
609018334Speter  enum machine_mode extraction_mode = word_mode;
609118334Speter  enum machine_mode tmode = mode_for_size (len, MODE_INT, 1);
609218334Speter  int spans_byte = 0;
609318334Speter  rtx new = 0;
609418334Speter  rtx orig_pos_rtx = pos_rtx;
609590075Sobrien  HOST_WIDE_INT orig_pos;
609618334Speter
609718334Speter  /* Get some information about INNER and get the innermost object.  */
609818334Speter  if (GET_CODE (inner) == USE)
609918334Speter    /* (use:SI (mem:QI foo)) stands for (mem:SI foo).  */
610018334Speter    /* We don't need to adjust the position because we set up the USE
610118334Speter       to pretend that it was a full-word object.  */
610218334Speter    spans_byte = 1, inner = XEXP (inner, 0);
610318334Speter  else if (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner))
610418334Speter    {
610518334Speter      /* If going from (subreg:SI (mem:QI ...)) to (mem:QI ...),
610618334Speter	 consider just the QI as the memory to extract from.
610718334Speter	 The subreg adds or removes high bits; its mode is
610818334Speter	 irrelevant to the meaning of this extraction,
610918334Speter	 since POS and LEN count from the lsb.  */
611018334Speter      if (GET_CODE (SUBREG_REG (inner)) == MEM)
611118334Speter	is_mode = GET_MODE (SUBREG_REG (inner));
611218334Speter      inner = SUBREG_REG (inner);
611318334Speter    }
6114117395Skan  else if (GET_CODE (inner) == ASHIFT
6115117395Skan	   && GET_CODE (XEXP (inner, 1)) == CONST_INT
6116117395Skan	   && pos_rtx == 0 && pos == 0
6117117395Skan	   && len > (unsigned HOST_WIDE_INT) INTVAL (XEXP (inner, 1)))
6118117395Skan    {
6119117395Skan      /* We're extracting the least significant bits of an rtx
6120117395Skan	 (ashift X (const_int C)), where LEN > C.  Extract the
6121117395Skan	 least significant (LEN - C) bits of X, giving an rtx
6122117395Skan	 whose mode is MODE, then shift it left C times.  */
6123117395Skan      new = make_extraction (mode, XEXP (inner, 0),
6124117395Skan			     0, 0, len - INTVAL (XEXP (inner, 1)),
6125117395Skan			     unsignedp, in_dest, in_compare);
6126117395Skan      if (new != 0)
6127117395Skan	return gen_rtx_ASHIFT (mode, new, XEXP (inner, 1));
6128117395Skan    }
612918334Speter
613018334Speter  inner_mode = GET_MODE (inner);
613118334Speter
613218334Speter  if (pos_rtx && GET_CODE (pos_rtx) == CONST_INT)
613318334Speter    pos = INTVAL (pos_rtx), pos_rtx = 0;
613418334Speter
613518334Speter  /* See if this can be done without an extraction.  We never can if the
613618334Speter     width of the field is not the same as that of some integer mode. For
613718334Speter     registers, we can only avoid the extraction if the position is at the
613818334Speter     low-order bit and this is either not in the destination or we have the
613918334Speter     appropriate STRICT_LOW_PART operation available.
614018334Speter
614118334Speter     For MEM, we can avoid an extract if the field starts on an appropriate
614218334Speter     boundary and we can change the mode of the memory reference.  However,
614318334Speter     we cannot directly access the MEM if we have a USE and the underlying
614418334Speter     MEM is not TMODE.  This combination means that MEM was being used in a
614518334Speter     context where bits outside its mode were being referenced; that is only
614618334Speter     valid in bit-field insns.  */
614718334Speter
614818334Speter  if (tmode != BLKmode
614918334Speter      && ! (spans_byte && inner_mode != tmode)
615050397Sobrien      && ((pos_rtx == 0 && (pos % BITS_PER_WORD) == 0
615150397Sobrien	   && GET_CODE (inner) != MEM
615218334Speter	   && (! in_dest
615318334Speter	       || (GET_CODE (inner) == REG
615490075Sobrien		   && have_insn_for (STRICT_LOW_PART, tmode))))
615518334Speter	  || (GET_CODE (inner) == MEM && pos_rtx == 0
615618334Speter	      && (pos
615718334Speter		  % (STRICT_ALIGNMENT ? GET_MODE_ALIGNMENT (tmode)
615818334Speter		     : BITS_PER_UNIT)) == 0
615918334Speter	      /* We can't do this if we are widening INNER_MODE (it
616018334Speter		 may not be aligned, for one thing).  */
616118334Speter	      && GET_MODE_BITSIZE (inner_mode) >= GET_MODE_BITSIZE (tmode)
616218334Speter	      && (inner_mode == tmode
616318334Speter		  || (! mode_dependent_address_p (XEXP (inner, 0))
616418334Speter		      && ! MEM_VOLATILE_P (inner))))))
616518334Speter    {
616618334Speter      /* If INNER is a MEM, make a new MEM that encompasses just the desired
616718334Speter	 field.  If the original and current mode are the same, we need not
616890075Sobrien	 adjust the offset.  Otherwise, we do if bytes big endian.
616918334Speter
617050397Sobrien	 If INNER is not a MEM, get a piece consisting of just the field
617150397Sobrien	 of interest (in this case POS % BITS_PER_WORD must be 0).  */
617218334Speter
617318334Speter      if (GET_CODE (inner) == MEM)
617418334Speter	{
617590075Sobrien	  HOST_WIDE_INT offset;
617690075Sobrien
617718334Speter	  /* POS counts from lsb, but make OFFSET count in memory order.  */
617818334Speter	  if (BYTES_BIG_ENDIAN)
617918334Speter	    offset = (GET_MODE_BITSIZE (is_mode) - len - pos) / BITS_PER_UNIT;
618018334Speter	  else
618118334Speter	    offset = pos / BITS_PER_UNIT;
618218334Speter
618390075Sobrien	  new = adjust_address_nv (inner, tmode, offset);
618418334Speter	}
618518334Speter      else if (GET_CODE (inner) == REG)
618618334Speter	{
618718334Speter	  /* We can't call gen_lowpart_for_combine here since we always want
618818334Speter	     a SUBREG and it would sometimes return a new hard register.  */
618918334Speter	  if (tmode != inner_mode)
619090075Sobrien	    {
619190075Sobrien	      HOST_WIDE_INT final_word = pos / BITS_PER_WORD;
619290075Sobrien
619390075Sobrien	      if (WORDS_BIG_ENDIAN
619490075Sobrien		  && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD)
619590075Sobrien		final_word = ((GET_MODE_SIZE (inner_mode)
619690075Sobrien			       - GET_MODE_SIZE (tmode))
619790075Sobrien			      / UNITS_PER_WORD) - final_word;
619890075Sobrien
619990075Sobrien	      final_word *= UNITS_PER_WORD;
620090075Sobrien	      if (BYTES_BIG_ENDIAN &&
620190075Sobrien		  GET_MODE_SIZE (inner_mode) > GET_MODE_SIZE (tmode))
620290075Sobrien		final_word += (GET_MODE_SIZE (inner_mode)
620390075Sobrien			       - GET_MODE_SIZE (tmode)) % UNITS_PER_WORD;
620490075Sobrien
6205110611Skan	      /* Avoid creating invalid subregs, for example when
6206117395Skan		 simplifying (x>>32)&255.  */
6207110611Skan	      if (final_word >= GET_MODE_SIZE (inner_mode))
6208110611Skan		return NULL_RTX;
6209110611Skan
621090075Sobrien	      new = gen_rtx_SUBREG (tmode, inner, final_word);
621190075Sobrien	    }
621218334Speter	  else
621318334Speter	    new = inner;
621418334Speter	}
621518334Speter      else
621618334Speter	new = force_to_mode (inner, tmode,
621718334Speter			     len >= HOST_BITS_PER_WIDE_INT
621890075Sobrien			     ? ~(unsigned HOST_WIDE_INT) 0
621990075Sobrien			     : ((unsigned HOST_WIDE_INT) 1 << len) - 1,
622018334Speter			     NULL_RTX, 0);
622118334Speter
622290075Sobrien      /* If this extraction is going into the destination of a SET,
622318334Speter	 make a STRICT_LOW_PART unless we made a MEM.  */
622418334Speter
622518334Speter      if (in_dest)
622618334Speter	return (GET_CODE (new) == MEM ? new
622718334Speter		: (GET_CODE (new) != SUBREG
622850397Sobrien		   ? gen_rtx_CLOBBER (tmode, const0_rtx)
622990075Sobrien		   : gen_rtx_STRICT_LOW_PART (VOIDmode, new)));
623018334Speter
623190075Sobrien      if (mode == tmode)
623290075Sobrien	return new;
623390075Sobrien
623496263Sobrien      if (GET_CODE (new) == CONST_INT)
6235117395Skan	return gen_int_mode (INTVAL (new), mode);
623696263Sobrien
623790075Sobrien      /* If we know that no extraneous bits are set, and that the high
623890075Sobrien	 bit is not set, convert the extraction to the cheaper of
623990075Sobrien	 sign and zero extension, that are equivalent in these cases.  */
624090075Sobrien      if (flag_expensive_optimizations
624190075Sobrien	  && (GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT
624290075Sobrien	      && ((nonzero_bits (new, tmode)
624390075Sobrien		   & ~(((unsigned HOST_WIDE_INT)
624490075Sobrien			GET_MODE_MASK (tmode))
624590075Sobrien		       >> 1))
624690075Sobrien		  == 0)))
624790075Sobrien	{
624890075Sobrien	  rtx temp = gen_rtx_ZERO_EXTEND (mode, new);
624990075Sobrien	  rtx temp1 = gen_rtx_SIGN_EXTEND (mode, new);
625090075Sobrien
625190075Sobrien	  /* Prefer ZERO_EXTENSION, since it gives more information to
625290075Sobrien	     backends.  */
625390075Sobrien	  if (rtx_cost (temp, SET) <= rtx_cost (temp1, SET))
625490075Sobrien	    return temp;
625590075Sobrien	  return temp1;
625690075Sobrien	}
625790075Sobrien
625818334Speter      /* Otherwise, sign- or zero-extend unless we already are in the
625918334Speter	 proper mode.  */
626018334Speter
626190075Sobrien      return (gen_rtx_fmt_e (unsignedp ? ZERO_EXTEND : SIGN_EXTEND,
626290075Sobrien			     mode, new));
626318334Speter    }
626418334Speter
626518334Speter  /* Unless this is a COMPARE or we have a funny memory reference,
626618334Speter     don't do anything with zero-extending field extracts starting at
626718334Speter     the low-order bit since they are simple AND operations.  */
626818334Speter  if (pos_rtx == 0 && pos == 0 && ! in_dest
626918334Speter      && ! in_compare && ! spans_byte && unsignedp)
627018334Speter    return 0;
627118334Speter
627290075Sobrien  /* Unless we are allowed to span bytes or INNER is not MEM, reject this if
627390075Sobrien     we would be spanning bytes or if the position is not a constant and the
627490075Sobrien     length is not 1.  In all other cases, we would only be going outside
627590075Sobrien     our object in cases when an original shift would have been
627618334Speter     undefined.  */
627790075Sobrien  if (! spans_byte && GET_CODE (inner) == MEM
627818334Speter      && ((pos_rtx == 0 && pos + len > GET_MODE_BITSIZE (is_mode))
627918334Speter	  || (pos_rtx != 0 && len != 1)))
628018334Speter    return 0;
628118334Speter
628250397Sobrien  /* Get the mode to use should INNER not be a MEM, the mode for the position,
628318334Speter     and the mode for the result.  */
628490075Sobrien  if (in_dest && mode_for_extraction (EP_insv, -1) != MAX_MACHINE_MODE)
628518334Speter    {
628690075Sobrien      wanted_inner_reg_mode = mode_for_extraction (EP_insv, 0);
628790075Sobrien      pos_mode = mode_for_extraction (EP_insv, 2);
628890075Sobrien      extraction_mode = mode_for_extraction (EP_insv, 3);
628918334Speter    }
629018334Speter
629190075Sobrien  if (! in_dest && unsignedp
629290075Sobrien      && mode_for_extraction (EP_extzv, -1) != MAX_MACHINE_MODE)
629318334Speter    {
629490075Sobrien      wanted_inner_reg_mode = mode_for_extraction (EP_extzv, 1);
629590075Sobrien      pos_mode = mode_for_extraction (EP_extzv, 3);
629690075Sobrien      extraction_mode = mode_for_extraction (EP_extzv, 0);
629718334Speter    }
629818334Speter
629990075Sobrien  if (! in_dest && ! unsignedp
630090075Sobrien      && mode_for_extraction (EP_extv, -1) != MAX_MACHINE_MODE)
630118334Speter    {
630290075Sobrien      wanted_inner_reg_mode = mode_for_extraction (EP_extv, 1);
630390075Sobrien      pos_mode = mode_for_extraction (EP_extv, 3);
630490075Sobrien      extraction_mode = mode_for_extraction (EP_extv, 0);
630518334Speter    }
630618334Speter
630718334Speter  /* Never narrow an object, since that might not be safe.  */
630818334Speter
630918334Speter  if (mode != VOIDmode
631018334Speter      && GET_MODE_SIZE (extraction_mode) < GET_MODE_SIZE (mode))
631118334Speter    extraction_mode = mode;
631218334Speter
631318334Speter  if (pos_rtx && GET_MODE (pos_rtx) != VOIDmode
631418334Speter      && GET_MODE_SIZE (pos_mode) < GET_MODE_SIZE (GET_MODE (pos_rtx)))
631518334Speter    pos_mode = GET_MODE (pos_rtx);
631618334Speter
631750397Sobrien  /* If this is not from memory, the desired mode is wanted_inner_reg_mode;
631850397Sobrien     if we have to change the mode of memory and cannot, the desired mode is
631950397Sobrien     EXTRACTION_MODE.  */
632050397Sobrien  if (GET_CODE (inner) != MEM)
632150397Sobrien    wanted_inner_mode = wanted_inner_reg_mode;
632250397Sobrien  else if (inner_mode != wanted_inner_mode
632350397Sobrien	   && (mode_dependent_address_p (XEXP (inner, 0))
632450397Sobrien	       || MEM_VOLATILE_P (inner)))
632550397Sobrien    wanted_inner_mode = extraction_mode;
632618334Speter
632718334Speter  orig_pos = pos;
632818334Speter
632918334Speter  if (BITS_BIG_ENDIAN)
633018334Speter    {
633150397Sobrien      /* POS is passed as if BITS_BIG_ENDIAN == 0, so we need to convert it to
633250397Sobrien	 BITS_BIG_ENDIAN style.  If position is constant, compute new
633350397Sobrien	 position.  Otherwise, build subtraction.
633450397Sobrien	 Note that POS is relative to the mode of the original argument.
633550397Sobrien	 If it's a MEM we need to recompute POS relative to that.
633650397Sobrien	 However, if we're extracting from (or inserting into) a register,
633750397Sobrien	 we want to recompute POS relative to wanted_inner_mode.  */
633850397Sobrien      int width = (GET_CODE (inner) == MEM
633950397Sobrien		   ? GET_MODE_BITSIZE (is_mode)
634050397Sobrien		   : GET_MODE_BITSIZE (wanted_inner_mode));
634150397Sobrien
634218334Speter      if (pos_rtx == 0)
634350397Sobrien	pos = width - len - pos;
634418334Speter      else
634518334Speter	pos_rtx
634690075Sobrien	  = gen_rtx_MINUS (GET_MODE (pos_rtx), GEN_INT (width - len), pos_rtx);
634750397Sobrien      /* POS may be less than 0 now, but we check for that below.
634850397Sobrien	 Note that it can only be less than 0 if GET_CODE (inner) != MEM.  */
634918334Speter    }
635018334Speter
635118334Speter  /* If INNER has a wider mode, make it smaller.  If this is a constant
635218334Speter     extract, try to adjust the byte to point to the byte containing
635318334Speter     the value.  */
635450397Sobrien  if (wanted_inner_mode != VOIDmode
635550397Sobrien      && GET_MODE_SIZE (wanted_inner_mode) < GET_MODE_SIZE (is_mode)
635618334Speter      && ((GET_CODE (inner) == MEM
635750397Sobrien	   && (inner_mode == wanted_inner_mode
635818334Speter	       || (! mode_dependent_address_p (XEXP (inner, 0))
635918334Speter		   && ! MEM_VOLATILE_P (inner))))))
636018334Speter    {
636118334Speter      int offset = 0;
636218334Speter
636318334Speter      /* The computations below will be correct if the machine is big
636418334Speter	 endian in both bits and bytes or little endian in bits and bytes.
636518334Speter	 If it is mixed, we must adjust.  */
636690075Sobrien
636718334Speter      /* If bytes are big endian and we had a paradoxical SUBREG, we must
636850397Sobrien	 adjust OFFSET to compensate.  */
636918334Speter      if (BYTES_BIG_ENDIAN
637018334Speter	  && ! spans_byte
637118334Speter	  && GET_MODE_SIZE (inner_mode) < GET_MODE_SIZE (is_mode))
637218334Speter	offset -= GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (inner_mode);
637318334Speter
637418334Speter      /* If this is a constant position, we can move to the desired byte.  */
637518334Speter      if (pos_rtx == 0)
637618334Speter	{
637718334Speter	  offset += pos / BITS_PER_UNIT;
637850397Sobrien	  pos %= GET_MODE_BITSIZE (wanted_inner_mode);
637918334Speter	}
638018334Speter
638118334Speter      if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN
638218334Speter	  && ! spans_byte
638350397Sobrien	  && is_mode != wanted_inner_mode)
638418334Speter	offset = (GET_MODE_SIZE (is_mode)
638550397Sobrien		  - GET_MODE_SIZE (wanted_inner_mode) - offset);
638618334Speter
638750397Sobrien      if (offset != 0 || inner_mode != wanted_inner_mode)
638890075Sobrien	inner = adjust_address_nv (inner, wanted_inner_mode, offset);
638918334Speter    }
639018334Speter
639150397Sobrien  /* If INNER is not memory, we can always get it into the proper mode.  If we
639250397Sobrien     are changing its mode, POS must be a constant and smaller than the size
639350397Sobrien     of the new mode.  */
639418334Speter  else if (GET_CODE (inner) != MEM)
639550397Sobrien    {
639650397Sobrien      if (GET_MODE (inner) != wanted_inner_mode
639750397Sobrien	  && (pos_rtx != 0
639850397Sobrien	      || orig_pos + len > GET_MODE_BITSIZE (wanted_inner_mode)))
639950397Sobrien	return 0;
640018334Speter
640150397Sobrien      inner = force_to_mode (inner, wanted_inner_mode,
640250397Sobrien			     pos_rtx
640350397Sobrien			     || len + orig_pos >= HOST_BITS_PER_WIDE_INT
640490075Sobrien			     ? ~(unsigned HOST_WIDE_INT) 0
640590075Sobrien			     : ((((unsigned HOST_WIDE_INT) 1 << len) - 1)
640690075Sobrien				<< orig_pos),
640750397Sobrien			     NULL_RTX, 0);
640850397Sobrien    }
640950397Sobrien
641018334Speter  /* Adjust mode of POS_RTX, if needed.  If we want a wider mode, we
641118334Speter     have to zero extend.  Otherwise, we can just use a SUBREG.  */
641218334Speter  if (pos_rtx != 0
641318334Speter      && GET_MODE_SIZE (pos_mode) > GET_MODE_SIZE (GET_MODE (pos_rtx)))
641490075Sobrien    {
641590075Sobrien      rtx temp = gen_rtx_ZERO_EXTEND (pos_mode, pos_rtx);
641690075Sobrien
641790075Sobrien      /* If we know that no extraneous bits are set, and that the high
641890075Sobrien	 bit is not set, convert extraction to cheaper one - either
641990075Sobrien	 SIGN_EXTENSION or ZERO_EXTENSION, that are equivalent in these
642090075Sobrien	 cases.  */
642190075Sobrien      if (flag_expensive_optimizations
642290075Sobrien	  && (GET_MODE_BITSIZE (GET_MODE (pos_rtx)) <= HOST_BITS_PER_WIDE_INT
642390075Sobrien	      && ((nonzero_bits (pos_rtx, GET_MODE (pos_rtx))
642490075Sobrien		   & ~(((unsigned HOST_WIDE_INT)
642590075Sobrien			GET_MODE_MASK (GET_MODE (pos_rtx)))
642690075Sobrien		       >> 1))
642790075Sobrien		  == 0)))
642890075Sobrien	{
642990075Sobrien	  rtx temp1 = gen_rtx_SIGN_EXTEND (pos_mode, pos_rtx);
643090075Sobrien
643190075Sobrien	  /* Prefer ZERO_EXTENSION, since it gives more information to
643290075Sobrien	     backends.  */
643390075Sobrien	  if (rtx_cost (temp1, SET) < rtx_cost (temp, SET))
643490075Sobrien	    temp = temp1;
643590075Sobrien	}
643690075Sobrien      pos_rtx = temp;
643790075Sobrien    }
643818334Speter  else if (pos_rtx != 0
643918334Speter	   && GET_MODE_SIZE (pos_mode) < GET_MODE_SIZE (GET_MODE (pos_rtx)))
644018334Speter    pos_rtx = gen_lowpart_for_combine (pos_mode, pos_rtx);
644118334Speter
644218334Speter  /* Make POS_RTX unless we already have it and it is correct.  If we don't
644318334Speter     have a POS_RTX but we do have an ORIG_POS_RTX, the latter must
644450397Sobrien     be a CONST_INT.  */
644518334Speter  if (pos_rtx == 0 && orig_pos_rtx != 0 && INTVAL (orig_pos_rtx) == pos)
644618334Speter    pos_rtx = orig_pos_rtx;
644718334Speter
644818334Speter  else if (pos_rtx == 0)
644918334Speter    pos_rtx = GEN_INT (pos);
645018334Speter
645118334Speter  /* Make the required operation.  See if we can use existing rtx.  */
645290075Sobrien  new = gen_rtx_fmt_eee (unsignedp ? ZERO_EXTRACT : SIGN_EXTRACT,
645318334Speter			 extraction_mode, inner, GEN_INT (len), pos_rtx);
645418334Speter  if (! in_dest)
645518334Speter    new = gen_lowpart_for_combine (mode, new);
645618334Speter
645718334Speter  return new;
645818334Speter}
645918334Speter
646018334Speter/* See if X contains an ASHIFT of COUNT or more bits that can be commuted
646118334Speter   with any other operations in X.  Return X without that shift if so.  */
646218334Speter
646318334Speterstatic rtx
646418334Speterextract_left_shift (x, count)
646518334Speter     rtx x;
646618334Speter     int count;
646718334Speter{
646818334Speter  enum rtx_code code = GET_CODE (x);
646918334Speter  enum machine_mode mode = GET_MODE (x);
647018334Speter  rtx tem;
647118334Speter
647218334Speter  switch (code)
647318334Speter    {
647418334Speter    case ASHIFT:
647518334Speter      /* This is the shift itself.  If it is wide enough, we will return
647618334Speter	 either the value being shifted if the shift count is equal to
647718334Speter	 COUNT or a shift for the difference.  */
647818334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
647918334Speter	  && INTVAL (XEXP (x, 1)) >= count)
648018334Speter	return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (x, 0),
648118334Speter				     INTVAL (XEXP (x, 1)) - count);
648218334Speter      break;
648318334Speter
648418334Speter    case NEG:  case NOT:
648518334Speter      if ((tem = extract_left_shift (XEXP (x, 0), count)) != 0)
648690075Sobrien	return simplify_gen_unary (code, mode, tem, mode);
648718334Speter
648818334Speter      break;
648918334Speter
649018334Speter    case PLUS:  case IOR:  case XOR:  case AND:
649118334Speter      /* If we can safely shift this constant and we find the inner shift,
649218334Speter	 make a new operation.  */
649318334Speter      if (GET_CODE (XEXP (x,1)) == CONST_INT
649450397Sobrien	  && (INTVAL (XEXP (x, 1)) & ((((HOST_WIDE_INT) 1 << count)) - 1)) == 0
649518334Speter	  && (tem = extract_left_shift (XEXP (x, 0), count)) != 0)
649690075Sobrien	return gen_binary (code, mode, tem,
649718334Speter			   GEN_INT (INTVAL (XEXP (x, 1)) >> count));
649818334Speter
649918334Speter      break;
650090075Sobrien
650150397Sobrien    default:
650250397Sobrien      break;
650318334Speter    }
650418334Speter
650518334Speter  return 0;
650618334Speter}
650718334Speter
650818334Speter/* Look at the expression rooted at X.  Look for expressions
650918334Speter   equivalent to ZERO_EXTRACT, SIGN_EXTRACT, ZERO_EXTEND, SIGN_EXTEND.
651018334Speter   Form these expressions.
651118334Speter
651218334Speter   Return the new rtx, usually just X.
651318334Speter
651490075Sobrien   Also, for machines like the VAX that don't have logical shift insns,
651518334Speter   try to convert logical to arithmetic shift operations in cases where
651618334Speter   they are equivalent.  This undoes the canonicalizations to logical
651718334Speter   shifts done elsewhere.
651818334Speter
651918334Speter   We try, as much as possible, to re-use rtl expressions to save memory.
652018334Speter
652118334Speter   IN_CODE says what kind of expression we are processing.  Normally, it is
652218334Speter   SET.  In a memory address (inside a MEM, PLUS or minus, the latter two
652318334Speter   being kludges), it is MEM.  When processing the arguments of a comparison
652418334Speter   or a COMPARE against zero, it is COMPARE.  */
652518334Speter
652618334Speterstatic rtx
652718334Spetermake_compound_operation (x, in_code)
652818334Speter     rtx x;
652918334Speter     enum rtx_code in_code;
653018334Speter{
653118334Speter  enum rtx_code code = GET_CODE (x);
653218334Speter  enum machine_mode mode = GET_MODE (x);
653318334Speter  int mode_width = GET_MODE_BITSIZE (mode);
653418334Speter  rtx rhs, lhs;
653518334Speter  enum rtx_code next_code;
653618334Speter  int i;
653718334Speter  rtx new = 0;
653818334Speter  rtx tem;
653990075Sobrien  const char *fmt;
654018334Speter
654118334Speter  /* Select the code to be used in recursive calls.  Once we are inside an
654218334Speter     address, we stay there.  If we have a comparison, set to COMPARE,
654318334Speter     but once inside, go back to our default of SET.  */
654418334Speter
654518334Speter  next_code = (code == MEM || code == PLUS || code == MINUS ? MEM
654618334Speter	       : ((code == COMPARE || GET_RTX_CLASS (code) == '<')
654718334Speter		  && XEXP (x, 1) == const0_rtx) ? COMPARE
654818334Speter	       : in_code == COMPARE ? SET : in_code);
654918334Speter
655018334Speter  /* Process depending on the code of this operation.  If NEW is set
6551117395Skan     nonzero, it will be returned.  */
655218334Speter
655318334Speter  switch (code)
655418334Speter    {
655518334Speter    case ASHIFT:
655618334Speter      /* Convert shifts by constants into multiplications if inside
655718334Speter	 an address.  */
655818334Speter      if (in_code == MEM && GET_CODE (XEXP (x, 1)) == CONST_INT
655918334Speter	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
656018334Speter	  && INTVAL (XEXP (x, 1)) >= 0)
656118334Speter	{
656218334Speter	  new = make_compound_operation (XEXP (x, 0), next_code);
656390075Sobrien	  new = gen_rtx_MULT (mode, new,
656490075Sobrien			      GEN_INT ((HOST_WIDE_INT) 1
656590075Sobrien				       << INTVAL (XEXP (x, 1))));
656618334Speter	}
656718334Speter      break;
656818334Speter
656918334Speter    case AND:
657018334Speter      /* If the second operand is not a constant, we can't do anything
657118334Speter	 with it.  */
657218334Speter      if (GET_CODE (XEXP (x, 1)) != CONST_INT)
657318334Speter	break;
657418334Speter
657518334Speter      /* If the constant is a power of two minus one and the first operand
657618334Speter	 is a logical right shift, make an extraction.  */
657718334Speter      if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
657818334Speter	  && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
657918334Speter	{
658018334Speter	  new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
658118334Speter	  new = make_extraction (mode, new, 0, XEXP (XEXP (x, 0), 1), i, 1,
658218334Speter				 0, in_code == COMPARE);
658318334Speter	}
658418334Speter
658518334Speter      /* Same as previous, but for (subreg (lshiftrt ...)) in first op.  */
658618334Speter      else if (GET_CODE (XEXP (x, 0)) == SUBREG
658718334Speter	       && subreg_lowpart_p (XEXP (x, 0))
658818334Speter	       && GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT
658918334Speter	       && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
659018334Speter	{
659118334Speter	  new = make_compound_operation (XEXP (SUBREG_REG (XEXP (x, 0)), 0),
659218334Speter					 next_code);
659318334Speter	  new = make_extraction (GET_MODE (SUBREG_REG (XEXP (x, 0))), new, 0,
659418334Speter				 XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1,
659518334Speter				 0, in_code == COMPARE);
659618334Speter	}
659718334Speter      /* Same as previous, but for (xor/ior (lshiftrt...) (lshiftrt...)).  */
659818334Speter      else if ((GET_CODE (XEXP (x, 0)) == XOR
659918334Speter		|| GET_CODE (XEXP (x, 0)) == IOR)
660018334Speter	       && GET_CODE (XEXP (XEXP (x, 0), 0)) == LSHIFTRT
660118334Speter	       && GET_CODE (XEXP (XEXP (x, 0), 1)) == LSHIFTRT
660218334Speter	       && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
660318334Speter	{
660418334Speter	  /* Apply the distributive law, and then try to make extractions.  */
660590075Sobrien	  new = gen_rtx_fmt_ee (GET_CODE (XEXP (x, 0)), mode,
660690075Sobrien				gen_rtx_AND (mode, XEXP (XEXP (x, 0), 0),
660790075Sobrien					     XEXP (x, 1)),
660890075Sobrien				gen_rtx_AND (mode, XEXP (XEXP (x, 0), 1),
660990075Sobrien					     XEXP (x, 1)));
661018334Speter	  new = make_compound_operation (new, in_code);
661118334Speter	}
661218334Speter
661318334Speter      /* If we are have (and (rotate X C) M) and C is larger than the number
661418334Speter	 of bits in M, this is an extraction.  */
661518334Speter
661618334Speter      else if (GET_CODE (XEXP (x, 0)) == ROTATE
661718334Speter	       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
661818334Speter	       && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0
661918334Speter	       && i <= INTVAL (XEXP (XEXP (x, 0), 1)))
662018334Speter	{
662118334Speter	  new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
662218334Speter	  new = make_extraction (mode, new,
662318334Speter				 (GET_MODE_BITSIZE (mode)
662418334Speter				  - INTVAL (XEXP (XEXP (x, 0), 1))),
662518334Speter				 NULL_RTX, i, 1, 0, in_code == COMPARE);
662618334Speter	}
662718334Speter
662818334Speter      /* On machines without logical shifts, if the operand of the AND is
662918334Speter	 a logical shift and our mask turns off all the propagated sign
663018334Speter	 bits, we can replace the logical shift with an arithmetic shift.  */
663190075Sobrien      else if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
663290075Sobrien	       && !have_insn_for (LSHIFTRT, mode)
663390075Sobrien	       && have_insn_for (ASHIFTRT, mode)
663418334Speter	       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
663518334Speter	       && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
663618334Speter	       && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT
663718334Speter	       && mode_width <= HOST_BITS_PER_WIDE_INT)
663818334Speter	{
663918334Speter	  unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
664018334Speter
664118334Speter	  mask >>= INTVAL (XEXP (XEXP (x, 0), 1));
664218334Speter	  if ((INTVAL (XEXP (x, 1)) & ~mask) == 0)
664318334Speter	    SUBST (XEXP (x, 0),
664490075Sobrien		   gen_rtx_ASHIFTRT (mode,
664590075Sobrien				     make_compound_operation
664690075Sobrien				     (XEXP (XEXP (x, 0), 0), next_code),
664790075Sobrien				     XEXP (XEXP (x, 0), 1)));
664818334Speter	}
664918334Speter
665018334Speter      /* If the constant is one less than a power of two, this might be
665118334Speter	 representable by an extraction even if no shift is present.
665218334Speter	 If it doesn't end up being a ZERO_EXTEND, we will ignore it unless
665318334Speter	 we are in a COMPARE.  */
665418334Speter      else if ((i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
665518334Speter	new = make_extraction (mode,
665618334Speter			       make_compound_operation (XEXP (x, 0),
665718334Speter							next_code),
665818334Speter			       0, NULL_RTX, i, 1, 0, in_code == COMPARE);
665918334Speter
666018334Speter      /* If we are in a comparison and this is an AND with a power of two,
666118334Speter	 convert this into the appropriate bit extract.  */
666218334Speter      else if (in_code == COMPARE
666318334Speter	       && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0)
666418334Speter	new = make_extraction (mode,
666518334Speter			       make_compound_operation (XEXP (x, 0),
666618334Speter							next_code),
666718334Speter			       i, NULL_RTX, 1, 1, 0, 1);
666818334Speter
666918334Speter      break;
667018334Speter
667118334Speter    case LSHIFTRT:
667218334Speter      /* If the sign bit is known to be zero, replace this with an
667318334Speter	 arithmetic shift.  */
667490075Sobrien      if (have_insn_for (ASHIFTRT, mode)
667590075Sobrien	  && ! have_insn_for (LSHIFTRT, mode)
667618334Speter	  && mode_width <= HOST_BITS_PER_WIDE_INT
667718334Speter	  && (nonzero_bits (XEXP (x, 0), mode) & (1 << (mode_width - 1))) == 0)
667818334Speter	{
667990075Sobrien	  new = gen_rtx_ASHIFTRT (mode,
668090075Sobrien				  make_compound_operation (XEXP (x, 0),
668190075Sobrien							   next_code),
668290075Sobrien				  XEXP (x, 1));
668318334Speter	  break;
668418334Speter	}
668518334Speter
668650397Sobrien      /* ... fall through ...  */
668718334Speter
668818334Speter    case ASHIFTRT:
668918334Speter      lhs = XEXP (x, 0);
669018334Speter      rhs = XEXP (x, 1);
669118334Speter
669218334Speter      /* If we have (ashiftrt (ashift foo C1) C2) with C2 >= C1,
669318334Speter	 this is a SIGN_EXTRACT.  */
669418334Speter      if (GET_CODE (rhs) == CONST_INT
669518334Speter	  && GET_CODE (lhs) == ASHIFT
669618334Speter	  && GET_CODE (XEXP (lhs, 1)) == CONST_INT
669718334Speter	  && INTVAL (rhs) >= INTVAL (XEXP (lhs, 1)))
669818334Speter	{
669918334Speter	  new = make_compound_operation (XEXP (lhs, 0), next_code);
670018334Speter	  new = make_extraction (mode, new,
670118334Speter				 INTVAL (rhs) - INTVAL (XEXP (lhs, 1)),
670218334Speter				 NULL_RTX, mode_width - INTVAL (rhs),
670318334Speter				 code == LSHIFTRT, 0, in_code == COMPARE);
670490075Sobrien	  break;
670518334Speter	}
670618334Speter
670718334Speter      /* See if we have operations between an ASHIFTRT and an ASHIFT.
670818334Speter	 If so, try to merge the shifts into a SIGN_EXTEND.  We could
670918334Speter	 also do this for some cases of SIGN_EXTRACT, but it doesn't
671018334Speter	 seem worth the effort; the case checked for occurs on Alpha.  */
671190075Sobrien
671218334Speter      if (GET_RTX_CLASS (GET_CODE (lhs)) != 'o'
671318334Speter	  && ! (GET_CODE (lhs) == SUBREG
671418334Speter		&& (GET_RTX_CLASS (GET_CODE (SUBREG_REG (lhs))) == 'o'))
671518334Speter	  && GET_CODE (rhs) == CONST_INT
671618334Speter	  && INTVAL (rhs) < HOST_BITS_PER_WIDE_INT
671718334Speter	  && (new = extract_left_shift (lhs, INTVAL (rhs))) != 0)
671818334Speter	new = make_extraction (mode, make_compound_operation (new, next_code),
671918334Speter			       0, NULL_RTX, mode_width - INTVAL (rhs),
672018334Speter			       code == LSHIFTRT, 0, in_code == COMPARE);
672190075Sobrien
672218334Speter      break;
672318334Speter
672418334Speter    case SUBREG:
672518334Speter      /* Call ourselves recursively on the inner expression.  If we are
672618334Speter	 narrowing the object and it has a different RTL code from
672718334Speter	 what it originally did, do this SUBREG as a force_to_mode.  */
672818334Speter
672918334Speter      tem = make_compound_operation (SUBREG_REG (x), in_code);
673018334Speter      if (GET_CODE (tem) != GET_CODE (SUBREG_REG (x))
673118334Speter	  && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (tem))
673218334Speter	  && subreg_lowpart_p (x))
673318334Speter	{
673490075Sobrien	  rtx newer = force_to_mode (tem, mode, ~(HOST_WIDE_INT) 0,
673590075Sobrien				     NULL_RTX, 0);
673618334Speter
673718334Speter	  /* If we have something other than a SUBREG, we might have
673890075Sobrien	     done an expansion, so rerun ourselves.  */
673918334Speter	  if (GET_CODE (newer) != SUBREG)
674018334Speter	    newer = make_compound_operation (newer, in_code);
674118334Speter
674218334Speter	  return newer;
674318334Speter	}
674450397Sobrien
674550397Sobrien      /* If this is a paradoxical subreg, and the new code is a sign or
674650397Sobrien	 zero extension, omit the subreg and widen the extension.  If it
674750397Sobrien	 is a regular subreg, we can still get rid of the subreg by not
674850397Sobrien	 widening so much, or in fact removing the extension entirely.  */
674950397Sobrien      if ((GET_CODE (tem) == SIGN_EXTEND
675050397Sobrien	   || GET_CODE (tem) == ZERO_EXTEND)
675150397Sobrien	  && subreg_lowpart_p (x))
675250397Sobrien	{
675350397Sobrien	  if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (tem))
675450397Sobrien	      || (GET_MODE_SIZE (mode) >
675550397Sobrien		  GET_MODE_SIZE (GET_MODE (XEXP (tem, 0)))))
6756117395Skan	    {
6757117395Skan	      if (! SCALAR_INT_MODE_P (mode))
6758117395Skan		break;
6759117395Skan	      tem = gen_rtx_fmt_e (GET_CODE (tem), mode, XEXP (tem, 0));
6760117395Skan	    }
676150397Sobrien	  else
676250397Sobrien	    tem = gen_lowpart_for_combine (mode, XEXP (tem, 0));
676350397Sobrien	  return tem;
676450397Sobrien	}
676550397Sobrien      break;
676690075Sobrien
676750397Sobrien    default:
676850397Sobrien      break;
676918334Speter    }
677018334Speter
677118334Speter  if (new)
677218334Speter    {
677318334Speter      x = gen_lowpart_for_combine (mode, new);
677418334Speter      code = GET_CODE (x);
677518334Speter    }
677618334Speter
677718334Speter  /* Now recursively process each operand of this operation.  */
677818334Speter  fmt = GET_RTX_FORMAT (code);
677918334Speter  for (i = 0; i < GET_RTX_LENGTH (code); i++)
678018334Speter    if (fmt[i] == 'e')
678118334Speter      {
678218334Speter	new = make_compound_operation (XEXP (x, i), next_code);
678318334Speter	SUBST (XEXP (x, i), new);
678418334Speter      }
678518334Speter
678618334Speter  return x;
678718334Speter}
678818334Speter
678918334Speter/* Given M see if it is a value that would select a field of bits
679090075Sobrien   within an item, but not the entire word.  Return -1 if not.
679190075Sobrien   Otherwise, return the starting position of the field, where 0 is the
679290075Sobrien   low-order bit.
679318334Speter
679418334Speter   *PLEN is set to the length of the field.  */
679518334Speter
679618334Speterstatic int
679718334Speterget_pos_from_mask (m, plen)
679818334Speter     unsigned HOST_WIDE_INT m;
679990075Sobrien     unsigned HOST_WIDE_INT *plen;
680018334Speter{
680118334Speter  /* Get the bit number of the first 1 bit from the right, -1 if none.  */
680290075Sobrien  int pos = exact_log2 (m & -m);
680390075Sobrien  int len;
680418334Speter
680518334Speter  if (pos < 0)
680618334Speter    return -1;
680718334Speter
680818334Speter  /* Now shift off the low-order zero bits and see if we have a power of
680918334Speter     two minus 1.  */
681090075Sobrien  len = exact_log2 ((m >> pos) + 1);
681118334Speter
681290075Sobrien  if (len <= 0)
681318334Speter    return -1;
681418334Speter
681590075Sobrien  *plen = len;
681618334Speter  return pos;
681718334Speter}
681818334Speter
681918334Speter/* See if X can be simplified knowing that we will only refer to it in
682018334Speter   MODE and will only refer to those bits that are nonzero in MASK.
682118334Speter   If other bits are being computed or if masking operations are done
682218334Speter   that select a superset of the bits in MASK, they can sometimes be
682318334Speter   ignored.
682418334Speter
682518334Speter   Return a possibly simplified expression, but always convert X to
682618334Speter   MODE.  If X is a CONST_INT, AND the CONST_INT with MASK.
682718334Speter
6828117395Skan   Also, if REG is nonzero and X is a register equal in value to REG,
682918334Speter   replace X with REG.
683018334Speter
683118334Speter   If JUST_SELECT is nonzero, don't optimize by noticing that bits in MASK
683218334Speter   are all off in X.  This is used when X will be complemented, by either
683318334Speter   NOT, NEG, or XOR.  */
683418334Speter
683518334Speterstatic rtx
683618334Speterforce_to_mode (x, mode, mask, reg, just_select)
683718334Speter     rtx x;
683818334Speter     enum machine_mode mode;
683918334Speter     unsigned HOST_WIDE_INT mask;
684018334Speter     rtx reg;
684118334Speter     int just_select;
684218334Speter{
684318334Speter  enum rtx_code code = GET_CODE (x);
684418334Speter  int next_select = just_select || code == XOR || code == NOT || code == NEG;
684518334Speter  enum machine_mode op_mode;
684618334Speter  unsigned HOST_WIDE_INT fuller_mask, nonzero;
684718334Speter  rtx op0, op1, temp;
684818334Speter
684950397Sobrien  /* If this is a CALL or ASM_OPERANDS, don't do anything.  Some of the
685050397Sobrien     code below will do the wrong thing since the mode of such an
685190075Sobrien     expression is VOIDmode.
685250397Sobrien
685350397Sobrien     Also do nothing if X is a CLOBBER; this can happen if X was
685450397Sobrien     the return value from a call to gen_lowpart_for_combine.  */
685550397Sobrien  if (code == CALL || code == ASM_OPERANDS || code == CLOBBER)
685618334Speter    return x;
685718334Speter
685818334Speter  /* We want to perform the operation is its present mode unless we know
685918334Speter     that the operation is valid in MODE, in which case we do the operation
686018334Speter     in MODE.  */
686118334Speter  op_mode = ((GET_MODE_CLASS (mode) == GET_MODE_CLASS (GET_MODE (x))
686290075Sobrien	      && have_insn_for (code, mode))
686318334Speter	     ? mode : GET_MODE (x));
686418334Speter
686518334Speter  /* It is not valid to do a right-shift in a narrower mode
686618334Speter     than the one it came in with.  */
686718334Speter  if ((code == LSHIFTRT || code == ASHIFTRT)
686818334Speter      && GET_MODE_BITSIZE (mode) < GET_MODE_BITSIZE (GET_MODE (x)))
686918334Speter    op_mode = GET_MODE (x);
687018334Speter
687118334Speter  /* Truncate MASK to fit OP_MODE.  */
687218334Speter  if (op_mode)
687318334Speter    mask &= GET_MODE_MASK (op_mode);
687418334Speter
687518334Speter  /* When we have an arithmetic operation, or a shift whose count we
687618334Speter     do not know, we need to assume that all bit the up to the highest-order
687718334Speter     bit in MASK will be needed.  This is how we form such a mask.  */
687818334Speter  if (op_mode)
687918334Speter    fuller_mask = (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT
688018334Speter		   ? GET_MODE_MASK (op_mode)
688190075Sobrien		   : (((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1))
688290075Sobrien		      - 1));
688318334Speter  else
688490075Sobrien    fuller_mask = ~(HOST_WIDE_INT) 0;
688518334Speter
688618334Speter  /* Determine what bits of X are guaranteed to be (non)zero.  */
688718334Speter  nonzero = nonzero_bits (x, mode);
688818334Speter
688918334Speter  /* If none of the bits in X are needed, return a zero.  */
689018334Speter  if (! just_select && (nonzero & mask) == 0)
6891117395Skan    x = const0_rtx;
689218334Speter
689318334Speter  /* If X is a CONST_INT, return a new one.  Do this here since the
689418334Speter     test below will fail.  */
689518334Speter  if (GET_CODE (x) == CONST_INT)
6896117395Skan    {
6897117395Skan      if (SCALAR_INT_MODE_P (mode))
6898117395Skan        return gen_int_mode (INTVAL (x) & mask, mode);
6899117395Skan      else
6900117395Skan	{
6901117395Skan	  x = GEN_INT (INTVAL (x) & mask);
6902117395Skan	  return gen_lowpart_common (mode, x);
6903117395Skan	}
6904117395Skan    }
690518334Speter
690618334Speter  /* If X is narrower than MODE and we want all the bits in X's mode, just
690718334Speter     get X in the proper mode.  */
690818334Speter  if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode)
690990075Sobrien      && (GET_MODE_MASK (GET_MODE (x)) & ~mask) == 0)
691018334Speter    return gen_lowpart_for_combine (mode, x);
691118334Speter
691218334Speter  /* If we aren't changing the mode, X is not a SUBREG, and all zero bits in
691318334Speter     MASK are already known to be zero in X, we need not do anything.  */
691490075Sobrien  if (GET_MODE (x) == mode && code != SUBREG && (~mask & nonzero) == 0)
691518334Speter    return x;
691618334Speter
691718334Speter  switch (code)
691818334Speter    {
691918334Speter    case CLOBBER:
692018334Speter      /* If X is a (clobber (const_int)), return it since we know we are
692150397Sobrien	 generating something that won't match.  */
692218334Speter      return x;
692318334Speter
692418334Speter    case USE:
692518334Speter      /* X is a (use (mem ..)) that was made from a bit-field extraction that
692618334Speter	 spanned the boundary of the MEM.  If we are now masking so it is
692718334Speter	 within that boundary, we don't need the USE any more.  */
692818334Speter      if (! BITS_BIG_ENDIAN
692990075Sobrien	  && (mask & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
693018334Speter	return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select);
693118334Speter      break;
693218334Speter
693318334Speter    case SIGN_EXTEND:
693418334Speter    case ZERO_EXTEND:
693518334Speter    case ZERO_EXTRACT:
693618334Speter    case SIGN_EXTRACT:
693718334Speter      x = expand_compound_operation (x);
693818334Speter      if (GET_CODE (x) != code)
693918334Speter	return force_to_mode (x, mode, mask, reg, next_select);
694018334Speter      break;
694118334Speter
694218334Speter    case REG:
694318334Speter      if (reg != 0 && (rtx_equal_p (get_last_value (reg), x)
694418334Speter		       || rtx_equal_p (reg, get_last_value (x))))
694518334Speter	x = reg;
694618334Speter      break;
694718334Speter
694818334Speter    case SUBREG:
694918334Speter      if (subreg_lowpart_p (x)
695018334Speter	  /* We can ignore the effect of this SUBREG if it narrows the mode or
695118334Speter	     if the constant masks to zero all the bits the mode doesn't
695218334Speter	     have.  */
695318334Speter	  && ((GET_MODE_SIZE (GET_MODE (x))
695418334Speter	       < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
695518334Speter	      || (0 == (mask
695618334Speter			& GET_MODE_MASK (GET_MODE (x))
695790075Sobrien			& ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))))))
695818334Speter	return force_to_mode (SUBREG_REG (x), mode, mask, reg, next_select);
695918334Speter      break;
696018334Speter
696118334Speter    case AND:
696218334Speter      /* If this is an AND with a constant, convert it into an AND
696318334Speter	 whose constant is the AND of that constant with MASK.  If it
696418334Speter	 remains an AND of MASK, delete it since it is redundant.  */
696518334Speter
696618334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
696718334Speter	{
696818334Speter	  x = simplify_and_const_int (x, op_mode, XEXP (x, 0),
696918334Speter				      mask & INTVAL (XEXP (x, 1)));
697018334Speter
697118334Speter	  /* If X is still an AND, see if it is an AND with a mask that
697218334Speter	     is just some low-order bits.  If so, and it is MASK, we don't
697318334Speter	     need it.  */
697418334Speter
697518334Speter	  if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT
697690075Sobrien	      && ((INTVAL (XEXP (x, 1)) & GET_MODE_MASK (GET_MODE (x)))
6977117395Skan		  == mask))
697818334Speter	    x = XEXP (x, 0);
697918334Speter
698018334Speter	  /* If it remains an AND, try making another AND with the bits
698118334Speter	     in the mode mask that aren't in MASK turned on.  If the
698218334Speter	     constant in the AND is wide enough, this might make a
698318334Speter	     cheaper constant.  */
698418334Speter
698518334Speter	  if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT
698618334Speter	      && GET_MODE_MASK (GET_MODE (x)) != mask
698718334Speter	      && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
698818334Speter	    {
698918334Speter	      HOST_WIDE_INT cval = (INTVAL (XEXP (x, 1))
699090075Sobrien				    | (GET_MODE_MASK (GET_MODE (x)) & ~mask));
699118334Speter	      int width = GET_MODE_BITSIZE (GET_MODE (x));
699218334Speter	      rtx y;
699318334Speter
699418334Speter	      /* If MODE is narrower that HOST_WIDE_INT and CVAL is a negative
699518334Speter		 number, sign extend it.  */
699618334Speter	      if (width > 0 && width < HOST_BITS_PER_WIDE_INT
699718334Speter		  && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
699818334Speter		cval |= (HOST_WIDE_INT) -1 << width;
699918334Speter
700018334Speter	      y = gen_binary (AND, GET_MODE (x), XEXP (x, 0), GEN_INT (cval));
700118334Speter	      if (rtx_cost (y, SET) < rtx_cost (x, SET))
700218334Speter		x = y;
700318334Speter	    }
700418334Speter
700518334Speter	  break;
700618334Speter	}
700718334Speter
700818334Speter      goto binop;
700918334Speter
701018334Speter    case PLUS:
701118334Speter      /* In (and (plus FOO C1) M), if M is a mask that just turns off
701218334Speter	 low-order bits (as in an alignment operation) and FOO is already
701318334Speter	 aligned to that boundary, mask C1 to that boundary as well.
701418334Speter	 This may eliminate that PLUS and, later, the AND.  */
701518334Speter
701618334Speter      {
701790075Sobrien	unsigned int width = GET_MODE_BITSIZE (mode);
701818334Speter	unsigned HOST_WIDE_INT smask = mask;
701918334Speter
702018334Speter	/* If MODE is narrower than HOST_WIDE_INT and mask is a negative
702118334Speter	   number, sign extend it.  */
702218334Speter
702318334Speter	if (width < HOST_BITS_PER_WIDE_INT
702418334Speter	    && (smask & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
702518334Speter	  smask |= (HOST_WIDE_INT) -1 << width;
702618334Speter
702718334Speter	if (GET_CODE (XEXP (x, 1)) == CONST_INT
702896263Sobrien	    && exact_log2 (- smask) >= 0
702996263Sobrien	    && (nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0
703096263Sobrien	    && (INTVAL (XEXP (x, 1)) & ~smask) != 0)
703196263Sobrien	  return force_to_mode (plus_constant (XEXP (x, 0),
703296263Sobrien					       (INTVAL (XEXP (x, 1)) & smask)),
703396263Sobrien				mode, smask, reg, next_select);
703418334Speter      }
703518334Speter
703650397Sobrien      /* ... fall through ...  */
703718334Speter
703818334Speter    case MULT:
703918334Speter      /* For PLUS, MINUS and MULT, we need any bits less significant than the
704018334Speter	 most significant bit in MASK since carries from those bits will
704118334Speter	 affect the bits we are interested in.  */
704218334Speter      mask = fuller_mask;
704318334Speter      goto binop;
704418334Speter
704590075Sobrien    case MINUS:
704690075Sobrien      /* If X is (minus C Y) where C's least set bit is larger than any bit
704790075Sobrien	 in the mask, then we may replace with (neg Y).  */
704890075Sobrien      if (GET_CODE (XEXP (x, 0)) == CONST_INT
704990075Sobrien	  && (((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 0))
705090075Sobrien					& -INTVAL (XEXP (x, 0))))
705190075Sobrien	      > mask))
705290075Sobrien	{
705390075Sobrien	  x = simplify_gen_unary (NEG, GET_MODE (x), XEXP (x, 1),
705490075Sobrien				  GET_MODE (x));
705590075Sobrien	  return force_to_mode (x, mode, mask, reg, next_select);
705690075Sobrien	}
705790075Sobrien
7058110611Skan      /* Similarly, if C contains every bit in the fuller_mask, then we may
705990075Sobrien	 replace with (not Y).  */
706090075Sobrien      if (GET_CODE (XEXP (x, 0)) == CONST_INT
7061110611Skan	  && ((INTVAL (XEXP (x, 0)) | (HOST_WIDE_INT) fuller_mask)
706290075Sobrien	      == INTVAL (XEXP (x, 0))))
706390075Sobrien	{
706490075Sobrien	  x = simplify_gen_unary (NOT, GET_MODE (x),
706590075Sobrien				  XEXP (x, 1), GET_MODE (x));
706690075Sobrien	  return force_to_mode (x, mode, mask, reg, next_select);
706790075Sobrien	}
706890075Sobrien
706990075Sobrien      mask = fuller_mask;
707090075Sobrien      goto binop;
707190075Sobrien
707218334Speter    case IOR:
707318334Speter    case XOR:
707418334Speter      /* If X is (ior (lshiftrt FOO C1) C2), try to commute the IOR and
707518334Speter	 LSHIFTRT so we end up with an (and (lshiftrt (ior ...) ...) ...)
707618334Speter	 operation which may be a bitfield extraction.  Ensure that the
707718334Speter	 constant we form is not wider than the mode of X.  */
707818334Speter
707918334Speter      if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
708018334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
708118334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
708218334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT
708318334Speter	  && GET_CODE (XEXP (x, 1)) == CONST_INT
708418334Speter	  && ((INTVAL (XEXP (XEXP (x, 0), 1))
708518334Speter	       + floor_log2 (INTVAL (XEXP (x, 1))))
708618334Speter	      < GET_MODE_BITSIZE (GET_MODE (x)))
708718334Speter	  && (INTVAL (XEXP (x, 1))
708890075Sobrien	      & ~nonzero_bits (XEXP (x, 0), GET_MODE (x))) == 0)
708918334Speter	{
709018334Speter	  temp = GEN_INT ((INTVAL (XEXP (x, 1)) & mask)
709190075Sobrien			  << INTVAL (XEXP (XEXP (x, 0), 1)));
709218334Speter	  temp = gen_binary (GET_CODE (x), GET_MODE (x),
709318334Speter			     XEXP (XEXP (x, 0), 0), temp);
709450397Sobrien	  x = gen_binary (LSHIFTRT, GET_MODE (x), temp,
709550397Sobrien			  XEXP (XEXP (x, 0), 1));
709618334Speter	  return force_to_mode (x, mode, mask, reg, next_select);
709718334Speter	}
709818334Speter
709918334Speter    binop:
710018334Speter      /* For most binary operations, just propagate into the operation and
710190075Sobrien	 change the mode if we have an operation of that mode.  */
710218334Speter
710318334Speter      op0 = gen_lowpart_for_combine (op_mode,
710418334Speter				     force_to_mode (XEXP (x, 0), mode, mask,
710518334Speter						    reg, next_select));
710618334Speter      op1 = gen_lowpart_for_combine (op_mode,
710718334Speter				     force_to_mode (XEXP (x, 1), mode, mask,
710818334Speter						    reg, next_select));
710918334Speter
711018334Speter      if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
711118334Speter	x = gen_binary (code, op_mode, op0, op1);
711218334Speter      break;
711318334Speter
711418334Speter    case ASHIFT:
711518334Speter      /* For left shifts, do the same, but just for the first operand.
711618334Speter	 However, we cannot do anything with shifts where we cannot
711718334Speter	 guarantee that the counts are smaller than the size of the mode
711818334Speter	 because such a count will have a different meaning in a
711918334Speter	 wider mode.  */
712018334Speter
712118334Speter      if (! (GET_CODE (XEXP (x, 1)) == CONST_INT
712218334Speter	     && INTVAL (XEXP (x, 1)) >= 0
712318334Speter	     && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (mode))
712418334Speter	  && ! (GET_MODE (XEXP (x, 1)) != VOIDmode
712518334Speter		&& (nonzero_bits (XEXP (x, 1), GET_MODE (XEXP (x, 1)))
712618334Speter		    < (unsigned HOST_WIDE_INT) GET_MODE_BITSIZE (mode))))
712718334Speter	break;
712890075Sobrien
712918334Speter      /* If the shift count is a constant and we can do arithmetic in
713018334Speter	 the mode of the shift, refine which bits we need.  Otherwise, use the
713118334Speter	 conservative form of the mask.  */
713218334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
713318334Speter	  && INTVAL (XEXP (x, 1)) >= 0
713418334Speter	  && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (op_mode)
713518334Speter	  && GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT)
713618334Speter	mask >>= INTVAL (XEXP (x, 1));
713718334Speter      else
713818334Speter	mask = fuller_mask;
713918334Speter
714018334Speter      op0 = gen_lowpart_for_combine (op_mode,
714118334Speter				     force_to_mode (XEXP (x, 0), op_mode,
714218334Speter						    mask, reg, next_select));
714318334Speter
714418334Speter      if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0))
714590075Sobrien	x = gen_binary (code, op_mode, op0, XEXP (x, 1));
714618334Speter      break;
714718334Speter
714818334Speter    case LSHIFTRT:
714918334Speter      /* Here we can only do something if the shift count is a constant,
715018334Speter	 this shift constant is valid for the host, and we can do arithmetic
715118334Speter	 in OP_MODE.  */
715218334Speter
715318334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
715418334Speter	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
715518334Speter	  && GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT)
715618334Speter	{
715718334Speter	  rtx inner = XEXP (x, 0);
715890075Sobrien	  unsigned HOST_WIDE_INT inner_mask;
715918334Speter
716018334Speter	  /* Select the mask of the bits we need for the shift operand.  */
716190075Sobrien	  inner_mask = mask << INTVAL (XEXP (x, 1));
716218334Speter
716318334Speter	  /* We can only change the mode of the shift if we can do arithmetic
716490075Sobrien	     in the mode of the shift and INNER_MASK is no wider than the
716590075Sobrien	     width of OP_MODE.  */
716618334Speter	  if (GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT
716790075Sobrien	      || (inner_mask & ~GET_MODE_MASK (op_mode)) != 0)
716818334Speter	    op_mode = GET_MODE (x);
716918334Speter
717090075Sobrien	  inner = force_to_mode (inner, op_mode, inner_mask, reg, next_select);
717118334Speter
717218334Speter	  if (GET_MODE (x) != op_mode || inner != XEXP (x, 0))
717318334Speter	    x = gen_binary (LSHIFTRT, op_mode, inner, XEXP (x, 1));
717418334Speter	}
717518334Speter
717618334Speter      /* If we have (and (lshiftrt FOO C1) C2) where the combination of the
717718334Speter	 shift and AND produces only copies of the sign bit (C2 is one less
717818334Speter	 than a power of two), we can do this with just a shift.  */
717918334Speter
718018334Speter      if (GET_CODE (x) == LSHIFTRT
718118334Speter	  && GET_CODE (XEXP (x, 1)) == CONST_INT
718290075Sobrien	  /* The shift puts one of the sign bit copies in the least significant
718390075Sobrien	     bit.  */
718418334Speter	  && ((INTVAL (XEXP (x, 1))
718518334Speter	       + num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0))))
718618334Speter	      >= GET_MODE_BITSIZE (GET_MODE (x)))
718718334Speter	  && exact_log2 (mask + 1) >= 0
718890075Sobrien	  /* Number of bits left after the shift must be more than the mask
718990075Sobrien	     needs.  */
719090075Sobrien	  && ((INTVAL (XEXP (x, 1)) + exact_log2 (mask + 1))
719190075Sobrien	      <= GET_MODE_BITSIZE (GET_MODE (x)))
719290075Sobrien	  /* Must be more sign bit copies than the mask needs.  */
719390075Sobrien	  && ((int) num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
719418334Speter	      >= exact_log2 (mask + 1)))
719518334Speter	x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0),
719618334Speter			GEN_INT (GET_MODE_BITSIZE (GET_MODE (x))
719718334Speter				 - exact_log2 (mask + 1)));
719818334Speter
719990075Sobrien      goto shiftrt;
720090075Sobrien
720118334Speter    case ASHIFTRT:
720218334Speter      /* If we are just looking for the sign bit, we don't need this shift at
720318334Speter	 all, even if it has a variable count.  */
720418334Speter      if (GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
720552284Sobrien	  && (mask == ((unsigned HOST_WIDE_INT) 1
720618334Speter		       << (GET_MODE_BITSIZE (GET_MODE (x)) - 1))))
720718334Speter	return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select);
720818334Speter
720918334Speter      /* If this is a shift by a constant, get a mask that contains those bits
721018334Speter	 that are not copies of the sign bit.  We then have two cases:  If
721118334Speter	 MASK only includes those bits, this can be a logical shift, which may
721218334Speter	 allow simplifications.  If MASK is a single-bit field not within
721318334Speter	 those bits, we are requesting a copy of the sign bit and hence can
721418334Speter	 shift the sign bit to the appropriate location.  */
721518334Speter
721618334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) >= 0
721718334Speter	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
721818334Speter	{
721918334Speter	  int i = -1;
722018334Speter
722190075Sobrien	  /* If the considered data is wider than HOST_WIDE_INT, we can't
722218334Speter	     represent a mask for all its bits in a single scalar.
722318334Speter	     But we only care about the lower bits, so calculate these.  */
722418334Speter
722518334Speter	  if (GET_MODE_BITSIZE (GET_MODE (x)) > HOST_BITS_PER_WIDE_INT)
722618334Speter	    {
722790075Sobrien	      nonzero = ~(HOST_WIDE_INT) 0;
722818334Speter
722918334Speter	      /* GET_MODE_BITSIZE (GET_MODE (x)) - INTVAL (XEXP (x, 1))
723018334Speter		 is the number of bits a full-width mask would have set.
723118334Speter		 We need only shift if these are fewer than nonzero can
723218334Speter		 hold.  If not, we must keep all bits set in nonzero.  */
723318334Speter
723418334Speter	      if (GET_MODE_BITSIZE (GET_MODE (x)) - INTVAL (XEXP (x, 1))
723518334Speter		  < HOST_BITS_PER_WIDE_INT)
723618334Speter		nonzero >>= INTVAL (XEXP (x, 1))
723718334Speter			    + HOST_BITS_PER_WIDE_INT
723818334Speter			    - GET_MODE_BITSIZE (GET_MODE (x)) ;
723918334Speter	    }
724018334Speter	  else
724118334Speter	    {
724218334Speter	      nonzero = GET_MODE_MASK (GET_MODE (x));
724318334Speter	      nonzero >>= INTVAL (XEXP (x, 1));
724418334Speter	    }
724518334Speter
724690075Sobrien	  if ((mask & ~nonzero) == 0
724718334Speter	      || (i = exact_log2 (mask)) >= 0)
724818334Speter	    {
724918334Speter	      x = simplify_shift_const
725018334Speter		(x, LSHIFTRT, GET_MODE (x), XEXP (x, 0),
725118334Speter		 i < 0 ? INTVAL (XEXP (x, 1))
725218334Speter		 : GET_MODE_BITSIZE (GET_MODE (x)) - 1 - i);
725318334Speter
725418334Speter	      if (GET_CODE (x) != ASHIFTRT)
725518334Speter		return force_to_mode (x, mode, mask, reg, next_select);
725618334Speter	    }
725718334Speter	}
725818334Speter
7259117395Skan      /* If MASK is 1, convert this to an LSHIFTRT.  This can be done
726018334Speter	 even if the shift count isn't a constant.  */
726118334Speter      if (mask == 1)
726218334Speter	x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0), XEXP (x, 1));
726318334Speter
726490075Sobrien    shiftrt:
726590075Sobrien
726690075Sobrien      /* If this is a zero- or sign-extension operation that just affects bits
726718334Speter	 we don't care about, remove it.  Be sure the call above returned
726818334Speter	 something that is still a shift.  */
726918334Speter
727018334Speter      if ((GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ASHIFTRT)
727118334Speter	  && GET_CODE (XEXP (x, 1)) == CONST_INT
727218334Speter	  && INTVAL (XEXP (x, 1)) >= 0
727318334Speter	  && (INTVAL (XEXP (x, 1))
727418334Speter	      <= GET_MODE_BITSIZE (GET_MODE (x)) - (floor_log2 (mask) + 1))
727518334Speter	  && GET_CODE (XEXP (x, 0)) == ASHIFT
727618334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
727718334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) == INTVAL (XEXP (x, 1)))
727818334Speter	return force_to_mode (XEXP (XEXP (x, 0), 0), mode, mask,
727918334Speter			      reg, next_select);
728018334Speter
728118334Speter      break;
728218334Speter
728318334Speter    case ROTATE:
728418334Speter    case ROTATERT:
728518334Speter      /* If the shift count is constant and we can do computations
728618334Speter	 in the mode of X, compute where the bits we care about are.
728718334Speter	 Otherwise, we can't do anything.  Don't change the mode of
728818334Speter	 the shift or propagate MODE into the shift, though.  */
728918334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
729018334Speter	  && INTVAL (XEXP (x, 1)) >= 0)
729118334Speter	{
729218334Speter	  temp = simplify_binary_operation (code == ROTATE ? ROTATERT : ROTATE,
729318334Speter					    GET_MODE (x), GEN_INT (mask),
729418334Speter					    XEXP (x, 1));
729518334Speter	  if (temp && GET_CODE(temp) == CONST_INT)
729618334Speter	    SUBST (XEXP (x, 0),
729718334Speter		   force_to_mode (XEXP (x, 0), GET_MODE (x),
729818334Speter				  INTVAL (temp), reg, next_select));
729918334Speter	}
730018334Speter      break;
730190075Sobrien
730218334Speter    case NEG:
730318334Speter      /* If we just want the low-order bit, the NEG isn't needed since it
730490075Sobrien	 won't change the low-order bit.  */
730518334Speter      if (mask == 1)
730618334Speter	return force_to_mode (XEXP (x, 0), mode, mask, reg, just_select);
730718334Speter
730818334Speter      /* We need any bits less significant than the most significant bit in
730918334Speter	 MASK since carries from those bits will affect the bits we are
731018334Speter	 interested in.  */
731118334Speter      mask = fuller_mask;
731218334Speter      goto unop;
731318334Speter
731418334Speter    case NOT:
731518334Speter      /* (not FOO) is (xor FOO CONST), so if FOO is an LSHIFTRT, we can do the
731618334Speter	 same as the XOR case above.  Ensure that the constant we form is not
731718334Speter	 wider than the mode of X.  */
731818334Speter
731918334Speter      if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
732018334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
732118334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
732218334Speter	  && (INTVAL (XEXP (XEXP (x, 0), 1)) + floor_log2 (mask)
732318334Speter	      < GET_MODE_BITSIZE (GET_MODE (x)))
732418334Speter	  && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT)
732518334Speter	{
7326117395Skan	  temp = gen_int_mode (mask << INTVAL (XEXP (XEXP (x, 0), 1)),
7327117395Skan			       GET_MODE (x));
732818334Speter	  temp = gen_binary (XOR, GET_MODE (x), XEXP (XEXP (x, 0), 0), temp);
732918334Speter	  x = gen_binary (LSHIFTRT, GET_MODE (x), temp, XEXP (XEXP (x, 0), 1));
733018334Speter
733118334Speter	  return force_to_mode (x, mode, mask, reg, next_select);
733218334Speter	}
733318334Speter
733450397Sobrien      /* (and (not FOO) CONST) is (not (or FOO (not CONST))), so we must
733550397Sobrien	 use the full mask inside the NOT.  */
733650397Sobrien      mask = fuller_mask;
733750397Sobrien
733818334Speter    unop:
733918334Speter      op0 = gen_lowpart_for_combine (op_mode,
734018334Speter				     force_to_mode (XEXP (x, 0), mode, mask,
734118334Speter						    reg, next_select));
734218334Speter      if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0))
734390075Sobrien	x = simplify_gen_unary (code, op_mode, op0, op_mode);
734418334Speter      break;
734518334Speter
734618334Speter    case NE:
734718334Speter      /* (and (ne FOO 0) CONST) can be (and FOO CONST) if CONST is included
734850397Sobrien	 in STORE_FLAG_VALUE and FOO has a single bit that might be nonzero,
734950397Sobrien	 which is equal to STORE_FLAG_VALUE.  */
735090075Sobrien      if ((mask & ~STORE_FLAG_VALUE) == 0 && XEXP (x, 1) == const0_rtx
735150397Sobrien	  && exact_log2 (nonzero_bits (XEXP (x, 0), mode)) >= 0
735250397Sobrien	  && nonzero_bits (XEXP (x, 0), mode) == STORE_FLAG_VALUE)
735318334Speter	return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select);
735418334Speter
735518334Speter      break;
735618334Speter
735718334Speter    case IF_THEN_ELSE:
735818334Speter      /* We have no way of knowing if the IF_THEN_ELSE can itself be
735918334Speter	 written in a narrower mode.  We play it safe and do not do so.  */
736018334Speter
736118334Speter      SUBST (XEXP (x, 1),
736218334Speter	     gen_lowpart_for_combine (GET_MODE (x),
736318334Speter				      force_to_mode (XEXP (x, 1), mode,
736418334Speter						     mask, reg, next_select)));
736518334Speter      SUBST (XEXP (x, 2),
736618334Speter	     gen_lowpart_for_combine (GET_MODE (x),
736718334Speter				      force_to_mode (XEXP (x, 2), mode,
736818334Speter						     mask, reg,next_select)));
736918334Speter      break;
737090075Sobrien
737150397Sobrien    default:
737250397Sobrien      break;
737318334Speter    }
737418334Speter
737518334Speter  /* Ensure we return a value of the proper mode.  */
737618334Speter  return gen_lowpart_for_combine (mode, x);
737718334Speter}
737818334Speter
737918334Speter/* Return nonzero if X is an expression that has one of two values depending on
738018334Speter   whether some other value is zero or nonzero.  In that case, we return the
738118334Speter   value that is being tested, *PTRUE is set to the value if the rtx being
738218334Speter   returned has a nonzero value, and *PFALSE is set to the other alternative.
738318334Speter
738418334Speter   If we return zero, we set *PTRUE and *PFALSE to X.  */
738518334Speter
738618334Speterstatic rtx
738718334Speterif_then_else_cond (x, ptrue, pfalse)
738818334Speter     rtx x;
738918334Speter     rtx *ptrue, *pfalse;
739018334Speter{
739118334Speter  enum machine_mode mode = GET_MODE (x);
739218334Speter  enum rtx_code code = GET_CODE (x);
739318334Speter  rtx cond0, cond1, true0, true1, false0, false1;
739418334Speter  unsigned HOST_WIDE_INT nz;
739518334Speter
739690075Sobrien  /* If we are comparing a value against zero, we are done.  */
739790075Sobrien  if ((code == NE || code == EQ)
739890075Sobrien      && GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 0)
739990075Sobrien    {
740090075Sobrien      *ptrue = (code == NE) ? const_true_rtx : const0_rtx;
740190075Sobrien      *pfalse = (code == NE) ? const0_rtx : const_true_rtx;
740290075Sobrien      return XEXP (x, 0);
740390075Sobrien    }
740490075Sobrien
740518334Speter  /* If this is a unary operation whose operand has one of two values, apply
740618334Speter     our opcode to compute those values.  */
740790075Sobrien  else if (GET_RTX_CLASS (code) == '1'
740890075Sobrien	   && (cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0)) != 0)
740918334Speter    {
741090075Sobrien      *ptrue = simplify_gen_unary (code, mode, true0, GET_MODE (XEXP (x, 0)));
741190075Sobrien      *pfalse = simplify_gen_unary (code, mode, false0,
741290075Sobrien				    GET_MODE (XEXP (x, 0)));
741318334Speter      return cond0;
741418334Speter    }
741518334Speter
741618334Speter  /* If this is a COMPARE, do nothing, since the IF_THEN_ELSE we would
741718334Speter     make can't possibly match and would suppress other optimizations.  */
741818334Speter  else if (code == COMPARE)
741918334Speter    ;
742018334Speter
742118334Speter  /* If this is a binary operation, see if either side has only one of two
742218334Speter     values.  If either one does or if both do and they are conditional on
742318334Speter     the same value, compute the new true and false values.  */
742418334Speter  else if (GET_RTX_CLASS (code) == 'c' || GET_RTX_CLASS (code) == '2'
742518334Speter	   || GET_RTX_CLASS (code) == '<')
742618334Speter    {
742718334Speter      cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0);
742818334Speter      cond1 = if_then_else_cond (XEXP (x, 1), &true1, &false1);
742918334Speter
743018334Speter      if ((cond0 != 0 || cond1 != 0)
743118334Speter	  && ! (cond0 != 0 && cond1 != 0 && ! rtx_equal_p (cond0, cond1)))
743218334Speter	{
743350397Sobrien	  /* If if_then_else_cond returned zero, then true/false are the
743450397Sobrien	     same rtl.  We must copy one of them to prevent invalid rtl
743550397Sobrien	     sharing.  */
743650397Sobrien	  if (cond0 == 0)
743750397Sobrien	    true0 = copy_rtx (true0);
743850397Sobrien	  else if (cond1 == 0)
743950397Sobrien	    true1 = copy_rtx (true1);
744050397Sobrien
744118334Speter	  *ptrue = gen_binary (code, mode, true0, true1);
744218334Speter	  *pfalse = gen_binary (code, mode, false0, false1);
744318334Speter	  return cond0 ? cond0 : cond1;
744418334Speter	}
744518334Speter
744618334Speter      /* See if we have PLUS, IOR, XOR, MINUS or UMAX, where one of the
7447117395Skan	 operands is zero when the other is nonzero, and vice-versa,
744850397Sobrien	 and STORE_FLAG_VALUE is 1 or -1.  */
744918334Speter
745050397Sobrien      if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
745150397Sobrien	  && (code == PLUS || code == IOR || code == XOR || code == MINUS
745290075Sobrien	      || code == UMAX)
745318334Speter	  && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == MULT)
745418334Speter	{
745518334Speter	  rtx op0 = XEXP (XEXP (x, 0), 1);
745618334Speter	  rtx op1 = XEXP (XEXP (x, 1), 1);
745718334Speter
745818334Speter	  cond0 = XEXP (XEXP (x, 0), 0);
745918334Speter	  cond1 = XEXP (XEXP (x, 1), 0);
746018334Speter
746118334Speter	  if (GET_RTX_CLASS (GET_CODE (cond0)) == '<'
746218334Speter	      && GET_RTX_CLASS (GET_CODE (cond1)) == '<'
746390075Sobrien	      && ((GET_CODE (cond0) == combine_reversed_comparison_code (cond1)
746418334Speter		   && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0))
746518334Speter		   && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1)))
746618334Speter		  || ((swap_condition (GET_CODE (cond0))
746790075Sobrien		       == combine_reversed_comparison_code (cond1))
746818334Speter		      && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 1))
746918334Speter		      && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0))))
747018334Speter	      && ! side_effects_p (x))
747118334Speter	    {
747218334Speter	      *ptrue = gen_binary (MULT, mode, op0, const_true_rtx);
747390075Sobrien	      *pfalse = gen_binary (MULT, mode,
747490075Sobrien				    (code == MINUS
747590075Sobrien				     ? simplify_gen_unary (NEG, mode, op1,
747690075Sobrien							   mode)
747790075Sobrien				     : op1),
747818334Speter				    const_true_rtx);
747918334Speter	      return cond0;
748018334Speter	    }
748118334Speter	}
748218334Speter
748390075Sobrien      /* Similarly for MULT, AND and UMIN, except that for these the result
748418334Speter	 is always zero.  */
748550397Sobrien      if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
748650397Sobrien	  && (code == MULT || code == AND || code == UMIN)
748718334Speter	  && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == MULT)
748818334Speter	{
748918334Speter	  cond0 = XEXP (XEXP (x, 0), 0);
749018334Speter	  cond1 = XEXP (XEXP (x, 1), 0);
749118334Speter
749218334Speter	  if (GET_RTX_CLASS (GET_CODE (cond0)) == '<'
749318334Speter	      && GET_RTX_CLASS (GET_CODE (cond1)) == '<'
749490075Sobrien	      && ((GET_CODE (cond0) == combine_reversed_comparison_code (cond1)
749518334Speter		   && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0))
749618334Speter		   && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1)))
749718334Speter		  || ((swap_condition (GET_CODE (cond0))
749890075Sobrien		       == combine_reversed_comparison_code (cond1))
749918334Speter		      && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 1))
750018334Speter		      && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0))))
750118334Speter	      && ! side_effects_p (x))
750218334Speter	    {
750318334Speter	      *ptrue = *pfalse = const0_rtx;
750418334Speter	      return cond0;
750518334Speter	    }
750618334Speter	}
750718334Speter    }
750818334Speter
750918334Speter  else if (code == IF_THEN_ELSE)
751018334Speter    {
751118334Speter      /* If we have IF_THEN_ELSE already, extract the condition and
751218334Speter	 canonicalize it if it is NE or EQ.  */
751318334Speter      cond0 = XEXP (x, 0);
751418334Speter      *ptrue = XEXP (x, 1), *pfalse = XEXP (x, 2);
751518334Speter      if (GET_CODE (cond0) == NE && XEXP (cond0, 1) == const0_rtx)
751618334Speter	return XEXP (cond0, 0);
751718334Speter      else if (GET_CODE (cond0) == EQ && XEXP (cond0, 1) == const0_rtx)
751818334Speter	{
751918334Speter	  *ptrue = XEXP (x, 2), *pfalse = XEXP (x, 1);
752018334Speter	  return XEXP (cond0, 0);
752118334Speter	}
752218334Speter      else
752318334Speter	return cond0;
752418334Speter    }
752518334Speter
752690075Sobrien  /* If X is a SUBREG, we can narrow both the true and false values
752790075Sobrien     if the inner expression, if there is a condition.  */
752890075Sobrien  else if (code == SUBREG
752918334Speter	   && 0 != (cond0 = if_then_else_cond (SUBREG_REG (x),
753018334Speter					       &true0, &false0)))
753118334Speter    {
753290075Sobrien      *ptrue = simplify_gen_subreg (mode, true0,
753390075Sobrien				    GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
753490075Sobrien      *pfalse = simplify_gen_subreg (mode, false0,
753590075Sobrien				     GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
753618334Speter
753718334Speter      return cond0;
753818334Speter    }
753918334Speter
754018334Speter  /* If X is a constant, this isn't special and will cause confusions
754118334Speter     if we treat it as such.  Likewise if it is equivalent to a constant.  */
754218334Speter  else if (CONSTANT_P (x)
754318334Speter	   || ((cond0 = get_last_value (x)) != 0 && CONSTANT_P (cond0)))
754418334Speter    ;
754518334Speter
754690075Sobrien  /* If we're in BImode, canonicalize on 0 and STORE_FLAG_VALUE, as that
754790075Sobrien     will be least confusing to the rest of the compiler.  */
754890075Sobrien  else if (mode == BImode)
754990075Sobrien    {
755090075Sobrien      *ptrue = GEN_INT (STORE_FLAG_VALUE), *pfalse = const0_rtx;
755190075Sobrien      return x;
755290075Sobrien    }
755390075Sobrien
755490075Sobrien  /* If X is known to be either 0 or -1, those are the true and
755518334Speter     false values when testing X.  */
755690075Sobrien  else if (x == constm1_rtx || x == const0_rtx
755790075Sobrien	   || (mode != VOIDmode
755890075Sobrien	       && num_sign_bit_copies (x, mode) == GET_MODE_BITSIZE (mode)))
755918334Speter    {
756018334Speter      *ptrue = constm1_rtx, *pfalse = const0_rtx;
756118334Speter      return x;
756218334Speter    }
756318334Speter
756418334Speter  /* Likewise for 0 or a single bit.  */
756590075Sobrien  else if (mode != VOIDmode
756690075Sobrien	   && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
756790075Sobrien	   && exact_log2 (nz = nonzero_bits (x, mode)) >= 0)
756818334Speter    {
7569117395Skan      *ptrue = gen_int_mode (nz, mode), *pfalse = const0_rtx;
757018334Speter      return x;
757118334Speter    }
757218334Speter
757318334Speter  /* Otherwise fail; show no condition with true and false values the same.  */
757418334Speter  *ptrue = *pfalse = x;
757518334Speter  return 0;
757618334Speter}
757718334Speter
757818334Speter/* Return the value of expression X given the fact that condition COND
757918334Speter   is known to be true when applied to REG as its first operand and VAL
758018334Speter   as its second.  X is known to not be shared and so can be modified in
758118334Speter   place.
758218334Speter
758318334Speter   We only handle the simplest cases, and specifically those cases that
758418334Speter   arise with IF_THEN_ELSE expressions.  */
758518334Speter
758618334Speterstatic rtx
758718334Speterknown_cond (x, cond, reg, val)
758818334Speter     rtx x;
758918334Speter     enum rtx_code cond;
759018334Speter     rtx reg, val;
759118334Speter{
759218334Speter  enum rtx_code code = GET_CODE (x);
759318334Speter  rtx temp;
759490075Sobrien  const char *fmt;
759518334Speter  int i, j;
759618334Speter
759718334Speter  if (side_effects_p (x))
759818334Speter    return x;
759918334Speter
760090075Sobrien  /* If either operand of the condition is a floating point value,
760190075Sobrien     then we have to avoid collapsing an EQ comparison.  */
760290075Sobrien  if (cond == EQ
760390075Sobrien      && rtx_equal_p (x, reg)
760490075Sobrien      && ! FLOAT_MODE_P (GET_MODE (x))
760590075Sobrien      && ! FLOAT_MODE_P (GET_MODE (val)))
760618334Speter    return val;
760718334Speter
760890075Sobrien  if (cond == UNEQ && rtx_equal_p (x, reg))
760990075Sobrien    return val;
761090075Sobrien
761118334Speter  /* If X is (abs REG) and we know something about REG's relationship
761218334Speter     with zero, we may be able to simplify this.  */
761318334Speter
761418334Speter  if (code == ABS && rtx_equal_p (XEXP (x, 0), reg) && val == const0_rtx)
761518334Speter    switch (cond)
761618334Speter      {
761718334Speter      case GE:  case GT:  case EQ:
761818334Speter	return XEXP (x, 0);
761918334Speter      case LT:  case LE:
762090075Sobrien	return simplify_gen_unary (NEG, GET_MODE (XEXP (x, 0)),
762190075Sobrien				   XEXP (x, 0),
762290075Sobrien				   GET_MODE (XEXP (x, 0)));
762350397Sobrien      default:
762450397Sobrien	break;
762518334Speter      }
762618334Speter
762718334Speter  /* The only other cases we handle are MIN, MAX, and comparisons if the
762818334Speter     operands are the same as REG and VAL.  */
762918334Speter
763018334Speter  else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == 'c')
763118334Speter    {
763218334Speter      if (rtx_equal_p (XEXP (x, 0), val))
763318334Speter	cond = swap_condition (cond), temp = val, val = reg, reg = temp;
763418334Speter
763518334Speter      if (rtx_equal_p (XEXP (x, 0), reg) && rtx_equal_p (XEXP (x, 1), val))
763618334Speter	{
763718334Speter	  if (GET_RTX_CLASS (code) == '<')
763890075Sobrien	    {
763990075Sobrien	      if (comparison_dominates_p (cond, code))
764090075Sobrien		return const_true_rtx;
764118334Speter
764290075Sobrien	      code = combine_reversed_comparison_code (x);
764390075Sobrien	      if (code != UNKNOWN
764490075Sobrien		  && comparison_dominates_p (cond, code))
764590075Sobrien		return const0_rtx;
764690075Sobrien	      else
764790075Sobrien		return x;
764890075Sobrien	    }
764918334Speter	  else if (code == SMAX || code == SMIN
765018334Speter		   || code == UMIN || code == UMAX)
765118334Speter	    {
765218334Speter	      int unsignedp = (code == UMIN || code == UMAX);
765318334Speter
765490075Sobrien	      /* Do not reverse the condition when it is NE or EQ.
765590075Sobrien		 This is because we cannot conclude anything about
765690075Sobrien		 the value of 'SMAX (x, y)' when x is not equal to y,
765790075Sobrien		 but we can when x equals y.  */
765890075Sobrien	      if ((code == SMAX || code == UMAX)
765990075Sobrien		  && ! (cond == EQ || cond == NE))
766018334Speter		cond = reverse_condition (cond);
766118334Speter
766218334Speter	      switch (cond)
766318334Speter		{
766418334Speter		case GE:   case GT:
766518334Speter		  return unsignedp ? x : XEXP (x, 1);
766618334Speter		case LE:   case LT:
766718334Speter		  return unsignedp ? x : XEXP (x, 0);
766818334Speter		case GEU:  case GTU:
766918334Speter		  return unsignedp ? XEXP (x, 1) : x;
767018334Speter		case LEU:  case LTU:
767118334Speter		  return unsignedp ? XEXP (x, 0) : x;
767250397Sobrien		default:
767350397Sobrien		  break;
767418334Speter		}
767518334Speter	    }
767618334Speter	}
767718334Speter    }
767896263Sobrien  else if (code == SUBREG)
767996263Sobrien    {
768096263Sobrien      enum machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
768196263Sobrien      rtx new, r = known_cond (SUBREG_REG (x), cond, reg, val);
768218334Speter
768396263Sobrien      if (SUBREG_REG (x) != r)
768496263Sobrien	{
768596263Sobrien	  /* We must simplify subreg here, before we lose track of the
768696263Sobrien	     original inner_mode.  */
768796263Sobrien	  new = simplify_subreg (GET_MODE (x), r,
768896263Sobrien				 inner_mode, SUBREG_BYTE (x));
768996263Sobrien	  if (new)
769096263Sobrien	    return new;
769196263Sobrien	  else
769296263Sobrien	    SUBST (SUBREG_REG (x), r);
769396263Sobrien	}
769496263Sobrien
769596263Sobrien      return x;
769696263Sobrien    }
769796263Sobrien  /* We don't have to handle SIGN_EXTEND here, because even in the
769896263Sobrien     case of replacing something with a modeless CONST_INT, a
769996263Sobrien     CONST_INT is already (supposed to be) a valid sign extension for
770096263Sobrien     its narrower mode, which implies it's already properly
770196263Sobrien     sign-extended for the wider mode.  Now, for ZERO_EXTEND, the
770296263Sobrien     story is different.  */
770396263Sobrien  else if (code == ZERO_EXTEND)
770496263Sobrien    {
770596263Sobrien      enum machine_mode inner_mode = GET_MODE (XEXP (x, 0));
770696263Sobrien      rtx new, r = known_cond (XEXP (x, 0), cond, reg, val);
770796263Sobrien
770896263Sobrien      if (XEXP (x, 0) != r)
770996263Sobrien	{
771096263Sobrien	  /* We must simplify the zero_extend here, before we lose
771196263Sobrien             track of the original inner_mode.  */
771296263Sobrien	  new = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
771396263Sobrien					  r, inner_mode);
771496263Sobrien	  if (new)
771596263Sobrien	    return new;
771696263Sobrien	  else
771796263Sobrien	    SUBST (XEXP (x, 0), r);
771896263Sobrien	}
771996263Sobrien
772096263Sobrien      return x;
772196263Sobrien    }
772296263Sobrien
772318334Speter  fmt = GET_RTX_FORMAT (code);
772418334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
772518334Speter    {
772618334Speter      if (fmt[i] == 'e')
772718334Speter	SUBST (XEXP (x, i), known_cond (XEXP (x, i), cond, reg, val));
772818334Speter      else if (fmt[i] == 'E')
772918334Speter	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
773018334Speter	  SUBST (XVECEXP (x, i, j), known_cond (XVECEXP (x, i, j),
773118334Speter						cond, reg, val));
773218334Speter    }
773318334Speter
773418334Speter  return x;
773518334Speter}
773618334Speter
773750397Sobrien/* See if X and Y are equal for the purposes of seeing if we can rewrite an
773850397Sobrien   assignment as a field assignment.  */
773950397Sobrien
774050397Sobrienstatic int
774150397Sobrienrtx_equal_for_field_assignment_p (x, y)
774250397Sobrien     rtx x;
774350397Sobrien     rtx y;
774450397Sobrien{
774550397Sobrien  if (x == y || rtx_equal_p (x, y))
774650397Sobrien    return 1;
774750397Sobrien
774850397Sobrien  if (x == 0 || y == 0 || GET_MODE (x) != GET_MODE (y))
774950397Sobrien    return 0;
775050397Sobrien
775150397Sobrien  /* Check for a paradoxical SUBREG of a MEM compared with the MEM.
775250397Sobrien     Note that all SUBREGs of MEM are paradoxical; otherwise they
775350397Sobrien     would have been rewritten.  */
775450397Sobrien  if (GET_CODE (x) == MEM && GET_CODE (y) == SUBREG
775550397Sobrien      && GET_CODE (SUBREG_REG (y)) == MEM
775650397Sobrien      && rtx_equal_p (SUBREG_REG (y),
775750397Sobrien		      gen_lowpart_for_combine (GET_MODE (SUBREG_REG (y)), x)))
775850397Sobrien    return 1;
775950397Sobrien
776050397Sobrien  if (GET_CODE (y) == MEM && GET_CODE (x) == SUBREG
776150397Sobrien      && GET_CODE (SUBREG_REG (x)) == MEM
776250397Sobrien      && rtx_equal_p (SUBREG_REG (x),
776350397Sobrien		      gen_lowpart_for_combine (GET_MODE (SUBREG_REG (x)), y)))
776450397Sobrien    return 1;
776550397Sobrien
776650397Sobrien  /* We used to see if get_last_value of X and Y were the same but that's
776750397Sobrien     not correct.  In one direction, we'll cause the assignment to have
776850397Sobrien     the wrong destination and in the case, we'll import a register into this
776950397Sobrien     insn that might have already have been dead.   So fail if none of the
777050397Sobrien     above cases are true.  */
777150397Sobrien  return 0;
777250397Sobrien}
777350397Sobrien
777418334Speter/* See if X, a SET operation, can be rewritten as a bit-field assignment.
777518334Speter   Return that assignment if so.
777618334Speter
777718334Speter   We only handle the most common cases.  */
777818334Speter
777918334Speterstatic rtx
778018334Spetermake_field_assignment (x)
778118334Speter     rtx x;
778218334Speter{
778318334Speter  rtx dest = SET_DEST (x);
778418334Speter  rtx src = SET_SRC (x);
778518334Speter  rtx assign;
778650397Sobrien  rtx rhs, lhs;
778718334Speter  HOST_WIDE_INT c1;
778890075Sobrien  HOST_WIDE_INT pos;
778990075Sobrien  unsigned HOST_WIDE_INT len;
779018334Speter  rtx other;
779118334Speter  enum machine_mode mode;
779218334Speter
779318334Speter  /* If SRC was (and (not (ashift (const_int 1) POS)) DEST), this is
779418334Speter     a clear of a one-bit field.  We will have changed it to
779518334Speter     (and (rotate (const_int -2) POS) DEST), so check for that.  Also check
779618334Speter     for a SUBREG.  */
779718334Speter
779818334Speter  if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == ROTATE
779918334Speter      && GET_CODE (XEXP (XEXP (src, 0), 0)) == CONST_INT
780018334Speter      && INTVAL (XEXP (XEXP (src, 0), 0)) == -2
780150397Sobrien      && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
780218334Speter    {
780318334Speter      assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1),
780418334Speter				1, 1, 1, 0);
780550397Sobrien      if (assign != 0)
780650397Sobrien	return gen_rtx_SET (VOIDmode, assign, const0_rtx);
780750397Sobrien      return x;
780818334Speter    }
780918334Speter
781018334Speter  else if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == SUBREG
781118334Speter	   && subreg_lowpart_p (XEXP (src, 0))
781290075Sobrien	   && (GET_MODE_SIZE (GET_MODE (XEXP (src, 0)))
781318334Speter	       < GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (src, 0)))))
781418334Speter	   && GET_CODE (SUBREG_REG (XEXP (src, 0))) == ROTATE
781518334Speter	   && INTVAL (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == -2
781650397Sobrien	   && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
781718334Speter    {
781818334Speter      assign = make_extraction (VOIDmode, dest, 0,
781918334Speter				XEXP (SUBREG_REG (XEXP (src, 0)), 1),
782018334Speter				1, 1, 1, 0);
782150397Sobrien      if (assign != 0)
782250397Sobrien	return gen_rtx_SET (VOIDmode, assign, const0_rtx);
782350397Sobrien      return x;
782418334Speter    }
782518334Speter
782650397Sobrien  /* If SRC is (ior (ashift (const_int 1) POS) DEST), this is a set of a
782718334Speter     one-bit field.  */
782818334Speter  else if (GET_CODE (src) == IOR && GET_CODE (XEXP (src, 0)) == ASHIFT
782918334Speter	   && XEXP (XEXP (src, 0), 0) == const1_rtx
783050397Sobrien	   && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
783118334Speter    {
783218334Speter      assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1),
783318334Speter				1, 1, 1, 0);
783450397Sobrien      if (assign != 0)
783550397Sobrien	return gen_rtx_SET (VOIDmode, assign, const1_rtx);
783650397Sobrien      return x;
783718334Speter    }
783818334Speter
783918334Speter  /* The other case we handle is assignments into a constant-position
784050397Sobrien     field.  They look like (ior/xor (and DEST C1) OTHER).  If C1 represents
784118334Speter     a mask that has all one bits except for a group of zero bits and
784218334Speter     OTHER is known to have zeros where C1 has ones, this is such an
784318334Speter     assignment.  Compute the position and length from C1.  Shift OTHER
784418334Speter     to the appropriate position, force it to the required mode, and
784518334Speter     make the extraction.  Check for the AND in both operands.  */
784618334Speter
784750397Sobrien  if (GET_CODE (src) != IOR && GET_CODE (src) != XOR)
784850397Sobrien    return x;
784950397Sobrien
785050397Sobrien  rhs = expand_compound_operation (XEXP (src, 0));
785150397Sobrien  lhs = expand_compound_operation (XEXP (src, 1));
785250397Sobrien
785350397Sobrien  if (GET_CODE (rhs) == AND
785450397Sobrien      && GET_CODE (XEXP (rhs, 1)) == CONST_INT
785550397Sobrien      && rtx_equal_for_field_assignment_p (XEXP (rhs, 0), dest))
785650397Sobrien    c1 = INTVAL (XEXP (rhs, 1)), other = lhs;
785750397Sobrien  else if (GET_CODE (lhs) == AND
785850397Sobrien	   && GET_CODE (XEXP (lhs, 1)) == CONST_INT
785950397Sobrien	   && rtx_equal_for_field_assignment_p (XEXP (lhs, 0), dest))
786050397Sobrien    c1 = INTVAL (XEXP (lhs, 1)), other = rhs;
786118334Speter  else
786218334Speter    return x;
786318334Speter
786490075Sobrien  pos = get_pos_from_mask ((~c1) & GET_MODE_MASK (GET_MODE (dest)), &len);
786518334Speter  if (pos < 0 || pos + len > GET_MODE_BITSIZE (GET_MODE (dest))
786650397Sobrien      || GET_MODE_BITSIZE (GET_MODE (dest)) > HOST_BITS_PER_WIDE_INT
786750397Sobrien      || (c1 & nonzero_bits (other, GET_MODE (dest))) != 0)
786818334Speter    return x;
786918334Speter
787018334Speter  assign = make_extraction (VOIDmode, dest, pos, NULL_RTX, len, 1, 1, 0);
787150397Sobrien  if (assign == 0)
787250397Sobrien    return x;
787318334Speter
787418334Speter  /* The mode to use for the source is the mode of the assignment, or of
787518334Speter     what is inside a possible STRICT_LOW_PART.  */
787690075Sobrien  mode = (GET_CODE (assign) == STRICT_LOW_PART
787718334Speter	  ? GET_MODE (XEXP (assign, 0)) : GET_MODE (assign));
787818334Speter
787918334Speter  /* Shift OTHER right POS places and make it the source, restricting it
788018334Speter     to the proper length and mode.  */
788118334Speter
788218334Speter  src = force_to_mode (simplify_shift_const (NULL_RTX, LSHIFTRT,
788318334Speter					     GET_MODE (src), other, pos),
788418334Speter		       mode,
788518334Speter		       GET_MODE_BITSIZE (mode) >= HOST_BITS_PER_WIDE_INT
788690075Sobrien		       ? ~(unsigned HOST_WIDE_INT) 0
788790075Sobrien		       : ((unsigned HOST_WIDE_INT) 1 << len) - 1,
788818334Speter		       dest, 0);
788918334Speter
789090075Sobrien  return gen_rtx_SET (VOIDmode, assign, src);
789118334Speter}
789218334Speter
789318334Speter/* See if X is of the form (+ (* a c) (* b c)) and convert to (* (+ a b) c)
789418334Speter   if so.  */
789518334Speter
789618334Speterstatic rtx
789718334Speterapply_distributive_law (x)
789818334Speter     rtx x;
789918334Speter{
790018334Speter  enum rtx_code code = GET_CODE (x);
790118334Speter  rtx lhs, rhs, other;
790218334Speter  rtx tem;
790318334Speter  enum rtx_code inner_code;
790418334Speter
790518334Speter  /* Distributivity is not true for floating point.
790618334Speter     It can change the value.  So don't do it.
790718334Speter     -- rms and moshier@world.std.com.  */
790818334Speter  if (FLOAT_MODE_P (GET_MODE (x)))
790918334Speter    return x;
791018334Speter
791118334Speter  /* The outer operation can only be one of the following:  */
791218334Speter  if (code != IOR && code != AND && code != XOR
791318334Speter      && code != PLUS && code != MINUS)
791418334Speter    return x;
791518334Speter
791618334Speter  lhs = XEXP (x, 0), rhs = XEXP (x, 1);
791718334Speter
791850397Sobrien  /* If either operand is a primitive we can't do anything, so get out
791950397Sobrien     fast.  */
792018334Speter  if (GET_RTX_CLASS (GET_CODE (lhs)) == 'o'
792118334Speter      || GET_RTX_CLASS (GET_CODE (rhs)) == 'o')
792218334Speter    return x;
792318334Speter
792418334Speter  lhs = expand_compound_operation (lhs);
792518334Speter  rhs = expand_compound_operation (rhs);
792618334Speter  inner_code = GET_CODE (lhs);
792718334Speter  if (inner_code != GET_CODE (rhs))
792818334Speter    return x;
792918334Speter
793018334Speter  /* See if the inner and outer operations distribute.  */
793118334Speter  switch (inner_code)
793218334Speter    {
793318334Speter    case LSHIFTRT:
793418334Speter    case ASHIFTRT:
793518334Speter    case AND:
793618334Speter    case IOR:
793718334Speter      /* These all distribute except over PLUS.  */
793818334Speter      if (code == PLUS || code == MINUS)
793918334Speter	return x;
794018334Speter      break;
794118334Speter
794218334Speter    case MULT:
794318334Speter      if (code != PLUS && code != MINUS)
794418334Speter	return x;
794518334Speter      break;
794618334Speter
794718334Speter    case ASHIFT:
794818334Speter      /* This is also a multiply, so it distributes over everything.  */
794918334Speter      break;
795018334Speter
795118334Speter    case SUBREG:
795218334Speter      /* Non-paradoxical SUBREGs distributes over all operations, provided
795390075Sobrien	 the inner modes and byte offsets are the same, this is an extraction
795418334Speter	 of a low-order part, we don't convert an fp operation to int or
795518334Speter	 vice versa, and we would not be converting a single-word
795618334Speter	 operation into a multi-word operation.  The latter test is not
795718334Speter	 required, but it prevents generating unneeded multi-word operations.
795818334Speter	 Some of the previous tests are redundant given the latter test, but
795918334Speter	 are retained because they are required for correctness.
796018334Speter
796118334Speter	 We produce the result slightly differently in this case.  */
796218334Speter
796318334Speter      if (GET_MODE (SUBREG_REG (lhs)) != GET_MODE (SUBREG_REG (rhs))
796490075Sobrien	  || SUBREG_BYTE (lhs) != SUBREG_BYTE (rhs)
796518334Speter	  || ! subreg_lowpart_p (lhs)
796618334Speter	  || (GET_MODE_CLASS (GET_MODE (lhs))
796718334Speter	      != GET_MODE_CLASS (GET_MODE (SUBREG_REG (lhs))))
796818334Speter	  || (GET_MODE_SIZE (GET_MODE (lhs))
796918334Speter	      > GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))))
797018334Speter	  || GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))) > UNITS_PER_WORD)
797118334Speter	return x;
797218334Speter
797318334Speter      tem = gen_binary (code, GET_MODE (SUBREG_REG (lhs)),
797418334Speter			SUBREG_REG (lhs), SUBREG_REG (rhs));
797518334Speter      return gen_lowpart_for_combine (GET_MODE (x), tem);
797618334Speter
797718334Speter    default:
797818334Speter      return x;
797918334Speter    }
798018334Speter
798118334Speter  /* Set LHS and RHS to the inner operands (A and B in the example
798218334Speter     above) and set OTHER to the common operand (C in the example).
798318334Speter     These is only one way to do this unless the inner operation is
798418334Speter     commutative.  */
798518334Speter  if (GET_RTX_CLASS (inner_code) == 'c'
798618334Speter      && rtx_equal_p (XEXP (lhs, 0), XEXP (rhs, 0)))
798718334Speter    other = XEXP (lhs, 0), lhs = XEXP (lhs, 1), rhs = XEXP (rhs, 1);
798818334Speter  else if (GET_RTX_CLASS (inner_code) == 'c'
798918334Speter	   && rtx_equal_p (XEXP (lhs, 0), XEXP (rhs, 1)))
799018334Speter    other = XEXP (lhs, 0), lhs = XEXP (lhs, 1), rhs = XEXP (rhs, 0);
799118334Speter  else if (GET_RTX_CLASS (inner_code) == 'c'
799218334Speter	   && rtx_equal_p (XEXP (lhs, 1), XEXP (rhs, 0)))
799318334Speter    other = XEXP (lhs, 1), lhs = XEXP (lhs, 0), rhs = XEXP (rhs, 1);
799418334Speter  else if (rtx_equal_p (XEXP (lhs, 1), XEXP (rhs, 1)))
799518334Speter    other = XEXP (lhs, 1), lhs = XEXP (lhs, 0), rhs = XEXP (rhs, 0);
799618334Speter  else
799718334Speter    return x;
799818334Speter
799918334Speter  /* Form the new inner operation, seeing if it simplifies first.  */
800018334Speter  tem = gen_binary (code, GET_MODE (x), lhs, rhs);
800118334Speter
800218334Speter  /* There is one exception to the general way of distributing:
800318334Speter     (a ^ b) | (a ^ c) -> (~a) & (b ^ c)  */
800418334Speter  if (code == XOR && inner_code == IOR)
800518334Speter    {
800618334Speter      inner_code = AND;
800790075Sobrien      other = simplify_gen_unary (NOT, GET_MODE (x), other, GET_MODE (x));
800818334Speter    }
800918334Speter
801018334Speter  /* We may be able to continuing distributing the result, so call
801118334Speter     ourselves recursively on the inner operation before forming the
801218334Speter     outer operation, which we return.  */
801318334Speter  return gen_binary (inner_code, GET_MODE (x),
801418334Speter		     apply_distributive_law (tem), other);
801518334Speter}
801618334Speter
801718334Speter/* We have X, a logical `and' of VAROP with the constant CONSTOP, to be done
801818334Speter   in MODE.
801918334Speter
802018334Speter   Return an equivalent form, if different from X.  Otherwise, return X.  If
802118334Speter   X is zero, we are to always construct the equivalent form.  */
802218334Speter
802318334Speterstatic rtx
802418334Spetersimplify_and_const_int (x, mode, varop, constop)
802518334Speter     rtx x;
802618334Speter     enum machine_mode mode;
802718334Speter     rtx varop;
802818334Speter     unsigned HOST_WIDE_INT constop;
802918334Speter{
803018334Speter  unsigned HOST_WIDE_INT nonzero;
803118334Speter  int i;
803218334Speter
803318334Speter  /* Simplify VAROP knowing that we will be only looking at some of the
803496263Sobrien     bits in it.
803596263Sobrien
803696263Sobrien     Note by passing in CONSTOP, we guarantee that the bits not set in
803796263Sobrien     CONSTOP are not significant and will never be examined.  We must
803896263Sobrien     ensure that is the case by explicitly masking out those bits
803996263Sobrien     before returning.  */
804018334Speter  varop = force_to_mode (varop, mode, constop, NULL_RTX, 0);
804118334Speter
804296263Sobrien  /* If VAROP is a CLOBBER, we will fail so return it.  */
804396263Sobrien  if (GET_CODE (varop) == CLOBBER)
804418334Speter    return varop;
804518334Speter
804696263Sobrien  /* If VAROP is a CONST_INT, then we need to apply the mask in CONSTOP
804796263Sobrien     to VAROP and return the new constant.  */
804896263Sobrien  if (GET_CODE (varop) == CONST_INT)
804996263Sobrien    return GEN_INT (trunc_int_for_mode (INTVAL (varop) & constop, mode));
805096263Sobrien
805118334Speter  /* See what bits may be nonzero in VAROP.  Unlike the general case of
805218334Speter     a call to nonzero_bits, here we don't care about bits outside
805318334Speter     MODE.  */
805418334Speter
805518334Speter  nonzero = nonzero_bits (varop, mode) & GET_MODE_MASK (mode);
805618334Speter
805718334Speter  /* Turn off all bits in the constant that are known to already be zero.
805818334Speter     Thus, if the AND isn't needed at all, we will have CONSTOP == NONZERO_BITS
805918334Speter     which is tested below.  */
806018334Speter
806118334Speter  constop &= nonzero;
806218334Speter
806318334Speter  /* If we don't have any bits left, return zero.  */
806418334Speter  if (constop == 0)
806518334Speter    return const0_rtx;
806618334Speter
806718334Speter  /* If VAROP is a NEG of something known to be zero or 1 and CONSTOP is
8068117395Skan     a power of two, we can replace this with an ASHIFT.  */
806918334Speter  if (GET_CODE (varop) == NEG && nonzero_bits (XEXP (varop, 0), mode) == 1
807018334Speter      && (i = exact_log2 (constop)) >= 0)
807118334Speter    return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (varop, 0), i);
807290075Sobrien
807318334Speter  /* If VAROP is an IOR or XOR, apply the AND to both branches of the IOR
807418334Speter     or XOR, then try to apply the distributive law.  This may eliminate
807518334Speter     operations if either branch can be simplified because of the AND.
807618334Speter     It may also make some cases more complex, but those cases probably
807718334Speter     won't match a pattern either with or without this.  */
807818334Speter
807918334Speter  if (GET_CODE (varop) == IOR || GET_CODE (varop) == XOR)
808018334Speter    return
808118334Speter      gen_lowpart_for_combine
808218334Speter	(mode,
808318334Speter	 apply_distributive_law
808418334Speter	 (gen_binary (GET_CODE (varop), GET_MODE (varop),
808518334Speter		      simplify_and_const_int (NULL_RTX, GET_MODE (varop),
808618334Speter					      XEXP (varop, 0), constop),
808718334Speter		      simplify_and_const_int (NULL_RTX, GET_MODE (varop),
808818334Speter					      XEXP (varop, 1), constop))));
808918334Speter
809090075Sobrien  /* If VAROP is PLUS, and the constant is a mask of low bite, distribute
809190075Sobrien     the AND and see if one of the operands simplifies to zero.  If so, we
809290075Sobrien     may eliminate it.  */
809390075Sobrien
809490075Sobrien  if (GET_CODE (varop) == PLUS
809590075Sobrien      && exact_log2 (constop + 1) >= 0)
809690075Sobrien    {
809790075Sobrien      rtx o0, o1;
809890075Sobrien
809990075Sobrien      o0 = simplify_and_const_int (NULL_RTX, mode, XEXP (varop, 0), constop);
810090075Sobrien      o1 = simplify_and_const_int (NULL_RTX, mode, XEXP (varop, 1), constop);
810190075Sobrien      if (o0 == const0_rtx)
810290075Sobrien	return o1;
810390075Sobrien      if (o1 == const0_rtx)
810490075Sobrien	return o0;
810590075Sobrien    }
810690075Sobrien
810718334Speter  /* Get VAROP in MODE.  Try to get a SUBREG if not.  Don't make a new SUBREG
810818334Speter     if we already had one (just check for the simplest cases).  */
810918334Speter  if (x && GET_CODE (XEXP (x, 0)) == SUBREG
811018334Speter      && GET_MODE (XEXP (x, 0)) == mode
811118334Speter      && SUBREG_REG (XEXP (x, 0)) == varop)
811218334Speter    varop = XEXP (x, 0);
811318334Speter  else
811418334Speter    varop = gen_lowpart_for_combine (mode, varop);
811518334Speter
811650397Sobrien  /* If we can't make the SUBREG, try to return what we were given.  */
811718334Speter  if (GET_CODE (varop) == CLOBBER)
811818334Speter    return x ? x : varop;
811918334Speter
812018334Speter  /* If we are only masking insignificant bits, return VAROP.  */
812118334Speter  if (constop == nonzero)
812218334Speter    x = varop;
812318334Speter  else
812418334Speter    {
812590075Sobrien      /* Otherwise, return an AND.  */
812690075Sobrien      constop = trunc_int_for_mode (constop, mode);
812790075Sobrien      /* See how much, if any, of X we can use.  */
812890075Sobrien      if (x == 0 || GET_CODE (x) != AND || GET_MODE (x) != mode)
812990075Sobrien	x = gen_binary (AND, mode, varop, GEN_INT (constop));
813018334Speter
813190075Sobrien      else
813290075Sobrien	{
813390075Sobrien	  if (GET_CODE (XEXP (x, 1)) != CONST_INT
813490075Sobrien	      || (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) != constop)
813590075Sobrien	    SUBST (XEXP (x, 1), GEN_INT (constop));
813690075Sobrien
813790075Sobrien	  SUBST (XEXP (x, 0), varop);
813890075Sobrien	}
813918334Speter    }
814018334Speter
814118334Speter  return x;
814218334Speter}
814318334Speter
8144117395Skan#define nonzero_bits_with_known(X, MODE) \
8145117395Skan  cached_nonzero_bits (X, MODE, known_x, known_mode, known_ret)
8146117395Skan
8147117395Skan/* The function cached_nonzero_bits is a wrapper around nonzero_bits1.
8148117395Skan   It avoids exponential behavior in nonzero_bits1 when X has
8149117395Skan   identical subexpressions on the first or the second level.  */
8150117395Skan
8151117395Skanstatic unsigned HOST_WIDE_INT
8152117395Skancached_nonzero_bits (x, mode, known_x, known_mode, known_ret)
8153117395Skan     rtx x;
8154117395Skan     enum machine_mode mode;
8155117395Skan     rtx known_x;
8156117395Skan     enum machine_mode known_mode;
8157117395Skan     unsigned HOST_WIDE_INT known_ret;
8158117395Skan{
8159117395Skan  if (x == known_x && mode == known_mode)
8160117395Skan    return known_ret;
8161117395Skan
8162117395Skan  /* Try to find identical subexpressions.  If found call
8163117395Skan     nonzero_bits1 on X with the subexpressions as KNOWN_X and the
8164117395Skan     precomputed value for the subexpression as KNOWN_RET.  */
8165117395Skan
8166117395Skan  if (GET_RTX_CLASS (GET_CODE (x)) == '2'
8167117395Skan      || GET_RTX_CLASS (GET_CODE (x)) == 'c')
8168117395Skan    {
8169117395Skan      rtx x0 = XEXP (x, 0);
8170117395Skan      rtx x1 = XEXP (x, 1);
8171117395Skan
8172117395Skan      /* Check the first level.  */
8173117395Skan      if (x0 == x1)
8174117395Skan	return nonzero_bits1 (x, mode, x0, mode,
8175117395Skan			      nonzero_bits_with_known (x0, mode));
8176117395Skan
8177117395Skan      /* Check the second level.  */
8178117395Skan      if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
8179117395Skan	   || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
8180117395Skan	  && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
8181117395Skan	return nonzero_bits1 (x, mode, x1, mode,
8182117395Skan			      nonzero_bits_with_known (x1, mode));
8183117395Skan
8184117395Skan      if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
8185117395Skan	   || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
8186117395Skan	  && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
8187117395Skan	return nonzero_bits1 (x, mode, x0, mode,
8188117395Skan			 nonzero_bits_with_known (x0, mode));
8189117395Skan    }
8190117395Skan
8191117395Skan  return nonzero_bits1 (x, mode, known_x, known_mode, known_ret);
8192117395Skan}
8193117395Skan
819450397Sobrien/* We let num_sign_bit_copies recur into nonzero_bits as that is useful.
819550397Sobrien   We don't let nonzero_bits recur into num_sign_bit_copies, because that
819650397Sobrien   is less useful.  We can't allow both, because that results in exponential
819750397Sobrien   run time recursion.  There is a nullstone testcase that triggered
819850397Sobrien   this.  This macro avoids accidental uses of num_sign_bit_copies.  */
8199117395Skan#define cached_num_sign_bit_copies()
820050397Sobrien
8201117395Skan/* Given an expression, X, compute which bits in X can be nonzero.
820218334Speter   We don't care about bits outside of those defined in MODE.
820318334Speter
820418334Speter   For most X this is simply GET_MODE_MASK (GET_MODE (MODE)), but if X is
820518334Speter   a shift, AND, or zero_extract, we can do better.  */
820618334Speter
820718334Speterstatic unsigned HOST_WIDE_INT
8208117395Skannonzero_bits1 (x, mode, known_x, known_mode, known_ret)
820918334Speter     rtx x;
821018334Speter     enum machine_mode mode;
8211117395Skan     rtx known_x;
8212117395Skan     enum machine_mode known_mode;
8213117395Skan     unsigned HOST_WIDE_INT known_ret;
821418334Speter{
821518334Speter  unsigned HOST_WIDE_INT nonzero = GET_MODE_MASK (mode);
821618334Speter  unsigned HOST_WIDE_INT inner_nz;
821718334Speter  enum rtx_code code;
821890075Sobrien  unsigned int mode_width = GET_MODE_BITSIZE (mode);
821918334Speter  rtx tem;
822018334Speter
822118334Speter  /* For floating-point values, assume all bits are needed.  */
822218334Speter  if (FLOAT_MODE_P (GET_MODE (x)) || FLOAT_MODE_P (mode))
822318334Speter    return nonzero;
822418334Speter
822518334Speter  /* If X is wider than MODE, use its mode instead.  */
822618334Speter  if (GET_MODE_BITSIZE (GET_MODE (x)) > mode_width)
822718334Speter    {
822818334Speter      mode = GET_MODE (x);
822918334Speter      nonzero = GET_MODE_MASK (mode);
823018334Speter      mode_width = GET_MODE_BITSIZE (mode);
823118334Speter    }
823218334Speter
823318334Speter  if (mode_width > HOST_BITS_PER_WIDE_INT)
823418334Speter    /* Our only callers in this case look for single bit values.  So
823518334Speter       just return the mode mask.  Those tests will then be false.  */
823618334Speter    return nonzero;
823718334Speter
823818334Speter#ifndef WORD_REGISTER_OPERATIONS
823918334Speter  /* If MODE is wider than X, but both are a single word for both the host
824090075Sobrien     and target machines, we can compute this from which bits of the
824118334Speter     object might be nonzero in its own mode, taking into account the fact
824218334Speter     that on many CISC machines, accessing an object in a wider mode
824318334Speter     causes the high-order bits to become undefined.  So they are
824418334Speter     not known to be zero.  */
824518334Speter
824618334Speter  if (GET_MODE (x) != VOIDmode && GET_MODE (x) != mode
824718334Speter      && GET_MODE_BITSIZE (GET_MODE (x)) <= BITS_PER_WORD
824818334Speter      && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
824918334Speter      && GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (GET_MODE (x)))
825018334Speter    {
8251117395Skan      nonzero &= nonzero_bits_with_known (x, GET_MODE (x));
825290075Sobrien      nonzero |= GET_MODE_MASK (mode) & ~GET_MODE_MASK (GET_MODE (x));
825318334Speter      return nonzero;
825418334Speter    }
825518334Speter#endif
825618334Speter
825718334Speter  code = GET_CODE (x);
825818334Speter  switch (code)
825918334Speter    {
826018334Speter    case REG:
826190075Sobrien#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
826218334Speter      /* If pointers extend unsigned and this is a pointer in Pmode, say that
826318334Speter	 all the bits above ptr_mode are known to be zero.  */
826418334Speter      if (POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
826590075Sobrien	  && REG_POINTER (x))
826618334Speter	nonzero &= GET_MODE_MASK (ptr_mode);
826718334Speter#endif
826818334Speter
826996263Sobrien      /* Include declared information about alignment of pointers.  */
827096263Sobrien      /* ??? We don't properly preserve REG_POINTER changes across
827196263Sobrien	 pointer-to-integer casts, so we can't trust it except for
827296263Sobrien	 things that we know must be pointers.  See execute/960116-1.c.  */
827396263Sobrien      if ((x == stack_pointer_rtx
827496263Sobrien	   || x == frame_pointer_rtx
827596263Sobrien	   || x == arg_pointer_rtx)
827696263Sobrien	  && REGNO_POINTER_ALIGN (REGNO (x)))
827718334Speter	{
827896263Sobrien	  unsigned HOST_WIDE_INT alignment
827996263Sobrien	    = REGNO_POINTER_ALIGN (REGNO (x)) / BITS_PER_UNIT;
828018334Speter
828118334Speter#ifdef PUSH_ROUNDING
828296263Sobrien	  /* If PUSH_ROUNDING is defined, it is possible for the
828396263Sobrien	     stack to be momentarily aligned only to that amount,
828496263Sobrien	     so we pick the least alignment.  */
828596263Sobrien	  if (x == stack_pointer_rtx && PUSH_ARGS)
828696263Sobrien	    alignment = MIN (PUSH_ROUNDING (1), alignment);
828718334Speter#endif
828818334Speter
828996263Sobrien	  nonzero &= ~(alignment - 1);
829018334Speter	}
829118334Speter
829218334Speter      /* If X is a register whose nonzero bits value is current, use it.
829318334Speter	 Otherwise, if X is a register whose value we can find, use that
829418334Speter	 value.  Otherwise, use the previously-computed global nonzero bits
829518334Speter	 for this register.  */
829618334Speter
829718334Speter      if (reg_last_set_value[REGNO (x)] != 0
829896263Sobrien	  && (reg_last_set_mode[REGNO (x)] == mode
829996263Sobrien	      || (GET_MODE_CLASS (reg_last_set_mode[REGNO (x)]) == MODE_INT
830096263Sobrien		  && GET_MODE_CLASS (mode) == MODE_INT))
830190075Sobrien	  && (reg_last_set_label[REGNO (x)] == label_tick
830290075Sobrien	      || (REGNO (x) >= FIRST_PSEUDO_REGISTER
830390075Sobrien		  && REG_N_SETS (REGNO (x)) == 1
8304117395Skan		  && ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start,
830590075Sobrien					REGNO (x))))
830618334Speter	  && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
830796263Sobrien	return reg_last_set_nonzero_bits[REGNO (x)] & nonzero;
830818334Speter
830918334Speter      tem = get_last_value (x);
831018334Speter
831118334Speter      if (tem)
831218334Speter	{
831318334Speter#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
831418334Speter	  /* If X is narrower than MODE and TEM is a non-negative
831518334Speter	     constant that would appear negative in the mode of X,
831618334Speter	     sign-extend it for use in reg_nonzero_bits because some
831718334Speter	     machines (maybe most) will actually do the sign-extension
831890075Sobrien	     and this is the conservative approach.
831918334Speter
832018334Speter	     ??? For 2.5, try to tighten up the MD files in this regard
832118334Speter	     instead of this kludge.  */
832218334Speter
832318334Speter	  if (GET_MODE_BITSIZE (GET_MODE (x)) < mode_width
832418334Speter	      && GET_CODE (tem) == CONST_INT
832518334Speter	      && INTVAL (tem) > 0
832618334Speter	      && 0 != (INTVAL (tem)
832718334Speter		       & ((HOST_WIDE_INT) 1
832818334Speter			  << (GET_MODE_BITSIZE (GET_MODE (x)) - 1))))
832918334Speter	    tem = GEN_INT (INTVAL (tem)
833018334Speter			   | ((HOST_WIDE_INT) (-1)
833118334Speter			      << GET_MODE_BITSIZE (GET_MODE (x))));
833218334Speter#endif
8333117395Skan	  return nonzero_bits_with_known (tem, mode) & nonzero;
833418334Speter	}
833518334Speter      else if (nonzero_sign_valid && reg_nonzero_bits[REGNO (x)])
833690075Sobrien	{
833790075Sobrien	  unsigned HOST_WIDE_INT mask = reg_nonzero_bits[REGNO (x)];
833890075Sobrien
833990075Sobrien	  if (GET_MODE_BITSIZE (GET_MODE (x)) < mode_width)
834090075Sobrien	    /* We don't know anything about the upper bits.  */
834190075Sobrien	    mask |= GET_MODE_MASK (mode) ^ GET_MODE_MASK (GET_MODE (x));
834290075Sobrien	  return nonzero & mask;
834390075Sobrien	}
834418334Speter      else
834518334Speter	return nonzero;
834618334Speter
834718334Speter    case CONST_INT:
834818334Speter#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
834918334Speter      /* If X is negative in MODE, sign-extend the value.  */
835018334Speter      if (INTVAL (x) > 0 && mode_width < BITS_PER_WORD
835118334Speter	  && 0 != (INTVAL (x) & ((HOST_WIDE_INT) 1 << (mode_width - 1))))
835218334Speter	return (INTVAL (x) | ((HOST_WIDE_INT) (-1) << mode_width));
835318334Speter#endif
835418334Speter
835518334Speter      return INTVAL (x);
835618334Speter
835718334Speter    case MEM:
835818334Speter#ifdef LOAD_EXTEND_OP
835918334Speter      /* In many, if not most, RISC machines, reading a byte from memory
836018334Speter	 zeros the rest of the register.  Noticing that fact saves a lot
836118334Speter	 of extra zero-extends.  */
836218334Speter      if (LOAD_EXTEND_OP (GET_MODE (x)) == ZERO_EXTEND)
836318334Speter	nonzero &= GET_MODE_MASK (GET_MODE (x));
836418334Speter#endif
836518334Speter      break;
836618334Speter
836718334Speter    case EQ:  case NE:
836890075Sobrien    case UNEQ:  case LTGT:
836990075Sobrien    case GT:  case GTU:  case UNGT:
837090075Sobrien    case LT:  case LTU:  case UNLT:
837190075Sobrien    case GE:  case GEU:  case UNGE:
837290075Sobrien    case LE:  case LEU:  case UNLE:
837390075Sobrien    case UNORDERED: case ORDERED:
837418334Speter
837518334Speter      /* If this produces an integer result, we know which bits are set.
837618334Speter	 Code here used to clear bits outside the mode of X, but that is
837718334Speter	 now done above.  */
837818334Speter
837918334Speter      if (GET_MODE_CLASS (mode) == MODE_INT
838018334Speter	  && mode_width <= HOST_BITS_PER_WIDE_INT)
838118334Speter	nonzero = STORE_FLAG_VALUE;
838218334Speter      break;
838318334Speter
838418334Speter    case NEG:
838550397Sobrien#if 0
838650397Sobrien      /* Disabled to avoid exponential mutual recursion between nonzero_bits
838750397Sobrien	 and num_sign_bit_copies.  */
838818334Speter      if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (x))
838918334Speter	  == GET_MODE_BITSIZE (GET_MODE (x)))
839018334Speter	nonzero = 1;
839150397Sobrien#endif
839218334Speter
839318334Speter      if (GET_MODE_SIZE (GET_MODE (x)) < mode_width)
839490075Sobrien	nonzero |= (GET_MODE_MASK (mode) & ~GET_MODE_MASK (GET_MODE (x)));
839518334Speter      break;
839618334Speter
839718334Speter    case ABS:
839850397Sobrien#if 0
839950397Sobrien      /* Disabled to avoid exponential mutual recursion between nonzero_bits
840050397Sobrien	 and num_sign_bit_copies.  */
840118334Speter      if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (x))
840218334Speter	  == GET_MODE_BITSIZE (GET_MODE (x)))
840318334Speter	nonzero = 1;
840450397Sobrien#endif
840518334Speter      break;
840618334Speter
840718334Speter    case TRUNCATE:
8408117395Skan      nonzero &= (nonzero_bits_with_known (XEXP (x, 0), mode)
8409117395Skan		  & GET_MODE_MASK (mode));
841018334Speter      break;
841118334Speter
841218334Speter    case ZERO_EXTEND:
8413117395Skan      nonzero &= nonzero_bits_with_known (XEXP (x, 0), mode);
841418334Speter      if (GET_MODE (XEXP (x, 0)) != VOIDmode)
841518334Speter	nonzero &= GET_MODE_MASK (GET_MODE (XEXP (x, 0)));
841618334Speter      break;
841718334Speter
841818334Speter    case SIGN_EXTEND:
841918334Speter      /* If the sign bit is known clear, this is the same as ZERO_EXTEND.
842018334Speter	 Otherwise, show all the bits in the outer mode but not the inner
8421117395Skan	 may be nonzero.  */
8422117395Skan      inner_nz = nonzero_bits_with_known (XEXP (x, 0), mode);
842318334Speter      if (GET_MODE (XEXP (x, 0)) != VOIDmode)
842418334Speter	{
842518334Speter	  inner_nz &= GET_MODE_MASK (GET_MODE (XEXP (x, 0)));
842650397Sobrien	  if (inner_nz
842750397Sobrien	      & (((HOST_WIDE_INT) 1
842850397Sobrien		  << (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - 1))))
842918334Speter	    inner_nz |= (GET_MODE_MASK (mode)
843090075Sobrien			 & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0))));
843118334Speter	}
843218334Speter
843318334Speter      nonzero &= inner_nz;
843418334Speter      break;
843518334Speter
843618334Speter    case AND:
8437117395Skan      nonzero &= (nonzero_bits_with_known (XEXP (x, 0), mode)
8438117395Skan		  & nonzero_bits_with_known (XEXP (x, 1), mode));
843918334Speter      break;
844018334Speter
844118334Speter    case XOR:   case IOR:
844218334Speter    case UMIN:  case UMAX:  case SMIN:  case SMAX:
844396263Sobrien      {
8444117395Skan	unsigned HOST_WIDE_INT nonzero0 =
8445117395Skan	  nonzero_bits_with_known (XEXP (x, 0), mode);
844696263Sobrien
844796263Sobrien	/* Don't call nonzero_bits for the second time if it cannot change
844896263Sobrien	   anything.  */
844996263Sobrien	if ((nonzero & nonzero0) != nonzero)
8450117395Skan	  nonzero &= (nonzero0
8451117395Skan		      | nonzero_bits_with_known (XEXP (x, 1), mode));
845296263Sobrien      }
845318334Speter      break;
845418334Speter
845518334Speter    case PLUS:  case MINUS:
845618334Speter    case MULT:
845718334Speter    case DIV:   case UDIV:
845818334Speter    case MOD:   case UMOD:
845918334Speter      /* We can apply the rules of arithmetic to compute the number of
846018334Speter	 high- and low-order zero bits of these operations.  We start by
8461117395Skan	 computing the width (position of the highest-order nonzero bit)
846218334Speter	 and the number of low-order zero bits for each value.  */
846318334Speter      {
8464117395Skan	unsigned HOST_WIDE_INT nz0 =
8465117395Skan	  nonzero_bits_with_known (XEXP (x, 0), mode);
8466117395Skan	unsigned HOST_WIDE_INT nz1 =
8467117395Skan	  nonzero_bits_with_known (XEXP (x, 1), mode);
846818334Speter	int width0 = floor_log2 (nz0) + 1;
846918334Speter	int width1 = floor_log2 (nz1) + 1;
847018334Speter	int low0 = floor_log2 (nz0 & -nz0);
847118334Speter	int low1 = floor_log2 (nz1 & -nz1);
847218334Speter	HOST_WIDE_INT op0_maybe_minusp
847318334Speter	  = (nz0 & ((HOST_WIDE_INT) 1 << (mode_width - 1)));
847418334Speter	HOST_WIDE_INT op1_maybe_minusp
847518334Speter	  = (nz1 & ((HOST_WIDE_INT) 1 << (mode_width - 1)));
847690075Sobrien	unsigned int result_width = mode_width;
847718334Speter	int result_low = 0;
847818334Speter
847918334Speter	switch (code)
848018334Speter	  {
848118334Speter	  case PLUS:
848218334Speter	    result_width = MAX (width0, width1) + 1;
848318334Speter	    result_low = MIN (low0, low1);
848418334Speter	    break;
848518334Speter	  case MINUS:
848618334Speter	    result_low = MIN (low0, low1);
848718334Speter	    break;
848818334Speter	  case MULT:
848918334Speter	    result_width = width0 + width1;
849018334Speter	    result_low = low0 + low1;
849118334Speter	    break;
849218334Speter	  case DIV:
849390075Sobrien	    if (width1 == 0)
849490075Sobrien	      break;
849518334Speter	    if (! op0_maybe_minusp && ! op1_maybe_minusp)
849618334Speter	      result_width = width0;
849718334Speter	    break;
849818334Speter	  case UDIV:
849990075Sobrien	    if (width1 == 0)
850090075Sobrien	      break;
850118334Speter	    result_width = width0;
850218334Speter	    break;
850318334Speter	  case MOD:
850490075Sobrien	    if (width1 == 0)
850590075Sobrien	      break;
850618334Speter	    if (! op0_maybe_minusp && ! op1_maybe_minusp)
850718334Speter	      result_width = MIN (width0, width1);
850818334Speter	    result_low = MIN (low0, low1);
850918334Speter	    break;
851018334Speter	  case UMOD:
851190075Sobrien	    if (width1 == 0)
851290075Sobrien	      break;
851318334Speter	    result_width = MIN (width0, width1);
851418334Speter	    result_low = MIN (low0, low1);
851518334Speter	    break;
851650397Sobrien	  default:
851750397Sobrien	    abort ();
851818334Speter	  }
851918334Speter
852018334Speter	if (result_width < mode_width)
852118334Speter	  nonzero &= ((HOST_WIDE_INT) 1 << result_width) - 1;
852218334Speter
852318334Speter	if (result_low > 0)
852490075Sobrien	  nonzero &= ~(((HOST_WIDE_INT) 1 << result_low) - 1);
852590075Sobrien
852690075Sobrien#ifdef POINTERS_EXTEND_UNSIGNED
852790075Sobrien	/* If pointers extend unsigned and this is an addition or subtraction
852890075Sobrien	   to a pointer in Pmode, all the bits above ptr_mode are known to be
852990075Sobrien	   zero.  */
853090075Sobrien	if (POINTERS_EXTEND_UNSIGNED > 0 && GET_MODE (x) == Pmode
853190075Sobrien	    && (code == PLUS || code == MINUS)
853290075Sobrien	    && GET_CODE (XEXP (x, 0)) == REG && REG_POINTER (XEXP (x, 0)))
853390075Sobrien	  nonzero &= GET_MODE_MASK (ptr_mode);
853490075Sobrien#endif
853518334Speter      }
853618334Speter      break;
853718334Speter
853818334Speter    case ZERO_EXTRACT:
853918334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
854018334Speter	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
854118334Speter	nonzero &= ((HOST_WIDE_INT) 1 << INTVAL (XEXP (x, 1))) - 1;
854218334Speter      break;
854318334Speter
854418334Speter    case SUBREG:
854518334Speter      /* If this is a SUBREG formed for a promoted variable that has
854618334Speter	 been zero-extended, we know that at least the high-order bits
854718334Speter	 are zero, though others might be too.  */
854818334Speter
8549117395Skan      if (SUBREG_PROMOTED_VAR_P (x) && SUBREG_PROMOTED_UNSIGNED_P (x) > 0)
855018334Speter	nonzero = (GET_MODE_MASK (GET_MODE (x))
8551117395Skan		   & nonzero_bits_with_known (SUBREG_REG (x), GET_MODE (x)));
855218334Speter
855318334Speter      /* If the inner mode is a single word for both the host and target
855418334Speter	 machines, we can compute this from which bits of the inner
855518334Speter	 object might be nonzero.  */
855618334Speter      if (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) <= BITS_PER_WORD
855718334Speter	  && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
855818334Speter	      <= HOST_BITS_PER_WIDE_INT))
855918334Speter	{
8560117395Skan	  nonzero &= nonzero_bits_with_known (SUBREG_REG (x), mode);
856118334Speter
856250397Sobrien#if defined (WORD_REGISTER_OPERATIONS) && defined (LOAD_EXTEND_OP)
856350397Sobrien	  /* If this is a typical RISC machine, we only have to worry
856450397Sobrien	     about the way loads are extended.  */
8565117395Skan	  if ((LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND
8566117395Skan	       ? (((nonzero
8567117395Skan		    & (((unsigned HOST_WIDE_INT) 1
8568117395Skan			<< (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) - 1))))
8569117395Skan		   != 0))
8570117395Skan	       : LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) != ZERO_EXTEND)
8571117395Skan	      || GET_CODE (SUBREG_REG (x)) != MEM)
857218334Speter#endif
857350397Sobrien	    {
857450397Sobrien	      /* On many CISC machines, accessing an object in a wider mode
857550397Sobrien		 causes the high-order bits to become undefined.  So they are
857650397Sobrien		 not known to be zero.  */
857750397Sobrien	      if (GET_MODE_SIZE (GET_MODE (x))
857850397Sobrien		  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
857950397Sobrien		nonzero |= (GET_MODE_MASK (GET_MODE (x))
858090075Sobrien			    & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x))));
858150397Sobrien	    }
858218334Speter	}
858318334Speter      break;
858418334Speter
858518334Speter    case ASHIFTRT:
858618334Speter    case LSHIFTRT:
858718334Speter    case ASHIFT:
858818334Speter    case ROTATE:
858918334Speter      /* The nonzero bits are in two classes: any bits within MODE
859018334Speter	 that aren't in GET_MODE (x) are always significant.  The rest of the
859118334Speter	 nonzero bits are those that are significant in the operand of
859218334Speter	 the shift when shifted the appropriate number of bits.  This
859318334Speter	 shows that high-order bits are cleared by the right shift and
859418334Speter	 low-order bits by left shifts.  */
859518334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
859618334Speter	  && INTVAL (XEXP (x, 1)) >= 0
859718334Speter	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
859818334Speter	{
859918334Speter	  enum machine_mode inner_mode = GET_MODE (x);
860090075Sobrien	  unsigned int width = GET_MODE_BITSIZE (inner_mode);
860118334Speter	  int count = INTVAL (XEXP (x, 1));
860218334Speter	  unsigned HOST_WIDE_INT mode_mask = GET_MODE_MASK (inner_mode);
8603117395Skan	  unsigned HOST_WIDE_INT op_nonzero =
8604117395Skan	    nonzero_bits_with_known (XEXP (x, 0), mode);
860518334Speter	  unsigned HOST_WIDE_INT inner = op_nonzero & mode_mask;
860618334Speter	  unsigned HOST_WIDE_INT outer = 0;
860718334Speter
860818334Speter	  if (mode_width > width)
860990075Sobrien	    outer = (op_nonzero & nonzero & ~mode_mask);
861018334Speter
861118334Speter	  if (code == LSHIFTRT)
861218334Speter	    inner >>= count;
861318334Speter	  else if (code == ASHIFTRT)
861418334Speter	    {
861518334Speter	      inner >>= count;
861618334Speter
861718334Speter	      /* If the sign bit may have been nonzero before the shift, we
861818334Speter		 need to mark all the places it could have been copied to
861918334Speter		 by the shift as possibly nonzero.  */
862018334Speter	      if (inner & ((HOST_WIDE_INT) 1 << (width - 1 - count)))
862118334Speter		inner |= (((HOST_WIDE_INT) 1 << count) - 1) << (width - count);
862218334Speter	    }
862318334Speter	  else if (code == ASHIFT)
862418334Speter	    inner <<= count;
862518334Speter	  else
862618334Speter	    inner = ((inner << (count % width)
862718334Speter		      | (inner >> (width - (count % width)))) & mode_mask);
862818334Speter
862918334Speter	  nonzero &= (outer | inner);
863018334Speter	}
863118334Speter      break;
863218334Speter
863318334Speter    case FFS:
863418334Speter      /* This is at most the number of bits in the mode.  */
863518334Speter      nonzero = ((HOST_WIDE_INT) 1 << (floor_log2 (mode_width) + 1)) - 1;
863618334Speter      break;
863718334Speter
863818334Speter    case IF_THEN_ELSE:
8639117395Skan      nonzero &= (nonzero_bits_with_known (XEXP (x, 1), mode)
8640117395Skan		  | nonzero_bits_with_known (XEXP (x, 2), mode));
864118334Speter      break;
864290075Sobrien
864350397Sobrien    default:
864450397Sobrien      break;
864518334Speter    }
864618334Speter
864718334Speter  return nonzero;
864818334Speter}
864950397Sobrien
865050397Sobrien/* See the macro definition above.  */
8651117395Skan#undef cached_num_sign_bit_copies
865218334Speter
8653117395Skan#define num_sign_bit_copies_with_known(X, M) \
8654117395Skan  cached_num_sign_bit_copies (X, M, known_x, known_mode, known_ret)
8655117395Skan
8656117395Skan/* The function cached_num_sign_bit_copies is a wrapper around
8657117395Skan   num_sign_bit_copies1.  It avoids exponential behavior in
8658117395Skan   num_sign_bit_copies1 when X has identical subexpressions on the
8659117395Skan   first or the second level.  */
8660117395Skan
8661117395Skanstatic unsigned int
8662117395Skancached_num_sign_bit_copies (x, mode, known_x, known_mode, known_ret)
8663117395Skan     rtx x;
8664117395Skan     enum machine_mode mode;
8665117395Skan     rtx known_x;
8666117395Skan     enum machine_mode known_mode;
8667117395Skan     unsigned int known_ret;
8668117395Skan{
8669117395Skan  if (x == known_x && mode == known_mode)
8670117395Skan    return known_ret;
8671117395Skan
8672117395Skan  /* Try to find identical subexpressions.  If found call
8673117395Skan     num_sign_bit_copies1 on X with the subexpressions as KNOWN_X and
8674117395Skan     the precomputed value for the subexpression as KNOWN_RET.  */
8675117395Skan
8676117395Skan  if (GET_RTX_CLASS (GET_CODE (x)) == '2'
8677117395Skan      || GET_RTX_CLASS (GET_CODE (x)) == 'c')
8678117395Skan    {
8679117395Skan      rtx x0 = XEXP (x, 0);
8680117395Skan      rtx x1 = XEXP (x, 1);
8681117395Skan
8682117395Skan      /* Check the first level.  */
8683117395Skan      if (x0 == x1)
8684117395Skan	return
8685117395Skan	  num_sign_bit_copies1 (x, mode, x0, mode,
8686117395Skan				num_sign_bit_copies_with_known (x0, mode));
8687117395Skan
8688117395Skan      /* Check the second level.  */
8689117395Skan      if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
8690117395Skan	   || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
8691117395Skan	  && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
8692117395Skan	return
8693117395Skan	  num_sign_bit_copies1 (x, mode, x1, mode,
8694117395Skan				num_sign_bit_copies_with_known (x1, mode));
8695117395Skan
8696117395Skan      if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
8697117395Skan	   || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
8698117395Skan	  && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
8699117395Skan	return
8700117395Skan	  num_sign_bit_copies1 (x, mode, x0, mode,
8701117395Skan				num_sign_bit_copies_with_known (x0, mode));
8702117395Skan    }
8703117395Skan
8704117395Skan  return num_sign_bit_copies1 (x, mode, known_x, known_mode, known_ret);
8705117395Skan}
8706117395Skan
870718334Speter/* Return the number of bits at the high-order end of X that are known to
870818334Speter   be equal to the sign bit.  X will be used in mode MODE; if MODE is
870918334Speter   VOIDmode, X will be used in its own mode.  The returned value  will always
871018334Speter   be between 1 and the number of bits in MODE.  */
871118334Speter
871290075Sobrienstatic unsigned int
8713117395Skannum_sign_bit_copies1 (x, mode, known_x, known_mode, known_ret)
871418334Speter     rtx x;
871518334Speter     enum machine_mode mode;
8716117395Skan     rtx known_x;
8717117395Skan     enum machine_mode known_mode;
8718117395Skan     unsigned int known_ret;
871918334Speter{
872018334Speter  enum rtx_code code = GET_CODE (x);
872190075Sobrien  unsigned int bitwidth;
872218334Speter  int num0, num1, result;
872318334Speter  unsigned HOST_WIDE_INT nonzero;
872418334Speter  rtx tem;
872518334Speter
872618334Speter  /* If we weren't given a mode, use the mode of X.  If the mode is still
872718334Speter     VOIDmode, we don't know anything.  Likewise if one of the modes is
872818334Speter     floating-point.  */
872918334Speter
873018334Speter  if (mode == VOIDmode)
873118334Speter    mode = GET_MODE (x);
873218334Speter
873318334Speter  if (mode == VOIDmode || FLOAT_MODE_P (mode) || FLOAT_MODE_P (GET_MODE (x)))
873418334Speter    return 1;
873518334Speter
873618334Speter  bitwidth = GET_MODE_BITSIZE (mode);
873718334Speter
873850397Sobrien  /* For a smaller object, just ignore the high bits.  */
873918334Speter  if (bitwidth < GET_MODE_BITSIZE (GET_MODE (x)))
874090075Sobrien    {
8741117395Skan      num0 = num_sign_bit_copies_with_known (x, GET_MODE (x));
874290075Sobrien      return MAX (1,
874390075Sobrien		  num0 - (int) (GET_MODE_BITSIZE (GET_MODE (x)) - bitwidth));
874490075Sobrien    }
874590075Sobrien
874650397Sobrien  if (GET_MODE (x) != VOIDmode && bitwidth > GET_MODE_BITSIZE (GET_MODE (x)))
874750397Sobrien    {
874818334Speter#ifndef WORD_REGISTER_OPERATIONS
874918334Speter  /* If this machine does not do all register operations on the entire
875018334Speter     register and MODE is wider than the mode of X, we can say nothing
875118334Speter     at all about the high-order bits.  */
875250397Sobrien      return 1;
875350397Sobrien#else
875450397Sobrien      /* Likewise on machines that do, if the mode of the object is smaller
875550397Sobrien	 than a word and loads of that size don't sign extend, we can say
875650397Sobrien	 nothing about the high order bits.  */
875750397Sobrien      if (GET_MODE_BITSIZE (GET_MODE (x)) < BITS_PER_WORD
875850397Sobrien#ifdef LOAD_EXTEND_OP
875950397Sobrien	  && LOAD_EXTEND_OP (GET_MODE (x)) != SIGN_EXTEND
876018334Speter#endif
876150397Sobrien	  )
876250397Sobrien	return 1;
876350397Sobrien#endif
876450397Sobrien    }
876518334Speter
876618334Speter  switch (code)
876718334Speter    {
876818334Speter    case REG:
876918334Speter
877090075Sobrien#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
877118334Speter      /* If pointers extend signed and this is a pointer in Pmode, say that
877218334Speter	 all the bits above ptr_mode are known to be sign bit copies.  */
877318334Speter      if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode && mode == Pmode
877490075Sobrien	  && REG_POINTER (x))
877518334Speter	return GET_MODE_BITSIZE (Pmode) - GET_MODE_BITSIZE (ptr_mode) + 1;
877618334Speter#endif
877718334Speter
877818334Speter      if (reg_last_set_value[REGNO (x)] != 0
877918334Speter	  && reg_last_set_mode[REGNO (x)] == mode
878090075Sobrien	  && (reg_last_set_label[REGNO (x)] == label_tick
878190075Sobrien	      || (REGNO (x) >= FIRST_PSEUDO_REGISTER
878290075Sobrien		  && REG_N_SETS (REGNO (x)) == 1
8783117395Skan		  && ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start,
878490075Sobrien					REGNO (x))))
878518334Speter	  && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
878618334Speter	return reg_last_set_sign_bit_copies[REGNO (x)];
878718334Speter
878890075Sobrien      tem = get_last_value (x);
878918334Speter      if (tem != 0)
8790117395Skan	return num_sign_bit_copies_with_known (tem, mode);
879118334Speter
879290075Sobrien      if (nonzero_sign_valid && reg_sign_bit_copies[REGNO (x)] != 0
879390075Sobrien	  && GET_MODE_BITSIZE (GET_MODE (x)) == bitwidth)
879418334Speter	return reg_sign_bit_copies[REGNO (x)];
879518334Speter      break;
879618334Speter
879718334Speter    case MEM:
879818334Speter#ifdef LOAD_EXTEND_OP
879918334Speter      /* Some RISC machines sign-extend all loads of smaller than a word.  */
880018334Speter      if (LOAD_EXTEND_OP (GET_MODE (x)) == SIGN_EXTEND)
880190075Sobrien	return MAX (1, ((int) bitwidth
880290075Sobrien			- (int) GET_MODE_BITSIZE (GET_MODE (x)) + 1));
880318334Speter#endif
880418334Speter      break;
880518334Speter
880618334Speter    case CONST_INT:
880718334Speter      /* If the constant is negative, take its 1's complement and remask.
880818334Speter	 Then see how many zero bits we have.  */
880918334Speter      nonzero = INTVAL (x) & GET_MODE_MASK (mode);
881018334Speter      if (bitwidth <= HOST_BITS_PER_WIDE_INT
881118334Speter	  && (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
881290075Sobrien	nonzero = (~nonzero) & GET_MODE_MASK (mode);
881318334Speter
881418334Speter      return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1);
881518334Speter
881618334Speter    case SUBREG:
881718334Speter      /* If this is a SUBREG for a promoted object that is sign-extended
881818334Speter	 and we are looking at it in a wider mode, we know that at least the
881918334Speter	 high-order bits are known to be sign bit copies.  */
882018334Speter
882118334Speter      if (SUBREG_PROMOTED_VAR_P (x) && ! SUBREG_PROMOTED_UNSIGNED_P (x))
882290075Sobrien	{
8823117395Skan	  num0 = num_sign_bit_copies_with_known (SUBREG_REG (x), mode);
882490075Sobrien	  return MAX ((int) bitwidth
882590075Sobrien		      - (int) GET_MODE_BITSIZE (GET_MODE (x)) + 1,
882690075Sobrien		      num0);
882790075Sobrien	}
882818334Speter
882950397Sobrien      /* For a smaller object, just ignore the high bits.  */
883018334Speter      if (bitwidth <= GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))))
883118334Speter	{
8832117395Skan	  num0 = num_sign_bit_copies_with_known (SUBREG_REG (x), VOIDmode);
883318334Speter	  return MAX (1, (num0
883490075Sobrien			  - (int) (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
883590075Sobrien				   - bitwidth)));
883618334Speter	}
883718334Speter
883818334Speter#ifdef WORD_REGISTER_OPERATIONS
883918334Speter#ifdef LOAD_EXTEND_OP
884018334Speter      /* For paradoxical SUBREGs on machines where all register operations
884118334Speter	 affect the entire register, just look inside.  Note that we are
884218334Speter	 passing MODE to the recursive call, so the number of sign bit copies
884318334Speter	 will remain relative to that mode, not the inner mode.  */
884418334Speter
884518334Speter      /* This works only if loads sign extend.  Otherwise, if we get a
884618334Speter	 reload for the inner part, it may be loaded from the stack, and
884718334Speter	 then we lose all sign bit copies that existed before the store
884818334Speter	 to the stack.  */
884918334Speter
885018334Speter      if ((GET_MODE_SIZE (GET_MODE (x))
885118334Speter	   > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
8852117395Skan	  && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND
8853117395Skan	  && GET_CODE (SUBREG_REG (x)) == MEM)
8854117395Skan	return num_sign_bit_copies_with_known (SUBREG_REG (x), mode);
885518334Speter#endif
885618334Speter#endif
885718334Speter      break;
885818334Speter
885918334Speter    case SIGN_EXTRACT:
886018334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
886190075Sobrien	return MAX (1, (int) bitwidth - INTVAL (XEXP (x, 1)));
886218334Speter      break;
886318334Speter
886490075Sobrien    case SIGN_EXTEND:
886518334Speter      return (bitwidth - GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
8866117395Skan	      + num_sign_bit_copies_with_known (XEXP (x, 0), VOIDmode));
886718334Speter
886818334Speter    case TRUNCATE:
886950397Sobrien      /* For a smaller object, just ignore the high bits.  */
8870117395Skan      num0 = num_sign_bit_copies_with_known (XEXP (x, 0), VOIDmode);
887190075Sobrien      return MAX (1, (num0 - (int) (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
887290075Sobrien				    - bitwidth)));
887318334Speter
887418334Speter    case NOT:
8875117395Skan      return num_sign_bit_copies_with_known (XEXP (x, 0), mode);
887618334Speter
887718334Speter    case ROTATE:       case ROTATERT:
887818334Speter      /* If we are rotating left by a number of bits less than the number
887918334Speter	 of sign bit copies, we can just subtract that amount from the
888018334Speter	 number.  */
888118334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
888290075Sobrien	  && INTVAL (XEXP (x, 1)) >= 0
888390075Sobrien	  && INTVAL (XEXP (x, 1)) < (int) bitwidth)
888418334Speter	{
8885117395Skan	  num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
888618334Speter	  return MAX (1, num0 - (code == ROTATE ? INTVAL (XEXP (x, 1))
888790075Sobrien				 : (int) bitwidth - INTVAL (XEXP (x, 1))));
888818334Speter	}
888918334Speter      break;
889018334Speter
889118334Speter    case NEG:
889218334Speter      /* In general, this subtracts one sign bit copy.  But if the value
889318334Speter	 is known to be positive, the number of sign bit copies is the
889418334Speter	 same as that of the input.  Finally, if the input has just one bit
889518334Speter	 that might be nonzero, all the bits are copies of the sign bit.  */
8896117395Skan      num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
889750397Sobrien      if (bitwidth > HOST_BITS_PER_WIDE_INT)
889850397Sobrien	return num0 > 1 ? num0 - 1 : 1;
889950397Sobrien
890018334Speter      nonzero = nonzero_bits (XEXP (x, 0), mode);
890118334Speter      if (nonzero == 1)
890218334Speter	return bitwidth;
890318334Speter
890418334Speter      if (num0 > 1
890518334Speter	  && (((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero))
890618334Speter	num0--;
890718334Speter
890818334Speter      return num0;
890918334Speter
891018334Speter    case IOR:   case AND:   case XOR:
891118334Speter    case SMIN:  case SMAX:  case UMIN:  case UMAX:
891218334Speter      /* Logical operations will preserve the number of sign-bit copies.
891318334Speter	 MIN and MAX operations always return one of the operands.  */
8914117395Skan      num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
8915117395Skan      num1 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
891618334Speter      return MIN (num0, num1);
891718334Speter
891818334Speter    case PLUS:  case MINUS:
891918334Speter      /* For addition and subtraction, we can have a 1-bit carry.  However,
892018334Speter	 if we are subtracting 1 from a positive number, there will not
892118334Speter	 be such a carry.  Furthermore, if the positive number is known to
892218334Speter	 be 0 or 1, we know the result is either -1 or 0.  */
892318334Speter
892418334Speter      if (code == PLUS && XEXP (x, 1) == constm1_rtx
892518334Speter	  && bitwidth <= HOST_BITS_PER_WIDE_INT)
892618334Speter	{
892718334Speter	  nonzero = nonzero_bits (XEXP (x, 0), mode);
892818334Speter	  if ((((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero) == 0)
892918334Speter	    return (nonzero == 1 || nonzero == 0 ? bitwidth
893018334Speter		    : bitwidth - floor_log2 (nonzero) - 1);
893118334Speter	}
893218334Speter
8933117395Skan      num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
8934117395Skan      num1 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
893590075Sobrien      result = MAX (1, MIN (num0, num1) - 1);
893690075Sobrien
893790075Sobrien#ifdef POINTERS_EXTEND_UNSIGNED
893890075Sobrien      /* If pointers extend signed and this is an addition or subtraction
893990075Sobrien	 to a pointer in Pmode, all the bits above ptr_mode are known to be
894090075Sobrien	 sign bit copies.  */
894190075Sobrien      if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
894290075Sobrien	  && (code == PLUS || code == MINUS)
894390075Sobrien	  && GET_CODE (XEXP (x, 0)) == REG && REG_POINTER (XEXP (x, 0)))
894490075Sobrien	result = MAX ((int) (GET_MODE_BITSIZE (Pmode)
894590075Sobrien			     - GET_MODE_BITSIZE (ptr_mode) + 1),
894690075Sobrien		      result);
894790075Sobrien#endif
894890075Sobrien      return result;
894990075Sobrien
895018334Speter    case MULT:
895118334Speter      /* The number of bits of the product is the sum of the number of
895218334Speter	 bits of both terms.  However, unless one of the terms if known
895318334Speter	 to be positive, we must allow for an additional bit since negating
895418334Speter	 a negative number can remove one sign bit copy.  */
895518334Speter
8956117395Skan      num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
8957117395Skan      num1 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
895818334Speter
895918334Speter      result = bitwidth - (bitwidth - num0) - (bitwidth - num1);
896018334Speter      if (result > 0
896150397Sobrien	  && (bitwidth > HOST_BITS_PER_WIDE_INT
896250397Sobrien	      || (((nonzero_bits (XEXP (x, 0), mode)
896350397Sobrien		    & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
896450397Sobrien		  && ((nonzero_bits (XEXP (x, 1), mode)
896550397Sobrien		       & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))))
896618334Speter	result--;
896718334Speter
896818334Speter      return MAX (1, result);
896918334Speter
897018334Speter    case UDIV:
897150397Sobrien      /* The result must be <= the first operand.  If the first operand
897250397Sobrien         has the high bit set, we know nothing about the number of sign
897350397Sobrien         bit copies.  */
897450397Sobrien      if (bitwidth > HOST_BITS_PER_WIDE_INT)
897550397Sobrien	return 1;
897650397Sobrien      else if ((nonzero_bits (XEXP (x, 0), mode)
897750397Sobrien		& ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
897850397Sobrien	return 1;
897950397Sobrien      else
8980117395Skan	return num_sign_bit_copies_with_known (XEXP (x, 0), mode);
898190075Sobrien
898218334Speter    case UMOD:
898390075Sobrien      /* The result must be <= the second operand.  */
8984117395Skan      return num_sign_bit_copies_with_known (XEXP (x, 1), mode);
898518334Speter
898618334Speter    case DIV:
898718334Speter      /* Similar to unsigned division, except that we have to worry about
898818334Speter	 the case where the divisor is negative, in which case we have
898918334Speter	 to add 1.  */
8990117395Skan      result = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
899118334Speter      if (result > 1
899250397Sobrien	  && (bitwidth > HOST_BITS_PER_WIDE_INT
899350397Sobrien	      || (nonzero_bits (XEXP (x, 1), mode)
899450397Sobrien		  & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
899550397Sobrien	result--;
899618334Speter
899718334Speter      return result;
899818334Speter
899918334Speter    case MOD:
9000117395Skan      result = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
900118334Speter      if (result > 1
900250397Sobrien	  && (bitwidth > HOST_BITS_PER_WIDE_INT
900350397Sobrien	      || (nonzero_bits (XEXP (x, 1), mode)
900450397Sobrien		  & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
900550397Sobrien	result--;
900618334Speter
900718334Speter      return result;
900818334Speter
900918334Speter    case ASHIFTRT:
901018334Speter      /* Shifts by a constant add to the number of bits equal to the
901118334Speter	 sign bit.  */
9012117395Skan      num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
901318334Speter      if (GET_CODE (XEXP (x, 1)) == CONST_INT
901418334Speter	  && INTVAL (XEXP (x, 1)) > 0)
901590075Sobrien	num0 = MIN ((int) bitwidth, num0 + INTVAL (XEXP (x, 1)));
901618334Speter
901718334Speter      return num0;
901818334Speter
901918334Speter    case ASHIFT:
902018334Speter      /* Left shifts destroy copies.  */
902118334Speter      if (GET_CODE (XEXP (x, 1)) != CONST_INT
902218334Speter	  || INTVAL (XEXP (x, 1)) < 0
902390075Sobrien	  || INTVAL (XEXP (x, 1)) >= (int) bitwidth)
902418334Speter	return 1;
902518334Speter
9026117395Skan      num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
902718334Speter      return MAX (1, num0 - INTVAL (XEXP (x, 1)));
902818334Speter
902918334Speter    case IF_THEN_ELSE:
9030117395Skan      num0 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
9031117395Skan      num1 = num_sign_bit_copies_with_known (XEXP (x, 2), mode);
903218334Speter      return MIN (num0, num1);
903318334Speter
903418334Speter    case EQ:  case NE:  case GE:  case GT:  case LE:  case LT:
903590075Sobrien    case UNEQ:  case LTGT:  case UNGE:  case UNGT:  case UNLE:  case UNLT:
903618334Speter    case GEU: case GTU: case LEU: case LTU:
903790075Sobrien    case UNORDERED: case ORDERED:
903890075Sobrien      /* If the constant is negative, take its 1's complement and remask.
903990075Sobrien	 Then see how many zero bits we have.  */
904090075Sobrien      nonzero = STORE_FLAG_VALUE;
904190075Sobrien      if (bitwidth <= HOST_BITS_PER_WIDE_INT
904290075Sobrien	  && (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
904390075Sobrien	nonzero = (~nonzero) & GET_MODE_MASK (mode);
904490075Sobrien
904590075Sobrien      return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1);
904650397Sobrien      break;
904790075Sobrien
904850397Sobrien    default:
904950397Sobrien      break;
905018334Speter    }
905118334Speter
905218334Speter  /* If we haven't been able to figure it out by one of the above rules,
905318334Speter     see if some of the high-order bits are known to be zero.  If so,
905418334Speter     count those bits and return one less than that amount.  If we can't
905518334Speter     safely compute the mask for this mode, always return BITWIDTH.  */
905618334Speter
905718334Speter  if (bitwidth > HOST_BITS_PER_WIDE_INT)
905818334Speter    return 1;
905918334Speter
906018334Speter  nonzero = nonzero_bits (x, mode);
906118334Speter  return (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))
906218334Speter	  ? 1 : bitwidth - floor_log2 (nonzero) - 1);
906318334Speter}
906418334Speter
906518334Speter/* Return the number of "extended" bits there are in X, when interpreted
906618334Speter   as a quantity in MODE whose signedness is indicated by UNSIGNEDP.  For
906718334Speter   unsigned quantities, this is the number of high-order zero bits.
906818334Speter   For signed quantities, this is the number of copies of the sign bit
906918334Speter   minus 1.  In both case, this function returns the number of "spare"
907018334Speter   bits.  For example, if two quantities for which this function returns
907118334Speter   at least 1 are added, the addition is known not to overflow.
907218334Speter
907318334Speter   This function will always return 0 unless called during combine, which
907418334Speter   implies that it must be called from a define_split.  */
907518334Speter
907690075Sobrienunsigned int
907718334Speterextended_count (x, mode, unsignedp)
907818334Speter     rtx x;
907918334Speter     enum machine_mode mode;
908018334Speter     int unsignedp;
908118334Speter{
908218334Speter  if (nonzero_sign_valid == 0)
908318334Speter    return 0;
908418334Speter
908518334Speter  return (unsignedp
908618334Speter	  ? (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
9087117395Skan	     ? (unsigned int) (GET_MODE_BITSIZE (mode) - 1
9088117395Skan			       - floor_log2 (nonzero_bits (x, mode)))
908990075Sobrien	     : 0)
909018334Speter	  : num_sign_bit_copies (x, mode) - 1);
909118334Speter}
909218334Speter
909318334Speter/* This function is called from `simplify_shift_const' to merge two
909418334Speter   outer operations.  Specifically, we have already found that we need
909518334Speter   to perform operation *POP0 with constant *PCONST0 at the outermost
909618334Speter   position.  We would now like to also perform OP1 with constant CONST1
909718334Speter   (with *POP0 being done last).
909818334Speter
909918334Speter   Return 1 if we can do the operation and update *POP0 and *PCONST0 with
910090075Sobrien   the resulting operation.  *PCOMP_P is set to 1 if we would need to
910118334Speter   complement the innermost operand, otherwise it is unchanged.
910218334Speter
910318334Speter   MODE is the mode in which the operation will be done.  No bits outside
910418334Speter   the width of this mode matter.  It is assumed that the width of this mode
910518334Speter   is smaller than or equal to HOST_BITS_PER_WIDE_INT.
910618334Speter
910718334Speter   If *POP0 or OP1 are NIL, it means no operation is required.  Only NEG, PLUS,
910818334Speter   IOR, XOR, and AND are supported.  We may set *POP0 to SET if the proper
910918334Speter   result is simply *PCONST0.
911018334Speter
911118334Speter   If the resulting operation cannot be expressed as one operation, we
911218334Speter   return 0 and do not change *POP0, *PCONST0, and *PCOMP_P.  */
911318334Speter
911418334Speterstatic int
911518334Spetermerge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p)
911618334Speter     enum rtx_code *pop0;
911718334Speter     HOST_WIDE_INT *pconst0;
911818334Speter     enum rtx_code op1;
911918334Speter     HOST_WIDE_INT const1;
912018334Speter     enum machine_mode mode;
912118334Speter     int *pcomp_p;
912218334Speter{
912318334Speter  enum rtx_code op0 = *pop0;
912418334Speter  HOST_WIDE_INT const0 = *pconst0;
912518334Speter
912618334Speter  const0 &= GET_MODE_MASK (mode);
912718334Speter  const1 &= GET_MODE_MASK (mode);
912818334Speter
912918334Speter  /* If OP0 is an AND, clear unimportant bits in CONST1.  */
913018334Speter  if (op0 == AND)
913118334Speter    const1 &= const0;
913218334Speter
913318334Speter  /* If OP0 or OP1 is NIL, this is easy.  Similarly if they are the same or
913418334Speter     if OP0 is SET.  */
913518334Speter
913618334Speter  if (op1 == NIL || op0 == SET)
913718334Speter    return 1;
913818334Speter
913918334Speter  else if (op0 == NIL)
914018334Speter    op0 = op1, const0 = const1;
914118334Speter
914218334Speter  else if (op0 == op1)
914318334Speter    {
914418334Speter      switch (op0)
914518334Speter	{
914618334Speter	case AND:
914718334Speter	  const0 &= const1;
914818334Speter	  break;
914918334Speter	case IOR:
915018334Speter	  const0 |= const1;
915118334Speter	  break;
915218334Speter	case XOR:
915318334Speter	  const0 ^= const1;
915418334Speter	  break;
915518334Speter	case PLUS:
915618334Speter	  const0 += const1;
915718334Speter	  break;
915818334Speter	case NEG:
915918334Speter	  op0 = NIL;
916018334Speter	  break;
916150397Sobrien	default:
916250397Sobrien	  break;
916318334Speter	}
916418334Speter    }
916518334Speter
916618334Speter  /* Otherwise, if either is a PLUS or NEG, we can't do anything.  */
916718334Speter  else if (op0 == PLUS || op1 == PLUS || op0 == NEG || op1 == NEG)
916818334Speter    return 0;
916918334Speter
917018334Speter  /* If the two constants aren't the same, we can't do anything.  The
917118334Speter     remaining six cases can all be done.  */
917218334Speter  else if (const0 != const1)
917318334Speter    return 0;
917418334Speter
917518334Speter  else
917618334Speter    switch (op0)
917718334Speter      {
917818334Speter      case IOR:
917918334Speter	if (op1 == AND)
918018334Speter	  /* (a & b) | b == b */
918118334Speter	  op0 = SET;
918218334Speter	else /* op1 == XOR */
918318334Speter	  /* (a ^ b) | b == a | b */
918450397Sobrien	  {;}
918518334Speter	break;
918618334Speter
918718334Speter      case XOR:
918818334Speter	if (op1 == AND)
918918334Speter	  /* (a & b) ^ b == (~a) & b */
919018334Speter	  op0 = AND, *pcomp_p = 1;
919118334Speter	else /* op1 == IOR */
919218334Speter	  /* (a | b) ^ b == a & ~b */
919390075Sobrien	  op0 = AND, *pconst0 = ~const0;
919418334Speter	break;
919518334Speter
919618334Speter      case AND:
919718334Speter	if (op1 == IOR)
919818334Speter	  /* (a | b) & b == b */
919918334Speter	op0 = SET;
920018334Speter	else /* op1 == XOR */
920118334Speter	  /* (a ^ b) & b) == (~a) & b */
920218334Speter	  *pcomp_p = 1;
920318334Speter	break;
920450397Sobrien      default:
920550397Sobrien	break;
920618334Speter      }
920718334Speter
920818334Speter  /* Check for NO-OP cases.  */
920918334Speter  const0 &= GET_MODE_MASK (mode);
921018334Speter  if (const0 == 0
921118334Speter      && (op0 == IOR || op0 == XOR || op0 == PLUS))
921218334Speter    op0 = NIL;
921318334Speter  else if (const0 == 0 && op0 == AND)
921418334Speter    op0 = SET;
921552284Sobrien  else if ((unsigned HOST_WIDE_INT) const0 == GET_MODE_MASK (mode)
921652284Sobrien	   && op0 == AND)
921718334Speter    op0 = NIL;
921818334Speter
921990075Sobrien  /* ??? Slightly redundant with the above mask, but not entirely.
922090075Sobrien     Moving this above means we'd have to sign-extend the mode mask
922190075Sobrien     for the final test.  */
922290075Sobrien  const0 = trunc_int_for_mode (const0, mode);
922318334Speter
922418334Speter  *pop0 = op0;
922518334Speter  *pconst0 = const0;
922618334Speter
922718334Speter  return 1;
922818334Speter}
922918334Speter
923018334Speter/* Simplify a shift of VAROP by COUNT bits.  CODE says what kind of shift.
9231117395Skan   The result of the shift is RESULT_MODE.  X, if nonzero, is an expression
923218334Speter   that we started with.
923318334Speter
923418334Speter   The shift is normally computed in the widest mode we find in VAROP, as
923518334Speter   long as it isn't a different number of words than RESULT_MODE.  Exceptions
923618334Speter   are ASHIFTRT and ROTATE, which are always done in their original mode,  */
923718334Speter
923818334Speterstatic rtx
923990075Sobriensimplify_shift_const (x, code, result_mode, varop, orig_count)
924018334Speter     rtx x;
924118334Speter     enum rtx_code code;
924218334Speter     enum machine_mode result_mode;
924318334Speter     rtx varop;
924490075Sobrien     int orig_count;
924518334Speter{
924618334Speter  enum rtx_code orig_code = code;
924790075Sobrien  unsigned int count;
924890075Sobrien  int signed_count;
924918334Speter  enum machine_mode mode = result_mode;
925018334Speter  enum machine_mode shift_mode, tmode;
925190075Sobrien  unsigned int mode_words
925218334Speter    = (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
925318334Speter  /* We form (outer_op (code varop count) (outer_const)).  */
925418334Speter  enum rtx_code outer_op = NIL;
925518334Speter  HOST_WIDE_INT outer_const = 0;
925618334Speter  rtx const_rtx;
925718334Speter  int complement_p = 0;
925818334Speter  rtx new;
925918334Speter
926090075Sobrien  /* Make sure and truncate the "natural" shift on the way in.  We don't
926190075Sobrien     want to do this inside the loop as it makes it more difficult to
926290075Sobrien     combine shifts.  */
926390075Sobrien#ifdef SHIFT_COUNT_TRUNCATED
926490075Sobrien  if (SHIFT_COUNT_TRUNCATED)
926590075Sobrien    orig_count &= GET_MODE_BITSIZE (mode) - 1;
926690075Sobrien#endif
926790075Sobrien
926818334Speter  /* If we were given an invalid count, don't do anything except exactly
926918334Speter     what was requested.  */
927018334Speter
927190075Sobrien  if (orig_count < 0 || orig_count >= (int) GET_MODE_BITSIZE (mode))
927218334Speter    {
927318334Speter      if (x)
927418334Speter	return x;
927518334Speter
927690075Sobrien      return gen_rtx_fmt_ee (code, mode, varop, GEN_INT (orig_count));
927718334Speter    }
927818334Speter
927990075Sobrien  count = orig_count;
928090075Sobrien
928118334Speter  /* Unless one of the branches of the `if' in this loop does a `continue',
928218334Speter     we will `break' the loop after the `if'.  */
928318334Speter
928418334Speter  while (count != 0)
928518334Speter    {
928618334Speter      /* If we have an operand of (clobber (const_int 0)), just return that
928718334Speter	 value.  */
928818334Speter      if (GET_CODE (varop) == CLOBBER)
928918334Speter	return varop;
929018334Speter
929118334Speter      /* If we discovered we had to complement VAROP, leave.  Making a NOT
929218334Speter	 here would cause an infinite loop.  */
929318334Speter      if (complement_p)
929418334Speter	break;
929518334Speter
929618334Speter      /* Convert ROTATERT to ROTATE.  */
929718334Speter      if (code == ROTATERT)
9298117395Skan	{
9299117395Skan	  unsigned int bitsize = GET_MODE_BITSIZE (result_mode);;
9300117395Skan	  code = ROTATE;
9301117395Skan	  if (VECTOR_MODE_P (result_mode))
9302117395Skan	    count = bitsize / GET_MODE_NUNITS (result_mode) - count;
9303117395Skan	  else
9304117395Skan	    count = bitsize - count;
9305117395Skan	}
930618334Speter
930718334Speter      /* We need to determine what mode we will do the shift in.  If the
930818334Speter	 shift is a right shift or a ROTATE, we must always do it in the mode
930918334Speter	 it was originally done in.  Otherwise, we can do it in MODE, the
931050397Sobrien	 widest mode encountered.  */
931118334Speter      shift_mode
931218334Speter	= (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE
931318334Speter	   ? result_mode : mode);
931418334Speter
931518334Speter      /* Handle cases where the count is greater than the size of the mode
931618334Speter	 minus 1.  For ASHIFT, use the size minus one as the count (this can
931718334Speter	 occur when simplifying (lshiftrt (ashiftrt ..))).  For rotates,
931818334Speter	 take the count modulo the size.  For other shifts, the result is
931918334Speter	 zero.
932018334Speter
932118334Speter	 Since these shifts are being produced by the compiler by combining
932218334Speter	 multiple operations, each of which are defined, we know what the
932318334Speter	 result is supposed to be.  */
932490075Sobrien
9325117395Skan      if (count > (unsigned int) (GET_MODE_BITSIZE (shift_mode) - 1))
932618334Speter	{
932718334Speter	  if (code == ASHIFTRT)
932818334Speter	    count = GET_MODE_BITSIZE (shift_mode) - 1;
932918334Speter	  else if (code == ROTATE || code == ROTATERT)
933018334Speter	    count %= GET_MODE_BITSIZE (shift_mode);
933118334Speter	  else
933218334Speter	    {
933318334Speter	      /* We can't simply return zero because there may be an
933418334Speter		 outer op.  */
933518334Speter	      varop = const0_rtx;
933618334Speter	      count = 0;
933718334Speter	      break;
933818334Speter	    }
933918334Speter	}
934018334Speter
934118334Speter      /* An arithmetic right shift of a quantity known to be -1 or 0
934218334Speter	 is a no-op.  */
934318334Speter      if (code == ASHIFTRT
934418334Speter	  && (num_sign_bit_copies (varop, shift_mode)
934518334Speter	      == GET_MODE_BITSIZE (shift_mode)))
934618334Speter	{
934718334Speter	  count = 0;
934818334Speter	  break;
934918334Speter	}
935018334Speter
935118334Speter      /* If we are doing an arithmetic right shift and discarding all but
935218334Speter	 the sign bit copies, this is equivalent to doing a shift by the
935318334Speter	 bitsize minus one.  Convert it into that shift because it will often
935418334Speter	 allow other simplifications.  */
935518334Speter
935618334Speter      if (code == ASHIFTRT
935718334Speter	  && (count + num_sign_bit_copies (varop, shift_mode)
935818334Speter	      >= GET_MODE_BITSIZE (shift_mode)))
935918334Speter	count = GET_MODE_BITSIZE (shift_mode) - 1;
936018334Speter
936118334Speter      /* We simplify the tests below and elsewhere by converting
936218334Speter	 ASHIFTRT to LSHIFTRT if we know the sign bit is clear.
9363117395Skan	 `make_compound_operation' will convert it to an ASHIFTRT for
9364117395Skan	 those machines (such as VAX) that don't have an LSHIFTRT.  */
936518334Speter      if (GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT
936618334Speter	  && code == ASHIFTRT
936718334Speter	  && ((nonzero_bits (varop, shift_mode)
936818334Speter	       & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (shift_mode) - 1)))
936918334Speter	      == 0))
937018334Speter	code = LSHIFTRT;
937118334Speter
937218334Speter      switch (GET_CODE (varop))
937318334Speter	{
937418334Speter	case SIGN_EXTEND:
937518334Speter	case ZERO_EXTEND:
937618334Speter	case SIGN_EXTRACT:
937718334Speter	case ZERO_EXTRACT:
937818334Speter	  new = expand_compound_operation (varop);
937918334Speter	  if (new != varop)
938018334Speter	    {
938118334Speter	      varop = new;
938218334Speter	      continue;
938318334Speter	    }
938418334Speter	  break;
938518334Speter
938618334Speter	case MEM:
938718334Speter	  /* If we have (xshiftrt (mem ...) C) and C is MODE_WIDTH
938818334Speter	     minus the width of a smaller mode, we can do this with a
938918334Speter	     SIGN_EXTEND or ZERO_EXTEND from the narrower memory location.  */
939018334Speter	  if ((code == ASHIFTRT || code == LSHIFTRT)
939118334Speter	      && ! mode_dependent_address_p (XEXP (varop, 0))
939218334Speter	      && ! MEM_VOLATILE_P (varop)
939318334Speter	      && (tmode = mode_for_size (GET_MODE_BITSIZE (mode) - count,
939418334Speter					 MODE_INT, 1)) != BLKmode)
939518334Speter	    {
939690075Sobrien	      new = adjust_address_nv (varop, tmode,
939790075Sobrien				       BYTES_BIG_ENDIAN ? 0
939890075Sobrien				       : count / BITS_PER_UNIT);
939990075Sobrien
940090075Sobrien	      varop = gen_rtx_fmt_e (code == ASHIFTRT ? SIGN_EXTEND
940190075Sobrien				     : ZERO_EXTEND, mode, new);
940218334Speter	      count = 0;
940318334Speter	      continue;
940418334Speter	    }
940518334Speter	  break;
940618334Speter
940718334Speter	case USE:
940818334Speter	  /* Similar to the case above, except that we can only do this if
940918334Speter	     the resulting mode is the same as that of the underlying
941018334Speter	     MEM and adjust the address depending on the *bits* endianness
941118334Speter	     because of the way that bit-field extract insns are defined.  */
941218334Speter	  if ((code == ASHIFTRT || code == LSHIFTRT)
941318334Speter	      && (tmode = mode_for_size (GET_MODE_BITSIZE (mode) - count,
941418334Speter					 MODE_INT, 1)) != BLKmode
941518334Speter	      && tmode == GET_MODE (XEXP (varop, 0)))
941618334Speter	    {
941718334Speter	      if (BITS_BIG_ENDIAN)
941818334Speter		new = XEXP (varop, 0);
941918334Speter	      else
942018334Speter		{
942118334Speter		  new = copy_rtx (XEXP (varop, 0));
942290075Sobrien		  SUBST (XEXP (new, 0),
942318334Speter			 plus_constant (XEXP (new, 0),
942418334Speter					count / BITS_PER_UNIT));
942518334Speter		}
942618334Speter
942790075Sobrien	      varop = gen_rtx_fmt_e (code == ASHIFTRT ? SIGN_EXTEND
942890075Sobrien				     : ZERO_EXTEND, mode, new);
942918334Speter	      count = 0;
943018334Speter	      continue;
943118334Speter	    }
943218334Speter	  break;
943318334Speter
943418334Speter	case SUBREG:
943518334Speter	  /* If VAROP is a SUBREG, strip it as long as the inner operand has
943618334Speter	     the same number of words as what we've seen so far.  Then store
943718334Speter	     the widest mode in MODE.  */
943818334Speter	  if (subreg_lowpart_p (varop)
943918334Speter	      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (varop)))
944018334Speter		  > GET_MODE_SIZE (GET_MODE (varop)))
9441117395Skan	      && (unsigned int) ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (varop)))
9442117395Skan				  + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
9443117395Skan		 == mode_words)
944418334Speter	    {
944518334Speter	      varop = SUBREG_REG (varop);
944618334Speter	      if (GET_MODE_SIZE (GET_MODE (varop)) > GET_MODE_SIZE (mode))
944718334Speter		mode = GET_MODE (varop);
944818334Speter	      continue;
944918334Speter	    }
945018334Speter	  break;
945118334Speter
945218334Speter	case MULT:
945318334Speter	  /* Some machines use MULT instead of ASHIFT because MULT
945418334Speter	     is cheaper.  But it is still better on those machines to
945518334Speter	     merge two shifts into one.  */
945618334Speter	  if (GET_CODE (XEXP (varop, 1)) == CONST_INT
945718334Speter	      && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
945818334Speter	    {
945990075Sobrien	      varop
946090075Sobrien		= gen_binary (ASHIFT, GET_MODE (varop), XEXP (varop, 0),
946190075Sobrien			      GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));
946218334Speter	      continue;
946318334Speter	    }
946418334Speter	  break;
946518334Speter
946618334Speter	case UDIV:
946718334Speter	  /* Similar, for when divides are cheaper.  */
946818334Speter	  if (GET_CODE (XEXP (varop, 1)) == CONST_INT
946918334Speter	      && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
947018334Speter	    {
947190075Sobrien	      varop
947290075Sobrien		= gen_binary (LSHIFTRT, GET_MODE (varop), XEXP (varop, 0),
947390075Sobrien			      GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));
947418334Speter	      continue;
947518334Speter	    }
947618334Speter	  break;
947718334Speter
947818334Speter	case ASHIFTRT:
947990075Sobrien	  /* If we are extracting just the sign bit of an arithmetic
948090075Sobrien	     right shift, that shift is not needed.  However, the sign
948190075Sobrien	     bit of a wider mode may be different from what would be
948290075Sobrien	     interpreted as the sign bit in a narrower mode, so, if
948390075Sobrien	     the result is narrower, don't discard the shift.  */
9484117395Skan	  if (code == LSHIFTRT
9485117395Skan	      && count == (unsigned int) (GET_MODE_BITSIZE (result_mode) - 1)
948690075Sobrien	      && (GET_MODE_BITSIZE (result_mode)
948790075Sobrien		  >= GET_MODE_BITSIZE (GET_MODE (varop))))
948818334Speter	    {
948918334Speter	      varop = XEXP (varop, 0);
949018334Speter	      continue;
949118334Speter	    }
949218334Speter
949350397Sobrien	  /* ... fall through ...  */
949418334Speter
949518334Speter	case LSHIFTRT:
949618334Speter	case ASHIFT:
949718334Speter	case ROTATE:
949818334Speter	  /* Here we have two nested shifts.  The result is usually the
949918334Speter	     AND of a new shift with a mask.  We compute the result below.  */
950018334Speter	  if (GET_CODE (XEXP (varop, 1)) == CONST_INT
950118334Speter	      && INTVAL (XEXP (varop, 1)) >= 0
950218334Speter	      && INTVAL (XEXP (varop, 1)) < GET_MODE_BITSIZE (GET_MODE (varop))
950318334Speter	      && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT
950418334Speter	      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
950518334Speter	    {
950618334Speter	      enum rtx_code first_code = GET_CODE (varop);
950790075Sobrien	      unsigned int first_count = INTVAL (XEXP (varop, 1));
950818334Speter	      unsigned HOST_WIDE_INT mask;
950918334Speter	      rtx mask_rtx;
951018334Speter
951118334Speter	      /* We have one common special case.  We can't do any merging if
951218334Speter		 the inner code is an ASHIFTRT of a smaller mode.  However, if
951318334Speter		 we have (ashift:M1 (subreg:M1 (ashiftrt:M2 FOO C1) 0) C2)
951418334Speter		 with C2 == GET_MODE_BITSIZE (M1) - GET_MODE_BITSIZE (M2),
951518334Speter		 we can convert it to
951618334Speter		 (ashiftrt:M1 (ashift:M1 (and:M1 (subreg:M1 FOO 0 C2) C3) C1).
951718334Speter		 This simplifies certain SIGN_EXTEND operations.  */
951818334Speter	      if (code == ASHIFT && first_code == ASHIFTRT
9519117395Skan		  && count == (unsigned int)
9520117395Skan			      (GET_MODE_BITSIZE (result_mode)
9521117395Skan			       - GET_MODE_BITSIZE (GET_MODE (varop))))
952218334Speter		{
952318334Speter		  /* C3 has the low-order C1 bits zero.  */
952490075Sobrien
952518334Speter		  mask = (GET_MODE_MASK (mode)
952690075Sobrien			  & ~(((HOST_WIDE_INT) 1 << first_count) - 1));
952718334Speter
952818334Speter		  varop = simplify_and_const_int (NULL_RTX, result_mode,
952918334Speter						  XEXP (varop, 0), mask);
953018334Speter		  varop = simplify_shift_const (NULL_RTX, ASHIFT, result_mode,
953118334Speter						varop, count);
953218334Speter		  count = first_count;
953318334Speter		  code = ASHIFTRT;
953418334Speter		  continue;
953518334Speter		}
953690075Sobrien
953718334Speter	      /* If this was (ashiftrt (ashift foo C1) C2) and FOO has more
953818334Speter		 than C1 high-order bits equal to the sign bit, we can convert
9539117395Skan		 this to either an ASHIFT or an ASHIFTRT depending on the
954090075Sobrien		 two counts.
954118334Speter
954218334Speter		 We cannot do this if VAROP's mode is not SHIFT_MODE.  */
954318334Speter
954418334Speter	      if (code == ASHIFTRT && first_code == ASHIFT
954518334Speter		  && GET_MODE (varop) == shift_mode
954618334Speter		  && (num_sign_bit_copies (XEXP (varop, 0), shift_mode)
954718334Speter		      > first_count))
954818334Speter		{
954918334Speter		  varop = XEXP (varop, 0);
955090075Sobrien
955190075Sobrien		  signed_count = count - first_count;
955290075Sobrien		  if (signed_count < 0)
955390075Sobrien		    count = -signed_count, code = ASHIFT;
955490075Sobrien		  else
955590075Sobrien		    count = signed_count;
955690075Sobrien
955718334Speter		  continue;
955818334Speter		}
955918334Speter
956018334Speter	      /* There are some cases we can't do.  If CODE is ASHIFTRT,
956118334Speter		 we can only do this if FIRST_CODE is also ASHIFTRT.
956218334Speter
956318334Speter		 We can't do the case when CODE is ROTATE and FIRST_CODE is
956418334Speter		 ASHIFTRT.
956518334Speter
956618334Speter		 If the mode of this shift is not the mode of the outer shift,
956718334Speter		 we can't do this if either shift is a right shift or ROTATE.
956818334Speter
956918334Speter		 Finally, we can't do any of these if the mode is too wide
957018334Speter		 unless the codes are the same.
957118334Speter
957218334Speter		 Handle the case where the shift codes are the same
957318334Speter		 first.  */
957418334Speter
957518334Speter	      if (code == first_code)
957618334Speter		{
957718334Speter		  if (GET_MODE (varop) != result_mode
957818334Speter		      && (code == ASHIFTRT || code == LSHIFTRT
957918334Speter			  || code == ROTATE))
958018334Speter		    break;
958118334Speter
958218334Speter		  count += first_count;
958318334Speter		  varop = XEXP (varop, 0);
958418334Speter		  continue;
958518334Speter		}
958618334Speter
958718334Speter	      if (code == ASHIFTRT
958818334Speter		  || (code == ROTATE && first_code == ASHIFTRT)
958918334Speter		  || GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT
959018334Speter		  || (GET_MODE (varop) != result_mode
959118334Speter		      && (first_code == ASHIFTRT || first_code == LSHIFTRT
959218334Speter			  || first_code == ROTATE
959318334Speter			  || code == ROTATE)))
959418334Speter		break;
959518334Speter
959618334Speter	      /* To compute the mask to apply after the shift, shift the
959790075Sobrien		 nonzero bits of the inner shift the same way the
959818334Speter		 outer shift will.  */
959918334Speter
960018334Speter	      mask_rtx = GEN_INT (nonzero_bits (varop, GET_MODE (varop)));
960118334Speter
960218334Speter	      mask_rtx
960318334Speter		= simplify_binary_operation (code, result_mode, mask_rtx,
960418334Speter					     GEN_INT (count));
960590075Sobrien
960618334Speter	      /* Give up if we can't compute an outer operation to use.  */
960718334Speter	      if (mask_rtx == 0
960818334Speter		  || GET_CODE (mask_rtx) != CONST_INT
960918334Speter		  || ! merge_outer_ops (&outer_op, &outer_const, AND,
961018334Speter					INTVAL (mask_rtx),
961118334Speter					result_mode, &complement_p))
961218334Speter		break;
961318334Speter
961418334Speter	      /* If the shifts are in the same direction, we add the
961518334Speter		 counts.  Otherwise, we subtract them.  */
961690075Sobrien	      signed_count = count;
961718334Speter	      if ((code == ASHIFTRT || code == LSHIFTRT)
961818334Speter		  == (first_code == ASHIFTRT || first_code == LSHIFTRT))
961990075Sobrien		signed_count += first_count;
962018334Speter	      else
962190075Sobrien		signed_count -= first_count;
962218334Speter
962390075Sobrien	      /* If COUNT is positive, the new shift is usually CODE,
962418334Speter		 except for the two exceptions below, in which case it is
962518334Speter		 FIRST_CODE.  If the count is negative, FIRST_CODE should
962618334Speter		 always be used  */
962790075Sobrien	      if (signed_count > 0
962818334Speter		  && ((first_code == ROTATE && code == ASHIFT)
962918334Speter		      || (first_code == ASHIFTRT && code == LSHIFTRT)))
963090075Sobrien		code = first_code, count = signed_count;
963190075Sobrien	      else if (signed_count < 0)
963290075Sobrien		code = first_code, count = -signed_count;
963390075Sobrien	      else
963490075Sobrien		count = signed_count;
963518334Speter
963618334Speter	      varop = XEXP (varop, 0);
963718334Speter	      continue;
963818334Speter	    }
963918334Speter
964018334Speter	  /* If we have (A << B << C) for any shift, we can convert this to
964118334Speter	     (A << C << B).  This wins if A is a constant.  Only try this if
964218334Speter	     B is not a constant.  */
964318334Speter
964418334Speter	  else if (GET_CODE (varop) == code
964518334Speter		   && GET_CODE (XEXP (varop, 1)) != CONST_INT
964618334Speter		   && 0 != (new
964718334Speter			    = simplify_binary_operation (code, mode,
964818334Speter							 XEXP (varop, 0),
964918334Speter							 GEN_INT (count))))
965018334Speter	    {
965190075Sobrien	      varop = gen_rtx_fmt_ee (code, mode, new, XEXP (varop, 1));
965218334Speter	      count = 0;
965318334Speter	      continue;
965418334Speter	    }
965518334Speter	  break;
965618334Speter
965718334Speter	case NOT:
965818334Speter	  /* Make this fit the case below.  */
965990075Sobrien	  varop = gen_rtx_XOR (mode, XEXP (varop, 0),
966090075Sobrien			       GEN_INT (GET_MODE_MASK (mode)));
966118334Speter	  continue;
966218334Speter
966318334Speter	case IOR:
966418334Speter	case AND:
966518334Speter	case XOR:
966618334Speter	  /* If we have (xshiftrt (ior (plus X (const_int -1)) X) C)
966718334Speter	     with C the size of VAROP - 1 and the shift is logical if
966818334Speter	     STORE_FLAG_VALUE is 1 and arithmetic if STORE_FLAG_VALUE is -1,
966918334Speter	     we have an (le X 0) operation.   If we have an arithmetic shift
967018334Speter	     and STORE_FLAG_VALUE is 1 or we have a logical shift with
967118334Speter	     STORE_FLAG_VALUE of -1, we have a (neg (le X 0)) operation.  */
967218334Speter
967318334Speter	  if (GET_CODE (varop) == IOR && GET_CODE (XEXP (varop, 0)) == PLUS
967418334Speter	      && XEXP (XEXP (varop, 0), 1) == constm1_rtx
967518334Speter	      && (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
967618334Speter	      && (code == LSHIFTRT || code == ASHIFTRT)
9677117395Skan	      && count == (unsigned int)
9678117395Skan			  (GET_MODE_BITSIZE (GET_MODE (varop)) - 1)
967918334Speter	      && rtx_equal_p (XEXP (XEXP (varop, 0), 0), XEXP (varop, 1)))
968018334Speter	    {
968118334Speter	      count = 0;
968290075Sobrien	      varop = gen_rtx_LE (GET_MODE (varop), XEXP (varop, 1),
968390075Sobrien				  const0_rtx);
968418334Speter
968518334Speter	      if (STORE_FLAG_VALUE == 1 ? code == ASHIFTRT : code == LSHIFTRT)
968690075Sobrien		varop = gen_rtx_NEG (GET_MODE (varop), varop);
968718334Speter
968818334Speter	      continue;
968918334Speter	    }
969018334Speter
969118334Speter	  /* If we have (shift (logical)), move the logical to the outside
969218334Speter	     to allow it to possibly combine with another logical and the
969318334Speter	     shift to combine with another shift.  This also canonicalizes to
969418334Speter	     what a ZERO_EXTRACT looks like.  Also, some machines have
969518334Speter	     (and (shift)) insns.  */
969618334Speter
969718334Speter	  if (GET_CODE (XEXP (varop, 1)) == CONST_INT
969818334Speter	      && (new = simplify_binary_operation (code, result_mode,
969918334Speter						   XEXP (varop, 1),
970018334Speter						   GEN_INT (count))) != 0
970190075Sobrien	      && GET_CODE (new) == CONST_INT
970218334Speter	      && merge_outer_ops (&outer_op, &outer_const, GET_CODE (varop),
970318334Speter				  INTVAL (new), result_mode, &complement_p))
970418334Speter	    {
970518334Speter	      varop = XEXP (varop, 0);
970618334Speter	      continue;
970718334Speter	    }
970818334Speter
970918334Speter	  /* If we can't do that, try to simplify the shift in each arm of the
971018334Speter	     logical expression, make a new logical expression, and apply
971118334Speter	     the inverse distributive law.  */
971218334Speter	  {
971318334Speter	    rtx lhs = simplify_shift_const (NULL_RTX, code, shift_mode,
971418334Speter					    XEXP (varop, 0), count);
971518334Speter	    rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode,
971618334Speter					    XEXP (varop, 1), count);
971718334Speter
971818334Speter	    varop = gen_binary (GET_CODE (varop), shift_mode, lhs, rhs);
971918334Speter	    varop = apply_distributive_law (varop);
972018334Speter
972118334Speter	    count = 0;
972218334Speter	  }
972318334Speter	  break;
972418334Speter
972518334Speter	case EQ:
972618334Speter	  /* convert (lshiftrt (eq FOO 0) C) to (xor FOO 1) if STORE_FLAG_VALUE
972718334Speter	     says that the sign bit can be tested, FOO has mode MODE, C is
972818334Speter	     GET_MODE_BITSIZE (MODE) - 1, and FOO has only its low-order bit
972918334Speter	     that may be nonzero.  */
973018334Speter	  if (code == LSHIFTRT
973118334Speter	      && XEXP (varop, 1) == const0_rtx
973218334Speter	      && GET_MODE (XEXP (varop, 0)) == result_mode
9733117395Skan	      && count == (unsigned int) (GET_MODE_BITSIZE (result_mode) - 1)
973418334Speter	      && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT
973518334Speter	      && ((STORE_FLAG_VALUE
973690075Sobrien		   & ((HOST_WIDE_INT) 1
973790075Sobrien		      < (GET_MODE_BITSIZE (result_mode) - 1))))
973818334Speter	      && nonzero_bits (XEXP (varop, 0), result_mode) == 1
973918334Speter	      && merge_outer_ops (&outer_op, &outer_const, XOR,
974018334Speter				  (HOST_WIDE_INT) 1, result_mode,
974118334Speter				  &complement_p))
974218334Speter	    {
974318334Speter	      varop = XEXP (varop, 0);
974418334Speter	      count = 0;
974518334Speter	      continue;
974618334Speter	    }
974718334Speter	  break;
974818334Speter
974918334Speter	case NEG:
975018334Speter	  /* (lshiftrt (neg A) C) where A is either 0 or 1 and C is one less
975118334Speter	     than the number of bits in the mode is equivalent to A.  */
9752117395Skan	  if (code == LSHIFTRT
9753117395Skan	      && count == (unsigned int) (GET_MODE_BITSIZE (result_mode) - 1)
975418334Speter	      && nonzero_bits (XEXP (varop, 0), result_mode) == 1)
975518334Speter	    {
975618334Speter	      varop = XEXP (varop, 0);
975718334Speter	      count = 0;
975818334Speter	      continue;
975918334Speter	    }
976018334Speter
976118334Speter	  /* NEG commutes with ASHIFT since it is multiplication.  Move the
976218334Speter	     NEG outside to allow shifts to combine.  */
976318334Speter	  if (code == ASHIFT
976418334Speter	      && merge_outer_ops (&outer_op, &outer_const, NEG,
976518334Speter				  (HOST_WIDE_INT) 0, result_mode,
976618334Speter				  &complement_p))
976718334Speter	    {
976818334Speter	      varop = XEXP (varop, 0);
976918334Speter	      continue;
977018334Speter	    }
977118334Speter	  break;
977218334Speter
977318334Speter	case PLUS:
977418334Speter	  /* (lshiftrt (plus A -1) C) where A is either 0 or 1 and C
977518334Speter	     is one less than the number of bits in the mode is
977618334Speter	     equivalent to (xor A 1).  */
9777117395Skan	  if (code == LSHIFTRT
9778117395Skan	      && count == (unsigned int) (GET_MODE_BITSIZE (result_mode) - 1)
977918334Speter	      && XEXP (varop, 1) == constm1_rtx
978018334Speter	      && nonzero_bits (XEXP (varop, 0), result_mode) == 1
978118334Speter	      && merge_outer_ops (&outer_op, &outer_const, XOR,
978218334Speter				  (HOST_WIDE_INT) 1, result_mode,
978318334Speter				  &complement_p))
978418334Speter	    {
978518334Speter	      count = 0;
978618334Speter	      varop = XEXP (varop, 0);
978718334Speter	      continue;
978818334Speter	    }
978918334Speter
979018334Speter	  /* If we have (xshiftrt (plus FOO BAR) C), and the only bits
979118334Speter	     that might be nonzero in BAR are those being shifted out and those
979218334Speter	     bits are known zero in FOO, we can replace the PLUS with FOO.
979318334Speter	     Similarly in the other operand order.  This code occurs when
979418334Speter	     we are computing the size of a variable-size array.  */
979518334Speter
979618334Speter	  if ((code == ASHIFTRT || code == LSHIFTRT)
979718334Speter	      && count < HOST_BITS_PER_WIDE_INT
979818334Speter	      && nonzero_bits (XEXP (varop, 1), result_mode) >> count == 0
979918334Speter	      && (nonzero_bits (XEXP (varop, 1), result_mode)
980018334Speter		  & nonzero_bits (XEXP (varop, 0), result_mode)) == 0)
980118334Speter	    {
980218334Speter	      varop = XEXP (varop, 0);
980318334Speter	      continue;
980418334Speter	    }
980518334Speter	  else if ((code == ASHIFTRT || code == LSHIFTRT)
980618334Speter		   && count < HOST_BITS_PER_WIDE_INT
980718334Speter		   && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT
980818334Speter		   && 0 == (nonzero_bits (XEXP (varop, 0), result_mode)
980918334Speter			    >> count)
981018334Speter		   && 0 == (nonzero_bits (XEXP (varop, 0), result_mode)
981118334Speter			    & nonzero_bits (XEXP (varop, 1),
981218334Speter						 result_mode)))
981318334Speter	    {
981418334Speter	      varop = XEXP (varop, 1);
981518334Speter	      continue;
981618334Speter	    }
981718334Speter
981818334Speter	  /* (ashift (plus foo C) N) is (plus (ashift foo N) C').  */
981918334Speter	  if (code == ASHIFT
982018334Speter	      && GET_CODE (XEXP (varop, 1)) == CONST_INT
982118334Speter	      && (new = simplify_binary_operation (ASHIFT, result_mode,
982218334Speter						   XEXP (varop, 1),
982318334Speter						   GEN_INT (count))) != 0
982490075Sobrien	      && GET_CODE (new) == CONST_INT
982518334Speter	      && merge_outer_ops (&outer_op, &outer_const, PLUS,
982618334Speter				  INTVAL (new), result_mode, &complement_p))
982718334Speter	    {
982818334Speter	      varop = XEXP (varop, 0);
982918334Speter	      continue;
983018334Speter	    }
983118334Speter	  break;
983218334Speter
983318334Speter	case MINUS:
983418334Speter	  /* If we have (xshiftrt (minus (ashiftrt X C)) X) C)
983518334Speter	     with C the size of VAROP - 1 and the shift is logical if
983618334Speter	     STORE_FLAG_VALUE is 1 and arithmetic if STORE_FLAG_VALUE is -1,
983718334Speter	     we have a (gt X 0) operation.  If the shift is arithmetic with
983818334Speter	     STORE_FLAG_VALUE of 1 or logical with STORE_FLAG_VALUE == -1,
983918334Speter	     we have a (neg (gt X 0)) operation.  */
984018334Speter
984150397Sobrien	  if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
984250397Sobrien	      && GET_CODE (XEXP (varop, 0)) == ASHIFTRT
9843117395Skan	      && count == (unsigned int)
9844117395Skan			  (GET_MODE_BITSIZE (GET_MODE (varop)) - 1)
984518334Speter	      && (code == LSHIFTRT || code == ASHIFTRT)
984618334Speter	      && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT
9847117395Skan	      && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (varop, 0), 1))
9848117395Skan		 == count
984918334Speter	      && rtx_equal_p (XEXP (XEXP (varop, 0), 0), XEXP (varop, 1)))
985018334Speter	    {
985118334Speter	      count = 0;
985290075Sobrien	      varop = gen_rtx_GT (GET_MODE (varop), XEXP (varop, 1),
985390075Sobrien				  const0_rtx);
985418334Speter
985518334Speter	      if (STORE_FLAG_VALUE == 1 ? code == ASHIFTRT : code == LSHIFTRT)
985690075Sobrien		varop = gen_rtx_NEG (GET_MODE (varop), varop);
985718334Speter
985818334Speter	      continue;
985918334Speter	    }
986018334Speter	  break;
986150397Sobrien
986250397Sobrien	case TRUNCATE:
986350397Sobrien	  /* Change (lshiftrt (truncate (lshiftrt))) to (truncate (lshiftrt))
986450397Sobrien	     if the truncate does not affect the value.  */
986550397Sobrien	  if (code == LSHIFTRT
986650397Sobrien	      && GET_CODE (XEXP (varop, 0)) == LSHIFTRT
986750397Sobrien	      && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT
986850397Sobrien	      && (INTVAL (XEXP (XEXP (varop, 0), 1))
986950397Sobrien		  >= (GET_MODE_BITSIZE (GET_MODE (XEXP (varop, 0)))
987050397Sobrien		      - GET_MODE_BITSIZE (GET_MODE (varop)))))
987150397Sobrien	    {
987250397Sobrien	      rtx varop_inner = XEXP (varop, 0);
987350397Sobrien
987490075Sobrien	      varop_inner
987590075Sobrien		= gen_rtx_LSHIFTRT (GET_MODE (varop_inner),
987690075Sobrien				    XEXP (varop_inner, 0),
987790075Sobrien				    GEN_INT
987890075Sobrien				    (count + INTVAL (XEXP (varop_inner, 1))));
987990075Sobrien	      varop = gen_rtx_TRUNCATE (GET_MODE (varop), varop_inner);
988050397Sobrien	      count = 0;
988150397Sobrien	      continue;
988250397Sobrien	    }
988350397Sobrien	  break;
988490075Sobrien
988550397Sobrien	default:
988650397Sobrien	  break;
988718334Speter	}
988818334Speter
988918334Speter      break;
989018334Speter    }
989118334Speter
989218334Speter  /* We need to determine what mode to do the shift in.  If the shift is
989318334Speter     a right shift or ROTATE, we must always do it in the mode it was
989418334Speter     originally done in.  Otherwise, we can do it in MODE, the widest mode
989518334Speter     encountered.  The code we care about is that of the shift that will
989618334Speter     actually be done, not the shift that was originally requested.  */
989718334Speter  shift_mode
989818334Speter    = (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE
989918334Speter       ? result_mode : mode);
990018334Speter
990118334Speter  /* We have now finished analyzing the shift.  The result should be
990218334Speter     a shift of type CODE with SHIFT_MODE shifting VAROP COUNT places.  If
990318334Speter     OUTER_OP is non-NIL, it is an operation that needs to be applied
990418334Speter     to the result of the shift.  OUTER_CONST is the relevant constant,
990518334Speter     but we must turn off all bits turned off in the shift.
990618334Speter
990718334Speter     If we were passed a value for X, see if we can use any pieces of
990818334Speter     it.  If not, make new rtx.  */
990918334Speter
991018334Speter  if (x && GET_RTX_CLASS (GET_CODE (x)) == '2'
991118334Speter      && GET_CODE (XEXP (x, 1)) == CONST_INT
9912117395Skan      && (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) == count)
991318334Speter    const_rtx = XEXP (x, 1);
991418334Speter  else
991518334Speter    const_rtx = GEN_INT (count);
991618334Speter
991718334Speter  if (x && GET_CODE (XEXP (x, 0)) == SUBREG
991818334Speter      && GET_MODE (XEXP (x, 0)) == shift_mode
991918334Speter      && SUBREG_REG (XEXP (x, 0)) == varop)
992018334Speter    varop = XEXP (x, 0);
992118334Speter  else if (GET_MODE (varop) != shift_mode)
992218334Speter    varop = gen_lowpart_for_combine (shift_mode, varop);
992318334Speter
992450397Sobrien  /* If we can't make the SUBREG, try to return what we were given.  */
992518334Speter  if (GET_CODE (varop) == CLOBBER)
992618334Speter    return x ? x : varop;
992718334Speter
992818334Speter  new = simplify_binary_operation (code, shift_mode, varop, const_rtx);
992918334Speter  if (new != 0)
993018334Speter    x = new;
993118334Speter  else
993290075Sobrien    x = gen_rtx_fmt_ee (code, shift_mode, varop, const_rtx);
993318334Speter
993418334Speter  /* If we have an outer operation and we just made a shift, it is
993518334Speter     possible that we could have simplified the shift were it not
993618334Speter     for the outer operation.  So try to do the simplification
993718334Speter     recursively.  */
993818334Speter
993918334Speter  if (outer_op != NIL && GET_CODE (x) == code
994018334Speter      && GET_CODE (XEXP (x, 1)) == CONST_INT)
994118334Speter    x = simplify_shift_const (x, code, shift_mode, XEXP (x, 0),
994218334Speter			      INTVAL (XEXP (x, 1)));
994318334Speter
9944117395Skan  /* If we were doing an LSHIFTRT in a wider mode than it was originally,
994518334Speter     turn off all the bits that the shift would have turned off.  */
994618334Speter  if (orig_code == LSHIFTRT && result_mode != shift_mode)
994718334Speter    x = simplify_and_const_int (NULL_RTX, shift_mode, x,
994818334Speter				GET_MODE_MASK (result_mode) >> orig_count);
994990075Sobrien
995018334Speter  /* Do the remainder of the processing in RESULT_MODE.  */
995118334Speter  x = gen_lowpart_for_combine (result_mode, x);
995218334Speter
995318334Speter  /* If COMPLEMENT_P is set, we have to complement X before doing the outer
995418334Speter     operation.  */
995518334Speter  if (complement_p)
995690075Sobrien    x =simplify_gen_unary (NOT, result_mode, x, result_mode);
995718334Speter
995818334Speter  if (outer_op != NIL)
995918334Speter    {
996018334Speter      if (GET_MODE_BITSIZE (result_mode) < HOST_BITS_PER_WIDE_INT)
996190075Sobrien	outer_const = trunc_int_for_mode (outer_const, result_mode);
996218334Speter
996318334Speter      if (outer_op == AND)
996418334Speter	x = simplify_and_const_int (NULL_RTX, result_mode, x, outer_const);
996518334Speter      else if (outer_op == SET)
996618334Speter	/* This means that we have determined that the result is
996718334Speter	   equivalent to a constant.  This should be rare.  */
996818334Speter	x = GEN_INT (outer_const);
996918334Speter      else if (GET_RTX_CLASS (outer_op) == '1')
997090075Sobrien	x = simplify_gen_unary (outer_op, result_mode, x, result_mode);
997118334Speter      else
997218334Speter	x = gen_binary (outer_op, result_mode, x, GEN_INT (outer_const));
997318334Speter    }
997418334Speter
997518334Speter  return x;
997690075Sobrien}
997718334Speter
997818334Speter/* Like recog, but we receive the address of a pointer to a new pattern.
997918334Speter   We try to match the rtx that the pointer points to.
998018334Speter   If that fails, we may try to modify or replace the pattern,
998118334Speter   storing the replacement into the same pointer object.
998218334Speter
998318334Speter   Modifications include deletion or addition of CLOBBERs.
998418334Speter
998518334Speter   PNOTES is a pointer to a location where any REG_UNUSED notes added for
998618334Speter   the CLOBBERs are placed.
998718334Speter
998818334Speter   The value is the final insn code from the pattern ultimately matched,
998918334Speter   or -1.  */
999018334Speter
999118334Speterstatic int
999252284Sobrienrecog_for_combine (pnewpat, insn, pnotes)
999318334Speter     rtx *pnewpat;
999418334Speter     rtx insn;
999518334Speter     rtx *pnotes;
999618334Speter{
999790075Sobrien  rtx pat = *pnewpat;
999818334Speter  int insn_code_number;
999918334Speter  int num_clobbers_to_add = 0;
1000018334Speter  int i;
1000118334Speter  rtx notes = 0;
1000296263Sobrien  rtx dummy_insn;
1000318334Speter
1000418334Speter  /* If PAT is a PARALLEL, check to see if it contains the CLOBBER
1000518334Speter     we use to indicate that something didn't match.  If we find such a
1000618334Speter     thing, force rejection.  */
1000718334Speter  if (GET_CODE (pat) == PARALLEL)
1000818334Speter    for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
1000918334Speter      if (GET_CODE (XVECEXP (pat, 0, i)) == CLOBBER
1001018334Speter	  && XEXP (XVECEXP (pat, 0, i), 0) == const0_rtx)
1001118334Speter	return -1;
1001218334Speter
1001396263Sobrien  /* *pnewpat does not have to be actual PATTERN (insn), so make a dummy
1001496263Sobrien     instruction for pattern recognition.  */
1001596263Sobrien  dummy_insn = shallow_copy_rtx (insn);
1001696263Sobrien  PATTERN (dummy_insn) = pat;
1001796263Sobrien  REG_NOTES (dummy_insn) = 0;
1001890075Sobrien
1001996263Sobrien  insn_code_number = recog (pat, dummy_insn, &num_clobbers_to_add);
1002018334Speter
1002118334Speter  /* If it isn't, there is the possibility that we previously had an insn
1002218334Speter     that clobbered some register as a side effect, but the combined
1002318334Speter     insn doesn't need to do that.  So try once more without the clobbers
1002418334Speter     unless this represents an ASM insn.  */
1002518334Speter
1002618334Speter  if (insn_code_number < 0 && ! check_asm_operands (pat)
1002718334Speter      && GET_CODE (pat) == PARALLEL)
1002818334Speter    {
1002918334Speter      int pos;
1003018334Speter
1003118334Speter      for (pos = 0, i = 0; i < XVECLEN (pat, 0); i++)
1003218334Speter	if (GET_CODE (XVECEXP (pat, 0, i)) != CLOBBER)
1003318334Speter	  {
1003418334Speter	    if (i != pos)
1003518334Speter	      SUBST (XVECEXP (pat, 0, pos), XVECEXP (pat, 0, i));
1003618334Speter	    pos++;
1003718334Speter	  }
1003818334Speter
1003918334Speter      SUBST_INT (XVECLEN (pat, 0), pos);
1004018334Speter
1004118334Speter      if (pos == 1)
1004218334Speter	pat = XVECEXP (pat, 0, 0);
1004318334Speter
1004496263Sobrien      PATTERN (dummy_insn) = pat;
1004596263Sobrien      insn_code_number = recog (pat, dummy_insn, &num_clobbers_to_add);
1004618334Speter    }
1004718334Speter
1004890075Sobrien  /* Recognize all noop sets, these will be killed by followup pass.  */
1004990075Sobrien  if (insn_code_number < 0 && GET_CODE (pat) == SET && set_noop_p (pat))
1005090075Sobrien    insn_code_number = NOOP_MOVE_INSN_CODE, num_clobbers_to_add = 0;
1005190075Sobrien
1005218334Speter  /* If we had any clobbers to add, make a new pattern than contains
1005318334Speter     them.  Then check to make sure that all of them are dead.  */
1005418334Speter  if (num_clobbers_to_add)
1005518334Speter    {
1005650397Sobrien      rtx newpat = gen_rtx_PARALLEL (VOIDmode,
1005790075Sobrien				     rtvec_alloc (GET_CODE (pat) == PARALLEL
1005890075Sobrien						  ? (XVECLEN (pat, 0)
1005990075Sobrien						     + num_clobbers_to_add)
1006090075Sobrien						  : num_clobbers_to_add + 1));
1006118334Speter
1006218334Speter      if (GET_CODE (pat) == PARALLEL)
1006318334Speter	for (i = 0; i < XVECLEN (pat, 0); i++)
1006418334Speter	  XVECEXP (newpat, 0, i) = XVECEXP (pat, 0, i);
1006518334Speter      else
1006618334Speter	XVECEXP (newpat, 0, 0) = pat;
1006718334Speter
1006818334Speter      add_clobbers (newpat, insn_code_number);
1006918334Speter
1007018334Speter      for (i = XVECLEN (newpat, 0) - num_clobbers_to_add;
1007118334Speter	   i < XVECLEN (newpat, 0); i++)
1007218334Speter	{
1007318334Speter	  if (GET_CODE (XEXP (XVECEXP (newpat, 0, i), 0)) == REG
1007418334Speter	      && ! reg_dead_at_p (XEXP (XVECEXP (newpat, 0, i), 0), insn))
1007518334Speter	    return -1;
1007650397Sobrien	  notes = gen_rtx_EXPR_LIST (REG_UNUSED,
1007750397Sobrien				     XEXP (XVECEXP (newpat, 0, i), 0), notes);
1007818334Speter	}
1007918334Speter      pat = newpat;
1008018334Speter    }
1008118334Speter
1008218334Speter  *pnewpat = pat;
1008318334Speter  *pnotes = notes;
1008418334Speter
1008518334Speter  return insn_code_number;
1008618334Speter}
1008718334Speter
1008818334Speter/* Like gen_lowpart but for use by combine.  In combine it is not possible
1008918334Speter   to create any new pseudoregs.  However, it is safe to create
1009018334Speter   invalid memory addresses, because combine will try to recognize
1009118334Speter   them and all they will do is make the combine attempt fail.
1009218334Speter
1009318334Speter   If for some reason this cannot do its job, an rtx
1009418334Speter   (clobber (const_int 0)) is returned.
1009518334Speter   An insn containing that will not be recognized.  */
1009618334Speter
1009718334Speter#undef gen_lowpart
1009818334Speter
1009918334Speterstatic rtx
1010018334Spetergen_lowpart_for_combine (mode, x)
1010118334Speter     enum machine_mode mode;
1010290075Sobrien     rtx x;
1010318334Speter{
1010418334Speter  rtx result;
1010518334Speter
1010618334Speter  if (GET_MODE (x) == mode)
1010718334Speter    return x;
1010818334Speter
1010918334Speter  /* We can only support MODE being wider than a word if X is a
1011018334Speter     constant integer or has a mode the same size.  */
1011118334Speter
1011218334Speter  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
1011318334Speter      && ! ((GET_MODE (x) == VOIDmode
1011418334Speter	     && (GET_CODE (x) == CONST_INT
1011518334Speter		 || GET_CODE (x) == CONST_DOUBLE))
1011618334Speter	    || GET_MODE_SIZE (GET_MODE (x)) == GET_MODE_SIZE (mode)))
1011750397Sobrien    return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
1011818334Speter
1011918334Speter  /* X might be a paradoxical (subreg (mem)).  In that case, gen_lowpart
1012018334Speter     won't know what to do.  So we will strip off the SUBREG here and
1012118334Speter     process normally.  */
1012218334Speter  if (GET_CODE (x) == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM)
1012318334Speter    {
1012418334Speter      x = SUBREG_REG (x);
1012518334Speter      if (GET_MODE (x) == mode)
1012618334Speter	return x;
1012718334Speter    }
1012818334Speter
1012918334Speter  result = gen_lowpart_common (mode, x);
10130117395Skan#ifdef CANNOT_CHANGE_MODE_CLASS
1013118334Speter  if (result != 0
1013218334Speter      && GET_CODE (result) == SUBREG
1013318334Speter      && GET_CODE (SUBREG_REG (result)) == REG
10134117395Skan      && REGNO (SUBREG_REG (result)) >= FIRST_PSEUDO_REGISTER)
10135117395Skan    bitmap_set_bit (&subregs_of_mode, REGNO (SUBREG_REG (result))
10136117395Skan				      * MAX_MACHINE_MODE
10137117395Skan				      + GET_MODE (result));
1013890075Sobrien#endif
1013918334Speter
1014018334Speter  if (result)
1014118334Speter    return result;
1014218334Speter
1014318334Speter  if (GET_CODE (x) == MEM)
1014418334Speter    {
1014590075Sobrien      int offset = 0;
1014618334Speter
1014718334Speter      /* Refuse to work on a volatile memory ref or one with a mode-dependent
1014818334Speter	 address.  */
1014918334Speter      if (MEM_VOLATILE_P (x) || mode_dependent_address_p (XEXP (x, 0)))
1015050397Sobrien	return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
1015118334Speter
1015218334Speter      /* If we want to refer to something bigger than the original memref,
1015318334Speter	 generate a perverse subreg instead.  That will force a reload
1015418334Speter	 of the original memref X.  */
1015518334Speter      if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode))
1015650397Sobrien	return gen_rtx_SUBREG (mode, x, 0);
1015718334Speter
1015818334Speter      if (WORDS_BIG_ENDIAN)
1015918334Speter	offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
1016018334Speter		  - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
1016190075Sobrien
1016218334Speter      if (BYTES_BIG_ENDIAN)
1016318334Speter	{
1016418334Speter	  /* Adjust the address so that the address-after-the-data is
1016518334Speter	     unchanged.  */
1016618334Speter	  offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
1016718334Speter		     - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
1016818334Speter	}
1016990075Sobrien
1017090075Sobrien      return adjust_address_nv (x, mode, offset);
1017118334Speter    }
1017218334Speter
1017318334Speter  /* If X is a comparison operator, rewrite it in a new mode.  This
1017418334Speter     probably won't match, but may allow further simplifications.  */
1017518334Speter  else if (GET_RTX_CLASS (GET_CODE (x)) == '<')
1017690075Sobrien    return gen_rtx_fmt_ee (GET_CODE (x), mode, XEXP (x, 0), XEXP (x, 1));
1017718334Speter
1017818334Speter  /* If we couldn't simplify X any other way, just enclose it in a
1017918334Speter     SUBREG.  Normally, this SUBREG won't match, but some patterns may
1018018334Speter     include an explicit SUBREG or we may simplify it further in combine.  */
1018118334Speter  else
1018218334Speter    {
1018390075Sobrien      int offset = 0;
1018490075Sobrien      rtx res;
10185117395Skan      enum machine_mode sub_mode = GET_MODE (x);
1018618334Speter
10187117395Skan      offset = subreg_lowpart_offset (mode, sub_mode);
10188117395Skan      if (sub_mode == VOIDmode)
10189117395Skan	{
10190117395Skan	  sub_mode = int_mode_for_mode (mode);
10191117395Skan	  x = gen_lowpart_common (sub_mode, x);
10192117395Skan	}
10193117395Skan      res = simplify_gen_subreg (mode, x, sub_mode, offset);
1019490075Sobrien      if (res)
1019590075Sobrien	return res;
1019690075Sobrien      return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
1019718334Speter    }
1019818334Speter}
1019918334Speter
1020018334Speter/* These routines make binary and unary operations by first seeing if they
1020118334Speter   fold; if not, a new expression is allocated.  */
1020218334Speter
1020318334Speterstatic rtx
1020418334Spetergen_binary (code, mode, op0, op1)
1020518334Speter     enum rtx_code code;
1020618334Speter     enum machine_mode mode;
1020718334Speter     rtx op0, op1;
1020818334Speter{
1020918334Speter  rtx result;
1021018334Speter  rtx tem;
1021118334Speter
1021218334Speter  if (GET_RTX_CLASS (code) == 'c'
1021390075Sobrien      && swap_commutative_operands_p (op0, op1))
1021418334Speter    tem = op0, op0 = op1, op1 = tem;
1021518334Speter
1021690075Sobrien  if (GET_RTX_CLASS (code) == '<')
1021718334Speter    {
1021818334Speter      enum machine_mode op_mode = GET_MODE (op0);
1021918334Speter
1022090075Sobrien      /* Strip the COMPARE from (REL_OP (compare X Y) 0) to get
1022150397Sobrien	 just (REL_OP X Y).  */
1022218334Speter      if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
1022318334Speter	{
1022418334Speter	  op1 = XEXP (op0, 1);
1022518334Speter	  op0 = XEXP (op0, 0);
1022618334Speter	  op_mode = GET_MODE (op0);
1022718334Speter	}
1022818334Speter
1022918334Speter      if (op_mode == VOIDmode)
1023018334Speter	op_mode = GET_MODE (op1);
1023118334Speter      result = simplify_relational_operation (code, op_mode, op0, op1);
1023218334Speter    }
1023318334Speter  else
1023418334Speter    result = simplify_binary_operation (code, mode, op0, op1);
1023518334Speter
1023618334Speter  if (result)
1023718334Speter    return result;
1023818334Speter
1023918334Speter  /* Put complex operands first and constants second.  */
1024018334Speter  if (GET_RTX_CLASS (code) == 'c'
1024190075Sobrien      && swap_commutative_operands_p (op0, op1))
1024290075Sobrien    return gen_rtx_fmt_ee (code, mode, op1, op0);
1024318334Speter
1024450397Sobrien  /* If we are turning off bits already known off in OP0, we need not do
1024550397Sobrien     an AND.  */
1024650397Sobrien  else if (code == AND && GET_CODE (op1) == CONST_INT
1024750397Sobrien	   && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
1024890075Sobrien	   && (nonzero_bits (op0, mode) & ~INTVAL (op1)) == 0)
1024950397Sobrien    return op0;
1025050397Sobrien
1025190075Sobrien  return gen_rtx_fmt_ee (code, mode, op0, op1);
1025218334Speter}
1025318334Speter
1025418334Speter/* Simplify a comparison between *POP0 and *POP1 where CODE is the
1025518334Speter   comparison code that will be tested.
1025618334Speter
1025718334Speter   The result is a possibly different comparison code to use.  *POP0 and
1025818334Speter   *POP1 may be updated.
1025918334Speter
1026018334Speter   It is possible that we might detect that a comparison is either always
1026118334Speter   true or always false.  However, we do not perform general constant
1026218334Speter   folding in combine, so this knowledge isn't useful.  Such tautologies
1026318334Speter   should have been detected earlier.  Hence we ignore all such cases.  */
1026418334Speter
1026518334Speterstatic enum rtx_code
1026618334Spetersimplify_comparison (code, pop0, pop1)
1026718334Speter     enum rtx_code code;
1026818334Speter     rtx *pop0;
1026918334Speter     rtx *pop1;
1027018334Speter{
1027118334Speter  rtx op0 = *pop0;
1027218334Speter  rtx op1 = *pop1;
1027318334Speter  rtx tem, tem1;
1027418334Speter  int i;
1027518334Speter  enum machine_mode mode, tmode;
1027618334Speter
1027718334Speter  /* Try a few ways of applying the same transformation to both operands.  */
1027818334Speter  while (1)
1027918334Speter    {
1028018334Speter#ifndef WORD_REGISTER_OPERATIONS
1028118334Speter      /* The test below this one won't handle SIGN_EXTENDs on these machines,
1028218334Speter	 so check specially.  */
1028318334Speter      if (code != GTU && code != GEU && code != LTU && code != LEU
1028418334Speter	  && GET_CODE (op0) == ASHIFTRT && GET_CODE (op1) == ASHIFTRT
1028518334Speter	  && GET_CODE (XEXP (op0, 0)) == ASHIFT
1028618334Speter	  && GET_CODE (XEXP (op1, 0)) == ASHIFT
1028718334Speter	  && GET_CODE (XEXP (XEXP (op0, 0), 0)) == SUBREG
1028818334Speter	  && GET_CODE (XEXP (XEXP (op1, 0), 0)) == SUBREG
1028918334Speter	  && (GET_MODE (SUBREG_REG (XEXP (XEXP (op0, 0), 0)))
1029018334Speter	      == GET_MODE (SUBREG_REG (XEXP (XEXP (op1, 0), 0))))
1029118334Speter	  && GET_CODE (XEXP (op0, 1)) == CONST_INT
1029218334Speter	  && GET_CODE (XEXP (op1, 1)) == CONST_INT
1029318334Speter	  && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
1029418334Speter	  && GET_CODE (XEXP (XEXP (op1, 0), 1)) == CONST_INT
1029518334Speter	  && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (op1, 1))
1029618334Speter	  && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (XEXP (op0, 0), 1))
1029718334Speter	  && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (XEXP (op1, 0), 1))
1029818334Speter	  && (INTVAL (XEXP (op0, 1))
1029918334Speter	      == (GET_MODE_BITSIZE (GET_MODE (op0))
1030018334Speter		  - (GET_MODE_BITSIZE
1030118334Speter		     (GET_MODE (SUBREG_REG (XEXP (XEXP (op0, 0), 0))))))))
1030218334Speter	{
1030318334Speter	  op0 = SUBREG_REG (XEXP (XEXP (op0, 0), 0));
1030418334Speter	  op1 = SUBREG_REG (XEXP (XEXP (op1, 0), 0));
1030518334Speter	}
1030618334Speter#endif
1030718334Speter
1030818334Speter      /* If both operands are the same constant shift, see if we can ignore the
1030918334Speter	 shift.  We can if the shift is a rotate or if the bits shifted out of
1031018334Speter	 this shift are known to be zero for both inputs and if the type of
1031118334Speter	 comparison is compatible with the shift.  */
1031218334Speter      if (GET_CODE (op0) == GET_CODE (op1)
1031318334Speter	  && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT
1031418334Speter	  && ((GET_CODE (op0) == ROTATE && (code == NE || code == EQ))
1031518334Speter	      || ((GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFT)
1031618334Speter		  && (code != GT && code != LT && code != GE && code != LE))
1031718334Speter	      || (GET_CODE (op0) == ASHIFTRT
1031818334Speter		  && (code != GTU && code != LTU
1031990075Sobrien		      && code != GEU && code != LEU)))
1032018334Speter	  && GET_CODE (XEXP (op0, 1)) == CONST_INT
1032118334Speter	  && INTVAL (XEXP (op0, 1)) >= 0
1032218334Speter	  && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT
1032318334Speter	  && XEXP (op0, 1) == XEXP (op1, 1))
1032418334Speter	{
1032518334Speter	  enum machine_mode mode = GET_MODE (op0);
1032618334Speter	  unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
1032718334Speter	  int shift_count = INTVAL (XEXP (op0, 1));
1032818334Speter
1032918334Speter	  if (GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFTRT)
1033018334Speter	    mask &= (mask >> shift_count) << shift_count;
1033118334Speter	  else if (GET_CODE (op0) == ASHIFT)
1033218334Speter	    mask = (mask & (mask << shift_count)) >> shift_count;
1033318334Speter
1033490075Sobrien	  if ((nonzero_bits (XEXP (op0, 0), mode) & ~mask) == 0
1033590075Sobrien	      && (nonzero_bits (XEXP (op1, 0), mode) & ~mask) == 0)
1033618334Speter	    op0 = XEXP (op0, 0), op1 = XEXP (op1, 0);
1033718334Speter	  else
1033818334Speter	    break;
1033918334Speter	}
1034018334Speter
1034118334Speter      /* If both operands are AND's of a paradoxical SUBREG by constant, the
1034218334Speter	 SUBREGs are of the same mode, and, in both cases, the AND would
1034318334Speter	 be redundant if the comparison was done in the narrower mode,
1034418334Speter	 do the comparison in the narrower mode (e.g., we are AND'ing with 1
1034518334Speter	 and the operand's possibly nonzero bits are 0xffffff01; in that case
1034618334Speter	 if we only care about QImode, we don't need the AND).  This case
1034718334Speter	 occurs if the output mode of an scc insn is not SImode and
1034818334Speter	 STORE_FLAG_VALUE == 1 (e.g., the 386).
1034918334Speter
1035018334Speter	 Similarly, check for a case where the AND's are ZERO_EXTEND
1035118334Speter	 operations from some narrower mode even though a SUBREG is not
1035218334Speter	 present.  */
1035318334Speter
1035490075Sobrien      else if (GET_CODE (op0) == AND && GET_CODE (op1) == AND
1035590075Sobrien	       && GET_CODE (XEXP (op0, 1)) == CONST_INT
1035690075Sobrien	       && GET_CODE (XEXP (op1, 1)) == CONST_INT)
1035718334Speter	{
1035818334Speter	  rtx inner_op0 = XEXP (op0, 0);
1035918334Speter	  rtx inner_op1 = XEXP (op1, 0);
1036018334Speter	  HOST_WIDE_INT c0 = INTVAL (XEXP (op0, 1));
1036118334Speter	  HOST_WIDE_INT c1 = INTVAL (XEXP (op1, 1));
1036218334Speter	  int changed = 0;
1036390075Sobrien
1036418334Speter	  if (GET_CODE (inner_op0) == SUBREG && GET_CODE (inner_op1) == SUBREG
1036518334Speter	      && (GET_MODE_SIZE (GET_MODE (inner_op0))
1036618334Speter		  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner_op0))))
1036718334Speter	      && (GET_MODE (SUBREG_REG (inner_op0))
1036818334Speter		  == GET_MODE (SUBREG_REG (inner_op1)))
1036950397Sobrien	      && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (inner_op0)))
1037018334Speter		  <= HOST_BITS_PER_WIDE_INT)
1037150397Sobrien	      && (0 == ((~c0) & nonzero_bits (SUBREG_REG (inner_op0),
1037250397Sobrien					     GET_MODE (SUBREG_REG (inner_op0)))))
1037350397Sobrien	      && (0 == ((~c1) & nonzero_bits (SUBREG_REG (inner_op1),
1037450397Sobrien					     GET_MODE (SUBREG_REG (inner_op1))))))
1037518334Speter	    {
1037618334Speter	      op0 = SUBREG_REG (inner_op0);
1037718334Speter	      op1 = SUBREG_REG (inner_op1);
1037818334Speter
1037918334Speter	      /* The resulting comparison is always unsigned since we masked
1038050397Sobrien		 off the original sign bit.  */
1038118334Speter	      code = unsigned_condition (code);
1038218334Speter
1038318334Speter	      changed = 1;
1038418334Speter	    }
1038518334Speter
1038618334Speter	  else if (c0 == c1)
1038718334Speter	    for (tmode = GET_CLASS_NARROWEST_MODE
1038818334Speter		 (GET_MODE_CLASS (GET_MODE (op0)));
1038918334Speter		 tmode != GET_MODE (op0); tmode = GET_MODE_WIDER_MODE (tmode))
1039052284Sobrien	      if ((unsigned HOST_WIDE_INT) c0 == GET_MODE_MASK (tmode))
1039118334Speter		{
1039218334Speter		  op0 = gen_lowpart_for_combine (tmode, inner_op0);
1039318334Speter		  op1 = gen_lowpart_for_combine (tmode, inner_op1);
1039418334Speter		  code = unsigned_condition (code);
1039518334Speter		  changed = 1;
1039618334Speter		  break;
1039718334Speter		}
1039818334Speter
1039918334Speter	  if (! changed)
1040018334Speter	    break;
1040118334Speter	}
1040218334Speter
1040318334Speter      /* If both operands are NOT, we can strip off the outer operation
1040418334Speter	 and adjust the comparison code for swapped operands; similarly for
1040518334Speter	 NEG, except that this must be an equality comparison.  */
1040618334Speter      else if ((GET_CODE (op0) == NOT && GET_CODE (op1) == NOT)
1040718334Speter	       || (GET_CODE (op0) == NEG && GET_CODE (op1) == NEG
1040818334Speter		   && (code == EQ || code == NE)))
1040918334Speter	op0 = XEXP (op0, 0), op1 = XEXP (op1, 0), code = swap_condition (code);
1041018334Speter
1041118334Speter      else
1041218334Speter	break;
1041318334Speter    }
1041490075Sobrien
1041518334Speter  /* If the first operand is a constant, swap the operands and adjust the
1041650397Sobrien     comparison code appropriately, but don't do this if the second operand
1041750397Sobrien     is already a constant integer.  */
1041890075Sobrien  if (swap_commutative_operands_p (op0, op1))
1041918334Speter    {
1042018334Speter      tem = op0, op0 = op1, op1 = tem;
1042118334Speter      code = swap_condition (code);
1042218334Speter    }
1042318334Speter
1042418334Speter  /* We now enter a loop during which we will try to simplify the comparison.
1042518334Speter     For the most part, we only are concerned with comparisons with zero,
1042618334Speter     but some things may really be comparisons with zero but not start
1042718334Speter     out looking that way.  */
1042818334Speter
1042918334Speter  while (GET_CODE (op1) == CONST_INT)
1043018334Speter    {
1043118334Speter      enum machine_mode mode = GET_MODE (op0);
1043290075Sobrien      unsigned int mode_width = GET_MODE_BITSIZE (mode);
1043318334Speter      unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
1043418334Speter      int equality_comparison_p;
1043518334Speter      int sign_bit_comparison_p;
1043618334Speter      int unsigned_comparison_p;
1043718334Speter      HOST_WIDE_INT const_op;
1043818334Speter
1043918334Speter      /* We only want to handle integral modes.  This catches VOIDmode,
1044018334Speter	 CCmode, and the floating-point modes.  An exception is that we
1044118334Speter	 can handle VOIDmode if OP0 is a COMPARE or a comparison
1044218334Speter	 operation.  */
1044318334Speter
1044418334Speter      if (GET_MODE_CLASS (mode) != MODE_INT
1044518334Speter	  && ! (mode == VOIDmode
1044618334Speter		&& (GET_CODE (op0) == COMPARE
1044718334Speter		    || GET_RTX_CLASS (GET_CODE (op0)) == '<')))
1044818334Speter	break;
1044918334Speter
1045018334Speter      /* Get the constant we are comparing against and turn off all bits
1045118334Speter	 not on in our mode.  */
10452117395Skan      const_op = INTVAL (op1);
10453117395Skan      if (mode != VOIDmode)
10454117395Skan	const_op = trunc_int_for_mode (const_op, mode);
1045590075Sobrien      op1 = GEN_INT (const_op);
1045618334Speter
1045718334Speter      /* If we are comparing against a constant power of two and the value
1045818334Speter	 being compared can only have that single bit nonzero (e.g., it was
1045918334Speter	 `and'ed with that bit), we can replace this with a comparison
1046018334Speter	 with zero.  */
1046118334Speter      if (const_op
1046218334Speter	  && (code == EQ || code == NE || code == GE || code == GEU
1046318334Speter	      || code == LT || code == LTU)
1046418334Speter	  && mode_width <= HOST_BITS_PER_WIDE_INT
1046518334Speter	  && exact_log2 (const_op) >= 0
1046652284Sobrien	  && nonzero_bits (op0, mode) == (unsigned HOST_WIDE_INT) const_op)
1046718334Speter	{
1046818334Speter	  code = (code == EQ || code == GE || code == GEU ? NE : EQ);
1046918334Speter	  op1 = const0_rtx, const_op = 0;
1047018334Speter	}
1047118334Speter
1047218334Speter      /* Similarly, if we are comparing a value known to be either -1 or
1047318334Speter	 0 with -1, change it to the opposite comparison against zero.  */
1047418334Speter
1047518334Speter      if (const_op == -1
1047618334Speter	  && (code == EQ || code == NE || code == GT || code == LE
1047718334Speter	      || code == GEU || code == LTU)
1047818334Speter	  && num_sign_bit_copies (op0, mode) == mode_width)
1047918334Speter	{
1048018334Speter	  code = (code == EQ || code == LE || code == GEU ? NE : EQ);
1048118334Speter	  op1 = const0_rtx, const_op = 0;
1048218334Speter	}
1048318334Speter
1048418334Speter      /* Do some canonicalizations based on the comparison code.  We prefer
1048590075Sobrien	 comparisons against zero and then prefer equality comparisons.
1048618334Speter	 If we can reduce the size of a constant, we will do that too.  */
1048718334Speter
1048818334Speter      switch (code)
1048918334Speter	{
1049018334Speter	case LT:
1049118334Speter	  /* < C is equivalent to <= (C - 1) */
1049218334Speter	  if (const_op > 0)
1049318334Speter	    {
1049418334Speter	      const_op -= 1;
1049518334Speter	      op1 = GEN_INT (const_op);
1049618334Speter	      code = LE;
1049718334Speter	      /* ... fall through to LE case below.  */
1049818334Speter	    }
1049918334Speter	  else
1050018334Speter	    break;
1050118334Speter
1050218334Speter	case LE:
1050318334Speter	  /* <= C is equivalent to < (C + 1); we do this for C < 0  */
1050418334Speter	  if (const_op < 0)
1050518334Speter	    {
1050618334Speter	      const_op += 1;
1050718334Speter	      op1 = GEN_INT (const_op);
1050818334Speter	      code = LT;
1050918334Speter	    }
1051018334Speter
1051118334Speter	  /* If we are doing a <= 0 comparison on a value known to have
1051218334Speter	     a zero sign bit, we can replace this with == 0.  */
1051318334Speter	  else if (const_op == 0
1051418334Speter		   && mode_width <= HOST_BITS_PER_WIDE_INT
1051518334Speter		   && (nonzero_bits (op0, mode)
1051618334Speter		       & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0)
1051718334Speter	    code = EQ;
1051818334Speter	  break;
1051918334Speter
1052018334Speter	case GE:
1052150397Sobrien	  /* >= C is equivalent to > (C - 1).  */
1052218334Speter	  if (const_op > 0)
1052318334Speter	    {
1052418334Speter	      const_op -= 1;
1052518334Speter	      op1 = GEN_INT (const_op);
1052618334Speter	      code = GT;
1052718334Speter	      /* ... fall through to GT below.  */
1052818334Speter	    }
1052918334Speter	  else
1053018334Speter	    break;
1053118334Speter
1053218334Speter	case GT:
1053390075Sobrien	  /* > C is equivalent to >= (C + 1); we do this for C < 0.  */
1053418334Speter	  if (const_op < 0)
1053518334Speter	    {
1053618334Speter	      const_op += 1;
1053718334Speter	      op1 = GEN_INT (const_op);
1053818334Speter	      code = GE;
1053918334Speter	    }
1054018334Speter
1054118334Speter	  /* If we are doing a > 0 comparison on a value known to have
1054218334Speter	     a zero sign bit, we can replace this with != 0.  */
1054318334Speter	  else if (const_op == 0
1054418334Speter		   && mode_width <= HOST_BITS_PER_WIDE_INT
1054518334Speter		   && (nonzero_bits (op0, mode)
1054618334Speter		       & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0)
1054718334Speter	    code = NE;
1054818334Speter	  break;
1054918334Speter
1055018334Speter	case LTU:
1055118334Speter	  /* < C is equivalent to <= (C - 1).  */
1055218334Speter	  if (const_op > 0)
1055318334Speter	    {
1055418334Speter	      const_op -= 1;
1055518334Speter	      op1 = GEN_INT (const_op);
1055618334Speter	      code = LEU;
1055750397Sobrien	      /* ... fall through ...  */
1055818334Speter	    }
1055918334Speter
1056018334Speter	  /* (unsigned) < 0x80000000 is equivalent to >= 0.  */
1056150397Sobrien	  else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
1056250397Sobrien		   && (const_op == (HOST_WIDE_INT) 1 << (mode_width - 1)))
1056318334Speter	    {
1056418334Speter	      const_op = 0, op1 = const0_rtx;
1056518334Speter	      code = GE;
1056618334Speter	      break;
1056718334Speter	    }
1056818334Speter	  else
1056918334Speter	    break;
1057018334Speter
1057118334Speter	case LEU:
1057218334Speter	  /* unsigned <= 0 is equivalent to == 0 */
1057318334Speter	  if (const_op == 0)
1057418334Speter	    code = EQ;
1057518334Speter
1057650397Sobrien	  /* (unsigned) <= 0x7fffffff is equivalent to >= 0.  */
1057750397Sobrien	  else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
1057850397Sobrien		   && (const_op == ((HOST_WIDE_INT) 1 << (mode_width - 1)) - 1))
1057918334Speter	    {
1058018334Speter	      const_op = 0, op1 = const0_rtx;
1058118334Speter	      code = GE;
1058218334Speter	    }
1058318334Speter	  break;
1058418334Speter
1058518334Speter	case GEU:
1058618334Speter	  /* >= C is equivalent to < (C - 1).  */
1058718334Speter	  if (const_op > 1)
1058818334Speter	    {
1058918334Speter	      const_op -= 1;
1059018334Speter	      op1 = GEN_INT (const_op);
1059118334Speter	      code = GTU;
1059250397Sobrien	      /* ... fall through ...  */
1059318334Speter	    }
1059418334Speter
1059518334Speter	  /* (unsigned) >= 0x80000000 is equivalent to < 0.  */
1059650397Sobrien	  else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
1059750397Sobrien		   && (const_op == (HOST_WIDE_INT) 1 << (mode_width - 1)))
1059818334Speter	    {
1059918334Speter	      const_op = 0, op1 = const0_rtx;
1060018334Speter	      code = LT;
1060118334Speter	      break;
1060218334Speter	    }
1060318334Speter	  else
1060418334Speter	    break;
1060518334Speter
1060618334Speter	case GTU:
1060718334Speter	  /* unsigned > 0 is equivalent to != 0 */
1060818334Speter	  if (const_op == 0)
1060918334Speter	    code = NE;
1061018334Speter
1061118334Speter	  /* (unsigned) > 0x7fffffff is equivalent to < 0.  */
1061250397Sobrien	  else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
1061350397Sobrien		    && (const_op == ((HOST_WIDE_INT) 1 << (mode_width - 1)) - 1))
1061418334Speter	    {
1061518334Speter	      const_op = 0, op1 = const0_rtx;
1061618334Speter	      code = LT;
1061718334Speter	    }
1061818334Speter	  break;
1061950397Sobrien
1062050397Sobrien	default:
1062150397Sobrien	  break;
1062218334Speter	}
1062318334Speter
1062418334Speter      /* Compute some predicates to simplify code below.  */
1062518334Speter
1062618334Speter      equality_comparison_p = (code == EQ || code == NE);
1062718334Speter      sign_bit_comparison_p = ((code == LT || code == GE) && const_op == 0);
1062818334Speter      unsigned_comparison_p = (code == LTU || code == LEU || code == GTU
1062990075Sobrien			       || code == GEU);
1063018334Speter
1063118334Speter      /* If this is a sign bit comparison and we can do arithmetic in
1063218334Speter	 MODE, say that we will only be needing the sign bit of OP0.  */
1063318334Speter      if (sign_bit_comparison_p
1063418334Speter	  && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
1063518334Speter	op0 = force_to_mode (op0, mode,
1063618334Speter			     ((HOST_WIDE_INT) 1
1063718334Speter			      << (GET_MODE_BITSIZE (mode) - 1)),
1063818334Speter			     NULL_RTX, 0);
1063918334Speter
1064018334Speter      /* Now try cases based on the opcode of OP0.  If none of the cases
1064118334Speter	 does a "continue", we exit this loop immediately after the
1064218334Speter	 switch.  */
1064318334Speter
1064418334Speter      switch (GET_CODE (op0))
1064518334Speter	{
1064618334Speter	case ZERO_EXTRACT:
1064718334Speter	  /* If we are extracting a single bit from a variable position in
1064818334Speter	     a constant that has only a single bit set and are comparing it
1064990075Sobrien	     with zero, we can convert this into an equality comparison
1065050397Sobrien	     between the position and the location of the single bit.  */
1065118334Speter
1065218334Speter	  if (GET_CODE (XEXP (op0, 0)) == CONST_INT
1065318334Speter	      && XEXP (op0, 1) == const1_rtx
1065418334Speter	      && equality_comparison_p && const_op == 0
1065550397Sobrien	      && (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0)
1065618334Speter	    {
1065750397Sobrien	      if (BITS_BIG_ENDIAN)
1065852284Sobrien		{
1065990075Sobrien		  enum machine_mode new_mode
1066090075Sobrien		    = mode_for_extraction (EP_extzv, 1);
1066190075Sobrien		  if (new_mode == MAX_MACHINE_MODE)
1066290075Sobrien		    i = BITS_PER_WORD - 1 - i;
1066390075Sobrien		  else
1066490075Sobrien		    {
1066590075Sobrien		      mode = new_mode;
1066690075Sobrien		      i = (GET_MODE_BITSIZE (mode) - 1 - i);
1066790075Sobrien		    }
1066852284Sobrien		}
1066918334Speter
1067018334Speter	      op0 = XEXP (op0, 2);
1067118334Speter	      op1 = GEN_INT (i);
1067218334Speter	      const_op = i;
1067318334Speter
1067418334Speter	      /* Result is nonzero iff shift count is equal to I.  */
1067518334Speter	      code = reverse_condition (code);
1067618334Speter	      continue;
1067718334Speter	    }
1067818334Speter
1067950397Sobrien	  /* ... fall through ...  */
1068018334Speter
1068118334Speter	case SIGN_EXTRACT:
1068218334Speter	  tem = expand_compound_operation (op0);
1068318334Speter	  if (tem != op0)
1068418334Speter	    {
1068518334Speter	      op0 = tem;
1068618334Speter	      continue;
1068718334Speter	    }
1068818334Speter	  break;
1068918334Speter
1069018334Speter	case NOT:
1069118334Speter	  /* If testing for equality, we can take the NOT of the constant.  */
1069218334Speter	  if (equality_comparison_p
1069318334Speter	      && (tem = simplify_unary_operation (NOT, mode, op1, mode)) != 0)
1069418334Speter	    {
1069518334Speter	      op0 = XEXP (op0, 0);
1069618334Speter	      op1 = tem;
1069718334Speter	      continue;
1069818334Speter	    }
1069918334Speter
1070018334Speter	  /* If just looking at the sign bit, reverse the sense of the
1070118334Speter	     comparison.  */
1070218334Speter	  if (sign_bit_comparison_p)
1070318334Speter	    {
1070418334Speter	      op0 = XEXP (op0, 0);
1070518334Speter	      code = (code == GE ? LT : GE);
1070618334Speter	      continue;
1070718334Speter	    }
1070818334Speter	  break;
1070918334Speter
1071018334Speter	case NEG:
1071118334Speter	  /* If testing for equality, we can take the NEG of the constant.  */
1071218334Speter	  if (equality_comparison_p
1071318334Speter	      && (tem = simplify_unary_operation (NEG, mode, op1, mode)) != 0)
1071418334Speter	    {
1071518334Speter	      op0 = XEXP (op0, 0);
1071618334Speter	      op1 = tem;
1071718334Speter	      continue;
1071818334Speter	    }
1071918334Speter
1072018334Speter	  /* The remaining cases only apply to comparisons with zero.  */
1072118334Speter	  if (const_op != 0)
1072218334Speter	    break;
1072318334Speter
1072418334Speter	  /* When X is ABS or is known positive,
1072518334Speter	     (neg X) is < 0 if and only if X != 0.  */
1072618334Speter
1072718334Speter	  if (sign_bit_comparison_p
1072818334Speter	      && (GET_CODE (XEXP (op0, 0)) == ABS
1072918334Speter		  || (mode_width <= HOST_BITS_PER_WIDE_INT
1073018334Speter		      && (nonzero_bits (XEXP (op0, 0), mode)
1073118334Speter			  & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0)))
1073218334Speter	    {
1073318334Speter	      op0 = XEXP (op0, 0);
1073418334Speter	      code = (code == LT ? NE : EQ);
1073518334Speter	      continue;
1073618334Speter	    }
1073718334Speter
1073818334Speter	  /* If we have NEG of something whose two high-order bits are the
1073950397Sobrien	     same, we know that "(-a) < 0" is equivalent to "a > 0".  */
1074018334Speter	  if (num_sign_bit_copies (op0, mode) >= 2)
1074118334Speter	    {
1074218334Speter	      op0 = XEXP (op0, 0);
1074318334Speter	      code = swap_condition (code);
1074418334Speter	      continue;
1074518334Speter	    }
1074618334Speter	  break;
1074718334Speter
1074818334Speter	case ROTATE:
1074918334Speter	  /* If we are testing equality and our count is a constant, we
1075018334Speter	     can perform the inverse operation on our RHS.  */
1075118334Speter	  if (equality_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT
1075218334Speter	      && (tem = simplify_binary_operation (ROTATERT, mode,
1075318334Speter						   op1, XEXP (op0, 1))) != 0)
1075418334Speter	    {
1075518334Speter	      op0 = XEXP (op0, 0);
1075618334Speter	      op1 = tem;
1075718334Speter	      continue;
1075818334Speter	    }
1075918334Speter
1076018334Speter	  /* If we are doing a < 0 or >= 0 comparison, it means we are testing
1076118334Speter	     a particular bit.  Convert it to an AND of a constant of that
1076218334Speter	     bit.  This will be converted into a ZERO_EXTRACT.  */
1076318334Speter	  if (const_op == 0 && sign_bit_comparison_p
1076418334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1076518334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT)
1076618334Speter	    {
1076718334Speter	      op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
1076818334Speter					    ((HOST_WIDE_INT) 1
1076918334Speter					     << (mode_width - 1
1077018334Speter						 - INTVAL (XEXP (op0, 1)))));
1077118334Speter	      code = (code == LT ? NE : EQ);
1077218334Speter	      continue;
1077318334Speter	    }
1077418334Speter
1077590075Sobrien	  /* Fall through.  */
1077618334Speter
1077718334Speter	case ABS:
1077818334Speter	  /* ABS is ignorable inside an equality comparison with zero.  */
1077918334Speter	  if (const_op == 0 && equality_comparison_p)
1078018334Speter	    {
1078118334Speter	      op0 = XEXP (op0, 0);
1078218334Speter	      continue;
1078318334Speter	    }
1078418334Speter	  break;
1078518334Speter
1078618334Speter	case SIGN_EXTEND:
1078718334Speter	  /* Can simplify (compare (zero/sign_extend FOO) CONST)
1078890075Sobrien	     to (compare FOO CONST) if CONST fits in FOO's mode and we
1078918334Speter	     are either testing inequality or have an unsigned comparison
1079018334Speter	     with ZERO_EXTEND or a signed comparison with SIGN_EXTEND.  */
1079118334Speter	  if (! unsigned_comparison_p
1079218334Speter	      && (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0)))
1079318334Speter		  <= HOST_BITS_PER_WIDE_INT)
1079418334Speter	      && ((unsigned HOST_WIDE_INT) const_op
1079552284Sobrien		  < (((unsigned HOST_WIDE_INT) 1
1079618334Speter		      << (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))) - 1)))))
1079718334Speter	    {
1079818334Speter	      op0 = XEXP (op0, 0);
1079918334Speter	      continue;
1080018334Speter	    }
1080118334Speter	  break;
1080218334Speter
1080318334Speter	case SUBREG:
1080418334Speter	  /* Check for the case where we are comparing A - C1 with C2,
1080518334Speter	     both constants are smaller than 1/2 the maximum positive
1080618334Speter	     value in MODE, and the comparison is equality or unsigned.
1080718334Speter	     In that case, if A is either zero-extended to MODE or has
1080818334Speter	     sufficient sign bits so that the high-order bit in MODE
1080918334Speter	     is a copy of the sign in the inner mode, we can prove that it is
1081018334Speter	     safe to do the operation in the wider mode.  This simplifies
1081118334Speter	     many range checks.  */
1081218334Speter
1081318334Speter	  if (mode_width <= HOST_BITS_PER_WIDE_INT
1081418334Speter	      && subreg_lowpart_p (op0)
1081518334Speter	      && GET_CODE (SUBREG_REG (op0)) == PLUS
1081618334Speter	      && GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT
1081718334Speter	      && INTVAL (XEXP (SUBREG_REG (op0), 1)) < 0
1081890075Sobrien	      && (-INTVAL (XEXP (SUBREG_REG (op0), 1))
1081990075Sobrien		  < (HOST_WIDE_INT) (GET_MODE_MASK (mode) / 2))
1082018334Speter	      && (unsigned HOST_WIDE_INT) const_op < GET_MODE_MASK (mode) / 2
1082118334Speter	      && (0 == (nonzero_bits (XEXP (SUBREG_REG (op0), 0),
1082218334Speter				      GET_MODE (SUBREG_REG (op0)))
1082390075Sobrien			& ~GET_MODE_MASK (mode))
1082418334Speter		  || (num_sign_bit_copies (XEXP (SUBREG_REG (op0), 0),
1082518334Speter					   GET_MODE (SUBREG_REG (op0)))
10826117395Skan		      > (unsigned int)
10827117395Skan			(GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
1082818334Speter			 - GET_MODE_BITSIZE (mode)))))
1082918334Speter	    {
1083018334Speter	      op0 = SUBREG_REG (op0);
1083118334Speter	      continue;
1083218334Speter	    }
1083318334Speter
1083418334Speter	  /* If the inner mode is narrower and we are extracting the low part,
1083518334Speter	     we can treat the SUBREG as if it were a ZERO_EXTEND.  */
1083618334Speter	  if (subreg_lowpart_p (op0)
1083718334Speter	      && GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) < mode_width)
1083818334Speter	    /* Fall through */ ;
1083918334Speter	  else
1084018334Speter	    break;
1084118334Speter
1084250397Sobrien	  /* ... fall through ...  */
1084318334Speter
1084418334Speter	case ZERO_EXTEND:
1084518334Speter	  if ((unsigned_comparison_p || equality_comparison_p)
1084618334Speter	      && (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0)))
1084718334Speter		  <= HOST_BITS_PER_WIDE_INT)
1084818334Speter	      && ((unsigned HOST_WIDE_INT) const_op
1084918334Speter		  < GET_MODE_MASK (GET_MODE (XEXP (op0, 0)))))
1085018334Speter	    {
1085118334Speter	      op0 = XEXP (op0, 0);
1085218334Speter	      continue;
1085318334Speter	    }
1085418334Speter	  break;
1085518334Speter
1085618334Speter	case PLUS:
1085718334Speter	  /* (eq (plus X A) B) -> (eq X (minus B A)).  We can only do
1085818334Speter	     this for equality comparisons due to pathological cases involving
1085918334Speter	     overflows.  */
1086018334Speter	  if (equality_comparison_p
1086118334Speter	      && 0 != (tem = simplify_binary_operation (MINUS, mode,
1086218334Speter							op1, XEXP (op0, 1))))
1086318334Speter	    {
1086418334Speter	      op0 = XEXP (op0, 0);
1086518334Speter	      op1 = tem;
1086618334Speter	      continue;
1086718334Speter	    }
1086818334Speter
1086918334Speter	  /* (plus (abs X) (const_int -1)) is < 0 if and only if X == 0.  */
1087018334Speter	  if (const_op == 0 && XEXP (op0, 1) == constm1_rtx
1087118334Speter	      && GET_CODE (XEXP (op0, 0)) == ABS && sign_bit_comparison_p)
1087218334Speter	    {
1087318334Speter	      op0 = XEXP (XEXP (op0, 0), 0);
1087418334Speter	      code = (code == LT ? EQ : NE);
1087518334Speter	      continue;
1087618334Speter	    }
1087718334Speter	  break;
1087818334Speter
1087918334Speter	case MINUS:
1088090075Sobrien	  /* We used to optimize signed comparisons against zero, but that
1088190075Sobrien	     was incorrect.  Unsigned comparisons against zero (GTU, LEU)
1088290075Sobrien	     arrive here as equality comparisons, or (GEU, LTU) are
1088390075Sobrien	     optimized away.  No need to special-case them.  */
1088490075Sobrien
1088518334Speter	  /* (eq (minus A B) C) -> (eq A (plus B C)) or
1088618334Speter	     (eq B (minus A C)), whichever simplifies.  We can only do
1088718334Speter	     this for equality comparisons due to pathological cases involving
1088818334Speter	     overflows.  */
1088918334Speter	  if (equality_comparison_p
1089018334Speter	      && 0 != (tem = simplify_binary_operation (PLUS, mode,
1089118334Speter							XEXP (op0, 1), op1)))
1089218334Speter	    {
1089318334Speter	      op0 = XEXP (op0, 0);
1089418334Speter	      op1 = tem;
1089518334Speter	      continue;
1089618334Speter	    }
1089718334Speter
1089818334Speter	  if (equality_comparison_p
1089918334Speter	      && 0 != (tem = simplify_binary_operation (MINUS, mode,
1090018334Speter							XEXP (op0, 0), op1)))
1090118334Speter	    {
1090218334Speter	      op0 = XEXP (op0, 1);
1090318334Speter	      op1 = tem;
1090418334Speter	      continue;
1090518334Speter	    }
1090618334Speter
1090718334Speter	  /* The sign bit of (minus (ashiftrt X C) X), where C is the number
1090818334Speter	     of bits in X minus 1, is one iff X > 0.  */
1090918334Speter	  if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 0)) == ASHIFTRT
1091018334Speter	      && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
10911117395Skan	      && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (op0, 0), 1))
10912117395Skan		 == mode_width - 1
1091318334Speter	      && rtx_equal_p (XEXP (XEXP (op0, 0), 0), XEXP (op0, 1)))
1091418334Speter	    {
1091518334Speter	      op0 = XEXP (op0, 1);
1091618334Speter	      code = (code == GE ? LE : GT);
1091718334Speter	      continue;
1091818334Speter	    }
1091918334Speter	  break;
1092018334Speter
1092118334Speter	case XOR:
1092218334Speter	  /* (eq (xor A B) C) -> (eq A (xor B C)).  This is a simplification
1092318334Speter	     if C is zero or B is a constant.  */
1092418334Speter	  if (equality_comparison_p
1092518334Speter	      && 0 != (tem = simplify_binary_operation (XOR, mode,
1092618334Speter							XEXP (op0, 1), op1)))
1092718334Speter	    {
1092818334Speter	      op0 = XEXP (op0, 0);
1092918334Speter	      op1 = tem;
1093018334Speter	      continue;
1093118334Speter	    }
1093218334Speter	  break;
1093318334Speter
1093418334Speter	case EQ:  case NE:
1093590075Sobrien	case UNEQ:  case LTGT:
1093690075Sobrien	case LT:  case LTU:  case UNLT:  case LE:  case LEU:  case UNLE:
1093790075Sobrien	case GT:  case GTU:  case UNGT:  case GE:  case GEU:  case UNGE:
1093890075Sobrien        case UNORDERED: case ORDERED:
1093918334Speter	  /* We can't do anything if OP0 is a condition code value, rather
1094018334Speter	     than an actual data value.  */
1094118334Speter	  if (const_op != 0
1094218334Speter#ifdef HAVE_cc0
1094318334Speter	      || XEXP (op0, 0) == cc0_rtx
1094418334Speter#endif
1094518334Speter	      || GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC)
1094618334Speter	    break;
1094718334Speter
1094818334Speter	  /* Get the two operands being compared.  */
1094918334Speter	  if (GET_CODE (XEXP (op0, 0)) == COMPARE)
1095018334Speter	    tem = XEXP (XEXP (op0, 0), 0), tem1 = XEXP (XEXP (op0, 0), 1);
1095118334Speter	  else
1095218334Speter	    tem = XEXP (op0, 0), tem1 = XEXP (op0, 1);
1095318334Speter
1095418334Speter	  /* Check for the cases where we simply want the result of the
1095518334Speter	     earlier test or the opposite of that result.  */
1095690075Sobrien	  if (code == NE || code == EQ
1095718334Speter	      || (GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT
1095818334Speter		  && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
1095918334Speter		  && (STORE_FLAG_VALUE
1096018334Speter		      & (((HOST_WIDE_INT) 1
1096118334Speter			  << (GET_MODE_BITSIZE (GET_MODE (op0)) - 1))))
1096290075Sobrien		  && (code == LT || code == GE)))
1096318334Speter	    {
1096490075Sobrien	      enum rtx_code new_code;
1096590075Sobrien	      if (code == LT || code == NE)
1096690075Sobrien		new_code = GET_CODE (op0);
1096790075Sobrien	      else
1096890075Sobrien		new_code = combine_reversed_comparison_code (op0);
1096990075Sobrien
1097090075Sobrien	      if (new_code != UNKNOWN)
1097190075Sobrien		{
1097290075Sobrien		  code = new_code;
1097390075Sobrien		  op0 = tem;
1097490075Sobrien		  op1 = tem1;
1097590075Sobrien		  continue;
1097690075Sobrien		}
1097718334Speter	    }
1097818334Speter	  break;
1097918334Speter
1098018334Speter	case IOR:
10981117395Skan	  /* The sign bit of (ior (plus X (const_int -1)) X) is nonzero
1098218334Speter	     iff X <= 0.  */
1098318334Speter	  if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 0)) == PLUS
1098418334Speter	      && XEXP (XEXP (op0, 0), 1) == constm1_rtx
1098518334Speter	      && rtx_equal_p (XEXP (XEXP (op0, 0), 0), XEXP (op0, 1)))
1098618334Speter	    {
1098718334Speter	      op0 = XEXP (op0, 1);
1098818334Speter	      code = (code == GE ? GT : LE);
1098918334Speter	      continue;
1099018334Speter	    }
1099118334Speter	  break;
1099218334Speter
1099318334Speter	case AND:
1099418334Speter	  /* Convert (and (xshift 1 X) Y) to (and (lshiftrt Y X) 1).  This
1099518334Speter	     will be converted to a ZERO_EXTRACT later.  */
1099618334Speter	  if (const_op == 0 && equality_comparison_p
1099718334Speter	      && GET_CODE (XEXP (op0, 0)) == ASHIFT
1099818334Speter	      && XEXP (XEXP (op0, 0), 0) == const1_rtx)
1099918334Speter	    {
1100018334Speter	      op0 = simplify_and_const_int
1100190075Sobrien		(op0, mode, gen_rtx_LSHIFTRT (mode,
1100290075Sobrien					      XEXP (op0, 1),
1100390075Sobrien					      XEXP (XEXP (op0, 0), 1)),
1100418334Speter		 (HOST_WIDE_INT) 1);
1100518334Speter	      continue;
1100618334Speter	    }
1100718334Speter
1100818334Speter	  /* If we are comparing (and (lshiftrt X C1) C2) for equality with
1100918334Speter	     zero and X is a comparison and C1 and C2 describe only bits set
1101018334Speter	     in STORE_FLAG_VALUE, we can compare with X.  */
1101118334Speter	  if (const_op == 0 && equality_comparison_p
1101218334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT
1101318334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1101418334Speter	      && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
1101518334Speter	      && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
1101618334Speter	      && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
1101718334Speter	      && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT)
1101818334Speter	    {
1101918334Speter	      mask = ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode))
1102018334Speter		      << INTVAL (XEXP (XEXP (op0, 0), 1)));
1102190075Sobrien	      if ((~STORE_FLAG_VALUE & mask) == 0
1102218334Speter		  && (GET_RTX_CLASS (GET_CODE (XEXP (XEXP (op0, 0), 0))) == '<'
1102318334Speter		      || ((tem = get_last_value (XEXP (XEXP (op0, 0), 0))) != 0
1102418334Speter			  && GET_RTX_CLASS (GET_CODE (tem)) == '<')))
1102518334Speter		{
1102618334Speter		  op0 = XEXP (XEXP (op0, 0), 0);
1102718334Speter		  continue;
1102818334Speter		}
1102918334Speter	    }
1103018334Speter
1103118334Speter	  /* If we are doing an equality comparison of an AND of a bit equal
1103218334Speter	     to the sign bit, replace this with a LT or GE comparison of
1103318334Speter	     the underlying value.  */
1103418334Speter	  if (equality_comparison_p
1103518334Speter	      && const_op == 0
1103618334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1103718334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT
1103818334Speter	      && ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode))
1103952284Sobrien		  == (unsigned HOST_WIDE_INT) 1 << (mode_width - 1)))
1104018334Speter	    {
1104118334Speter	      op0 = XEXP (op0, 0);
1104218334Speter	      code = (code == EQ ? GE : LT);
1104318334Speter	      continue;
1104418334Speter	    }
1104518334Speter
1104618334Speter	  /* If this AND operation is really a ZERO_EXTEND from a narrower
1104718334Speter	     mode, the constant fits within that mode, and this is either an
1104818334Speter	     equality or unsigned comparison, try to do this comparison in
1104918334Speter	     the narrower mode.  */
1105018334Speter	  if ((equality_comparison_p || unsigned_comparison_p)
1105118334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1105218334Speter	      && (i = exact_log2 ((INTVAL (XEXP (op0, 1))
1105318334Speter				   & GET_MODE_MASK (mode))
1105418334Speter				  + 1)) >= 0
1105518334Speter	      && const_op >> i == 0
1105618334Speter	      && (tmode = mode_for_size (i, MODE_INT, 1)) != BLKmode)
1105718334Speter	    {
1105818334Speter	      op0 = gen_lowpart_for_combine (tmode, XEXP (op0, 0));
1105918334Speter	      continue;
1106018334Speter	    }
1106150397Sobrien
1106250397Sobrien	  /* If this is (and:M1 (subreg:M2 X 0) (const_int C1)) where C1 fits
1106350397Sobrien	     in both M1 and M2 and the SUBREG is either paradoxical or
1106450397Sobrien	     represents the low part, permute the SUBREG and the AND and
1106550397Sobrien	     try again.  */
1106650397Sobrien	  if (GET_CODE (XEXP (op0, 0)) == SUBREG
11067117395Skan	      /* Require an integral mode, to avoid creating something like
11068117395Skan		 (AND:SF ...).  */
11069117395Skan	      && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (XEXP (op0, 0))))
1107090075Sobrien	      && (0
1107150397Sobrien#ifdef WORD_REGISTER_OPERATIONS
1107290075Sobrien		  || ((mode_width
1107390075Sobrien		       > (GET_MODE_BITSIZE
1107490075Sobrien			   (GET_MODE (SUBREG_REG (XEXP (op0, 0))))))
1107590075Sobrien		      && mode_width <= BITS_PER_WORD)
1107650397Sobrien#endif
1107790075Sobrien		  || ((mode_width
1107890075Sobrien		       <= (GET_MODE_BITSIZE
1107990075Sobrien			   (GET_MODE (SUBREG_REG (XEXP (op0, 0))))))
1108090075Sobrien		      && subreg_lowpart_p (XEXP (op0, 0))))
1108150397Sobrien#ifndef WORD_REGISTER_OPERATIONS
1108250397Sobrien	      /* It is unsafe to commute the AND into the SUBREG if the SUBREG
1108350397Sobrien		 is paradoxical and WORD_REGISTER_OPERATIONS is not defined.
1108450397Sobrien		 As originally written the upper bits have a defined value
1108550397Sobrien		 due to the AND operation.  However, if we commute the AND
1108650397Sobrien		 inside the SUBREG then they no longer have defined values
1108750397Sobrien		 and the meaning of the code has been changed.  */
1108850397Sobrien	      && (GET_MODE_SIZE (GET_MODE (XEXP (op0, 0)))
1108950397Sobrien		  <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0)))))
1109050397Sobrien#endif
1109150397Sobrien	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1109250397Sobrien	      && mode_width <= HOST_BITS_PER_WIDE_INT
1109350397Sobrien	      && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0))))
1109450397Sobrien		  <= HOST_BITS_PER_WIDE_INT)
1109590075Sobrien	      && (INTVAL (XEXP (op0, 1)) & ~mask) == 0
1109690075Sobrien	      && 0 == (~GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0))))
1109750397Sobrien		       & INTVAL (XEXP (op0, 1)))
1109852284Sobrien	      && (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1)) != mask
1109952284Sobrien	      && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1))
1110050397Sobrien		  != GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0))))))
1110190075Sobrien
1110250397Sobrien	    {
1110350397Sobrien	      op0
1110450397Sobrien		= gen_lowpart_for_combine
1110550397Sobrien		  (mode,
1110650397Sobrien		   gen_binary (AND, GET_MODE (SUBREG_REG (XEXP (op0, 0))),
1110750397Sobrien			       SUBREG_REG (XEXP (op0, 0)), XEXP (op0, 1)));
1110850397Sobrien	      continue;
1110950397Sobrien	    }
1111050397Sobrien
1111190075Sobrien	  /* Convert (ne (and (lshiftrt (not X)) 1) 0) to
1111290075Sobrien	     (eq (and (lshiftrt X) 1) 0).  */
1111390075Sobrien	  if (const_op == 0 && equality_comparison_p
1111490075Sobrien	      && XEXP (op0, 1) == const1_rtx
1111590075Sobrien	      && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
1111690075Sobrien	      && GET_CODE (XEXP (XEXP (op0, 0), 0)) == NOT)
1111790075Sobrien	    {
1111890075Sobrien	      op0 = simplify_and_const_int
1111990075Sobrien		(op0, mode,
1112090075Sobrien		 gen_rtx_LSHIFTRT (mode, XEXP (XEXP (XEXP (op0, 0), 0), 0),
1112190075Sobrien				   XEXP (XEXP (op0, 0), 1)),
1112290075Sobrien		 (HOST_WIDE_INT) 1);
1112390075Sobrien	      code = (code == NE ? EQ : NE);
1112490075Sobrien	      continue;
1112590075Sobrien	    }
1112618334Speter	  break;
1112718334Speter
1112818334Speter	case ASHIFT:
1112918334Speter	  /* If we have (compare (ashift FOO N) (const_int C)) and
1113018334Speter	     the high order N bits of FOO (N+1 if an inequality comparison)
1113118334Speter	     are known to be zero, we can do this by comparing FOO with C
1113218334Speter	     shifted right N bits so long as the low-order N bits of C are
1113318334Speter	     zero.  */
1113418334Speter	  if (GET_CODE (XEXP (op0, 1)) == CONST_INT
1113518334Speter	      && INTVAL (XEXP (op0, 1)) >= 0
1113618334Speter	      && ((INTVAL (XEXP (op0, 1)) + ! equality_comparison_p)
1113718334Speter		  < HOST_BITS_PER_WIDE_INT)
1113818334Speter	      && ((const_op
1113918334Speter		   & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0)
1114018334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT
1114118334Speter	      && (nonzero_bits (XEXP (op0, 0), mode)
1114290075Sobrien		  & ~(mask >> (INTVAL (XEXP (op0, 1))
1114390075Sobrien			       + ! equality_comparison_p))) == 0)
1114418334Speter	    {
1114590075Sobrien	      /* We must perform a logical shift, not an arithmetic one,
1114690075Sobrien		 as we want the top N bits of C to be zero.  */
1114790075Sobrien	      unsigned HOST_WIDE_INT temp = const_op & GET_MODE_MASK (mode);
1114890075Sobrien
1114990075Sobrien	      temp >>= INTVAL (XEXP (op0, 1));
11150117395Skan	      op1 = gen_int_mode (temp, mode);
1115118334Speter	      op0 = XEXP (op0, 0);
1115218334Speter	      continue;
1115318334Speter	    }
1115418334Speter
1115518334Speter	  /* If we are doing a sign bit comparison, it means we are testing
1115618334Speter	     a particular bit.  Convert it to the appropriate AND.  */
1115718334Speter	  if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT
1115818334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT)
1115918334Speter	    {
1116018334Speter	      op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
1116118334Speter					    ((HOST_WIDE_INT) 1
1116218334Speter					     << (mode_width - 1
1116318334Speter						 - INTVAL (XEXP (op0, 1)))));
1116418334Speter	      code = (code == LT ? NE : EQ);
1116518334Speter	      continue;
1116618334Speter	    }
1116718334Speter
1116818334Speter	  /* If this an equality comparison with zero and we are shifting
1116918334Speter	     the low bit to the sign bit, we can convert this to an AND of the
1117018334Speter	     low-order bit.  */
1117118334Speter	  if (const_op == 0 && equality_comparison_p
1117218334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
11173117395Skan	      && (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1))
11174117395Skan		 == mode_width - 1)
1117518334Speter	    {
1117618334Speter	      op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
1117718334Speter					    (HOST_WIDE_INT) 1);
1117818334Speter	      continue;
1117918334Speter	    }
1118018334Speter	  break;
1118118334Speter
1118218334Speter	case ASHIFTRT:
1118318334Speter	  /* If this is an equality comparison with zero, we can do this
1118418334Speter	     as a logical shift, which might be much simpler.  */
1118518334Speter	  if (equality_comparison_p && const_op == 0
1118618334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT)
1118718334Speter	    {
1118818334Speter	      op0 = simplify_shift_const (NULL_RTX, LSHIFTRT, mode,
1118918334Speter					  XEXP (op0, 0),
1119018334Speter					  INTVAL (XEXP (op0, 1)));
1119118334Speter	      continue;
1119218334Speter	    }
1119318334Speter
1119418334Speter	  /* If OP0 is a sign extension and CODE is not an unsigned comparison,
1119518334Speter	     do the comparison in a narrower mode.  */
1119618334Speter	  if (! unsigned_comparison_p
1119718334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1119818334Speter	      && GET_CODE (XEXP (op0, 0)) == ASHIFT
1119918334Speter	      && XEXP (op0, 1) == XEXP (XEXP (op0, 0), 1)
1120018334Speter	      && (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)),
1120118334Speter					 MODE_INT, 1)) != BLKmode
1120296263Sobrien	      && (((unsigned HOST_WIDE_INT) const_op
1120396263Sobrien		   + (GET_MODE_MASK (tmode) >> 1) + 1)
1120496263Sobrien		  <= GET_MODE_MASK (tmode)))
1120518334Speter	    {
1120618334Speter	      op0 = gen_lowpart_for_combine (tmode, XEXP (XEXP (op0, 0), 0));
1120718334Speter	      continue;
1120818334Speter	    }
1120918334Speter
1121090075Sobrien	  /* Likewise if OP0 is a PLUS of a sign extension with a
1121190075Sobrien	     constant, which is usually represented with the PLUS
1121290075Sobrien	     between the shifts.  */
1121390075Sobrien	  if (! unsigned_comparison_p
1121490075Sobrien	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
1121590075Sobrien	      && GET_CODE (XEXP (op0, 0)) == PLUS
1121690075Sobrien	      && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
1121790075Sobrien	      && GET_CODE (XEXP (XEXP (op0, 0), 0)) == ASHIFT
1121890075Sobrien	      && XEXP (op0, 1) == XEXP (XEXP (XEXP (op0, 0), 0), 1)
1121990075Sobrien	      && (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)),
1122090075Sobrien					 MODE_INT, 1)) != BLKmode
1122196263Sobrien	      && (((unsigned HOST_WIDE_INT) const_op
1122296263Sobrien		   + (GET_MODE_MASK (tmode) >> 1) + 1)
1122396263Sobrien		  <= GET_MODE_MASK (tmode)))
1122490075Sobrien	    {
1122590075Sobrien	      rtx inner = XEXP (XEXP (XEXP (op0, 0), 0), 0);
1122690075Sobrien	      rtx add_const = XEXP (XEXP (op0, 0), 1);
1122790075Sobrien	      rtx new_const = gen_binary (ASHIFTRT, GET_MODE (op0), add_const,
1122890075Sobrien					  XEXP (op0, 1));
1122990075Sobrien
1123090075Sobrien	      op0 = gen_binary (PLUS, tmode,
1123190075Sobrien				gen_lowpart_for_combine (tmode, inner),
1123290075Sobrien				new_const);
1123390075Sobrien	      continue;
1123490075Sobrien	    }
1123590075Sobrien
1123650397Sobrien	  /* ... fall through ...  */
1123718334Speter	case LSHIFTRT:
1123818334Speter	  /* If we have (compare (xshiftrt FOO N) (const_int C)) and
1123918334Speter	     the low order N bits of FOO are known to be zero, we can do this
1124018334Speter	     by comparing FOO with C shifted left N bits so long as no
1124118334Speter	     overflow occurs.  */
1124218334Speter	  if (GET_CODE (XEXP (op0, 1)) == CONST_INT
1124318334Speter	      && INTVAL (XEXP (op0, 1)) >= 0
1124418334Speter	      && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT
1124518334Speter	      && mode_width <= HOST_BITS_PER_WIDE_INT
1124618334Speter	      && (nonzero_bits (XEXP (op0, 0), mode)
1124718334Speter		  & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0
1124896263Sobrien	      && (((unsigned HOST_WIDE_INT) const_op
1124996263Sobrien		   + (GET_CODE (op0) != LSHIFTRT
1125096263Sobrien		      ? ((GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1)) >> 1)
1125196263Sobrien			 + 1)
1125296263Sobrien		      : 0))
1125396263Sobrien		  <= GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1))))
1125418334Speter	    {
1125596263Sobrien	      /* If the shift was logical, then we must make the condition
1125696263Sobrien		 unsigned.  */
1125796263Sobrien	      if (GET_CODE (op0) == LSHIFTRT)
1125896263Sobrien		code = unsigned_condition (code);
1125996263Sobrien
1126018334Speter	      const_op <<= INTVAL (XEXP (op0, 1));
1126118334Speter	      op1 = GEN_INT (const_op);
1126218334Speter	      op0 = XEXP (op0, 0);
1126318334Speter	      continue;
1126418334Speter	    }
1126518334Speter
1126618334Speter	  /* If we are using this shift to extract just the sign bit, we
1126718334Speter	     can replace this with an LT or GE comparison.  */
1126818334Speter	  if (const_op == 0
1126918334Speter	      && (equality_comparison_p || sign_bit_comparison_p)
1127018334Speter	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
11271117395Skan	      && (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1))
11272117395Skan		 == mode_width - 1)
1127318334Speter	    {
1127418334Speter	      op0 = XEXP (op0, 0);
1127518334Speter	      code = (code == NE || code == GT ? LT : GE);
1127618334Speter	      continue;
1127718334Speter	    }
1127818334Speter	  break;
1127990075Sobrien
1128050397Sobrien	default:
1128150397Sobrien	  break;
1128218334Speter	}
1128318334Speter
1128418334Speter      break;
1128518334Speter    }
1128618334Speter
1128718334Speter  /* Now make any compound operations involved in this comparison.  Then,
1128850397Sobrien     check for an outmost SUBREG on OP0 that is not doing anything or is
1128996263Sobrien     paradoxical.  The latter transformation must only be performed when
1129096263Sobrien     it is known that the "extra" bits will be the same in op0 and op1 or
1129196263Sobrien     that they don't matter.  There are three cases to consider:
1129218334Speter
1129396263Sobrien     1. SUBREG_REG (op0) is a register.  In this case the bits are don't
1129496263Sobrien     care bits and we can assume they have any convenient value.  So
1129596263Sobrien     making the transformation is safe.
1129696263Sobrien
1129796263Sobrien     2. SUBREG_REG (op0) is a memory and LOAD_EXTEND_OP is not defined.
1129896263Sobrien     In this case the upper bits of op0 are undefined.  We should not make
1129996263Sobrien     the simplification in that case as we do not know the contents of
1130096263Sobrien     those bits.
1130196263Sobrien
1130296263Sobrien     3. SUBREG_REG (op0) is a memory and LOAD_EXTEND_OP is defined and not
1130396263Sobrien     NIL.  In that case we know those bits are zeros or ones.  We must
1130496263Sobrien     also be sure that they are the same as the upper bits of op1.
1130596263Sobrien
1130696263Sobrien     We can never remove a SUBREG for a non-equality comparison because
1130796263Sobrien     the sign bit is in a different place in the underlying object.  */
1130896263Sobrien
1130918334Speter  op0 = make_compound_operation (op0, op1 == const0_rtx ? COMPARE : SET);
1131018334Speter  op1 = make_compound_operation (op1, SET);
1131118334Speter
1131218334Speter  if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0)
1131396263Sobrien      /* Case 3 above, to sometimes allow (subreg (mem x)), isn't
1131496263Sobrien	 implemented.  */
1131596263Sobrien      && GET_CODE (SUBREG_REG (op0)) == REG
1131618334Speter      && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
1131790075Sobrien      && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT
1131896263Sobrien      && (code == NE || code == EQ))
1131918334Speter    {
1132096263Sobrien      if (GET_MODE_SIZE (GET_MODE (op0))
1132196263Sobrien	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))
1132296263Sobrien	{
1132396263Sobrien	  op0 = SUBREG_REG (op0);
1132496263Sobrien	  op1 = gen_lowpart_for_combine (GET_MODE (op0), op1);
1132596263Sobrien	}
1132696263Sobrien      else if ((GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
1132796263Sobrien		<= HOST_BITS_PER_WIDE_INT)
1132896263Sobrien	       && (nonzero_bits (SUBREG_REG (op0),
1132996263Sobrien				 GET_MODE (SUBREG_REG (op0)))
1133096263Sobrien		   & ~GET_MODE_MASK (GET_MODE (op0))) == 0)
1133196263Sobrien	{
1133296263Sobrien	  tem = gen_lowpart_for_combine (GET_MODE (SUBREG_REG (op0)), op1);
1133396263Sobrien
1133496263Sobrien	  if ((nonzero_bits (tem, GET_MODE (SUBREG_REG (op0)))
1133596263Sobrien	       & ~GET_MODE_MASK (GET_MODE (op0))) == 0)
1133696263Sobrien	    op0 = SUBREG_REG (op0), op1 = tem;
1133796263Sobrien	}
1133818334Speter    }
1133918334Speter
1134018334Speter  /* We now do the opposite procedure: Some machines don't have compare
1134118334Speter     insns in all modes.  If OP0's mode is an integer mode smaller than a
1134218334Speter     word and we can't do a compare in that mode, see if there is a larger
1134318334Speter     mode for which we can do the compare.  There are a number of cases in
1134418334Speter     which we can use the wider mode.  */
1134518334Speter
1134618334Speter  mode = GET_MODE (op0);
1134718334Speter  if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT
1134818334Speter      && GET_MODE_SIZE (mode) < UNITS_PER_WORD
1134990075Sobrien      && ! have_insn_for (COMPARE, mode))
1135018334Speter    for (tmode = GET_MODE_WIDER_MODE (mode);
1135118334Speter	 (tmode != VOIDmode
1135218334Speter	  && GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT);
1135318334Speter	 tmode = GET_MODE_WIDER_MODE (tmode))
1135490075Sobrien      if (have_insn_for (COMPARE, tmode))
1135518334Speter	{
1135696263Sobrien	  int zero_extended;
1135796263Sobrien
1135818334Speter	  /* If the only nonzero bits in OP0 and OP1 are those in the
1135918334Speter	     narrower mode and this is an equality or unsigned comparison,
1136018334Speter	     we can use the wider mode.  Similarly for sign-extended
1136118334Speter	     values, in which case it is true for all comparisons.  */
1136296263Sobrien	  zero_extended = ((code == EQ || code == NE
1136396263Sobrien			    || code == GEU || code == GTU
1136496263Sobrien			    || code == LEU || code == LTU)
1136596263Sobrien			   && (nonzero_bits (op0, tmode)
1136696263Sobrien			       & ~GET_MODE_MASK (mode)) == 0
1136796263Sobrien			   && ((GET_CODE (op1) == CONST_INT
1136896263Sobrien				|| (nonzero_bits (op1, tmode)
1136996263Sobrien				    & ~GET_MODE_MASK (mode)) == 0)));
1137096263Sobrien
1137196263Sobrien	  if (zero_extended
1137218334Speter	      || ((num_sign_bit_copies (op0, tmode)
11373117395Skan		   > (unsigned int) (GET_MODE_BITSIZE (tmode)
11374117395Skan				     - GET_MODE_BITSIZE (mode)))
1137518334Speter		  && (num_sign_bit_copies (op1, tmode)
11376117395Skan		      > (unsigned int) (GET_MODE_BITSIZE (tmode)
11377117395Skan					- GET_MODE_BITSIZE (mode)))))
1137818334Speter	    {
1137990075Sobrien	      /* If OP0 is an AND and we don't have an AND in MODE either,
1138090075Sobrien		 make a new AND in the proper mode.  */
1138190075Sobrien	      if (GET_CODE (op0) == AND
1138290075Sobrien		  && !have_insn_for (AND, mode))
1138390075Sobrien		op0 = gen_binary (AND, tmode,
1138490075Sobrien				  gen_lowpart_for_combine (tmode,
1138590075Sobrien							   XEXP (op0, 0)),
1138690075Sobrien				  gen_lowpart_for_combine (tmode,
1138790075Sobrien							   XEXP (op0, 1)));
1138890075Sobrien
1138918334Speter	      op0 = gen_lowpart_for_combine (tmode, op0);
1139096263Sobrien	      if (zero_extended && GET_CODE (op1) == CONST_INT)
1139196263Sobrien		op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (mode));
1139218334Speter	      op1 = gen_lowpart_for_combine (tmode, op1);
1139318334Speter	      break;
1139418334Speter	    }
1139518334Speter
1139618334Speter	  /* If this is a test for negative, we can make an explicit
1139718334Speter	     test of the sign bit.  */
1139818334Speter
1139918334Speter	  if (op1 == const0_rtx && (code == LT || code == GE)
1140018334Speter	      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
1140118334Speter	    {
1140218334Speter	      op0 = gen_binary (AND, tmode,
1140318334Speter				gen_lowpart_for_combine (tmode, op0),
1140418334Speter				GEN_INT ((HOST_WIDE_INT) 1
1140518334Speter					 << (GET_MODE_BITSIZE (mode) - 1)));
1140618334Speter	      code = (code == LT) ? NE : EQ;
1140718334Speter	      break;
1140818334Speter	    }
1140918334Speter	}
1141018334Speter
1141118334Speter#ifdef CANONICALIZE_COMPARISON
1141218334Speter  /* If this machine only supports a subset of valid comparisons, see if we
1141318334Speter     can convert an unsupported one into a supported one.  */
1141418334Speter  CANONICALIZE_COMPARISON (code, op0, op1);
1141518334Speter#endif
1141618334Speter
1141718334Speter  *pop0 = op0;
1141818334Speter  *pop1 = op1;
1141918334Speter
1142018334Speter  return code;
1142118334Speter}
1142218334Speter
1142390075Sobrien/* Like jump.c' reversed_comparison_code, but use combine infrastructure for
1142490075Sobrien   searching backward.  */
1142590075Sobrienstatic enum rtx_code
1142690075Sobriencombine_reversed_comparison_code (exp)
1142790075Sobrien     rtx exp;
1142818334Speter{
1142990075Sobrien  enum rtx_code code1 = reversed_comparison_code (exp, NULL);
1143090075Sobrien  rtx x;
1143118334Speter
1143290075Sobrien  if (code1 != UNKNOWN
1143390075Sobrien      || GET_MODE_CLASS (GET_MODE (XEXP (exp, 0))) != MODE_CC)
1143490075Sobrien    return code1;
1143590075Sobrien  /* Otherwise try and find where the condition codes were last set and
1143690075Sobrien     use that.  */
1143790075Sobrien  x = get_last_value (XEXP (exp, 0));
1143890075Sobrien  if (!x || GET_CODE (x) != COMPARE)
1143990075Sobrien    return UNKNOWN;
1144090075Sobrien  return reversed_comparison_code_parts (GET_CODE (exp),
1144190075Sobrien					 XEXP (x, 0), XEXP (x, 1), NULL);
1144218334Speter}
1144390075Sobrien/* Return comparison with reversed code of EXP and operands OP0 and OP1.
1144490075Sobrien   Return NULL_RTX in case we fail to do the reversal.  */
1144590075Sobrienstatic rtx
1144690075Sobrienreversed_comparison (exp, mode, op0, op1)
1144790075Sobrien     rtx exp, op0, op1;
1144890075Sobrien     enum machine_mode mode;
1144990075Sobrien{
1145090075Sobrien  enum rtx_code reversed_code = combine_reversed_comparison_code (exp);
1145190075Sobrien  if (reversed_code == UNKNOWN)
1145290075Sobrien    return NULL_RTX;
1145390075Sobrien  else
1145490075Sobrien    return gen_binary (reversed_code, mode, op0, op1);
1145590075Sobrien}
1145618334Speter
1145718334Speter/* Utility function for following routine.  Called when X is part of a value
1145818334Speter   being stored into reg_last_set_value.  Sets reg_last_set_table_tick
1145918334Speter   for each register mentioned.  Similar to mention_regs in cse.c  */
1146018334Speter
1146118334Speterstatic void
1146218334Speterupdate_table_tick (x)
1146318334Speter     rtx x;
1146418334Speter{
1146590075Sobrien  enum rtx_code code = GET_CODE (x);
1146690075Sobrien  const char *fmt = GET_RTX_FORMAT (code);
1146790075Sobrien  int i;
1146818334Speter
1146918334Speter  if (code == REG)
1147018334Speter    {
1147190075Sobrien      unsigned int regno = REGNO (x);
1147290075Sobrien      unsigned int endregno
1147390075Sobrien	= regno + (regno < FIRST_PSEUDO_REGISTER
1147490075Sobrien		   ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
1147590075Sobrien      unsigned int r;
1147618334Speter
1147790075Sobrien      for (r = regno; r < endregno; r++)
1147890075Sobrien	reg_last_set_table_tick[r] = label_tick;
1147918334Speter
1148018334Speter      return;
1148118334Speter    }
1148290075Sobrien
1148318334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1148418334Speter    /* Note that we can't have an "E" in values stored; see
1148518334Speter       get_last_value_validate.  */
1148618334Speter    if (fmt[i] == 'e')
11487117395Skan      {
11488117395Skan	/* Check for identical subexpressions.  If x contains
11489117395Skan	   identical subexpression we only have to traverse one of
11490117395Skan	   them.  */
11491117395Skan	if (i == 0
11492117395Skan	    && (GET_RTX_CLASS (code) == '2'
11493117395Skan		|| GET_RTX_CLASS (code) == 'c'))
11494117395Skan	  {
11495117395Skan	    /* Note that at this point x1 has already been
11496117395Skan	       processed.  */
11497117395Skan	    rtx x0 = XEXP (x, 0);
11498117395Skan	    rtx x1 = XEXP (x, 1);
11499117395Skan
11500117395Skan	    /* If x0 and x1 are identical then there is no need to
11501117395Skan	       process x0.  */
11502117395Skan	    if (x0 == x1)
11503117395Skan	      break;
11504117395Skan
11505117395Skan	    /* If x0 is identical to a subexpression of x1 then while
11506117395Skan	       processing x1, x0 has already been processed.  Thus we
11507117395Skan	       are done with x.  */
11508117395Skan	    if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
11509117395Skan		 || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
11510117395Skan		&& (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
11511117395Skan	      break;
11512117395Skan
11513117395Skan	    /* If x1 is identical to a subexpression of x0 then we
11514117395Skan	       still have to process the rest of x0.  */
11515117395Skan	    if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
11516117395Skan		 || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
11517117395Skan		&& (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
11518117395Skan	      {
11519117395Skan		update_table_tick (XEXP (x0, x1 == XEXP (x0, 0) ? 1 : 0));
11520117395Skan		break;
11521117395Skan	      }
11522117395Skan	  }
11523117395Skan
11524117395Skan	update_table_tick (XEXP (x, i));
11525117395Skan      }
1152618334Speter}
1152718334Speter
1152818334Speter/* Record that REG is set to VALUE in insn INSN.  If VALUE is zero, we
1152918334Speter   are saying that the register is clobbered and we no longer know its
1153018334Speter   value.  If INSN is zero, don't update reg_last_set; this is only permitted
1153118334Speter   with VALUE also zero and is used to invalidate the register.  */
1153218334Speter
1153318334Speterstatic void
1153418334Speterrecord_value_for_reg (reg, insn, value)
1153518334Speter     rtx reg;
1153618334Speter     rtx insn;
1153718334Speter     rtx value;
1153818334Speter{
1153990075Sobrien  unsigned int regno = REGNO (reg);
1154090075Sobrien  unsigned int endregno
1154190075Sobrien    = regno + (regno < FIRST_PSEUDO_REGISTER
1154290075Sobrien	       ? HARD_REGNO_NREGS (regno, GET_MODE (reg)) : 1);
1154390075Sobrien  unsigned int i;
1154418334Speter
1154518334Speter  /* If VALUE contains REG and we have a previous value for REG, substitute
1154618334Speter     the previous value.  */
1154718334Speter  if (value && insn && reg_overlap_mentioned_p (reg, value))
1154818334Speter    {
1154918334Speter      rtx tem;
1155018334Speter
1155118334Speter      /* Set things up so get_last_value is allowed to see anything set up to
1155218334Speter	 our insn.  */
1155318334Speter      subst_low_cuid = INSN_CUID (insn);
1155490075Sobrien      tem = get_last_value (reg);
1155518334Speter
1155690075Sobrien      /* If TEM is simply a binary operation with two CLOBBERs as operands,
1155790075Sobrien	 it isn't going to be useful and will take a lot of time to process,
1155890075Sobrien	 so just use the CLOBBER.  */
1155990075Sobrien
1156018334Speter      if (tem)
1156190075Sobrien	{
1156290075Sobrien	  if ((GET_RTX_CLASS (GET_CODE (tem)) == '2'
1156390075Sobrien	       || GET_RTX_CLASS (GET_CODE (tem)) == 'c')
1156490075Sobrien	      && GET_CODE (XEXP (tem, 0)) == CLOBBER
1156590075Sobrien	      && GET_CODE (XEXP (tem, 1)) == CLOBBER)
1156690075Sobrien	    tem = XEXP (tem, 0);
1156790075Sobrien
1156890075Sobrien	  value = replace_rtx (copy_rtx (value), reg, tem);
1156990075Sobrien	}
1157018334Speter    }
1157118334Speter
1157218334Speter  /* For each register modified, show we don't know its value, that
1157318334Speter     we don't know about its bitwise content, that its value has been
1157418334Speter     updated, and that we don't know the location of the death of the
1157518334Speter     register.  */
1157690075Sobrien  for (i = regno; i < endregno; i++)
1157718334Speter    {
1157818334Speter      if (insn)
1157918334Speter	reg_last_set[i] = insn;
1158090075Sobrien
1158118334Speter      reg_last_set_value[i] = 0;
1158218334Speter      reg_last_set_mode[i] = 0;
1158318334Speter      reg_last_set_nonzero_bits[i] = 0;
1158418334Speter      reg_last_set_sign_bit_copies[i] = 0;
1158518334Speter      reg_last_death[i] = 0;
1158618334Speter    }
1158718334Speter
1158818334Speter  /* Mark registers that are being referenced in this value.  */
1158918334Speter  if (value)
1159018334Speter    update_table_tick (value);
1159118334Speter
1159218334Speter  /* Now update the status of each register being set.
1159318334Speter     If someone is using this register in this block, set this register
1159418334Speter     to invalid since we will get confused between the two lives in this
1159518334Speter     basic block.  This makes using this register always invalid.  In cse, we
1159618334Speter     scan the table to invalidate all entries using this register, but this
1159718334Speter     is too much work for us.  */
1159818334Speter
1159918334Speter  for (i = regno; i < endregno; i++)
1160018334Speter    {
1160118334Speter      reg_last_set_label[i] = label_tick;
1160218334Speter      if (value && reg_last_set_table_tick[i] == label_tick)
1160318334Speter	reg_last_set_invalid[i] = 1;
1160418334Speter      else
1160518334Speter	reg_last_set_invalid[i] = 0;
1160618334Speter    }
1160718334Speter
1160818334Speter  /* The value being assigned might refer to X (like in "x++;").  In that
1160918334Speter     case, we must replace it with (clobber (const_int 0)) to prevent
1161018334Speter     infinite loops.  */
1161150397Sobrien  if (value && ! get_last_value_validate (&value, insn,
1161218334Speter					  reg_last_set_label[regno], 0))
1161318334Speter    {
1161418334Speter      value = copy_rtx (value);
1161550397Sobrien      if (! get_last_value_validate (&value, insn,
1161650397Sobrien				     reg_last_set_label[regno], 1))
1161718334Speter	value = 0;
1161818334Speter    }
1161918334Speter
1162018334Speter  /* For the main register being modified, update the value, the mode, the
1162118334Speter     nonzero bits, and the number of sign bit copies.  */
1162218334Speter
1162318334Speter  reg_last_set_value[regno] = value;
1162418334Speter
1162518334Speter  if (value)
1162618334Speter    {
1162796263Sobrien      enum machine_mode mode = GET_MODE (reg);
1162818334Speter      subst_low_cuid = INSN_CUID (insn);
1162996263Sobrien      reg_last_set_mode[regno] = mode;
1163096263Sobrien      if (GET_MODE_CLASS (mode) == MODE_INT
1163196263Sobrien	  && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
1163296263Sobrien	mode = nonzero_bits_mode;
1163396263Sobrien      reg_last_set_nonzero_bits[regno] = nonzero_bits (value, mode);
1163418334Speter      reg_last_set_sign_bit_copies[regno]
1163518334Speter	= num_sign_bit_copies (value, GET_MODE (reg));
1163618334Speter    }
1163718334Speter}
1163818334Speter
1163918334Speter/* Called via note_stores from record_dead_and_set_regs to handle one
1164090075Sobrien   SET or CLOBBER in an insn.  DATA is the instruction in which the
1164190075Sobrien   set is occurring.  */
1164218334Speter
1164318334Speterstatic void
1164490075Sobrienrecord_dead_and_set_regs_1 (dest, setter, data)
1164518334Speter     rtx dest, setter;
1164690075Sobrien     void *data;
1164718334Speter{
1164890075Sobrien  rtx record_dead_insn = (rtx) data;
1164990075Sobrien
1165018334Speter  if (GET_CODE (dest) == SUBREG)
1165118334Speter    dest = SUBREG_REG (dest);
1165218334Speter
1165318334Speter  if (GET_CODE (dest) == REG)
1165418334Speter    {
1165518334Speter      /* If we are setting the whole register, we know its value.  Otherwise
1165618334Speter	 show that we don't know the value.  We can handle SUBREG in
1165718334Speter	 some cases.  */
1165818334Speter      if (GET_CODE (setter) == SET && dest == SET_DEST (setter))
1165918334Speter	record_value_for_reg (dest, record_dead_insn, SET_SRC (setter));
1166018334Speter      else if (GET_CODE (setter) == SET
1166118334Speter	       && GET_CODE (SET_DEST (setter)) == SUBREG
1166218334Speter	       && SUBREG_REG (SET_DEST (setter)) == dest
1166318334Speter	       && GET_MODE_BITSIZE (GET_MODE (dest)) <= BITS_PER_WORD
1166418334Speter	       && subreg_lowpart_p (SET_DEST (setter)))
1166518334Speter	record_value_for_reg (dest, record_dead_insn,
1166618334Speter			      gen_lowpart_for_combine (GET_MODE (dest),
1166718334Speter						       SET_SRC (setter)));
1166818334Speter      else
1166918334Speter	record_value_for_reg (dest, record_dead_insn, NULL_RTX);
1167018334Speter    }
1167118334Speter  else if (GET_CODE (dest) == MEM
1167218334Speter	   /* Ignore pushes, they clobber nothing.  */
1167318334Speter	   && ! push_operand (dest, GET_MODE (dest)))
1167418334Speter    mem_last_set = INSN_CUID (record_dead_insn);
1167518334Speter}
1167618334Speter
1167718334Speter/* Update the records of when each REG was most recently set or killed
1167818334Speter   for the things done by INSN.  This is the last thing done in processing
1167918334Speter   INSN in the combiner loop.
1168018334Speter
1168118334Speter   We update reg_last_set, reg_last_set_value, reg_last_set_mode,
1168218334Speter   reg_last_set_nonzero_bits, reg_last_set_sign_bit_copies, reg_last_death,
1168318334Speter   and also the similar information mem_last_set (which insn most recently
1168418334Speter   modified memory) and last_call_cuid (which insn was the most recent
1168518334Speter   subroutine call).  */
1168618334Speter
1168718334Speterstatic void
1168818334Speterrecord_dead_and_set_regs (insn)
1168918334Speter     rtx insn;
1169018334Speter{
1169190075Sobrien  rtx link;
1169290075Sobrien  unsigned int i;
1169318334Speter
1169418334Speter  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1169518334Speter    {
1169618334Speter      if (REG_NOTE_KIND (link) == REG_DEAD
1169718334Speter	  && GET_CODE (XEXP (link, 0)) == REG)
1169818334Speter	{
1169990075Sobrien	  unsigned int regno = REGNO (XEXP (link, 0));
1170090075Sobrien	  unsigned int endregno
1170118334Speter	    = regno + (regno < FIRST_PSEUDO_REGISTER
1170218334Speter		       ? HARD_REGNO_NREGS (regno, GET_MODE (XEXP (link, 0)))
1170318334Speter		       : 1);
1170418334Speter
1170518334Speter	  for (i = regno; i < endregno; i++)
1170618334Speter	    reg_last_death[i] = insn;
1170718334Speter	}
1170818334Speter      else if (REG_NOTE_KIND (link) == REG_INC)
1170918334Speter	record_value_for_reg (XEXP (link, 0), insn, NULL_RTX);
1171018334Speter    }
1171118334Speter
1171218334Speter  if (GET_CODE (insn) == CALL_INSN)
1171318334Speter    {
1171418334Speter      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1171590075Sobrien	if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
1171618334Speter	  {
1171718334Speter	    reg_last_set_value[i] = 0;
1171818334Speter	    reg_last_set_mode[i] = 0;
1171918334Speter	    reg_last_set_nonzero_bits[i] = 0;
1172018334Speter	    reg_last_set_sign_bit_copies[i] = 0;
1172118334Speter	    reg_last_death[i] = 0;
1172218334Speter	  }
1172318334Speter
1172418334Speter      last_call_cuid = mem_last_set = INSN_CUID (insn);
1172590075Sobrien
1172690075Sobrien      /* Don't bother recording what this insn does.  It might set the
1172790075Sobrien	 return value register, but we can't combine into a call
1172890075Sobrien	 pattern anyway, so there's no point trying (and it may cause
1172990075Sobrien	 a crash, if e.g. we wind up asking for last_set_value of a
1173090075Sobrien	 SUBREG of the return value register).  */
1173190075Sobrien      return;
1173218334Speter    }
1173318334Speter
1173490075Sobrien  note_stores (PATTERN (insn), record_dead_and_set_regs_1, insn);
1173518334Speter}
1173690075Sobrien
1173790075Sobrien/* If a SUBREG has the promoted bit set, it is in fact a property of the
1173890075Sobrien   register present in the SUBREG, so for each such SUBREG go back and
1173990075Sobrien   adjust nonzero and sign bit information of the registers that are
1174090075Sobrien   known to have some zero/sign bits set.
1174190075Sobrien
1174290075Sobrien   This is needed because when combine blows the SUBREGs away, the
1174390075Sobrien   information on zero/sign bits is lost and further combines can be
1174490075Sobrien   missed because of that.  */
1174590075Sobrien
1174690075Sobrienstatic void
1174790075Sobrienrecord_promoted_value (insn, subreg)
1174890075Sobrien     rtx insn;
1174990075Sobrien     rtx subreg;
1175090075Sobrien{
1175190075Sobrien  rtx links, set;
1175290075Sobrien  unsigned int regno = REGNO (SUBREG_REG (subreg));
1175390075Sobrien  enum machine_mode mode = GET_MODE (subreg);
1175490075Sobrien
1175590075Sobrien  if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
1175690075Sobrien    return;
1175790075Sobrien
1175890075Sobrien  for (links = LOG_LINKS (insn); links;)
1175990075Sobrien    {
1176090075Sobrien      insn = XEXP (links, 0);
1176190075Sobrien      set = single_set (insn);
1176290075Sobrien
1176390075Sobrien      if (! set || GET_CODE (SET_DEST (set)) != REG
1176490075Sobrien	  || REGNO (SET_DEST (set)) != regno
1176590075Sobrien	  || GET_MODE (SET_DEST (set)) != GET_MODE (SUBREG_REG (subreg)))
1176690075Sobrien	{
1176790075Sobrien	  links = XEXP (links, 1);
1176890075Sobrien	  continue;
1176990075Sobrien	}
1177090075Sobrien
1177190075Sobrien      if (reg_last_set[regno] == insn)
1177290075Sobrien	{
11773117395Skan	  if (SUBREG_PROMOTED_UNSIGNED_P (subreg) > 0)
1177490075Sobrien	    reg_last_set_nonzero_bits[regno] &= GET_MODE_MASK (mode);
1177590075Sobrien	}
1177690075Sobrien
1177790075Sobrien      if (GET_CODE (SET_SRC (set)) == REG)
1177890075Sobrien	{
1177990075Sobrien	  regno = REGNO (SET_SRC (set));
1178090075Sobrien	  links = LOG_LINKS (insn);
1178190075Sobrien	}
1178290075Sobrien      else
1178390075Sobrien	break;
1178490075Sobrien    }
1178590075Sobrien}
1178690075Sobrien
1178790075Sobrien/* Scan X for promoted SUBREGs.  For each one found,
1178890075Sobrien   note what it implies to the registers used in it.  */
1178990075Sobrien
1179090075Sobrienstatic void
1179190075Sobriencheck_promoted_subreg (insn, x)
1179290075Sobrien     rtx insn;
1179390075Sobrien     rtx x;
1179490075Sobrien{
1179590075Sobrien  if (GET_CODE (x) == SUBREG && SUBREG_PROMOTED_VAR_P (x)
1179690075Sobrien      && GET_CODE (SUBREG_REG (x)) == REG)
1179790075Sobrien    record_promoted_value (insn, x);
1179890075Sobrien  else
1179990075Sobrien    {
1180090075Sobrien      const char *format = GET_RTX_FORMAT (GET_CODE (x));
1180190075Sobrien      int i, j;
1180290075Sobrien
1180390075Sobrien      for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
1180490075Sobrien	switch (format[i])
1180590075Sobrien	  {
1180690075Sobrien	  case 'e':
1180790075Sobrien	    check_promoted_subreg (insn, XEXP (x, i));
1180890075Sobrien	    break;
1180990075Sobrien	  case 'V':
1181090075Sobrien	  case 'E':
1181190075Sobrien	    if (XVEC (x, i) != 0)
1181290075Sobrien	      for (j = 0; j < XVECLEN (x, i); j++)
1181390075Sobrien		check_promoted_subreg (insn, XVECEXP (x, i, j));
1181490075Sobrien	    break;
1181590075Sobrien	  }
1181690075Sobrien    }
1181790075Sobrien}
1181818334Speter
1181918334Speter/* Utility routine for the following function.  Verify that all the registers
1182018334Speter   mentioned in *LOC are valid when *LOC was part of a value set when
1182118334Speter   label_tick == TICK.  Return 0 if some are not.
1182218334Speter
11823117395Skan   If REPLACE is nonzero, replace the invalid reference with
1182418334Speter   (clobber (const_int 0)) and return 1.  This replacement is useful because
1182518334Speter   we often can get useful information about the form of a value (e.g., if
1182618334Speter   it was produced by a shift that always produces -1 or 0) even though
1182718334Speter   we don't know exactly what registers it was produced from.  */
1182818334Speter
1182918334Speterstatic int
1183050397Sobrienget_last_value_validate (loc, insn, tick, replace)
1183118334Speter     rtx *loc;
1183250397Sobrien     rtx insn;
1183318334Speter     int tick;
1183418334Speter     int replace;
1183518334Speter{
1183618334Speter  rtx x = *loc;
1183790075Sobrien  const char *fmt = GET_RTX_FORMAT (GET_CODE (x));
1183818334Speter  int len = GET_RTX_LENGTH (GET_CODE (x));
1183918334Speter  int i;
1184018334Speter
1184118334Speter  if (GET_CODE (x) == REG)
1184218334Speter    {
1184390075Sobrien      unsigned int regno = REGNO (x);
1184490075Sobrien      unsigned int endregno
1184590075Sobrien	= regno + (regno < FIRST_PSEUDO_REGISTER
1184690075Sobrien		   ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
1184790075Sobrien      unsigned int j;
1184818334Speter
1184918334Speter      for (j = regno; j < endregno; j++)
1185018334Speter	if (reg_last_set_invalid[j]
1185190075Sobrien	    /* If this is a pseudo-register that was only set once and not
1185290075Sobrien	       live at the beginning of the function, it is always valid.  */
1185390075Sobrien	    || (! (regno >= FIRST_PSEUDO_REGISTER
1185490075Sobrien		   && REG_N_SETS (regno) == 1
1185590075Sobrien		   && (! REGNO_REG_SET_P
11856117395Skan		       (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, regno)))
1185718334Speter		&& reg_last_set_label[j] > tick))
1185818334Speter	  {
1185918334Speter	    if (replace)
1186050397Sobrien	      *loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
1186118334Speter	    return replace;
1186218334Speter	  }
1186318334Speter
1186418334Speter      return 1;
1186518334Speter    }
1186650397Sobrien  /* If this is a memory reference, make sure that there were
1186750397Sobrien     no stores after it that might have clobbered the value.  We don't
1186850397Sobrien     have alias info, so we assume any store invalidates it.  */
1186950397Sobrien  else if (GET_CODE (x) == MEM && ! RTX_UNCHANGING_P (x)
1187050397Sobrien	   && INSN_CUID (insn) <= mem_last_set)
1187150397Sobrien    {
1187250397Sobrien      if (replace)
1187350397Sobrien	*loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
1187450397Sobrien      return replace;
1187550397Sobrien    }
1187618334Speter
1187718334Speter  for (i = 0; i < len; i++)
11878117395Skan    {
11879117395Skan      if (fmt[i] == 'e')
11880117395Skan	{
11881117395Skan	  /* Check for identical subexpressions.  If x contains
11882117395Skan	     identical subexpression we only have to traverse one of
11883117395Skan	     them.  */
11884117395Skan	  if (i == 1
11885117395Skan	      && (GET_RTX_CLASS (GET_CODE (x)) == '2'
11886117395Skan		  || GET_RTX_CLASS (GET_CODE (x)) == 'c'))
11887117395Skan	    {
11888117395Skan	      /* Note that at this point x0 has already been checked
11889117395Skan		 and found valid.  */
11890117395Skan	      rtx x0 = XEXP (x, 0);
11891117395Skan	      rtx x1 = XEXP (x, 1);
1189218334Speter
11893117395Skan	      /* If x0 and x1 are identical then x is also valid.  */
11894117395Skan	      if (x0 == x1)
11895117395Skan		return 1;
11896117395Skan
11897117395Skan	      /* If x1 is identical to a subexpression of x0 then
11898117395Skan		 while checking x0, x1 has already been checked.  Thus
11899117395Skan		 it is valid and so as x.  */
11900117395Skan	      if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
11901117395Skan		   || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
11902117395Skan		  && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
11903117395Skan		return 1;
11904117395Skan
11905117395Skan	      /* If x0 is identical to a subexpression of x1 then x is
11906117395Skan		 valid iff the rest of x1 is valid.  */
11907117395Skan	      if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
11908117395Skan		   || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
11909117395Skan		  && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
11910117395Skan		return
11911117395Skan		  get_last_value_validate (&XEXP (x1,
11912117395Skan						  x0 == XEXP (x1, 0) ? 1 : 0),
11913117395Skan					   insn, tick, replace);
11914117395Skan	    }
11915117395Skan
11916117395Skan	  if (get_last_value_validate (&XEXP (x, i), insn, tick,
11917117395Skan				       replace) == 0)
11918117395Skan	    return 0;
11919117395Skan	}
11920117395Skan      /* Don't bother with these.  They shouldn't occur anyway.  */
11921117395Skan      else if (fmt[i] == 'E')
11922117395Skan	return 0;
11923117395Skan    }
11924117395Skan
1192518334Speter  /* If we haven't found a reason for it to be invalid, it is valid.  */
1192618334Speter  return 1;
1192718334Speter}
1192818334Speter
1192918334Speter/* Get the last value assigned to X, if known.  Some registers
1193018334Speter   in the value may be replaced with (clobber (const_int 0)) if their value
1193118334Speter   is known longer known reliably.  */
1193218334Speter
1193318334Speterstatic rtx
1193418334Speterget_last_value (x)
1193518334Speter     rtx x;
1193618334Speter{
1193790075Sobrien  unsigned int regno;
1193818334Speter  rtx value;
1193918334Speter
1194018334Speter  /* If this is a non-paradoxical SUBREG, get the value of its operand and
1194118334Speter     then convert it to the desired mode.  If this is a paradoxical SUBREG,
1194250397Sobrien     we cannot predict what values the "extra" bits might have.  */
1194318334Speter  if (GET_CODE (x) == SUBREG
1194418334Speter      && subreg_lowpart_p (x)
1194518334Speter      && (GET_MODE_SIZE (GET_MODE (x))
1194618334Speter	  <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
1194718334Speter      && (value = get_last_value (SUBREG_REG (x))) != 0)
1194818334Speter    return gen_lowpart_for_combine (GET_MODE (x), value);
1194918334Speter
1195018334Speter  if (GET_CODE (x) != REG)
1195118334Speter    return 0;
1195218334Speter
1195318334Speter  regno = REGNO (x);
1195418334Speter  value = reg_last_set_value[regno];
1195518334Speter
1195690075Sobrien  /* If we don't have a value, or if it isn't for this basic block and
1195790075Sobrien     it's either a hard register, set more than once, or it's a live
1195890075Sobrien     at the beginning of the function, return 0.
1195918334Speter
1196090075Sobrien     Because if it's not live at the beginning of the function then the reg
1196190075Sobrien     is always set before being used (is never used without being set).
1196290075Sobrien     And, if it's set only once, and it's always set before use, then all
1196390075Sobrien     uses must have the same last value, even if it's not from this basic
1196490075Sobrien     block.  */
1196590075Sobrien
1196618334Speter  if (value == 0
1196790075Sobrien      || (reg_last_set_label[regno] != label_tick
1196890075Sobrien	  && (regno < FIRST_PSEUDO_REGISTER
1196990075Sobrien	      || REG_N_SETS (regno) != 1
1197090075Sobrien	      || (REGNO_REG_SET_P
11971117395Skan		  (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, regno)))))
1197218334Speter    return 0;
1197318334Speter
1197418334Speter  /* If the value was set in a later insn than the ones we are processing,
1197552750Sobrien     we can't use it even if the register was only set once.  */
1197618334Speter  if (INSN_CUID (reg_last_set[regno]) >= subst_low_cuid)
1197752750Sobrien    return 0;
1197818334Speter
1197918334Speter  /* If the value has all its registers valid, return it.  */
1198050397Sobrien  if (get_last_value_validate (&value, reg_last_set[regno],
1198150397Sobrien			       reg_last_set_label[regno], 0))
1198218334Speter    return value;
1198318334Speter
1198418334Speter  /* Otherwise, make a copy and replace any invalid register with
1198518334Speter     (clobber (const_int 0)).  If that fails for some reason, return 0.  */
1198618334Speter
1198718334Speter  value = copy_rtx (value);
1198850397Sobrien  if (get_last_value_validate (&value, reg_last_set[regno],
1198950397Sobrien			       reg_last_set_label[regno], 1))
1199018334Speter    return value;
1199118334Speter
1199218334Speter  return 0;
1199318334Speter}
1199418334Speter
1199518334Speter/* Return nonzero if expression X refers to a REG or to memory
1199618334Speter   that is set in an instruction more recent than FROM_CUID.  */
1199718334Speter
1199818334Speterstatic int
1199918334Speteruse_crosses_set_p (x, from_cuid)
1200090075Sobrien     rtx x;
1200118334Speter     int from_cuid;
1200218334Speter{
1200390075Sobrien  const char *fmt;
1200490075Sobrien  int i;
1200590075Sobrien  enum rtx_code code = GET_CODE (x);
1200618334Speter
1200718334Speter  if (code == REG)
1200818334Speter    {
1200990075Sobrien      unsigned int regno = REGNO (x);
1201090075Sobrien      unsigned endreg = regno + (regno < FIRST_PSEUDO_REGISTER
1201190075Sobrien				 ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
1201290075Sobrien
1201318334Speter#ifdef PUSH_ROUNDING
1201418334Speter      /* Don't allow uses of the stack pointer to be moved,
1201518334Speter	 because we don't know whether the move crosses a push insn.  */
1201690075Sobrien      if (regno == STACK_POINTER_REGNUM && PUSH_ARGS)
1201718334Speter	return 1;
1201818334Speter#endif
1201990075Sobrien      for (; regno < endreg; regno++)
1202018334Speter	if (reg_last_set[regno]
1202118334Speter	    && INSN_CUID (reg_last_set[regno]) > from_cuid)
1202218334Speter	  return 1;
1202318334Speter      return 0;
1202418334Speter    }
1202518334Speter
1202618334Speter  if (code == MEM && mem_last_set > from_cuid)
1202718334Speter    return 1;
1202818334Speter
1202918334Speter  fmt = GET_RTX_FORMAT (code);
1203018334Speter
1203118334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1203218334Speter    {
1203318334Speter      if (fmt[i] == 'E')
1203418334Speter	{
1203590075Sobrien	  int j;
1203618334Speter	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1203718334Speter	    if (use_crosses_set_p (XVECEXP (x, i, j), from_cuid))
1203818334Speter	      return 1;
1203918334Speter	}
1204018334Speter      else if (fmt[i] == 'e'
1204118334Speter	       && use_crosses_set_p (XEXP (x, i), from_cuid))
1204218334Speter	return 1;
1204318334Speter    }
1204418334Speter  return 0;
1204518334Speter}
1204618334Speter
1204718334Speter/* Define three variables used for communication between the following
1204818334Speter   routines.  */
1204918334Speter
1205090075Sobrienstatic unsigned int reg_dead_regno, reg_dead_endregno;
1205118334Speterstatic int reg_dead_flag;
1205218334Speter
1205318334Speter/* Function called via note_stores from reg_dead_at_p.
1205418334Speter
1205590075Sobrien   If DEST is within [reg_dead_regno, reg_dead_endregno), set
1205618334Speter   reg_dead_flag to 1 if X is a CLOBBER and to -1 it is a SET.  */
1205718334Speter
1205818334Speterstatic void
1205990075Sobrienreg_dead_at_p_1 (dest, x, data)
1206018334Speter     rtx dest;
1206118334Speter     rtx x;
1206290075Sobrien     void *data ATTRIBUTE_UNUSED;
1206318334Speter{
1206490075Sobrien  unsigned int regno, endregno;
1206518334Speter
1206618334Speter  if (GET_CODE (dest) != REG)
1206718334Speter    return;
1206818334Speter
1206918334Speter  regno = REGNO (dest);
1207090075Sobrien  endregno = regno + (regno < FIRST_PSEUDO_REGISTER
1207118334Speter		      ? HARD_REGNO_NREGS (regno, GET_MODE (dest)) : 1);
1207218334Speter
1207318334Speter  if (reg_dead_endregno > regno && reg_dead_regno < endregno)
1207418334Speter    reg_dead_flag = (GET_CODE (x) == CLOBBER) ? 1 : -1;
1207518334Speter}
1207618334Speter
12077117395Skan/* Return nonzero if REG is known to be dead at INSN.
1207818334Speter
1207918334Speter   We scan backwards from INSN.  If we hit a REG_DEAD note or a CLOBBER
1208018334Speter   referencing REG, it is dead.  If we hit a SET referencing REG, it is
1208118334Speter   live.  Otherwise, see if it is live or dead at the start of the basic
1208218334Speter   block we are in.  Hard regs marked as being live in NEWPAT_USED_REGS
1208318334Speter   must be assumed to be always live.  */
1208418334Speter
1208518334Speterstatic int
1208618334Speterreg_dead_at_p (reg, insn)
1208718334Speter     rtx reg;
1208818334Speter     rtx insn;
1208918334Speter{
12090117395Skan  basic_block block;
1209190075Sobrien  unsigned int i;
1209218334Speter
1209318334Speter  /* Set variables for reg_dead_at_p_1.  */
1209418334Speter  reg_dead_regno = REGNO (reg);
1209518334Speter  reg_dead_endregno = reg_dead_regno + (reg_dead_regno < FIRST_PSEUDO_REGISTER
1209618334Speter					? HARD_REGNO_NREGS (reg_dead_regno,
1209718334Speter							    GET_MODE (reg))
1209818334Speter					: 1);
1209918334Speter
1210018334Speter  reg_dead_flag = 0;
1210118334Speter
1210218334Speter  /* Check that reg isn't mentioned in NEWPAT_USED_REGS.  */
1210318334Speter  if (reg_dead_regno < FIRST_PSEUDO_REGISTER)
1210418334Speter    {
1210518334Speter      for (i = reg_dead_regno; i < reg_dead_endregno; i++)
1210618334Speter	if (TEST_HARD_REG_BIT (newpat_used_regs, i))
1210718334Speter	  return 0;
1210818334Speter    }
1210918334Speter
1211018334Speter  /* Scan backwards until we find a REG_DEAD note, SET, CLOBBER, label, or
1211118334Speter     beginning of function.  */
1211218334Speter  for (; insn && GET_CODE (insn) != CODE_LABEL && GET_CODE (insn) != BARRIER;
1211318334Speter       insn = prev_nonnote_insn (insn))
1211418334Speter    {
1211590075Sobrien      note_stores (PATTERN (insn), reg_dead_at_p_1, NULL);
1211618334Speter      if (reg_dead_flag)
1211718334Speter	return reg_dead_flag == 1 ? 1 : 0;
1211818334Speter
1211918334Speter      if (find_regno_note (insn, REG_DEAD, reg_dead_regno))
1212018334Speter	return 1;
1212118334Speter    }
1212218334Speter
12123117395Skan  /* Get the basic block that we were in.  */
1212418334Speter  if (insn == 0)
12125117395Skan    block = ENTRY_BLOCK_PTR->next_bb;
1212618334Speter  else
1212718334Speter    {
12128117395Skan      FOR_EACH_BB (block)
12129117395Skan	if (insn == block->head)
1213018334Speter	  break;
1213118334Speter
12132117395Skan      if (block == EXIT_BLOCK_PTR)
1213318334Speter	return 0;
1213418334Speter    }
1213518334Speter
1213618334Speter  for (i = reg_dead_regno; i < reg_dead_endregno; i++)
12137117395Skan    if (REGNO_REG_SET_P (block->global_live_at_start, i))
1213818334Speter      return 0;
1213918334Speter
1214018334Speter  return 1;
1214118334Speter}
1214218334Speter
1214318334Speter/* Note hard registers in X that are used.  This code is similar to
1214418334Speter   that in flow.c, but much simpler since we don't care about pseudos.  */
1214518334Speter
1214618334Speterstatic void
1214718334Spetermark_used_regs_combine (x)
1214818334Speter     rtx x;
1214918334Speter{
1215090075Sobrien  RTX_CODE code = GET_CODE (x);
1215190075Sobrien  unsigned int regno;
1215218334Speter  int i;
1215318334Speter
1215418334Speter  switch (code)
1215518334Speter    {
1215618334Speter    case LABEL_REF:
1215718334Speter    case SYMBOL_REF:
1215818334Speter    case CONST_INT:
1215918334Speter    case CONST:
1216018334Speter    case CONST_DOUBLE:
1216196263Sobrien    case CONST_VECTOR:
1216218334Speter    case PC:
1216318334Speter    case ADDR_VEC:
1216418334Speter    case ADDR_DIFF_VEC:
1216518334Speter    case ASM_INPUT:
1216618334Speter#ifdef HAVE_cc0
1216718334Speter    /* CC0 must die in the insn after it is set, so we don't need to take
1216818334Speter       special note of it here.  */
1216918334Speter    case CC0:
1217018334Speter#endif
1217118334Speter      return;
1217218334Speter
1217318334Speter    case CLOBBER:
1217418334Speter      /* If we are clobbering a MEM, mark any hard registers inside the
1217518334Speter	 address as used.  */
1217618334Speter      if (GET_CODE (XEXP (x, 0)) == MEM)
1217718334Speter	mark_used_regs_combine (XEXP (XEXP (x, 0), 0));
1217818334Speter      return;
1217918334Speter
1218018334Speter    case REG:
1218118334Speter      regno = REGNO (x);
1218218334Speter      /* A hard reg in a wide mode may really be multiple registers.
1218318334Speter	 If so, mark all of them just like the first.  */
1218418334Speter      if (regno < FIRST_PSEUDO_REGISTER)
1218518334Speter	{
1218690075Sobrien	  unsigned int endregno, r;
1218790075Sobrien
12188117395Skan	  /* None of this applies to the stack, frame or arg pointers.  */
1218918334Speter	  if (regno == STACK_POINTER_REGNUM
1219018334Speter#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
1219118334Speter	      || regno == HARD_FRAME_POINTER_REGNUM
1219218334Speter#endif
1219318334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
1219418334Speter	      || (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
1219518334Speter#endif
1219618334Speter	      || regno == FRAME_POINTER_REGNUM)
1219718334Speter	    return;
1219818334Speter
1219990075Sobrien	  endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
1220090075Sobrien	  for (r = regno; r < endregno; r++)
1220190075Sobrien	    SET_HARD_REG_BIT (newpat_used_regs, r);
1220218334Speter	}
1220318334Speter      return;
1220418334Speter
1220518334Speter    case SET:
1220618334Speter      {
1220718334Speter	/* If setting a MEM, or a SUBREG of a MEM, then note any hard regs in
1220818334Speter	   the address.  */
1220990075Sobrien	rtx testreg = SET_DEST (x);
1221018334Speter
1221118334Speter	while (GET_CODE (testreg) == SUBREG
1221218334Speter	       || GET_CODE (testreg) == ZERO_EXTRACT
1221318334Speter	       || GET_CODE (testreg) == SIGN_EXTRACT
1221418334Speter	       || GET_CODE (testreg) == STRICT_LOW_PART)
1221518334Speter	  testreg = XEXP (testreg, 0);
1221618334Speter
1221718334Speter	if (GET_CODE (testreg) == MEM)
1221818334Speter	  mark_used_regs_combine (XEXP (testreg, 0));
1221918334Speter
1222018334Speter	mark_used_regs_combine (SET_SRC (x));
1222118334Speter      }
1222250397Sobrien      return;
1222350397Sobrien
1222450397Sobrien    default:
1222550397Sobrien      break;
1222618334Speter    }
1222718334Speter
1222818334Speter  /* Recursively scan the operands of this expression.  */
1222918334Speter
1223018334Speter  {
1223190075Sobrien    const char *fmt = GET_RTX_FORMAT (code);
1223218334Speter
1223318334Speter    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1223418334Speter      {
1223590075Sobrien	if (fmt[i] == 'e')
1223618334Speter	  mark_used_regs_combine (XEXP (x, i));
1223790075Sobrien	else if (fmt[i] == 'E')
1223890075Sobrien	  {
1223990075Sobrien	    int j;
1224018334Speter
1224190075Sobrien	    for (j = 0; j < XVECLEN (x, i); j++)
1224290075Sobrien	      mark_used_regs_combine (XVECEXP (x, i, j));
1224390075Sobrien	  }
1224418334Speter      }
1224518334Speter  }
1224618334Speter}
1224718334Speter
1224818334Speter/* Remove register number REGNO from the dead registers list of INSN.
1224918334Speter
1225018334Speter   Return the note used to record the death, if there was one.  */
1225118334Speter
1225218334Speterrtx
1225318334Speterremove_death (regno, insn)
1225490075Sobrien     unsigned int regno;
1225518334Speter     rtx insn;
1225618334Speter{
1225790075Sobrien  rtx note = find_regno_note (insn, REG_DEAD, regno);
1225818334Speter
1225918334Speter  if (note)
1226018334Speter    {
1226150397Sobrien      REG_N_DEATHS (regno)--;
1226218334Speter      remove_note (insn, note);
1226318334Speter    }
1226418334Speter
1226518334Speter  return note;
1226618334Speter}
1226718334Speter
1226818334Speter/* For each register (hardware or pseudo) used within expression X, if its
1226918334Speter   death is in an instruction with cuid between FROM_CUID (inclusive) and
1227018334Speter   TO_INSN (exclusive), put a REG_DEAD note for that register in the
1227190075Sobrien   list headed by PNOTES.
1227218334Speter
1227350397Sobrien   That said, don't move registers killed by maybe_kill_insn.
1227450397Sobrien
1227518334Speter   This is done when X is being merged by combination into TO_INSN.  These
1227618334Speter   notes will then be distributed as needed.  */
1227718334Speter
1227818334Speterstatic void
1227950397Sobrienmove_deaths (x, maybe_kill_insn, from_cuid, to_insn, pnotes)
1228018334Speter     rtx x;
1228150397Sobrien     rtx maybe_kill_insn;
1228218334Speter     int from_cuid;
1228318334Speter     rtx to_insn;
1228418334Speter     rtx *pnotes;
1228518334Speter{
1228690075Sobrien  const char *fmt;
1228790075Sobrien  int len, i;
1228890075Sobrien  enum rtx_code code = GET_CODE (x);
1228918334Speter
1229018334Speter  if (code == REG)
1229118334Speter    {
1229290075Sobrien      unsigned int regno = REGNO (x);
1229390075Sobrien      rtx where_dead = reg_last_death[regno];
1229490075Sobrien      rtx before_dead, after_dead;
1229518334Speter
12296117395Skan      /* Don't move the register if it gets killed in between from and to.  */
1229750397Sobrien      if (maybe_kill_insn && reg_set_p (x, maybe_kill_insn)
1229890075Sobrien	  && ! reg_referenced_p (x, maybe_kill_insn))
1229950397Sobrien	return;
1230050397Sobrien
1230118334Speter      /* WHERE_DEAD could be a USE insn made by combine, so first we
1230218334Speter	 make sure that we have insns with valid INSN_CUID values.  */
1230318334Speter      before_dead = where_dead;
1230418334Speter      while (before_dead && INSN_UID (before_dead) > max_uid_cuid)
1230518334Speter	before_dead = PREV_INSN (before_dead);
1230690075Sobrien
1230718334Speter      after_dead = where_dead;
1230818334Speter      while (after_dead && INSN_UID (after_dead) > max_uid_cuid)
1230918334Speter	after_dead = NEXT_INSN (after_dead);
1231018334Speter
1231118334Speter      if (before_dead && after_dead
1231218334Speter	  && INSN_CUID (before_dead) >= from_cuid
1231318334Speter	  && (INSN_CUID (after_dead) < INSN_CUID (to_insn)
1231418334Speter	      || (where_dead != after_dead
1231518334Speter		  && INSN_CUID (after_dead) == INSN_CUID (to_insn))))
1231618334Speter	{
1231718334Speter	  rtx note = remove_death (regno, where_dead);
1231818334Speter
1231918334Speter	  /* It is possible for the call above to return 0.  This can occur
1232018334Speter	     when reg_last_death points to I2 or I1 that we combined with.
1232118334Speter	     In that case make a new note.
1232218334Speter
1232318334Speter	     We must also check for the case where X is a hard register
1232418334Speter	     and NOTE is a death note for a range of hard registers
1232518334Speter	     including X.  In that case, we must put REG_DEAD notes for
1232618334Speter	     the remaining registers in place of NOTE.  */
1232718334Speter
1232818334Speter	  if (note != 0 && regno < FIRST_PSEUDO_REGISTER
1232918334Speter	      && (GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
1233050397Sobrien		  > GET_MODE_SIZE (GET_MODE (x))))
1233118334Speter	    {
1233290075Sobrien	      unsigned int deadregno = REGNO (XEXP (note, 0));
1233390075Sobrien	      unsigned int deadend
1233418334Speter		= (deadregno + HARD_REGNO_NREGS (deadregno,
1233518334Speter						 GET_MODE (XEXP (note, 0))));
1233690075Sobrien	      unsigned int ourend
1233790075Sobrien		= regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
1233890075Sobrien	      unsigned int i;
1233918334Speter
1234018334Speter	      for (i = deadregno; i < deadend; i++)
1234118334Speter		if (i < regno || i >= ourend)
1234218334Speter		  REG_NOTES (where_dead)
1234350397Sobrien		    = gen_rtx_EXPR_LIST (REG_DEAD,
12344117395Skan					 regno_reg_rtx[i],
1234550397Sobrien					 REG_NOTES (where_dead));
1234618334Speter	    }
1234790075Sobrien
1234850397Sobrien	  /* If we didn't find any note, or if we found a REG_DEAD note that
1234950397Sobrien	     covers only part of the given reg, and we have a multi-reg hard
1235018334Speter	     register, then to be safe we must check for REG_DEAD notes
1235118334Speter	     for each register other than the first.  They could have
1235218334Speter	     their own REG_DEAD notes lying around.  */
1235350397Sobrien	  else if ((note == 0
1235450397Sobrien		    || (note != 0
1235550397Sobrien			&& (GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
1235650397Sobrien			    < GET_MODE_SIZE (GET_MODE (x)))))
1235750397Sobrien		   && regno < FIRST_PSEUDO_REGISTER
1235818334Speter		   && HARD_REGNO_NREGS (regno, GET_MODE (x)) > 1)
1235918334Speter	    {
1236090075Sobrien	      unsigned int ourend
1236190075Sobrien		= regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
1236290075Sobrien	      unsigned int i, offset;
1236318334Speter	      rtx oldnotes = 0;
1236418334Speter
1236550397Sobrien	      if (note)
1236650397Sobrien		offset = HARD_REGNO_NREGS (regno, GET_MODE (XEXP (note, 0)));
1236750397Sobrien	      else
1236850397Sobrien		offset = 1;
1236950397Sobrien
1237050397Sobrien	      for (i = regno + offset; i < ourend; i++)
12371117395Skan		move_deaths (regno_reg_rtx[i],
1237250397Sobrien			     maybe_kill_insn, from_cuid, to_insn, &oldnotes);
1237318334Speter	    }
1237418334Speter
1237518334Speter	  if (note != 0 && GET_MODE (XEXP (note, 0)) == GET_MODE (x))
1237618334Speter	    {
1237718334Speter	      XEXP (note, 1) = *pnotes;
1237818334Speter	      *pnotes = note;
1237918334Speter	    }
1238018334Speter	  else
1238150397Sobrien	    *pnotes = gen_rtx_EXPR_LIST (REG_DEAD, x, *pnotes);
1238218334Speter
1238350397Sobrien	  REG_N_DEATHS (regno)++;
1238418334Speter	}
1238518334Speter
1238618334Speter      return;
1238718334Speter    }
1238818334Speter
1238918334Speter  else if (GET_CODE (x) == SET)
1239018334Speter    {
1239118334Speter      rtx dest = SET_DEST (x);
1239218334Speter
1239350397Sobrien      move_deaths (SET_SRC (x), maybe_kill_insn, from_cuid, to_insn, pnotes);
1239418334Speter
1239518334Speter      /* In the case of a ZERO_EXTRACT, a STRICT_LOW_PART, or a SUBREG
1239618334Speter	 that accesses one word of a multi-word item, some
1239718334Speter	 piece of everything register in the expression is used by
1239818334Speter	 this insn, so remove any old death.  */
1239990075Sobrien      /* ??? So why do we test for equality of the sizes?  */
1240018334Speter
1240118334Speter      if (GET_CODE (dest) == ZERO_EXTRACT
1240218334Speter	  || GET_CODE (dest) == STRICT_LOW_PART
1240318334Speter	  || (GET_CODE (dest) == SUBREG
1240418334Speter	      && (((GET_MODE_SIZE (GET_MODE (dest))
1240518334Speter		    + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
1240618334Speter		  == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
1240718334Speter		       + UNITS_PER_WORD - 1) / UNITS_PER_WORD))))
1240818334Speter	{
1240950397Sobrien	  move_deaths (dest, maybe_kill_insn, from_cuid, to_insn, pnotes);
1241018334Speter	  return;
1241118334Speter	}
1241218334Speter
1241318334Speter      /* If this is some other SUBREG, we know it replaces the entire
1241418334Speter	 value, so use that as the destination.  */
1241518334Speter      if (GET_CODE (dest) == SUBREG)
1241618334Speter	dest = SUBREG_REG (dest);
1241718334Speter
1241818334Speter      /* If this is a MEM, adjust deaths of anything used in the address.
1241918334Speter	 For a REG (the only other possibility), the entire value is
1242018334Speter	 being replaced so the old value is not used in this insn.  */
1242118334Speter
1242218334Speter      if (GET_CODE (dest) == MEM)
1242350397Sobrien	move_deaths (XEXP (dest, 0), maybe_kill_insn, from_cuid,
1242450397Sobrien		     to_insn, pnotes);
1242518334Speter      return;
1242618334Speter    }
1242718334Speter
1242818334Speter  else if (GET_CODE (x) == CLOBBER)
1242918334Speter    return;
1243018334Speter
1243118334Speter  len = GET_RTX_LENGTH (code);
1243218334Speter  fmt = GET_RTX_FORMAT (code);
1243318334Speter
1243418334Speter  for (i = 0; i < len; i++)
1243518334Speter    {
1243618334Speter      if (fmt[i] == 'E')
1243718334Speter	{
1243890075Sobrien	  int j;
1243918334Speter	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1244050397Sobrien	    move_deaths (XVECEXP (x, i, j), maybe_kill_insn, from_cuid,
1244150397Sobrien			 to_insn, pnotes);
1244218334Speter	}
1244318334Speter      else if (fmt[i] == 'e')
1244450397Sobrien	move_deaths (XEXP (x, i), maybe_kill_insn, from_cuid, to_insn, pnotes);
1244518334Speter    }
1244618334Speter}
1244718334Speter
1244818334Speter/* Return 1 if X is the target of a bit-field assignment in BODY, the
1244918334Speter   pattern of an insn.  X must be a REG.  */
1245018334Speter
1245118334Speterstatic int
1245218334Speterreg_bitfield_target_p (x, body)
1245318334Speter     rtx x;
1245418334Speter     rtx body;
1245518334Speter{
1245618334Speter  int i;
1245718334Speter
1245818334Speter  if (GET_CODE (body) == SET)
1245918334Speter    {
1246018334Speter      rtx dest = SET_DEST (body);
1246118334Speter      rtx target;
1246290075Sobrien      unsigned int regno, tregno, endregno, endtregno;
1246318334Speter
1246418334Speter      if (GET_CODE (dest) == ZERO_EXTRACT)
1246518334Speter	target = XEXP (dest, 0);
1246618334Speter      else if (GET_CODE (dest) == STRICT_LOW_PART)
1246718334Speter	target = SUBREG_REG (XEXP (dest, 0));
1246818334Speter      else
1246918334Speter	return 0;
1247018334Speter
1247118334Speter      if (GET_CODE (target) == SUBREG)
1247218334Speter	target = SUBREG_REG (target);
1247318334Speter
1247418334Speter      if (GET_CODE (target) != REG)
1247518334Speter	return 0;
1247618334Speter
1247718334Speter      tregno = REGNO (target), regno = REGNO (x);
1247818334Speter      if (tregno >= FIRST_PSEUDO_REGISTER || regno >= FIRST_PSEUDO_REGISTER)
1247918334Speter	return target == x;
1248018334Speter
1248118334Speter      endtregno = tregno + HARD_REGNO_NREGS (tregno, GET_MODE (target));
1248218334Speter      endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
1248318334Speter
1248418334Speter      return endregno > tregno && regno < endtregno;
1248518334Speter    }
1248618334Speter
1248718334Speter  else if (GET_CODE (body) == PARALLEL)
1248818334Speter    for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
1248918334Speter      if (reg_bitfield_target_p (x, XVECEXP (body, 0, i)))
1249018334Speter	return 1;
1249118334Speter
1249218334Speter  return 0;
1249390075Sobrien}
1249418334Speter
1249518334Speter/* Given a chain of REG_NOTES originally from FROM_INSN, try to place them
1249618334Speter   as appropriate.  I3 and I2 are the insns resulting from the combination
1249718334Speter   insns including FROM (I2 may be zero).
1249818334Speter
1249918334Speter   ELIM_I2 and ELIM_I1 are either zero or registers that we know will
1250018334Speter   not need REG_DEAD notes because they are being substituted for.  This
1250118334Speter   saves searching in the most common cases.
1250218334Speter
1250318334Speter   Each note in the list is either ignored or placed on some insns, depending
1250418334Speter   on the type of note.  */
1250518334Speter
1250618334Speterstatic void
1250718334Speterdistribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
1250818334Speter     rtx notes;
1250918334Speter     rtx from_insn;
1251018334Speter     rtx i3, i2;
1251118334Speter     rtx elim_i2, elim_i1;
1251218334Speter{
1251318334Speter  rtx note, next_note;
1251418334Speter  rtx tem;
1251518334Speter
1251618334Speter  for (note = notes; note; note = next_note)
1251718334Speter    {
1251818334Speter      rtx place = 0, place2 = 0;
1251918334Speter
1252018334Speter      /* If this NOTE references a pseudo register, ensure it references
1252118334Speter	 the latest copy of that register.  */
1252218334Speter      if (XEXP (note, 0) && GET_CODE (XEXP (note, 0)) == REG
1252318334Speter	  && REGNO (XEXP (note, 0)) >= FIRST_PSEUDO_REGISTER)
1252418334Speter	XEXP (note, 0) = regno_reg_rtx[REGNO (XEXP (note, 0))];
1252518334Speter
1252618334Speter      next_note = XEXP (note, 1);
1252718334Speter      switch (REG_NOTE_KIND (note))
1252818334Speter	{
1252950397Sobrien	case REG_BR_PROB:
1253090075Sobrien	case REG_BR_PRED:
1253150397Sobrien	  /* Doesn't matter much where we put this, as long as it's somewhere.
1253250397Sobrien	     It is preferable to keep these notes on branches, which is most
1253350397Sobrien	     likely to be i3.  */
1253450397Sobrien	  place = i3;
1253550397Sobrien	  break;
1253650397Sobrien
1253790075Sobrien	case REG_VTABLE_REF:
1253890075Sobrien	  /* ??? Should remain with *a particular* memory load.  Given the
1253990075Sobrien	     nature of vtable data, the last insn seems relatively safe.  */
1254090075Sobrien	  place = i3;
1254190075Sobrien	  break;
1254290075Sobrien
1254390075Sobrien	case REG_NON_LOCAL_GOTO:
1254490075Sobrien	  if (GET_CODE (i3) == JUMP_INSN)
1254590075Sobrien	    place = i3;
1254690075Sobrien	  else if (i2 && GET_CODE (i2) == JUMP_INSN)
1254790075Sobrien	    place = i2;
1254890075Sobrien	  else
1254990075Sobrien	    abort ();
1255090075Sobrien	  break;
1255190075Sobrien
1255252284Sobrien	case REG_EH_REGION:
1255390075Sobrien	  /* These notes must remain with the call or trapping instruction.  */
1255490075Sobrien	  if (GET_CODE (i3) == CALL_INSN)
1255552284Sobrien	    place = i3;
1255652284Sobrien	  else if (i2 && GET_CODE (i2) == CALL_INSN)
1255752284Sobrien	    place = i2;
1255890075Sobrien	  else if (flag_non_call_exceptions)
1255990075Sobrien	    {
1256090075Sobrien	      if (may_trap_p (i3))
1256190075Sobrien		place = i3;
1256290075Sobrien	      else if (i2 && may_trap_p (i2))
1256390075Sobrien		place = i2;
1256490075Sobrien	      /* ??? Otherwise assume we've combined things such that we
1256590075Sobrien		 can now prove that the instructions can't trap.  Drop the
1256690075Sobrien		 note in this case.  */
1256790075Sobrien	    }
1256852284Sobrien	  else
1256952284Sobrien	    abort ();
1257052284Sobrien	  break;
1257152284Sobrien
1257290075Sobrien	case REG_NORETURN:
1257390075Sobrien	case REG_SETJMP:
1257490075Sobrien	  /* These notes must remain with the call.  It should not be
1257590075Sobrien	     possible for both I2 and I3 to be a call.  */
1257690075Sobrien	  if (GET_CODE (i3) == CALL_INSN)
1257790075Sobrien	    place = i3;
1257890075Sobrien	  else if (i2 && GET_CODE (i2) == CALL_INSN)
1257990075Sobrien	    place = i2;
1258090075Sobrien	  else
1258190075Sobrien	    abort ();
1258290075Sobrien	  break;
1258390075Sobrien
1258418334Speter	case REG_UNUSED:
1258518334Speter	  /* Any clobbers for i3 may still exist, and so we must process
1258618334Speter	     REG_UNUSED notes from that insn.
1258718334Speter
1258818334Speter	     Any clobbers from i2 or i1 can only exist if they were added by
1258918334Speter	     recog_for_combine.  In that case, recog_for_combine created the
1259018334Speter	     necessary REG_UNUSED notes.  Trying to keep any original
1259118334Speter	     REG_UNUSED notes from these insns can cause incorrect output
1259218334Speter	     if it is for the same register as the original i3 dest.
1259318334Speter	     In that case, we will notice that the register is set in i3,
1259418334Speter	     and then add a REG_UNUSED note for the destination of i3, which
1259518334Speter	     is wrong.  However, it is possible to have REG_UNUSED notes from
1259618334Speter	     i2 or i1 for register which were both used and clobbered, so
1259718334Speter	     we keep notes from i2 or i1 if they will turn into REG_DEAD
1259818334Speter	     notes.  */
1259918334Speter
1260018334Speter	  /* If this register is set or clobbered in I3, put the note there
1260118334Speter	     unless there is one already.  */
1260218334Speter	  if (reg_set_p (XEXP (note, 0), PATTERN (i3)))
1260318334Speter	    {
1260418334Speter	      if (from_insn != i3)
1260518334Speter		break;
1260618334Speter
1260718334Speter	      if (! (GET_CODE (XEXP (note, 0)) == REG
1260818334Speter		     ? find_regno_note (i3, REG_UNUSED, REGNO (XEXP (note, 0)))
1260918334Speter		     : find_reg_note (i3, REG_UNUSED, XEXP (note, 0))))
1261018334Speter		place = i3;
1261118334Speter	    }
1261218334Speter	  /* Otherwise, if this register is used by I3, then this register
1261318334Speter	     now dies here, so we must put a REG_DEAD note here unless there
1261418334Speter	     is one already.  */
1261518334Speter	  else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3))
1261618334Speter		   && ! (GET_CODE (XEXP (note, 0)) == REG
1261790075Sobrien			 ? find_regno_note (i3, REG_DEAD,
1261890075Sobrien					    REGNO (XEXP (note, 0)))
1261918334Speter			 : find_reg_note (i3, REG_DEAD, XEXP (note, 0))))
1262018334Speter	    {
1262118334Speter	      PUT_REG_NOTE_KIND (note, REG_DEAD);
1262218334Speter	      place = i3;
1262318334Speter	    }
1262418334Speter	  break;
1262518334Speter
1262618334Speter	case REG_EQUAL:
1262718334Speter	case REG_EQUIV:
1262850397Sobrien	case REG_NOALIAS:
1262918334Speter	  /* These notes say something about results of an insn.  We can
1263018334Speter	     only support them if they used to be on I3 in which case they
1263118334Speter	     remain on I3.  Otherwise they are ignored.
1263218334Speter
1263318334Speter	     If the note refers to an expression that is not a constant, we
1263418334Speter	     must also ignore the note since we cannot tell whether the
1263518334Speter	     equivalence is still true.  It might be possible to do
1263618334Speter	     slightly better than this (we only have a problem if I2DEST
1263718334Speter	     or I1DEST is present in the expression), but it doesn't
1263818334Speter	     seem worth the trouble.  */
1263918334Speter
1264018334Speter	  if (from_insn == i3
1264118334Speter	      && (XEXP (note, 0) == 0 || CONSTANT_P (XEXP (note, 0))))
1264218334Speter	    place = i3;
1264318334Speter	  break;
1264418334Speter
1264518334Speter	case REG_INC:
1264618334Speter	case REG_NO_CONFLICT:
1264718334Speter	  /* These notes say something about how a register is used.  They must
1264818334Speter	     be present on any use of the register in I2 or I3.  */
1264918334Speter	  if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3)))
1265018334Speter	    place = i3;
1265118334Speter
1265218334Speter	  if (i2 && reg_mentioned_p (XEXP (note, 0), PATTERN (i2)))
1265318334Speter	    {
1265418334Speter	      if (place)
1265518334Speter		place2 = i2;
1265618334Speter	      else
1265718334Speter		place = i2;
1265818334Speter	    }
1265918334Speter	  break;
1266018334Speter
1266152284Sobrien	case REG_LABEL:
1266252284Sobrien	  /* This can show up in several ways -- either directly in the
1266352284Sobrien	     pattern, or hidden off in the constant pool with (or without?)
1266452284Sobrien	     a REG_EQUAL note.  */
1266552284Sobrien	  /* ??? Ignore the without-reg_equal-note problem for now.  */
1266652284Sobrien	  if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3))
1266752284Sobrien	      || ((tem = find_reg_note (i3, REG_EQUAL, NULL_RTX))
1266852284Sobrien		  && GET_CODE (XEXP (tem, 0)) == LABEL_REF
1266952284Sobrien		  && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0)))
1267052284Sobrien	    place = i3;
1267152284Sobrien
1267252284Sobrien	  if (i2
1267352284Sobrien	      && (reg_mentioned_p (XEXP (note, 0), PATTERN (i2))
1267490075Sobrien		  || ((tem = find_reg_note (i2, REG_EQUAL, NULL_RTX))
1267552284Sobrien		      && GET_CODE (XEXP (tem, 0)) == LABEL_REF
1267652284Sobrien		      && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0))))
1267752284Sobrien	    {
1267852284Sobrien	      if (place)
1267952284Sobrien		place2 = i2;
1268052284Sobrien	      else
1268152284Sobrien		place = i2;
1268252284Sobrien	    }
1268390075Sobrien
1268490075Sobrien	  /* Don't attach REG_LABEL note to a JUMP_INSN which has
1268590075Sobrien	     JUMP_LABEL already.  Instead, decrement LABEL_NUSES.  */
1268690075Sobrien	  if (place && GET_CODE (place) == JUMP_INSN && JUMP_LABEL (place))
1268790075Sobrien	    {
1268890075Sobrien	      if (JUMP_LABEL (place) != XEXP (note, 0))
1268990075Sobrien		abort ();
1269090075Sobrien	      if (GET_CODE (JUMP_LABEL (place)) == CODE_LABEL)
1269190075Sobrien		LABEL_NUSES (JUMP_LABEL (place))--;
1269290075Sobrien	      place = 0;
1269390075Sobrien	    }
1269490075Sobrien	  if (place2 && GET_CODE (place2) == JUMP_INSN && JUMP_LABEL (place2))
1269590075Sobrien	    {
1269690075Sobrien	      if (JUMP_LABEL (place2) != XEXP (note, 0))
1269790075Sobrien		abort ();
1269890075Sobrien	      if (GET_CODE (JUMP_LABEL (place2)) == CODE_LABEL)
1269990075Sobrien		LABEL_NUSES (JUMP_LABEL (place2))--;
1270090075Sobrien	      place2 = 0;
1270190075Sobrien	    }
1270252284Sobrien	  break;
1270352284Sobrien
1270490075Sobrien	case REG_NONNEG:
1270518334Speter	case REG_WAS_0:
1270690075Sobrien	  /* These notes say something about the value of a register prior
1270790075Sobrien	     to the execution of an insn.  It is too much trouble to see
1270890075Sobrien	     if the note is still correct in all situations.  It is better
1270990075Sobrien	     to simply delete it.  */
1271018334Speter	  break;
1271118334Speter
1271218334Speter	case REG_RETVAL:
1271318334Speter	  /* If the insn previously containing this note still exists,
1271418334Speter	     put it back where it was.  Otherwise move it to the previous
1271518334Speter	     insn.  Adjust the corresponding REG_LIBCALL note.  */
1271618334Speter	  if (GET_CODE (from_insn) != NOTE)
1271718334Speter	    place = from_insn;
1271818334Speter	  else
1271918334Speter	    {
1272018334Speter	      tem = find_reg_note (XEXP (note, 0), REG_LIBCALL, NULL_RTX);
1272118334Speter	      place = prev_real_insn (from_insn);
1272218334Speter	      if (tem && place)
1272318334Speter		XEXP (tem, 0) = place;
1272490075Sobrien	      /* If we're deleting the last remaining instruction of a
1272590075Sobrien		 libcall sequence, don't add the notes.  */
1272690075Sobrien	      else if (XEXP (note, 0) == from_insn)
1272790075Sobrien		tem = place = 0;
1272818334Speter	    }
1272918334Speter	  break;
1273018334Speter
1273118334Speter	case REG_LIBCALL:
1273218334Speter	  /* This is handled similarly to REG_RETVAL.  */
1273318334Speter	  if (GET_CODE (from_insn) != NOTE)
1273418334Speter	    place = from_insn;
1273518334Speter	  else
1273618334Speter	    {
1273718334Speter	      tem = find_reg_note (XEXP (note, 0), REG_RETVAL, NULL_RTX);
1273818334Speter	      place = next_real_insn (from_insn);
1273918334Speter	      if (tem && place)
1274018334Speter		XEXP (tem, 0) = place;
1274190075Sobrien	      /* If we're deleting the last remaining instruction of a
1274290075Sobrien		 libcall sequence, don't add the notes.  */
1274390075Sobrien	      else if (XEXP (note, 0) == from_insn)
1274490075Sobrien		tem = place = 0;
1274518334Speter	    }
1274618334Speter	  break;
1274718334Speter
1274818334Speter	case REG_DEAD:
1274918334Speter	  /* If the register is used as an input in I3, it dies there.
12750117395Skan	     Similarly for I2, if it is nonzero and adjacent to I3.
1275118334Speter
1275218334Speter	     If the register is not used as an input in either I3 or I2
1275318334Speter	     and it is not one of the registers we were supposed to eliminate,
1275418334Speter	     there are two possibilities.  We might have a non-adjacent I2
1275518334Speter	     or we might have somehow eliminated an additional register
1275618334Speter	     from a computation.  For example, we might have had A & B where
1275718334Speter	     we discover that B will always be zero.  In this case we will
1275818334Speter	     eliminate the reference to A.
1275918334Speter
1276018334Speter	     In both cases, we must search to see if we can find a previous
1276118334Speter	     use of A and put the death note there.  */
1276218334Speter
1276318334Speter	  if (from_insn
1276418334Speter	      && GET_CODE (from_insn) == CALL_INSN
1276590075Sobrien	      && find_reg_fusage (from_insn, USE, XEXP (note, 0)))
1276618334Speter	    place = from_insn;
1276718334Speter	  else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)))
1276818334Speter	    place = i3;
1276918334Speter	  else if (i2 != 0 && next_nonnote_insn (i2) == i3
1277018334Speter		   && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
1277118334Speter	    place = i2;
1277218334Speter
1277390075Sobrien	  if (rtx_equal_p (XEXP (note, 0), elim_i2)
1277490075Sobrien	      || rtx_equal_p (XEXP (note, 0), elim_i1))
1277518334Speter	    break;
1277618334Speter
1277718334Speter	  if (place == 0)
1277818334Speter	    {
12779117395Skan	      basic_block bb = this_basic_block;
1278090075Sobrien
1278190075Sobrien	      for (tem = PREV_INSN (i3); place == 0; tem = PREV_INSN (tem))
1278218334Speter		{
1278390075Sobrien		  if (! INSN_P (tem))
1278490075Sobrien		    {
1278590075Sobrien		      if (tem == bb->head)
1278690075Sobrien			break;
1278790075Sobrien		      continue;
1278890075Sobrien		    }
1278990075Sobrien
1279018334Speter		  /* If the register is being set at TEM, see if that is all
1279118334Speter		     TEM is doing.  If so, delete TEM.  Otherwise, make this
1279218334Speter		     into a REG_UNUSED note instead.  */
1279318334Speter		  if (reg_set_p (XEXP (note, 0), PATTERN (tem)))
1279418334Speter		    {
1279518334Speter		      rtx set = single_set (tem);
1279650397Sobrien		      rtx inner_dest = 0;
1279752284Sobrien#ifdef HAVE_cc0
1279852284Sobrien		      rtx cc0_setter = NULL_RTX;
1279952284Sobrien#endif
1280018334Speter
1280150397Sobrien		      if (set != 0)
1280250397Sobrien			for (inner_dest = SET_DEST (set);
1280390075Sobrien			     (GET_CODE (inner_dest) == STRICT_LOW_PART
1280490075Sobrien			      || GET_CODE (inner_dest) == SUBREG
1280590075Sobrien			      || GET_CODE (inner_dest) == ZERO_EXTRACT);
1280650397Sobrien			     inner_dest = XEXP (inner_dest, 0))
1280750397Sobrien			  ;
1280850397Sobrien
1280918334Speter		      /* Verify that it was the set, and not a clobber that
1281090075Sobrien			 modified the register.
1281118334Speter
1281252284Sobrien			 CC0 targets must be careful to maintain setter/user
1281352284Sobrien			 pairs.  If we cannot delete the setter due to side
1281452284Sobrien			 effects, mark the user with an UNUSED note instead
1281552284Sobrien			 of deleting it.  */
1281652284Sobrien
1281718334Speter		      if (set != 0 && ! side_effects_p (SET_SRC (set))
1281852284Sobrien			  && rtx_equal_p (XEXP (note, 0), inner_dest)
1281952284Sobrien#ifdef HAVE_cc0
1282052284Sobrien			  && (! reg_mentioned_p (cc0_rtx, SET_SRC (set))
1282152284Sobrien			      || ((cc0_setter = prev_cc0_setter (tem)) != NULL
1282252284Sobrien				  && sets_cc0_p (PATTERN (cc0_setter)) > 0))
1282352284Sobrien#endif
1282452284Sobrien			  )
1282518334Speter			{
1282618334Speter			  /* Move the notes and links of TEM elsewhere.
1282790075Sobrien			     This might delete other dead insns recursively.
1282818334Speter			     First set the pattern to something that won't use
1282918334Speter			     any register.  */
1283018334Speter
1283118334Speter			  PATTERN (tem) = pc_rtx;
1283218334Speter
1283318334Speter			  distribute_notes (REG_NOTES (tem), tem, tem,
1283418334Speter					    NULL_RTX, NULL_RTX, NULL_RTX);
1283518334Speter			  distribute_links (LOG_LINKS (tem));
1283618334Speter
1283718334Speter			  PUT_CODE (tem, NOTE);
1283818334Speter			  NOTE_LINE_NUMBER (tem) = NOTE_INSN_DELETED;
1283918334Speter			  NOTE_SOURCE_FILE (tem) = 0;
1284052284Sobrien
1284152284Sobrien#ifdef HAVE_cc0
1284252284Sobrien			  /* Delete the setter too.  */
1284352284Sobrien			  if (cc0_setter)
1284452284Sobrien			    {
1284552284Sobrien			      PATTERN (cc0_setter) = pc_rtx;
1284652284Sobrien
1284752284Sobrien			      distribute_notes (REG_NOTES (cc0_setter),
1284852284Sobrien						cc0_setter, cc0_setter,
1284952284Sobrien						NULL_RTX, NULL_RTX, NULL_RTX);
1285052284Sobrien			      distribute_links (LOG_LINKS (cc0_setter));
1285152284Sobrien
1285252284Sobrien			      PUT_CODE (cc0_setter, NOTE);
1285390075Sobrien			      NOTE_LINE_NUMBER (cc0_setter)
1285490075Sobrien				= NOTE_INSN_DELETED;
1285552284Sobrien			      NOTE_SOURCE_FILE (cc0_setter) = 0;
1285652284Sobrien			    }
1285752284Sobrien#endif
1285818334Speter			}
1285950397Sobrien		      /* If the register is both set and used here, put the
1286050397Sobrien			 REG_DEAD note here, but place a REG_UNUSED note
1286150397Sobrien			 here too unless there already is one.  */
1286250397Sobrien		      else if (reg_referenced_p (XEXP (note, 0),
1286350397Sobrien						 PATTERN (tem)))
1286450397Sobrien			{
1286550397Sobrien			  place = tem;
1286650397Sobrien
1286750397Sobrien			  if (! find_regno_note (tem, REG_UNUSED,
1286850397Sobrien						 REGNO (XEXP (note, 0))))
1286950397Sobrien			    REG_NOTES (tem)
1287090075Sobrien			      = gen_rtx_EXPR_LIST (REG_UNUSED, XEXP (note, 0),
1287150397Sobrien						   REG_NOTES (tem));
1287250397Sobrien			}
1287318334Speter		      else
1287418334Speter			{
1287518334Speter			  PUT_REG_NOTE_KIND (note, REG_UNUSED);
1287690075Sobrien
1287718334Speter			  /*  If there isn't already a REG_UNUSED note, put one
1287818334Speter			      here.  */
1287918334Speter			  if (! find_regno_note (tem, REG_UNUSED,
1288018334Speter						 REGNO (XEXP (note, 0))))
1288118334Speter			    place = tem;
1288218334Speter			  break;
1288390075Sobrien			}
1288490075Sobrien		    }
1288590075Sobrien		  else if (reg_referenced_p (XEXP (note, 0), PATTERN (tem))
1288690075Sobrien			   || (GET_CODE (tem) == CALL_INSN
1288790075Sobrien			       && find_reg_fusage (tem, USE, XEXP (note, 0))))
1288890075Sobrien		    {
1288990075Sobrien		      place = tem;
1289018334Speter
1289190075Sobrien		      /* If we are doing a 3->2 combination, and we have a
1289290075Sobrien			 register which formerly died in i3 and was not used
1289390075Sobrien			 by i2, which now no longer dies in i3 and is used in
1289490075Sobrien			 i2 but does not die in i2, and place is between i2
1289590075Sobrien			 and i3, then we may need to move a link from place to
1289690075Sobrien			 i2.  */
1289790075Sobrien		      if (i2 && INSN_UID (place) <= max_uid_cuid
1289890075Sobrien			  && INSN_CUID (place) > INSN_CUID (i2)
1289990075Sobrien			  && from_insn
1290090075Sobrien			  && INSN_CUID (from_insn) > INSN_CUID (i2)
1290190075Sobrien			  && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
1290290075Sobrien			{
1290390075Sobrien			  rtx links = LOG_LINKS (place);
1290490075Sobrien			  LOG_LINKS (place) = 0;
1290590075Sobrien			  distribute_links (links);
1290690075Sobrien			}
1290790075Sobrien		      break;
1290890075Sobrien		    }
1290990075Sobrien
1291090075Sobrien		  if (tem == bb->head)
1291118334Speter		    break;
1291218334Speter		}
1291390075Sobrien
1291490075Sobrien	      /* We haven't found an insn for the death note and it
1291590075Sobrien		 is still a REG_DEAD note, but we have hit the beginning
1291690075Sobrien		 of the block.  If the existing life info says the reg
1291790075Sobrien		 was dead, there's nothing left to do.  Otherwise, we'll
1291890075Sobrien		 need to do a global life update after combine.  */
1291990075Sobrien	      if (REG_NOTE_KIND (note) == REG_DEAD && place == 0
1292090075Sobrien		  && REGNO_REG_SET_P (bb->global_live_at_start,
1292190075Sobrien				      REGNO (XEXP (note, 0))))
1292218334Speter		{
12923117395Skan		  SET_BIT (refresh_blocks, this_basic_block->index);
1292490075Sobrien		  need_refresh = 1;
1292518334Speter		}
1292618334Speter	    }
1292718334Speter
1292818334Speter	  /* If the register is set or already dead at PLACE, we needn't do
1292950397Sobrien	     anything with this note if it is still a REG_DEAD note.
1293050397Sobrien	     We can here if it is set at all, not if is it totally replace,
1293150397Sobrien	     which is what `dead_or_set_p' checks, so also check for it being
1293250397Sobrien	     set partially.  */
1293318334Speter
1293418334Speter	  if (place && REG_NOTE_KIND (note) == REG_DEAD)
1293518334Speter	    {
1293690075Sobrien	      unsigned int regno = REGNO (XEXP (note, 0));
1293718334Speter
1293890075Sobrien	      /* Similarly, if the instruction on which we want to place
1293990075Sobrien		 the note is a noop, we'll need do a global live update
1294090075Sobrien		 after we remove them in delete_noop_moves.  */
1294190075Sobrien	      if (noop_move_p (place))
1294290075Sobrien		{
12943117395Skan		  SET_BIT (refresh_blocks, this_basic_block->index);
1294490075Sobrien		  need_refresh = 1;
1294590075Sobrien		}
1294690075Sobrien
1294718334Speter	      if (dead_or_set_p (place, XEXP (note, 0))
1294818334Speter		  || reg_bitfield_target_p (XEXP (note, 0), PATTERN (place)))
1294918334Speter		{
1295018334Speter		  /* Unless the register previously died in PLACE, clear
1295118334Speter		     reg_last_death.  [I no longer understand why this is
1295218334Speter		     being done.] */
1295318334Speter		  if (reg_last_death[regno] != place)
1295418334Speter		    reg_last_death[regno] = 0;
1295518334Speter		  place = 0;
1295618334Speter		}
1295718334Speter	      else
1295818334Speter		reg_last_death[regno] = place;
1295918334Speter
1296018334Speter	      /* If this is a death note for a hard reg that is occupying
1296118334Speter		 multiple registers, ensure that we are still using all
1296218334Speter		 parts of the object.  If we find a piece of the object
1296390075Sobrien		 that is unused, we must arrange for an appropriate REG_DEAD
1296490075Sobrien		 note to be added for it.  However, we can't just emit a USE
1296590075Sobrien		 and tag the note to it, since the register might actually
1296690075Sobrien		 be dead; so we recourse, and the recursive call then finds
1296790075Sobrien		 the previous insn that used this register.  */
1296818334Speter
1296918334Speter	      if (place && regno < FIRST_PSEUDO_REGISTER
1297018334Speter		  && HARD_REGNO_NREGS (regno, GET_MODE (XEXP (note, 0))) > 1)
1297118334Speter		{
1297290075Sobrien		  unsigned int endregno
1297318334Speter		    = regno + HARD_REGNO_NREGS (regno,
1297418334Speter						GET_MODE (XEXP (note, 0)));
1297518334Speter		  int all_used = 1;
1297690075Sobrien		  unsigned int i;
1297718334Speter
1297818334Speter		  for (i = regno; i < endregno; i++)
1297990075Sobrien		    if ((! refers_to_regno_p (i, i + 1, PATTERN (place), 0)
1298090075Sobrien			 && ! find_regno_fusage (place, USE, i))
1298190075Sobrien			|| dead_or_set_regno_p (place, i))
1298290075Sobrien		      all_used = 0;
1298318334Speter
1298418334Speter		  if (! all_used)
1298518334Speter		    {
1298618334Speter		      /* Put only REG_DEAD notes for pieces that are
1298790075Sobrien			 not already dead or set.  */
1298818334Speter
1298990075Sobrien		      for (i = regno; i < endregno;
1299090075Sobrien			   i += HARD_REGNO_NREGS (i, reg_raw_mode[i]))
1299118334Speter			{
12992117395Skan			  rtx piece = regno_reg_rtx[i];
12993117395Skan			  basic_block bb = this_basic_block;
1299418334Speter
1299590075Sobrien			  if (! dead_or_set_p (place, piece)
1299618334Speter			      && ! reg_bitfield_target_p (piece,
1299718334Speter							  PATTERN (place)))
1299890075Sobrien			    {
1299990075Sobrien			      rtx new_note
1300090075Sobrien				= gen_rtx_EXPR_LIST (REG_DEAD, piece, NULL_RTX);
1300190075Sobrien
1300290075Sobrien			      distribute_notes (new_note, place, place,
1300390075Sobrien						NULL_RTX, NULL_RTX, NULL_RTX);
1300490075Sobrien			    }
1300590075Sobrien			  else if (! refers_to_regno_p (i, i + 1,
1300690075Sobrien							PATTERN (place), 0)
1300790075Sobrien				   && ! find_regno_fusage (place, USE, i))
1300890075Sobrien			    for (tem = PREV_INSN (place); ;
1300990075Sobrien				 tem = PREV_INSN (tem))
1301090075Sobrien			      {
1301190075Sobrien				if (! INSN_P (tem))
1301290075Sobrien				  {
1301390075Sobrien				    if (tem == bb->head)
1301490075Sobrien				      {
1301590075Sobrien					SET_BIT (refresh_blocks,
13016117395Skan						 this_basic_block->index);
1301790075Sobrien					need_refresh = 1;
1301890075Sobrien					break;
1301990075Sobrien				      }
1302090075Sobrien				    continue;
1302190075Sobrien				  }
1302290075Sobrien				if (dead_or_set_p (tem, piece)
1302390075Sobrien				    || reg_bitfield_target_p (piece,
1302490075Sobrien							      PATTERN (tem)))
1302590075Sobrien				  {
1302690075Sobrien				    REG_NOTES (tem)
1302790075Sobrien				      = gen_rtx_EXPR_LIST (REG_UNUSED, piece,
1302890075Sobrien							   REG_NOTES (tem));
1302990075Sobrien				    break;
1303090075Sobrien				  }
1303190075Sobrien			      }
1303290075Sobrien
1303318334Speter			}
1303418334Speter
1303518334Speter		      place = 0;
1303618334Speter		    }
1303718334Speter		}
1303818334Speter	    }
1303918334Speter	  break;
1304018334Speter
1304118334Speter	default:
1304218334Speter	  /* Any other notes should not be present at this point in the
1304318334Speter	     compilation.  */
1304418334Speter	  abort ();
1304518334Speter	}
1304618334Speter
1304718334Speter      if (place)
1304818334Speter	{
1304918334Speter	  XEXP (note, 1) = REG_NOTES (place);
1305018334Speter	  REG_NOTES (place) = note;
1305118334Speter	}
1305218334Speter      else if ((REG_NOTE_KIND (note) == REG_DEAD
1305318334Speter		|| REG_NOTE_KIND (note) == REG_UNUSED)
1305418334Speter	       && GET_CODE (XEXP (note, 0)) == REG)
1305550397Sobrien	REG_N_DEATHS (REGNO (XEXP (note, 0)))--;
1305618334Speter
1305718334Speter      if (place2)
1305818334Speter	{
1305918334Speter	  if ((REG_NOTE_KIND (note) == REG_DEAD
1306018334Speter	       || REG_NOTE_KIND (note) == REG_UNUSED)
1306118334Speter	      && GET_CODE (XEXP (note, 0)) == REG)
1306250397Sobrien	    REG_N_DEATHS (REGNO (XEXP (note, 0)))++;
1306318334Speter
1306450397Sobrien	  REG_NOTES (place2) = gen_rtx_fmt_ee (GET_CODE (note),
1306550397Sobrien					       REG_NOTE_KIND (note),
1306650397Sobrien					       XEXP (note, 0),
1306750397Sobrien					       REG_NOTES (place2));
1306818334Speter	}
1306918334Speter    }
1307018334Speter}
1307118334Speter
1307218334Speter/* Similarly to above, distribute the LOG_LINKS that used to be present on
1307318334Speter   I3, I2, and I1 to new locations.  This is also called in one case to
1307418334Speter   add a link pointing at I3 when I3's destination is changed.  */
1307518334Speter
1307618334Speterstatic void
1307718334Speterdistribute_links (links)
1307818334Speter     rtx links;
1307918334Speter{
1308018334Speter  rtx link, next_link;
1308118334Speter
1308218334Speter  for (link = links; link; link = next_link)
1308318334Speter    {
1308418334Speter      rtx place = 0;
1308518334Speter      rtx insn;
1308618334Speter      rtx set, reg;
1308718334Speter
1308818334Speter      next_link = XEXP (link, 1);
1308918334Speter
1309018334Speter      /* If the insn that this link points to is a NOTE or isn't a single
1309118334Speter	 set, ignore it.  In the latter case, it isn't clear what we
1309290075Sobrien	 can do other than ignore the link, since we can't tell which
1309318334Speter	 register it was for.  Such links wouldn't be used by combine
1309418334Speter	 anyway.
1309518334Speter
1309618334Speter	 It is not possible for the destination of the target of the link to
1309718334Speter	 have been changed by combine.  The only potential of this is if we
1309818334Speter	 replace I3, I2, and I1 by I3 and I2.  But in that case the
1309918334Speter	 destination of I2 also remains unchanged.  */
1310018334Speter
1310118334Speter      if (GET_CODE (XEXP (link, 0)) == NOTE
1310218334Speter	  || (set = single_set (XEXP (link, 0))) == 0)
1310318334Speter	continue;
1310418334Speter
1310518334Speter      reg = SET_DEST (set);
1310618334Speter      while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT
1310718334Speter	     || GET_CODE (reg) == SIGN_EXTRACT
1310818334Speter	     || GET_CODE (reg) == STRICT_LOW_PART)
1310918334Speter	reg = XEXP (reg, 0);
1311018334Speter
1311118334Speter      /* A LOG_LINK is defined as being placed on the first insn that uses
1311218334Speter	 a register and points to the insn that sets the register.  Start
1311318334Speter	 searching at the next insn after the target of the link and stop
1311418334Speter	 when we reach a set of the register or the end of the basic block.
1311518334Speter
1311618334Speter	 Note that this correctly handles the link that used to point from
1311718334Speter	 I3 to I2.  Also note that not much searching is typically done here
1311818334Speter	 since most links don't point very far away.  */
1311918334Speter
1312018334Speter      for (insn = NEXT_INSN (XEXP (link, 0));
13121117395Skan	   (insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR
13122117395Skan		     || this_basic_block->next_bb->head != insn));
1312318334Speter	   insn = NEXT_INSN (insn))
1312490075Sobrien	if (INSN_P (insn) && reg_overlap_mentioned_p (reg, PATTERN (insn)))
1312518334Speter	  {
1312618334Speter	    if (reg_referenced_p (reg, PATTERN (insn)))
1312718334Speter	      place = insn;
1312818334Speter	    break;
1312918334Speter	  }
1313018334Speter	else if (GET_CODE (insn) == CALL_INSN
1313190075Sobrien		 && find_reg_fusage (insn, USE, reg))
1313218334Speter	  {
1313318334Speter	    place = insn;
1313418334Speter	    break;
1313518334Speter	  }
1313618334Speter
1313718334Speter      /* If we found a place to put the link, place it there unless there
1313818334Speter	 is already a link to the same insn as LINK at that point.  */
1313918334Speter
1314018334Speter      if (place)
1314118334Speter	{
1314218334Speter	  rtx link2;
1314318334Speter
1314418334Speter	  for (link2 = LOG_LINKS (place); link2; link2 = XEXP (link2, 1))
1314518334Speter	    if (XEXP (link2, 0) == XEXP (link, 0))
1314618334Speter	      break;
1314718334Speter
1314818334Speter	  if (link2 == 0)
1314918334Speter	    {
1315018334Speter	      XEXP (link, 1) = LOG_LINKS (place);
1315118334Speter	      LOG_LINKS (place) = link;
1315218334Speter
1315318334Speter	      /* Set added_links_insn to the earliest insn we added a
1315418334Speter		 link to.  */
1315590075Sobrien	      if (added_links_insn == 0
1315618334Speter		  || INSN_CUID (added_links_insn) > INSN_CUID (place))
1315718334Speter		added_links_insn = place;
1315818334Speter	    }
1315918334Speter	}
1316018334Speter    }
1316118334Speter}
1316218334Speter
1316350397Sobrien/* Compute INSN_CUID for INSN, which is an insn made by combine.  */
1316450397Sobrien
1316550397Sobrienstatic int
1316650397Sobrieninsn_cuid (insn)
1316750397Sobrien     rtx insn;
1316850397Sobrien{
1316950397Sobrien  while (insn != 0 && INSN_UID (insn) > max_uid_cuid
1317050397Sobrien	 && GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == USE)
1317150397Sobrien    insn = NEXT_INSN (insn);
1317250397Sobrien
1317350397Sobrien  if (INSN_UID (insn) > max_uid_cuid)
1317450397Sobrien    abort ();
1317550397Sobrien
1317650397Sobrien  return INSN_CUID (insn);
1317750397Sobrien}
1317850397Sobrien
1317918334Spetervoid
1318018334Speterdump_combine_stats (file)
1318118334Speter     FILE *file;
1318218334Speter{
1318352284Sobrien  fnotice
1318418334Speter    (file,
1318518334Speter     ";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n",
1318618334Speter     combine_attempts, combine_merges, combine_extras, combine_successes);
1318718334Speter}
1318818334Speter
1318918334Spetervoid
1319018334Speterdump_combine_total_stats (file)
1319118334Speter     FILE *file;
1319218334Speter{
1319352284Sobrien  fnotice
1319418334Speter    (file,
1319518334Speter     "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n",
1319618334Speter     total_attempts, total_merges, total_extras, total_successes);
1319718334Speter}
13198