combine.c revision 52284
118334Speter/* Optimize by combining instructions for GNU compiler. 250397Sobrien Copyright (C) 1987, 88, 92-98, 1999 Free Software Foundation, Inc. 318334Speter 418334SpeterThis file is part of GNU CC. 518334Speter 618334SpeterGNU CC is free software; you can redistribute it and/or modify 718334Speterit under the terms of the GNU General Public License as published by 818334Speterthe Free Software Foundation; either version 2, or (at your option) 918334Speterany later version. 1018334Speter 1118334SpeterGNU CC is distributed in the hope that it will be useful, 1218334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of 1318334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1418334SpeterGNU General Public License for more details. 1518334Speter 1618334SpeterYou should have received a copy of the GNU General Public License 1718334Speteralong with GNU CC; see the file COPYING. If not, write to 1818334Speterthe Free Software Foundation, 59 Temple Place - Suite 330, 1918334SpeterBoston, MA 02111-1307, USA. */ 2018334Speter 2118334Speter 2218334Speter/* This module is essentially the "combiner" phase of the U. of Arizona 2318334Speter Portable Optimizer, but redone to work on our list-structured 2418334Speter representation for RTL instead of their string representation. 2518334Speter 2618334Speter The LOG_LINKS of each insn identify the most recent assignment 2718334Speter to each REG used in the insn. It is a list of previous insns, 2818334Speter each of which contains a SET for a REG that is used in this insn 2918334Speter and not used or set in between. LOG_LINKs never cross basic blocks. 3018334Speter They were set up by the preceding pass (lifetime analysis). 3118334Speter 3218334Speter We try to combine each pair of insns joined by a logical link. 3318334Speter We also try to combine triples of insns A, B and C when 3418334Speter C has a link back to B and B has a link back to A. 3518334Speter 3618334Speter LOG_LINKS does not have links for use of the CC0. They don't 3718334Speter need to, because the insn that sets the CC0 is always immediately 3818334Speter before the insn that tests it. So we always regard a branch 3918334Speter insn as having a logical link to the preceding insn. The same is true 4018334Speter for an insn explicitly using CC0. 4118334Speter 4218334Speter We check (with use_crosses_set_p) to avoid combining in such a way 4318334Speter as to move a computation to a place where its value would be different. 4418334Speter 4518334Speter Combination is done by mathematically substituting the previous 4618334Speter insn(s) values for the regs they set into the expressions in 4718334Speter the later insns that refer to these regs. If the result is a valid insn 4818334Speter for our target machine, according to the machine description, 4918334Speter we install it, delete the earlier insns, and update the data flow 5018334Speter information (LOG_LINKS and REG_NOTES) for what we did. 5118334Speter 5218334Speter There are a few exceptions where the dataflow information created by 5318334Speter flow.c aren't completely updated: 5418334Speter 5518334Speter - reg_live_length is not updated 5618334Speter - reg_n_refs is not adjusted in the rare case when a register is 5718334Speter no longer required in a computation 5818334Speter - there are extremely rare cases (see distribute_regnotes) when a 5918334Speter REG_DEAD note is lost 6018334Speter - a LOG_LINKS entry that refers to an insn with multiple SETs may be 6118334Speter removed because there is no way to know which register it was 6218334Speter linking 6318334Speter 6418334Speter To simplify substitution, we combine only when the earlier insn(s) 6518334Speter consist of only a single assignment. To simplify updating afterward, 6618334Speter we never combine when a subroutine call appears in the middle. 6718334Speter 6818334Speter Since we do not represent assignments to CC0 explicitly except when that 6918334Speter is all an insn does, there is no LOG_LINKS entry in an insn that uses 7018334Speter the condition code for the insn that set the condition code. 7118334Speter Fortunately, these two insns must be consecutive. 7218334Speter Therefore, every JUMP_INSN is taken to have an implicit logical link 7318334Speter to the preceding insn. This is not quite right, since non-jumps can 7418334Speter also use the condition code; but in practice such insns would not 7518334Speter combine anyway. */ 7618334Speter 7718334Speter#include "config.h" 7850397Sobrien#include "system.h" 7952284Sobrien#include "rtl.h" /* stdio.h must precede rtl.h for FFS. */ 8018334Speter#include "flags.h" 8118334Speter#include "regs.h" 8218334Speter#include "hard-reg-set.h" 8318334Speter#include "basic-block.h" 8418334Speter#include "insn-config.h" 8550397Sobrien/* Include expr.h after insn-config.h so we get HAVE_conditional_move. */ 8650397Sobrien#include "expr.h" 8718334Speter#include "insn-flags.h" 8818334Speter#include "insn-codes.h" 8918334Speter#include "insn-attr.h" 9018334Speter#include "recog.h" 9118334Speter#include "real.h" 9250397Sobrien#include "toplev.h" 9318334Speter 9418334Speter/* It is not safe to use ordinary gen_lowpart in combine. 9518334Speter Use gen_lowpart_for_combine instead. See comments there. */ 9618334Speter#define gen_lowpart dont_use_gen_lowpart_you_dummy 9718334Speter 9818334Speter/* Number of attempts to combine instructions in this function. */ 9918334Speter 10018334Speterstatic int combine_attempts; 10118334Speter 10218334Speter/* Number of attempts that got as far as substitution in this function. */ 10318334Speter 10418334Speterstatic int combine_merges; 10518334Speter 10618334Speter/* Number of instructions combined with added SETs in this function. */ 10718334Speter 10818334Speterstatic int combine_extras; 10918334Speter 11018334Speter/* Number of instructions combined in this function. */ 11118334Speter 11218334Speterstatic int combine_successes; 11318334Speter 11418334Speter/* Totals over entire compilation. */ 11518334Speter 11618334Speterstatic int total_attempts, total_merges, total_extras, total_successes; 11718334Speter 11818334Speter/* Define a default value for REVERSIBLE_CC_MODE. 11918334Speter We can never assume that a condition code mode is safe to reverse unless 12018334Speter the md tells us so. */ 12118334Speter#ifndef REVERSIBLE_CC_MODE 12218334Speter#define REVERSIBLE_CC_MODE(MODE) 0 12318334Speter#endif 12418334Speter 12518334Speter/* Vector mapping INSN_UIDs to cuids. 12618334Speter The cuids are like uids but increase monotonically always. 12718334Speter Combine always uses cuids so that it can compare them. 12818334Speter But actually renumbering the uids, which we used to do, 12918334Speter proves to be a bad idea because it makes it hard to compare 13018334Speter the dumps produced by earlier passes with those from later passes. */ 13118334Speter 13218334Speterstatic int *uid_cuid; 13318334Speterstatic int max_uid_cuid; 13418334Speter 13518334Speter/* Get the cuid of an insn. */ 13618334Speter 13750397Sobrien#define INSN_CUID(INSN) \ 13850397Sobrien(INSN_UID (INSN) > max_uid_cuid ? insn_cuid (INSN) : uid_cuid[INSN_UID (INSN)]) 13918334Speter 14018334Speter/* Maximum register number, which is the size of the tables below. */ 14118334Speter 14218334Speterstatic int combine_max_regno; 14318334Speter 14418334Speter/* Record last point of death of (hard or pseudo) register n. */ 14518334Speter 14618334Speterstatic rtx *reg_last_death; 14718334Speter 14818334Speter/* Record last point of modification of (hard or pseudo) register n. */ 14918334Speter 15018334Speterstatic rtx *reg_last_set; 15118334Speter 15218334Speter/* Record the cuid of the last insn that invalidated memory 15318334Speter (anything that writes memory, and subroutine calls, but not pushes). */ 15418334Speter 15518334Speterstatic int mem_last_set; 15618334Speter 15718334Speter/* Record the cuid of the last CALL_INSN 15818334Speter so we can tell whether a potential combination crosses any calls. */ 15918334Speter 16018334Speterstatic int last_call_cuid; 16118334Speter 16218334Speter/* When `subst' is called, this is the insn that is being modified 16318334Speter (by combining in a previous insn). The PATTERN of this insn 16418334Speter is still the old pattern partially modified and it should not be 16518334Speter looked at, but this may be used to examine the successors of the insn 16618334Speter to judge whether a simplification is valid. */ 16718334Speter 16818334Speterstatic rtx subst_insn; 16918334Speter 17018334Speter/* This is an insn that belongs before subst_insn, but is not currently 17118334Speter on the insn chain. */ 17218334Speter 17318334Speterstatic rtx subst_prev_insn; 17418334Speter 17518334Speter/* This is the lowest CUID that `subst' is currently dealing with. 17618334Speter get_last_value will not return a value if the register was set at or 17718334Speter after this CUID. If not for this mechanism, we could get confused if 17818334Speter I2 or I1 in try_combine were an insn that used the old value of a register 17918334Speter to obtain a new value. In that case, we might erroneously get the 18018334Speter new value of the register when we wanted the old one. */ 18118334Speter 18218334Speterstatic int subst_low_cuid; 18318334Speter 18418334Speter/* This contains any hard registers that are used in newpat; reg_dead_at_p 18518334Speter must consider all these registers to be always live. */ 18618334Speter 18718334Speterstatic HARD_REG_SET newpat_used_regs; 18818334Speter 18918334Speter/* This is an insn to which a LOG_LINKS entry has been added. If this 19018334Speter insn is the earlier than I2 or I3, combine should rescan starting at 19118334Speter that location. */ 19218334Speter 19318334Speterstatic rtx added_links_insn; 19418334Speter 19518334Speter/* Basic block number of the block in which we are performing combines. */ 19618334Speterstatic int this_basic_block; 19718334Speter 19818334Speter/* The next group of arrays allows the recording of the last value assigned 19918334Speter to (hard or pseudo) register n. We use this information to see if a 20018334Speter operation being processed is redundant given a prior operation performed 20118334Speter on the register. For example, an `and' with a constant is redundant if 20218334Speter all the zero bits are already known to be turned off. 20318334Speter 20418334Speter We use an approach similar to that used by cse, but change it in the 20518334Speter following ways: 20618334Speter 20718334Speter (1) We do not want to reinitialize at each label. 20818334Speter (2) It is useful, but not critical, to know the actual value assigned 20918334Speter to a register. Often just its form is helpful. 21018334Speter 21118334Speter Therefore, we maintain the following arrays: 21218334Speter 21318334Speter reg_last_set_value the last value assigned 21418334Speter reg_last_set_label records the value of label_tick when the 21518334Speter register was assigned 21618334Speter reg_last_set_table_tick records the value of label_tick when a 21718334Speter value using the register is assigned 21818334Speter reg_last_set_invalid set to non-zero when it is not valid 21918334Speter to use the value of this register in some 22018334Speter register's value 22118334Speter 22218334Speter To understand the usage of these tables, it is important to understand 22318334Speter the distinction between the value in reg_last_set_value being valid 22418334Speter and the register being validly contained in some other expression in the 22518334Speter table. 22618334Speter 22718334Speter Entry I in reg_last_set_value is valid if it is non-zero, and either 22818334Speter reg_n_sets[i] is 1 or reg_last_set_label[i] == label_tick. 22918334Speter 23018334Speter Register I may validly appear in any expression returned for the value 23118334Speter of another register if reg_n_sets[i] is 1. It may also appear in the 23218334Speter value for register J if reg_last_set_label[i] < reg_last_set_label[j] or 23318334Speter reg_last_set_invalid[j] is zero. 23418334Speter 23518334Speter If an expression is found in the table containing a register which may 23618334Speter not validly appear in an expression, the register is replaced by 23718334Speter something that won't match, (clobber (const_int 0)). 23818334Speter 23918334Speter reg_last_set_invalid[i] is set non-zero when register I is being assigned 24018334Speter to and reg_last_set_table_tick[i] == label_tick. */ 24118334Speter 24250397Sobrien/* Record last value assigned to (hard or pseudo) register n. */ 24318334Speter 24418334Speterstatic rtx *reg_last_set_value; 24518334Speter 24618334Speter/* Record the value of label_tick when the value for register n is placed in 24718334Speter reg_last_set_value[n]. */ 24818334Speter 24918334Speterstatic int *reg_last_set_label; 25018334Speter 25118334Speter/* Record the value of label_tick when an expression involving register n 25250397Sobrien is placed in reg_last_set_value. */ 25318334Speter 25418334Speterstatic int *reg_last_set_table_tick; 25518334Speter 25618334Speter/* Set non-zero if references to register n in expressions should not be 25718334Speter used. */ 25818334Speter 25918334Speterstatic char *reg_last_set_invalid; 26018334Speter 26150397Sobrien/* Incremented for each label. */ 26218334Speter 26318334Speterstatic int label_tick; 26418334Speter 26518334Speter/* Some registers that are set more than once and used in more than one 26618334Speter basic block are nevertheless always set in similar ways. For example, 26718334Speter a QImode register may be loaded from memory in two places on a machine 26818334Speter where byte loads zero extend. 26918334Speter 27018334Speter We record in the following array what we know about the nonzero 27118334Speter bits of a register, specifically which bits are known to be zero. 27218334Speter 27318334Speter If an entry is zero, it means that we don't know anything special. */ 27418334Speter 27518334Speterstatic unsigned HOST_WIDE_INT *reg_nonzero_bits; 27618334Speter 27718334Speter/* Mode used to compute significance in reg_nonzero_bits. It is the largest 27818334Speter integer mode that can fit in HOST_BITS_PER_WIDE_INT. */ 27918334Speter 28018334Speterstatic enum machine_mode nonzero_bits_mode; 28118334Speter 28218334Speter/* Nonzero if we know that a register has some leading bits that are always 28318334Speter equal to the sign bit. */ 28418334Speter 28518334Speterstatic char *reg_sign_bit_copies; 28618334Speter 28718334Speter/* Nonzero when reg_nonzero_bits and reg_sign_bit_copies can be safely used. 28818334Speter It is zero while computing them and after combine has completed. This 28918334Speter former test prevents propagating values based on previously set values, 29018334Speter which can be incorrect if a variable is modified in a loop. */ 29118334Speter 29218334Speterstatic int nonzero_sign_valid; 29318334Speter 29418334Speter/* These arrays are maintained in parallel with reg_last_set_value 29518334Speter and are used to store the mode in which the register was last set, 29618334Speter the bits that were known to be zero when it was last set, and the 29718334Speter number of sign bits copies it was known to have when it was last set. */ 29818334Speter 29918334Speterstatic enum machine_mode *reg_last_set_mode; 30018334Speterstatic unsigned HOST_WIDE_INT *reg_last_set_nonzero_bits; 30118334Speterstatic char *reg_last_set_sign_bit_copies; 30218334Speter 30318334Speter/* Record one modification to rtl structure 30418334Speter to be undone by storing old_contents into *where. 30518334Speter is_int is 1 if the contents are an int. */ 30618334Speter 30718334Speterstruct undo 30818334Speter{ 30950397Sobrien struct undo *next; 31018334Speter int is_int; 31118334Speter union {rtx r; int i;} old_contents; 31218334Speter union {rtx *r; int *i;} where; 31318334Speter}; 31418334Speter 31518334Speter/* Record a bunch of changes to be undone, up to MAX_UNDO of them. 31618334Speter num_undo says how many are currently recorded. 31718334Speter 31818334Speter storage is nonzero if we must undo the allocation of new storage. 31918334Speter The value of storage is what to pass to obfree. 32018334Speter 32118334Speter other_insn is nonzero if we have modified some other insn in the process 32250397Sobrien of working on subst_insn. It must be verified too. 32318334Speter 32450397Sobrien previous_undos is the value of undobuf.undos when we started processing 32550397Sobrien this substitution. This will prevent gen_rtx_combine from re-used a piece 32650397Sobrien from the previous expression. Doing so can produce circular rtl 32750397Sobrien structures. */ 32818334Speter 32918334Speterstruct undobuf 33018334Speter{ 33118334Speter char *storage; 33250397Sobrien struct undo *undos; 33350397Sobrien struct undo *frees; 33450397Sobrien struct undo *previous_undos; 33518334Speter rtx other_insn; 33618334Speter}; 33718334Speter 33818334Speterstatic struct undobuf undobuf; 33918334Speter 34018334Speter/* Substitute NEWVAL, an rtx expression, into INTO, a place in some 34118334Speter insn. The substitution can be undone by undo_all. If INTO is already 34218334Speter set to NEWVAL, do not record this change. Because computing NEWVAL might 34318334Speter also call SUBST, we have to compute it before we put anything into 34418334Speter the undo table. */ 34518334Speter 34618334Speter#define SUBST(INTO, NEWVAL) \ 34750397Sobrien do { rtx _new = (NEWVAL); \ 34850397Sobrien struct undo *_buf; \ 34950397Sobrien \ 35050397Sobrien if (undobuf.frees) \ 35150397Sobrien _buf = undobuf.frees, undobuf.frees = _buf->next; \ 35250397Sobrien else \ 35350397Sobrien _buf = (struct undo *) xmalloc (sizeof (struct undo)); \ 35450397Sobrien \ 35550397Sobrien _buf->is_int = 0; \ 35650397Sobrien _buf->where.r = &INTO; \ 35750397Sobrien _buf->old_contents.r = INTO; \ 35850397Sobrien INTO = _new; \ 35950397Sobrien if (_buf->old_contents.r == INTO) \ 36050397Sobrien _buf->next = undobuf.frees, undobuf.frees = _buf; \ 36150397Sobrien else \ 36250397Sobrien _buf->next = undobuf.undos, undobuf.undos = _buf; \ 36318334Speter } while (0) 36418334Speter 36550397Sobrien/* Similar to SUBST, but NEWVAL is an int expression. Note that substitution 36650397Sobrien for the value of a HOST_WIDE_INT value (including CONST_INT) is 36750397Sobrien not safe. */ 36818334Speter 36918334Speter#define SUBST_INT(INTO, NEWVAL) \ 37050397Sobrien do { struct undo *_buf; \ 37150397Sobrien \ 37250397Sobrien if (undobuf.frees) \ 37350397Sobrien _buf = undobuf.frees, undobuf.frees = _buf->next; \ 37450397Sobrien else \ 37550397Sobrien _buf = (struct undo *) xmalloc (sizeof (struct undo)); \ 37650397Sobrien \ 37750397Sobrien _buf->is_int = 1; \ 37850397Sobrien _buf->where.i = (int *) &INTO; \ 37950397Sobrien _buf->old_contents.i = INTO; \ 38050397Sobrien INTO = NEWVAL; \ 38150397Sobrien if (_buf->old_contents.i == INTO) \ 38250397Sobrien _buf->next = undobuf.frees, undobuf.frees = _buf; \ 38350397Sobrien else \ 38450397Sobrien _buf->next = undobuf.undos, undobuf.undos = _buf; \ 38518334Speter } while (0) 38618334Speter 38718334Speter/* Number of times the pseudo being substituted for 38818334Speter was found and replaced. */ 38918334Speter 39018334Speterstatic int n_occurrences; 39118334Speter 39250397Sobrienstatic void init_reg_last_arrays PROTO((void)); 39350397Sobrienstatic void setup_incoming_promotions PROTO((void)); 39418334Speterstatic void set_nonzero_bits_and_sign_copies PROTO((rtx, rtx)); 39518334Speterstatic int can_combine_p PROTO((rtx, rtx, rtx, rtx, rtx *, rtx *)); 39650397Sobrienstatic int sets_function_arg_p PROTO((rtx)); 39718334Speterstatic int combinable_i3pat PROTO((rtx, rtx *, rtx, rtx, int, rtx *)); 39818334Speterstatic rtx try_combine PROTO((rtx, rtx, rtx)); 39918334Speterstatic void undo_all PROTO((void)); 40018334Speterstatic rtx *find_split_point PROTO((rtx *, rtx)); 40118334Speterstatic rtx subst PROTO((rtx, rtx, rtx, int, int)); 40218334Speterstatic rtx simplify_rtx PROTO((rtx, enum machine_mode, int, int)); 40318334Speterstatic rtx simplify_if_then_else PROTO((rtx)); 40418334Speterstatic rtx simplify_set PROTO((rtx)); 40518334Speterstatic rtx simplify_logical PROTO((rtx, int)); 40618334Speterstatic rtx expand_compound_operation PROTO((rtx)); 40718334Speterstatic rtx expand_field_assignment PROTO((rtx)); 40818334Speterstatic rtx make_extraction PROTO((enum machine_mode, rtx, int, rtx, int, 40918334Speter int, int, int)); 41018334Speterstatic rtx extract_left_shift PROTO((rtx, int)); 41118334Speterstatic rtx make_compound_operation PROTO((rtx, enum rtx_code)); 41218334Speterstatic int get_pos_from_mask PROTO((unsigned HOST_WIDE_INT, int *)); 41318334Speterstatic rtx force_to_mode PROTO((rtx, enum machine_mode, 41418334Speter unsigned HOST_WIDE_INT, rtx, int)); 41518334Speterstatic rtx if_then_else_cond PROTO((rtx, rtx *, rtx *)); 41618334Speterstatic rtx known_cond PROTO((rtx, enum rtx_code, rtx, rtx)); 41750397Sobrienstatic int rtx_equal_for_field_assignment_p PROTO((rtx, rtx)); 41818334Speterstatic rtx make_field_assignment PROTO((rtx)); 41918334Speterstatic rtx apply_distributive_law PROTO((rtx)); 42018334Speterstatic rtx simplify_and_const_int PROTO((rtx, enum machine_mode, rtx, 42118334Speter unsigned HOST_WIDE_INT)); 42218334Speterstatic unsigned HOST_WIDE_INT nonzero_bits PROTO((rtx, enum machine_mode)); 42318334Speterstatic int num_sign_bit_copies PROTO((rtx, enum machine_mode)); 42418334Speterstatic int merge_outer_ops PROTO((enum rtx_code *, HOST_WIDE_INT *, 42518334Speter enum rtx_code, HOST_WIDE_INT, 42618334Speter enum machine_mode, int *)); 42718334Speterstatic rtx simplify_shift_const PROTO((rtx, enum rtx_code, enum machine_mode, 42818334Speter rtx, int)); 42952284Sobrienstatic int recog_for_combine PROTO((rtx *, rtx, rtx *)); 43018334Speterstatic rtx gen_lowpart_for_combine PROTO((enum machine_mode, rtx)); 43118334Speterstatic rtx gen_rtx_combine PVPROTO((enum rtx_code code, enum machine_mode mode, 43218334Speter ...)); 43318334Speterstatic rtx gen_binary PROTO((enum rtx_code, enum machine_mode, 43418334Speter rtx, rtx)); 43518334Speterstatic rtx gen_unary PROTO((enum rtx_code, enum machine_mode, 43618334Speter enum machine_mode, rtx)); 43718334Speterstatic enum rtx_code simplify_comparison PROTO((enum rtx_code, rtx *, rtx *)); 43818334Speterstatic int reversible_comparison_p PROTO((rtx)); 43918334Speterstatic void update_table_tick PROTO((rtx)); 44018334Speterstatic void record_value_for_reg PROTO((rtx, rtx, rtx)); 44118334Speterstatic void record_dead_and_set_regs_1 PROTO((rtx, rtx)); 44218334Speterstatic void record_dead_and_set_regs PROTO((rtx)); 44350397Sobrienstatic int get_last_value_validate PROTO((rtx *, rtx, int, int)); 44418334Speterstatic rtx get_last_value PROTO((rtx)); 44518334Speterstatic int use_crosses_set_p PROTO((rtx, int)); 44618334Speterstatic void reg_dead_at_p_1 PROTO((rtx, rtx)); 44718334Speterstatic int reg_dead_at_p PROTO((rtx, rtx)); 44850397Sobrienstatic void move_deaths PROTO((rtx, rtx, int, rtx, rtx *)); 44918334Speterstatic int reg_bitfield_target_p PROTO((rtx, rtx)); 45018334Speterstatic void distribute_notes PROTO((rtx, rtx, rtx, rtx, rtx, rtx)); 45118334Speterstatic void distribute_links PROTO((rtx)); 45218334Speterstatic void mark_used_regs_combine PROTO((rtx)); 45350397Sobrienstatic int insn_cuid PROTO((rtx)); 45418334Speter 45518334Speter/* Main entry point for combiner. F is the first insn of the function. 45618334Speter NREGS is the first unused pseudo-reg number. */ 45718334Speter 45818334Spetervoid 45918334Spetercombine_instructions (f, nregs) 46018334Speter rtx f; 46118334Speter int nregs; 46218334Speter{ 46350397Sobrien register rtx insn, next; 46450397Sobrien#ifdef HAVE_cc0 46550397Sobrien register rtx prev; 46650397Sobrien#endif 46718334Speter register int i; 46818334Speter register rtx links, nextlinks; 46918334Speter 47018334Speter combine_attempts = 0; 47118334Speter combine_merges = 0; 47218334Speter combine_extras = 0; 47318334Speter combine_successes = 0; 47450397Sobrien undobuf.undos = undobuf.previous_undos = 0; 47518334Speter 47618334Speter combine_max_regno = nregs; 47718334Speter 47818334Speter reg_nonzero_bits 47918334Speter = (unsigned HOST_WIDE_INT *) alloca (nregs * sizeof (HOST_WIDE_INT)); 48018334Speter reg_sign_bit_copies = (char *) alloca (nregs * sizeof (char)); 48118334Speter 48218334Speter bzero ((char *) reg_nonzero_bits, nregs * sizeof (HOST_WIDE_INT)); 48318334Speter bzero (reg_sign_bit_copies, nregs * sizeof (char)); 48418334Speter 48518334Speter reg_last_death = (rtx *) alloca (nregs * sizeof (rtx)); 48618334Speter reg_last_set = (rtx *) alloca (nregs * sizeof (rtx)); 48718334Speter reg_last_set_value = (rtx *) alloca (nregs * sizeof (rtx)); 48818334Speter reg_last_set_table_tick = (int *) alloca (nregs * sizeof (int)); 48918334Speter reg_last_set_label = (int *) alloca (nregs * sizeof (int)); 49018334Speter reg_last_set_invalid = (char *) alloca (nregs * sizeof (char)); 49118334Speter reg_last_set_mode 49218334Speter = (enum machine_mode *) alloca (nregs * sizeof (enum machine_mode)); 49318334Speter reg_last_set_nonzero_bits 49418334Speter = (unsigned HOST_WIDE_INT *) alloca (nregs * sizeof (HOST_WIDE_INT)); 49518334Speter reg_last_set_sign_bit_copies 49618334Speter = (char *) alloca (nregs * sizeof (char)); 49718334Speter 49818334Speter init_reg_last_arrays (); 49918334Speter 50018334Speter init_recog_no_volatile (); 50118334Speter 50218334Speter /* Compute maximum uid value so uid_cuid can be allocated. */ 50318334Speter 50418334Speter for (insn = f, i = 0; insn; insn = NEXT_INSN (insn)) 50518334Speter if (INSN_UID (insn) > i) 50618334Speter i = INSN_UID (insn); 50718334Speter 50818334Speter uid_cuid = (int *) alloca ((i + 1) * sizeof (int)); 50918334Speter max_uid_cuid = i; 51018334Speter 51118334Speter nonzero_bits_mode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0); 51218334Speter 51318334Speter /* Don't use reg_nonzero_bits when computing it. This can cause problems 51418334Speter when, for example, we have j <<= 1 in a loop. */ 51518334Speter 51618334Speter nonzero_sign_valid = 0; 51718334Speter 51818334Speter /* Compute the mapping from uids to cuids. 51918334Speter Cuids are numbers assigned to insns, like uids, 52018334Speter except that cuids increase monotonically through the code. 52118334Speter 52218334Speter Scan all SETs and see if we can deduce anything about what 52318334Speter bits are known to be zero for some registers and how many copies 52418334Speter of the sign bit are known to exist for those registers. 52518334Speter 52618334Speter Also set any known values so that we can use it while searching 52718334Speter for what bits are known to be set. */ 52818334Speter 52918334Speter label_tick = 1; 53018334Speter 53118334Speter /* We need to initialize it here, because record_dead_and_set_regs may call 53218334Speter get_last_value. */ 53318334Speter subst_prev_insn = NULL_RTX; 53418334Speter 53518334Speter setup_incoming_promotions (); 53618334Speter 53718334Speter for (insn = f, i = 0; insn; insn = NEXT_INSN (insn)) 53818334Speter { 53918334Speter uid_cuid[INSN_UID (insn)] = ++i; 54018334Speter subst_low_cuid = i; 54118334Speter subst_insn = insn; 54218334Speter 54318334Speter if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') 54418334Speter { 54518334Speter note_stores (PATTERN (insn), set_nonzero_bits_and_sign_copies); 54618334Speter record_dead_and_set_regs (insn); 54750397Sobrien 54850397Sobrien#ifdef AUTO_INC_DEC 54950397Sobrien for (links = REG_NOTES (insn); links; links = XEXP (links, 1)) 55050397Sobrien if (REG_NOTE_KIND (links) == REG_INC) 55150397Sobrien set_nonzero_bits_and_sign_copies (XEXP (links, 0), NULL_RTX); 55250397Sobrien#endif 55318334Speter } 55418334Speter 55518334Speter if (GET_CODE (insn) == CODE_LABEL) 55618334Speter label_tick++; 55718334Speter } 55818334Speter 55918334Speter nonzero_sign_valid = 1; 56018334Speter 56118334Speter /* Now scan all the insns in forward order. */ 56218334Speter 56318334Speter this_basic_block = -1; 56418334Speter label_tick = 1; 56518334Speter last_call_cuid = 0; 56618334Speter mem_last_set = 0; 56718334Speter init_reg_last_arrays (); 56818334Speter setup_incoming_promotions (); 56918334Speter 57018334Speter for (insn = f; insn; insn = next ? next : NEXT_INSN (insn)) 57118334Speter { 57218334Speter next = 0; 57318334Speter 57418334Speter /* If INSN starts a new basic block, update our basic block number. */ 57518334Speter if (this_basic_block + 1 < n_basic_blocks 57652284Sobrien && BLOCK_HEAD (this_basic_block + 1) == insn) 57718334Speter this_basic_block++; 57818334Speter 57918334Speter if (GET_CODE (insn) == CODE_LABEL) 58018334Speter label_tick++; 58118334Speter 58218334Speter else if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') 58318334Speter { 58418334Speter /* Try this insn with each insn it links back to. */ 58518334Speter 58618334Speter for (links = LOG_LINKS (insn); links; links = XEXP (links, 1)) 58718334Speter if ((next = try_combine (insn, XEXP (links, 0), NULL_RTX)) != 0) 58818334Speter goto retry; 58918334Speter 59018334Speter /* Try each sequence of three linked insns ending with this one. */ 59118334Speter 59218334Speter for (links = LOG_LINKS (insn); links; links = XEXP (links, 1)) 59318334Speter for (nextlinks = LOG_LINKS (XEXP (links, 0)); nextlinks; 59418334Speter nextlinks = XEXP (nextlinks, 1)) 59518334Speter if ((next = try_combine (insn, XEXP (links, 0), 59618334Speter XEXP (nextlinks, 0))) != 0) 59718334Speter goto retry; 59818334Speter 59918334Speter#ifdef HAVE_cc0 60018334Speter /* Try to combine a jump insn that uses CC0 60118334Speter with a preceding insn that sets CC0, and maybe with its 60218334Speter logical predecessor as well. 60318334Speter This is how we make decrement-and-branch insns. 60418334Speter We need this special code because data flow connections 60518334Speter via CC0 do not get entered in LOG_LINKS. */ 60618334Speter 60718334Speter if (GET_CODE (insn) == JUMP_INSN 60818334Speter && (prev = prev_nonnote_insn (insn)) != 0 60918334Speter && GET_CODE (prev) == INSN 61018334Speter && sets_cc0_p (PATTERN (prev))) 61118334Speter { 61218334Speter if ((next = try_combine (insn, prev, NULL_RTX)) != 0) 61318334Speter goto retry; 61418334Speter 61518334Speter for (nextlinks = LOG_LINKS (prev); nextlinks; 61618334Speter nextlinks = XEXP (nextlinks, 1)) 61718334Speter if ((next = try_combine (insn, prev, 61818334Speter XEXP (nextlinks, 0))) != 0) 61918334Speter goto retry; 62018334Speter } 62118334Speter 62218334Speter /* Do the same for an insn that explicitly references CC0. */ 62318334Speter if (GET_CODE (insn) == INSN 62418334Speter && (prev = prev_nonnote_insn (insn)) != 0 62518334Speter && GET_CODE (prev) == INSN 62618334Speter && sets_cc0_p (PATTERN (prev)) 62718334Speter && GET_CODE (PATTERN (insn)) == SET 62818334Speter && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (insn)))) 62918334Speter { 63018334Speter if ((next = try_combine (insn, prev, NULL_RTX)) != 0) 63118334Speter goto retry; 63218334Speter 63318334Speter for (nextlinks = LOG_LINKS (prev); nextlinks; 63418334Speter nextlinks = XEXP (nextlinks, 1)) 63518334Speter if ((next = try_combine (insn, prev, 63618334Speter XEXP (nextlinks, 0))) != 0) 63718334Speter goto retry; 63818334Speter } 63918334Speter 64018334Speter /* Finally, see if any of the insns that this insn links to 64118334Speter explicitly references CC0. If so, try this insn, that insn, 64218334Speter and its predecessor if it sets CC0. */ 64318334Speter for (links = LOG_LINKS (insn); links; links = XEXP (links, 1)) 64418334Speter if (GET_CODE (XEXP (links, 0)) == INSN 64518334Speter && GET_CODE (PATTERN (XEXP (links, 0))) == SET 64618334Speter && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (XEXP (links, 0)))) 64718334Speter && (prev = prev_nonnote_insn (XEXP (links, 0))) != 0 64818334Speter && GET_CODE (prev) == INSN 64918334Speter && sets_cc0_p (PATTERN (prev)) 65018334Speter && (next = try_combine (insn, XEXP (links, 0), prev)) != 0) 65118334Speter goto retry; 65218334Speter#endif 65318334Speter 65418334Speter /* Try combining an insn with two different insns whose results it 65518334Speter uses. */ 65618334Speter for (links = LOG_LINKS (insn); links; links = XEXP (links, 1)) 65718334Speter for (nextlinks = XEXP (links, 1); nextlinks; 65818334Speter nextlinks = XEXP (nextlinks, 1)) 65918334Speter if ((next = try_combine (insn, XEXP (links, 0), 66018334Speter XEXP (nextlinks, 0))) != 0) 66118334Speter goto retry; 66218334Speter 66318334Speter if (GET_CODE (insn) != NOTE) 66418334Speter record_dead_and_set_regs (insn); 66518334Speter 66618334Speter retry: 66718334Speter ; 66818334Speter } 66918334Speter } 67018334Speter 67118334Speter total_attempts += combine_attempts; 67218334Speter total_merges += combine_merges; 67318334Speter total_extras += combine_extras; 67418334Speter total_successes += combine_successes; 67518334Speter 67618334Speter nonzero_sign_valid = 0; 67752284Sobrien 67852284Sobrien /* Make recognizer allow volatile MEMs again. */ 67952284Sobrien init_recog (); 68018334Speter} 68118334Speter 68218334Speter/* Wipe the reg_last_xxx arrays in preparation for another pass. */ 68318334Speter 68418334Speterstatic void 68518334Speterinit_reg_last_arrays () 68618334Speter{ 68718334Speter int nregs = combine_max_regno; 68818334Speter 68918334Speter bzero ((char *) reg_last_death, nregs * sizeof (rtx)); 69018334Speter bzero ((char *) reg_last_set, nregs * sizeof (rtx)); 69118334Speter bzero ((char *) reg_last_set_value, nregs * sizeof (rtx)); 69218334Speter bzero ((char *) reg_last_set_table_tick, nregs * sizeof (int)); 69318334Speter bzero ((char *) reg_last_set_label, nregs * sizeof (int)); 69418334Speter bzero (reg_last_set_invalid, nregs * sizeof (char)); 69518334Speter bzero ((char *) reg_last_set_mode, nregs * sizeof (enum machine_mode)); 69618334Speter bzero ((char *) reg_last_set_nonzero_bits, nregs * sizeof (HOST_WIDE_INT)); 69718334Speter bzero (reg_last_set_sign_bit_copies, nregs * sizeof (char)); 69818334Speter} 69918334Speter 70018334Speter/* Set up any promoted values for incoming argument registers. */ 70118334Speter 70218334Speterstatic void 70318334Spetersetup_incoming_promotions () 70418334Speter{ 70518334Speter#ifdef PROMOTE_FUNCTION_ARGS 70618334Speter int regno; 70718334Speter rtx reg; 70818334Speter enum machine_mode mode; 70918334Speter int unsignedp; 71018334Speter rtx first = get_insns (); 71118334Speter 71218334Speter for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 71318334Speter if (FUNCTION_ARG_REGNO_P (regno) 71418334Speter && (reg = promoted_input_arg (regno, &mode, &unsignedp)) != 0) 71550397Sobrien { 71650397Sobrien record_value_for_reg 71750397Sobrien (reg, first, gen_rtx_fmt_e ((unsignedp ? ZERO_EXTEND 71850397Sobrien : SIGN_EXTEND), 71950397Sobrien GET_MODE (reg), 72050397Sobrien gen_rtx_CLOBBER (mode, const0_rtx))); 72150397Sobrien } 72218334Speter#endif 72318334Speter} 72418334Speter 72550397Sobrien/* Called via note_stores. If X is a pseudo that is narrower than 72650397Sobrien HOST_BITS_PER_WIDE_INT and is being set, record what bits are known zero. 72718334Speter 72818334Speter If we are setting only a portion of X and we can't figure out what 72918334Speter portion, assume all bits will be used since we don't know what will 73018334Speter be happening. 73118334Speter 73218334Speter Similarly, set how many bits of X are known to be copies of the sign bit 73318334Speter at all locations in the function. This is the smallest number implied 73418334Speter by any set of X. */ 73518334Speter 73618334Speterstatic void 73718334Speterset_nonzero_bits_and_sign_copies (x, set) 73818334Speter rtx x; 73918334Speter rtx set; 74018334Speter{ 74118334Speter int num; 74218334Speter 74318334Speter if (GET_CODE (x) == REG 74418334Speter && REGNO (x) >= FIRST_PSEUDO_REGISTER 74518334Speter /* If this register is undefined at the start of the file, we can't 74618334Speter say what its contents were. */ 74752284Sobrien && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, REGNO (x)) 74818334Speter && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT) 74918334Speter { 75050397Sobrien if (set == 0 || GET_CODE (set) == CLOBBER) 75118334Speter { 75218334Speter reg_nonzero_bits[REGNO (x)] = GET_MODE_MASK (GET_MODE (x)); 75350397Sobrien reg_sign_bit_copies[REGNO (x)] = 1; 75418334Speter return; 75518334Speter } 75618334Speter 75718334Speter /* If this is a complex assignment, see if we can convert it into a 75818334Speter simple assignment. */ 75918334Speter set = expand_field_assignment (set); 76018334Speter 76118334Speter /* If this is a simple assignment, or we have a paradoxical SUBREG, 76218334Speter set what we know about X. */ 76318334Speter 76418334Speter if (SET_DEST (set) == x 76518334Speter || (GET_CODE (SET_DEST (set)) == SUBREG 76618334Speter && (GET_MODE_SIZE (GET_MODE (SET_DEST (set))) 76718334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (set))))) 76818334Speter && SUBREG_REG (SET_DEST (set)) == x)) 76918334Speter { 77018334Speter rtx src = SET_SRC (set); 77118334Speter 77218334Speter#ifdef SHORT_IMMEDIATES_SIGN_EXTEND 77318334Speter /* If X is narrower than a word and SRC is a non-negative 77418334Speter constant that would appear negative in the mode of X, 77518334Speter sign-extend it for use in reg_nonzero_bits because some 77618334Speter machines (maybe most) will actually do the sign-extension 77718334Speter and this is the conservative approach. 77818334Speter 77918334Speter ??? For 2.5, try to tighten up the MD files in this regard 78018334Speter instead of this kludge. */ 78118334Speter 78218334Speter if (GET_MODE_BITSIZE (GET_MODE (x)) < BITS_PER_WORD 78318334Speter && GET_CODE (src) == CONST_INT 78418334Speter && INTVAL (src) > 0 78518334Speter && 0 != (INTVAL (src) 78618334Speter & ((HOST_WIDE_INT) 1 78718334Speter << (GET_MODE_BITSIZE (GET_MODE (x)) - 1)))) 78818334Speter src = GEN_INT (INTVAL (src) 78918334Speter | ((HOST_WIDE_INT) (-1) 79018334Speter << GET_MODE_BITSIZE (GET_MODE (x)))); 79118334Speter#endif 79218334Speter 79318334Speter reg_nonzero_bits[REGNO (x)] 79418334Speter |= nonzero_bits (src, nonzero_bits_mode); 79518334Speter num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x)); 79618334Speter if (reg_sign_bit_copies[REGNO (x)] == 0 79718334Speter || reg_sign_bit_copies[REGNO (x)] > num) 79818334Speter reg_sign_bit_copies[REGNO (x)] = num; 79918334Speter } 80018334Speter else 80118334Speter { 80218334Speter reg_nonzero_bits[REGNO (x)] = GET_MODE_MASK (GET_MODE (x)); 80350397Sobrien reg_sign_bit_copies[REGNO (x)] = 1; 80418334Speter } 80518334Speter } 80618334Speter} 80718334Speter 80818334Speter/* See if INSN can be combined into I3. PRED and SUCC are optionally 80918334Speter insns that were previously combined into I3 or that will be combined 81018334Speter into the merger of INSN and I3. 81118334Speter 81218334Speter Return 0 if the combination is not allowed for any reason. 81318334Speter 81418334Speter If the combination is allowed, *PDEST will be set to the single 81518334Speter destination of INSN and *PSRC to the single source, and this function 81618334Speter will return 1. */ 81718334Speter 81818334Speterstatic int 81918334Spetercan_combine_p (insn, i3, pred, succ, pdest, psrc) 82018334Speter rtx insn; 82118334Speter rtx i3; 82252284Sobrien rtx pred ATTRIBUTE_UNUSED; 82352284Sobrien rtx succ; 82418334Speter rtx *pdest, *psrc; 82518334Speter{ 82618334Speter int i; 82718334Speter rtx set = 0, src, dest; 82850397Sobrien rtx p; 82950397Sobrien#ifdef AUTO_INC_DEC 83050397Sobrien rtx link; 83150397Sobrien#endif 83218334Speter int all_adjacent = (succ ? (next_active_insn (insn) == succ 83318334Speter && next_active_insn (succ) == i3) 83418334Speter : next_active_insn (insn) == i3); 83518334Speter 83618334Speter /* Can combine only if previous insn is a SET of a REG, a SUBREG or CC0. 83718334Speter or a PARALLEL consisting of such a SET and CLOBBERs. 83818334Speter 83918334Speter If INSN has CLOBBER parallel parts, ignore them for our processing. 84018334Speter By definition, these happen during the execution of the insn. When it 84118334Speter is merged with another insn, all bets are off. If they are, in fact, 84218334Speter needed and aren't also supplied in I3, they may be added by 84318334Speter recog_for_combine. Otherwise, it won't match. 84418334Speter 84518334Speter We can also ignore a SET whose SET_DEST is mentioned in a REG_UNUSED 84618334Speter note. 84718334Speter 84818334Speter Get the source and destination of INSN. If more than one, can't 84918334Speter combine. */ 85018334Speter 85118334Speter if (GET_CODE (PATTERN (insn)) == SET) 85218334Speter set = PATTERN (insn); 85318334Speter else if (GET_CODE (PATTERN (insn)) == PARALLEL 85418334Speter && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET) 85518334Speter { 85618334Speter for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++) 85718334Speter { 85818334Speter rtx elt = XVECEXP (PATTERN (insn), 0, i); 85918334Speter 86018334Speter switch (GET_CODE (elt)) 86118334Speter { 86250397Sobrien /* This is important to combine floating point insns 86350397Sobrien for the SH4 port. */ 86450397Sobrien case USE: 86550397Sobrien /* Combining an isolated USE doesn't make sense. 86650397Sobrien We depend here on combinable_i3_pat to reject them. */ 86750397Sobrien /* The code below this loop only verifies that the inputs of 86850397Sobrien the SET in INSN do not change. We call reg_set_between_p 86950397Sobrien to verify that the REG in the USE does not change betweeen 87050397Sobrien I3 and INSN. 87150397Sobrien If the USE in INSN was for a pseudo register, the matching 87250397Sobrien insn pattern will likely match any register; combining this 87350397Sobrien with any other USE would only be safe if we knew that the 87450397Sobrien used registers have identical values, or if there was 87550397Sobrien something to tell them apart, e.g. different modes. For 87650397Sobrien now, we forgo such compilcated tests and simply disallow 87750397Sobrien combining of USES of pseudo registers with any other USE. */ 87850397Sobrien if (GET_CODE (XEXP (elt, 0)) == REG 87950397Sobrien && GET_CODE (PATTERN (i3)) == PARALLEL) 88050397Sobrien { 88150397Sobrien rtx i3pat = PATTERN (i3); 88250397Sobrien int i = XVECLEN (i3pat, 0) - 1; 88350397Sobrien int regno = REGNO (XEXP (elt, 0)); 88450397Sobrien do 88550397Sobrien { 88650397Sobrien rtx i3elt = XVECEXP (i3pat, 0, i); 88750397Sobrien if (GET_CODE (i3elt) == USE 88850397Sobrien && GET_CODE (XEXP (i3elt, 0)) == REG 88950397Sobrien && (REGNO (XEXP (i3elt, 0)) == regno 89050397Sobrien ? reg_set_between_p (XEXP (elt, 0), 89150397Sobrien PREV_INSN (insn), i3) 89250397Sobrien : regno >= FIRST_PSEUDO_REGISTER)) 89350397Sobrien return 0; 89450397Sobrien } 89550397Sobrien while (--i >= 0); 89650397Sobrien } 89750397Sobrien break; 89850397Sobrien 89918334Speter /* We can ignore CLOBBERs. */ 90018334Speter case CLOBBER: 90118334Speter break; 90218334Speter 90318334Speter case SET: 90418334Speter /* Ignore SETs whose result isn't used but not those that 90518334Speter have side-effects. */ 90618334Speter if (find_reg_note (insn, REG_UNUSED, SET_DEST (elt)) 90718334Speter && ! side_effects_p (elt)) 90818334Speter break; 90918334Speter 91018334Speter /* If we have already found a SET, this is a second one and 91118334Speter so we cannot combine with this insn. */ 91218334Speter if (set) 91318334Speter return 0; 91418334Speter 91518334Speter set = elt; 91618334Speter break; 91718334Speter 91818334Speter default: 91918334Speter /* Anything else means we can't combine. */ 92018334Speter return 0; 92118334Speter } 92218334Speter } 92318334Speter 92418334Speter if (set == 0 92518334Speter /* If SET_SRC is an ASM_OPERANDS we can't throw away these CLOBBERs, 92618334Speter so don't do anything with it. */ 92718334Speter || GET_CODE (SET_SRC (set)) == ASM_OPERANDS) 92818334Speter return 0; 92918334Speter } 93018334Speter else 93118334Speter return 0; 93218334Speter 93318334Speter if (set == 0) 93418334Speter return 0; 93518334Speter 93618334Speter set = expand_field_assignment (set); 93718334Speter src = SET_SRC (set), dest = SET_DEST (set); 93818334Speter 93918334Speter /* Don't eliminate a store in the stack pointer. */ 94018334Speter if (dest == stack_pointer_rtx 94118334Speter /* If we couldn't eliminate a field assignment, we can't combine. */ 94218334Speter || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == STRICT_LOW_PART 94318334Speter /* Don't combine with an insn that sets a register to itself if it has 94418334Speter a REG_EQUAL note. This may be part of a REG_NO_CONFLICT sequence. */ 94518334Speter || (rtx_equal_p (src, dest) && find_reg_note (insn, REG_EQUAL, NULL_RTX)) 94618334Speter /* Can't merge a function call. */ 94718334Speter || GET_CODE (src) == CALL 94818334Speter /* Don't eliminate a function call argument. */ 94918334Speter || (GET_CODE (i3) == CALL_INSN 95018334Speter && (find_reg_fusage (i3, USE, dest) 95118334Speter || (GET_CODE (dest) == REG 95218334Speter && REGNO (dest) < FIRST_PSEUDO_REGISTER 95318334Speter && global_regs[REGNO (dest)]))) 95418334Speter /* Don't substitute into an incremented register. */ 95518334Speter || FIND_REG_INC_NOTE (i3, dest) 95618334Speter || (succ && FIND_REG_INC_NOTE (succ, dest)) 95752284Sobrien#if 0 95818334Speter /* Don't combine the end of a libcall into anything. */ 95952284Sobrien /* ??? This gives worse code, and appears to be unnecessary, since no 96052284Sobrien pass after flow uses REG_LIBCALL/REG_RETVAL notes. Local-alloc does 96152284Sobrien use REG_RETVAL notes for noconflict blocks, but other code here 96252284Sobrien makes sure that those insns don't disappear. */ 96318334Speter || find_reg_note (insn, REG_RETVAL, NULL_RTX) 96452284Sobrien#endif 96518334Speter /* Make sure that DEST is not used after SUCC but before I3. */ 96618334Speter || (succ && ! all_adjacent 96718334Speter && reg_used_between_p (dest, succ, i3)) 96818334Speter /* Make sure that the value that is to be substituted for the register 96918334Speter does not use any registers whose values alter in between. However, 97018334Speter If the insns are adjacent, a use can't cross a set even though we 97118334Speter think it might (this can happen for a sequence of insns each setting 97218334Speter the same destination; reg_last_set of that register might point to 97318334Speter a NOTE). If INSN has a REG_EQUIV note, the register is always 97418334Speter equivalent to the memory so the substitution is valid even if there 97518334Speter are intervening stores. Also, don't move a volatile asm or 97618334Speter UNSPEC_VOLATILE across any other insns. */ 97718334Speter || (! all_adjacent 97818334Speter && (((GET_CODE (src) != MEM 97918334Speter || ! find_reg_note (insn, REG_EQUIV, src)) 98018334Speter && use_crosses_set_p (src, INSN_CUID (insn))) 98118334Speter || (GET_CODE (src) == ASM_OPERANDS && MEM_VOLATILE_P (src)) 98218334Speter || GET_CODE (src) == UNSPEC_VOLATILE)) 98318334Speter /* If there is a REG_NO_CONFLICT note for DEST in I3 or SUCC, we get 98418334Speter better register allocation by not doing the combine. */ 98518334Speter || find_reg_note (i3, REG_NO_CONFLICT, dest) 98618334Speter || (succ && find_reg_note (succ, REG_NO_CONFLICT, dest)) 98718334Speter /* Don't combine across a CALL_INSN, because that would possibly 98818334Speter change whether the life span of some REGs crosses calls or not, 98918334Speter and it is a pain to update that information. 99018334Speter Exception: if source is a constant, moving it later can't hurt. 99118334Speter Accept that special case, because it helps -fforce-addr a lot. */ 99218334Speter || (INSN_CUID (insn) < last_call_cuid && ! CONSTANT_P (src))) 99318334Speter return 0; 99418334Speter 99518334Speter /* DEST must either be a REG or CC0. */ 99618334Speter if (GET_CODE (dest) == REG) 99718334Speter { 99818334Speter /* If register alignment is being enforced for multi-word items in all 99918334Speter cases except for parameters, it is possible to have a register copy 100018334Speter insn referencing a hard register that is not allowed to contain the 100118334Speter mode being copied and which would not be valid as an operand of most 100218334Speter insns. Eliminate this problem by not combining with such an insn. 100318334Speter 100418334Speter Also, on some machines we don't want to extend the life of a hard 100550397Sobrien register. 100618334Speter 100750397Sobrien This is the same test done in can_combine except that we don't test 100850397Sobrien if SRC is a CALL operation to permit a hard register with 100950397Sobrien SMALL_REGISTER_CLASSES, and that we have to take all_adjacent 101050397Sobrien into account. */ 101150397Sobrien 101218334Speter if (GET_CODE (src) == REG 101318334Speter && ((REGNO (dest) < FIRST_PSEUDO_REGISTER 101418334Speter && ! HARD_REGNO_MODE_OK (REGNO (dest), GET_MODE (dest))) 101518334Speter /* Don't extend the life of a hard register unless it is 101618334Speter user variable (if we have few registers) or it can't 101718334Speter fit into the desired register (meaning something special 101850397Sobrien is going on). 101950397Sobrien Also avoid substituting a return register into I3, because 102050397Sobrien reload can't handle a conflict with constraints of other 102150397Sobrien inputs. */ 102218334Speter || (REGNO (src) < FIRST_PSEUDO_REGISTER 102318334Speter && (! HARD_REGNO_MODE_OK (REGNO (src), GET_MODE (src)) 102450397Sobrien || (SMALL_REGISTER_CLASSES 102550397Sobrien && ((! all_adjacent && ! REG_USERVAR_P (src)) 102650397Sobrien || (FUNCTION_VALUE_REGNO_P (REGNO (src)) 102750397Sobrien && ! REG_USERVAR_P (src)))))))) 102818334Speter return 0; 102918334Speter } 103018334Speter else if (GET_CODE (dest) != CC0) 103118334Speter return 0; 103218334Speter 103318334Speter /* Don't substitute for a register intended as a clobberable operand. 103418334Speter Similarly, don't substitute an expression containing a register that 103518334Speter will be clobbered in I3. */ 103618334Speter if (GET_CODE (PATTERN (i3)) == PARALLEL) 103718334Speter for (i = XVECLEN (PATTERN (i3), 0) - 1; i >= 0; i--) 103818334Speter if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER 103918334Speter && (reg_overlap_mentioned_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0), 104018334Speter src) 104118334Speter || rtx_equal_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0), dest))) 104218334Speter return 0; 104318334Speter 104418334Speter /* If INSN contains anything volatile, or is an `asm' (whether volatile 104550397Sobrien or not), reject, unless nothing volatile comes between it and I3 */ 104618334Speter 104718334Speter if (GET_CODE (src) == ASM_OPERANDS || volatile_refs_p (src)) 104850397Sobrien { 104950397Sobrien /* Make sure succ doesn't contain a volatile reference. */ 105050397Sobrien if (succ != 0 && volatile_refs_p (PATTERN (succ))) 105150397Sobrien return 0; 105250397Sobrien 105350397Sobrien for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p)) 105450397Sobrien if (GET_RTX_CLASS (GET_CODE (p)) == 'i' 105550397Sobrien && p != succ && volatile_refs_p (PATTERN (p))) 105650397Sobrien return 0; 105750397Sobrien } 105818334Speter 105950397Sobrien /* If INSN is an asm, and DEST is a hard register, reject, since it has 106050397Sobrien to be an explicit register variable, and was chosen for a reason. */ 106150397Sobrien 106250397Sobrien if (GET_CODE (src) == ASM_OPERANDS 106350397Sobrien && GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER) 106450397Sobrien return 0; 106550397Sobrien 106618334Speter /* If there are any volatile insns between INSN and I3, reject, because 106718334Speter they might affect machine state. */ 106818334Speter 106918334Speter for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p)) 107018334Speter if (GET_RTX_CLASS (GET_CODE (p)) == 'i' 107118334Speter && p != succ && volatile_insn_p (PATTERN (p))) 107218334Speter return 0; 107318334Speter 107418334Speter /* If INSN or I2 contains an autoincrement or autodecrement, 107518334Speter make sure that register is not used between there and I3, 107618334Speter and not already used in I3 either. 107718334Speter Also insist that I3 not be a jump; if it were one 107818334Speter and the incremented register were spilled, we would lose. */ 107918334Speter 108018334Speter#ifdef AUTO_INC_DEC 108118334Speter for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) 108218334Speter if (REG_NOTE_KIND (link) == REG_INC 108318334Speter && (GET_CODE (i3) == JUMP_INSN 108418334Speter || reg_used_between_p (XEXP (link, 0), insn, i3) 108518334Speter || reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i3)))) 108618334Speter return 0; 108718334Speter#endif 108818334Speter 108918334Speter#ifdef HAVE_cc0 109018334Speter /* Don't combine an insn that follows a CC0-setting insn. 109118334Speter An insn that uses CC0 must not be separated from the one that sets it. 109218334Speter We do, however, allow I2 to follow a CC0-setting insn if that insn 109318334Speter is passed as I1; in that case it will be deleted also. 109418334Speter We also allow combining in this case if all the insns are adjacent 109518334Speter because that would leave the two CC0 insns adjacent as well. 109618334Speter It would be more logical to test whether CC0 occurs inside I1 or I2, 109718334Speter but that would be much slower, and this ought to be equivalent. */ 109818334Speter 109918334Speter p = prev_nonnote_insn (insn); 110018334Speter if (p && p != pred && GET_CODE (p) == INSN && sets_cc0_p (PATTERN (p)) 110118334Speter && ! all_adjacent) 110218334Speter return 0; 110318334Speter#endif 110418334Speter 110518334Speter /* If we get here, we have passed all the tests and the combination is 110618334Speter to be allowed. */ 110718334Speter 110818334Speter *pdest = dest; 110918334Speter *psrc = src; 111018334Speter 111118334Speter return 1; 111218334Speter} 111318334Speter 111450397Sobrien/* Check if PAT is an insn - or a part of it - used to set up an 111550397Sobrien argument for a function in a hard register. */ 111650397Sobrien 111750397Sobrienstatic int 111850397Sobriensets_function_arg_p (pat) 111950397Sobrien rtx pat; 112050397Sobrien{ 112150397Sobrien int i; 112250397Sobrien rtx inner_dest; 112350397Sobrien 112450397Sobrien switch (GET_CODE (pat)) 112550397Sobrien { 112650397Sobrien case INSN: 112750397Sobrien return sets_function_arg_p (PATTERN (pat)); 112850397Sobrien 112950397Sobrien case PARALLEL: 113050397Sobrien for (i = XVECLEN (pat, 0); --i >= 0;) 113150397Sobrien if (sets_function_arg_p (XVECEXP (pat, 0, i))) 113250397Sobrien return 1; 113350397Sobrien 113450397Sobrien break; 113550397Sobrien 113650397Sobrien case SET: 113750397Sobrien inner_dest = SET_DEST (pat); 113850397Sobrien while (GET_CODE (inner_dest) == STRICT_LOW_PART 113950397Sobrien || GET_CODE (inner_dest) == SUBREG 114050397Sobrien || GET_CODE (inner_dest) == ZERO_EXTRACT) 114150397Sobrien inner_dest = XEXP (inner_dest, 0); 114250397Sobrien 114350397Sobrien return (GET_CODE (inner_dest) == REG 114450397Sobrien && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER 114550397Sobrien && FUNCTION_ARG_REGNO_P (REGNO (inner_dest))); 114650397Sobrien 114750397Sobrien default: 114850397Sobrien break; 114950397Sobrien } 115050397Sobrien 115150397Sobrien return 0; 115250397Sobrien} 115350397Sobrien 115418334Speter/* LOC is the location within I3 that contains its pattern or the component 115518334Speter of a PARALLEL of the pattern. We validate that it is valid for combining. 115618334Speter 115718334Speter One problem is if I3 modifies its output, as opposed to replacing it 115818334Speter entirely, we can't allow the output to contain I2DEST or I1DEST as doing 115918334Speter so would produce an insn that is not equivalent to the original insns. 116018334Speter 116118334Speter Consider: 116218334Speter 116318334Speter (set (reg:DI 101) (reg:DI 100)) 116418334Speter (set (subreg:SI (reg:DI 101) 0) <foo>) 116518334Speter 116618334Speter This is NOT equivalent to: 116718334Speter 116818334Speter (parallel [(set (subreg:SI (reg:DI 100) 0) <foo>) 116918334Speter (set (reg:DI 101) (reg:DI 100))]) 117018334Speter 117118334Speter Not only does this modify 100 (in which case it might still be valid 117218334Speter if 100 were dead in I2), it sets 101 to the ORIGINAL value of 100. 117318334Speter 117418334Speter We can also run into a problem if I2 sets a register that I1 117518334Speter uses and I1 gets directly substituted into I3 (not via I2). In that 117618334Speter case, we would be getting the wrong value of I2DEST into I3, so we 117718334Speter must reject the combination. This case occurs when I2 and I1 both 117818334Speter feed into I3, rather than when I1 feeds into I2, which feeds into I3. 117918334Speter If I1_NOT_IN_SRC is non-zero, it means that finding I1 in the source 118018334Speter of a SET must prevent combination from occurring. 118118334Speter 118250397Sobrien On machines where SMALL_REGISTER_CLASSES is non-zero, we don't combine 118318334Speter if the destination of a SET is a hard register that isn't a user 118418334Speter variable. 118518334Speter 118618334Speter Before doing the above check, we first try to expand a field assignment 118718334Speter into a set of logical operations. 118818334Speter 118918334Speter If PI3_DEST_KILLED is non-zero, it is a pointer to a location in which 119018334Speter we place a register that is both set and used within I3. If more than one 119118334Speter such register is detected, we fail. 119218334Speter 119318334Speter Return 1 if the combination is valid, zero otherwise. */ 119418334Speter 119518334Speterstatic int 119618334Spetercombinable_i3pat (i3, loc, i2dest, i1dest, i1_not_in_src, pi3dest_killed) 119718334Speter rtx i3; 119818334Speter rtx *loc; 119918334Speter rtx i2dest; 120018334Speter rtx i1dest; 120118334Speter int i1_not_in_src; 120218334Speter rtx *pi3dest_killed; 120318334Speter{ 120418334Speter rtx x = *loc; 120518334Speter 120618334Speter if (GET_CODE (x) == SET) 120718334Speter { 120818334Speter rtx set = expand_field_assignment (x); 120918334Speter rtx dest = SET_DEST (set); 121018334Speter rtx src = SET_SRC (set); 121150397Sobrien rtx inner_dest = dest; 121250397Sobrien 121350397Sobrien#if 0 121450397Sobrien rtx inner_src = src; 121550397Sobrien#endif 121618334Speter 121718334Speter SUBST (*loc, set); 121818334Speter 121918334Speter while (GET_CODE (inner_dest) == STRICT_LOW_PART 122018334Speter || GET_CODE (inner_dest) == SUBREG 122118334Speter || GET_CODE (inner_dest) == ZERO_EXTRACT) 122218334Speter inner_dest = XEXP (inner_dest, 0); 122318334Speter 122418334Speter /* We probably don't need this any more now that LIMIT_RELOAD_CLASS 122518334Speter was added. */ 122618334Speter#if 0 122718334Speter while (GET_CODE (inner_src) == STRICT_LOW_PART 122818334Speter || GET_CODE (inner_src) == SUBREG 122918334Speter || GET_CODE (inner_src) == ZERO_EXTRACT) 123018334Speter inner_src = XEXP (inner_src, 0); 123118334Speter 123218334Speter /* If it is better that two different modes keep two different pseudos, 123318334Speter avoid combining them. This avoids producing the following pattern 123418334Speter on a 386: 123518334Speter (set (subreg:SI (reg/v:QI 21) 0) 123618334Speter (lshiftrt:SI (reg/v:SI 20) 123718334Speter (const_int 24))) 123818334Speter If that were made, reload could not handle the pair of 123918334Speter reg 20/21, since it would try to get any GENERAL_REGS 124018334Speter but some of them don't handle QImode. */ 124118334Speter 124218334Speter if (rtx_equal_p (inner_src, i2dest) 124318334Speter && GET_CODE (inner_dest) == REG 124418334Speter && ! MODES_TIEABLE_P (GET_MODE (i2dest), GET_MODE (inner_dest))) 124518334Speter return 0; 124618334Speter#endif 124718334Speter 124818334Speter /* Check for the case where I3 modifies its output, as 124918334Speter discussed above. */ 125018334Speter if ((inner_dest != dest 125118334Speter && (reg_overlap_mentioned_p (i2dest, inner_dest) 125218334Speter || (i1dest && reg_overlap_mentioned_p (i1dest, inner_dest)))) 125350397Sobrien 125418334Speter /* This is the same test done in can_combine_p except that we 125518334Speter allow a hard register with SMALL_REGISTER_CLASSES if SRC is a 125650397Sobrien CALL operation. Moreover, we can't test all_adjacent; we don't 125750397Sobrien have to, since this instruction will stay in place, thus we are 125850397Sobrien not considering increasing the lifetime of INNER_DEST. 125950397Sobrien 126050397Sobrien Also, if this insn sets a function argument, combining it with 126150397Sobrien something that might need a spill could clobber a previous 126250397Sobrien function argument; the all_adjacent test in can_combine_p also 126350397Sobrien checks this; here, we do a more specific test for this case. */ 126450397Sobrien 126518334Speter || (GET_CODE (inner_dest) == REG 126618334Speter && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER 126718334Speter && (! HARD_REGNO_MODE_OK (REGNO (inner_dest), 126818334Speter GET_MODE (inner_dest)) 126950397Sobrien || (SMALL_REGISTER_CLASSES && GET_CODE (src) != CALL 127050397Sobrien && ! REG_USERVAR_P (inner_dest) 127150397Sobrien && (FUNCTION_VALUE_REGNO_P (REGNO (inner_dest)) 127250397Sobrien || (FUNCTION_ARG_REGNO_P (REGNO (inner_dest)) 127350397Sobrien && i3 != 0 127450397Sobrien && sets_function_arg_p (prev_nonnote_insn (i3))))))) 127518334Speter || (i1_not_in_src && reg_overlap_mentioned_p (i1dest, src))) 127618334Speter return 0; 127718334Speter 127818334Speter /* If DEST is used in I3, it is being killed in this insn, 127918334Speter so record that for later. 128018334Speter Never add REG_DEAD notes for the FRAME_POINTER_REGNUM or the 128118334Speter STACK_POINTER_REGNUM, since these are always considered to be 128218334Speter live. Similarly for ARG_POINTER_REGNUM if it is fixed. */ 128318334Speter if (pi3dest_killed && GET_CODE (dest) == REG 128418334Speter && reg_referenced_p (dest, PATTERN (i3)) 128518334Speter && REGNO (dest) != FRAME_POINTER_REGNUM 128618334Speter#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM 128718334Speter && REGNO (dest) != HARD_FRAME_POINTER_REGNUM 128818334Speter#endif 128918334Speter#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM 129018334Speter && (REGNO (dest) != ARG_POINTER_REGNUM 129118334Speter || ! fixed_regs [REGNO (dest)]) 129218334Speter#endif 129318334Speter && REGNO (dest) != STACK_POINTER_REGNUM) 129418334Speter { 129518334Speter if (*pi3dest_killed) 129618334Speter return 0; 129718334Speter 129818334Speter *pi3dest_killed = dest; 129918334Speter } 130018334Speter } 130118334Speter 130218334Speter else if (GET_CODE (x) == PARALLEL) 130318334Speter { 130418334Speter int i; 130518334Speter 130618334Speter for (i = 0; i < XVECLEN (x, 0); i++) 130718334Speter if (! combinable_i3pat (i3, &XVECEXP (x, 0, i), i2dest, i1dest, 130818334Speter i1_not_in_src, pi3dest_killed)) 130918334Speter return 0; 131018334Speter } 131118334Speter 131218334Speter return 1; 131318334Speter} 131418334Speter 131518334Speter/* Try to combine the insns I1 and I2 into I3. 131618334Speter Here I1 and I2 appear earlier than I3. 131718334Speter I1 can be zero; then we combine just I2 into I3. 131818334Speter 131918334Speter It we are combining three insns and the resulting insn is not recognized, 132018334Speter try splitting it into two insns. If that happens, I2 and I3 are retained 132118334Speter and I1 is pseudo-deleted by turning it into a NOTE. Otherwise, I1 and I2 132218334Speter are pseudo-deleted. 132318334Speter 132418334Speter Return 0 if the combination does not work. Then nothing is changed. 132518334Speter If we did the combination, return the insn at which combine should 132618334Speter resume scanning. */ 132718334Speter 132818334Speterstatic rtx 132918334Spetertry_combine (i3, i2, i1) 133018334Speter register rtx i3, i2, i1; 133118334Speter{ 133218334Speter /* New patterns for I3 and I3, respectively. */ 133318334Speter rtx newpat, newi2pat = 0; 133418334Speter /* Indicates need to preserve SET in I1 or I2 in I3 if it is not dead. */ 133518334Speter int added_sets_1, added_sets_2; 133618334Speter /* Total number of SETs to put into I3. */ 133718334Speter int total_sets; 133818334Speter /* Nonzero is I2's body now appears in I3. */ 133918334Speter int i2_is_used; 134018334Speter /* INSN_CODEs for new I3, new I2, and user of condition code. */ 134118334Speter int insn_code_number, i2_code_number, other_code_number; 134218334Speter /* Contains I3 if the destination of I3 is used in its source, which means 134318334Speter that the old life of I3 is being killed. If that usage is placed into 134418334Speter I2 and not in I3, a REG_DEAD note must be made. */ 134518334Speter rtx i3dest_killed = 0; 134618334Speter /* SET_DEST and SET_SRC of I2 and I1. */ 134718334Speter rtx i2dest, i2src, i1dest = 0, i1src = 0; 134818334Speter /* PATTERN (I2), or a copy of it in certain cases. */ 134918334Speter rtx i2pat; 135018334Speter /* Indicates if I2DEST or I1DEST is in I2SRC or I1_SRC. */ 135118334Speter int i2dest_in_i2src = 0, i1dest_in_i1src = 0, i2dest_in_i1src = 0; 135218334Speter int i1_feeds_i3 = 0; 135318334Speter /* Notes that must be added to REG_NOTES in I3 and I2. */ 135418334Speter rtx new_i3_notes, new_i2_notes; 135518334Speter /* Notes that we substituted I3 into I2 instead of the normal case. */ 135618334Speter int i3_subst_into_i2 = 0; 135718334Speter /* Notes that I1, I2 or I3 is a MULT operation. */ 135818334Speter int have_mult = 0; 135918334Speter 136018334Speter int maxreg; 136118334Speter rtx temp; 136218334Speter register rtx link; 136318334Speter int i; 136418334Speter 136518334Speter /* If any of I1, I2, and I3 isn't really an insn, we can't do anything. 136618334Speter This can occur when flow deletes an insn that it has merged into an 136718334Speter auto-increment address. We also can't do anything if I3 has a 136818334Speter REG_LIBCALL note since we don't want to disrupt the contiguity of a 136918334Speter libcall. */ 137018334Speter 137118334Speter if (GET_RTX_CLASS (GET_CODE (i3)) != 'i' 137218334Speter || GET_RTX_CLASS (GET_CODE (i2)) != 'i' 137318334Speter || (i1 && GET_RTX_CLASS (GET_CODE (i1)) != 'i') 137452284Sobrien#if 0 137552284Sobrien /* ??? This gives worse code, and appears to be unnecessary, since no 137652284Sobrien pass after flow uses REG_LIBCALL/REG_RETVAL notes. */ 137752284Sobrien || find_reg_note (i3, REG_LIBCALL, NULL_RTX) 137852284Sobrien#endif 137952284Sobrien) 138018334Speter return 0; 138118334Speter 138218334Speter combine_attempts++; 138318334Speter 138450397Sobrien undobuf.undos = undobuf.previous_undos = 0; 138518334Speter undobuf.other_insn = 0; 138618334Speter 138718334Speter /* Save the current high-water-mark so we can free storage if we didn't 138818334Speter accept this combination. */ 138918334Speter undobuf.storage = (char *) oballoc (0); 139018334Speter 139118334Speter /* Reset the hard register usage information. */ 139218334Speter CLEAR_HARD_REG_SET (newpat_used_regs); 139318334Speter 139418334Speter /* If I1 and I2 both feed I3, they can be in any order. To simplify the 139518334Speter code below, set I1 to be the earlier of the two insns. */ 139618334Speter if (i1 && INSN_CUID (i1) > INSN_CUID (i2)) 139718334Speter temp = i1, i1 = i2, i2 = temp; 139818334Speter 139918334Speter added_links_insn = 0; 140018334Speter 140118334Speter /* First check for one important special-case that the code below will 140218334Speter not handle. Namely, the case where I1 is zero, I2 has multiple sets, 140318334Speter and I3 is a SET whose SET_SRC is a SET_DEST in I2. In that case, 140418334Speter we may be able to replace that destination with the destination of I3. 140518334Speter This occurs in the common code where we compute both a quotient and 140618334Speter remainder into a structure, in which case we want to do the computation 140718334Speter directly into the structure to avoid register-register copies. 140818334Speter 140918334Speter We make very conservative checks below and only try to handle the 141018334Speter most common cases of this. For example, we only handle the case 141118334Speter where I2 and I3 are adjacent to avoid making difficult register 141218334Speter usage tests. */ 141318334Speter 141418334Speter if (i1 == 0 && GET_CODE (i3) == INSN && GET_CODE (PATTERN (i3)) == SET 141518334Speter && GET_CODE (SET_SRC (PATTERN (i3))) == REG 141618334Speter && REGNO (SET_SRC (PATTERN (i3))) >= FIRST_PSEUDO_REGISTER 141750397Sobrien && (! SMALL_REGISTER_CLASSES 141850397Sobrien || (GET_CODE (SET_DEST (PATTERN (i3))) != REG 141950397Sobrien || REGNO (SET_DEST (PATTERN (i3))) >= FIRST_PSEUDO_REGISTER 142050397Sobrien || REG_USERVAR_P (SET_DEST (PATTERN (i3))))) 142118334Speter && find_reg_note (i3, REG_DEAD, SET_SRC (PATTERN (i3))) 142218334Speter && GET_CODE (PATTERN (i2)) == PARALLEL 142318334Speter && ! side_effects_p (SET_DEST (PATTERN (i3))) 142418334Speter /* If the dest of I3 is a ZERO_EXTRACT or STRICT_LOW_PART, the code 142518334Speter below would need to check what is inside (and reg_overlap_mentioned_p 142618334Speter doesn't support those codes anyway). Don't allow those destinations; 142718334Speter the resulting insn isn't likely to be recognized anyway. */ 142818334Speter && GET_CODE (SET_DEST (PATTERN (i3))) != ZERO_EXTRACT 142918334Speter && GET_CODE (SET_DEST (PATTERN (i3))) != STRICT_LOW_PART 143018334Speter && ! reg_overlap_mentioned_p (SET_SRC (PATTERN (i3)), 143118334Speter SET_DEST (PATTERN (i3))) 143218334Speter && next_real_insn (i2) == i3) 143318334Speter { 143418334Speter rtx p2 = PATTERN (i2); 143518334Speter 143618334Speter /* Make sure that the destination of I3, 143718334Speter which we are going to substitute into one output of I2, 143818334Speter is not used within another output of I2. We must avoid making this: 143918334Speter (parallel [(set (mem (reg 69)) ...) 144018334Speter (set (reg 69) ...)]) 144118334Speter which is not well-defined as to order of actions. 144218334Speter (Besides, reload can't handle output reloads for this.) 144318334Speter 144418334Speter The problem can also happen if the dest of I3 is a memory ref, 144518334Speter if another dest in I2 is an indirect memory ref. */ 144618334Speter for (i = 0; i < XVECLEN (p2, 0); i++) 144750397Sobrien if ((GET_CODE (XVECEXP (p2, 0, i)) == SET 144850397Sobrien || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER) 144918334Speter && reg_overlap_mentioned_p (SET_DEST (PATTERN (i3)), 145018334Speter SET_DEST (XVECEXP (p2, 0, i)))) 145118334Speter break; 145218334Speter 145318334Speter if (i == XVECLEN (p2, 0)) 145418334Speter for (i = 0; i < XVECLEN (p2, 0); i++) 145518334Speter if (SET_DEST (XVECEXP (p2, 0, i)) == SET_SRC (PATTERN (i3))) 145618334Speter { 145718334Speter combine_merges++; 145818334Speter 145918334Speter subst_insn = i3; 146018334Speter subst_low_cuid = INSN_CUID (i2); 146118334Speter 146218334Speter added_sets_2 = added_sets_1 = 0; 146318334Speter i2dest = SET_SRC (PATTERN (i3)); 146418334Speter 146518334Speter /* Replace the dest in I2 with our dest and make the resulting 146618334Speter insn the new pattern for I3. Then skip to where we 146718334Speter validate the pattern. Everything was set up above. */ 146818334Speter SUBST (SET_DEST (XVECEXP (p2, 0, i)), 146918334Speter SET_DEST (PATTERN (i3))); 147018334Speter 147118334Speter newpat = p2; 147218334Speter i3_subst_into_i2 = 1; 147318334Speter goto validate_replacement; 147418334Speter } 147518334Speter } 147618334Speter 147718334Speter#ifndef HAVE_cc0 147818334Speter /* If we have no I1 and I2 looks like: 147918334Speter (parallel [(set (reg:CC X) (compare:CC OP (const_int 0))) 148018334Speter (set Y OP)]) 148118334Speter make up a dummy I1 that is 148218334Speter (set Y OP) 148318334Speter and change I2 to be 148418334Speter (set (reg:CC X) (compare:CC Y (const_int 0))) 148518334Speter 148618334Speter (We can ignore any trailing CLOBBERs.) 148718334Speter 148818334Speter This undoes a previous combination and allows us to match a branch-and- 148918334Speter decrement insn. */ 149018334Speter 149118334Speter if (i1 == 0 && GET_CODE (PATTERN (i2)) == PARALLEL 149218334Speter && XVECLEN (PATTERN (i2), 0) >= 2 149318334Speter && GET_CODE (XVECEXP (PATTERN (i2), 0, 0)) == SET 149418334Speter && (GET_MODE_CLASS (GET_MODE (SET_DEST (XVECEXP (PATTERN (i2), 0, 0)))) 149518334Speter == MODE_CC) 149618334Speter && GET_CODE (SET_SRC (XVECEXP (PATTERN (i2), 0, 0))) == COMPARE 149718334Speter && XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 1) == const0_rtx 149818334Speter && GET_CODE (XVECEXP (PATTERN (i2), 0, 1)) == SET 149918334Speter && GET_CODE (SET_DEST (XVECEXP (PATTERN (i2), 0, 1))) == REG 150018334Speter && rtx_equal_p (XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 0), 150118334Speter SET_SRC (XVECEXP (PATTERN (i2), 0, 1)))) 150218334Speter { 150318334Speter for (i = XVECLEN (PATTERN (i2), 0) - 1; i >= 2; i--) 150418334Speter if (GET_CODE (XVECEXP (PATTERN (i2), 0, i)) != CLOBBER) 150518334Speter break; 150618334Speter 150718334Speter if (i == 1) 150818334Speter { 150918334Speter /* We make I1 with the same INSN_UID as I2. This gives it 151018334Speter the same INSN_CUID for value tracking. Our fake I1 will 151118334Speter never appear in the insn stream so giving it the same INSN_UID 151218334Speter as I2 will not cause a problem. */ 151318334Speter 151418334Speter subst_prev_insn = i1 151550397Sobrien = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2, 151650397Sobrien XVECEXP (PATTERN (i2), 0, 1), -1, NULL_RTX, 151750397Sobrien NULL_RTX); 151818334Speter 151918334Speter SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0)); 152018334Speter SUBST (XEXP (SET_SRC (PATTERN (i2)), 0), 152118334Speter SET_DEST (PATTERN (i1))); 152218334Speter } 152318334Speter } 152418334Speter#endif 152518334Speter 152618334Speter /* Verify that I2 and I1 are valid for combining. */ 152718334Speter if (! can_combine_p (i2, i3, i1, NULL_RTX, &i2dest, &i2src) 152818334Speter || (i1 && ! can_combine_p (i1, i3, NULL_RTX, i2, &i1dest, &i1src))) 152918334Speter { 153018334Speter undo_all (); 153118334Speter return 0; 153218334Speter } 153318334Speter 153418334Speter /* Record whether I2DEST is used in I2SRC and similarly for the other 153518334Speter cases. Knowing this will help in register status updating below. */ 153618334Speter i2dest_in_i2src = reg_overlap_mentioned_p (i2dest, i2src); 153718334Speter i1dest_in_i1src = i1 && reg_overlap_mentioned_p (i1dest, i1src); 153818334Speter i2dest_in_i1src = i1 && reg_overlap_mentioned_p (i2dest, i1src); 153918334Speter 154018334Speter /* See if I1 directly feeds into I3. It does if I1DEST is not used 154118334Speter in I2SRC. */ 154218334Speter i1_feeds_i3 = i1 && ! reg_overlap_mentioned_p (i1dest, i2src); 154318334Speter 154418334Speter /* Ensure that I3's pattern can be the destination of combines. */ 154518334Speter if (! combinable_i3pat (i3, &PATTERN (i3), i2dest, i1dest, 154618334Speter i1 && i2dest_in_i1src && i1_feeds_i3, 154718334Speter &i3dest_killed)) 154818334Speter { 154918334Speter undo_all (); 155018334Speter return 0; 155118334Speter } 155218334Speter 155318334Speter /* See if any of the insns is a MULT operation. Unless one is, we will 155418334Speter reject a combination that is, since it must be slower. Be conservative 155518334Speter here. */ 155618334Speter if (GET_CODE (i2src) == MULT 155718334Speter || (i1 != 0 && GET_CODE (i1src) == MULT) 155818334Speter || (GET_CODE (PATTERN (i3)) == SET 155918334Speter && GET_CODE (SET_SRC (PATTERN (i3))) == MULT)) 156018334Speter have_mult = 1; 156118334Speter 156218334Speter /* If I3 has an inc, then give up if I1 or I2 uses the reg that is inc'd. 156318334Speter We used to do this EXCEPT in one case: I3 has a post-inc in an 156418334Speter output operand. However, that exception can give rise to insns like 156518334Speter mov r3,(r3)+ 156618334Speter which is a famous insn on the PDP-11 where the value of r3 used as the 156718334Speter source was model-dependent. Avoid this sort of thing. */ 156818334Speter 156918334Speter#if 0 157018334Speter if (!(GET_CODE (PATTERN (i3)) == SET 157118334Speter && GET_CODE (SET_SRC (PATTERN (i3))) == REG 157218334Speter && GET_CODE (SET_DEST (PATTERN (i3))) == MEM 157318334Speter && (GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_INC 157418334Speter || GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_DEC))) 157518334Speter /* It's not the exception. */ 157618334Speter#endif 157718334Speter#ifdef AUTO_INC_DEC 157818334Speter for (link = REG_NOTES (i3); link; link = XEXP (link, 1)) 157918334Speter if (REG_NOTE_KIND (link) == REG_INC 158018334Speter && (reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i2)) 158118334Speter || (i1 != 0 158218334Speter && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i1))))) 158318334Speter { 158418334Speter undo_all (); 158518334Speter return 0; 158618334Speter } 158718334Speter#endif 158818334Speter 158918334Speter /* See if the SETs in I1 or I2 need to be kept around in the merged 159018334Speter instruction: whenever the value set there is still needed past I3. 159118334Speter For the SETs in I2, this is easy: we see if I2DEST dies or is set in I3. 159218334Speter 159318334Speter For the SET in I1, we have two cases: If I1 and I2 independently 159418334Speter feed into I3, the set in I1 needs to be kept around if I1DEST dies 159518334Speter or is set in I3. Otherwise (if I1 feeds I2 which feeds I3), the set 159618334Speter in I1 needs to be kept around unless I1DEST dies or is set in either 159718334Speter I2 or I3. We can distinguish these cases by seeing if I2SRC mentions 159818334Speter I1DEST. If so, we know I1 feeds into I2. */ 159918334Speter 160018334Speter added_sets_2 = ! dead_or_set_p (i3, i2dest); 160118334Speter 160218334Speter added_sets_1 160318334Speter = i1 && ! (i1_feeds_i3 ? dead_or_set_p (i3, i1dest) 160418334Speter : (dead_or_set_p (i3, i1dest) || dead_or_set_p (i2, i1dest))); 160518334Speter 160618334Speter /* If the set in I2 needs to be kept around, we must make a copy of 160718334Speter PATTERN (I2), so that when we substitute I1SRC for I1DEST in 160818334Speter PATTERN (I2), we are only substituting for the original I1DEST, not into 160918334Speter an already-substituted copy. This also prevents making self-referential 161018334Speter rtx. If I2 is a PARALLEL, we just need the piece that assigns I2SRC to 161118334Speter I2DEST. */ 161218334Speter 161318334Speter i2pat = (GET_CODE (PATTERN (i2)) == PARALLEL 161450397Sobrien ? gen_rtx_SET (VOIDmode, i2dest, i2src) 161518334Speter : PATTERN (i2)); 161618334Speter 161718334Speter if (added_sets_2) 161818334Speter i2pat = copy_rtx (i2pat); 161918334Speter 162018334Speter combine_merges++; 162118334Speter 162218334Speter /* Substitute in the latest insn for the regs set by the earlier ones. */ 162318334Speter 162418334Speter maxreg = max_reg_num (); 162518334Speter 162618334Speter subst_insn = i3; 162718334Speter 162818334Speter /* It is possible that the source of I2 or I1 may be performing an 162918334Speter unneeded operation, such as a ZERO_EXTEND of something that is known 163018334Speter to have the high part zero. Handle that case by letting subst look at 163118334Speter the innermost one of them. 163218334Speter 163318334Speter Another way to do this would be to have a function that tries to 163418334Speter simplify a single insn instead of merging two or more insns. We don't 163518334Speter do this because of the potential of infinite loops and because 163618334Speter of the potential extra memory required. However, doing it the way 163718334Speter we are is a bit of a kludge and doesn't catch all cases. 163818334Speter 163918334Speter But only do this if -fexpensive-optimizations since it slows things down 164018334Speter and doesn't usually win. */ 164118334Speter 164218334Speter if (flag_expensive_optimizations) 164318334Speter { 164418334Speter /* Pass pc_rtx so no substitutions are done, just simplifications. 164518334Speter The cases that we are interested in here do not involve the few 164618334Speter cases were is_replaced is checked. */ 164718334Speter if (i1) 164818334Speter { 164918334Speter subst_low_cuid = INSN_CUID (i1); 165018334Speter i1src = subst (i1src, pc_rtx, pc_rtx, 0, 0); 165118334Speter } 165218334Speter else 165318334Speter { 165418334Speter subst_low_cuid = INSN_CUID (i2); 165518334Speter i2src = subst (i2src, pc_rtx, pc_rtx, 0, 0); 165618334Speter } 165718334Speter 165850397Sobrien undobuf.previous_undos = undobuf.undos; 165918334Speter } 166018334Speter 166118334Speter#ifndef HAVE_cc0 166218334Speter /* Many machines that don't use CC0 have insns that can both perform an 166318334Speter arithmetic operation and set the condition code. These operations will 166418334Speter be represented as a PARALLEL with the first element of the vector 166518334Speter being a COMPARE of an arithmetic operation with the constant zero. 166618334Speter The second element of the vector will set some pseudo to the result 166718334Speter of the same arithmetic operation. If we simplify the COMPARE, we won't 166818334Speter match such a pattern and so will generate an extra insn. Here we test 166918334Speter for this case, where both the comparison and the operation result are 167018334Speter needed, and make the PARALLEL by just replacing I2DEST in I3SRC with 167118334Speter I2SRC. Later we will make the PARALLEL that contains I2. */ 167218334Speter 167318334Speter if (i1 == 0 && added_sets_2 && GET_CODE (PATTERN (i3)) == SET 167418334Speter && GET_CODE (SET_SRC (PATTERN (i3))) == COMPARE 167518334Speter && XEXP (SET_SRC (PATTERN (i3)), 1) == const0_rtx 167618334Speter && rtx_equal_p (XEXP (SET_SRC (PATTERN (i3)), 0), i2dest)) 167718334Speter { 167850397Sobrien#ifdef EXTRA_CC_MODES 167918334Speter rtx *cc_use; 168018334Speter enum machine_mode compare_mode; 168150397Sobrien#endif 168218334Speter 168318334Speter newpat = PATTERN (i3); 168418334Speter SUBST (XEXP (SET_SRC (newpat), 0), i2src); 168518334Speter 168618334Speter i2_is_used = 1; 168718334Speter 168818334Speter#ifdef EXTRA_CC_MODES 168918334Speter /* See if a COMPARE with the operand we substituted in should be done 169018334Speter with the mode that is currently being used. If not, do the same 169118334Speter processing we do in `subst' for a SET; namely, if the destination 169218334Speter is used only once, try to replace it with a register of the proper 169318334Speter mode and also replace the COMPARE. */ 169418334Speter if (undobuf.other_insn == 0 169518334Speter && (cc_use = find_single_use (SET_DEST (newpat), i3, 169618334Speter &undobuf.other_insn)) 169718334Speter && ((compare_mode = SELECT_CC_MODE (GET_CODE (*cc_use), 169818334Speter i2src, const0_rtx)) 169918334Speter != GET_MODE (SET_DEST (newpat)))) 170018334Speter { 170118334Speter int regno = REGNO (SET_DEST (newpat)); 170250397Sobrien rtx new_dest = gen_rtx_REG (compare_mode, regno); 170318334Speter 170418334Speter if (regno < FIRST_PSEUDO_REGISTER 170550397Sobrien || (REG_N_SETS (regno) == 1 && ! added_sets_2 170618334Speter && ! REG_USERVAR_P (SET_DEST (newpat)))) 170718334Speter { 170818334Speter if (regno >= FIRST_PSEUDO_REGISTER) 170918334Speter SUBST (regno_reg_rtx[regno], new_dest); 171018334Speter 171118334Speter SUBST (SET_DEST (newpat), new_dest); 171218334Speter SUBST (XEXP (*cc_use, 0), new_dest); 171318334Speter SUBST (SET_SRC (newpat), 171418334Speter gen_rtx_combine (COMPARE, compare_mode, 171518334Speter i2src, const0_rtx)); 171618334Speter } 171718334Speter else 171818334Speter undobuf.other_insn = 0; 171918334Speter } 172018334Speter#endif 172118334Speter } 172218334Speter else 172318334Speter#endif 172418334Speter { 172518334Speter n_occurrences = 0; /* `subst' counts here */ 172618334Speter 172718334Speter /* If I1 feeds into I2 (not into I3) and I1DEST is in I1SRC, we 172818334Speter need to make a unique copy of I2SRC each time we substitute it 172918334Speter to avoid self-referential rtl. */ 173018334Speter 173118334Speter subst_low_cuid = INSN_CUID (i2); 173218334Speter newpat = subst (PATTERN (i3), i2dest, i2src, 0, 173318334Speter ! i1_feeds_i3 && i1dest_in_i1src); 173450397Sobrien undobuf.previous_undos = undobuf.undos; 173518334Speter 173618334Speter /* Record whether i2's body now appears within i3's body. */ 173718334Speter i2_is_used = n_occurrences; 173818334Speter } 173918334Speter 174018334Speter /* If we already got a failure, don't try to do more. Otherwise, 174118334Speter try to substitute in I1 if we have it. */ 174218334Speter 174318334Speter if (i1 && GET_CODE (newpat) != CLOBBER) 174418334Speter { 174518334Speter /* Before we can do this substitution, we must redo the test done 174618334Speter above (see detailed comments there) that ensures that I1DEST 174750397Sobrien isn't mentioned in any SETs in NEWPAT that are field assignments. */ 174818334Speter 174918334Speter if (! combinable_i3pat (NULL_RTX, &newpat, i1dest, NULL_RTX, 175018334Speter 0, NULL_PTR)) 175118334Speter { 175218334Speter undo_all (); 175318334Speter return 0; 175418334Speter } 175518334Speter 175618334Speter n_occurrences = 0; 175718334Speter subst_low_cuid = INSN_CUID (i1); 175818334Speter newpat = subst (newpat, i1dest, i1src, 0, 0); 175950397Sobrien undobuf.previous_undos = undobuf.undos; 176018334Speter } 176118334Speter 176218334Speter /* Fail if an autoincrement side-effect has been duplicated. Be careful 176318334Speter to count all the ways that I2SRC and I1SRC can be used. */ 176418334Speter if ((FIND_REG_INC_NOTE (i2, NULL_RTX) != 0 176518334Speter && i2_is_used + added_sets_2 > 1) 176618334Speter || (i1 != 0 && FIND_REG_INC_NOTE (i1, NULL_RTX) != 0 176718334Speter && (n_occurrences + added_sets_1 + (added_sets_2 && ! i1_feeds_i3) 176818334Speter > 1)) 176918334Speter /* Fail if we tried to make a new register (we used to abort, but there's 177018334Speter really no reason to). */ 177118334Speter || max_reg_num () != maxreg 177218334Speter /* Fail if we couldn't do something and have a CLOBBER. */ 177318334Speter || GET_CODE (newpat) == CLOBBER 177418334Speter /* Fail if this new pattern is a MULT and we didn't have one before 177518334Speter at the outer level. */ 177618334Speter || (GET_CODE (newpat) == SET && GET_CODE (SET_SRC (newpat)) == MULT 177718334Speter && ! have_mult)) 177818334Speter { 177918334Speter undo_all (); 178018334Speter return 0; 178118334Speter } 178218334Speter 178318334Speter /* If the actions of the earlier insns must be kept 178418334Speter in addition to substituting them into the latest one, 178518334Speter we must make a new PARALLEL for the latest insn 178618334Speter to hold additional the SETs. */ 178718334Speter 178818334Speter if (added_sets_1 || added_sets_2) 178918334Speter { 179018334Speter combine_extras++; 179118334Speter 179218334Speter if (GET_CODE (newpat) == PARALLEL) 179318334Speter { 179418334Speter rtvec old = XVEC (newpat, 0); 179518334Speter total_sets = XVECLEN (newpat, 0) + added_sets_1 + added_sets_2; 179650397Sobrien newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets)); 179750397Sobrien bcopy ((char *) &old->elem[0], (char *) XVEC (newpat, 0)->elem, 179818334Speter sizeof (old->elem[0]) * old->num_elem); 179918334Speter } 180018334Speter else 180118334Speter { 180218334Speter rtx old = newpat; 180318334Speter total_sets = 1 + added_sets_1 + added_sets_2; 180450397Sobrien newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets)); 180518334Speter XVECEXP (newpat, 0, 0) = old; 180618334Speter } 180718334Speter 180818334Speter if (added_sets_1) 180918334Speter XVECEXP (newpat, 0, --total_sets) 181018334Speter = (GET_CODE (PATTERN (i1)) == PARALLEL 181150397Sobrien ? gen_rtx_SET (VOIDmode, i1dest, i1src) : PATTERN (i1)); 181218334Speter 181318334Speter if (added_sets_2) 181418334Speter { 181518334Speter /* If there is no I1, use I2's body as is. We used to also not do 181618334Speter the subst call below if I2 was substituted into I3, 181718334Speter but that could lose a simplification. */ 181818334Speter if (i1 == 0) 181918334Speter XVECEXP (newpat, 0, --total_sets) = i2pat; 182018334Speter else 182118334Speter /* See comment where i2pat is assigned. */ 182218334Speter XVECEXP (newpat, 0, --total_sets) 182318334Speter = subst (i2pat, i1dest, i1src, 0, 0); 182418334Speter } 182518334Speter } 182618334Speter 182718334Speter /* We come here when we are replacing a destination in I2 with the 182818334Speter destination of I3. */ 182918334Speter validate_replacement: 183018334Speter 183118334Speter /* Note which hard regs this insn has as inputs. */ 183218334Speter mark_used_regs_combine (newpat); 183318334Speter 183418334Speter /* Is the result of combination a valid instruction? */ 183552284Sobrien insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); 183618334Speter 183718334Speter /* If the result isn't valid, see if it is a PARALLEL of two SETs where 183818334Speter the second SET's destination is a register that is unused. In that case, 183918334Speter we just need the first SET. This can occur when simplifying a divmod 184018334Speter insn. We *must* test for this case here because the code below that 184118334Speter splits two independent SETs doesn't handle this case correctly when it 184218334Speter updates the register status. Also check the case where the first 184318334Speter SET's destination is unused. That would not cause incorrect code, but 184418334Speter does cause an unneeded insn to remain. */ 184518334Speter 184618334Speter if (insn_code_number < 0 && GET_CODE (newpat) == PARALLEL 184718334Speter && XVECLEN (newpat, 0) == 2 184818334Speter && GET_CODE (XVECEXP (newpat, 0, 0)) == SET 184918334Speter && GET_CODE (XVECEXP (newpat, 0, 1)) == SET 185018334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == REG 185118334Speter && find_reg_note (i3, REG_UNUSED, SET_DEST (XVECEXP (newpat, 0, 1))) 185218334Speter && ! side_effects_p (SET_SRC (XVECEXP (newpat, 0, 1))) 185318334Speter && asm_noperands (newpat) < 0) 185418334Speter { 185518334Speter newpat = XVECEXP (newpat, 0, 0); 185652284Sobrien insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); 185718334Speter } 185818334Speter 185918334Speter else if (insn_code_number < 0 && GET_CODE (newpat) == PARALLEL 186018334Speter && XVECLEN (newpat, 0) == 2 186118334Speter && GET_CODE (XVECEXP (newpat, 0, 0)) == SET 186218334Speter && GET_CODE (XVECEXP (newpat, 0, 1)) == SET 186318334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) == REG 186418334Speter && find_reg_note (i3, REG_UNUSED, SET_DEST (XVECEXP (newpat, 0, 0))) 186518334Speter && ! side_effects_p (SET_SRC (XVECEXP (newpat, 0, 0))) 186618334Speter && asm_noperands (newpat) < 0) 186718334Speter { 186818334Speter newpat = XVECEXP (newpat, 0, 1); 186952284Sobrien insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); 187018334Speter } 187118334Speter 187218334Speter /* If we were combining three insns and the result is a simple SET 187318334Speter with no ASM_OPERANDS that wasn't recognized, try to split it into two 187418334Speter insns. There are two ways to do this. It can be split using a 187518334Speter machine-specific method (like when you have an addition of a large 187618334Speter constant) or by combine in the function find_split_point. */ 187718334Speter 187818334Speter if (i1 && insn_code_number < 0 && GET_CODE (newpat) == SET 187918334Speter && asm_noperands (newpat) < 0) 188018334Speter { 188118334Speter rtx m_split, *split; 188218334Speter rtx ni2dest = i2dest; 188318334Speter 188418334Speter /* See if the MD file can split NEWPAT. If it can't, see if letting it 188518334Speter use I2DEST as a scratch register will help. In the latter case, 188618334Speter convert I2DEST to the mode of the source of NEWPAT if we can. */ 188718334Speter 188818334Speter m_split = split_insns (newpat, i3); 188918334Speter 189018334Speter /* We can only use I2DEST as a scratch reg if it doesn't overlap any 189118334Speter inputs of NEWPAT. */ 189218334Speter 189318334Speter /* ??? If I2DEST is not safe, and I1DEST exists, then it would be 189418334Speter possible to try that as a scratch reg. This would require adding 189518334Speter more code to make it work though. */ 189618334Speter 189718334Speter if (m_split == 0 && ! reg_overlap_mentioned_p (ni2dest, newpat)) 189818334Speter { 189918334Speter /* If I2DEST is a hard register or the only use of a pseudo, 190018334Speter we can change its mode. */ 190118334Speter if (GET_MODE (SET_DEST (newpat)) != GET_MODE (i2dest) 190218334Speter && GET_MODE (SET_DEST (newpat)) != VOIDmode 190318334Speter && GET_CODE (i2dest) == REG 190418334Speter && (REGNO (i2dest) < FIRST_PSEUDO_REGISTER 190550397Sobrien || (REG_N_SETS (REGNO (i2dest)) == 1 && ! added_sets_2 190618334Speter && ! REG_USERVAR_P (i2dest)))) 190750397Sobrien ni2dest = gen_rtx_REG (GET_MODE (SET_DEST (newpat)), 190818334Speter REGNO (i2dest)); 190918334Speter 191050397Sobrien m_split = split_insns 191150397Sobrien (gen_rtx_PARALLEL (VOIDmode, 191250397Sobrien gen_rtvec (2, newpat, 191350397Sobrien gen_rtx_CLOBBER (VOIDmode, 191450397Sobrien ni2dest))), 191550397Sobrien i3); 191618334Speter } 191718334Speter 191818334Speter if (m_split && GET_CODE (m_split) == SEQUENCE 191918334Speter && XVECLEN (m_split, 0) == 2 192018334Speter && (next_real_insn (i2) == i3 192118334Speter || ! use_crosses_set_p (PATTERN (XVECEXP (m_split, 0, 0)), 192218334Speter INSN_CUID (i2)))) 192318334Speter { 192418334Speter rtx i2set, i3set; 192518334Speter rtx newi3pat = PATTERN (XVECEXP (m_split, 0, 1)); 192618334Speter newi2pat = PATTERN (XVECEXP (m_split, 0, 0)); 192718334Speter 192818334Speter i3set = single_set (XVECEXP (m_split, 0, 1)); 192918334Speter i2set = single_set (XVECEXP (m_split, 0, 0)); 193018334Speter 193118334Speter /* In case we changed the mode of I2DEST, replace it in the 193218334Speter pseudo-register table here. We can't do it above in case this 193318334Speter code doesn't get executed and we do a split the other way. */ 193418334Speter 193518334Speter if (REGNO (i2dest) >= FIRST_PSEUDO_REGISTER) 193618334Speter SUBST (regno_reg_rtx[REGNO (i2dest)], ni2dest); 193718334Speter 193852284Sobrien i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes); 193918334Speter 194018334Speter /* If I2 or I3 has multiple SETs, we won't know how to track 194150397Sobrien register status, so don't use these insns. If I2's destination 194250397Sobrien is used between I2 and I3, we also can't use these insns. */ 194318334Speter 194450397Sobrien if (i2_code_number >= 0 && i2set && i3set 194550397Sobrien && (next_real_insn (i2) == i3 194650397Sobrien || ! reg_used_between_p (SET_DEST (i2set), i2, i3))) 194752284Sobrien insn_code_number = recog_for_combine (&newi3pat, i3, 194852284Sobrien &new_i3_notes); 194918334Speter if (insn_code_number >= 0) 195018334Speter newpat = newi3pat; 195118334Speter 195218334Speter /* It is possible that both insns now set the destination of I3. 195318334Speter If so, we must show an extra use of it. */ 195418334Speter 195550397Sobrien if (insn_code_number >= 0) 195650397Sobrien { 195750397Sobrien rtx new_i3_dest = SET_DEST (i3set); 195850397Sobrien rtx new_i2_dest = SET_DEST (i2set); 195950397Sobrien 196050397Sobrien while (GET_CODE (new_i3_dest) == ZERO_EXTRACT 196150397Sobrien || GET_CODE (new_i3_dest) == STRICT_LOW_PART 196250397Sobrien || GET_CODE (new_i3_dest) == SUBREG) 196350397Sobrien new_i3_dest = XEXP (new_i3_dest, 0); 196450397Sobrien 196550397Sobrien while (GET_CODE (new_i2_dest) == ZERO_EXTRACT 196650397Sobrien || GET_CODE (new_i2_dest) == STRICT_LOW_PART 196750397Sobrien || GET_CODE (new_i2_dest) == SUBREG) 196850397Sobrien new_i2_dest = XEXP (new_i2_dest, 0); 196950397Sobrien 197050397Sobrien if (GET_CODE (new_i3_dest) == REG 197150397Sobrien && GET_CODE (new_i2_dest) == REG 197250397Sobrien && REGNO (new_i3_dest) == REGNO (new_i2_dest)) 197350397Sobrien REG_N_SETS (REGNO (new_i2_dest))++; 197450397Sobrien } 197518334Speter } 197618334Speter 197718334Speter /* If we can split it and use I2DEST, go ahead and see if that 197818334Speter helps things be recognized. Verify that none of the registers 197918334Speter are set between I2 and I3. */ 198018334Speter if (insn_code_number < 0 && (split = find_split_point (&newpat, i3)) != 0 198118334Speter#ifdef HAVE_cc0 198218334Speter && GET_CODE (i2dest) == REG 198318334Speter#endif 198418334Speter /* We need I2DEST in the proper mode. If it is a hard register 198518334Speter or the only use of a pseudo, we can change its mode. */ 198618334Speter && (GET_MODE (*split) == GET_MODE (i2dest) 198718334Speter || GET_MODE (*split) == VOIDmode 198818334Speter || REGNO (i2dest) < FIRST_PSEUDO_REGISTER 198950397Sobrien || (REG_N_SETS (REGNO (i2dest)) == 1 && ! added_sets_2 199018334Speter && ! REG_USERVAR_P (i2dest))) 199118334Speter && (next_real_insn (i2) == i3 199218334Speter || ! use_crosses_set_p (*split, INSN_CUID (i2))) 199318334Speter /* We can't overwrite I2DEST if its value is still used by 199418334Speter NEWPAT. */ 199518334Speter && ! reg_referenced_p (i2dest, newpat)) 199618334Speter { 199718334Speter rtx newdest = i2dest; 199818334Speter enum rtx_code split_code = GET_CODE (*split); 199918334Speter enum machine_mode split_mode = GET_MODE (*split); 200018334Speter 200118334Speter /* Get NEWDEST as a register in the proper mode. We have already 200218334Speter validated that we can do this. */ 200318334Speter if (GET_MODE (i2dest) != split_mode && split_mode != VOIDmode) 200418334Speter { 200550397Sobrien newdest = gen_rtx_REG (split_mode, REGNO (i2dest)); 200618334Speter 200718334Speter if (REGNO (i2dest) >= FIRST_PSEUDO_REGISTER) 200818334Speter SUBST (regno_reg_rtx[REGNO (i2dest)], newdest); 200918334Speter } 201018334Speter 201118334Speter /* If *SPLIT is a (mult FOO (const_int pow2)), convert it to 201218334Speter an ASHIFT. This can occur if it was inside a PLUS and hence 201318334Speter appeared to be a memory address. This is a kludge. */ 201418334Speter if (split_code == MULT 201518334Speter && GET_CODE (XEXP (*split, 1)) == CONST_INT 201618334Speter && (i = exact_log2 (INTVAL (XEXP (*split, 1)))) >= 0) 201718334Speter { 201818334Speter SUBST (*split, gen_rtx_combine (ASHIFT, split_mode, 201918334Speter XEXP (*split, 0), GEN_INT (i))); 202018334Speter /* Update split_code because we may not have a multiply 202118334Speter anymore. */ 202218334Speter split_code = GET_CODE (*split); 202318334Speter } 202418334Speter 202518334Speter#ifdef INSN_SCHEDULING 202618334Speter /* If *SPLIT is a paradoxical SUBREG, when we split it, it should 202718334Speter be written as a ZERO_EXTEND. */ 202818334Speter if (split_code == SUBREG && GET_CODE (SUBREG_REG (*split)) == MEM) 202918334Speter SUBST (*split, gen_rtx_combine (ZERO_EXTEND, split_mode, 203018334Speter XEXP (*split, 0))); 203118334Speter#endif 203218334Speter 203318334Speter newi2pat = gen_rtx_combine (SET, VOIDmode, newdest, *split); 203418334Speter SUBST (*split, newdest); 203552284Sobrien i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes); 203618334Speter 203718334Speter /* If the split point was a MULT and we didn't have one before, 203818334Speter don't use one now. */ 203918334Speter if (i2_code_number >= 0 && ! (split_code == MULT && ! have_mult)) 204052284Sobrien insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); 204118334Speter } 204218334Speter } 204318334Speter 204418334Speter /* Check for a case where we loaded from memory in a narrow mode and 204518334Speter then sign extended it, but we need both registers. In that case, 204618334Speter we have a PARALLEL with both loads from the same memory location. 204718334Speter We can split this into a load from memory followed by a register-register 204818334Speter copy. This saves at least one insn, more if register allocation can 204918334Speter eliminate the copy. 205018334Speter 205118334Speter We cannot do this if the destination of the second assignment is 205218334Speter a register that we have already assumed is zero-extended. Similarly 205318334Speter for a SUBREG of such a register. */ 205418334Speter 205518334Speter else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0 205618334Speter && GET_CODE (newpat) == PARALLEL 205718334Speter && XVECLEN (newpat, 0) == 2 205818334Speter && GET_CODE (XVECEXP (newpat, 0, 0)) == SET 205918334Speter && GET_CODE (SET_SRC (XVECEXP (newpat, 0, 0))) == SIGN_EXTEND 206018334Speter && GET_CODE (XVECEXP (newpat, 0, 1)) == SET 206118334Speter && rtx_equal_p (SET_SRC (XVECEXP (newpat, 0, 1)), 206218334Speter XEXP (SET_SRC (XVECEXP (newpat, 0, 0)), 0)) 206318334Speter && ! use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)), 206418334Speter INSN_CUID (i2)) 206518334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT 206618334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART 206718334Speter && ! (temp = SET_DEST (XVECEXP (newpat, 0, 1)), 206818334Speter (GET_CODE (temp) == REG 206918334Speter && reg_nonzero_bits[REGNO (temp)] != 0 207018334Speter && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD 207118334Speter && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT 207218334Speter && (reg_nonzero_bits[REGNO (temp)] 207318334Speter != GET_MODE_MASK (word_mode)))) 207418334Speter && ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == SUBREG 207518334Speter && (temp = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1))), 207618334Speter (GET_CODE (temp) == REG 207718334Speter && reg_nonzero_bits[REGNO (temp)] != 0 207818334Speter && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD 207918334Speter && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT 208018334Speter && (reg_nonzero_bits[REGNO (temp)] 208118334Speter != GET_MODE_MASK (word_mode))))) 208218334Speter && ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1)), 208318334Speter SET_SRC (XVECEXP (newpat, 0, 1))) 208418334Speter && ! find_reg_note (i3, REG_UNUSED, 208518334Speter SET_DEST (XVECEXP (newpat, 0, 0)))) 208618334Speter { 208718334Speter rtx ni2dest; 208818334Speter 208918334Speter newi2pat = XVECEXP (newpat, 0, 0); 209018334Speter ni2dest = SET_DEST (XVECEXP (newpat, 0, 0)); 209118334Speter newpat = XVECEXP (newpat, 0, 1); 209218334Speter SUBST (SET_SRC (newpat), 209318334Speter gen_lowpart_for_combine (GET_MODE (SET_SRC (newpat)), ni2dest)); 209452284Sobrien i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes); 209518334Speter 209618334Speter if (i2_code_number >= 0) 209752284Sobrien insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); 209818334Speter 209918334Speter if (insn_code_number >= 0) 210018334Speter { 210118334Speter rtx insn; 210218334Speter rtx link; 210318334Speter 210418334Speter /* If we will be able to accept this, we have made a change to the 210518334Speter destination of I3. This can invalidate a LOG_LINKS pointing 210618334Speter to I3. No other part of combine.c makes such a transformation. 210718334Speter 210818334Speter The new I3 will have a destination that was previously the 210918334Speter destination of I1 or I2 and which was used in i2 or I3. Call 211018334Speter distribute_links to make a LOG_LINK from the next use of 211118334Speter that destination. */ 211218334Speter 211318334Speter PATTERN (i3) = newpat; 211450397Sobrien distribute_links (gen_rtx_INSN_LIST (VOIDmode, i3, NULL_RTX)); 211518334Speter 211618334Speter /* I3 now uses what used to be its destination and which is 211718334Speter now I2's destination. That means we need a LOG_LINK from 211818334Speter I3 to I2. But we used to have one, so we still will. 211918334Speter 212018334Speter However, some later insn might be using I2's dest and have 212118334Speter a LOG_LINK pointing at I3. We must remove this link. 212218334Speter The simplest way to remove the link is to point it at I1, 212318334Speter which we know will be a NOTE. */ 212418334Speter 212518334Speter for (insn = NEXT_INSN (i3); 212618334Speter insn && (this_basic_block == n_basic_blocks - 1 212752284Sobrien || insn != BLOCK_HEAD (this_basic_block + 1)); 212818334Speter insn = NEXT_INSN (insn)) 212918334Speter { 213018334Speter if (GET_RTX_CLASS (GET_CODE (insn)) == 'i' 213118334Speter && reg_referenced_p (ni2dest, PATTERN (insn))) 213218334Speter { 213318334Speter for (link = LOG_LINKS (insn); link; 213418334Speter link = XEXP (link, 1)) 213518334Speter if (XEXP (link, 0) == i3) 213618334Speter XEXP (link, 0) = i1; 213718334Speter 213818334Speter break; 213918334Speter } 214018334Speter } 214118334Speter } 214218334Speter } 214318334Speter 214418334Speter /* Similarly, check for a case where we have a PARALLEL of two independent 214518334Speter SETs but we started with three insns. In this case, we can do the sets 214618334Speter as two separate insns. This case occurs when some SET allows two 214718334Speter other insns to combine, but the destination of that SET is still live. */ 214818334Speter 214918334Speter else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0 215018334Speter && GET_CODE (newpat) == PARALLEL 215118334Speter && XVECLEN (newpat, 0) == 2 215218334Speter && GET_CODE (XVECEXP (newpat, 0, 0)) == SET 215318334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != ZERO_EXTRACT 215418334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != STRICT_LOW_PART 215518334Speter && GET_CODE (XVECEXP (newpat, 0, 1)) == SET 215618334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT 215718334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART 215818334Speter && ! use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)), 215918334Speter INSN_CUID (i2)) 216018334Speter /* Don't pass sets with (USE (MEM ...)) dests to the following. */ 216118334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != USE 216218334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != USE 216318334Speter && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 1)), 216418334Speter XVECEXP (newpat, 0, 0)) 216518334Speter && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 0)), 216618334Speter XVECEXP (newpat, 0, 1))) 216718334Speter { 216850397Sobrien /* Normally, it doesn't matter which of the two is done first, 216950397Sobrien but it does if one references cc0. In that case, it has to 217050397Sobrien be first. */ 217150397Sobrien#ifdef HAVE_cc0 217250397Sobrien if (reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0))) 217350397Sobrien { 217450397Sobrien newi2pat = XVECEXP (newpat, 0, 0); 217550397Sobrien newpat = XVECEXP (newpat, 0, 1); 217650397Sobrien } 217750397Sobrien else 217850397Sobrien#endif 217950397Sobrien { 218050397Sobrien newi2pat = XVECEXP (newpat, 0, 1); 218150397Sobrien newpat = XVECEXP (newpat, 0, 0); 218250397Sobrien } 218318334Speter 218452284Sobrien i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes); 218518334Speter 218618334Speter if (i2_code_number >= 0) 218752284Sobrien insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); 218818334Speter } 218918334Speter 219018334Speter /* If it still isn't recognized, fail and change things back the way they 219118334Speter were. */ 219218334Speter if ((insn_code_number < 0 219318334Speter /* Is the result a reasonable ASM_OPERANDS? */ 219418334Speter && (! check_asm_operands (newpat) || added_sets_1 || added_sets_2))) 219518334Speter { 219618334Speter undo_all (); 219718334Speter return 0; 219818334Speter } 219918334Speter 220018334Speter /* If we had to change another insn, make sure it is valid also. */ 220118334Speter if (undobuf.other_insn) 220218334Speter { 220318334Speter rtx other_pat = PATTERN (undobuf.other_insn); 220418334Speter rtx new_other_notes; 220518334Speter rtx note, next; 220618334Speter 220718334Speter CLEAR_HARD_REG_SET (newpat_used_regs); 220818334Speter 220952284Sobrien other_code_number = recog_for_combine (&other_pat, undobuf.other_insn, 221052284Sobrien &new_other_notes); 221118334Speter 221218334Speter if (other_code_number < 0 && ! check_asm_operands (other_pat)) 221318334Speter { 221418334Speter undo_all (); 221518334Speter return 0; 221618334Speter } 221718334Speter 221818334Speter PATTERN (undobuf.other_insn) = other_pat; 221918334Speter 222018334Speter /* If any of the notes in OTHER_INSN were REG_UNUSED, ensure that they 222118334Speter are still valid. Then add any non-duplicate notes added by 222218334Speter recog_for_combine. */ 222318334Speter for (note = REG_NOTES (undobuf.other_insn); note; note = next) 222418334Speter { 222518334Speter next = XEXP (note, 1); 222618334Speter 222718334Speter if (REG_NOTE_KIND (note) == REG_UNUSED 222818334Speter && ! reg_set_p (XEXP (note, 0), PATTERN (undobuf.other_insn))) 222918334Speter { 223018334Speter if (GET_CODE (XEXP (note, 0)) == REG) 223150397Sobrien REG_N_DEATHS (REGNO (XEXP (note, 0)))--; 223218334Speter 223318334Speter remove_note (undobuf.other_insn, note); 223418334Speter } 223518334Speter } 223618334Speter 223718334Speter for (note = new_other_notes; note; note = XEXP (note, 1)) 223818334Speter if (GET_CODE (XEXP (note, 0)) == REG) 223950397Sobrien REG_N_DEATHS (REGNO (XEXP (note, 0)))++; 224018334Speter 224118334Speter distribute_notes (new_other_notes, undobuf.other_insn, 224218334Speter undobuf.other_insn, NULL_RTX, NULL_RTX, NULL_RTX); 224318334Speter } 224418334Speter 224518334Speter /* We now know that we can do this combination. Merge the insns and 224618334Speter update the status of registers and LOG_LINKS. */ 224718334Speter 224818334Speter { 224918334Speter rtx i3notes, i2notes, i1notes = 0; 225018334Speter rtx i3links, i2links, i1links = 0; 225118334Speter rtx midnotes = 0; 225218334Speter register int regno; 225350397Sobrien /* Compute which registers we expect to eliminate. newi2pat may be setting 225450397Sobrien either i3dest or i2dest, so we must check it. Also, i1dest may be the 225550397Sobrien same as i3dest, in which case newi2pat may be setting i1dest. */ 225650397Sobrien rtx elim_i2 = ((newi2pat && reg_set_p (i2dest, newi2pat)) 225750397Sobrien || i2dest_in_i2src || i2dest_in_i1src 225818334Speter ? 0 : i2dest); 225950397Sobrien rtx elim_i1 = (i1 == 0 || i1dest_in_i1src 226050397Sobrien || (newi2pat && reg_set_p (i1dest, newi2pat)) 226150397Sobrien ? 0 : i1dest); 226218334Speter 226318334Speter /* Get the old REG_NOTES and LOG_LINKS from all our insns and 226418334Speter clear them. */ 226518334Speter i3notes = REG_NOTES (i3), i3links = LOG_LINKS (i3); 226618334Speter i2notes = REG_NOTES (i2), i2links = LOG_LINKS (i2); 226718334Speter if (i1) 226818334Speter i1notes = REG_NOTES (i1), i1links = LOG_LINKS (i1); 226918334Speter 227018334Speter /* Ensure that we do not have something that should not be shared but 227118334Speter occurs multiple times in the new insns. Check this by first 227218334Speter resetting all the `used' flags and then copying anything is shared. */ 227318334Speter 227418334Speter reset_used_flags (i3notes); 227518334Speter reset_used_flags (i2notes); 227618334Speter reset_used_flags (i1notes); 227718334Speter reset_used_flags (newpat); 227818334Speter reset_used_flags (newi2pat); 227918334Speter if (undobuf.other_insn) 228018334Speter reset_used_flags (PATTERN (undobuf.other_insn)); 228118334Speter 228218334Speter i3notes = copy_rtx_if_shared (i3notes); 228318334Speter i2notes = copy_rtx_if_shared (i2notes); 228418334Speter i1notes = copy_rtx_if_shared (i1notes); 228518334Speter newpat = copy_rtx_if_shared (newpat); 228618334Speter newi2pat = copy_rtx_if_shared (newi2pat); 228718334Speter if (undobuf.other_insn) 228818334Speter reset_used_flags (PATTERN (undobuf.other_insn)); 228918334Speter 229018334Speter INSN_CODE (i3) = insn_code_number; 229118334Speter PATTERN (i3) = newpat; 229218334Speter if (undobuf.other_insn) 229318334Speter INSN_CODE (undobuf.other_insn) = other_code_number; 229418334Speter 229518334Speter /* We had one special case above where I2 had more than one set and 229618334Speter we replaced a destination of one of those sets with the destination 229718334Speter of I3. In that case, we have to update LOG_LINKS of insns later 229818334Speter in this basic block. Note that this (expensive) case is rare. 229918334Speter 230018334Speter Also, in this case, we must pretend that all REG_NOTEs for I2 230118334Speter actually came from I3, so that REG_UNUSED notes from I2 will be 230218334Speter properly handled. */ 230318334Speter 230418334Speter if (i3_subst_into_i2) 230518334Speter { 230618334Speter for (i = 0; i < XVECLEN (PATTERN (i2), 0); i++) 230718334Speter if (GET_CODE (SET_DEST (XVECEXP (PATTERN (i2), 0, i))) == REG 230818334Speter && SET_DEST (XVECEXP (PATTERN (i2), 0, i)) != i2dest 230918334Speter && ! find_reg_note (i2, REG_UNUSED, 231018334Speter SET_DEST (XVECEXP (PATTERN (i2), 0, i)))) 231118334Speter for (temp = NEXT_INSN (i2); 231218334Speter temp && (this_basic_block == n_basic_blocks - 1 231352284Sobrien || BLOCK_HEAD (this_basic_block) != temp); 231418334Speter temp = NEXT_INSN (temp)) 231518334Speter if (temp != i3 && GET_RTX_CLASS (GET_CODE (temp)) == 'i') 231618334Speter for (link = LOG_LINKS (temp); link; link = XEXP (link, 1)) 231718334Speter if (XEXP (link, 0) == i2) 231818334Speter XEXP (link, 0) = i3; 231918334Speter 232018334Speter if (i3notes) 232118334Speter { 232218334Speter rtx link = i3notes; 232318334Speter while (XEXP (link, 1)) 232418334Speter link = XEXP (link, 1); 232518334Speter XEXP (link, 1) = i2notes; 232618334Speter } 232718334Speter else 232818334Speter i3notes = i2notes; 232918334Speter i2notes = 0; 233018334Speter } 233118334Speter 233218334Speter LOG_LINKS (i3) = 0; 233318334Speter REG_NOTES (i3) = 0; 233418334Speter LOG_LINKS (i2) = 0; 233518334Speter REG_NOTES (i2) = 0; 233618334Speter 233718334Speter if (newi2pat) 233818334Speter { 233918334Speter INSN_CODE (i2) = i2_code_number; 234018334Speter PATTERN (i2) = newi2pat; 234118334Speter } 234218334Speter else 234318334Speter { 234418334Speter PUT_CODE (i2, NOTE); 234518334Speter NOTE_LINE_NUMBER (i2) = NOTE_INSN_DELETED; 234618334Speter NOTE_SOURCE_FILE (i2) = 0; 234718334Speter } 234818334Speter 234918334Speter if (i1) 235018334Speter { 235118334Speter LOG_LINKS (i1) = 0; 235218334Speter REG_NOTES (i1) = 0; 235318334Speter PUT_CODE (i1, NOTE); 235418334Speter NOTE_LINE_NUMBER (i1) = NOTE_INSN_DELETED; 235518334Speter NOTE_SOURCE_FILE (i1) = 0; 235618334Speter } 235718334Speter 235818334Speter /* Get death notes for everything that is now used in either I3 or 235950397Sobrien I2 and used to die in a previous insn. If we built two new 236050397Sobrien patterns, move from I1 to I2 then I2 to I3 so that we get the 236150397Sobrien proper movement on registers that I2 modifies. */ 236218334Speter 236318334Speter if (newi2pat) 236450397Sobrien { 236550397Sobrien move_deaths (newi2pat, NULL_RTX, INSN_CUID (i1), i2, &midnotes); 236650397Sobrien move_deaths (newpat, newi2pat, INSN_CUID (i1), i3, &midnotes); 236750397Sobrien } 236850397Sobrien else 236950397Sobrien move_deaths (newpat, NULL_RTX, i1 ? INSN_CUID (i1) : INSN_CUID (i2), 237050397Sobrien i3, &midnotes); 237118334Speter 237218334Speter /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3. */ 237318334Speter if (i3notes) 237418334Speter distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL_RTX, 237518334Speter elim_i2, elim_i1); 237618334Speter if (i2notes) 237718334Speter distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL_RTX, 237818334Speter elim_i2, elim_i1); 237918334Speter if (i1notes) 238018334Speter distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL_RTX, 238118334Speter elim_i2, elim_i1); 238218334Speter if (midnotes) 238318334Speter distribute_notes (midnotes, NULL_RTX, i3, newi2pat ? i2 : NULL_RTX, 238418334Speter elim_i2, elim_i1); 238518334Speter 238618334Speter /* Distribute any notes added to I2 or I3 by recog_for_combine. We 238718334Speter know these are REG_UNUSED and want them to go to the desired insn, 238818334Speter so we always pass it as i3. We have not counted the notes in 238918334Speter reg_n_deaths yet, so we need to do so now. */ 239018334Speter 239118334Speter if (newi2pat && new_i2_notes) 239218334Speter { 239318334Speter for (temp = new_i2_notes; temp; temp = XEXP (temp, 1)) 239418334Speter if (GET_CODE (XEXP (temp, 0)) == REG) 239550397Sobrien REG_N_DEATHS (REGNO (XEXP (temp, 0)))++; 239618334Speter 239718334Speter distribute_notes (new_i2_notes, i2, i2, NULL_RTX, NULL_RTX, NULL_RTX); 239818334Speter } 239918334Speter 240018334Speter if (new_i3_notes) 240118334Speter { 240218334Speter for (temp = new_i3_notes; temp; temp = XEXP (temp, 1)) 240318334Speter if (GET_CODE (XEXP (temp, 0)) == REG) 240450397Sobrien REG_N_DEATHS (REGNO (XEXP (temp, 0)))++; 240518334Speter 240618334Speter distribute_notes (new_i3_notes, i3, i3, NULL_RTX, NULL_RTX, NULL_RTX); 240718334Speter } 240818334Speter 240918334Speter /* If I3DEST was used in I3SRC, it really died in I3. We may need to 241050397Sobrien put a REG_DEAD note for it somewhere. If NEWI2PAT exists and sets 241150397Sobrien I3DEST, the death must be somewhere before I2, not I3. If we passed I3 241250397Sobrien in that case, it might delete I2. Similarly for I2 and I1. 241318334Speter Show an additional death due to the REG_DEAD note we make here. If 241418334Speter we discard it in distribute_notes, we will decrement it again. */ 241518334Speter 241618334Speter if (i3dest_killed) 241718334Speter { 241818334Speter if (GET_CODE (i3dest_killed) == REG) 241950397Sobrien REG_N_DEATHS (REGNO (i3dest_killed))++; 242018334Speter 242150397Sobrien if (newi2pat && reg_set_p (i3dest_killed, newi2pat)) 242250397Sobrien distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed, 242350397Sobrien NULL_RTX), 242450397Sobrien NULL_RTX, i2, NULL_RTX, elim_i2, elim_i1); 242550397Sobrien else 242650397Sobrien distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed, 242750397Sobrien NULL_RTX), 242850397Sobrien NULL_RTX, i3, newi2pat ? i2 : NULL_RTX, 242950397Sobrien elim_i2, elim_i1); 243018334Speter } 243118334Speter 243218334Speter if (i2dest_in_i2src) 243318334Speter { 243418334Speter if (GET_CODE (i2dest) == REG) 243550397Sobrien REG_N_DEATHS (REGNO (i2dest))++; 243618334Speter 243718334Speter if (newi2pat && reg_set_p (i2dest, newi2pat)) 243850397Sobrien distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX), 243918334Speter NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX); 244018334Speter else 244150397Sobrien distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX), 244218334Speter NULL_RTX, i3, newi2pat ? i2 : NULL_RTX, 244318334Speter NULL_RTX, NULL_RTX); 244418334Speter } 244518334Speter 244618334Speter if (i1dest_in_i1src) 244718334Speter { 244818334Speter if (GET_CODE (i1dest) == REG) 244950397Sobrien REG_N_DEATHS (REGNO (i1dest))++; 245018334Speter 245118334Speter if (newi2pat && reg_set_p (i1dest, newi2pat)) 245250397Sobrien distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX), 245318334Speter NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX); 245418334Speter else 245550397Sobrien distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX), 245618334Speter NULL_RTX, i3, newi2pat ? i2 : NULL_RTX, 245718334Speter NULL_RTX, NULL_RTX); 245818334Speter } 245918334Speter 246018334Speter distribute_links (i3links); 246118334Speter distribute_links (i2links); 246218334Speter distribute_links (i1links); 246318334Speter 246418334Speter if (GET_CODE (i2dest) == REG) 246518334Speter { 246618334Speter rtx link; 246718334Speter rtx i2_insn = 0, i2_val = 0, set; 246818334Speter 246918334Speter /* The insn that used to set this register doesn't exist, and 247018334Speter this life of the register may not exist either. See if one of 247118334Speter I3's links points to an insn that sets I2DEST. If it does, 247218334Speter that is now the last known value for I2DEST. If we don't update 247318334Speter this and I2 set the register to a value that depended on its old 247418334Speter contents, we will get confused. If this insn is used, thing 247518334Speter will be set correctly in combine_instructions. */ 247618334Speter 247718334Speter for (link = LOG_LINKS (i3); link; link = XEXP (link, 1)) 247818334Speter if ((set = single_set (XEXP (link, 0))) != 0 247918334Speter && rtx_equal_p (i2dest, SET_DEST (set))) 248018334Speter i2_insn = XEXP (link, 0), i2_val = SET_SRC (set); 248118334Speter 248218334Speter record_value_for_reg (i2dest, i2_insn, i2_val); 248318334Speter 248418334Speter /* If the reg formerly set in I2 died only once and that was in I3, 248518334Speter zero its use count so it won't make `reload' do any work. */ 248650397Sobrien if (! added_sets_2 248750397Sobrien && (newi2pat == 0 || ! reg_mentioned_p (i2dest, newi2pat)) 248850397Sobrien && ! i2dest_in_i2src) 248918334Speter { 249018334Speter regno = REGNO (i2dest); 249150397Sobrien REG_N_SETS (regno)--; 249250397Sobrien if (REG_N_SETS (regno) == 0 249352284Sobrien && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, 249452284Sobrien regno)) 249550397Sobrien REG_N_REFS (regno) = 0; 249618334Speter } 249718334Speter } 249818334Speter 249918334Speter if (i1 && GET_CODE (i1dest) == REG) 250018334Speter { 250118334Speter rtx link; 250218334Speter rtx i1_insn = 0, i1_val = 0, set; 250318334Speter 250418334Speter for (link = LOG_LINKS (i3); link; link = XEXP (link, 1)) 250518334Speter if ((set = single_set (XEXP (link, 0))) != 0 250618334Speter && rtx_equal_p (i1dest, SET_DEST (set))) 250718334Speter i1_insn = XEXP (link, 0), i1_val = SET_SRC (set); 250818334Speter 250918334Speter record_value_for_reg (i1dest, i1_insn, i1_val); 251018334Speter 251118334Speter regno = REGNO (i1dest); 251218334Speter if (! added_sets_1 && ! i1dest_in_i1src) 251318334Speter { 251450397Sobrien REG_N_SETS (regno)--; 251550397Sobrien if (REG_N_SETS (regno) == 0 251652284Sobrien && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, 251752284Sobrien regno)) 251850397Sobrien REG_N_REFS (regno) = 0; 251918334Speter } 252018334Speter } 252118334Speter 252218334Speter /* Update reg_nonzero_bits et al for any changes that may have been made 252318334Speter to this insn. */ 252418334Speter 252518334Speter note_stores (newpat, set_nonzero_bits_and_sign_copies); 252618334Speter if (newi2pat) 252718334Speter note_stores (newi2pat, set_nonzero_bits_and_sign_copies); 252818334Speter 252918334Speter /* If I3 is now an unconditional jump, ensure that it has a 253018334Speter BARRIER following it since it may have initially been a 253118334Speter conditional jump. It may also be the last nonnote insn. */ 253218334Speter 253318334Speter if ((GET_CODE (newpat) == RETURN || simplejump_p (i3)) 253418334Speter && ((temp = next_nonnote_insn (i3)) == NULL_RTX 253518334Speter || GET_CODE (temp) != BARRIER)) 253618334Speter emit_barrier_after (i3); 253718334Speter } 253818334Speter 253918334Speter combine_successes++; 254018334Speter 254118334Speter /* Clear this here, so that subsequent get_last_value calls are not 254218334Speter affected. */ 254318334Speter subst_prev_insn = NULL_RTX; 254418334Speter 254518334Speter if (added_links_insn 254618334Speter && (newi2pat == 0 || INSN_CUID (added_links_insn) < INSN_CUID (i2)) 254718334Speter && INSN_CUID (added_links_insn) < INSN_CUID (i3)) 254818334Speter return added_links_insn; 254918334Speter else 255018334Speter return newi2pat ? i2 : i3; 255118334Speter} 255218334Speter 255318334Speter/* Undo all the modifications recorded in undobuf. */ 255418334Speter 255518334Speterstatic void 255618334Speterundo_all () 255718334Speter{ 255850397Sobrien struct undo *undo, *next; 255950397Sobrien 256050397Sobrien for (undo = undobuf.undos; undo; undo = next) 256118334Speter { 256250397Sobrien next = undo->next; 256350397Sobrien if (undo->is_int) 256450397Sobrien *undo->where.i = undo->old_contents.i; 256518334Speter else 256650397Sobrien *undo->where.r = undo->old_contents.r; 256750397Sobrien 256850397Sobrien undo->next = undobuf.frees; 256950397Sobrien undobuf.frees = undo; 257018334Speter } 257118334Speter 257218334Speter obfree (undobuf.storage); 257350397Sobrien undobuf.undos = undobuf.previous_undos = 0; 257418334Speter 257518334Speter /* Clear this here, so that subsequent get_last_value calls are not 257618334Speter affected. */ 257718334Speter subst_prev_insn = NULL_RTX; 257818334Speter} 257918334Speter 258018334Speter/* Find the innermost point within the rtx at LOC, possibly LOC itself, 258118334Speter where we have an arithmetic expression and return that point. LOC will 258218334Speter be inside INSN. 258318334Speter 258418334Speter try_combine will call this function to see if an insn can be split into 258518334Speter two insns. */ 258618334Speter 258718334Speterstatic rtx * 258818334Speterfind_split_point (loc, insn) 258918334Speter rtx *loc; 259018334Speter rtx insn; 259118334Speter{ 259218334Speter rtx x = *loc; 259318334Speter enum rtx_code code = GET_CODE (x); 259418334Speter rtx *split; 259518334Speter int len = 0, pos, unsignedp; 259618334Speter rtx inner; 259718334Speter 259818334Speter /* First special-case some codes. */ 259918334Speter switch (code) 260018334Speter { 260118334Speter case SUBREG: 260218334Speter#ifdef INSN_SCHEDULING 260318334Speter /* If we are making a paradoxical SUBREG invalid, it becomes a split 260418334Speter point. */ 260518334Speter if (GET_CODE (SUBREG_REG (x)) == MEM) 260618334Speter return loc; 260718334Speter#endif 260818334Speter return find_split_point (&SUBREG_REG (x), insn); 260918334Speter 261018334Speter case MEM: 261118334Speter#ifdef HAVE_lo_sum 261218334Speter /* If we have (mem (const ..)) or (mem (symbol_ref ...)), split it 261318334Speter using LO_SUM and HIGH. */ 261418334Speter if (GET_CODE (XEXP (x, 0)) == CONST 261518334Speter || GET_CODE (XEXP (x, 0)) == SYMBOL_REF) 261618334Speter { 261718334Speter SUBST (XEXP (x, 0), 261818334Speter gen_rtx_combine (LO_SUM, Pmode, 261918334Speter gen_rtx_combine (HIGH, Pmode, XEXP (x, 0)), 262018334Speter XEXP (x, 0))); 262118334Speter return &XEXP (XEXP (x, 0), 0); 262218334Speter } 262318334Speter#endif 262418334Speter 262518334Speter /* If we have a PLUS whose second operand is a constant and the 262618334Speter address is not valid, perhaps will can split it up using 262718334Speter the machine-specific way to split large constants. We use 262818334Speter the first pseudo-reg (one of the virtual regs) as a placeholder; 262918334Speter it will not remain in the result. */ 263018334Speter if (GET_CODE (XEXP (x, 0)) == PLUS 263118334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 263218334Speter && ! memory_address_p (GET_MODE (x), XEXP (x, 0))) 263318334Speter { 263418334Speter rtx reg = regno_reg_rtx[FIRST_PSEUDO_REGISTER]; 263550397Sobrien rtx seq = split_insns (gen_rtx_SET (VOIDmode, reg, XEXP (x, 0)), 263618334Speter subst_insn); 263718334Speter 263818334Speter /* This should have produced two insns, each of which sets our 263918334Speter placeholder. If the source of the second is a valid address, 264018334Speter we can make put both sources together and make a split point 264118334Speter in the middle. */ 264218334Speter 264318334Speter if (seq && XVECLEN (seq, 0) == 2 264418334Speter && GET_CODE (XVECEXP (seq, 0, 0)) == INSN 264518334Speter && GET_CODE (PATTERN (XVECEXP (seq, 0, 0))) == SET 264618334Speter && SET_DEST (PATTERN (XVECEXP (seq, 0, 0))) == reg 264718334Speter && ! reg_mentioned_p (reg, 264818334Speter SET_SRC (PATTERN (XVECEXP (seq, 0, 0)))) 264918334Speter && GET_CODE (XVECEXP (seq, 0, 1)) == INSN 265018334Speter && GET_CODE (PATTERN (XVECEXP (seq, 0, 1))) == SET 265118334Speter && SET_DEST (PATTERN (XVECEXP (seq, 0, 1))) == reg 265218334Speter && memory_address_p (GET_MODE (x), 265318334Speter SET_SRC (PATTERN (XVECEXP (seq, 0, 1))))) 265418334Speter { 265518334Speter rtx src1 = SET_SRC (PATTERN (XVECEXP (seq, 0, 0))); 265618334Speter rtx src2 = SET_SRC (PATTERN (XVECEXP (seq, 0, 1))); 265718334Speter 265818334Speter /* Replace the placeholder in SRC2 with SRC1. If we can 265918334Speter find where in SRC2 it was placed, that can become our 266018334Speter split point and we can replace this address with SRC2. 266118334Speter Just try two obvious places. */ 266218334Speter 266318334Speter src2 = replace_rtx (src2, reg, src1); 266418334Speter split = 0; 266518334Speter if (XEXP (src2, 0) == src1) 266618334Speter split = &XEXP (src2, 0); 266718334Speter else if (GET_RTX_FORMAT (GET_CODE (XEXP (src2, 0)))[0] == 'e' 266818334Speter && XEXP (XEXP (src2, 0), 0) == src1) 266918334Speter split = &XEXP (XEXP (src2, 0), 0); 267018334Speter 267118334Speter if (split) 267218334Speter { 267318334Speter SUBST (XEXP (x, 0), src2); 267418334Speter return split; 267518334Speter } 267618334Speter } 267718334Speter 267818334Speter /* If that didn't work, perhaps the first operand is complex and 267918334Speter needs to be computed separately, so make a split point there. 268018334Speter This will occur on machines that just support REG + CONST 268118334Speter and have a constant moved through some previous computation. */ 268218334Speter 268318334Speter else if (GET_RTX_CLASS (GET_CODE (XEXP (XEXP (x, 0), 0))) != 'o' 268418334Speter && ! (GET_CODE (XEXP (XEXP (x, 0), 0)) == SUBREG 268518334Speter && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (XEXP (x, 0), 0)))) 268618334Speter == 'o'))) 268718334Speter return &XEXP (XEXP (x, 0), 0); 268818334Speter } 268918334Speter break; 269018334Speter 269118334Speter case SET: 269218334Speter#ifdef HAVE_cc0 269318334Speter /* If SET_DEST is CC0 and SET_SRC is not an operand, a COMPARE, or a 269418334Speter ZERO_EXTRACT, the most likely reason why this doesn't match is that 269518334Speter we need to put the operand into a register. So split at that 269618334Speter point. */ 269718334Speter 269818334Speter if (SET_DEST (x) == cc0_rtx 269918334Speter && GET_CODE (SET_SRC (x)) != COMPARE 270018334Speter && GET_CODE (SET_SRC (x)) != ZERO_EXTRACT 270118334Speter && GET_RTX_CLASS (GET_CODE (SET_SRC (x))) != 'o' 270218334Speter && ! (GET_CODE (SET_SRC (x)) == SUBREG 270318334Speter && GET_RTX_CLASS (GET_CODE (SUBREG_REG (SET_SRC (x)))) == 'o')) 270418334Speter return &SET_SRC (x); 270518334Speter#endif 270618334Speter 270718334Speter /* See if we can split SET_SRC as it stands. */ 270818334Speter split = find_split_point (&SET_SRC (x), insn); 270918334Speter if (split && split != &SET_SRC (x)) 271018334Speter return split; 271118334Speter 271250397Sobrien /* See if we can split SET_DEST as it stands. */ 271350397Sobrien split = find_split_point (&SET_DEST (x), insn); 271450397Sobrien if (split && split != &SET_DEST (x)) 271550397Sobrien return split; 271650397Sobrien 271718334Speter /* See if this is a bitfield assignment with everything constant. If 271818334Speter so, this is an IOR of an AND, so split it into that. */ 271918334Speter if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT 272018334Speter && (GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0))) 272118334Speter <= HOST_BITS_PER_WIDE_INT) 272218334Speter && GET_CODE (XEXP (SET_DEST (x), 1)) == CONST_INT 272318334Speter && GET_CODE (XEXP (SET_DEST (x), 2)) == CONST_INT 272418334Speter && GET_CODE (SET_SRC (x)) == CONST_INT 272518334Speter && ((INTVAL (XEXP (SET_DEST (x), 1)) 272618334Speter + INTVAL (XEXP (SET_DEST (x), 2))) 272718334Speter <= GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0)))) 272818334Speter && ! side_effects_p (XEXP (SET_DEST (x), 0))) 272918334Speter { 273018334Speter int pos = INTVAL (XEXP (SET_DEST (x), 2)); 273118334Speter int len = INTVAL (XEXP (SET_DEST (x), 1)); 273218334Speter int src = INTVAL (SET_SRC (x)); 273318334Speter rtx dest = XEXP (SET_DEST (x), 0); 273418334Speter enum machine_mode mode = GET_MODE (dest); 273518334Speter unsigned HOST_WIDE_INT mask = ((HOST_WIDE_INT) 1 << len) - 1; 273618334Speter 273718334Speter if (BITS_BIG_ENDIAN) 273818334Speter pos = GET_MODE_BITSIZE (mode) - len - pos; 273918334Speter 274052284Sobrien if ((unsigned HOST_WIDE_INT) src == mask) 274118334Speter SUBST (SET_SRC (x), 274218334Speter gen_binary (IOR, mode, dest, GEN_INT (src << pos))); 274318334Speter else 274418334Speter SUBST (SET_SRC (x), 274518334Speter gen_binary (IOR, mode, 274618334Speter gen_binary (AND, mode, dest, 274718334Speter GEN_INT (~ (mask << pos) 274818334Speter & GET_MODE_MASK (mode))), 274918334Speter GEN_INT (src << pos))); 275018334Speter 275118334Speter SUBST (SET_DEST (x), dest); 275218334Speter 275318334Speter split = find_split_point (&SET_SRC (x), insn); 275418334Speter if (split && split != &SET_SRC (x)) 275518334Speter return split; 275618334Speter } 275718334Speter 275818334Speter /* Otherwise, see if this is an operation that we can split into two. 275918334Speter If so, try to split that. */ 276018334Speter code = GET_CODE (SET_SRC (x)); 276118334Speter 276218334Speter switch (code) 276318334Speter { 276418334Speter case AND: 276518334Speter /* If we are AND'ing with a large constant that is only a single 276618334Speter bit and the result is only being used in a context where we 276718334Speter need to know if it is zero or non-zero, replace it with a bit 276818334Speter extraction. This will avoid the large constant, which might 276918334Speter have taken more than one insn to make. If the constant were 277018334Speter not a valid argument to the AND but took only one insn to make, 277118334Speter this is no worse, but if it took more than one insn, it will 277218334Speter be better. */ 277318334Speter 277418334Speter if (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT 277518334Speter && GET_CODE (XEXP (SET_SRC (x), 0)) == REG 277618334Speter && (pos = exact_log2 (INTVAL (XEXP (SET_SRC (x), 1)))) >= 7 277718334Speter && GET_CODE (SET_DEST (x)) == REG 277818334Speter && (split = find_single_use (SET_DEST (x), insn, NULL_PTR)) != 0 277918334Speter && (GET_CODE (*split) == EQ || GET_CODE (*split) == NE) 278018334Speter && XEXP (*split, 0) == SET_DEST (x) 278118334Speter && XEXP (*split, 1) == const0_rtx) 278218334Speter { 278350397Sobrien rtx extraction = make_extraction (GET_MODE (SET_DEST (x)), 278450397Sobrien XEXP (SET_SRC (x), 0), 278550397Sobrien pos, NULL_RTX, 1, 1, 0, 0); 278650397Sobrien if (extraction != 0) 278750397Sobrien { 278850397Sobrien SUBST (SET_SRC (x), extraction); 278950397Sobrien return find_split_point (loc, insn); 279050397Sobrien } 279150397Sobrien } 279250397Sobrien break; 279350397Sobrien 279450397Sobrien case NE: 279550397Sobrien /* if STORE_FLAG_VALUE is -1, this is (NE X 0) and only one bit of X 279650397Sobrien is known to be on, this can be converted into a NEG of a shift. */ 279750397Sobrien if (STORE_FLAG_VALUE == -1 && XEXP (SET_SRC (x), 1) == const0_rtx 279850397Sobrien && GET_MODE (SET_SRC (x)) == GET_MODE (XEXP (SET_SRC (x), 0)) 279950397Sobrien && 1 <= (pos = exact_log2 280050397Sobrien (nonzero_bits (XEXP (SET_SRC (x), 0), 280150397Sobrien GET_MODE (XEXP (SET_SRC (x), 0)))))) 280250397Sobrien { 280350397Sobrien enum machine_mode mode = GET_MODE (XEXP (SET_SRC (x), 0)); 280450397Sobrien 280518334Speter SUBST (SET_SRC (x), 280650397Sobrien gen_rtx_combine (NEG, mode, 280750397Sobrien gen_rtx_combine (LSHIFTRT, mode, 280850397Sobrien XEXP (SET_SRC (x), 0), 280950397Sobrien GEN_INT (pos)))); 281050397Sobrien 281150397Sobrien split = find_split_point (&SET_SRC (x), insn); 281250397Sobrien if (split && split != &SET_SRC (x)) 281350397Sobrien return split; 281418334Speter } 281518334Speter break; 281618334Speter 281718334Speter case SIGN_EXTEND: 281818334Speter inner = XEXP (SET_SRC (x), 0); 281950397Sobrien 282050397Sobrien /* We can't optimize if either mode is a partial integer 282150397Sobrien mode as we don't know how many bits are significant 282250397Sobrien in those modes. */ 282350397Sobrien if (GET_MODE_CLASS (GET_MODE (inner)) == MODE_PARTIAL_INT 282450397Sobrien || GET_MODE_CLASS (GET_MODE (SET_SRC (x))) == MODE_PARTIAL_INT) 282550397Sobrien break; 282650397Sobrien 282718334Speter pos = 0; 282818334Speter len = GET_MODE_BITSIZE (GET_MODE (inner)); 282918334Speter unsignedp = 0; 283018334Speter break; 283118334Speter 283218334Speter case SIGN_EXTRACT: 283318334Speter case ZERO_EXTRACT: 283418334Speter if (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT 283518334Speter && GET_CODE (XEXP (SET_SRC (x), 2)) == CONST_INT) 283618334Speter { 283718334Speter inner = XEXP (SET_SRC (x), 0); 283818334Speter len = INTVAL (XEXP (SET_SRC (x), 1)); 283918334Speter pos = INTVAL (XEXP (SET_SRC (x), 2)); 284018334Speter 284118334Speter if (BITS_BIG_ENDIAN) 284218334Speter pos = GET_MODE_BITSIZE (GET_MODE (inner)) - len - pos; 284318334Speter unsignedp = (code == ZERO_EXTRACT); 284418334Speter } 284518334Speter break; 284650397Sobrien 284750397Sobrien default: 284850397Sobrien break; 284918334Speter } 285018334Speter 285118334Speter if (len && pos >= 0 && pos + len <= GET_MODE_BITSIZE (GET_MODE (inner))) 285218334Speter { 285318334Speter enum machine_mode mode = GET_MODE (SET_SRC (x)); 285418334Speter 285518334Speter /* For unsigned, we have a choice of a shift followed by an 285618334Speter AND or two shifts. Use two shifts for field sizes where the 285718334Speter constant might be too large. We assume here that we can 285818334Speter always at least get 8-bit constants in an AND insn, which is 285918334Speter true for every current RISC. */ 286018334Speter 286118334Speter if (unsignedp && len <= 8) 286218334Speter { 286318334Speter SUBST (SET_SRC (x), 286418334Speter gen_rtx_combine 286518334Speter (AND, mode, 286618334Speter gen_rtx_combine (LSHIFTRT, mode, 286718334Speter gen_lowpart_for_combine (mode, inner), 286818334Speter GEN_INT (pos)), 286918334Speter GEN_INT (((HOST_WIDE_INT) 1 << len) - 1))); 287018334Speter 287118334Speter split = find_split_point (&SET_SRC (x), insn); 287218334Speter if (split && split != &SET_SRC (x)) 287318334Speter return split; 287418334Speter } 287518334Speter else 287618334Speter { 287718334Speter SUBST (SET_SRC (x), 287818334Speter gen_rtx_combine 287918334Speter (unsignedp ? LSHIFTRT : ASHIFTRT, mode, 288018334Speter gen_rtx_combine (ASHIFT, mode, 288118334Speter gen_lowpart_for_combine (mode, inner), 288218334Speter GEN_INT (GET_MODE_BITSIZE (mode) 288318334Speter - len - pos)), 288418334Speter GEN_INT (GET_MODE_BITSIZE (mode) - len))); 288518334Speter 288618334Speter split = find_split_point (&SET_SRC (x), insn); 288718334Speter if (split && split != &SET_SRC (x)) 288818334Speter return split; 288918334Speter } 289018334Speter } 289118334Speter 289218334Speter /* See if this is a simple operation with a constant as the second 289318334Speter operand. It might be that this constant is out of range and hence 289418334Speter could be used as a split point. */ 289518334Speter if ((GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '2' 289618334Speter || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == 'c' 289718334Speter || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '<') 289818334Speter && CONSTANT_P (XEXP (SET_SRC (x), 1)) 289918334Speter && (GET_RTX_CLASS (GET_CODE (XEXP (SET_SRC (x), 0))) == 'o' 290018334Speter || (GET_CODE (XEXP (SET_SRC (x), 0)) == SUBREG 290118334Speter && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (SET_SRC (x), 0)))) 290218334Speter == 'o')))) 290318334Speter return &XEXP (SET_SRC (x), 1); 290418334Speter 290518334Speter /* Finally, see if this is a simple operation with its first operand 290618334Speter not in a register. The operation might require this operand in a 290718334Speter register, so return it as a split point. We can always do this 290818334Speter because if the first operand were another operation, we would have 290918334Speter already found it as a split point. */ 291018334Speter if ((GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '2' 291118334Speter || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == 'c' 291218334Speter || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '<' 291318334Speter || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '1') 291418334Speter && ! register_operand (XEXP (SET_SRC (x), 0), VOIDmode)) 291518334Speter return &XEXP (SET_SRC (x), 0); 291618334Speter 291718334Speter return 0; 291818334Speter 291918334Speter case AND: 292018334Speter case IOR: 292118334Speter /* We write NOR as (and (not A) (not B)), but if we don't have a NOR, 292218334Speter it is better to write this as (not (ior A B)) so we can split it. 292318334Speter Similarly for IOR. */ 292418334Speter if (GET_CODE (XEXP (x, 0)) == NOT && GET_CODE (XEXP (x, 1)) == NOT) 292518334Speter { 292618334Speter SUBST (*loc, 292718334Speter gen_rtx_combine (NOT, GET_MODE (x), 292818334Speter gen_rtx_combine (code == IOR ? AND : IOR, 292918334Speter GET_MODE (x), 293018334Speter XEXP (XEXP (x, 0), 0), 293118334Speter XEXP (XEXP (x, 1), 0)))); 293218334Speter return find_split_point (loc, insn); 293318334Speter } 293418334Speter 293518334Speter /* Many RISC machines have a large set of logical insns. If the 293618334Speter second operand is a NOT, put it first so we will try to split the 293718334Speter other operand first. */ 293818334Speter if (GET_CODE (XEXP (x, 1)) == NOT) 293918334Speter { 294018334Speter rtx tem = XEXP (x, 0); 294118334Speter SUBST (XEXP (x, 0), XEXP (x, 1)); 294218334Speter SUBST (XEXP (x, 1), tem); 294318334Speter } 294418334Speter break; 294550397Sobrien 294650397Sobrien default: 294750397Sobrien break; 294818334Speter } 294918334Speter 295018334Speter /* Otherwise, select our actions depending on our rtx class. */ 295118334Speter switch (GET_RTX_CLASS (code)) 295218334Speter { 295318334Speter case 'b': /* This is ZERO_EXTRACT and SIGN_EXTRACT. */ 295418334Speter case '3': 295518334Speter split = find_split_point (&XEXP (x, 2), insn); 295618334Speter if (split) 295718334Speter return split; 295850397Sobrien /* ... fall through ... */ 295918334Speter case '2': 296018334Speter case 'c': 296118334Speter case '<': 296218334Speter split = find_split_point (&XEXP (x, 1), insn); 296318334Speter if (split) 296418334Speter return split; 296550397Sobrien /* ... fall through ... */ 296618334Speter case '1': 296718334Speter /* Some machines have (and (shift ...) ...) insns. If X is not 296818334Speter an AND, but XEXP (X, 0) is, use it as our split point. */ 296918334Speter if (GET_CODE (x) != AND && GET_CODE (XEXP (x, 0)) == AND) 297018334Speter return &XEXP (x, 0); 297118334Speter 297218334Speter split = find_split_point (&XEXP (x, 0), insn); 297318334Speter if (split) 297418334Speter return split; 297518334Speter return loc; 297618334Speter } 297718334Speter 297818334Speter /* Otherwise, we don't have a split point. */ 297918334Speter return 0; 298018334Speter} 298118334Speter 298218334Speter/* Throughout X, replace FROM with TO, and return the result. 298318334Speter The result is TO if X is FROM; 298418334Speter otherwise the result is X, but its contents may have been modified. 298518334Speter If they were modified, a record was made in undobuf so that 298618334Speter undo_all will (among other things) return X to its original state. 298718334Speter 298818334Speter If the number of changes necessary is too much to record to undo, 298918334Speter the excess changes are not made, so the result is invalid. 299018334Speter The changes already made can still be undone. 299118334Speter undobuf.num_undo is incremented for such changes, so by testing that 299218334Speter the caller can tell whether the result is valid. 299318334Speter 299418334Speter `n_occurrences' is incremented each time FROM is replaced. 299518334Speter 299618334Speter IN_DEST is non-zero if we are processing the SET_DEST of a SET. 299718334Speter 299818334Speter UNIQUE_COPY is non-zero if each substitution must be unique. We do this 299918334Speter by copying if `n_occurrences' is non-zero. */ 300018334Speter 300118334Speterstatic rtx 300218334Spetersubst (x, from, to, in_dest, unique_copy) 300318334Speter register rtx x, from, to; 300418334Speter int in_dest; 300518334Speter int unique_copy; 300618334Speter{ 300718334Speter register enum rtx_code code = GET_CODE (x); 300818334Speter enum machine_mode op0_mode = VOIDmode; 300918334Speter register char *fmt; 301018334Speter register int len, i; 301118334Speter rtx new; 301218334Speter 301318334Speter/* Two expressions are equal if they are identical copies of a shared 301418334Speter RTX or if they are both registers with the same register number 301518334Speter and mode. */ 301618334Speter 301718334Speter#define COMBINE_RTX_EQUAL_P(X,Y) \ 301818334Speter ((X) == (Y) \ 301918334Speter || (GET_CODE (X) == REG && GET_CODE (Y) == REG \ 302018334Speter && REGNO (X) == REGNO (Y) && GET_MODE (X) == GET_MODE (Y))) 302118334Speter 302218334Speter if (! in_dest && COMBINE_RTX_EQUAL_P (x, from)) 302318334Speter { 302418334Speter n_occurrences++; 302518334Speter return (unique_copy && n_occurrences > 1 ? copy_rtx (to) : to); 302618334Speter } 302718334Speter 302818334Speter /* If X and FROM are the same register but different modes, they will 302918334Speter not have been seen as equal above. However, flow.c will make a 303018334Speter LOG_LINKS entry for that case. If we do nothing, we will try to 303118334Speter rerecognize our original insn and, when it succeeds, we will 303218334Speter delete the feeding insn, which is incorrect. 303318334Speter 303418334Speter So force this insn not to match in this (rare) case. */ 303518334Speter if (! in_dest && code == REG && GET_CODE (from) == REG 303618334Speter && REGNO (x) == REGNO (from)) 303750397Sobrien return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx); 303818334Speter 303918334Speter /* If this is an object, we are done unless it is a MEM or LO_SUM, both 304018334Speter of which may contain things that can be combined. */ 304118334Speter if (code != MEM && code != LO_SUM && GET_RTX_CLASS (code) == 'o') 304218334Speter return x; 304318334Speter 304418334Speter /* It is possible to have a subexpression appear twice in the insn. 304518334Speter Suppose that FROM is a register that appears within TO. 304618334Speter Then, after that subexpression has been scanned once by `subst', 304718334Speter the second time it is scanned, TO may be found. If we were 304818334Speter to scan TO here, we would find FROM within it and create a 304918334Speter self-referent rtl structure which is completely wrong. */ 305018334Speter if (COMBINE_RTX_EQUAL_P (x, to)) 305118334Speter return to; 305218334Speter 305350397Sobrien /* Parallel asm_operands need special attention because all of the 305450397Sobrien inputs are shared across the arms. Furthermore, unsharing the 305550397Sobrien rtl results in recognition failures. Failure to handle this case 305650397Sobrien specially can result in circular rtl. 305718334Speter 305850397Sobrien Solve this by doing a normal pass across the first entry of the 305950397Sobrien parallel, and only processing the SET_DESTs of the subsequent 306050397Sobrien entries. Ug. */ 306118334Speter 306250397Sobrien if (code == PARALLEL 306350397Sobrien && GET_CODE (XVECEXP (x, 0, 0)) == SET 306450397Sobrien && GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS) 306550397Sobrien { 306650397Sobrien new = subst (XVECEXP (x, 0, 0), from, to, 0, unique_copy); 306718334Speter 306850397Sobrien /* If this substitution failed, this whole thing fails. */ 306950397Sobrien if (GET_CODE (new) == CLOBBER 307050397Sobrien && XEXP (new, 0) == const0_rtx) 307150397Sobrien return new; 307250397Sobrien 307350397Sobrien SUBST (XVECEXP (x, 0, 0), new); 307450397Sobrien 307550397Sobrien for (i = XVECLEN (x, 0) - 1; i >= 1; i--) 307618334Speter { 307750397Sobrien rtx dest = SET_DEST (XVECEXP (x, 0, i)); 307850397Sobrien 307950397Sobrien if (GET_CODE (dest) != REG 308050397Sobrien && GET_CODE (dest) != CC0 308150397Sobrien && GET_CODE (dest) != PC) 308218334Speter { 308350397Sobrien new = subst (dest, from, to, 0, unique_copy); 308418334Speter 308550397Sobrien /* If this substitution failed, this whole thing fails. */ 308650397Sobrien if (GET_CODE (new) == CLOBBER 308750397Sobrien && XEXP (new, 0) == const0_rtx) 308850397Sobrien return new; 308918334Speter 309050397Sobrien SUBST (SET_DEST (XVECEXP (x, 0, i)), new); 309118334Speter } 309218334Speter } 309350397Sobrien } 309450397Sobrien else 309550397Sobrien { 309650397Sobrien len = GET_RTX_LENGTH (code); 309750397Sobrien fmt = GET_RTX_FORMAT (code); 309850397Sobrien 309950397Sobrien /* We don't need to process a SET_DEST that is a register, CC0, 310050397Sobrien or PC, so set up to skip this common case. All other cases 310150397Sobrien where we want to suppress replacing something inside a 310250397Sobrien SET_SRC are handled via the IN_DEST operand. */ 310350397Sobrien if (code == SET 310450397Sobrien && (GET_CODE (SET_DEST (x)) == REG 310550397Sobrien || GET_CODE (SET_DEST (x)) == CC0 310650397Sobrien || GET_CODE (SET_DEST (x)) == PC)) 310750397Sobrien fmt = "ie"; 310850397Sobrien 310950397Sobrien /* Get the mode of operand 0 in case X is now a SIGN_EXTEND of a 311050397Sobrien constant. */ 311150397Sobrien if (fmt[0] == 'e') 311250397Sobrien op0_mode = GET_MODE (XEXP (x, 0)); 311350397Sobrien 311450397Sobrien for (i = 0; i < len; i++) 311518334Speter { 311650397Sobrien if (fmt[i] == 'E') 311718334Speter { 311850397Sobrien register int j; 311950397Sobrien for (j = XVECLEN (x, i) - 1; j >= 0; j--) 312050397Sobrien { 312150397Sobrien if (COMBINE_RTX_EQUAL_P (XVECEXP (x, i, j), from)) 312250397Sobrien { 312350397Sobrien new = (unique_copy && n_occurrences 312450397Sobrien ? copy_rtx (to) : to); 312550397Sobrien n_occurrences++; 312650397Sobrien } 312750397Sobrien else 312850397Sobrien { 312950397Sobrien new = subst (XVECEXP (x, i, j), from, to, 0, 313050397Sobrien unique_copy); 313118334Speter 313250397Sobrien /* If this substitution failed, this whole thing 313350397Sobrien fails. */ 313450397Sobrien if (GET_CODE (new) == CLOBBER 313550397Sobrien && XEXP (new, 0) == const0_rtx) 313650397Sobrien return new; 313750397Sobrien } 313850397Sobrien 313950397Sobrien SUBST (XVECEXP (x, i, j), new); 314050397Sobrien } 314150397Sobrien } 314250397Sobrien else if (fmt[i] == 'e') 314350397Sobrien { 314450397Sobrien if (COMBINE_RTX_EQUAL_P (XEXP (x, i), from)) 314550397Sobrien { 314650397Sobrien /* In general, don't install a subreg involving two 314750397Sobrien modes not tieable. It can worsen register 314850397Sobrien allocation, and can even make invalid reload 314950397Sobrien insns, since the reg inside may need to be copied 315050397Sobrien from in the outside mode, and that may be invalid 315150397Sobrien if it is an fp reg copied in integer mode. 315250397Sobrien 315350397Sobrien We allow two exceptions to this: It is valid if 315450397Sobrien it is inside another SUBREG and the mode of that 315550397Sobrien SUBREG and the mode of the inside of TO is 315650397Sobrien tieable and it is valid if X is a SET that copies 315750397Sobrien FROM to CC0. */ 315850397Sobrien 315950397Sobrien if (GET_CODE (to) == SUBREG 316050397Sobrien && ! MODES_TIEABLE_P (GET_MODE (to), 316150397Sobrien GET_MODE (SUBREG_REG (to))) 316250397Sobrien && ! (code == SUBREG 316350397Sobrien && MODES_TIEABLE_P (GET_MODE (x), 316450397Sobrien GET_MODE (SUBREG_REG (to)))) 316518334Speter#ifdef HAVE_cc0 316650397Sobrien && ! (code == SET && i == 1 && XEXP (x, 0) == cc0_rtx) 316718334Speter#endif 316850397Sobrien ) 316950397Sobrien return gen_rtx_CLOBBER (VOIDmode, const0_rtx); 317018334Speter 317150397Sobrien new = (unique_copy && n_occurrences ? copy_rtx (to) : to); 317250397Sobrien n_occurrences++; 317350397Sobrien } 317450397Sobrien else 317550397Sobrien /* If we are in a SET_DEST, suppress most cases unless we 317650397Sobrien have gone inside a MEM, in which case we want to 317750397Sobrien simplify the address. We assume here that things that 317850397Sobrien are actually part of the destination have their inner 317950397Sobrien parts in the first expression. This is true for SUBREG, 318050397Sobrien STRICT_LOW_PART, and ZERO_EXTRACT, which are the only 318150397Sobrien things aside from REG and MEM that should appear in a 318250397Sobrien SET_DEST. */ 318350397Sobrien new = subst (XEXP (x, i), from, to, 318450397Sobrien (((in_dest 318550397Sobrien && (code == SUBREG || code == STRICT_LOW_PART 318650397Sobrien || code == ZERO_EXTRACT)) 318750397Sobrien || code == SET) 318850397Sobrien && i == 0), unique_copy); 318918334Speter 319050397Sobrien /* If we found that we will have to reject this combination, 319150397Sobrien indicate that by returning the CLOBBER ourselves, rather than 319250397Sobrien an expression containing it. This will speed things up as 319350397Sobrien well as prevent accidents where two CLOBBERs are considered 319450397Sobrien to be equal, thus producing an incorrect simplification. */ 319518334Speter 319650397Sobrien if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx) 319750397Sobrien return new; 319818334Speter 319950397Sobrien SUBST (XEXP (x, i), new); 320050397Sobrien } 320118334Speter } 320218334Speter } 320318334Speter 320418334Speter /* Try to simplify X. If the simplification changed the code, it is likely 320518334Speter that further simplification will help, so loop, but limit the number 320618334Speter of repetitions that will be performed. */ 320718334Speter 320818334Speter for (i = 0; i < 4; i++) 320918334Speter { 321018334Speter /* If X is sufficiently simple, don't bother trying to do anything 321118334Speter with it. */ 321218334Speter if (code != CONST_INT && code != REG && code != CLOBBER) 321318334Speter x = simplify_rtx (x, op0_mode, i == 3, in_dest); 321418334Speter 321518334Speter if (GET_CODE (x) == code) 321618334Speter break; 321718334Speter 321818334Speter code = GET_CODE (x); 321918334Speter 322018334Speter /* We no longer know the original mode of operand 0 since we 322118334Speter have changed the form of X) */ 322218334Speter op0_mode = VOIDmode; 322318334Speter } 322418334Speter 322518334Speter return x; 322618334Speter} 322718334Speter 322818334Speter/* Simplify X, a piece of RTL. We just operate on the expression at the 322918334Speter outer level; call `subst' to simplify recursively. Return the new 323018334Speter expression. 323118334Speter 323218334Speter OP0_MODE is the original mode of XEXP (x, 0); LAST is nonzero if this 323318334Speter will be the iteration even if an expression with a code different from 323418334Speter X is returned; IN_DEST is nonzero if we are inside a SET_DEST. */ 323518334Speter 323618334Speterstatic rtx 323718334Spetersimplify_rtx (x, op0_mode, last, in_dest) 323818334Speter rtx x; 323918334Speter enum machine_mode op0_mode; 324018334Speter int last; 324118334Speter int in_dest; 324218334Speter{ 324318334Speter enum rtx_code code = GET_CODE (x); 324418334Speter enum machine_mode mode = GET_MODE (x); 324518334Speter rtx temp; 324618334Speter int i; 324718334Speter 324818334Speter /* If this is a commutative operation, put a constant last and a complex 324918334Speter expression first. We don't need to do this for comparisons here. */ 325018334Speter if (GET_RTX_CLASS (code) == 'c' 325118334Speter && ((CONSTANT_P (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) != CONST_INT) 325218334Speter || (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == 'o' 325318334Speter && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) != 'o') 325418334Speter || (GET_CODE (XEXP (x, 0)) == SUBREG 325518334Speter && GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0)))) == 'o' 325618334Speter && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) != 'o'))) 325718334Speter { 325818334Speter temp = XEXP (x, 0); 325918334Speter SUBST (XEXP (x, 0), XEXP (x, 1)); 326018334Speter SUBST (XEXP (x, 1), temp); 326118334Speter } 326218334Speter 326318334Speter /* If this is a PLUS, MINUS, or MULT, and the first operand is the 326418334Speter sign extension of a PLUS with a constant, reverse the order of the sign 326518334Speter extension and the addition. Note that this not the same as the original 326618334Speter code, but overflow is undefined for signed values. Also note that the 326718334Speter PLUS will have been partially moved "inside" the sign-extension, so that 326818334Speter the first operand of X will really look like: 326918334Speter (ashiftrt (plus (ashift A C4) C5) C4). 327018334Speter We convert this to 327118334Speter (plus (ashiftrt (ashift A C4) C2) C4) 327218334Speter and replace the first operand of X with that expression. Later parts 327318334Speter of this function may simplify the expression further. 327418334Speter 327518334Speter For example, if we start with (mult (sign_extend (plus A C1)) C2), 327618334Speter we swap the SIGN_EXTEND and PLUS. Later code will apply the 327718334Speter distributive law to produce (plus (mult (sign_extend X) C1) C3). 327818334Speter 327918334Speter We do this to simplify address expressions. */ 328018334Speter 328118334Speter if ((code == PLUS || code == MINUS || code == MULT) 328218334Speter && GET_CODE (XEXP (x, 0)) == ASHIFTRT 328318334Speter && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS 328418334Speter && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ASHIFT 328518334Speter && GET_CODE (XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 1)) == CONST_INT 328618334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 328718334Speter && XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 1) == XEXP (XEXP (x, 0), 1) 328818334Speter && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT 328918334Speter && (temp = simplify_binary_operation (ASHIFTRT, mode, 329018334Speter XEXP (XEXP (XEXP (x, 0), 0), 1), 329118334Speter XEXP (XEXP (x, 0), 1))) != 0) 329218334Speter { 329318334Speter rtx new 329418334Speter = simplify_shift_const (NULL_RTX, ASHIFT, mode, 329518334Speter XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 0), 329618334Speter INTVAL (XEXP (XEXP (x, 0), 1))); 329718334Speter 329818334Speter new = simplify_shift_const (NULL_RTX, ASHIFTRT, mode, new, 329918334Speter INTVAL (XEXP (XEXP (x, 0), 1))); 330018334Speter 330118334Speter SUBST (XEXP (x, 0), gen_binary (PLUS, mode, new, temp)); 330218334Speter } 330318334Speter 330418334Speter /* If this is a simple operation applied to an IF_THEN_ELSE, try 330518334Speter applying it to the arms of the IF_THEN_ELSE. This often simplifies 330618334Speter things. Check for cases where both arms are testing the same 330718334Speter condition. 330818334Speter 330918334Speter Don't do anything if all operands are very simple. */ 331018334Speter 331118334Speter if (((GET_RTX_CLASS (code) == '2' || GET_RTX_CLASS (code) == 'c' 331218334Speter || GET_RTX_CLASS (code) == '<') 331318334Speter && ((GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) != 'o' 331418334Speter && ! (GET_CODE (XEXP (x, 0)) == SUBREG 331518334Speter && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0)))) 331618334Speter == 'o'))) 331718334Speter || (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) != 'o' 331818334Speter && ! (GET_CODE (XEXP (x, 1)) == SUBREG 331918334Speter && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 1)))) 332018334Speter == 'o'))))) 332118334Speter || (GET_RTX_CLASS (code) == '1' 332218334Speter && ((GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) != 'o' 332318334Speter && ! (GET_CODE (XEXP (x, 0)) == SUBREG 332418334Speter && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0)))) 332518334Speter == 'o')))))) 332618334Speter { 332718334Speter rtx cond, true, false; 332818334Speter 332918334Speter cond = if_then_else_cond (x, &true, &false); 333050397Sobrien if (cond != 0 333150397Sobrien /* If everything is a comparison, what we have is highly unlikely 333250397Sobrien to be simpler, so don't use it. */ 333350397Sobrien && ! (GET_RTX_CLASS (code) == '<' 333450397Sobrien && (GET_RTX_CLASS (GET_CODE (true)) == '<' 333550397Sobrien || GET_RTX_CLASS (GET_CODE (false)) == '<'))) 333618334Speter { 333718334Speter rtx cop1 = const0_rtx; 333818334Speter enum rtx_code cond_code = simplify_comparison (NE, &cond, &cop1); 333918334Speter 334018334Speter if (cond_code == NE && GET_RTX_CLASS (GET_CODE (cond)) == '<') 334118334Speter return x; 334218334Speter 334318334Speter /* Simplify the alternative arms; this may collapse the true and 334418334Speter false arms to store-flag values. */ 334518334Speter true = subst (true, pc_rtx, pc_rtx, 0, 0); 334618334Speter false = subst (false, pc_rtx, pc_rtx, 0, 0); 334718334Speter 334818334Speter /* Restarting if we generate a store-flag expression will cause 334918334Speter us to loop. Just drop through in this case. */ 335018334Speter 335118334Speter /* If the result values are STORE_FLAG_VALUE and zero, we can 335218334Speter just make the comparison operation. */ 335318334Speter if (true == const_true_rtx && false == const0_rtx) 335418334Speter x = gen_binary (cond_code, mode, cond, cop1); 335518334Speter else if (true == const0_rtx && false == const_true_rtx) 335618334Speter x = gen_binary (reverse_condition (cond_code), mode, cond, cop1); 335718334Speter 335818334Speter /* Likewise, we can make the negate of a comparison operation 335918334Speter if the result values are - STORE_FLAG_VALUE and zero. */ 336018334Speter else if (GET_CODE (true) == CONST_INT 336118334Speter && INTVAL (true) == - STORE_FLAG_VALUE 336218334Speter && false == const0_rtx) 336318334Speter x = gen_unary (NEG, mode, mode, 336418334Speter gen_binary (cond_code, mode, cond, cop1)); 336518334Speter else if (GET_CODE (false) == CONST_INT 336618334Speter && INTVAL (false) == - STORE_FLAG_VALUE 336718334Speter && true == const0_rtx) 336818334Speter x = gen_unary (NEG, mode, mode, 336918334Speter gen_binary (reverse_condition (cond_code), 337018334Speter mode, cond, cop1)); 337118334Speter else 337250397Sobrien return gen_rtx_IF_THEN_ELSE (mode, 337350397Sobrien gen_binary (cond_code, VOIDmode, 337450397Sobrien cond, cop1), 337550397Sobrien true, false); 337618334Speter 337718334Speter code = GET_CODE (x); 337818334Speter op0_mode = VOIDmode; 337918334Speter } 338018334Speter } 338118334Speter 338218334Speter /* Try to fold this expression in case we have constants that weren't 338318334Speter present before. */ 338418334Speter temp = 0; 338518334Speter switch (GET_RTX_CLASS (code)) 338618334Speter { 338718334Speter case '1': 338818334Speter temp = simplify_unary_operation (code, mode, XEXP (x, 0), op0_mode); 338918334Speter break; 339018334Speter case '<': 339118334Speter temp = simplify_relational_operation (code, op0_mode, 339218334Speter XEXP (x, 0), XEXP (x, 1)); 339318334Speter#ifdef FLOAT_STORE_FLAG_VALUE 339418334Speter if (temp != 0 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) 339518334Speter temp = ((temp == const0_rtx) ? CONST0_RTX (GET_MODE (x)) 339618334Speter : immed_real_const_1 (FLOAT_STORE_FLAG_VALUE, GET_MODE (x))); 339718334Speter#endif 339818334Speter break; 339918334Speter case 'c': 340018334Speter case '2': 340118334Speter temp = simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1)); 340218334Speter break; 340318334Speter case 'b': 340418334Speter case '3': 340518334Speter temp = simplify_ternary_operation (code, mode, op0_mode, XEXP (x, 0), 340618334Speter XEXP (x, 1), XEXP (x, 2)); 340718334Speter break; 340818334Speter } 340918334Speter 341018334Speter if (temp) 341118334Speter x = temp, code = GET_CODE (temp); 341218334Speter 341318334Speter /* First see if we can apply the inverse distributive law. */ 341418334Speter if (code == PLUS || code == MINUS 341518334Speter || code == AND || code == IOR || code == XOR) 341618334Speter { 341718334Speter x = apply_distributive_law (x); 341818334Speter code = GET_CODE (x); 341918334Speter } 342018334Speter 342118334Speter /* If CODE is an associative operation not otherwise handled, see if we 342218334Speter can associate some operands. This can win if they are constants or 342318334Speter if they are logically related (i.e. (a & b) & a. */ 342418334Speter if ((code == PLUS || code == MINUS 342518334Speter || code == MULT || code == AND || code == IOR || code == XOR 342618334Speter || code == DIV || code == UDIV 342718334Speter || code == SMAX || code == SMIN || code == UMAX || code == UMIN) 342818334Speter && INTEGRAL_MODE_P (mode)) 342918334Speter { 343018334Speter if (GET_CODE (XEXP (x, 0)) == code) 343118334Speter { 343218334Speter rtx other = XEXP (XEXP (x, 0), 0); 343318334Speter rtx inner_op0 = XEXP (XEXP (x, 0), 1); 343418334Speter rtx inner_op1 = XEXP (x, 1); 343518334Speter rtx inner; 343618334Speter 343718334Speter /* Make sure we pass the constant operand if any as the second 343818334Speter one if this is a commutative operation. */ 343918334Speter if (CONSTANT_P (inner_op0) && GET_RTX_CLASS (code) == 'c') 344018334Speter { 344118334Speter rtx tem = inner_op0; 344218334Speter inner_op0 = inner_op1; 344318334Speter inner_op1 = tem; 344418334Speter } 344518334Speter inner = simplify_binary_operation (code == MINUS ? PLUS 344618334Speter : code == DIV ? MULT 344718334Speter : code == UDIV ? MULT 344818334Speter : code, 344918334Speter mode, inner_op0, inner_op1); 345018334Speter 345118334Speter /* For commutative operations, try the other pair if that one 345218334Speter didn't simplify. */ 345318334Speter if (inner == 0 && GET_RTX_CLASS (code) == 'c') 345418334Speter { 345518334Speter other = XEXP (XEXP (x, 0), 1); 345618334Speter inner = simplify_binary_operation (code, mode, 345718334Speter XEXP (XEXP (x, 0), 0), 345818334Speter XEXP (x, 1)); 345918334Speter } 346018334Speter 346118334Speter if (inner) 346218334Speter return gen_binary (code, mode, other, inner); 346318334Speter } 346418334Speter } 346518334Speter 346618334Speter /* A little bit of algebraic simplification here. */ 346718334Speter switch (code) 346818334Speter { 346918334Speter case MEM: 347018334Speter /* Ensure that our address has any ASHIFTs converted to MULT in case 347118334Speter address-recognizing predicates are called later. */ 347218334Speter temp = make_compound_operation (XEXP (x, 0), MEM); 347318334Speter SUBST (XEXP (x, 0), temp); 347418334Speter break; 347518334Speter 347618334Speter case SUBREG: 347718334Speter /* (subreg:A (mem:B X) N) becomes a modified MEM unless the SUBREG 347818334Speter is paradoxical. If we can't do that safely, then it becomes 347918334Speter something nonsensical so that this combination won't take place. */ 348018334Speter 348118334Speter if (GET_CODE (SUBREG_REG (x)) == MEM 348218334Speter && (GET_MODE_SIZE (mode) 348318334Speter <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))) 348418334Speter { 348518334Speter rtx inner = SUBREG_REG (x); 348618334Speter int endian_offset = 0; 348718334Speter /* Don't change the mode of the MEM 348818334Speter if that would change the meaning of the address. */ 348918334Speter if (MEM_VOLATILE_P (SUBREG_REG (x)) 349018334Speter || mode_dependent_address_p (XEXP (inner, 0))) 349150397Sobrien return gen_rtx_CLOBBER (mode, const0_rtx); 349218334Speter 349318334Speter if (BYTES_BIG_ENDIAN) 349418334Speter { 349518334Speter if (GET_MODE_SIZE (mode) < UNITS_PER_WORD) 349618334Speter endian_offset += UNITS_PER_WORD - GET_MODE_SIZE (mode); 349718334Speter if (GET_MODE_SIZE (GET_MODE (inner)) < UNITS_PER_WORD) 349818334Speter endian_offset -= (UNITS_PER_WORD 349918334Speter - GET_MODE_SIZE (GET_MODE (inner))); 350018334Speter } 350118334Speter /* Note if the plus_constant doesn't make a valid address 350218334Speter then this combination won't be accepted. */ 350350397Sobrien x = gen_rtx_MEM (mode, 350450397Sobrien plus_constant (XEXP (inner, 0), 350550397Sobrien (SUBREG_WORD (x) * UNITS_PER_WORD 350650397Sobrien + endian_offset))); 350718334Speter RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (inner); 350852284Sobrien MEM_COPY_ATTRIBUTES (x, inner); 350918334Speter return x; 351018334Speter } 351118334Speter 351218334Speter /* If we are in a SET_DEST, these other cases can't apply. */ 351318334Speter if (in_dest) 351418334Speter return x; 351518334Speter 351618334Speter /* Changing mode twice with SUBREG => just change it once, 351718334Speter or not at all if changing back to starting mode. */ 351818334Speter if (GET_CODE (SUBREG_REG (x)) == SUBREG) 351918334Speter { 352018334Speter if (mode == GET_MODE (SUBREG_REG (SUBREG_REG (x))) 352118334Speter && SUBREG_WORD (x) == 0 && SUBREG_WORD (SUBREG_REG (x)) == 0) 352218334Speter return SUBREG_REG (SUBREG_REG (x)); 352318334Speter 352418334Speter SUBST_INT (SUBREG_WORD (x), 352518334Speter SUBREG_WORD (x) + SUBREG_WORD (SUBREG_REG (x))); 352618334Speter SUBST (SUBREG_REG (x), SUBREG_REG (SUBREG_REG (x))); 352718334Speter } 352818334Speter 352918334Speter /* SUBREG of a hard register => just change the register number 353018334Speter and/or mode. If the hard register is not valid in that mode, 353118334Speter suppress this combination. If the hard register is the stack, 353218334Speter frame, or argument pointer, leave this as a SUBREG. */ 353318334Speter 353418334Speter if (GET_CODE (SUBREG_REG (x)) == REG 353518334Speter && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER 353618334Speter && REGNO (SUBREG_REG (x)) != FRAME_POINTER_REGNUM 353718334Speter#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM 353818334Speter && REGNO (SUBREG_REG (x)) != HARD_FRAME_POINTER_REGNUM 353918334Speter#endif 354018334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM 354118334Speter && REGNO (SUBREG_REG (x)) != ARG_POINTER_REGNUM 354218334Speter#endif 354318334Speter && REGNO (SUBREG_REG (x)) != STACK_POINTER_REGNUM) 354418334Speter { 354518334Speter if (HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (x)) + SUBREG_WORD (x), 354618334Speter mode)) 354750397Sobrien return gen_rtx_REG (mode, 354850397Sobrien REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)); 354918334Speter else 355050397Sobrien return gen_rtx_CLOBBER (mode, const0_rtx); 355118334Speter } 355218334Speter 355318334Speter /* For a constant, try to pick up the part we want. Handle a full 355418334Speter word and low-order part. Only do this if we are narrowing 355518334Speter the constant; if it is being widened, we have no idea what 355618334Speter the extra bits will have been set to. */ 355718334Speter 355818334Speter if (CONSTANT_P (SUBREG_REG (x)) && op0_mode != VOIDmode 355918334Speter && GET_MODE_SIZE (mode) == UNITS_PER_WORD 356050397Sobrien && GET_MODE_SIZE (op0_mode) > UNITS_PER_WORD 356118334Speter && GET_MODE_CLASS (mode) == MODE_INT) 356218334Speter { 356318334Speter temp = operand_subword (SUBREG_REG (x), SUBREG_WORD (x), 356418334Speter 0, op0_mode); 356518334Speter if (temp) 356618334Speter return temp; 356718334Speter } 356818334Speter 356918334Speter /* If we want a subreg of a constant, at offset 0, 357018334Speter take the low bits. On a little-endian machine, that's 357118334Speter always valid. On a big-endian machine, it's valid 357250397Sobrien only if the constant's mode fits in one word. Note that we 357350397Sobrien cannot use subreg_lowpart_p since SUBREG_REG may be VOIDmode. */ 357450397Sobrien if (CONSTANT_P (SUBREG_REG (x)) 357550397Sobrien && ((GET_MODE_SIZE (op0_mode) <= UNITS_PER_WORD 357650397Sobrien || ! WORDS_BIG_ENDIAN) 357750397Sobrien ? SUBREG_WORD (x) == 0 357850397Sobrien : (SUBREG_WORD (x) 357950397Sobrien == ((GET_MODE_SIZE (op0_mode) 358050397Sobrien - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)) 358150397Sobrien / UNITS_PER_WORD))) 358250397Sobrien && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (op0_mode) 358318334Speter && (! WORDS_BIG_ENDIAN 358418334Speter || GET_MODE_BITSIZE (op0_mode) <= BITS_PER_WORD)) 358518334Speter return gen_lowpart_for_combine (mode, SUBREG_REG (x)); 358618334Speter 358718334Speter /* A paradoxical SUBREG of a VOIDmode constant is the same constant, 358818334Speter since we are saying that the high bits don't matter. */ 358918334Speter if (CONSTANT_P (SUBREG_REG (x)) && GET_MODE (SUBREG_REG (x)) == VOIDmode 359018334Speter && GET_MODE_SIZE (mode) > GET_MODE_SIZE (op0_mode)) 359118334Speter return SUBREG_REG (x); 359218334Speter 359318334Speter /* Note that we cannot do any narrowing for non-constants since 359418334Speter we might have been counting on using the fact that some bits were 359518334Speter zero. We now do this in the SET. */ 359618334Speter 359718334Speter break; 359818334Speter 359918334Speter case NOT: 360018334Speter /* (not (plus X -1)) can become (neg X). */ 360118334Speter if (GET_CODE (XEXP (x, 0)) == PLUS 360218334Speter && XEXP (XEXP (x, 0), 1) == constm1_rtx) 360318334Speter return gen_rtx_combine (NEG, mode, XEXP (XEXP (x, 0), 0)); 360418334Speter 360518334Speter /* Similarly, (not (neg X)) is (plus X -1). */ 360618334Speter if (GET_CODE (XEXP (x, 0)) == NEG) 360718334Speter return gen_rtx_combine (PLUS, mode, XEXP (XEXP (x, 0), 0), 360818334Speter constm1_rtx); 360918334Speter 361018334Speter /* (not (xor X C)) for C constant is (xor X D) with D = ~ C. */ 361118334Speter if (GET_CODE (XEXP (x, 0)) == XOR 361218334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 361318334Speter && (temp = simplify_unary_operation (NOT, mode, 361418334Speter XEXP (XEXP (x, 0), 1), 361518334Speter mode)) != 0) 361618334Speter return gen_binary (XOR, mode, XEXP (XEXP (x, 0), 0), temp); 361718334Speter 361818334Speter /* (not (ashift 1 X)) is (rotate ~1 X). We used to do this for operands 361918334Speter other than 1, but that is not valid. We could do a similar 362018334Speter simplification for (not (lshiftrt C X)) where C is just the sign bit, 362118334Speter but this doesn't seem common enough to bother with. */ 362218334Speter if (GET_CODE (XEXP (x, 0)) == ASHIFT 362318334Speter && XEXP (XEXP (x, 0), 0) == const1_rtx) 362450397Sobrien return gen_rtx_ROTATE (mode, gen_unary (NOT, mode, mode, const1_rtx), 362550397Sobrien XEXP (XEXP (x, 0), 1)); 362618334Speter 362718334Speter if (GET_CODE (XEXP (x, 0)) == SUBREG 362818334Speter && subreg_lowpart_p (XEXP (x, 0)) 362918334Speter && (GET_MODE_SIZE (GET_MODE (XEXP (x, 0))) 363018334Speter < GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (x, 0))))) 363118334Speter && GET_CODE (SUBREG_REG (XEXP (x, 0))) == ASHIFT 363218334Speter && XEXP (SUBREG_REG (XEXP (x, 0)), 0) == const1_rtx) 363318334Speter { 363418334Speter enum machine_mode inner_mode = GET_MODE (SUBREG_REG (XEXP (x, 0))); 363518334Speter 363650397Sobrien x = gen_rtx_ROTATE (inner_mode, 363750397Sobrien gen_unary (NOT, inner_mode, inner_mode, 363850397Sobrien const1_rtx), 363950397Sobrien XEXP (SUBREG_REG (XEXP (x, 0)), 1)); 364018334Speter return gen_lowpart_for_combine (mode, x); 364118334Speter } 364218334Speter 364350397Sobrien /* If STORE_FLAG_VALUE is -1, (not (comparison foo bar)) can be done by 364450397Sobrien reversing the comparison code if valid. */ 364550397Sobrien if (STORE_FLAG_VALUE == -1 364650397Sobrien && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<' 364718334Speter && reversible_comparison_p (XEXP (x, 0))) 364818334Speter return gen_rtx_combine (reverse_condition (GET_CODE (XEXP (x, 0))), 364918334Speter mode, XEXP (XEXP (x, 0), 0), 365018334Speter XEXP (XEXP (x, 0), 1)); 365118334Speter 365218334Speter /* (ashiftrt foo C) where C is the number of bits in FOO minus 1 365350397Sobrien is (lt foo (const_int 0)) if STORE_FLAG_VALUE is -1, so we can 365450397Sobrien perform the above simplification. */ 365518334Speter 365650397Sobrien if (STORE_FLAG_VALUE == -1 365750397Sobrien && XEXP (x, 1) == const1_rtx 365818334Speter && GET_CODE (XEXP (x, 0)) == ASHIFTRT 365918334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 366018334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) == GET_MODE_BITSIZE (mode) - 1) 366118334Speter return gen_rtx_combine (GE, mode, XEXP (XEXP (x, 0), 0), const0_rtx); 366218334Speter 366318334Speter /* Apply De Morgan's laws to reduce number of patterns for machines 366418334Speter with negating logical insns (and-not, nand, etc.). If result has 366518334Speter only one NOT, put it first, since that is how the patterns are 366618334Speter coded. */ 366718334Speter 366818334Speter if (GET_CODE (XEXP (x, 0)) == IOR || GET_CODE (XEXP (x, 0)) == AND) 366918334Speter { 367018334Speter rtx in1 = XEXP (XEXP (x, 0), 0), in2 = XEXP (XEXP (x, 0), 1); 367118334Speter 367218334Speter if (GET_CODE (in1) == NOT) 367318334Speter in1 = XEXP (in1, 0); 367418334Speter else 367518334Speter in1 = gen_rtx_combine (NOT, GET_MODE (in1), in1); 367618334Speter 367718334Speter if (GET_CODE (in2) == NOT) 367818334Speter in2 = XEXP (in2, 0); 367918334Speter else if (GET_CODE (in2) == CONST_INT 368018334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) 368118334Speter in2 = GEN_INT (GET_MODE_MASK (mode) & ~ INTVAL (in2)); 368218334Speter else 368318334Speter in2 = gen_rtx_combine (NOT, GET_MODE (in2), in2); 368418334Speter 368518334Speter if (GET_CODE (in2) == NOT) 368618334Speter { 368718334Speter rtx tem = in2; 368818334Speter in2 = in1; in1 = tem; 368918334Speter } 369018334Speter 369118334Speter return gen_rtx_combine (GET_CODE (XEXP (x, 0)) == IOR ? AND : IOR, 369218334Speter mode, in1, in2); 369318334Speter } 369418334Speter break; 369518334Speter 369618334Speter case NEG: 369718334Speter /* (neg (plus X 1)) can become (not X). */ 369818334Speter if (GET_CODE (XEXP (x, 0)) == PLUS 369918334Speter && XEXP (XEXP (x, 0), 1) == const1_rtx) 370018334Speter return gen_rtx_combine (NOT, mode, XEXP (XEXP (x, 0), 0)); 370118334Speter 370218334Speter /* Similarly, (neg (not X)) is (plus X 1). */ 370318334Speter if (GET_CODE (XEXP (x, 0)) == NOT) 370418334Speter return plus_constant (XEXP (XEXP (x, 0), 0), 1); 370518334Speter 370618334Speter /* (neg (minus X Y)) can become (minus Y X). */ 370718334Speter if (GET_CODE (XEXP (x, 0)) == MINUS 370818334Speter && (! FLOAT_MODE_P (mode) 370950397Sobrien /* x-y != -(y-x) with IEEE floating point. */ 371018334Speter || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT 371118334Speter || flag_fast_math)) 371218334Speter return gen_binary (MINUS, mode, XEXP (XEXP (x, 0), 1), 371318334Speter XEXP (XEXP (x, 0), 0)); 371418334Speter 371550397Sobrien /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */ 371618334Speter if (GET_CODE (XEXP (x, 0)) == XOR && XEXP (XEXP (x, 0), 1) == const1_rtx 371718334Speter && nonzero_bits (XEXP (XEXP (x, 0), 0), mode) == 1) 371818334Speter return gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0), constm1_rtx); 371918334Speter 372018334Speter /* NEG commutes with ASHIFT since it is multiplication. Only do this 372118334Speter if we can then eliminate the NEG (e.g., 372218334Speter if the operand is a constant). */ 372318334Speter 372418334Speter if (GET_CODE (XEXP (x, 0)) == ASHIFT) 372518334Speter { 372618334Speter temp = simplify_unary_operation (NEG, mode, 372718334Speter XEXP (XEXP (x, 0), 0), mode); 372818334Speter if (temp) 372918334Speter { 373018334Speter SUBST (XEXP (XEXP (x, 0), 0), temp); 373118334Speter return XEXP (x, 0); 373218334Speter } 373318334Speter } 373418334Speter 373518334Speter temp = expand_compound_operation (XEXP (x, 0)); 373618334Speter 373718334Speter /* For C equal to the width of MODE minus 1, (neg (ashiftrt X C)) can be 373818334Speter replaced by (lshiftrt X C). This will convert 373918334Speter (neg (sign_extract X 1 Y)) to (zero_extract X 1 Y). */ 374018334Speter 374118334Speter if (GET_CODE (temp) == ASHIFTRT 374218334Speter && GET_CODE (XEXP (temp, 1)) == CONST_INT 374318334Speter && INTVAL (XEXP (temp, 1)) == GET_MODE_BITSIZE (mode) - 1) 374418334Speter return simplify_shift_const (temp, LSHIFTRT, mode, XEXP (temp, 0), 374518334Speter INTVAL (XEXP (temp, 1))); 374618334Speter 374718334Speter /* If X has only a single bit that might be nonzero, say, bit I, convert 374818334Speter (neg X) to (ashiftrt (ashift X C-I) C-I) where C is the bitsize of 374918334Speter MODE minus 1. This will convert (neg (zero_extract X 1 Y)) to 375018334Speter (sign_extract X 1 Y). But only do this if TEMP isn't a register 375118334Speter or a SUBREG of one since we'd be making the expression more 375218334Speter complex if it was just a register. */ 375318334Speter 375418334Speter if (GET_CODE (temp) != REG 375518334Speter && ! (GET_CODE (temp) == SUBREG 375618334Speter && GET_CODE (SUBREG_REG (temp)) == REG) 375718334Speter && (i = exact_log2 (nonzero_bits (temp, mode))) >= 0) 375818334Speter { 375918334Speter rtx temp1 = simplify_shift_const 376018334Speter (NULL_RTX, ASHIFTRT, mode, 376118334Speter simplify_shift_const (NULL_RTX, ASHIFT, mode, temp, 376218334Speter GET_MODE_BITSIZE (mode) - 1 - i), 376318334Speter GET_MODE_BITSIZE (mode) - 1 - i); 376418334Speter 376518334Speter /* If all we did was surround TEMP with the two shifts, we 376618334Speter haven't improved anything, so don't use it. Otherwise, 376718334Speter we are better off with TEMP1. */ 376818334Speter if (GET_CODE (temp1) != ASHIFTRT 376918334Speter || GET_CODE (XEXP (temp1, 0)) != ASHIFT 377018334Speter || XEXP (XEXP (temp1, 0), 0) != temp) 377118334Speter return temp1; 377218334Speter } 377318334Speter break; 377418334Speter 377518334Speter case TRUNCATE: 377650397Sobrien /* We can't handle truncation to a partial integer mode here 377750397Sobrien because we don't know the real bitsize of the partial 377850397Sobrien integer mode. */ 377950397Sobrien if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT) 378050397Sobrien break; 378150397Sobrien 378250397Sobrien if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 378350397Sobrien && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode), 378450397Sobrien GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))))) 378518334Speter SUBST (XEXP (x, 0), 378618334Speter force_to_mode (XEXP (x, 0), GET_MODE (XEXP (x, 0)), 378718334Speter GET_MODE_MASK (mode), NULL_RTX, 0)); 378850397Sobrien 378950397Sobrien /* (truncate:SI ({sign,zero}_extend:DI foo:SI)) == foo:SI. */ 379050397Sobrien if ((GET_CODE (XEXP (x, 0)) == SIGN_EXTEND 379150397Sobrien || GET_CODE (XEXP (x, 0)) == ZERO_EXTEND) 379250397Sobrien && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode) 379350397Sobrien return XEXP (XEXP (x, 0), 0); 379450397Sobrien 379550397Sobrien /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is 379650397Sobrien (OP:SI foo:SI) if OP is NEG or ABS. */ 379750397Sobrien if ((GET_CODE (XEXP (x, 0)) == ABS 379850397Sobrien || GET_CODE (XEXP (x, 0)) == NEG) 379950397Sobrien && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SIGN_EXTEND 380050397Sobrien || GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND) 380150397Sobrien && GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == mode) 380250397Sobrien return gen_unary (GET_CODE (XEXP (x, 0)), mode, mode, 380350397Sobrien XEXP (XEXP (XEXP (x, 0), 0), 0)); 380450397Sobrien 380550397Sobrien /* (truncate:SI (subreg:DI (truncate:SI X) 0)) is 380650397Sobrien (truncate:SI x). */ 380750397Sobrien if (GET_CODE (XEXP (x, 0)) == SUBREG 380850397Sobrien && GET_CODE (SUBREG_REG (XEXP (x, 0))) == TRUNCATE 380950397Sobrien && subreg_lowpart_p (XEXP (x, 0))) 381050397Sobrien return SUBREG_REG (XEXP (x, 0)); 381150397Sobrien 381250397Sobrien /* If we know that the value is already truncated, we can 381352284Sobrien replace the TRUNCATE with a SUBREG if TRULY_NOOP_TRUNCATION is 381452284Sobrien nonzero for the corresponding modes. */ 381552284Sobrien if (TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode), 381652284Sobrien GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))) 381752284Sobrien && num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0))) 381852284Sobrien >= GET_MODE_BITSIZE (mode) + 1) 381950397Sobrien return gen_lowpart_for_combine (mode, XEXP (x, 0)); 382050397Sobrien 382150397Sobrien /* A truncate of a comparison can be replaced with a subreg if 382250397Sobrien STORE_FLAG_VALUE permits. This is like the previous test, 382350397Sobrien but it works even if the comparison is done in a mode larger 382450397Sobrien than HOST_BITS_PER_WIDE_INT. */ 382550397Sobrien if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 382650397Sobrien && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<' 382750397Sobrien && ((HOST_WIDE_INT) STORE_FLAG_VALUE &~ GET_MODE_MASK (mode)) == 0) 382850397Sobrien return gen_lowpart_for_combine (mode, XEXP (x, 0)); 382950397Sobrien 383050397Sobrien /* Similarly, a truncate of a register whose value is a 383150397Sobrien comparison can be replaced with a subreg if STORE_FLAG_VALUE 383250397Sobrien permits. */ 383350397Sobrien if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 383450397Sobrien && ((HOST_WIDE_INT) STORE_FLAG_VALUE &~ GET_MODE_MASK (mode)) == 0 383550397Sobrien && (temp = get_last_value (XEXP (x, 0))) 383650397Sobrien && GET_RTX_CLASS (GET_CODE (temp)) == '<') 383750397Sobrien return gen_lowpart_for_combine (mode, XEXP (x, 0)); 383850397Sobrien 383918334Speter break; 384018334Speter 384118334Speter case FLOAT_TRUNCATE: 384218334Speter /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */ 384318334Speter if (GET_CODE (XEXP (x, 0)) == FLOAT_EXTEND 384418334Speter && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode) 384518334Speter return XEXP (XEXP (x, 0), 0); 384618334Speter 384718334Speter /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is 384818334Speter (OP:SF foo:SF) if OP is NEG or ABS. */ 384918334Speter if ((GET_CODE (XEXP (x, 0)) == ABS 385018334Speter || GET_CODE (XEXP (x, 0)) == NEG) 385118334Speter && GET_CODE (XEXP (XEXP (x, 0), 0)) == FLOAT_EXTEND 385218334Speter && GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == mode) 385318334Speter return gen_unary (GET_CODE (XEXP (x, 0)), mode, mode, 385418334Speter XEXP (XEXP (XEXP (x, 0), 0), 0)); 385518334Speter 385618334Speter /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0)) 385718334Speter is (float_truncate:SF x). */ 385818334Speter if (GET_CODE (XEXP (x, 0)) == SUBREG 385918334Speter && subreg_lowpart_p (XEXP (x, 0)) 386018334Speter && GET_CODE (SUBREG_REG (XEXP (x, 0))) == FLOAT_TRUNCATE) 386118334Speter return SUBREG_REG (XEXP (x, 0)); 386218334Speter break; 386318334Speter 386418334Speter#ifdef HAVE_cc0 386518334Speter case COMPARE: 386618334Speter /* Convert (compare FOO (const_int 0)) to FOO unless we aren't 386718334Speter using cc0, in which case we want to leave it as a COMPARE 386818334Speter so we can distinguish it from a register-register-copy. */ 386918334Speter if (XEXP (x, 1) == const0_rtx) 387018334Speter return XEXP (x, 0); 387118334Speter 387218334Speter /* In IEEE floating point, x-0 is not the same as x. */ 387318334Speter if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT 387418334Speter || ! FLOAT_MODE_P (GET_MODE (XEXP (x, 0))) 387518334Speter || flag_fast_math) 387618334Speter && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 0)))) 387718334Speter return XEXP (x, 0); 387818334Speter break; 387918334Speter#endif 388018334Speter 388118334Speter case CONST: 388218334Speter /* (const (const X)) can become (const X). Do it this way rather than 388318334Speter returning the inner CONST since CONST can be shared with a 388418334Speter REG_EQUAL note. */ 388518334Speter if (GET_CODE (XEXP (x, 0)) == CONST) 388618334Speter SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0)); 388718334Speter break; 388818334Speter 388918334Speter#ifdef HAVE_lo_sum 389018334Speter case LO_SUM: 389118334Speter /* Convert (lo_sum (high FOO) FOO) to FOO. This is necessary so we 389218334Speter can add in an offset. find_split_point will split this address up 389318334Speter again if it doesn't match. */ 389418334Speter if (GET_CODE (XEXP (x, 0)) == HIGH 389518334Speter && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1))) 389618334Speter return XEXP (x, 1); 389718334Speter break; 389818334Speter#endif 389918334Speter 390018334Speter case PLUS: 390118334Speter /* If we have (plus (plus (A const) B)), associate it so that CONST is 390218334Speter outermost. That's because that's the way indexed addresses are 390318334Speter supposed to appear. This code used to check many more cases, but 390418334Speter they are now checked elsewhere. */ 390518334Speter if (GET_CODE (XEXP (x, 0)) == PLUS 390618334Speter && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1))) 390718334Speter return gen_binary (PLUS, mode, 390818334Speter gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0), 390918334Speter XEXP (x, 1)), 391018334Speter XEXP (XEXP (x, 0), 1)); 391118334Speter 391218334Speter /* (plus (xor (and <foo> (const_int pow2 - 1)) <c>) <-c>) 391318334Speter when c is (const_int (pow2 + 1) / 2) is a sign extension of a 391418334Speter bit-field and can be replaced by either a sign_extend or a 391518334Speter sign_extract. The `and' may be a zero_extend. */ 391618334Speter if (GET_CODE (XEXP (x, 0)) == XOR 391718334Speter && GET_CODE (XEXP (x, 1)) == CONST_INT 391818334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 391918334Speter && INTVAL (XEXP (x, 1)) == - INTVAL (XEXP (XEXP (x, 0), 1)) 392018334Speter && (i = exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) >= 0 392118334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 392218334Speter && ((GET_CODE (XEXP (XEXP (x, 0), 0)) == AND 392318334Speter && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT 392418334Speter && (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)) 392518334Speter == ((HOST_WIDE_INT) 1 << (i + 1)) - 1)) 392618334Speter || (GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND 392718334Speter && (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0))) 392818334Speter == i + 1)))) 392918334Speter return simplify_shift_const 393018334Speter (NULL_RTX, ASHIFTRT, mode, 393118334Speter simplify_shift_const (NULL_RTX, ASHIFT, mode, 393218334Speter XEXP (XEXP (XEXP (x, 0), 0), 0), 393318334Speter GET_MODE_BITSIZE (mode) - (i + 1)), 393418334Speter GET_MODE_BITSIZE (mode) - (i + 1)); 393518334Speter 393618334Speter /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if 393718334Speter C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE 393818334Speter is 1. This produces better code than the alternative immediately 393918334Speter below. */ 394018334Speter if (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<' 394118334Speter && reversible_comparison_p (XEXP (x, 0)) 394218334Speter && ((STORE_FLAG_VALUE == -1 && XEXP (x, 1) == const1_rtx) 394318334Speter || (STORE_FLAG_VALUE == 1 && XEXP (x, 1) == constm1_rtx))) 394418334Speter return 394518334Speter gen_unary (NEG, mode, mode, 394618334Speter gen_binary (reverse_condition (GET_CODE (XEXP (x, 0))), 394718334Speter mode, XEXP (XEXP (x, 0), 0), 394818334Speter XEXP (XEXP (x, 0), 1))); 394918334Speter 395018334Speter /* If only the low-order bit of X is possibly nonzero, (plus x -1) 395118334Speter can become (ashiftrt (ashift (xor x 1) C) C) where C is 395218334Speter the bitsize of the mode - 1. This allows simplification of 395318334Speter "a = (b & 8) == 0;" */ 395418334Speter if (XEXP (x, 1) == constm1_rtx 395518334Speter && GET_CODE (XEXP (x, 0)) != REG 395618334Speter && ! (GET_CODE (XEXP (x,0)) == SUBREG 395718334Speter && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG) 395818334Speter && nonzero_bits (XEXP (x, 0), mode) == 1) 395918334Speter return simplify_shift_const (NULL_RTX, ASHIFTRT, mode, 396018334Speter simplify_shift_const (NULL_RTX, ASHIFT, mode, 396118334Speter gen_rtx_combine (XOR, mode, 396218334Speter XEXP (x, 0), const1_rtx), 396318334Speter GET_MODE_BITSIZE (mode) - 1), 396418334Speter GET_MODE_BITSIZE (mode) - 1); 396518334Speter 396618334Speter /* If we are adding two things that have no bits in common, convert 396718334Speter the addition into an IOR. This will often be further simplified, 396818334Speter for example in cases like ((a & 1) + (a & 2)), which can 396918334Speter become a & 3. */ 397018334Speter 397118334Speter if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 397218334Speter && (nonzero_bits (XEXP (x, 0), mode) 397318334Speter & nonzero_bits (XEXP (x, 1), mode)) == 0) 397418334Speter return gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1)); 397518334Speter break; 397618334Speter 397718334Speter case MINUS: 397850397Sobrien /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done 397950397Sobrien by reversing the comparison code if valid. */ 398050397Sobrien if (STORE_FLAG_VALUE == 1 398150397Sobrien && XEXP (x, 0) == const1_rtx 398218334Speter && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<' 398318334Speter && reversible_comparison_p (XEXP (x, 1))) 398418334Speter return gen_binary (reverse_condition (GET_CODE (XEXP (x, 1))), 398518334Speter mode, XEXP (XEXP (x, 1), 0), 398618334Speter XEXP (XEXP (x, 1), 1)); 398718334Speter 398818334Speter /* (minus <foo> (and <foo> (const_int -pow2))) becomes 398918334Speter (and <foo> (const_int pow2-1)) */ 399018334Speter if (GET_CODE (XEXP (x, 1)) == AND 399118334Speter && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT 399218334Speter && exact_log2 (- INTVAL (XEXP (XEXP (x, 1), 1))) >= 0 399318334Speter && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0))) 399418334Speter return simplify_and_const_int (NULL_RTX, mode, XEXP (x, 0), 399518334Speter - INTVAL (XEXP (XEXP (x, 1), 1)) - 1); 399618334Speter 399718334Speter /* Canonicalize (minus A (plus B C)) to (minus (minus A B) C) for 399818334Speter integers. */ 399918334Speter if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode)) 400018334Speter return gen_binary (MINUS, mode, 400118334Speter gen_binary (MINUS, mode, XEXP (x, 0), 400218334Speter XEXP (XEXP (x, 1), 0)), 400318334Speter XEXP (XEXP (x, 1), 1)); 400418334Speter break; 400518334Speter 400618334Speter case MULT: 400718334Speter /* If we have (mult (plus A B) C), apply the distributive law and then 400818334Speter the inverse distributive law to see if things simplify. This 400918334Speter occurs mostly in addresses, often when unrolling loops. */ 401018334Speter 401118334Speter if (GET_CODE (XEXP (x, 0)) == PLUS) 401218334Speter { 401318334Speter x = apply_distributive_law 401418334Speter (gen_binary (PLUS, mode, 401518334Speter gen_binary (MULT, mode, 401618334Speter XEXP (XEXP (x, 0), 0), XEXP (x, 1)), 401718334Speter gen_binary (MULT, mode, 401818334Speter XEXP (XEXP (x, 0), 1), XEXP (x, 1)))); 401918334Speter 402018334Speter if (GET_CODE (x) != MULT) 402118334Speter return x; 402218334Speter } 402318334Speter break; 402418334Speter 402518334Speter case UDIV: 402618334Speter /* If this is a divide by a power of two, treat it as a shift if 402718334Speter its first operand is a shift. */ 402818334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 402918334Speter && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0 403018334Speter && (GET_CODE (XEXP (x, 0)) == ASHIFT 403118334Speter || GET_CODE (XEXP (x, 0)) == LSHIFTRT 403218334Speter || GET_CODE (XEXP (x, 0)) == ASHIFTRT 403318334Speter || GET_CODE (XEXP (x, 0)) == ROTATE 403418334Speter || GET_CODE (XEXP (x, 0)) == ROTATERT)) 403518334Speter return simplify_shift_const (NULL_RTX, LSHIFTRT, mode, XEXP (x, 0), i); 403618334Speter break; 403718334Speter 403818334Speter case EQ: case NE: 403918334Speter case GT: case GTU: case GE: case GEU: 404018334Speter case LT: case LTU: case LE: case LEU: 404118334Speter /* If the first operand is a condition code, we can't do anything 404218334Speter with it. */ 404318334Speter if (GET_CODE (XEXP (x, 0)) == COMPARE 404418334Speter || (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_CC 404518334Speter#ifdef HAVE_cc0 404618334Speter && XEXP (x, 0) != cc0_rtx 404718334Speter#endif 404818334Speter )) 404918334Speter { 405018334Speter rtx op0 = XEXP (x, 0); 405118334Speter rtx op1 = XEXP (x, 1); 405218334Speter enum rtx_code new_code; 405318334Speter 405418334Speter if (GET_CODE (op0) == COMPARE) 405518334Speter op1 = XEXP (op0, 1), op0 = XEXP (op0, 0); 405618334Speter 405718334Speter /* Simplify our comparison, if possible. */ 405818334Speter new_code = simplify_comparison (code, &op0, &op1); 405918334Speter 406018334Speter /* If STORE_FLAG_VALUE is 1, we can convert (ne x 0) to simply X 406118334Speter if only the low-order bit is possibly nonzero in X (such as when 406218334Speter X is a ZERO_EXTRACT of one bit). Similarly, we can convert EQ to 406318334Speter (xor X 1) or (minus 1 X); we use the former. Finally, if X is 406418334Speter known to be either 0 or -1, NE becomes a NEG and EQ becomes 406518334Speter (plus X 1). 406618334Speter 406718334Speter Remove any ZERO_EXTRACT we made when thinking this was a 406818334Speter comparison. It may now be simpler to use, e.g., an AND. If a 406918334Speter ZERO_EXTRACT is indeed appropriate, it will be placed back by 407018334Speter the call to make_compound_operation in the SET case. */ 407118334Speter 407250397Sobrien if (STORE_FLAG_VALUE == 1 407350397Sobrien && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT 407450397Sobrien && op1 == const0_rtx && nonzero_bits (op0, mode) == 1) 407518334Speter return gen_lowpart_for_combine (mode, 407618334Speter expand_compound_operation (op0)); 407718334Speter 407850397Sobrien else if (STORE_FLAG_VALUE == 1 407950397Sobrien && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT 408018334Speter && op1 == const0_rtx 408118334Speter && (num_sign_bit_copies (op0, mode) 408218334Speter == GET_MODE_BITSIZE (mode))) 408318334Speter { 408418334Speter op0 = expand_compound_operation (op0); 408518334Speter return gen_unary (NEG, mode, mode, 408618334Speter gen_lowpart_for_combine (mode, op0)); 408718334Speter } 408818334Speter 408950397Sobrien else if (STORE_FLAG_VALUE == 1 409050397Sobrien && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT 409118334Speter && op1 == const0_rtx 409218334Speter && nonzero_bits (op0, mode) == 1) 409318334Speter { 409418334Speter op0 = expand_compound_operation (op0); 409518334Speter return gen_binary (XOR, mode, 409618334Speter gen_lowpart_for_combine (mode, op0), 409718334Speter const1_rtx); 409818334Speter } 409918334Speter 410050397Sobrien else if (STORE_FLAG_VALUE == 1 410150397Sobrien && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT 410218334Speter && op1 == const0_rtx 410318334Speter && (num_sign_bit_copies (op0, mode) 410418334Speter == GET_MODE_BITSIZE (mode))) 410518334Speter { 410618334Speter op0 = expand_compound_operation (op0); 410718334Speter return plus_constant (gen_lowpart_for_combine (mode, op0), 1); 410818334Speter } 410918334Speter 411018334Speter /* If STORE_FLAG_VALUE is -1, we have cases similar to 411118334Speter those above. */ 411250397Sobrien if (STORE_FLAG_VALUE == -1 411350397Sobrien && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT 411418334Speter && op1 == const0_rtx 411518334Speter && (num_sign_bit_copies (op0, mode) 411618334Speter == GET_MODE_BITSIZE (mode))) 411718334Speter return gen_lowpart_for_combine (mode, 411818334Speter expand_compound_operation (op0)); 411918334Speter 412050397Sobrien else if (STORE_FLAG_VALUE == -1 412150397Sobrien && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT 412218334Speter && op1 == const0_rtx 412318334Speter && nonzero_bits (op0, mode) == 1) 412418334Speter { 412518334Speter op0 = expand_compound_operation (op0); 412618334Speter return gen_unary (NEG, mode, mode, 412718334Speter gen_lowpart_for_combine (mode, op0)); 412818334Speter } 412918334Speter 413050397Sobrien else if (STORE_FLAG_VALUE == -1 413150397Sobrien && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT 413218334Speter && op1 == const0_rtx 413318334Speter && (num_sign_bit_copies (op0, mode) 413418334Speter == GET_MODE_BITSIZE (mode))) 413518334Speter { 413618334Speter op0 = expand_compound_operation (op0); 413718334Speter return gen_unary (NOT, mode, mode, 413818334Speter gen_lowpart_for_combine (mode, op0)); 413918334Speter } 414018334Speter 414118334Speter /* If X is 0/1, (eq X 0) is X-1. */ 414250397Sobrien else if (STORE_FLAG_VALUE == -1 414350397Sobrien && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT 414418334Speter && op1 == const0_rtx 414518334Speter && nonzero_bits (op0, mode) == 1) 414618334Speter { 414718334Speter op0 = expand_compound_operation (op0); 414818334Speter return plus_constant (gen_lowpart_for_combine (mode, op0), -1); 414918334Speter } 415018334Speter 415118334Speter /* If STORE_FLAG_VALUE says to just test the sign bit and X has just 415218334Speter one bit that might be nonzero, we can convert (ne x 0) to 415318334Speter (ashift x c) where C puts the bit in the sign bit. Remove any 415418334Speter AND with STORE_FLAG_VALUE when we are done, since we are only 415518334Speter going to test the sign bit. */ 415618334Speter if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT 415718334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 415850397Sobrien && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode)) 415952284Sobrien == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE(mode)-1)) 416018334Speter && op1 == const0_rtx 416118334Speter && mode == GET_MODE (op0) 416218334Speter && (i = exact_log2 (nonzero_bits (op0, mode))) >= 0) 416318334Speter { 416418334Speter x = simplify_shift_const (NULL_RTX, ASHIFT, mode, 416518334Speter expand_compound_operation (op0), 416618334Speter GET_MODE_BITSIZE (mode) - 1 - i); 416718334Speter if (GET_CODE (x) == AND && XEXP (x, 1) == const_true_rtx) 416818334Speter return XEXP (x, 0); 416918334Speter else 417018334Speter return x; 417118334Speter } 417218334Speter 417318334Speter /* If the code changed, return a whole new comparison. */ 417418334Speter if (new_code != code) 417518334Speter return gen_rtx_combine (new_code, mode, op0, op1); 417618334Speter 417718334Speter /* Otherwise, keep this operation, but maybe change its operands. 417818334Speter This also converts (ne (compare FOO BAR) 0) to (ne FOO BAR). */ 417918334Speter SUBST (XEXP (x, 0), op0); 418018334Speter SUBST (XEXP (x, 1), op1); 418118334Speter } 418218334Speter break; 418318334Speter 418418334Speter case IF_THEN_ELSE: 418518334Speter return simplify_if_then_else (x); 418618334Speter 418718334Speter case ZERO_EXTRACT: 418818334Speter case SIGN_EXTRACT: 418918334Speter case ZERO_EXTEND: 419018334Speter case SIGN_EXTEND: 419150397Sobrien /* If we are processing SET_DEST, we are done. */ 419218334Speter if (in_dest) 419318334Speter return x; 419418334Speter 419518334Speter return expand_compound_operation (x); 419618334Speter 419718334Speter case SET: 419818334Speter return simplify_set (x); 419918334Speter 420018334Speter case AND: 420118334Speter case IOR: 420218334Speter case XOR: 420318334Speter return simplify_logical (x, last); 420418334Speter 420550397Sobrien case ABS: 420618334Speter /* (abs (neg <foo>)) -> (abs <foo>) */ 420718334Speter if (GET_CODE (XEXP (x, 0)) == NEG) 420818334Speter SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0)); 420918334Speter 421050397Sobrien /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS), 421150397Sobrien do nothing. */ 421250397Sobrien if (GET_MODE (XEXP (x, 0)) == VOIDmode) 421350397Sobrien break; 421450397Sobrien 421518334Speter /* If operand is something known to be positive, ignore the ABS. */ 421618334Speter if (GET_CODE (XEXP (x, 0)) == FFS || GET_CODE (XEXP (x, 0)) == ABS 421718334Speter || ((GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) 421818334Speter <= HOST_BITS_PER_WIDE_INT) 421918334Speter && ((nonzero_bits (XEXP (x, 0), GET_MODE (XEXP (x, 0))) 422018334Speter & ((HOST_WIDE_INT) 1 422118334Speter << (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - 1))) 422218334Speter == 0))) 422318334Speter return XEXP (x, 0); 422418334Speter 422518334Speter 422618334Speter /* If operand is known to be only -1 or 0, convert ABS to NEG. */ 422718334Speter if (num_sign_bit_copies (XEXP (x, 0), mode) == GET_MODE_BITSIZE (mode)) 422818334Speter return gen_rtx_combine (NEG, mode, XEXP (x, 0)); 422918334Speter 423018334Speter break; 423118334Speter 423218334Speter case FFS: 423318334Speter /* (ffs (*_extend <X>)) = (ffs <X>) */ 423418334Speter if (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND 423518334Speter || GET_CODE (XEXP (x, 0)) == ZERO_EXTEND) 423618334Speter SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0)); 423718334Speter break; 423818334Speter 423918334Speter case FLOAT: 424018334Speter /* (float (sign_extend <X>)) = (float <X>). */ 424118334Speter if (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND) 424218334Speter SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0)); 424318334Speter break; 424418334Speter 424518334Speter case ASHIFT: 424618334Speter case LSHIFTRT: 424718334Speter case ASHIFTRT: 424818334Speter case ROTATE: 424918334Speter case ROTATERT: 425018334Speter /* If this is a shift by a constant amount, simplify it. */ 425118334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT) 425218334Speter return simplify_shift_const (x, code, mode, XEXP (x, 0), 425318334Speter INTVAL (XEXP (x, 1))); 425418334Speter 425518334Speter#ifdef SHIFT_COUNT_TRUNCATED 425618334Speter else if (SHIFT_COUNT_TRUNCATED && GET_CODE (XEXP (x, 1)) != REG) 425718334Speter SUBST (XEXP (x, 1), 425818334Speter force_to_mode (XEXP (x, 1), GET_MODE (x), 425918334Speter ((HOST_WIDE_INT) 1 426018334Speter << exact_log2 (GET_MODE_BITSIZE (GET_MODE (x)))) 426118334Speter - 1, 426218334Speter NULL_RTX, 0)); 426318334Speter#endif 426418334Speter 426518334Speter break; 426650397Sobrien 426750397Sobrien default: 426850397Sobrien break; 426918334Speter } 427018334Speter 427118334Speter return x; 427218334Speter} 427318334Speter 427418334Speter/* Simplify X, an IF_THEN_ELSE expression. Return the new expression. */ 427518334Speter 427618334Speterstatic rtx 427718334Spetersimplify_if_then_else (x) 427818334Speter rtx x; 427918334Speter{ 428018334Speter enum machine_mode mode = GET_MODE (x); 428118334Speter rtx cond = XEXP (x, 0); 428218334Speter rtx true = XEXP (x, 1); 428318334Speter rtx false = XEXP (x, 2); 428418334Speter enum rtx_code true_code = GET_CODE (cond); 428518334Speter int comparison_p = GET_RTX_CLASS (true_code) == '<'; 428618334Speter rtx temp; 428718334Speter int i; 428818334Speter 428950397Sobrien /* Simplify storing of the truth value. */ 429018334Speter if (comparison_p && true == const_true_rtx && false == const0_rtx) 429118334Speter return gen_binary (true_code, mode, XEXP (cond, 0), XEXP (cond, 1)); 429218334Speter 429350397Sobrien /* Also when the truth value has to be reversed. */ 429418334Speter if (comparison_p && reversible_comparison_p (cond) 429518334Speter && true == const0_rtx && false == const_true_rtx) 429618334Speter return gen_binary (reverse_condition (true_code), 429718334Speter mode, XEXP (cond, 0), XEXP (cond, 1)); 429818334Speter 429918334Speter /* Sometimes we can simplify the arm of an IF_THEN_ELSE if a register used 430018334Speter in it is being compared against certain values. Get the true and false 430118334Speter comparisons and see if that says anything about the value of each arm. */ 430218334Speter 430318334Speter if (comparison_p && reversible_comparison_p (cond) 430418334Speter && GET_CODE (XEXP (cond, 0)) == REG) 430518334Speter { 430618334Speter HOST_WIDE_INT nzb; 430718334Speter rtx from = XEXP (cond, 0); 430818334Speter enum rtx_code false_code = reverse_condition (true_code); 430918334Speter rtx true_val = XEXP (cond, 1); 431018334Speter rtx false_val = true_val; 431118334Speter int swapped = 0; 431218334Speter 431318334Speter /* If FALSE_CODE is EQ, swap the codes and arms. */ 431418334Speter 431518334Speter if (false_code == EQ) 431618334Speter { 431718334Speter swapped = 1, true_code = EQ, false_code = NE; 431818334Speter temp = true, true = false, false = temp; 431918334Speter } 432018334Speter 432118334Speter /* If we are comparing against zero and the expression being tested has 432218334Speter only a single bit that might be nonzero, that is its value when it is 432318334Speter not equal to zero. Similarly if it is known to be -1 or 0. */ 432418334Speter 432518334Speter if (true_code == EQ && true_val == const0_rtx 432618334Speter && exact_log2 (nzb = nonzero_bits (from, GET_MODE (from))) >= 0) 432718334Speter false_code = EQ, false_val = GEN_INT (nzb); 432818334Speter else if (true_code == EQ && true_val == const0_rtx 432918334Speter && (num_sign_bit_copies (from, GET_MODE (from)) 433018334Speter == GET_MODE_BITSIZE (GET_MODE (from)))) 433118334Speter false_code = EQ, false_val = constm1_rtx; 433218334Speter 433318334Speter /* Now simplify an arm if we know the value of the register in the 433418334Speter branch and it is used in the arm. Be careful due to the potential 433518334Speter of locally-shared RTL. */ 433618334Speter 433718334Speter if (reg_mentioned_p (from, true)) 433818334Speter true = subst (known_cond (copy_rtx (true), true_code, from, true_val), 433918334Speter pc_rtx, pc_rtx, 0, 0); 434018334Speter if (reg_mentioned_p (from, false)) 434118334Speter false = subst (known_cond (copy_rtx (false), false_code, 434218334Speter from, false_val), 434318334Speter pc_rtx, pc_rtx, 0, 0); 434418334Speter 434518334Speter SUBST (XEXP (x, 1), swapped ? false : true); 434618334Speter SUBST (XEXP (x, 2), swapped ? true : false); 434718334Speter 434818334Speter true = XEXP (x, 1), false = XEXP (x, 2), true_code = GET_CODE (cond); 434918334Speter } 435018334Speter 435118334Speter /* If we have (if_then_else FOO (pc) (label_ref BAR)) and FOO can be 435218334Speter reversed, do so to avoid needing two sets of patterns for 435318334Speter subtract-and-branch insns. Similarly if we have a constant in the true 435418334Speter arm, the false arm is the same as the first operand of the comparison, or 435518334Speter the false arm is more complicated than the true arm. */ 435618334Speter 435718334Speter if (comparison_p && reversible_comparison_p (cond) 435818334Speter && (true == pc_rtx 435918334Speter || (CONSTANT_P (true) 436018334Speter && GET_CODE (false) != CONST_INT && false != pc_rtx) 436118334Speter || true == const0_rtx 436218334Speter || (GET_RTX_CLASS (GET_CODE (true)) == 'o' 436318334Speter && GET_RTX_CLASS (GET_CODE (false)) != 'o') 436418334Speter || (GET_CODE (true) == SUBREG 436518334Speter && GET_RTX_CLASS (GET_CODE (SUBREG_REG (true))) == 'o' 436618334Speter && GET_RTX_CLASS (GET_CODE (false)) != 'o') 436718334Speter || reg_mentioned_p (true, false) 436818334Speter || rtx_equal_p (false, XEXP (cond, 0)))) 436918334Speter { 437018334Speter true_code = reverse_condition (true_code); 437118334Speter SUBST (XEXP (x, 0), 437218334Speter gen_binary (true_code, GET_MODE (cond), XEXP (cond, 0), 437318334Speter XEXP (cond, 1))); 437418334Speter 437518334Speter SUBST (XEXP (x, 1), false); 437618334Speter SUBST (XEXP (x, 2), true); 437718334Speter 437818334Speter temp = true, true = false, false = temp, cond = XEXP (x, 0); 437950397Sobrien 438050397Sobrien /* It is possible that the conditional has been simplified out. */ 438150397Sobrien true_code = GET_CODE (cond); 438250397Sobrien comparison_p = GET_RTX_CLASS (true_code) == '<'; 438318334Speter } 438418334Speter 438518334Speter /* If the two arms are identical, we don't need the comparison. */ 438618334Speter 438718334Speter if (rtx_equal_p (true, false) && ! side_effects_p (cond)) 438818334Speter return true; 438918334Speter 439050397Sobrien /* Convert a == b ? b : a to "a". */ 439150397Sobrien if (true_code == EQ && ! side_effects_p (cond) 439250397Sobrien && rtx_equal_p (XEXP (cond, 0), false) 439350397Sobrien && rtx_equal_p (XEXP (cond, 1), true)) 439450397Sobrien return false; 439550397Sobrien else if (true_code == NE && ! side_effects_p (cond) 439650397Sobrien && rtx_equal_p (XEXP (cond, 0), true) 439750397Sobrien && rtx_equal_p (XEXP (cond, 1), false)) 439850397Sobrien return true; 439950397Sobrien 440018334Speter /* Look for cases where we have (abs x) or (neg (abs X)). */ 440118334Speter 440218334Speter if (GET_MODE_CLASS (mode) == MODE_INT 440318334Speter && GET_CODE (false) == NEG 440418334Speter && rtx_equal_p (true, XEXP (false, 0)) 440518334Speter && comparison_p 440618334Speter && rtx_equal_p (true, XEXP (cond, 0)) 440718334Speter && ! side_effects_p (true)) 440818334Speter switch (true_code) 440918334Speter { 441018334Speter case GT: 441118334Speter case GE: 441218334Speter return gen_unary (ABS, mode, mode, true); 441318334Speter case LT: 441418334Speter case LE: 441518334Speter return gen_unary (NEG, mode, mode, gen_unary (ABS, mode, mode, true)); 441650397Sobrien default: 441750397Sobrien break; 441818334Speter } 441918334Speter 442018334Speter /* Look for MIN or MAX. */ 442118334Speter 442218334Speter if ((! FLOAT_MODE_P (mode) || flag_fast_math) 442318334Speter && comparison_p 442418334Speter && rtx_equal_p (XEXP (cond, 0), true) 442518334Speter && rtx_equal_p (XEXP (cond, 1), false) 442618334Speter && ! side_effects_p (cond)) 442718334Speter switch (true_code) 442818334Speter { 442918334Speter case GE: 443018334Speter case GT: 443118334Speter return gen_binary (SMAX, mode, true, false); 443218334Speter case LE: 443318334Speter case LT: 443418334Speter return gen_binary (SMIN, mode, true, false); 443518334Speter case GEU: 443618334Speter case GTU: 443718334Speter return gen_binary (UMAX, mode, true, false); 443818334Speter case LEU: 443918334Speter case LTU: 444018334Speter return gen_binary (UMIN, mode, true, false); 444150397Sobrien default: 444250397Sobrien break; 444318334Speter } 444418334Speter 444518334Speter /* If we have (if_then_else COND (OP Z C1) Z) and OP is an identity when its 444618334Speter second operand is zero, this can be done as (OP Z (mult COND C2)) where 444718334Speter C2 = C1 * STORE_FLAG_VALUE. Similarly if OP has an outer ZERO_EXTEND or 444818334Speter SIGN_EXTEND as long as Z is already extended (so we don't destroy it). 444918334Speter We can do this kind of thing in some cases when STORE_FLAG_VALUE is 445050397Sobrien neither 1 or -1, but it isn't worth checking for. */ 445118334Speter 445250397Sobrien if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1) 445350397Sobrien && comparison_p && mode != VOIDmode && ! side_effects_p (x)) 445418334Speter { 445518334Speter rtx t = make_compound_operation (true, SET); 445618334Speter rtx f = make_compound_operation (false, SET); 445718334Speter rtx cond_op0 = XEXP (cond, 0); 445818334Speter rtx cond_op1 = XEXP (cond, 1); 445918334Speter enum rtx_code op, extend_op = NIL; 446018334Speter enum machine_mode m = mode; 446118334Speter rtx z = 0, c1; 446218334Speter 446318334Speter if ((GET_CODE (t) == PLUS || GET_CODE (t) == MINUS 446418334Speter || GET_CODE (t) == IOR || GET_CODE (t) == XOR 446518334Speter || GET_CODE (t) == ASHIFT 446618334Speter || GET_CODE (t) == LSHIFTRT || GET_CODE (t) == ASHIFTRT) 446718334Speter && rtx_equal_p (XEXP (t, 0), f)) 446818334Speter c1 = XEXP (t, 1), op = GET_CODE (t), z = f; 446918334Speter 447018334Speter /* If an identity-zero op is commutative, check whether there 447150397Sobrien would be a match if we swapped the operands. */ 447218334Speter else if ((GET_CODE (t) == PLUS || GET_CODE (t) == IOR 447318334Speter || GET_CODE (t) == XOR) 447418334Speter && rtx_equal_p (XEXP (t, 1), f)) 447518334Speter c1 = XEXP (t, 0), op = GET_CODE (t), z = f; 447618334Speter else if (GET_CODE (t) == SIGN_EXTEND 447718334Speter && (GET_CODE (XEXP (t, 0)) == PLUS 447818334Speter || GET_CODE (XEXP (t, 0)) == MINUS 447918334Speter || GET_CODE (XEXP (t, 0)) == IOR 448018334Speter || GET_CODE (XEXP (t, 0)) == XOR 448118334Speter || GET_CODE (XEXP (t, 0)) == ASHIFT 448218334Speter || GET_CODE (XEXP (t, 0)) == LSHIFTRT 448318334Speter || GET_CODE (XEXP (t, 0)) == ASHIFTRT) 448418334Speter && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG 448518334Speter && subreg_lowpart_p (XEXP (XEXP (t, 0), 0)) 448618334Speter && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f) 448718334Speter && (num_sign_bit_copies (f, GET_MODE (f)) 448818334Speter > (GET_MODE_BITSIZE (mode) 448918334Speter - GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (t, 0), 0)))))) 449018334Speter { 449118334Speter c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0)); 449218334Speter extend_op = SIGN_EXTEND; 449318334Speter m = GET_MODE (XEXP (t, 0)); 449418334Speter } 449518334Speter else if (GET_CODE (t) == SIGN_EXTEND 449618334Speter && (GET_CODE (XEXP (t, 0)) == PLUS 449718334Speter || GET_CODE (XEXP (t, 0)) == IOR 449818334Speter || GET_CODE (XEXP (t, 0)) == XOR) 449918334Speter && GET_CODE (XEXP (XEXP (t, 0), 1)) == SUBREG 450018334Speter && subreg_lowpart_p (XEXP (XEXP (t, 0), 1)) 450118334Speter && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 1)), f) 450218334Speter && (num_sign_bit_copies (f, GET_MODE (f)) 450318334Speter > (GET_MODE_BITSIZE (mode) 450418334Speter - GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (t, 0), 1)))))) 450518334Speter { 450618334Speter c1 = XEXP (XEXP (t, 0), 0); z = f; op = GET_CODE (XEXP (t, 0)); 450718334Speter extend_op = SIGN_EXTEND; 450818334Speter m = GET_MODE (XEXP (t, 0)); 450918334Speter } 451018334Speter else if (GET_CODE (t) == ZERO_EXTEND 451118334Speter && (GET_CODE (XEXP (t, 0)) == PLUS 451218334Speter || GET_CODE (XEXP (t, 0)) == MINUS 451318334Speter || GET_CODE (XEXP (t, 0)) == IOR 451418334Speter || GET_CODE (XEXP (t, 0)) == XOR 451518334Speter || GET_CODE (XEXP (t, 0)) == ASHIFT 451618334Speter || GET_CODE (XEXP (t, 0)) == LSHIFTRT 451718334Speter || GET_CODE (XEXP (t, 0)) == ASHIFTRT) 451818334Speter && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG 451918334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 452018334Speter && subreg_lowpart_p (XEXP (XEXP (t, 0), 0)) 452118334Speter && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f) 452218334Speter && ((nonzero_bits (f, GET_MODE (f)) 452318334Speter & ~ GET_MODE_MASK (GET_MODE (XEXP (XEXP (t, 0), 0)))) 452418334Speter == 0)) 452518334Speter { 452618334Speter c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0)); 452718334Speter extend_op = ZERO_EXTEND; 452818334Speter m = GET_MODE (XEXP (t, 0)); 452918334Speter } 453018334Speter else if (GET_CODE (t) == ZERO_EXTEND 453118334Speter && (GET_CODE (XEXP (t, 0)) == PLUS 453218334Speter || GET_CODE (XEXP (t, 0)) == IOR 453318334Speter || GET_CODE (XEXP (t, 0)) == XOR) 453418334Speter && GET_CODE (XEXP (XEXP (t, 0), 1)) == SUBREG 453518334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 453618334Speter && subreg_lowpart_p (XEXP (XEXP (t, 0), 1)) 453718334Speter && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 1)), f) 453818334Speter && ((nonzero_bits (f, GET_MODE (f)) 453918334Speter & ~ GET_MODE_MASK (GET_MODE (XEXP (XEXP (t, 0), 1)))) 454018334Speter == 0)) 454118334Speter { 454218334Speter c1 = XEXP (XEXP (t, 0), 0); z = f; op = GET_CODE (XEXP (t, 0)); 454318334Speter extend_op = ZERO_EXTEND; 454418334Speter m = GET_MODE (XEXP (t, 0)); 454518334Speter } 454618334Speter 454718334Speter if (z) 454818334Speter { 454918334Speter temp = subst (gen_binary (true_code, m, cond_op0, cond_op1), 455018334Speter pc_rtx, pc_rtx, 0, 0); 455118334Speter temp = gen_binary (MULT, m, temp, 455218334Speter gen_binary (MULT, m, c1, const_true_rtx)); 455318334Speter temp = subst (temp, pc_rtx, pc_rtx, 0, 0); 455418334Speter temp = gen_binary (op, m, gen_lowpart_for_combine (m, z), temp); 455518334Speter 455618334Speter if (extend_op != NIL) 455718334Speter temp = gen_unary (extend_op, mode, m, temp); 455818334Speter 455918334Speter return temp; 456018334Speter } 456118334Speter } 456218334Speter 456318334Speter /* If we have (if_then_else (ne A 0) C1 0) and either A is known to be 0 or 456418334Speter 1 and C1 is a single bit or A is known to be 0 or -1 and C1 is the 456518334Speter negation of a single bit, we can convert this operation to a shift. We 456618334Speter can actually do this more generally, but it doesn't seem worth it. */ 456718334Speter 456818334Speter if (true_code == NE && XEXP (cond, 1) == const0_rtx 456918334Speter && false == const0_rtx && GET_CODE (true) == CONST_INT 457018334Speter && ((1 == nonzero_bits (XEXP (cond, 0), mode) 457118334Speter && (i = exact_log2 (INTVAL (true))) >= 0) 457218334Speter || ((num_sign_bit_copies (XEXP (cond, 0), mode) 457318334Speter == GET_MODE_BITSIZE (mode)) 457418334Speter && (i = exact_log2 (- INTVAL (true))) >= 0))) 457518334Speter return 457618334Speter simplify_shift_const (NULL_RTX, ASHIFT, mode, 457718334Speter gen_lowpart_for_combine (mode, XEXP (cond, 0)), i); 457818334Speter 457918334Speter return x; 458018334Speter} 458118334Speter 458218334Speter/* Simplify X, a SET expression. Return the new expression. */ 458318334Speter 458418334Speterstatic rtx 458518334Spetersimplify_set (x) 458618334Speter rtx x; 458718334Speter{ 458818334Speter rtx src = SET_SRC (x); 458918334Speter rtx dest = SET_DEST (x); 459018334Speter enum machine_mode mode 459118334Speter = GET_MODE (src) != VOIDmode ? GET_MODE (src) : GET_MODE (dest); 459218334Speter rtx other_insn; 459318334Speter rtx *cc_use; 459418334Speter 459518334Speter /* (set (pc) (return)) gets written as (return). */ 459618334Speter if (GET_CODE (dest) == PC && GET_CODE (src) == RETURN) 459718334Speter return src; 459818334Speter 459918334Speter /* Now that we know for sure which bits of SRC we are using, see if we can 460018334Speter simplify the expression for the object knowing that we only need the 460118334Speter low-order bits. */ 460218334Speter 460318334Speter if (GET_MODE_CLASS (mode) == MODE_INT) 460418334Speter src = force_to_mode (src, mode, GET_MODE_MASK (mode), NULL_RTX, 0); 460518334Speter 460618334Speter /* If we are setting CC0 or if the source is a COMPARE, look for the use of 460718334Speter the comparison result and try to simplify it unless we already have used 460818334Speter undobuf.other_insn. */ 460918334Speter if ((GET_CODE (src) == COMPARE 461018334Speter#ifdef HAVE_cc0 461118334Speter || dest == cc0_rtx 461218334Speter#endif 461318334Speter ) 461418334Speter && (cc_use = find_single_use (dest, subst_insn, &other_insn)) != 0 461518334Speter && (undobuf.other_insn == 0 || other_insn == undobuf.other_insn) 461618334Speter && GET_RTX_CLASS (GET_CODE (*cc_use)) == '<' 461718334Speter && rtx_equal_p (XEXP (*cc_use, 0), dest)) 461818334Speter { 461918334Speter enum rtx_code old_code = GET_CODE (*cc_use); 462018334Speter enum rtx_code new_code; 462118334Speter rtx op0, op1; 462218334Speter int other_changed = 0; 462318334Speter enum machine_mode compare_mode = GET_MODE (dest); 462418334Speter 462518334Speter if (GET_CODE (src) == COMPARE) 462618334Speter op0 = XEXP (src, 0), op1 = XEXP (src, 1); 462718334Speter else 462818334Speter op0 = src, op1 = const0_rtx; 462918334Speter 463018334Speter /* Simplify our comparison, if possible. */ 463118334Speter new_code = simplify_comparison (old_code, &op0, &op1); 463218334Speter 463318334Speter#ifdef EXTRA_CC_MODES 463418334Speter /* If this machine has CC modes other than CCmode, check to see if we 463518334Speter need to use a different CC mode here. */ 463618334Speter compare_mode = SELECT_CC_MODE (new_code, op0, op1); 463718334Speter#endif /* EXTRA_CC_MODES */ 463818334Speter 463918334Speter#if !defined (HAVE_cc0) && defined (EXTRA_CC_MODES) 464018334Speter /* If the mode changed, we have to change SET_DEST, the mode in the 464118334Speter compare, and the mode in the place SET_DEST is used. If SET_DEST is 464218334Speter a hard register, just build new versions with the proper mode. If it 464318334Speter is a pseudo, we lose unless it is only time we set the pseudo, in 464418334Speter which case we can safely change its mode. */ 464518334Speter if (compare_mode != GET_MODE (dest)) 464618334Speter { 464718334Speter int regno = REGNO (dest); 464850397Sobrien rtx new_dest = gen_rtx_REG (compare_mode, regno); 464918334Speter 465018334Speter if (regno < FIRST_PSEUDO_REGISTER 465150397Sobrien || (REG_N_SETS (regno) == 1 && ! REG_USERVAR_P (dest))) 465218334Speter { 465318334Speter if (regno >= FIRST_PSEUDO_REGISTER) 465418334Speter SUBST (regno_reg_rtx[regno], new_dest); 465518334Speter 465618334Speter SUBST (SET_DEST (x), new_dest); 465718334Speter SUBST (XEXP (*cc_use, 0), new_dest); 465818334Speter other_changed = 1; 465918334Speter 466018334Speter dest = new_dest; 466118334Speter } 466218334Speter } 466318334Speter#endif 466418334Speter 466518334Speter /* If the code changed, we have to build a new comparison in 466618334Speter undobuf.other_insn. */ 466718334Speter if (new_code != old_code) 466818334Speter { 466918334Speter unsigned HOST_WIDE_INT mask; 467018334Speter 467118334Speter SUBST (*cc_use, gen_rtx_combine (new_code, GET_MODE (*cc_use), 467218334Speter dest, const0_rtx)); 467318334Speter 467418334Speter /* If the only change we made was to change an EQ into an NE or 467518334Speter vice versa, OP0 has only one bit that might be nonzero, and OP1 467618334Speter is zero, check if changing the user of the condition code will 467718334Speter produce a valid insn. If it won't, we can keep the original code 467818334Speter in that insn by surrounding our operation with an XOR. */ 467918334Speter 468018334Speter if (((old_code == NE && new_code == EQ) 468118334Speter || (old_code == EQ && new_code == NE)) 468218334Speter && ! other_changed && op1 == const0_rtx 468318334Speter && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT 468418334Speter && exact_log2 (mask = nonzero_bits (op0, GET_MODE (op0))) >= 0) 468518334Speter { 468618334Speter rtx pat = PATTERN (other_insn), note = 0; 468718334Speter 468852284Sobrien if ((recog_for_combine (&pat, other_insn, ¬e) < 0 468918334Speter && ! check_asm_operands (pat))) 469018334Speter { 469118334Speter PUT_CODE (*cc_use, old_code); 469218334Speter other_insn = 0; 469318334Speter 469418334Speter op0 = gen_binary (XOR, GET_MODE (op0), op0, GEN_INT (mask)); 469518334Speter } 469618334Speter } 469718334Speter 469818334Speter other_changed = 1; 469918334Speter } 470018334Speter 470118334Speter if (other_changed) 470218334Speter undobuf.other_insn = other_insn; 470318334Speter 470418334Speter#ifdef HAVE_cc0 470518334Speter /* If we are now comparing against zero, change our source if 470618334Speter needed. If we do not use cc0, we always have a COMPARE. */ 470718334Speter if (op1 == const0_rtx && dest == cc0_rtx) 470818334Speter { 470918334Speter SUBST (SET_SRC (x), op0); 471018334Speter src = op0; 471118334Speter } 471218334Speter else 471318334Speter#endif 471418334Speter 471518334Speter /* Otherwise, if we didn't previously have a COMPARE in the 471618334Speter correct mode, we need one. */ 471718334Speter if (GET_CODE (src) != COMPARE || GET_MODE (src) != compare_mode) 471818334Speter { 471918334Speter SUBST (SET_SRC (x), 472018334Speter gen_rtx_combine (COMPARE, compare_mode, op0, op1)); 472118334Speter src = SET_SRC (x); 472218334Speter } 472318334Speter else 472418334Speter { 472518334Speter /* Otherwise, update the COMPARE if needed. */ 472618334Speter SUBST (XEXP (src, 0), op0); 472718334Speter SUBST (XEXP (src, 1), op1); 472818334Speter } 472918334Speter } 473018334Speter else 473118334Speter { 473218334Speter /* Get SET_SRC in a form where we have placed back any 473318334Speter compound expressions. Then do the checks below. */ 473418334Speter src = make_compound_operation (src, SET); 473518334Speter SUBST (SET_SRC (x), src); 473618334Speter } 473718334Speter 473818334Speter /* If we have (set x (subreg:m1 (op:m2 ...) 0)) with OP being some operation, 473918334Speter and X being a REG or (subreg (reg)), we may be able to convert this to 474018334Speter (set (subreg:m2 x) (op)). 474118334Speter 474218334Speter We can always do this if M1 is narrower than M2 because that means that 474318334Speter we only care about the low bits of the result. 474418334Speter 474518334Speter However, on machines without WORD_REGISTER_OPERATIONS defined, we cannot 474650397Sobrien perform a narrower operation than requested since the high-order bits will 474718334Speter be undefined. On machine where it is defined, this transformation is safe 474818334Speter as long as M1 and M2 have the same number of words. */ 474918334Speter 475018334Speter if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src) 475118334Speter && GET_RTX_CLASS (GET_CODE (SUBREG_REG (src))) != 'o' 475218334Speter && (((GET_MODE_SIZE (GET_MODE (src)) + (UNITS_PER_WORD - 1)) 475318334Speter / UNITS_PER_WORD) 475418334Speter == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))) 475518334Speter + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)) 475618334Speter#ifndef WORD_REGISTER_OPERATIONS 475718334Speter && (GET_MODE_SIZE (GET_MODE (src)) 475818334Speter < GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))) 475918334Speter#endif 476018334Speter#ifdef CLASS_CANNOT_CHANGE_SIZE 476118334Speter && ! (GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER 476218334Speter && (TEST_HARD_REG_BIT 476318334Speter (reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE], 476418334Speter REGNO (dest))) 476518334Speter && (GET_MODE_SIZE (GET_MODE (src)) 476618334Speter != GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))) 476718334Speter#endif 476818334Speter && (GET_CODE (dest) == REG 476918334Speter || (GET_CODE (dest) == SUBREG 477018334Speter && GET_CODE (SUBREG_REG (dest)) == REG))) 477118334Speter { 477218334Speter SUBST (SET_DEST (x), 477318334Speter gen_lowpart_for_combine (GET_MODE (SUBREG_REG (src)), 477418334Speter dest)); 477518334Speter SUBST (SET_SRC (x), SUBREG_REG (src)); 477618334Speter 477718334Speter src = SET_SRC (x), dest = SET_DEST (x); 477818334Speter } 477918334Speter 478018334Speter#ifdef LOAD_EXTEND_OP 478118334Speter /* If we have (set FOO (subreg:M (mem:N BAR) 0)) with M wider than N, this 478218334Speter would require a paradoxical subreg. Replace the subreg with a 478350397Sobrien zero_extend to avoid the reload that would otherwise be required. */ 478418334Speter 478518334Speter if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src) 478618334Speter && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (src))) != NIL 478718334Speter && SUBREG_WORD (src) == 0 478818334Speter && (GET_MODE_SIZE (GET_MODE (src)) 478918334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))) 479018334Speter && GET_CODE (SUBREG_REG (src)) == MEM) 479118334Speter { 479218334Speter SUBST (SET_SRC (x), 479318334Speter gen_rtx_combine (LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (src))), 479418334Speter GET_MODE (src), XEXP (src, 0))); 479518334Speter 479618334Speter src = SET_SRC (x); 479718334Speter } 479818334Speter#endif 479918334Speter 480018334Speter /* If we don't have a conditional move, SET_SRC is an IF_THEN_ELSE, and we 480118334Speter are comparing an item known to be 0 or -1 against 0, use a logical 480218334Speter operation instead. Check for one of the arms being an IOR of the other 480318334Speter arm with some value. We compute three terms to be IOR'ed together. In 480418334Speter practice, at most two will be nonzero. Then we do the IOR's. */ 480518334Speter 480618334Speter if (GET_CODE (dest) != PC 480718334Speter && GET_CODE (src) == IF_THEN_ELSE 480818334Speter && GET_MODE_CLASS (GET_MODE (src)) == MODE_INT 480918334Speter && (GET_CODE (XEXP (src, 0)) == EQ || GET_CODE (XEXP (src, 0)) == NE) 481018334Speter && XEXP (XEXP (src, 0), 1) == const0_rtx 481118334Speter && GET_MODE (src) == GET_MODE (XEXP (XEXP (src, 0), 0)) 481218334Speter#ifdef HAVE_conditional_move 481318334Speter && ! can_conditionally_move_p (GET_MODE (src)) 481418334Speter#endif 481518334Speter && (num_sign_bit_copies (XEXP (XEXP (src, 0), 0), 481618334Speter GET_MODE (XEXP (XEXP (src, 0), 0))) 481718334Speter == GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (src, 0), 0)))) 481818334Speter && ! side_effects_p (src)) 481918334Speter { 482018334Speter rtx true = (GET_CODE (XEXP (src, 0)) == NE 482118334Speter ? XEXP (src, 1) : XEXP (src, 2)); 482218334Speter rtx false = (GET_CODE (XEXP (src, 0)) == NE 482318334Speter ? XEXP (src, 2) : XEXP (src, 1)); 482418334Speter rtx term1 = const0_rtx, term2, term3; 482518334Speter 482618334Speter if (GET_CODE (true) == IOR && rtx_equal_p (XEXP (true, 0), false)) 482718334Speter term1 = false, true = XEXP (true, 1), false = const0_rtx; 482818334Speter else if (GET_CODE (true) == IOR 482918334Speter && rtx_equal_p (XEXP (true, 1), false)) 483018334Speter term1 = false, true = XEXP (true, 0), false = const0_rtx; 483118334Speter else if (GET_CODE (false) == IOR 483218334Speter && rtx_equal_p (XEXP (false, 0), true)) 483318334Speter term1 = true, false = XEXP (false, 1), true = const0_rtx; 483418334Speter else if (GET_CODE (false) == IOR 483518334Speter && rtx_equal_p (XEXP (false, 1), true)) 483618334Speter term1 = true, false = XEXP (false, 0), true = const0_rtx; 483718334Speter 483818334Speter term2 = gen_binary (AND, GET_MODE (src), XEXP (XEXP (src, 0), 0), true); 483918334Speter term3 = gen_binary (AND, GET_MODE (src), 484018334Speter gen_unary (NOT, GET_MODE (src), GET_MODE (src), 484118334Speter XEXP (XEXP (src, 0), 0)), 484218334Speter false); 484318334Speter 484418334Speter SUBST (SET_SRC (x), 484518334Speter gen_binary (IOR, GET_MODE (src), 484618334Speter gen_binary (IOR, GET_MODE (src), term1, term2), 484718334Speter term3)); 484818334Speter 484918334Speter src = SET_SRC (x); 485018334Speter } 485118334Speter 485218334Speter /* If either SRC or DEST is a CLOBBER of (const_int 0), make this 485318334Speter whole thing fail. */ 485418334Speter if (GET_CODE (src) == CLOBBER && XEXP (src, 0) == const0_rtx) 485518334Speter return src; 485618334Speter else if (GET_CODE (dest) == CLOBBER && XEXP (dest, 0) == const0_rtx) 485718334Speter return dest; 485818334Speter else 485918334Speter /* Convert this into a field assignment operation, if possible. */ 486018334Speter return make_field_assignment (x); 486118334Speter} 486218334Speter 486318334Speter/* Simplify, X, and AND, IOR, or XOR operation, and return the simplified 486418334Speter result. LAST is nonzero if this is the last retry. */ 486518334Speter 486618334Speterstatic rtx 486718334Spetersimplify_logical (x, last) 486818334Speter rtx x; 486918334Speter int last; 487018334Speter{ 487118334Speter enum machine_mode mode = GET_MODE (x); 487218334Speter rtx op0 = XEXP (x, 0); 487318334Speter rtx op1 = XEXP (x, 1); 487418334Speter 487518334Speter switch (GET_CODE (x)) 487618334Speter { 487718334Speter case AND: 487818334Speter /* Convert (A ^ B) & A to A & (~ B) since the latter is often a single 487918334Speter insn (and may simplify more). */ 488018334Speter if (GET_CODE (op0) == XOR 488118334Speter && rtx_equal_p (XEXP (op0, 0), op1) 488218334Speter && ! side_effects_p (op1)) 488318334Speter x = gen_binary (AND, mode, 488418334Speter gen_unary (NOT, mode, mode, XEXP (op0, 1)), op1); 488518334Speter 488618334Speter if (GET_CODE (op0) == XOR 488718334Speter && rtx_equal_p (XEXP (op0, 1), op1) 488818334Speter && ! side_effects_p (op1)) 488918334Speter x = gen_binary (AND, mode, 489018334Speter gen_unary (NOT, mode, mode, XEXP (op0, 0)), op1); 489118334Speter 489218334Speter /* Similarly for (~ (A ^ B)) & A. */ 489318334Speter if (GET_CODE (op0) == NOT 489418334Speter && GET_CODE (XEXP (op0, 0)) == XOR 489518334Speter && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1) 489618334Speter && ! side_effects_p (op1)) 489718334Speter x = gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1); 489818334Speter 489918334Speter if (GET_CODE (op0) == NOT 490018334Speter && GET_CODE (XEXP (op0, 0)) == XOR 490118334Speter && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1) 490218334Speter && ! side_effects_p (op1)) 490318334Speter x = gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1); 490418334Speter 490518334Speter if (GET_CODE (op1) == CONST_INT) 490618334Speter { 490718334Speter x = simplify_and_const_int (x, mode, op0, INTVAL (op1)); 490818334Speter 490918334Speter /* If we have (ior (and (X C1) C2)) and the next restart would be 491018334Speter the last, simplify this by making C1 as small as possible 491150397Sobrien and then exit. */ 491218334Speter if (last 491318334Speter && GET_CODE (x) == IOR && GET_CODE (op0) == AND 491418334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 491518334Speter && GET_CODE (op1) == CONST_INT) 491618334Speter return gen_binary (IOR, mode, 491718334Speter gen_binary (AND, mode, XEXP (op0, 0), 491818334Speter GEN_INT (INTVAL (XEXP (op0, 1)) 491918334Speter & ~ INTVAL (op1))), op1); 492018334Speter 492118334Speter if (GET_CODE (x) != AND) 492218334Speter return x; 492318334Speter 492418334Speter if (GET_RTX_CLASS (GET_CODE (x)) == 'c' 492518334Speter || GET_RTX_CLASS (GET_CODE (x)) == '2') 492618334Speter op0 = XEXP (x, 0), op1 = XEXP (x, 1); 492718334Speter } 492818334Speter 492918334Speter /* Convert (A | B) & A to A. */ 493018334Speter if (GET_CODE (op0) == IOR 493118334Speter && (rtx_equal_p (XEXP (op0, 0), op1) 493218334Speter || rtx_equal_p (XEXP (op0, 1), op1)) 493318334Speter && ! side_effects_p (XEXP (op0, 0)) 493418334Speter && ! side_effects_p (XEXP (op0, 1))) 493518334Speter return op1; 493618334Speter 493718334Speter /* In the following group of tests (and those in case IOR below), 493818334Speter we start with some combination of logical operations and apply 493918334Speter the distributive law followed by the inverse distributive law. 494018334Speter Most of the time, this results in no change. However, if some of 494118334Speter the operands are the same or inverses of each other, simplifications 494218334Speter will result. 494318334Speter 494418334Speter For example, (and (ior A B) (not B)) can occur as the result of 494518334Speter expanding a bit field assignment. When we apply the distributive 494618334Speter law to this, we get (ior (and (A (not B))) (and (B (not B)))), 494718334Speter which then simplifies to (and (A (not B))). 494818334Speter 494918334Speter If we have (and (ior A B) C), apply the distributive law and then 495018334Speter the inverse distributive law to see if things simplify. */ 495118334Speter 495218334Speter if (GET_CODE (op0) == IOR || GET_CODE (op0) == XOR) 495318334Speter { 495418334Speter x = apply_distributive_law 495518334Speter (gen_binary (GET_CODE (op0), mode, 495618334Speter gen_binary (AND, mode, XEXP (op0, 0), op1), 495718334Speter gen_binary (AND, mode, XEXP (op0, 1), op1))); 495818334Speter if (GET_CODE (x) != AND) 495918334Speter return x; 496018334Speter } 496118334Speter 496218334Speter if (GET_CODE (op1) == IOR || GET_CODE (op1) == XOR) 496318334Speter return apply_distributive_law 496418334Speter (gen_binary (GET_CODE (op1), mode, 496518334Speter gen_binary (AND, mode, XEXP (op1, 0), op0), 496618334Speter gen_binary (AND, mode, XEXP (op1, 1), op0))); 496718334Speter 496818334Speter /* Similarly, taking advantage of the fact that 496918334Speter (and (not A) (xor B C)) == (xor (ior A B) (ior A C)) */ 497018334Speter 497118334Speter if (GET_CODE (op0) == NOT && GET_CODE (op1) == XOR) 497218334Speter return apply_distributive_law 497318334Speter (gen_binary (XOR, mode, 497418334Speter gen_binary (IOR, mode, XEXP (op0, 0), XEXP (op1, 0)), 497518334Speter gen_binary (IOR, mode, XEXP (op0, 0), XEXP (op1, 1)))); 497618334Speter 497718334Speter else if (GET_CODE (op1) == NOT && GET_CODE (op0) == XOR) 497818334Speter return apply_distributive_law 497918334Speter (gen_binary (XOR, mode, 498018334Speter gen_binary (IOR, mode, XEXP (op1, 0), XEXP (op0, 0)), 498118334Speter gen_binary (IOR, mode, XEXP (op1, 0), XEXP (op0, 1)))); 498218334Speter break; 498318334Speter 498418334Speter case IOR: 498518334Speter /* (ior A C) is C if all bits of A that might be nonzero are on in C. */ 498618334Speter if (GET_CODE (op1) == CONST_INT 498718334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 498818334Speter && (nonzero_bits (op0, mode) & ~ INTVAL (op1)) == 0) 498918334Speter return op1; 499018334Speter 499118334Speter /* Convert (A & B) | A to A. */ 499218334Speter if (GET_CODE (op0) == AND 499318334Speter && (rtx_equal_p (XEXP (op0, 0), op1) 499418334Speter || rtx_equal_p (XEXP (op0, 1), op1)) 499518334Speter && ! side_effects_p (XEXP (op0, 0)) 499618334Speter && ! side_effects_p (XEXP (op0, 1))) 499718334Speter return op1; 499818334Speter 499918334Speter /* If we have (ior (and A B) C), apply the distributive law and then 500018334Speter the inverse distributive law to see if things simplify. */ 500118334Speter 500218334Speter if (GET_CODE (op0) == AND) 500318334Speter { 500418334Speter x = apply_distributive_law 500518334Speter (gen_binary (AND, mode, 500618334Speter gen_binary (IOR, mode, XEXP (op0, 0), op1), 500718334Speter gen_binary (IOR, mode, XEXP (op0, 1), op1))); 500818334Speter 500918334Speter if (GET_CODE (x) != IOR) 501018334Speter return x; 501118334Speter } 501218334Speter 501318334Speter if (GET_CODE (op1) == AND) 501418334Speter { 501518334Speter x = apply_distributive_law 501618334Speter (gen_binary (AND, mode, 501718334Speter gen_binary (IOR, mode, XEXP (op1, 0), op0), 501818334Speter gen_binary (IOR, mode, XEXP (op1, 1), op0))); 501918334Speter 502018334Speter if (GET_CODE (x) != IOR) 502118334Speter return x; 502218334Speter } 502318334Speter 502418334Speter /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the 502518334Speter mode size to (rotate A CX). */ 502618334Speter 502718334Speter if (((GET_CODE (op0) == ASHIFT && GET_CODE (op1) == LSHIFTRT) 502818334Speter || (GET_CODE (op1) == ASHIFT && GET_CODE (op0) == LSHIFTRT)) 502918334Speter && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)) 503018334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 503118334Speter && GET_CODE (XEXP (op1, 1)) == CONST_INT 503218334Speter && (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)) 503318334Speter == GET_MODE_BITSIZE (mode))) 503450397Sobrien return gen_rtx_ROTATE (mode, XEXP (op0, 0), 503550397Sobrien (GET_CODE (op0) == ASHIFT 503650397Sobrien ? XEXP (op0, 1) : XEXP (op1, 1))); 503718334Speter 503818334Speter /* If OP0 is (ashiftrt (plus ...) C), it might actually be 503918334Speter a (sign_extend (plus ...)). If so, OP1 is a CONST_INT, and the PLUS 504018334Speter does not affect any of the bits in OP1, it can really be done 504118334Speter as a PLUS and we can associate. We do this by seeing if OP1 504218334Speter can be safely shifted left C bits. */ 504318334Speter if (GET_CODE (op1) == CONST_INT && GET_CODE (op0) == ASHIFTRT 504418334Speter && GET_CODE (XEXP (op0, 0)) == PLUS 504518334Speter && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT 504618334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 504718334Speter && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT) 504818334Speter { 504918334Speter int count = INTVAL (XEXP (op0, 1)); 505018334Speter HOST_WIDE_INT mask = INTVAL (op1) << count; 505118334Speter 505218334Speter if (mask >> count == INTVAL (op1) 505318334Speter && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0) 505418334Speter { 505518334Speter SUBST (XEXP (XEXP (op0, 0), 1), 505618334Speter GEN_INT (INTVAL (XEXP (XEXP (op0, 0), 1)) | mask)); 505718334Speter return op0; 505818334Speter } 505918334Speter } 506018334Speter break; 506118334Speter 506218334Speter case XOR: 506318334Speter /* Convert (XOR (NOT x) (NOT y)) to (XOR x y). 506418334Speter Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for 506518334Speter (NOT y). */ 506618334Speter { 506718334Speter int num_negated = 0; 506818334Speter 506918334Speter if (GET_CODE (op0) == NOT) 507018334Speter num_negated++, op0 = XEXP (op0, 0); 507118334Speter if (GET_CODE (op1) == NOT) 507218334Speter num_negated++, op1 = XEXP (op1, 0); 507318334Speter 507418334Speter if (num_negated == 2) 507518334Speter { 507618334Speter SUBST (XEXP (x, 0), op0); 507718334Speter SUBST (XEXP (x, 1), op1); 507818334Speter } 507918334Speter else if (num_negated == 1) 508018334Speter return gen_unary (NOT, mode, mode, gen_binary (XOR, mode, op0, op1)); 508118334Speter } 508218334Speter 508318334Speter /* Convert (xor (and A B) B) to (and (not A) B). The latter may 508418334Speter correspond to a machine insn or result in further simplifications 508518334Speter if B is a constant. */ 508618334Speter 508718334Speter if (GET_CODE (op0) == AND 508818334Speter && rtx_equal_p (XEXP (op0, 1), op1) 508918334Speter && ! side_effects_p (op1)) 509018334Speter return gen_binary (AND, mode, 509118334Speter gen_unary (NOT, mode, mode, XEXP (op0, 0)), 509218334Speter op1); 509318334Speter 509418334Speter else if (GET_CODE (op0) == AND 509518334Speter && rtx_equal_p (XEXP (op0, 0), op1) 509618334Speter && ! side_effects_p (op1)) 509718334Speter return gen_binary (AND, mode, 509818334Speter gen_unary (NOT, mode, mode, XEXP (op0, 1)), 509918334Speter op1); 510018334Speter 510118334Speter /* (xor (comparison foo bar) (const_int 1)) can become the reversed 510250397Sobrien comparison if STORE_FLAG_VALUE is 1. */ 510350397Sobrien if (STORE_FLAG_VALUE == 1 510450397Sobrien && op1 == const1_rtx 510518334Speter && GET_RTX_CLASS (GET_CODE (op0)) == '<' 510618334Speter && reversible_comparison_p (op0)) 510718334Speter return gen_rtx_combine (reverse_condition (GET_CODE (op0)), 510818334Speter mode, XEXP (op0, 0), XEXP (op0, 1)); 510918334Speter 511018334Speter /* (lshiftrt foo C) where C is the number of bits in FOO minus 1 511118334Speter is (lt foo (const_int 0)), so we can perform the above 511250397Sobrien simplification if STORE_FLAG_VALUE is 1. */ 511318334Speter 511450397Sobrien if (STORE_FLAG_VALUE == 1 511550397Sobrien && op1 == const1_rtx 511618334Speter && GET_CODE (op0) == LSHIFTRT 511718334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 511818334Speter && INTVAL (XEXP (op0, 1)) == GET_MODE_BITSIZE (mode) - 1) 511918334Speter return gen_rtx_combine (GE, mode, XEXP (op0, 0), const0_rtx); 512018334Speter 512118334Speter /* (xor (comparison foo bar) (const_int sign-bit)) 512218334Speter when STORE_FLAG_VALUE is the sign bit. */ 512318334Speter if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 512450397Sobrien && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode)) 512552284Sobrien == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)) 512618334Speter && op1 == const_true_rtx 512718334Speter && GET_RTX_CLASS (GET_CODE (op0)) == '<' 512818334Speter && reversible_comparison_p (op0)) 512918334Speter return gen_rtx_combine (reverse_condition (GET_CODE (op0)), 513018334Speter mode, XEXP (op0, 0), XEXP (op0, 1)); 513118334Speter break; 513250397Sobrien 513350397Sobrien default: 513450397Sobrien abort (); 513518334Speter } 513618334Speter 513718334Speter return x; 513818334Speter} 513918334Speter 514018334Speter/* We consider ZERO_EXTRACT, SIGN_EXTRACT, and SIGN_EXTEND as "compound 514118334Speter operations" because they can be replaced with two more basic operations. 514218334Speter ZERO_EXTEND is also considered "compound" because it can be replaced with 514318334Speter an AND operation, which is simpler, though only one operation. 514418334Speter 514518334Speter The function expand_compound_operation is called with an rtx expression 514618334Speter and will convert it to the appropriate shifts and AND operations, 514718334Speter simplifying at each stage. 514818334Speter 514918334Speter The function make_compound_operation is called to convert an expression 515018334Speter consisting of shifts and ANDs into the equivalent compound expression. 515118334Speter It is the inverse of this function, loosely speaking. */ 515218334Speter 515318334Speterstatic rtx 515418334Speterexpand_compound_operation (x) 515518334Speter rtx x; 515618334Speter{ 515718334Speter int pos = 0, len; 515818334Speter int unsignedp = 0; 515918334Speter int modewidth; 516018334Speter rtx tem; 516118334Speter 516218334Speter switch (GET_CODE (x)) 516318334Speter { 516418334Speter case ZERO_EXTEND: 516518334Speter unsignedp = 1; 516618334Speter case SIGN_EXTEND: 516718334Speter /* We can't necessarily use a const_int for a multiword mode; 516818334Speter it depends on implicitly extending the value. 516918334Speter Since we don't know the right way to extend it, 517018334Speter we can't tell whether the implicit way is right. 517118334Speter 517218334Speter Even for a mode that is no wider than a const_int, 517318334Speter we can't win, because we need to sign extend one of its bits through 517418334Speter the rest of it, and we don't know which bit. */ 517518334Speter if (GET_CODE (XEXP (x, 0)) == CONST_INT) 517618334Speter return x; 517718334Speter 517818334Speter /* Return if (subreg:MODE FROM 0) is not a safe replacement for 517918334Speter (zero_extend:MODE FROM) or (sign_extend:MODE FROM). It is for any MEM 518018334Speter because (SUBREG (MEM...)) is guaranteed to cause the MEM to be 518118334Speter reloaded. If not for that, MEM's would very rarely be safe. 518218334Speter 518318334Speter Reject MODEs bigger than a word, because we might not be able 518418334Speter to reference a two-register group starting with an arbitrary register 518518334Speter (and currently gen_lowpart might crash for a SUBREG). */ 518618334Speter 518718334Speter if (GET_MODE_SIZE (GET_MODE (XEXP (x, 0))) > UNITS_PER_WORD) 518818334Speter return x; 518918334Speter 519018334Speter len = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))); 519118334Speter /* If the inner object has VOIDmode (the only way this can happen 519218334Speter is if it is a ASM_OPERANDS), we can't do anything since we don't 519318334Speter know how much masking to do. */ 519418334Speter if (len == 0) 519518334Speter return x; 519618334Speter 519718334Speter break; 519818334Speter 519918334Speter case ZERO_EXTRACT: 520018334Speter unsignedp = 1; 520118334Speter case SIGN_EXTRACT: 520218334Speter /* If the operand is a CLOBBER, just return it. */ 520318334Speter if (GET_CODE (XEXP (x, 0)) == CLOBBER) 520418334Speter return XEXP (x, 0); 520518334Speter 520618334Speter if (GET_CODE (XEXP (x, 1)) != CONST_INT 520718334Speter || GET_CODE (XEXP (x, 2)) != CONST_INT 520818334Speter || GET_MODE (XEXP (x, 0)) == VOIDmode) 520918334Speter return x; 521018334Speter 521118334Speter len = INTVAL (XEXP (x, 1)); 521218334Speter pos = INTVAL (XEXP (x, 2)); 521318334Speter 521418334Speter /* If this goes outside the object being extracted, replace the object 521518334Speter with a (use (mem ...)) construct that only combine understands 521618334Speter and is used only for this purpose. */ 521718334Speter if (len + pos > GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))) 521850397Sobrien SUBST (XEXP (x, 0), gen_rtx_USE (GET_MODE (x), XEXP (x, 0))); 521918334Speter 522018334Speter if (BITS_BIG_ENDIAN) 522118334Speter pos = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - len - pos; 522218334Speter 522318334Speter break; 522418334Speter 522518334Speter default: 522618334Speter return x; 522718334Speter } 522818334Speter 522950397Sobrien /* We can optimize some special cases of ZERO_EXTEND. */ 523050397Sobrien if (GET_CODE (x) == ZERO_EXTEND) 523150397Sobrien { 523250397Sobrien /* (zero_extend:DI (truncate:SI foo:DI)) is just foo:DI if we 523350397Sobrien know that the last value didn't have any inappropriate bits 523450397Sobrien set. */ 523550397Sobrien if (GET_CODE (XEXP (x, 0)) == TRUNCATE 523650397Sobrien && GET_MODE (XEXP (XEXP (x, 0), 0)) == GET_MODE (x) 523750397Sobrien && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT 523850397Sobrien && (nonzero_bits (XEXP (XEXP (x, 0), 0), GET_MODE (x)) 523950397Sobrien & ~ GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0) 524050397Sobrien return XEXP (XEXP (x, 0), 0); 524150397Sobrien 524250397Sobrien /* Likewise for (zero_extend:DI (subreg:SI foo:DI 0)). */ 524350397Sobrien if (GET_CODE (XEXP (x, 0)) == SUBREG 524450397Sobrien && GET_MODE (SUBREG_REG (XEXP (x, 0))) == GET_MODE (x) 524550397Sobrien && subreg_lowpart_p (XEXP (x, 0)) 524650397Sobrien && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT 524750397Sobrien && (nonzero_bits (SUBREG_REG (XEXP (x, 0)), GET_MODE (x)) 524850397Sobrien & ~ GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0) 524950397Sobrien return SUBREG_REG (XEXP (x, 0)); 525050397Sobrien 525150397Sobrien /* (zero_extend:DI (truncate:SI foo:DI)) is just foo:DI when foo 525250397Sobrien is a comparison and STORE_FLAG_VALUE permits. This is like 525350397Sobrien the first case, but it works even when GET_MODE (x) is larger 525450397Sobrien than HOST_WIDE_INT. */ 525550397Sobrien if (GET_CODE (XEXP (x, 0)) == TRUNCATE 525650397Sobrien && GET_MODE (XEXP (XEXP (x, 0), 0)) == GET_MODE (x) 525750397Sobrien && GET_RTX_CLASS (GET_CODE (XEXP (XEXP (x, 0), 0))) == '<' 525850397Sobrien && (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) 525950397Sobrien <= HOST_BITS_PER_WIDE_INT) 526050397Sobrien && ((HOST_WIDE_INT) STORE_FLAG_VALUE 526150397Sobrien & ~ GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0) 526250397Sobrien return XEXP (XEXP (x, 0), 0); 526350397Sobrien 526450397Sobrien /* Likewise for (zero_extend:DI (subreg:SI foo:DI 0)). */ 526550397Sobrien if (GET_CODE (XEXP (x, 0)) == SUBREG 526650397Sobrien && GET_MODE (SUBREG_REG (XEXP (x, 0))) == GET_MODE (x) 526750397Sobrien && subreg_lowpart_p (XEXP (x, 0)) 526850397Sobrien && GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0)))) == '<' 526950397Sobrien && (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) 527050397Sobrien <= HOST_BITS_PER_WIDE_INT) 527150397Sobrien && ((HOST_WIDE_INT) STORE_FLAG_VALUE 527250397Sobrien & ~ GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0) 527350397Sobrien return SUBREG_REG (XEXP (x, 0)); 527450397Sobrien 527550397Sobrien /* If sign extension is cheaper than zero extension, then use it 527650397Sobrien if we know that no extraneous bits are set, and that the high 527750397Sobrien bit is not set. */ 527850397Sobrien if (flag_expensive_optimizations 527950397Sobrien && ((GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT 528050397Sobrien && ((nonzero_bits (XEXP (x, 0), GET_MODE (x)) 528150397Sobrien & ~ (((unsigned HOST_WIDE_INT) 528250397Sobrien GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) 528350397Sobrien >> 1)) 528450397Sobrien == 0)) 528550397Sobrien || (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<' 528650397Sobrien && (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) 528750397Sobrien <= HOST_BITS_PER_WIDE_INT) 528850397Sobrien && (((HOST_WIDE_INT) STORE_FLAG_VALUE 528950397Sobrien & ~ (((unsigned HOST_WIDE_INT) 529050397Sobrien GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) 529150397Sobrien >> 1)) 529250397Sobrien == 0)))) 529350397Sobrien { 529450397Sobrien rtx temp = gen_rtx_SIGN_EXTEND (GET_MODE (x), XEXP (x, 0)); 529550397Sobrien 529650397Sobrien if (rtx_cost (temp, SET) < rtx_cost (x, SET)) 529750397Sobrien return expand_compound_operation (temp); 529850397Sobrien } 529950397Sobrien } 530050397Sobrien 530118334Speter /* If we reach here, we want to return a pair of shifts. The inner 530218334Speter shift is a left shift of BITSIZE - POS - LEN bits. The outer 530318334Speter shift is a right shift of BITSIZE - LEN bits. It is arithmetic or 530418334Speter logical depending on the value of UNSIGNEDP. 530518334Speter 530618334Speter If this was a ZERO_EXTEND or ZERO_EXTRACT, this pair of shifts will be 530718334Speter converted into an AND of a shift. 530818334Speter 530918334Speter We must check for the case where the left shift would have a negative 531018334Speter count. This can happen in a case like (x >> 31) & 255 on machines 531118334Speter that can't shift by a constant. On those machines, we would first 531218334Speter combine the shift with the AND to produce a variable-position 531318334Speter extraction. Then the constant of 31 would be substituted in to produce 531418334Speter a such a position. */ 531518334Speter 531618334Speter modewidth = GET_MODE_BITSIZE (GET_MODE (x)); 531718334Speter if (modewidth >= pos - len) 531818334Speter tem = simplify_shift_const (NULL_RTX, unsignedp ? LSHIFTRT : ASHIFTRT, 531918334Speter GET_MODE (x), 532018334Speter simplify_shift_const (NULL_RTX, ASHIFT, 532118334Speter GET_MODE (x), 532218334Speter XEXP (x, 0), 532318334Speter modewidth - pos - len), 532418334Speter modewidth - len); 532518334Speter 532618334Speter else if (unsignedp && len < HOST_BITS_PER_WIDE_INT) 532718334Speter tem = simplify_and_const_int (NULL_RTX, GET_MODE (x), 532818334Speter simplify_shift_const (NULL_RTX, LSHIFTRT, 532918334Speter GET_MODE (x), 533018334Speter XEXP (x, 0), pos), 533118334Speter ((HOST_WIDE_INT) 1 << len) - 1); 533218334Speter else 533318334Speter /* Any other cases we can't handle. */ 533418334Speter return x; 533518334Speter 533618334Speter 533718334Speter /* If we couldn't do this for some reason, return the original 533818334Speter expression. */ 533918334Speter if (GET_CODE (tem) == CLOBBER) 534018334Speter return x; 534118334Speter 534218334Speter return tem; 534318334Speter} 534418334Speter 534518334Speter/* X is a SET which contains an assignment of one object into 534618334Speter a part of another (such as a bit-field assignment, STRICT_LOW_PART, 534718334Speter or certain SUBREGS). If possible, convert it into a series of 534818334Speter logical operations. 534918334Speter 535018334Speter We half-heartedly support variable positions, but do not at all 535118334Speter support variable lengths. */ 535218334Speter 535318334Speterstatic rtx 535418334Speterexpand_field_assignment (x) 535518334Speter rtx x; 535618334Speter{ 535718334Speter rtx inner; 535850397Sobrien rtx pos; /* Always counts from low bit. */ 535918334Speter int len; 536018334Speter rtx mask; 536118334Speter enum machine_mode compute_mode; 536218334Speter 536318334Speter /* Loop until we find something we can't simplify. */ 536418334Speter while (1) 536518334Speter { 536618334Speter if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART 536718334Speter && GET_CODE (XEXP (SET_DEST (x), 0)) == SUBREG) 536818334Speter { 536918334Speter inner = SUBREG_REG (XEXP (SET_DEST (x), 0)); 537018334Speter len = GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0))); 537150397Sobrien pos = GEN_INT (BITS_PER_WORD * SUBREG_WORD (XEXP (SET_DEST (x), 0))); 537218334Speter } 537318334Speter else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT 537418334Speter && GET_CODE (XEXP (SET_DEST (x), 1)) == CONST_INT) 537518334Speter { 537618334Speter inner = XEXP (SET_DEST (x), 0); 537718334Speter len = INTVAL (XEXP (SET_DEST (x), 1)); 537818334Speter pos = XEXP (SET_DEST (x), 2); 537918334Speter 538018334Speter /* If the position is constant and spans the width of INNER, 538118334Speter surround INNER with a USE to indicate this. */ 538218334Speter if (GET_CODE (pos) == CONST_INT 538318334Speter && INTVAL (pos) + len > GET_MODE_BITSIZE (GET_MODE (inner))) 538450397Sobrien inner = gen_rtx_USE (GET_MODE (SET_DEST (x)), inner); 538518334Speter 538618334Speter if (BITS_BIG_ENDIAN) 538718334Speter { 538818334Speter if (GET_CODE (pos) == CONST_INT) 538918334Speter pos = GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner)) - len 539018334Speter - INTVAL (pos)); 539118334Speter else if (GET_CODE (pos) == MINUS 539218334Speter && GET_CODE (XEXP (pos, 1)) == CONST_INT 539318334Speter && (INTVAL (XEXP (pos, 1)) 539418334Speter == GET_MODE_BITSIZE (GET_MODE (inner)) - len)) 539518334Speter /* If position is ADJUST - X, new position is X. */ 539618334Speter pos = XEXP (pos, 0); 539718334Speter else 539818334Speter pos = gen_binary (MINUS, GET_MODE (pos), 539918334Speter GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner)) 540018334Speter - len), 540118334Speter pos); 540218334Speter } 540318334Speter } 540418334Speter 540518334Speter /* A SUBREG between two modes that occupy the same numbers of words 540618334Speter can be done by moving the SUBREG to the source. */ 540718334Speter else if (GET_CODE (SET_DEST (x)) == SUBREG 540818334Speter && (((GET_MODE_SIZE (GET_MODE (SET_DEST (x))) 540918334Speter + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) 541018334Speter == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x)))) 541118334Speter + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))) 541218334Speter { 541350397Sobrien x = gen_rtx_SET (VOIDmode, SUBREG_REG (SET_DEST (x)), 541450397Sobrien gen_lowpart_for_combine (GET_MODE (SUBREG_REG (SET_DEST (x))), 541550397Sobrien SET_SRC (x))); 541618334Speter continue; 541718334Speter } 541818334Speter else 541918334Speter break; 542018334Speter 542118334Speter while (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner)) 542218334Speter inner = SUBREG_REG (inner); 542318334Speter 542418334Speter compute_mode = GET_MODE (inner); 542518334Speter 542652284Sobrien /* Don't attempt bitwise arithmetic on non-integral modes. */ 542752284Sobrien if (! INTEGRAL_MODE_P (compute_mode)) 542852284Sobrien { 542952284Sobrien enum machine_mode imode; 543052284Sobrien 543152284Sobrien /* Something is probably seriously wrong if this matches. */ 543252284Sobrien if (! FLOAT_MODE_P (compute_mode)) 543352284Sobrien break; 543452284Sobrien 543552284Sobrien /* Try to find an integral mode to pun with. */ 543652284Sobrien imode = mode_for_size (GET_MODE_BITSIZE (compute_mode), MODE_INT, 0); 543752284Sobrien if (imode == BLKmode) 543852284Sobrien break; 543952284Sobrien 544052284Sobrien compute_mode = imode; 544152284Sobrien inner = gen_lowpart_for_combine (imode, inner); 544252284Sobrien } 544352284Sobrien 544418334Speter /* Compute a mask of LEN bits, if we can do this on the host machine. */ 544518334Speter if (len < HOST_BITS_PER_WIDE_INT) 544618334Speter mask = GEN_INT (((HOST_WIDE_INT) 1 << len) - 1); 544718334Speter else 544818334Speter break; 544918334Speter 545018334Speter /* Now compute the equivalent expression. Make a copy of INNER 545118334Speter for the SET_DEST in case it is a MEM into which we will substitute; 545218334Speter we don't want shared RTL in that case. */ 545350397Sobrien x = gen_rtx_SET (VOIDmode, copy_rtx (inner), 545450397Sobrien gen_binary (IOR, compute_mode, 545550397Sobrien gen_binary (AND, compute_mode, 545650397Sobrien gen_unary (NOT, compute_mode, 545750397Sobrien compute_mode, 545850397Sobrien gen_binary (ASHIFT, 545950397Sobrien compute_mode, 546050397Sobrien mask, pos)), 546150397Sobrien inner), 546250397Sobrien gen_binary (ASHIFT, compute_mode, 546350397Sobrien gen_binary (AND, compute_mode, 546450397Sobrien gen_lowpart_for_combine 546550397Sobrien (compute_mode, 546650397Sobrien SET_SRC (x)), 546750397Sobrien mask), 546850397Sobrien pos))); 546918334Speter } 547018334Speter 547118334Speter return x; 547218334Speter} 547318334Speter 547418334Speter/* Return an RTX for a reference to LEN bits of INNER. If POS_RTX is nonzero, 547518334Speter it is an RTX that represents a variable starting position; otherwise, 547618334Speter POS is the (constant) starting bit position (counted from the LSB). 547718334Speter 547818334Speter INNER may be a USE. This will occur when we started with a bitfield 547918334Speter that went outside the boundary of the object in memory, which is 548018334Speter allowed on most machines. To isolate this case, we produce a USE 548118334Speter whose mode is wide enough and surround the MEM with it. The only 548218334Speter code that understands the USE is this routine. If it is not removed, 548318334Speter it will cause the resulting insn not to match. 548418334Speter 548518334Speter UNSIGNEDP is non-zero for an unsigned reference and zero for a 548618334Speter signed reference. 548718334Speter 548818334Speter IN_DEST is non-zero if this is a reference in the destination of a 548918334Speter SET. This is used when a ZERO_ or SIGN_EXTRACT isn't needed. If non-zero, 549018334Speter a STRICT_LOW_PART will be used, if zero, ZERO_EXTEND or SIGN_EXTEND will 549118334Speter be used. 549218334Speter 549318334Speter IN_COMPARE is non-zero if we are in a COMPARE. This means that a 549418334Speter ZERO_EXTRACT should be built even for bits starting at bit 0. 549518334Speter 549650397Sobrien MODE is the desired mode of the result (if IN_DEST == 0). 549718334Speter 549850397Sobrien The result is an RTX for the extraction or NULL_RTX if the target 549950397Sobrien can't handle it. */ 550050397Sobrien 550118334Speterstatic rtx 550218334Spetermake_extraction (mode, inner, pos, pos_rtx, len, 550318334Speter unsignedp, in_dest, in_compare) 550418334Speter enum machine_mode mode; 550518334Speter rtx inner; 550618334Speter int pos; 550718334Speter rtx pos_rtx; 550818334Speter int len; 550918334Speter int unsignedp; 551018334Speter int in_dest, in_compare; 551118334Speter{ 551218334Speter /* This mode describes the size of the storage area 551318334Speter to fetch the overall value from. Within that, we 551418334Speter ignore the POS lowest bits, etc. */ 551518334Speter enum machine_mode is_mode = GET_MODE (inner); 551618334Speter enum machine_mode inner_mode; 551750397Sobrien enum machine_mode wanted_inner_mode = byte_mode; 551850397Sobrien enum machine_mode wanted_inner_reg_mode = word_mode; 551918334Speter enum machine_mode pos_mode = word_mode; 552018334Speter enum machine_mode extraction_mode = word_mode; 552118334Speter enum machine_mode tmode = mode_for_size (len, MODE_INT, 1); 552218334Speter int spans_byte = 0; 552318334Speter rtx new = 0; 552418334Speter rtx orig_pos_rtx = pos_rtx; 552518334Speter int orig_pos; 552618334Speter 552718334Speter /* Get some information about INNER and get the innermost object. */ 552818334Speter if (GET_CODE (inner) == USE) 552918334Speter /* (use:SI (mem:QI foo)) stands for (mem:SI foo). */ 553018334Speter /* We don't need to adjust the position because we set up the USE 553118334Speter to pretend that it was a full-word object. */ 553218334Speter spans_byte = 1, inner = XEXP (inner, 0); 553318334Speter else if (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner)) 553418334Speter { 553518334Speter /* If going from (subreg:SI (mem:QI ...)) to (mem:QI ...), 553618334Speter consider just the QI as the memory to extract from. 553718334Speter The subreg adds or removes high bits; its mode is 553818334Speter irrelevant to the meaning of this extraction, 553918334Speter since POS and LEN count from the lsb. */ 554018334Speter if (GET_CODE (SUBREG_REG (inner)) == MEM) 554118334Speter is_mode = GET_MODE (SUBREG_REG (inner)); 554218334Speter inner = SUBREG_REG (inner); 554318334Speter } 554418334Speter 554518334Speter inner_mode = GET_MODE (inner); 554618334Speter 554718334Speter if (pos_rtx && GET_CODE (pos_rtx) == CONST_INT) 554818334Speter pos = INTVAL (pos_rtx), pos_rtx = 0; 554918334Speter 555018334Speter /* See if this can be done without an extraction. We never can if the 555118334Speter width of the field is not the same as that of some integer mode. For 555218334Speter registers, we can only avoid the extraction if the position is at the 555318334Speter low-order bit and this is either not in the destination or we have the 555418334Speter appropriate STRICT_LOW_PART operation available. 555518334Speter 555618334Speter For MEM, we can avoid an extract if the field starts on an appropriate 555718334Speter boundary and we can change the mode of the memory reference. However, 555818334Speter we cannot directly access the MEM if we have a USE and the underlying 555918334Speter MEM is not TMODE. This combination means that MEM was being used in a 556018334Speter context where bits outside its mode were being referenced; that is only 556118334Speter valid in bit-field insns. */ 556218334Speter 556318334Speter if (tmode != BLKmode 556418334Speter && ! (spans_byte && inner_mode != tmode) 556550397Sobrien && ((pos_rtx == 0 && (pos % BITS_PER_WORD) == 0 556650397Sobrien && GET_CODE (inner) != MEM 556718334Speter && (! in_dest 556818334Speter || (GET_CODE (inner) == REG 556918334Speter && (movstrict_optab->handlers[(int) tmode].insn_code 557018334Speter != CODE_FOR_nothing)))) 557118334Speter || (GET_CODE (inner) == MEM && pos_rtx == 0 557218334Speter && (pos 557318334Speter % (STRICT_ALIGNMENT ? GET_MODE_ALIGNMENT (tmode) 557418334Speter : BITS_PER_UNIT)) == 0 557518334Speter /* We can't do this if we are widening INNER_MODE (it 557618334Speter may not be aligned, for one thing). */ 557718334Speter && GET_MODE_BITSIZE (inner_mode) >= GET_MODE_BITSIZE (tmode) 557818334Speter && (inner_mode == tmode 557918334Speter || (! mode_dependent_address_p (XEXP (inner, 0)) 558018334Speter && ! MEM_VOLATILE_P (inner)))))) 558118334Speter { 558218334Speter /* If INNER is a MEM, make a new MEM that encompasses just the desired 558318334Speter field. If the original and current mode are the same, we need not 558418334Speter adjust the offset. Otherwise, we do if bytes big endian. 558518334Speter 558650397Sobrien If INNER is not a MEM, get a piece consisting of just the field 558750397Sobrien of interest (in this case POS % BITS_PER_WORD must be 0). */ 558818334Speter 558918334Speter if (GET_CODE (inner) == MEM) 559018334Speter { 559118334Speter int offset; 559218334Speter /* POS counts from lsb, but make OFFSET count in memory order. */ 559318334Speter if (BYTES_BIG_ENDIAN) 559418334Speter offset = (GET_MODE_BITSIZE (is_mode) - len - pos) / BITS_PER_UNIT; 559518334Speter else 559618334Speter offset = pos / BITS_PER_UNIT; 559718334Speter 559850397Sobrien new = gen_rtx_MEM (tmode, plus_constant (XEXP (inner, 0), offset)); 559918334Speter RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (inner); 560052284Sobrien MEM_COPY_ATTRIBUTES (new, inner); 560118334Speter } 560218334Speter else if (GET_CODE (inner) == REG) 560318334Speter { 560418334Speter /* We can't call gen_lowpart_for_combine here since we always want 560518334Speter a SUBREG and it would sometimes return a new hard register. */ 560618334Speter if (tmode != inner_mode) 560750397Sobrien new = gen_rtx_SUBREG (tmode, inner, 560850397Sobrien (WORDS_BIG_ENDIAN 560950397Sobrien && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD 561050397Sobrien ? (((GET_MODE_SIZE (inner_mode) 561150397Sobrien - GET_MODE_SIZE (tmode)) 561250397Sobrien / UNITS_PER_WORD) 561350397Sobrien - pos / BITS_PER_WORD) 561450397Sobrien : pos / BITS_PER_WORD)); 561518334Speter else 561618334Speter new = inner; 561718334Speter } 561818334Speter else 561918334Speter new = force_to_mode (inner, tmode, 562018334Speter len >= HOST_BITS_PER_WIDE_INT 562118334Speter ? GET_MODE_MASK (tmode) 562218334Speter : ((HOST_WIDE_INT) 1 << len) - 1, 562318334Speter NULL_RTX, 0); 562418334Speter 562518334Speter /* If this extraction is going into the destination of a SET, 562618334Speter make a STRICT_LOW_PART unless we made a MEM. */ 562718334Speter 562818334Speter if (in_dest) 562918334Speter return (GET_CODE (new) == MEM ? new 563018334Speter : (GET_CODE (new) != SUBREG 563150397Sobrien ? gen_rtx_CLOBBER (tmode, const0_rtx) 563218334Speter : gen_rtx_combine (STRICT_LOW_PART, VOIDmode, new))); 563318334Speter 563418334Speter /* Otherwise, sign- or zero-extend unless we already are in the 563518334Speter proper mode. */ 563618334Speter 563718334Speter return (mode == tmode ? new 563818334Speter : gen_rtx_combine (unsignedp ? ZERO_EXTEND : SIGN_EXTEND, 563918334Speter mode, new)); 564018334Speter } 564118334Speter 564218334Speter /* Unless this is a COMPARE or we have a funny memory reference, 564318334Speter don't do anything with zero-extending field extracts starting at 564418334Speter the low-order bit since they are simple AND operations. */ 564518334Speter if (pos_rtx == 0 && pos == 0 && ! in_dest 564618334Speter && ! in_compare && ! spans_byte && unsignedp) 564718334Speter return 0; 564818334Speter 564918334Speter /* Unless we are allowed to span bytes, reject this if we would be 565018334Speter spanning bytes or if the position is not a constant and the length 565118334Speter is not 1. In all other cases, we would only be going outside 565218334Speter out object in cases when an original shift would have been 565318334Speter undefined. */ 565418334Speter if (! spans_byte 565518334Speter && ((pos_rtx == 0 && pos + len > GET_MODE_BITSIZE (is_mode)) 565618334Speter || (pos_rtx != 0 && len != 1))) 565718334Speter return 0; 565818334Speter 565950397Sobrien /* Get the mode to use should INNER not be a MEM, the mode for the position, 566018334Speter and the mode for the result. */ 566118334Speter#ifdef HAVE_insv 566218334Speter if (in_dest) 566318334Speter { 566452284Sobrien wanted_inner_reg_mode 566552284Sobrien = (insn_operand_mode[(int) CODE_FOR_insv][0] == VOIDmode 566652284Sobrien ? word_mode 566752284Sobrien : insn_operand_mode[(int) CODE_FOR_insv][0]); 566852284Sobrien pos_mode = (insn_operand_mode[(int) CODE_FOR_insv][2] == VOIDmode 566952284Sobrien ? word_mode : insn_operand_mode[(int) CODE_FOR_insv][2]); 567052284Sobrien extraction_mode = (insn_operand_mode[(int) CODE_FOR_insv][3] == VOIDmode 567152284Sobrien ? word_mode 567252284Sobrien : insn_operand_mode[(int) CODE_FOR_insv][3]); 567318334Speter } 567418334Speter#endif 567518334Speter 567618334Speter#ifdef HAVE_extzv 567718334Speter if (! in_dest && unsignedp) 567818334Speter { 567952284Sobrien wanted_inner_reg_mode 568052284Sobrien = (insn_operand_mode[(int) CODE_FOR_extzv][1] == VOIDmode 568152284Sobrien ? word_mode 568252284Sobrien : insn_operand_mode[(int) CODE_FOR_extzv][1]); 568352284Sobrien pos_mode = (insn_operand_mode[(int) CODE_FOR_extzv][3] == VOIDmode 568452284Sobrien ? word_mode : insn_operand_mode[(int) CODE_FOR_extzv][3]); 568552284Sobrien extraction_mode = (insn_operand_mode[(int) CODE_FOR_extzv][0] == VOIDmode 568652284Sobrien ? word_mode 568752284Sobrien : insn_operand_mode[(int) CODE_FOR_extzv][0]); 568818334Speter } 568918334Speter#endif 569018334Speter 569118334Speter#ifdef HAVE_extv 569218334Speter if (! in_dest && ! unsignedp) 569318334Speter { 569452284Sobrien wanted_inner_reg_mode 569552284Sobrien = (insn_operand_mode[(int) CODE_FOR_extv][1] == VOIDmode 569652284Sobrien ? word_mode 569752284Sobrien : insn_operand_mode[(int) CODE_FOR_extv][1]); 569852284Sobrien pos_mode = (insn_operand_mode[(int) CODE_FOR_extv][3] == VOIDmode 569952284Sobrien ? word_mode : insn_operand_mode[(int) CODE_FOR_extv][3]); 570052284Sobrien extraction_mode = (insn_operand_mode[(int) CODE_FOR_extv][0] == VOIDmode 570152284Sobrien ? word_mode 570252284Sobrien : insn_operand_mode[(int) CODE_FOR_extv][0]); 570318334Speter } 570418334Speter#endif 570518334Speter 570618334Speter /* Never narrow an object, since that might not be safe. */ 570718334Speter 570818334Speter if (mode != VOIDmode 570918334Speter && GET_MODE_SIZE (extraction_mode) < GET_MODE_SIZE (mode)) 571018334Speter extraction_mode = mode; 571118334Speter 571218334Speter if (pos_rtx && GET_MODE (pos_rtx) != VOIDmode 571318334Speter && GET_MODE_SIZE (pos_mode) < GET_MODE_SIZE (GET_MODE (pos_rtx))) 571418334Speter pos_mode = GET_MODE (pos_rtx); 571518334Speter 571650397Sobrien /* If this is not from memory, the desired mode is wanted_inner_reg_mode; 571750397Sobrien if we have to change the mode of memory and cannot, the desired mode is 571850397Sobrien EXTRACTION_MODE. */ 571950397Sobrien if (GET_CODE (inner) != MEM) 572050397Sobrien wanted_inner_mode = wanted_inner_reg_mode; 572150397Sobrien else if (inner_mode != wanted_inner_mode 572250397Sobrien && (mode_dependent_address_p (XEXP (inner, 0)) 572350397Sobrien || MEM_VOLATILE_P (inner))) 572450397Sobrien wanted_inner_mode = extraction_mode; 572518334Speter 572618334Speter orig_pos = pos; 572718334Speter 572818334Speter if (BITS_BIG_ENDIAN) 572918334Speter { 573050397Sobrien /* POS is passed as if BITS_BIG_ENDIAN == 0, so we need to convert it to 573150397Sobrien BITS_BIG_ENDIAN style. If position is constant, compute new 573250397Sobrien position. Otherwise, build subtraction. 573350397Sobrien Note that POS is relative to the mode of the original argument. 573450397Sobrien If it's a MEM we need to recompute POS relative to that. 573550397Sobrien However, if we're extracting from (or inserting into) a register, 573650397Sobrien we want to recompute POS relative to wanted_inner_mode. */ 573750397Sobrien int width = (GET_CODE (inner) == MEM 573850397Sobrien ? GET_MODE_BITSIZE (is_mode) 573950397Sobrien : GET_MODE_BITSIZE (wanted_inner_mode)); 574050397Sobrien 574118334Speter if (pos_rtx == 0) 574250397Sobrien pos = width - len - pos; 574318334Speter else 574418334Speter pos_rtx 574518334Speter = gen_rtx_combine (MINUS, GET_MODE (pos_rtx), 574650397Sobrien GEN_INT (width - len), pos_rtx); 574750397Sobrien /* POS may be less than 0 now, but we check for that below. 574850397Sobrien Note that it can only be less than 0 if GET_CODE (inner) != MEM. */ 574918334Speter } 575018334Speter 575118334Speter /* If INNER has a wider mode, make it smaller. If this is a constant 575218334Speter extract, try to adjust the byte to point to the byte containing 575318334Speter the value. */ 575450397Sobrien if (wanted_inner_mode != VOIDmode 575550397Sobrien && GET_MODE_SIZE (wanted_inner_mode) < GET_MODE_SIZE (is_mode) 575618334Speter && ((GET_CODE (inner) == MEM 575750397Sobrien && (inner_mode == wanted_inner_mode 575818334Speter || (! mode_dependent_address_p (XEXP (inner, 0)) 575918334Speter && ! MEM_VOLATILE_P (inner)))))) 576018334Speter { 576118334Speter int offset = 0; 576218334Speter 576318334Speter /* The computations below will be correct if the machine is big 576418334Speter endian in both bits and bytes or little endian in bits and bytes. 576518334Speter If it is mixed, we must adjust. */ 576618334Speter 576718334Speter /* If bytes are big endian and we had a paradoxical SUBREG, we must 576850397Sobrien adjust OFFSET to compensate. */ 576918334Speter if (BYTES_BIG_ENDIAN 577018334Speter && ! spans_byte 577118334Speter && GET_MODE_SIZE (inner_mode) < GET_MODE_SIZE (is_mode)) 577218334Speter offset -= GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (inner_mode); 577318334Speter 577418334Speter /* If this is a constant position, we can move to the desired byte. */ 577518334Speter if (pos_rtx == 0) 577618334Speter { 577718334Speter offset += pos / BITS_PER_UNIT; 577850397Sobrien pos %= GET_MODE_BITSIZE (wanted_inner_mode); 577918334Speter } 578018334Speter 578118334Speter if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN 578218334Speter && ! spans_byte 578350397Sobrien && is_mode != wanted_inner_mode) 578418334Speter offset = (GET_MODE_SIZE (is_mode) 578550397Sobrien - GET_MODE_SIZE (wanted_inner_mode) - offset); 578618334Speter 578750397Sobrien if (offset != 0 || inner_mode != wanted_inner_mode) 578818334Speter { 578950397Sobrien rtx newmem = gen_rtx_MEM (wanted_inner_mode, 579050397Sobrien plus_constant (XEXP (inner, 0), offset)); 579118334Speter RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (inner); 579252284Sobrien MEM_COPY_ATTRIBUTES (newmem, inner); 579318334Speter inner = newmem; 579418334Speter } 579518334Speter } 579618334Speter 579750397Sobrien /* If INNER is not memory, we can always get it into the proper mode. If we 579850397Sobrien are changing its mode, POS must be a constant and smaller than the size 579950397Sobrien of the new mode. */ 580018334Speter else if (GET_CODE (inner) != MEM) 580150397Sobrien { 580250397Sobrien if (GET_MODE (inner) != wanted_inner_mode 580350397Sobrien && (pos_rtx != 0 580450397Sobrien || orig_pos + len > GET_MODE_BITSIZE (wanted_inner_mode))) 580550397Sobrien return 0; 580618334Speter 580750397Sobrien inner = force_to_mode (inner, wanted_inner_mode, 580850397Sobrien pos_rtx 580950397Sobrien || len + orig_pos >= HOST_BITS_PER_WIDE_INT 581050397Sobrien ? GET_MODE_MASK (wanted_inner_mode) 581150397Sobrien : (((HOST_WIDE_INT) 1 << len) - 1) << orig_pos, 581250397Sobrien NULL_RTX, 0); 581350397Sobrien } 581450397Sobrien 581518334Speter /* Adjust mode of POS_RTX, if needed. If we want a wider mode, we 581618334Speter have to zero extend. Otherwise, we can just use a SUBREG. */ 581718334Speter if (pos_rtx != 0 581818334Speter && GET_MODE_SIZE (pos_mode) > GET_MODE_SIZE (GET_MODE (pos_rtx))) 581918334Speter pos_rtx = gen_rtx_combine (ZERO_EXTEND, pos_mode, pos_rtx); 582018334Speter else if (pos_rtx != 0 582118334Speter && GET_MODE_SIZE (pos_mode) < GET_MODE_SIZE (GET_MODE (pos_rtx))) 582218334Speter pos_rtx = gen_lowpart_for_combine (pos_mode, pos_rtx); 582318334Speter 582418334Speter /* Make POS_RTX unless we already have it and it is correct. If we don't 582518334Speter have a POS_RTX but we do have an ORIG_POS_RTX, the latter must 582650397Sobrien be a CONST_INT. */ 582718334Speter if (pos_rtx == 0 && orig_pos_rtx != 0 && INTVAL (orig_pos_rtx) == pos) 582818334Speter pos_rtx = orig_pos_rtx; 582918334Speter 583018334Speter else if (pos_rtx == 0) 583118334Speter pos_rtx = GEN_INT (pos); 583218334Speter 583318334Speter /* Make the required operation. See if we can use existing rtx. */ 583418334Speter new = gen_rtx_combine (unsignedp ? ZERO_EXTRACT : SIGN_EXTRACT, 583518334Speter extraction_mode, inner, GEN_INT (len), pos_rtx); 583618334Speter if (! in_dest) 583718334Speter new = gen_lowpart_for_combine (mode, new); 583818334Speter 583918334Speter return new; 584018334Speter} 584118334Speter 584218334Speter/* See if X contains an ASHIFT of COUNT or more bits that can be commuted 584318334Speter with any other operations in X. Return X without that shift if so. */ 584418334Speter 584518334Speterstatic rtx 584618334Speterextract_left_shift (x, count) 584718334Speter rtx x; 584818334Speter int count; 584918334Speter{ 585018334Speter enum rtx_code code = GET_CODE (x); 585118334Speter enum machine_mode mode = GET_MODE (x); 585218334Speter rtx tem; 585318334Speter 585418334Speter switch (code) 585518334Speter { 585618334Speter case ASHIFT: 585718334Speter /* This is the shift itself. If it is wide enough, we will return 585818334Speter either the value being shifted if the shift count is equal to 585918334Speter COUNT or a shift for the difference. */ 586018334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 586118334Speter && INTVAL (XEXP (x, 1)) >= count) 586218334Speter return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (x, 0), 586318334Speter INTVAL (XEXP (x, 1)) - count); 586418334Speter break; 586518334Speter 586618334Speter case NEG: case NOT: 586718334Speter if ((tem = extract_left_shift (XEXP (x, 0), count)) != 0) 586818334Speter return gen_unary (code, mode, mode, tem); 586918334Speter 587018334Speter break; 587118334Speter 587218334Speter case PLUS: case IOR: case XOR: case AND: 587318334Speter /* If we can safely shift this constant and we find the inner shift, 587418334Speter make a new operation. */ 587518334Speter if (GET_CODE (XEXP (x,1)) == CONST_INT 587650397Sobrien && (INTVAL (XEXP (x, 1)) & ((((HOST_WIDE_INT) 1 << count)) - 1)) == 0 587718334Speter && (tem = extract_left_shift (XEXP (x, 0), count)) != 0) 587818334Speter return gen_binary (code, mode, tem, 587918334Speter GEN_INT (INTVAL (XEXP (x, 1)) >> count)); 588018334Speter 588118334Speter break; 588250397Sobrien 588350397Sobrien default: 588450397Sobrien break; 588518334Speter } 588618334Speter 588718334Speter return 0; 588818334Speter} 588918334Speter 589018334Speter/* Look at the expression rooted at X. Look for expressions 589118334Speter equivalent to ZERO_EXTRACT, SIGN_EXTRACT, ZERO_EXTEND, SIGN_EXTEND. 589218334Speter Form these expressions. 589318334Speter 589418334Speter Return the new rtx, usually just X. 589518334Speter 589618334Speter Also, for machines like the Vax that don't have logical shift insns, 589718334Speter try to convert logical to arithmetic shift operations in cases where 589818334Speter they are equivalent. This undoes the canonicalizations to logical 589918334Speter shifts done elsewhere. 590018334Speter 590118334Speter We try, as much as possible, to re-use rtl expressions to save memory. 590218334Speter 590318334Speter IN_CODE says what kind of expression we are processing. Normally, it is 590418334Speter SET. In a memory address (inside a MEM, PLUS or minus, the latter two 590518334Speter being kludges), it is MEM. When processing the arguments of a comparison 590618334Speter or a COMPARE against zero, it is COMPARE. */ 590718334Speter 590818334Speterstatic rtx 590918334Spetermake_compound_operation (x, in_code) 591018334Speter rtx x; 591118334Speter enum rtx_code in_code; 591218334Speter{ 591318334Speter enum rtx_code code = GET_CODE (x); 591418334Speter enum machine_mode mode = GET_MODE (x); 591518334Speter int mode_width = GET_MODE_BITSIZE (mode); 591618334Speter rtx rhs, lhs; 591718334Speter enum rtx_code next_code; 591818334Speter int i; 591918334Speter rtx new = 0; 592018334Speter rtx tem; 592118334Speter char *fmt; 592218334Speter 592318334Speter /* Select the code to be used in recursive calls. Once we are inside an 592418334Speter address, we stay there. If we have a comparison, set to COMPARE, 592518334Speter but once inside, go back to our default of SET. */ 592618334Speter 592718334Speter next_code = (code == MEM || code == PLUS || code == MINUS ? MEM 592818334Speter : ((code == COMPARE || GET_RTX_CLASS (code) == '<') 592918334Speter && XEXP (x, 1) == const0_rtx) ? COMPARE 593018334Speter : in_code == COMPARE ? SET : in_code); 593118334Speter 593218334Speter /* Process depending on the code of this operation. If NEW is set 593318334Speter non-zero, it will be returned. */ 593418334Speter 593518334Speter switch (code) 593618334Speter { 593718334Speter case ASHIFT: 593818334Speter /* Convert shifts by constants into multiplications if inside 593918334Speter an address. */ 594018334Speter if (in_code == MEM && GET_CODE (XEXP (x, 1)) == CONST_INT 594118334Speter && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT 594218334Speter && INTVAL (XEXP (x, 1)) >= 0) 594318334Speter { 594418334Speter new = make_compound_operation (XEXP (x, 0), next_code); 594518334Speter new = gen_rtx_combine (MULT, mode, new, 594618334Speter GEN_INT ((HOST_WIDE_INT) 1 594718334Speter << INTVAL (XEXP (x, 1)))); 594818334Speter } 594918334Speter break; 595018334Speter 595118334Speter case AND: 595218334Speter /* If the second operand is not a constant, we can't do anything 595318334Speter with it. */ 595418334Speter if (GET_CODE (XEXP (x, 1)) != CONST_INT) 595518334Speter break; 595618334Speter 595718334Speter /* If the constant is a power of two minus one and the first operand 595818334Speter is a logical right shift, make an extraction. */ 595918334Speter if (GET_CODE (XEXP (x, 0)) == LSHIFTRT 596018334Speter && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0) 596118334Speter { 596218334Speter new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code); 596318334Speter new = make_extraction (mode, new, 0, XEXP (XEXP (x, 0), 1), i, 1, 596418334Speter 0, in_code == COMPARE); 596518334Speter } 596618334Speter 596718334Speter /* Same as previous, but for (subreg (lshiftrt ...)) in first op. */ 596818334Speter else if (GET_CODE (XEXP (x, 0)) == SUBREG 596918334Speter && subreg_lowpart_p (XEXP (x, 0)) 597018334Speter && GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT 597118334Speter && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0) 597218334Speter { 597318334Speter new = make_compound_operation (XEXP (SUBREG_REG (XEXP (x, 0)), 0), 597418334Speter next_code); 597518334Speter new = make_extraction (GET_MODE (SUBREG_REG (XEXP (x, 0))), new, 0, 597618334Speter XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1, 597718334Speter 0, in_code == COMPARE); 597818334Speter } 597918334Speter /* Same as previous, but for (xor/ior (lshiftrt...) (lshiftrt...)). */ 598018334Speter else if ((GET_CODE (XEXP (x, 0)) == XOR 598118334Speter || GET_CODE (XEXP (x, 0)) == IOR) 598218334Speter && GET_CODE (XEXP (XEXP (x, 0), 0)) == LSHIFTRT 598318334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == LSHIFTRT 598418334Speter && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0) 598518334Speter { 598618334Speter /* Apply the distributive law, and then try to make extractions. */ 598718334Speter new = gen_rtx_combine (GET_CODE (XEXP (x, 0)), mode, 598850397Sobrien gen_rtx_AND (mode, XEXP (XEXP (x, 0), 0), 598950397Sobrien XEXP (x, 1)), 599050397Sobrien gen_rtx_AND (mode, XEXP (XEXP (x, 0), 1), 599150397Sobrien XEXP (x, 1))); 599218334Speter new = make_compound_operation (new, in_code); 599318334Speter } 599418334Speter 599518334Speter /* If we are have (and (rotate X C) M) and C is larger than the number 599618334Speter of bits in M, this is an extraction. */ 599718334Speter 599818334Speter else if (GET_CODE (XEXP (x, 0)) == ROTATE 599918334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 600018334Speter && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0 600118334Speter && i <= INTVAL (XEXP (XEXP (x, 0), 1))) 600218334Speter { 600318334Speter new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code); 600418334Speter new = make_extraction (mode, new, 600518334Speter (GET_MODE_BITSIZE (mode) 600618334Speter - INTVAL (XEXP (XEXP (x, 0), 1))), 600718334Speter NULL_RTX, i, 1, 0, in_code == COMPARE); 600818334Speter } 600918334Speter 601018334Speter /* On machines without logical shifts, if the operand of the AND is 601118334Speter a logical shift and our mask turns off all the propagated sign 601218334Speter bits, we can replace the logical shift with an arithmetic shift. */ 601318334Speter else if (ashr_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing 601418334Speter && (lshr_optab->handlers[(int) mode].insn_code 601518334Speter == CODE_FOR_nothing) 601618334Speter && GET_CODE (XEXP (x, 0)) == LSHIFTRT 601718334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 601818334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0 601918334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT 602018334Speter && mode_width <= HOST_BITS_PER_WIDE_INT) 602118334Speter { 602218334Speter unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode); 602318334Speter 602418334Speter mask >>= INTVAL (XEXP (XEXP (x, 0), 1)); 602518334Speter if ((INTVAL (XEXP (x, 1)) & ~mask) == 0) 602618334Speter SUBST (XEXP (x, 0), 602718334Speter gen_rtx_combine (ASHIFTRT, mode, 602818334Speter make_compound_operation (XEXP (XEXP (x, 0), 0), 602918334Speter next_code), 603018334Speter XEXP (XEXP (x, 0), 1))); 603118334Speter } 603218334Speter 603318334Speter /* If the constant is one less than a power of two, this might be 603418334Speter representable by an extraction even if no shift is present. 603518334Speter If it doesn't end up being a ZERO_EXTEND, we will ignore it unless 603618334Speter we are in a COMPARE. */ 603718334Speter else if ((i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0) 603818334Speter new = make_extraction (mode, 603918334Speter make_compound_operation (XEXP (x, 0), 604018334Speter next_code), 604118334Speter 0, NULL_RTX, i, 1, 0, in_code == COMPARE); 604218334Speter 604318334Speter /* If we are in a comparison and this is an AND with a power of two, 604418334Speter convert this into the appropriate bit extract. */ 604518334Speter else if (in_code == COMPARE 604618334Speter && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0) 604718334Speter new = make_extraction (mode, 604818334Speter make_compound_operation (XEXP (x, 0), 604918334Speter next_code), 605018334Speter i, NULL_RTX, 1, 1, 0, 1); 605118334Speter 605218334Speter break; 605318334Speter 605418334Speter case LSHIFTRT: 605518334Speter /* If the sign bit is known to be zero, replace this with an 605618334Speter arithmetic shift. */ 605718334Speter if (ashr_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing 605818334Speter && lshr_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing 605918334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 606018334Speter && (nonzero_bits (XEXP (x, 0), mode) & (1 << (mode_width - 1))) == 0) 606118334Speter { 606218334Speter new = gen_rtx_combine (ASHIFTRT, mode, 606318334Speter make_compound_operation (XEXP (x, 0), 606418334Speter next_code), 606518334Speter XEXP (x, 1)); 606618334Speter break; 606718334Speter } 606818334Speter 606950397Sobrien /* ... fall through ... */ 607018334Speter 607118334Speter case ASHIFTRT: 607218334Speter lhs = XEXP (x, 0); 607318334Speter rhs = XEXP (x, 1); 607418334Speter 607518334Speter /* If we have (ashiftrt (ashift foo C1) C2) with C2 >= C1, 607618334Speter this is a SIGN_EXTRACT. */ 607718334Speter if (GET_CODE (rhs) == CONST_INT 607818334Speter && GET_CODE (lhs) == ASHIFT 607918334Speter && GET_CODE (XEXP (lhs, 1)) == CONST_INT 608018334Speter && INTVAL (rhs) >= INTVAL (XEXP (lhs, 1))) 608118334Speter { 608218334Speter new = make_compound_operation (XEXP (lhs, 0), next_code); 608318334Speter new = make_extraction (mode, new, 608418334Speter INTVAL (rhs) - INTVAL (XEXP (lhs, 1)), 608518334Speter NULL_RTX, mode_width - INTVAL (rhs), 608618334Speter code == LSHIFTRT, 0, in_code == COMPARE); 608718334Speter } 608818334Speter 608918334Speter /* See if we have operations between an ASHIFTRT and an ASHIFT. 609018334Speter If so, try to merge the shifts into a SIGN_EXTEND. We could 609118334Speter also do this for some cases of SIGN_EXTRACT, but it doesn't 609218334Speter seem worth the effort; the case checked for occurs on Alpha. */ 609318334Speter 609418334Speter if (GET_RTX_CLASS (GET_CODE (lhs)) != 'o' 609518334Speter && ! (GET_CODE (lhs) == SUBREG 609618334Speter && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (lhs))) == 'o')) 609718334Speter && GET_CODE (rhs) == CONST_INT 609818334Speter && INTVAL (rhs) < HOST_BITS_PER_WIDE_INT 609918334Speter && (new = extract_left_shift (lhs, INTVAL (rhs))) != 0) 610018334Speter new = make_extraction (mode, make_compound_operation (new, next_code), 610118334Speter 0, NULL_RTX, mode_width - INTVAL (rhs), 610218334Speter code == LSHIFTRT, 0, in_code == COMPARE); 610318334Speter 610418334Speter break; 610518334Speter 610618334Speter case SUBREG: 610718334Speter /* Call ourselves recursively on the inner expression. If we are 610818334Speter narrowing the object and it has a different RTL code from 610918334Speter what it originally did, do this SUBREG as a force_to_mode. */ 611018334Speter 611118334Speter tem = make_compound_operation (SUBREG_REG (x), in_code); 611218334Speter if (GET_CODE (tem) != GET_CODE (SUBREG_REG (x)) 611318334Speter && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (tem)) 611418334Speter && subreg_lowpart_p (x)) 611518334Speter { 611618334Speter rtx newer = force_to_mode (tem, mode, 611718334Speter GET_MODE_MASK (mode), NULL_RTX, 0); 611818334Speter 611918334Speter /* If we have something other than a SUBREG, we might have 612018334Speter done an expansion, so rerun outselves. */ 612118334Speter if (GET_CODE (newer) != SUBREG) 612218334Speter newer = make_compound_operation (newer, in_code); 612318334Speter 612418334Speter return newer; 612518334Speter } 612650397Sobrien 612750397Sobrien /* If this is a paradoxical subreg, and the new code is a sign or 612850397Sobrien zero extension, omit the subreg and widen the extension. If it 612950397Sobrien is a regular subreg, we can still get rid of the subreg by not 613050397Sobrien widening so much, or in fact removing the extension entirely. */ 613150397Sobrien if ((GET_CODE (tem) == SIGN_EXTEND 613250397Sobrien || GET_CODE (tem) == ZERO_EXTEND) 613350397Sobrien && subreg_lowpart_p (x)) 613450397Sobrien { 613550397Sobrien if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (tem)) 613650397Sobrien || (GET_MODE_SIZE (mode) > 613750397Sobrien GET_MODE_SIZE (GET_MODE (XEXP (tem, 0))))) 613850397Sobrien tem = gen_rtx_combine (GET_CODE (tem), mode, XEXP (tem, 0)); 613950397Sobrien else 614050397Sobrien tem = gen_lowpart_for_combine (mode, XEXP (tem, 0)); 614150397Sobrien return tem; 614250397Sobrien } 614350397Sobrien break; 614450397Sobrien 614550397Sobrien default: 614650397Sobrien break; 614718334Speter } 614818334Speter 614918334Speter if (new) 615018334Speter { 615118334Speter x = gen_lowpart_for_combine (mode, new); 615218334Speter code = GET_CODE (x); 615318334Speter } 615418334Speter 615518334Speter /* Now recursively process each operand of this operation. */ 615618334Speter fmt = GET_RTX_FORMAT (code); 615718334Speter for (i = 0; i < GET_RTX_LENGTH (code); i++) 615818334Speter if (fmt[i] == 'e') 615918334Speter { 616018334Speter new = make_compound_operation (XEXP (x, i), next_code); 616118334Speter SUBST (XEXP (x, i), new); 616218334Speter } 616318334Speter 616418334Speter return x; 616518334Speter} 616618334Speter 616718334Speter/* Given M see if it is a value that would select a field of bits 616818334Speter within an item, but not the entire word. Return -1 if not. 616918334Speter Otherwise, return the starting position of the field, where 0 is the 617018334Speter low-order bit. 617118334Speter 617218334Speter *PLEN is set to the length of the field. */ 617318334Speter 617418334Speterstatic int 617518334Speterget_pos_from_mask (m, plen) 617618334Speter unsigned HOST_WIDE_INT m; 617718334Speter int *plen; 617818334Speter{ 617918334Speter /* Get the bit number of the first 1 bit from the right, -1 if none. */ 618018334Speter int pos = exact_log2 (m & - m); 618118334Speter 618218334Speter if (pos < 0) 618318334Speter return -1; 618418334Speter 618518334Speter /* Now shift off the low-order zero bits and see if we have a power of 618618334Speter two minus 1. */ 618718334Speter *plen = exact_log2 ((m >> pos) + 1); 618818334Speter 618918334Speter if (*plen <= 0) 619018334Speter return -1; 619118334Speter 619218334Speter return pos; 619318334Speter} 619418334Speter 619518334Speter/* See if X can be simplified knowing that we will only refer to it in 619618334Speter MODE and will only refer to those bits that are nonzero in MASK. 619718334Speter If other bits are being computed or if masking operations are done 619818334Speter that select a superset of the bits in MASK, they can sometimes be 619918334Speter ignored. 620018334Speter 620118334Speter Return a possibly simplified expression, but always convert X to 620218334Speter MODE. If X is a CONST_INT, AND the CONST_INT with MASK. 620318334Speter 620418334Speter Also, if REG is non-zero and X is a register equal in value to REG, 620518334Speter replace X with REG. 620618334Speter 620718334Speter If JUST_SELECT is nonzero, don't optimize by noticing that bits in MASK 620818334Speter are all off in X. This is used when X will be complemented, by either 620918334Speter NOT, NEG, or XOR. */ 621018334Speter 621118334Speterstatic rtx 621218334Speterforce_to_mode (x, mode, mask, reg, just_select) 621318334Speter rtx x; 621418334Speter enum machine_mode mode; 621518334Speter unsigned HOST_WIDE_INT mask; 621618334Speter rtx reg; 621718334Speter int just_select; 621818334Speter{ 621918334Speter enum rtx_code code = GET_CODE (x); 622018334Speter int next_select = just_select || code == XOR || code == NOT || code == NEG; 622118334Speter enum machine_mode op_mode; 622218334Speter unsigned HOST_WIDE_INT fuller_mask, nonzero; 622318334Speter rtx op0, op1, temp; 622418334Speter 622550397Sobrien /* If this is a CALL or ASM_OPERANDS, don't do anything. Some of the 622650397Sobrien code below will do the wrong thing since the mode of such an 622750397Sobrien expression is VOIDmode. 622850397Sobrien 622950397Sobrien Also do nothing if X is a CLOBBER; this can happen if X was 623050397Sobrien the return value from a call to gen_lowpart_for_combine. */ 623150397Sobrien if (code == CALL || code == ASM_OPERANDS || code == CLOBBER) 623218334Speter return x; 623318334Speter 623418334Speter /* We want to perform the operation is its present mode unless we know 623518334Speter that the operation is valid in MODE, in which case we do the operation 623618334Speter in MODE. */ 623718334Speter op_mode = ((GET_MODE_CLASS (mode) == GET_MODE_CLASS (GET_MODE (x)) 623818334Speter && code_to_optab[(int) code] != 0 623918334Speter && (code_to_optab[(int) code]->handlers[(int) mode].insn_code 624018334Speter != CODE_FOR_nothing)) 624118334Speter ? mode : GET_MODE (x)); 624218334Speter 624318334Speter /* It is not valid to do a right-shift in a narrower mode 624418334Speter than the one it came in with. */ 624518334Speter if ((code == LSHIFTRT || code == ASHIFTRT) 624618334Speter && GET_MODE_BITSIZE (mode) < GET_MODE_BITSIZE (GET_MODE (x))) 624718334Speter op_mode = GET_MODE (x); 624818334Speter 624918334Speter /* Truncate MASK to fit OP_MODE. */ 625018334Speter if (op_mode) 625118334Speter mask &= GET_MODE_MASK (op_mode); 625218334Speter 625318334Speter /* When we have an arithmetic operation, or a shift whose count we 625418334Speter do not know, we need to assume that all bit the up to the highest-order 625518334Speter bit in MASK will be needed. This is how we form such a mask. */ 625618334Speter if (op_mode) 625718334Speter fuller_mask = (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT 625818334Speter ? GET_MODE_MASK (op_mode) 625918334Speter : ((HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1)) - 1); 626018334Speter else 626118334Speter fuller_mask = ~ (HOST_WIDE_INT) 0; 626218334Speter 626318334Speter /* Determine what bits of X are guaranteed to be (non)zero. */ 626418334Speter nonzero = nonzero_bits (x, mode); 626518334Speter 626618334Speter /* If none of the bits in X are needed, return a zero. */ 626718334Speter if (! just_select && (nonzero & mask) == 0) 626818334Speter return const0_rtx; 626918334Speter 627018334Speter /* If X is a CONST_INT, return a new one. Do this here since the 627118334Speter test below will fail. */ 627218334Speter if (GET_CODE (x) == CONST_INT) 627318334Speter { 627418334Speter HOST_WIDE_INT cval = INTVAL (x) & mask; 627518334Speter int width = GET_MODE_BITSIZE (mode); 627618334Speter 627718334Speter /* If MODE is narrower that HOST_WIDE_INT and CVAL is a negative 627818334Speter number, sign extend it. */ 627918334Speter if (width > 0 && width < HOST_BITS_PER_WIDE_INT 628018334Speter && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0) 628118334Speter cval |= (HOST_WIDE_INT) -1 << width; 628218334Speter 628318334Speter return GEN_INT (cval); 628418334Speter } 628518334Speter 628618334Speter /* If X is narrower than MODE and we want all the bits in X's mode, just 628718334Speter get X in the proper mode. */ 628818334Speter if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode) 628918334Speter && (GET_MODE_MASK (GET_MODE (x)) & ~ mask) == 0) 629018334Speter return gen_lowpart_for_combine (mode, x); 629118334Speter 629218334Speter /* If we aren't changing the mode, X is not a SUBREG, and all zero bits in 629318334Speter MASK are already known to be zero in X, we need not do anything. */ 629418334Speter if (GET_MODE (x) == mode && code != SUBREG && (~ mask & nonzero) == 0) 629518334Speter return x; 629618334Speter 629718334Speter switch (code) 629818334Speter { 629918334Speter case CLOBBER: 630018334Speter /* If X is a (clobber (const_int)), return it since we know we are 630150397Sobrien generating something that won't match. */ 630218334Speter return x; 630318334Speter 630418334Speter case USE: 630518334Speter /* X is a (use (mem ..)) that was made from a bit-field extraction that 630618334Speter spanned the boundary of the MEM. If we are now masking so it is 630718334Speter within that boundary, we don't need the USE any more. */ 630818334Speter if (! BITS_BIG_ENDIAN 630918334Speter && (mask & ~ GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0) 631018334Speter return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select); 631118334Speter break; 631218334Speter 631318334Speter case SIGN_EXTEND: 631418334Speter case ZERO_EXTEND: 631518334Speter case ZERO_EXTRACT: 631618334Speter case SIGN_EXTRACT: 631718334Speter x = expand_compound_operation (x); 631818334Speter if (GET_CODE (x) != code) 631918334Speter return force_to_mode (x, mode, mask, reg, next_select); 632018334Speter break; 632118334Speter 632218334Speter case REG: 632318334Speter if (reg != 0 && (rtx_equal_p (get_last_value (reg), x) 632418334Speter || rtx_equal_p (reg, get_last_value (x)))) 632518334Speter x = reg; 632618334Speter break; 632718334Speter 632818334Speter case SUBREG: 632918334Speter if (subreg_lowpart_p (x) 633018334Speter /* We can ignore the effect of this SUBREG if it narrows the mode or 633118334Speter if the constant masks to zero all the bits the mode doesn't 633218334Speter have. */ 633318334Speter && ((GET_MODE_SIZE (GET_MODE (x)) 633418334Speter < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) 633518334Speter || (0 == (mask 633618334Speter & GET_MODE_MASK (GET_MODE (x)) 633718334Speter & ~ GET_MODE_MASK (GET_MODE (SUBREG_REG (x))))))) 633818334Speter return force_to_mode (SUBREG_REG (x), mode, mask, reg, next_select); 633918334Speter break; 634018334Speter 634118334Speter case AND: 634218334Speter /* If this is an AND with a constant, convert it into an AND 634318334Speter whose constant is the AND of that constant with MASK. If it 634418334Speter remains an AND of MASK, delete it since it is redundant. */ 634518334Speter 634618334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT) 634718334Speter { 634818334Speter x = simplify_and_const_int (x, op_mode, XEXP (x, 0), 634918334Speter mask & INTVAL (XEXP (x, 1))); 635018334Speter 635118334Speter /* If X is still an AND, see if it is an AND with a mask that 635218334Speter is just some low-order bits. If so, and it is MASK, we don't 635318334Speter need it. */ 635418334Speter 635518334Speter if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT 635652284Sobrien && (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) == mask) 635718334Speter x = XEXP (x, 0); 635818334Speter 635918334Speter /* If it remains an AND, try making another AND with the bits 636018334Speter in the mode mask that aren't in MASK turned on. If the 636118334Speter constant in the AND is wide enough, this might make a 636218334Speter cheaper constant. */ 636318334Speter 636418334Speter if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT 636518334Speter && GET_MODE_MASK (GET_MODE (x)) != mask 636618334Speter && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT) 636718334Speter { 636818334Speter HOST_WIDE_INT cval = (INTVAL (XEXP (x, 1)) 636918334Speter | (GET_MODE_MASK (GET_MODE (x)) & ~ mask)); 637018334Speter int width = GET_MODE_BITSIZE (GET_MODE (x)); 637118334Speter rtx y; 637218334Speter 637318334Speter /* If MODE is narrower that HOST_WIDE_INT and CVAL is a negative 637418334Speter number, sign extend it. */ 637518334Speter if (width > 0 && width < HOST_BITS_PER_WIDE_INT 637618334Speter && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0) 637718334Speter cval |= (HOST_WIDE_INT) -1 << width; 637818334Speter 637918334Speter y = gen_binary (AND, GET_MODE (x), XEXP (x, 0), GEN_INT (cval)); 638018334Speter if (rtx_cost (y, SET) < rtx_cost (x, SET)) 638118334Speter x = y; 638218334Speter } 638318334Speter 638418334Speter break; 638518334Speter } 638618334Speter 638718334Speter goto binop; 638818334Speter 638918334Speter case PLUS: 639018334Speter /* In (and (plus FOO C1) M), if M is a mask that just turns off 639118334Speter low-order bits (as in an alignment operation) and FOO is already 639218334Speter aligned to that boundary, mask C1 to that boundary as well. 639318334Speter This may eliminate that PLUS and, later, the AND. */ 639418334Speter 639518334Speter { 639618334Speter int width = GET_MODE_BITSIZE (mode); 639718334Speter unsigned HOST_WIDE_INT smask = mask; 639818334Speter 639918334Speter /* If MODE is narrower than HOST_WIDE_INT and mask is a negative 640018334Speter number, sign extend it. */ 640118334Speter 640218334Speter if (width < HOST_BITS_PER_WIDE_INT 640318334Speter && (smask & ((HOST_WIDE_INT) 1 << (width - 1))) != 0) 640418334Speter smask |= (HOST_WIDE_INT) -1 << width; 640518334Speter 640618334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 640750397Sobrien && exact_log2 (- smask) >= 0) 640850397Sobrien { 640950397Sobrien#ifdef STACK_BIAS 641050397Sobrien if (STACK_BIAS 641150397Sobrien && (XEXP (x, 0) == stack_pointer_rtx 641250397Sobrien || XEXP (x, 0) == frame_pointer_rtx)) 641350397Sobrien { 641450397Sobrien int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT; 641550397Sobrien unsigned HOST_WIDE_INT sp_mask = GET_MODE_MASK (mode); 641650397Sobrien 641750397Sobrien sp_mask &= ~ (sp_alignment - 1); 641852284Sobrien if ((sp_mask & ~ smask) == 0 641952284Sobrien && ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~ smask) != 0) 642050397Sobrien return force_to_mode (plus_constant (XEXP (x, 0), 642150397Sobrien ((INTVAL (XEXP (x, 1)) - 642252284Sobrien STACK_BIAS) & smask) 642350397Sobrien + STACK_BIAS), 642452284Sobrien mode, smask, reg, next_select); 642550397Sobrien } 642650397Sobrien#endif 642752284Sobrien if ((nonzero_bits (XEXP (x, 0), mode) & ~ smask) == 0 642852284Sobrien && (INTVAL (XEXP (x, 1)) & ~ smask) != 0) 642950397Sobrien return force_to_mode (plus_constant (XEXP (x, 0), 643052284Sobrien (INTVAL (XEXP (x, 1)) 643152284Sobrien & smask)), 643252284Sobrien mode, smask, reg, next_select); 643350397Sobrien } 643418334Speter } 643518334Speter 643650397Sobrien /* ... fall through ... */ 643718334Speter 643818334Speter case MINUS: 643918334Speter case MULT: 644018334Speter /* For PLUS, MINUS and MULT, we need any bits less significant than the 644118334Speter most significant bit in MASK since carries from those bits will 644218334Speter affect the bits we are interested in. */ 644318334Speter mask = fuller_mask; 644418334Speter goto binop; 644518334Speter 644618334Speter case IOR: 644718334Speter case XOR: 644818334Speter /* If X is (ior (lshiftrt FOO C1) C2), try to commute the IOR and 644918334Speter LSHIFTRT so we end up with an (and (lshiftrt (ior ...) ...) ...) 645018334Speter operation which may be a bitfield extraction. Ensure that the 645118334Speter constant we form is not wider than the mode of X. */ 645218334Speter 645318334Speter if (GET_CODE (XEXP (x, 0)) == LSHIFTRT 645418334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 645518334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0 645618334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT 645718334Speter && GET_CODE (XEXP (x, 1)) == CONST_INT 645818334Speter && ((INTVAL (XEXP (XEXP (x, 0), 1)) 645918334Speter + floor_log2 (INTVAL (XEXP (x, 1)))) 646018334Speter < GET_MODE_BITSIZE (GET_MODE (x))) 646118334Speter && (INTVAL (XEXP (x, 1)) 646250397Sobrien & ~ nonzero_bits (XEXP (x, 0), GET_MODE (x))) == 0) 646318334Speter { 646418334Speter temp = GEN_INT ((INTVAL (XEXP (x, 1)) & mask) 646518334Speter << INTVAL (XEXP (XEXP (x, 0), 1))); 646618334Speter temp = gen_binary (GET_CODE (x), GET_MODE (x), 646718334Speter XEXP (XEXP (x, 0), 0), temp); 646850397Sobrien x = gen_binary (LSHIFTRT, GET_MODE (x), temp, 646950397Sobrien XEXP (XEXP (x, 0), 1)); 647018334Speter return force_to_mode (x, mode, mask, reg, next_select); 647118334Speter } 647218334Speter 647318334Speter binop: 647418334Speter /* For most binary operations, just propagate into the operation and 647518334Speter change the mode if we have an operation of that mode. */ 647618334Speter 647718334Speter op0 = gen_lowpart_for_combine (op_mode, 647818334Speter force_to_mode (XEXP (x, 0), mode, mask, 647918334Speter reg, next_select)); 648018334Speter op1 = gen_lowpart_for_combine (op_mode, 648118334Speter force_to_mode (XEXP (x, 1), mode, mask, 648218334Speter reg, next_select)); 648318334Speter 648418334Speter /* If OP1 is a CONST_INT and X is an IOR or XOR, clear bits outside 648518334Speter MASK since OP1 might have been sign-extended but we never want 648618334Speter to turn on extra bits, since combine might have previously relied 648718334Speter on them being off. */ 648818334Speter if (GET_CODE (op1) == CONST_INT && (code == IOR || code == XOR) 648918334Speter && (INTVAL (op1) & mask) != 0) 649018334Speter op1 = GEN_INT (INTVAL (op1) & mask); 649118334Speter 649218334Speter if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1)) 649318334Speter x = gen_binary (code, op_mode, op0, op1); 649418334Speter break; 649518334Speter 649618334Speter case ASHIFT: 649718334Speter /* For left shifts, do the same, but just for the first operand. 649818334Speter However, we cannot do anything with shifts where we cannot 649918334Speter guarantee that the counts are smaller than the size of the mode 650018334Speter because such a count will have a different meaning in a 650118334Speter wider mode. */ 650218334Speter 650318334Speter if (! (GET_CODE (XEXP (x, 1)) == CONST_INT 650418334Speter && INTVAL (XEXP (x, 1)) >= 0 650518334Speter && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (mode)) 650618334Speter && ! (GET_MODE (XEXP (x, 1)) != VOIDmode 650718334Speter && (nonzero_bits (XEXP (x, 1), GET_MODE (XEXP (x, 1))) 650818334Speter < (unsigned HOST_WIDE_INT) GET_MODE_BITSIZE (mode)))) 650918334Speter break; 651018334Speter 651118334Speter /* If the shift count is a constant and we can do arithmetic in 651218334Speter the mode of the shift, refine which bits we need. Otherwise, use the 651318334Speter conservative form of the mask. */ 651418334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 651518334Speter && INTVAL (XEXP (x, 1)) >= 0 651618334Speter && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (op_mode) 651718334Speter && GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT) 651818334Speter mask >>= INTVAL (XEXP (x, 1)); 651918334Speter else 652018334Speter mask = fuller_mask; 652118334Speter 652218334Speter op0 = gen_lowpart_for_combine (op_mode, 652318334Speter force_to_mode (XEXP (x, 0), op_mode, 652418334Speter mask, reg, next_select)); 652518334Speter 652618334Speter if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0)) 652718334Speter x = gen_binary (code, op_mode, op0, XEXP (x, 1)); 652818334Speter break; 652918334Speter 653018334Speter case LSHIFTRT: 653118334Speter /* Here we can only do something if the shift count is a constant, 653218334Speter this shift constant is valid for the host, and we can do arithmetic 653318334Speter in OP_MODE. */ 653418334Speter 653518334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 653618334Speter && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT 653718334Speter && GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT) 653818334Speter { 653918334Speter rtx inner = XEXP (x, 0); 654018334Speter 654118334Speter /* Select the mask of the bits we need for the shift operand. */ 654218334Speter mask <<= INTVAL (XEXP (x, 1)); 654318334Speter 654418334Speter /* We can only change the mode of the shift if we can do arithmetic 654518334Speter in the mode of the shift and MASK is no wider than the width of 654618334Speter OP_MODE. */ 654718334Speter if (GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT 654818334Speter || (mask & ~ GET_MODE_MASK (op_mode)) != 0) 654918334Speter op_mode = GET_MODE (x); 655018334Speter 655118334Speter inner = force_to_mode (inner, op_mode, mask, reg, next_select); 655218334Speter 655318334Speter if (GET_MODE (x) != op_mode || inner != XEXP (x, 0)) 655418334Speter x = gen_binary (LSHIFTRT, op_mode, inner, XEXP (x, 1)); 655518334Speter } 655618334Speter 655718334Speter /* If we have (and (lshiftrt FOO C1) C2) where the combination of the 655818334Speter shift and AND produces only copies of the sign bit (C2 is one less 655918334Speter than a power of two), we can do this with just a shift. */ 656018334Speter 656118334Speter if (GET_CODE (x) == LSHIFTRT 656218334Speter && GET_CODE (XEXP (x, 1)) == CONST_INT 656318334Speter && ((INTVAL (XEXP (x, 1)) 656418334Speter + num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))) 656518334Speter >= GET_MODE_BITSIZE (GET_MODE (x))) 656618334Speter && exact_log2 (mask + 1) >= 0 656718334Speter && (num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0))) 656818334Speter >= exact_log2 (mask + 1))) 656918334Speter x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0), 657018334Speter GEN_INT (GET_MODE_BITSIZE (GET_MODE (x)) 657118334Speter - exact_log2 (mask + 1))); 657218334Speter break; 657318334Speter 657418334Speter case ASHIFTRT: 657518334Speter /* If we are just looking for the sign bit, we don't need this shift at 657618334Speter all, even if it has a variable count. */ 657718334Speter if (GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT 657852284Sobrien && (mask == ((unsigned HOST_WIDE_INT) 1 657918334Speter << (GET_MODE_BITSIZE (GET_MODE (x)) - 1)))) 658018334Speter return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select); 658118334Speter 658218334Speter /* If this is a shift by a constant, get a mask that contains those bits 658318334Speter that are not copies of the sign bit. We then have two cases: If 658418334Speter MASK only includes those bits, this can be a logical shift, which may 658518334Speter allow simplifications. If MASK is a single-bit field not within 658618334Speter those bits, we are requesting a copy of the sign bit and hence can 658718334Speter shift the sign bit to the appropriate location. */ 658818334Speter 658918334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) >= 0 659018334Speter && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT) 659118334Speter { 659218334Speter int i = -1; 659318334Speter 659418334Speter /* If the considered data is wider then HOST_WIDE_INT, we can't 659518334Speter represent a mask for all its bits in a single scalar. 659618334Speter But we only care about the lower bits, so calculate these. */ 659718334Speter 659818334Speter if (GET_MODE_BITSIZE (GET_MODE (x)) > HOST_BITS_PER_WIDE_INT) 659918334Speter { 660050397Sobrien nonzero = ~ (HOST_WIDE_INT) 0; 660118334Speter 660218334Speter /* GET_MODE_BITSIZE (GET_MODE (x)) - INTVAL (XEXP (x, 1)) 660318334Speter is the number of bits a full-width mask would have set. 660418334Speter We need only shift if these are fewer than nonzero can 660518334Speter hold. If not, we must keep all bits set in nonzero. */ 660618334Speter 660718334Speter if (GET_MODE_BITSIZE (GET_MODE (x)) - INTVAL (XEXP (x, 1)) 660818334Speter < HOST_BITS_PER_WIDE_INT) 660918334Speter nonzero >>= INTVAL (XEXP (x, 1)) 661018334Speter + HOST_BITS_PER_WIDE_INT 661118334Speter - GET_MODE_BITSIZE (GET_MODE (x)) ; 661218334Speter } 661318334Speter else 661418334Speter { 661518334Speter nonzero = GET_MODE_MASK (GET_MODE (x)); 661618334Speter nonzero >>= INTVAL (XEXP (x, 1)); 661718334Speter } 661818334Speter 661918334Speter if ((mask & ~ nonzero) == 0 662018334Speter || (i = exact_log2 (mask)) >= 0) 662118334Speter { 662218334Speter x = simplify_shift_const 662318334Speter (x, LSHIFTRT, GET_MODE (x), XEXP (x, 0), 662418334Speter i < 0 ? INTVAL (XEXP (x, 1)) 662518334Speter : GET_MODE_BITSIZE (GET_MODE (x)) - 1 - i); 662618334Speter 662718334Speter if (GET_CODE (x) != ASHIFTRT) 662818334Speter return force_to_mode (x, mode, mask, reg, next_select); 662918334Speter } 663018334Speter } 663118334Speter 663218334Speter /* If MASK is 1, convert this to a LSHIFTRT. This can be done 663318334Speter even if the shift count isn't a constant. */ 663418334Speter if (mask == 1) 663518334Speter x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0), XEXP (x, 1)); 663618334Speter 663718334Speter /* If this is a sign-extension operation that just affects bits 663818334Speter we don't care about, remove it. Be sure the call above returned 663918334Speter something that is still a shift. */ 664018334Speter 664118334Speter if ((GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ASHIFTRT) 664218334Speter && GET_CODE (XEXP (x, 1)) == CONST_INT 664318334Speter && INTVAL (XEXP (x, 1)) >= 0 664418334Speter && (INTVAL (XEXP (x, 1)) 664518334Speter <= GET_MODE_BITSIZE (GET_MODE (x)) - (floor_log2 (mask) + 1)) 664618334Speter && GET_CODE (XEXP (x, 0)) == ASHIFT 664718334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 664818334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) == INTVAL (XEXP (x, 1))) 664918334Speter return force_to_mode (XEXP (XEXP (x, 0), 0), mode, mask, 665018334Speter reg, next_select); 665118334Speter 665218334Speter break; 665318334Speter 665418334Speter case ROTATE: 665518334Speter case ROTATERT: 665618334Speter /* If the shift count is constant and we can do computations 665718334Speter in the mode of X, compute where the bits we care about are. 665818334Speter Otherwise, we can't do anything. Don't change the mode of 665918334Speter the shift or propagate MODE into the shift, though. */ 666018334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 666118334Speter && INTVAL (XEXP (x, 1)) >= 0) 666218334Speter { 666318334Speter temp = simplify_binary_operation (code == ROTATE ? ROTATERT : ROTATE, 666418334Speter GET_MODE (x), GEN_INT (mask), 666518334Speter XEXP (x, 1)); 666618334Speter if (temp && GET_CODE(temp) == CONST_INT) 666718334Speter SUBST (XEXP (x, 0), 666818334Speter force_to_mode (XEXP (x, 0), GET_MODE (x), 666918334Speter INTVAL (temp), reg, next_select)); 667018334Speter } 667118334Speter break; 667218334Speter 667318334Speter case NEG: 667418334Speter /* If we just want the low-order bit, the NEG isn't needed since it 667518334Speter won't change the low-order bit. */ 667618334Speter if (mask == 1) 667718334Speter return force_to_mode (XEXP (x, 0), mode, mask, reg, just_select); 667818334Speter 667918334Speter /* We need any bits less significant than the most significant bit in 668018334Speter MASK since carries from those bits will affect the bits we are 668118334Speter interested in. */ 668218334Speter mask = fuller_mask; 668318334Speter goto unop; 668418334Speter 668518334Speter case NOT: 668618334Speter /* (not FOO) is (xor FOO CONST), so if FOO is an LSHIFTRT, we can do the 668718334Speter same as the XOR case above. Ensure that the constant we form is not 668818334Speter wider than the mode of X. */ 668918334Speter 669018334Speter if (GET_CODE (XEXP (x, 0)) == LSHIFTRT 669118334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 669218334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0 669318334Speter && (INTVAL (XEXP (XEXP (x, 0), 1)) + floor_log2 (mask) 669418334Speter < GET_MODE_BITSIZE (GET_MODE (x))) 669518334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT) 669618334Speter { 669718334Speter temp = GEN_INT (mask << INTVAL (XEXP (XEXP (x, 0), 1))); 669818334Speter temp = gen_binary (XOR, GET_MODE (x), XEXP (XEXP (x, 0), 0), temp); 669918334Speter x = gen_binary (LSHIFTRT, GET_MODE (x), temp, XEXP (XEXP (x, 0), 1)); 670018334Speter 670118334Speter return force_to_mode (x, mode, mask, reg, next_select); 670218334Speter } 670318334Speter 670450397Sobrien /* (and (not FOO) CONST) is (not (or FOO (not CONST))), so we must 670550397Sobrien use the full mask inside the NOT. */ 670650397Sobrien mask = fuller_mask; 670750397Sobrien 670818334Speter unop: 670918334Speter op0 = gen_lowpart_for_combine (op_mode, 671018334Speter force_to_mode (XEXP (x, 0), mode, mask, 671118334Speter reg, next_select)); 671218334Speter if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0)) 671318334Speter x = gen_unary (code, op_mode, op_mode, op0); 671418334Speter break; 671518334Speter 671618334Speter case NE: 671718334Speter /* (and (ne FOO 0) CONST) can be (and FOO CONST) if CONST is included 671850397Sobrien in STORE_FLAG_VALUE and FOO has a single bit that might be nonzero, 671950397Sobrien which is equal to STORE_FLAG_VALUE. */ 672050397Sobrien if ((mask & ~ STORE_FLAG_VALUE) == 0 && XEXP (x, 1) == const0_rtx 672150397Sobrien && exact_log2 (nonzero_bits (XEXP (x, 0), mode)) >= 0 672250397Sobrien && nonzero_bits (XEXP (x, 0), mode) == STORE_FLAG_VALUE) 672318334Speter return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select); 672418334Speter 672518334Speter break; 672618334Speter 672718334Speter case IF_THEN_ELSE: 672818334Speter /* We have no way of knowing if the IF_THEN_ELSE can itself be 672918334Speter written in a narrower mode. We play it safe and do not do so. */ 673018334Speter 673118334Speter SUBST (XEXP (x, 1), 673218334Speter gen_lowpart_for_combine (GET_MODE (x), 673318334Speter force_to_mode (XEXP (x, 1), mode, 673418334Speter mask, reg, next_select))); 673518334Speter SUBST (XEXP (x, 2), 673618334Speter gen_lowpart_for_combine (GET_MODE (x), 673718334Speter force_to_mode (XEXP (x, 2), mode, 673818334Speter mask, reg,next_select))); 673918334Speter break; 674050397Sobrien 674150397Sobrien default: 674250397Sobrien break; 674318334Speter } 674418334Speter 674518334Speter /* Ensure we return a value of the proper mode. */ 674618334Speter return gen_lowpart_for_combine (mode, x); 674718334Speter} 674818334Speter 674918334Speter/* Return nonzero if X is an expression that has one of two values depending on 675018334Speter whether some other value is zero or nonzero. In that case, we return the 675118334Speter value that is being tested, *PTRUE is set to the value if the rtx being 675218334Speter returned has a nonzero value, and *PFALSE is set to the other alternative. 675318334Speter 675418334Speter If we return zero, we set *PTRUE and *PFALSE to X. */ 675518334Speter 675618334Speterstatic rtx 675718334Speterif_then_else_cond (x, ptrue, pfalse) 675818334Speter rtx x; 675918334Speter rtx *ptrue, *pfalse; 676018334Speter{ 676118334Speter enum machine_mode mode = GET_MODE (x); 676218334Speter enum rtx_code code = GET_CODE (x); 676318334Speter int size = GET_MODE_BITSIZE (mode); 676418334Speter rtx cond0, cond1, true0, true1, false0, false1; 676518334Speter unsigned HOST_WIDE_INT nz; 676618334Speter 676718334Speter /* If this is a unary operation whose operand has one of two values, apply 676818334Speter our opcode to compute those values. */ 676918334Speter if (GET_RTX_CLASS (code) == '1' 677018334Speter && (cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0)) != 0) 677118334Speter { 677218334Speter *ptrue = gen_unary (code, mode, GET_MODE (XEXP (x, 0)), true0); 677318334Speter *pfalse = gen_unary (code, mode, GET_MODE (XEXP (x, 0)), false0); 677418334Speter return cond0; 677518334Speter } 677618334Speter 677718334Speter /* If this is a COMPARE, do nothing, since the IF_THEN_ELSE we would 677818334Speter make can't possibly match and would suppress other optimizations. */ 677918334Speter else if (code == COMPARE) 678018334Speter ; 678118334Speter 678218334Speter /* If this is a binary operation, see if either side has only one of two 678318334Speter values. If either one does or if both do and they are conditional on 678418334Speter the same value, compute the new true and false values. */ 678518334Speter else if (GET_RTX_CLASS (code) == 'c' || GET_RTX_CLASS (code) == '2' 678618334Speter || GET_RTX_CLASS (code) == '<') 678718334Speter { 678818334Speter cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0); 678918334Speter cond1 = if_then_else_cond (XEXP (x, 1), &true1, &false1); 679018334Speter 679118334Speter if ((cond0 != 0 || cond1 != 0) 679218334Speter && ! (cond0 != 0 && cond1 != 0 && ! rtx_equal_p (cond0, cond1))) 679318334Speter { 679450397Sobrien /* If if_then_else_cond returned zero, then true/false are the 679550397Sobrien same rtl. We must copy one of them to prevent invalid rtl 679650397Sobrien sharing. */ 679750397Sobrien if (cond0 == 0) 679850397Sobrien true0 = copy_rtx (true0); 679950397Sobrien else if (cond1 == 0) 680050397Sobrien true1 = copy_rtx (true1); 680150397Sobrien 680218334Speter *ptrue = gen_binary (code, mode, true0, true1); 680318334Speter *pfalse = gen_binary (code, mode, false0, false1); 680418334Speter return cond0 ? cond0 : cond1; 680518334Speter } 680618334Speter 680718334Speter /* See if we have PLUS, IOR, XOR, MINUS or UMAX, where one of the 680850397Sobrien operands is zero when the other is non-zero, and vice-versa, 680950397Sobrien and STORE_FLAG_VALUE is 1 or -1. */ 681018334Speter 681150397Sobrien if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1) 681250397Sobrien && (code == PLUS || code == IOR || code == XOR || code == MINUS 681318334Speter || code == UMAX) 681418334Speter && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == MULT) 681518334Speter { 681618334Speter rtx op0 = XEXP (XEXP (x, 0), 1); 681718334Speter rtx op1 = XEXP (XEXP (x, 1), 1); 681818334Speter 681918334Speter cond0 = XEXP (XEXP (x, 0), 0); 682018334Speter cond1 = XEXP (XEXP (x, 1), 0); 682118334Speter 682218334Speter if (GET_RTX_CLASS (GET_CODE (cond0)) == '<' 682318334Speter && GET_RTX_CLASS (GET_CODE (cond1)) == '<' 682418334Speter && reversible_comparison_p (cond1) 682518334Speter && ((GET_CODE (cond0) == reverse_condition (GET_CODE (cond1)) 682618334Speter && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0)) 682718334Speter && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1))) 682818334Speter || ((swap_condition (GET_CODE (cond0)) 682918334Speter == reverse_condition (GET_CODE (cond1))) 683018334Speter && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 1)) 683118334Speter && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0)))) 683218334Speter && ! side_effects_p (x)) 683318334Speter { 683418334Speter *ptrue = gen_binary (MULT, mode, op0, const_true_rtx); 683518334Speter *pfalse = gen_binary (MULT, mode, 683618334Speter (code == MINUS 683718334Speter ? gen_unary (NEG, mode, mode, op1) : op1), 683818334Speter const_true_rtx); 683918334Speter return cond0; 684018334Speter } 684118334Speter } 684218334Speter 684318334Speter /* Similarly for MULT, AND and UMIN, execpt that for these the result 684418334Speter is always zero. */ 684550397Sobrien if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1) 684650397Sobrien && (code == MULT || code == AND || code == UMIN) 684718334Speter && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == MULT) 684818334Speter { 684918334Speter cond0 = XEXP (XEXP (x, 0), 0); 685018334Speter cond1 = XEXP (XEXP (x, 1), 0); 685118334Speter 685218334Speter if (GET_RTX_CLASS (GET_CODE (cond0)) == '<' 685318334Speter && GET_RTX_CLASS (GET_CODE (cond1)) == '<' 685418334Speter && reversible_comparison_p (cond1) 685518334Speter && ((GET_CODE (cond0) == reverse_condition (GET_CODE (cond1)) 685618334Speter && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0)) 685718334Speter && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1))) 685818334Speter || ((swap_condition (GET_CODE (cond0)) 685918334Speter == reverse_condition (GET_CODE (cond1))) 686018334Speter && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 1)) 686118334Speter && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0)))) 686218334Speter && ! side_effects_p (x)) 686318334Speter { 686418334Speter *ptrue = *pfalse = const0_rtx; 686518334Speter return cond0; 686618334Speter } 686718334Speter } 686818334Speter } 686918334Speter 687018334Speter else if (code == IF_THEN_ELSE) 687118334Speter { 687218334Speter /* If we have IF_THEN_ELSE already, extract the condition and 687318334Speter canonicalize it if it is NE or EQ. */ 687418334Speter cond0 = XEXP (x, 0); 687518334Speter *ptrue = XEXP (x, 1), *pfalse = XEXP (x, 2); 687618334Speter if (GET_CODE (cond0) == NE && XEXP (cond0, 1) == const0_rtx) 687718334Speter return XEXP (cond0, 0); 687818334Speter else if (GET_CODE (cond0) == EQ && XEXP (cond0, 1) == const0_rtx) 687918334Speter { 688018334Speter *ptrue = XEXP (x, 2), *pfalse = XEXP (x, 1); 688118334Speter return XEXP (cond0, 0); 688218334Speter } 688318334Speter else 688418334Speter return cond0; 688518334Speter } 688618334Speter 688718334Speter /* If X is a normal SUBREG with both inner and outer modes integral, 688818334Speter we can narrow both the true and false values of the inner expression, 688918334Speter if there is a condition. */ 689018334Speter else if (code == SUBREG && GET_MODE_CLASS (mode) == MODE_INT 689118334Speter && GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_INT 689218334Speter && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) 689318334Speter && 0 != (cond0 = if_then_else_cond (SUBREG_REG (x), 689418334Speter &true0, &false0))) 689518334Speter { 689618334Speter *ptrue = force_to_mode (true0, mode, GET_MODE_MASK (mode), NULL_RTX, 0); 689718334Speter *pfalse 689818334Speter = force_to_mode (false0, mode, GET_MODE_MASK (mode), NULL_RTX, 0); 689918334Speter 690018334Speter return cond0; 690118334Speter } 690218334Speter 690318334Speter /* If X is a constant, this isn't special and will cause confusions 690418334Speter if we treat it as such. Likewise if it is equivalent to a constant. */ 690518334Speter else if (CONSTANT_P (x) 690618334Speter || ((cond0 = get_last_value (x)) != 0 && CONSTANT_P (cond0))) 690718334Speter ; 690818334Speter 690918334Speter /* If X is known to be either 0 or -1, those are the true and 691018334Speter false values when testing X. */ 691118334Speter else if (num_sign_bit_copies (x, mode) == size) 691218334Speter { 691318334Speter *ptrue = constm1_rtx, *pfalse = const0_rtx; 691418334Speter return x; 691518334Speter } 691618334Speter 691718334Speter /* Likewise for 0 or a single bit. */ 691818334Speter else if (exact_log2 (nz = nonzero_bits (x, mode)) >= 0) 691918334Speter { 692018334Speter *ptrue = GEN_INT (nz), *pfalse = const0_rtx; 692118334Speter return x; 692218334Speter } 692318334Speter 692418334Speter /* Otherwise fail; show no condition with true and false values the same. */ 692518334Speter *ptrue = *pfalse = x; 692618334Speter return 0; 692718334Speter} 692818334Speter 692918334Speter/* Return the value of expression X given the fact that condition COND 693018334Speter is known to be true when applied to REG as its first operand and VAL 693118334Speter as its second. X is known to not be shared and so can be modified in 693218334Speter place. 693318334Speter 693418334Speter We only handle the simplest cases, and specifically those cases that 693518334Speter arise with IF_THEN_ELSE expressions. */ 693618334Speter 693718334Speterstatic rtx 693818334Speterknown_cond (x, cond, reg, val) 693918334Speter rtx x; 694018334Speter enum rtx_code cond; 694118334Speter rtx reg, val; 694218334Speter{ 694318334Speter enum rtx_code code = GET_CODE (x); 694418334Speter rtx temp; 694518334Speter char *fmt; 694618334Speter int i, j; 694718334Speter 694818334Speter if (side_effects_p (x)) 694918334Speter return x; 695018334Speter 695118334Speter if (cond == EQ && rtx_equal_p (x, reg)) 695218334Speter return val; 695318334Speter 695418334Speter /* If X is (abs REG) and we know something about REG's relationship 695518334Speter with zero, we may be able to simplify this. */ 695618334Speter 695718334Speter if (code == ABS && rtx_equal_p (XEXP (x, 0), reg) && val == const0_rtx) 695818334Speter switch (cond) 695918334Speter { 696018334Speter case GE: case GT: case EQ: 696118334Speter return XEXP (x, 0); 696218334Speter case LT: case LE: 696318334Speter return gen_unary (NEG, GET_MODE (XEXP (x, 0)), GET_MODE (XEXP (x, 0)), 696418334Speter XEXP (x, 0)); 696550397Sobrien default: 696650397Sobrien break; 696718334Speter } 696818334Speter 696918334Speter /* The only other cases we handle are MIN, MAX, and comparisons if the 697018334Speter operands are the same as REG and VAL. */ 697118334Speter 697218334Speter else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == 'c') 697318334Speter { 697418334Speter if (rtx_equal_p (XEXP (x, 0), val)) 697518334Speter cond = swap_condition (cond), temp = val, val = reg, reg = temp; 697618334Speter 697718334Speter if (rtx_equal_p (XEXP (x, 0), reg) && rtx_equal_p (XEXP (x, 1), val)) 697818334Speter { 697918334Speter if (GET_RTX_CLASS (code) == '<') 698018334Speter return (comparison_dominates_p (cond, code) ? const_true_rtx 698118334Speter : (comparison_dominates_p (cond, 698218334Speter reverse_condition (code)) 698318334Speter ? const0_rtx : x)); 698418334Speter 698518334Speter else if (code == SMAX || code == SMIN 698618334Speter || code == UMIN || code == UMAX) 698718334Speter { 698818334Speter int unsignedp = (code == UMIN || code == UMAX); 698918334Speter 699018334Speter if (code == SMAX || code == UMAX) 699118334Speter cond = reverse_condition (cond); 699218334Speter 699318334Speter switch (cond) 699418334Speter { 699518334Speter case GE: case GT: 699618334Speter return unsignedp ? x : XEXP (x, 1); 699718334Speter case LE: case LT: 699818334Speter return unsignedp ? x : XEXP (x, 0); 699918334Speter case GEU: case GTU: 700018334Speter return unsignedp ? XEXP (x, 1) : x; 700118334Speter case LEU: case LTU: 700218334Speter return unsignedp ? XEXP (x, 0) : x; 700350397Sobrien default: 700450397Sobrien break; 700518334Speter } 700618334Speter } 700718334Speter } 700818334Speter } 700918334Speter 701018334Speter fmt = GET_RTX_FORMAT (code); 701118334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 701218334Speter { 701318334Speter if (fmt[i] == 'e') 701418334Speter SUBST (XEXP (x, i), known_cond (XEXP (x, i), cond, reg, val)); 701518334Speter else if (fmt[i] == 'E') 701618334Speter for (j = XVECLEN (x, i) - 1; j >= 0; j--) 701718334Speter SUBST (XVECEXP (x, i, j), known_cond (XVECEXP (x, i, j), 701818334Speter cond, reg, val)); 701918334Speter } 702018334Speter 702118334Speter return x; 702218334Speter} 702318334Speter 702450397Sobrien/* See if X and Y are equal for the purposes of seeing if we can rewrite an 702550397Sobrien assignment as a field assignment. */ 702650397Sobrien 702750397Sobrienstatic int 702850397Sobrienrtx_equal_for_field_assignment_p (x, y) 702950397Sobrien rtx x; 703050397Sobrien rtx y; 703150397Sobrien{ 703250397Sobrien if (x == y || rtx_equal_p (x, y)) 703350397Sobrien return 1; 703450397Sobrien 703550397Sobrien if (x == 0 || y == 0 || GET_MODE (x) != GET_MODE (y)) 703650397Sobrien return 0; 703750397Sobrien 703850397Sobrien /* Check for a paradoxical SUBREG of a MEM compared with the MEM. 703950397Sobrien Note that all SUBREGs of MEM are paradoxical; otherwise they 704050397Sobrien would have been rewritten. */ 704150397Sobrien if (GET_CODE (x) == MEM && GET_CODE (y) == SUBREG 704250397Sobrien && GET_CODE (SUBREG_REG (y)) == MEM 704350397Sobrien && rtx_equal_p (SUBREG_REG (y), 704450397Sobrien gen_lowpart_for_combine (GET_MODE (SUBREG_REG (y)), x))) 704550397Sobrien return 1; 704650397Sobrien 704750397Sobrien if (GET_CODE (y) == MEM && GET_CODE (x) == SUBREG 704850397Sobrien && GET_CODE (SUBREG_REG (x)) == MEM 704950397Sobrien && rtx_equal_p (SUBREG_REG (x), 705050397Sobrien gen_lowpart_for_combine (GET_MODE (SUBREG_REG (x)), y))) 705150397Sobrien return 1; 705250397Sobrien 705350397Sobrien /* We used to see if get_last_value of X and Y were the same but that's 705450397Sobrien not correct. In one direction, we'll cause the assignment to have 705550397Sobrien the wrong destination and in the case, we'll import a register into this 705650397Sobrien insn that might have already have been dead. So fail if none of the 705750397Sobrien above cases are true. */ 705850397Sobrien return 0; 705950397Sobrien} 706050397Sobrien 706118334Speter/* See if X, a SET operation, can be rewritten as a bit-field assignment. 706218334Speter Return that assignment if so. 706318334Speter 706418334Speter We only handle the most common cases. */ 706518334Speter 706618334Speterstatic rtx 706718334Spetermake_field_assignment (x) 706818334Speter rtx x; 706918334Speter{ 707018334Speter rtx dest = SET_DEST (x); 707118334Speter rtx src = SET_SRC (x); 707218334Speter rtx assign; 707350397Sobrien rtx rhs, lhs; 707418334Speter HOST_WIDE_INT c1; 707518334Speter int pos, len; 707618334Speter rtx other; 707718334Speter enum machine_mode mode; 707818334Speter 707918334Speter /* If SRC was (and (not (ashift (const_int 1) POS)) DEST), this is 708018334Speter a clear of a one-bit field. We will have changed it to 708118334Speter (and (rotate (const_int -2) POS) DEST), so check for that. Also check 708218334Speter for a SUBREG. */ 708318334Speter 708418334Speter if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == ROTATE 708518334Speter && GET_CODE (XEXP (XEXP (src, 0), 0)) == CONST_INT 708618334Speter && INTVAL (XEXP (XEXP (src, 0), 0)) == -2 708750397Sobrien && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1))) 708818334Speter { 708918334Speter assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1), 709018334Speter 1, 1, 1, 0); 709150397Sobrien if (assign != 0) 709250397Sobrien return gen_rtx_SET (VOIDmode, assign, const0_rtx); 709350397Sobrien return x; 709418334Speter } 709518334Speter 709618334Speter else if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == SUBREG 709718334Speter && subreg_lowpart_p (XEXP (src, 0)) 709818334Speter && (GET_MODE_SIZE (GET_MODE (XEXP (src, 0))) 709918334Speter < GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (src, 0))))) 710018334Speter && GET_CODE (SUBREG_REG (XEXP (src, 0))) == ROTATE 710118334Speter && INTVAL (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == -2 710250397Sobrien && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1))) 710318334Speter { 710418334Speter assign = make_extraction (VOIDmode, dest, 0, 710518334Speter XEXP (SUBREG_REG (XEXP (src, 0)), 1), 710618334Speter 1, 1, 1, 0); 710750397Sobrien if (assign != 0) 710850397Sobrien return gen_rtx_SET (VOIDmode, assign, const0_rtx); 710950397Sobrien return x; 711018334Speter } 711118334Speter 711250397Sobrien /* If SRC is (ior (ashift (const_int 1) POS) DEST), this is a set of a 711318334Speter one-bit field. */ 711418334Speter else if (GET_CODE (src) == IOR && GET_CODE (XEXP (src, 0)) == ASHIFT 711518334Speter && XEXP (XEXP (src, 0), 0) == const1_rtx 711650397Sobrien && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1))) 711718334Speter { 711818334Speter assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1), 711918334Speter 1, 1, 1, 0); 712050397Sobrien if (assign != 0) 712150397Sobrien return gen_rtx_SET (VOIDmode, assign, const1_rtx); 712250397Sobrien return x; 712318334Speter } 712418334Speter 712518334Speter /* The other case we handle is assignments into a constant-position 712650397Sobrien field. They look like (ior/xor (and DEST C1) OTHER). If C1 represents 712718334Speter a mask that has all one bits except for a group of zero bits and 712818334Speter OTHER is known to have zeros where C1 has ones, this is such an 712918334Speter assignment. Compute the position and length from C1. Shift OTHER 713018334Speter to the appropriate position, force it to the required mode, and 713118334Speter make the extraction. Check for the AND in both operands. */ 713218334Speter 713350397Sobrien if (GET_CODE (src) != IOR && GET_CODE (src) != XOR) 713450397Sobrien return x; 713550397Sobrien 713650397Sobrien rhs = expand_compound_operation (XEXP (src, 0)); 713750397Sobrien lhs = expand_compound_operation (XEXP (src, 1)); 713850397Sobrien 713950397Sobrien if (GET_CODE (rhs) == AND 714050397Sobrien && GET_CODE (XEXP (rhs, 1)) == CONST_INT 714150397Sobrien && rtx_equal_for_field_assignment_p (XEXP (rhs, 0), dest)) 714250397Sobrien c1 = INTVAL (XEXP (rhs, 1)), other = lhs; 714350397Sobrien else if (GET_CODE (lhs) == AND 714450397Sobrien && GET_CODE (XEXP (lhs, 1)) == CONST_INT 714550397Sobrien && rtx_equal_for_field_assignment_p (XEXP (lhs, 0), dest)) 714650397Sobrien c1 = INTVAL (XEXP (lhs, 1)), other = rhs; 714718334Speter else 714818334Speter return x; 714918334Speter 715050397Sobrien pos = get_pos_from_mask ((~ c1) & GET_MODE_MASK (GET_MODE (dest)), &len); 715118334Speter if (pos < 0 || pos + len > GET_MODE_BITSIZE (GET_MODE (dest)) 715250397Sobrien || GET_MODE_BITSIZE (GET_MODE (dest)) > HOST_BITS_PER_WIDE_INT 715350397Sobrien || (c1 & nonzero_bits (other, GET_MODE (dest))) != 0) 715418334Speter return x; 715518334Speter 715618334Speter assign = make_extraction (VOIDmode, dest, pos, NULL_RTX, len, 1, 1, 0); 715750397Sobrien if (assign == 0) 715850397Sobrien return x; 715918334Speter 716018334Speter /* The mode to use for the source is the mode of the assignment, or of 716118334Speter what is inside a possible STRICT_LOW_PART. */ 716218334Speter mode = (GET_CODE (assign) == STRICT_LOW_PART 716318334Speter ? GET_MODE (XEXP (assign, 0)) : GET_MODE (assign)); 716418334Speter 716518334Speter /* Shift OTHER right POS places and make it the source, restricting it 716618334Speter to the proper length and mode. */ 716718334Speter 716818334Speter src = force_to_mode (simplify_shift_const (NULL_RTX, LSHIFTRT, 716918334Speter GET_MODE (src), other, pos), 717018334Speter mode, 717118334Speter GET_MODE_BITSIZE (mode) >= HOST_BITS_PER_WIDE_INT 717218334Speter ? GET_MODE_MASK (mode) 717318334Speter : ((HOST_WIDE_INT) 1 << len) - 1, 717418334Speter dest, 0); 717518334Speter 717618334Speter return gen_rtx_combine (SET, VOIDmode, assign, src); 717718334Speter} 717818334Speter 717918334Speter/* See if X is of the form (+ (* a c) (* b c)) and convert to (* (+ a b) c) 718018334Speter if so. */ 718118334Speter 718218334Speterstatic rtx 718318334Speterapply_distributive_law (x) 718418334Speter rtx x; 718518334Speter{ 718618334Speter enum rtx_code code = GET_CODE (x); 718718334Speter rtx lhs, rhs, other; 718818334Speter rtx tem; 718918334Speter enum rtx_code inner_code; 719018334Speter 719118334Speter /* Distributivity is not true for floating point. 719218334Speter It can change the value. So don't do it. 719318334Speter -- rms and moshier@world.std.com. */ 719418334Speter if (FLOAT_MODE_P (GET_MODE (x))) 719518334Speter return x; 719618334Speter 719718334Speter /* The outer operation can only be one of the following: */ 719818334Speter if (code != IOR && code != AND && code != XOR 719918334Speter && code != PLUS && code != MINUS) 720018334Speter return x; 720118334Speter 720218334Speter lhs = XEXP (x, 0), rhs = XEXP (x, 1); 720318334Speter 720450397Sobrien /* If either operand is a primitive we can't do anything, so get out 720550397Sobrien fast. */ 720618334Speter if (GET_RTX_CLASS (GET_CODE (lhs)) == 'o' 720718334Speter || GET_RTX_CLASS (GET_CODE (rhs)) == 'o') 720818334Speter return x; 720918334Speter 721018334Speter lhs = expand_compound_operation (lhs); 721118334Speter rhs = expand_compound_operation (rhs); 721218334Speter inner_code = GET_CODE (lhs); 721318334Speter if (inner_code != GET_CODE (rhs)) 721418334Speter return x; 721518334Speter 721618334Speter /* See if the inner and outer operations distribute. */ 721718334Speter switch (inner_code) 721818334Speter { 721918334Speter case LSHIFTRT: 722018334Speter case ASHIFTRT: 722118334Speter case AND: 722218334Speter case IOR: 722318334Speter /* These all distribute except over PLUS. */ 722418334Speter if (code == PLUS || code == MINUS) 722518334Speter return x; 722618334Speter break; 722718334Speter 722818334Speter case MULT: 722918334Speter if (code != PLUS && code != MINUS) 723018334Speter return x; 723118334Speter break; 723218334Speter 723318334Speter case ASHIFT: 723418334Speter /* This is also a multiply, so it distributes over everything. */ 723518334Speter break; 723618334Speter 723718334Speter case SUBREG: 723818334Speter /* Non-paradoxical SUBREGs distributes over all operations, provided 723918334Speter the inner modes and word numbers are the same, this is an extraction 724018334Speter of a low-order part, we don't convert an fp operation to int or 724118334Speter vice versa, and we would not be converting a single-word 724218334Speter operation into a multi-word operation. The latter test is not 724318334Speter required, but it prevents generating unneeded multi-word operations. 724418334Speter Some of the previous tests are redundant given the latter test, but 724518334Speter are retained because they are required for correctness. 724618334Speter 724718334Speter We produce the result slightly differently in this case. */ 724818334Speter 724918334Speter if (GET_MODE (SUBREG_REG (lhs)) != GET_MODE (SUBREG_REG (rhs)) 725018334Speter || SUBREG_WORD (lhs) != SUBREG_WORD (rhs) 725118334Speter || ! subreg_lowpart_p (lhs) 725218334Speter || (GET_MODE_CLASS (GET_MODE (lhs)) 725318334Speter != GET_MODE_CLASS (GET_MODE (SUBREG_REG (lhs)))) 725418334Speter || (GET_MODE_SIZE (GET_MODE (lhs)) 725518334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs)))) 725618334Speter || GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))) > UNITS_PER_WORD) 725718334Speter return x; 725818334Speter 725918334Speter tem = gen_binary (code, GET_MODE (SUBREG_REG (lhs)), 726018334Speter SUBREG_REG (lhs), SUBREG_REG (rhs)); 726118334Speter return gen_lowpart_for_combine (GET_MODE (x), tem); 726218334Speter 726318334Speter default: 726418334Speter return x; 726518334Speter } 726618334Speter 726718334Speter /* Set LHS and RHS to the inner operands (A and B in the example 726818334Speter above) and set OTHER to the common operand (C in the example). 726918334Speter These is only one way to do this unless the inner operation is 727018334Speter commutative. */ 727118334Speter if (GET_RTX_CLASS (inner_code) == 'c' 727218334Speter && rtx_equal_p (XEXP (lhs, 0), XEXP (rhs, 0))) 727318334Speter other = XEXP (lhs, 0), lhs = XEXP (lhs, 1), rhs = XEXP (rhs, 1); 727418334Speter else if (GET_RTX_CLASS (inner_code) == 'c' 727518334Speter && rtx_equal_p (XEXP (lhs, 0), XEXP (rhs, 1))) 727618334Speter other = XEXP (lhs, 0), lhs = XEXP (lhs, 1), rhs = XEXP (rhs, 0); 727718334Speter else if (GET_RTX_CLASS (inner_code) == 'c' 727818334Speter && rtx_equal_p (XEXP (lhs, 1), XEXP (rhs, 0))) 727918334Speter other = XEXP (lhs, 1), lhs = XEXP (lhs, 0), rhs = XEXP (rhs, 1); 728018334Speter else if (rtx_equal_p (XEXP (lhs, 1), XEXP (rhs, 1))) 728118334Speter other = XEXP (lhs, 1), lhs = XEXP (lhs, 0), rhs = XEXP (rhs, 0); 728218334Speter else 728318334Speter return x; 728418334Speter 728518334Speter /* Form the new inner operation, seeing if it simplifies first. */ 728618334Speter tem = gen_binary (code, GET_MODE (x), lhs, rhs); 728718334Speter 728818334Speter /* There is one exception to the general way of distributing: 728918334Speter (a ^ b) | (a ^ c) -> (~a) & (b ^ c) */ 729018334Speter if (code == XOR && inner_code == IOR) 729118334Speter { 729218334Speter inner_code = AND; 729318334Speter other = gen_unary (NOT, GET_MODE (x), GET_MODE (x), other); 729418334Speter } 729518334Speter 729618334Speter /* We may be able to continuing distributing the result, so call 729718334Speter ourselves recursively on the inner operation before forming the 729818334Speter outer operation, which we return. */ 729918334Speter return gen_binary (inner_code, GET_MODE (x), 730018334Speter apply_distributive_law (tem), other); 730118334Speter} 730218334Speter 730318334Speter/* We have X, a logical `and' of VAROP with the constant CONSTOP, to be done 730418334Speter in MODE. 730518334Speter 730618334Speter Return an equivalent form, if different from X. Otherwise, return X. If 730718334Speter X is zero, we are to always construct the equivalent form. */ 730818334Speter 730918334Speterstatic rtx 731018334Spetersimplify_and_const_int (x, mode, varop, constop) 731118334Speter rtx x; 731218334Speter enum machine_mode mode; 731318334Speter rtx varop; 731418334Speter unsigned HOST_WIDE_INT constop; 731518334Speter{ 731618334Speter unsigned HOST_WIDE_INT nonzero; 731718334Speter int width = GET_MODE_BITSIZE (mode); 731818334Speter int i; 731918334Speter 732018334Speter /* Simplify VAROP knowing that we will be only looking at some of the 732118334Speter bits in it. */ 732218334Speter varop = force_to_mode (varop, mode, constop, NULL_RTX, 0); 732318334Speter 732418334Speter /* If VAROP is a CLOBBER, we will fail so return it; if it is a 732518334Speter CONST_INT, we are done. */ 732618334Speter if (GET_CODE (varop) == CLOBBER || GET_CODE (varop) == CONST_INT) 732718334Speter return varop; 732818334Speter 732918334Speter /* See what bits may be nonzero in VAROP. Unlike the general case of 733018334Speter a call to nonzero_bits, here we don't care about bits outside 733118334Speter MODE. */ 733218334Speter 733318334Speter nonzero = nonzero_bits (varop, mode) & GET_MODE_MASK (mode); 733418334Speter 733518334Speter /* If this would be an entire word for the target, but is not for 733618334Speter the host, then sign-extend on the host so that the number will look 733718334Speter the same way on the host that it would on the target. 733818334Speter 733918334Speter For example, when building a 64 bit alpha hosted 32 bit sparc 734018334Speter targeted compiler, then we want the 32 bit unsigned value -1 to be 734118334Speter represented as a 64 bit value -1, and not as 0x00000000ffffffff. 734218334Speter The later confuses the sparc backend. */ 734318334Speter 734418334Speter if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width 734518334Speter && (nonzero & ((HOST_WIDE_INT) 1 << (width - 1)))) 734618334Speter nonzero |= ((HOST_WIDE_INT) (-1) << width); 734718334Speter 734818334Speter /* Turn off all bits in the constant that are known to already be zero. 734918334Speter Thus, if the AND isn't needed at all, we will have CONSTOP == NONZERO_BITS 735018334Speter which is tested below. */ 735118334Speter 735218334Speter constop &= nonzero; 735318334Speter 735418334Speter /* If we don't have any bits left, return zero. */ 735518334Speter if (constop == 0) 735618334Speter return const0_rtx; 735718334Speter 735818334Speter /* If VAROP is a NEG of something known to be zero or 1 and CONSTOP is 735918334Speter a power of two, we can replace this with a ASHIFT. */ 736018334Speter if (GET_CODE (varop) == NEG && nonzero_bits (XEXP (varop, 0), mode) == 1 736118334Speter && (i = exact_log2 (constop)) >= 0) 736218334Speter return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (varop, 0), i); 736318334Speter 736418334Speter /* If VAROP is an IOR or XOR, apply the AND to both branches of the IOR 736518334Speter or XOR, then try to apply the distributive law. This may eliminate 736618334Speter operations if either branch can be simplified because of the AND. 736718334Speter It may also make some cases more complex, but those cases probably 736818334Speter won't match a pattern either with or without this. */ 736918334Speter 737018334Speter if (GET_CODE (varop) == IOR || GET_CODE (varop) == XOR) 737118334Speter return 737218334Speter gen_lowpart_for_combine 737318334Speter (mode, 737418334Speter apply_distributive_law 737518334Speter (gen_binary (GET_CODE (varop), GET_MODE (varop), 737618334Speter simplify_and_const_int (NULL_RTX, GET_MODE (varop), 737718334Speter XEXP (varop, 0), constop), 737818334Speter simplify_and_const_int (NULL_RTX, GET_MODE (varop), 737918334Speter XEXP (varop, 1), constop)))); 738018334Speter 738118334Speter /* Get VAROP in MODE. Try to get a SUBREG if not. Don't make a new SUBREG 738218334Speter if we already had one (just check for the simplest cases). */ 738318334Speter if (x && GET_CODE (XEXP (x, 0)) == SUBREG 738418334Speter && GET_MODE (XEXP (x, 0)) == mode 738518334Speter && SUBREG_REG (XEXP (x, 0)) == varop) 738618334Speter varop = XEXP (x, 0); 738718334Speter else 738818334Speter varop = gen_lowpart_for_combine (mode, varop); 738918334Speter 739050397Sobrien /* If we can't make the SUBREG, try to return what we were given. */ 739118334Speter if (GET_CODE (varop) == CLOBBER) 739218334Speter return x ? x : varop; 739318334Speter 739418334Speter /* If we are only masking insignificant bits, return VAROP. */ 739518334Speter if (constop == nonzero) 739618334Speter x = varop; 739718334Speter 739818334Speter /* Otherwise, return an AND. See how much, if any, of X we can use. */ 739918334Speter else if (x == 0 || GET_CODE (x) != AND || GET_MODE (x) != mode) 740018334Speter x = gen_binary (AND, mode, varop, GEN_INT (constop)); 740118334Speter 740218334Speter else 740318334Speter { 740418334Speter if (GET_CODE (XEXP (x, 1)) != CONST_INT 740552284Sobrien || (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) != constop) 740618334Speter SUBST (XEXP (x, 1), GEN_INT (constop)); 740718334Speter 740818334Speter SUBST (XEXP (x, 0), varop); 740918334Speter } 741018334Speter 741118334Speter return x; 741218334Speter} 741318334Speter 741450397Sobrien/* We let num_sign_bit_copies recur into nonzero_bits as that is useful. 741550397Sobrien We don't let nonzero_bits recur into num_sign_bit_copies, because that 741650397Sobrien is less useful. We can't allow both, because that results in exponential 741750397Sobrien run time recursion. There is a nullstone testcase that triggered 741850397Sobrien this. This macro avoids accidental uses of num_sign_bit_copies. */ 741950397Sobrien#define num_sign_bit_copies() 742050397Sobrien 742118334Speter/* Given an expression, X, compute which bits in X can be non-zero. 742218334Speter We don't care about bits outside of those defined in MODE. 742318334Speter 742418334Speter For most X this is simply GET_MODE_MASK (GET_MODE (MODE)), but if X is 742518334Speter a shift, AND, or zero_extract, we can do better. */ 742618334Speter 742718334Speterstatic unsigned HOST_WIDE_INT 742818334Speternonzero_bits (x, mode) 742918334Speter rtx x; 743018334Speter enum machine_mode mode; 743118334Speter{ 743218334Speter unsigned HOST_WIDE_INT nonzero = GET_MODE_MASK (mode); 743318334Speter unsigned HOST_WIDE_INT inner_nz; 743418334Speter enum rtx_code code; 743518334Speter int mode_width = GET_MODE_BITSIZE (mode); 743618334Speter rtx tem; 743718334Speter 743818334Speter /* For floating-point values, assume all bits are needed. */ 743918334Speter if (FLOAT_MODE_P (GET_MODE (x)) || FLOAT_MODE_P (mode)) 744018334Speter return nonzero; 744118334Speter 744218334Speter /* If X is wider than MODE, use its mode instead. */ 744318334Speter if (GET_MODE_BITSIZE (GET_MODE (x)) > mode_width) 744418334Speter { 744518334Speter mode = GET_MODE (x); 744618334Speter nonzero = GET_MODE_MASK (mode); 744718334Speter mode_width = GET_MODE_BITSIZE (mode); 744818334Speter } 744918334Speter 745018334Speter if (mode_width > HOST_BITS_PER_WIDE_INT) 745118334Speter /* Our only callers in this case look for single bit values. So 745218334Speter just return the mode mask. Those tests will then be false. */ 745318334Speter return nonzero; 745418334Speter 745518334Speter#ifndef WORD_REGISTER_OPERATIONS 745618334Speter /* If MODE is wider than X, but both are a single word for both the host 745718334Speter and target machines, we can compute this from which bits of the 745818334Speter object might be nonzero in its own mode, taking into account the fact 745918334Speter that on many CISC machines, accessing an object in a wider mode 746018334Speter causes the high-order bits to become undefined. So they are 746118334Speter not known to be zero. */ 746218334Speter 746318334Speter if (GET_MODE (x) != VOIDmode && GET_MODE (x) != mode 746418334Speter && GET_MODE_BITSIZE (GET_MODE (x)) <= BITS_PER_WORD 746518334Speter && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT 746618334Speter && GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (GET_MODE (x))) 746718334Speter { 746818334Speter nonzero &= nonzero_bits (x, GET_MODE (x)); 746918334Speter nonzero |= GET_MODE_MASK (mode) & ~ GET_MODE_MASK (GET_MODE (x)); 747018334Speter return nonzero; 747118334Speter } 747218334Speter#endif 747318334Speter 747418334Speter code = GET_CODE (x); 747518334Speter switch (code) 747618334Speter { 747718334Speter case REG: 747818334Speter#ifdef POINTERS_EXTEND_UNSIGNED 747918334Speter /* If pointers extend unsigned and this is a pointer in Pmode, say that 748018334Speter all the bits above ptr_mode are known to be zero. */ 748118334Speter if (POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode 748218334Speter && REGNO_POINTER_FLAG (REGNO (x))) 748318334Speter nonzero &= GET_MODE_MASK (ptr_mode); 748418334Speter#endif 748518334Speter 748618334Speter#ifdef STACK_BOUNDARY 748718334Speter /* If this is the stack pointer, we may know something about its 748818334Speter alignment. If PUSH_ROUNDING is defined, it is possible for the 748918334Speter stack to be momentarily aligned only to that amount, so we pick 749018334Speter the least alignment. */ 749118334Speter 749250397Sobrien /* We can't check for arg_pointer_rtx here, because it is not 749350397Sobrien guaranteed to have as much alignment as the stack pointer. 749450397Sobrien In particular, in the Irix6 n64 ABI, the stack has 128 bit 749550397Sobrien alignment but the argument pointer has only 64 bit alignment. */ 749650397Sobrien 749750397Sobrien if ((x == frame_pointer_rtx 749850397Sobrien || x == stack_pointer_rtx 749950397Sobrien || x == hard_frame_pointer_rtx 750050397Sobrien || (REGNO (x) >= FIRST_VIRTUAL_REGISTER 750150397Sobrien && REGNO (x) <= LAST_VIRTUAL_REGISTER)) 750250397Sobrien#ifdef STACK_BIAS 750350397Sobrien && !STACK_BIAS 750450397Sobrien#endif 750550397Sobrien ) 750618334Speter { 750718334Speter int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT; 750818334Speter 750918334Speter#ifdef PUSH_ROUNDING 751050397Sobrien if (REGNO (x) == STACK_POINTER_REGNUM) 751150397Sobrien sp_alignment = MIN (PUSH_ROUNDING (1), sp_alignment); 751218334Speter#endif 751318334Speter 751418334Speter /* We must return here, otherwise we may get a worse result from 751518334Speter one of the choices below. There is nothing useful below as 751618334Speter far as the stack pointer is concerned. */ 751718334Speter return nonzero &= ~ (sp_alignment - 1); 751818334Speter } 751918334Speter#endif 752018334Speter 752118334Speter /* If X is a register whose nonzero bits value is current, use it. 752218334Speter Otherwise, if X is a register whose value we can find, use that 752318334Speter value. Otherwise, use the previously-computed global nonzero bits 752418334Speter for this register. */ 752518334Speter 752618334Speter if (reg_last_set_value[REGNO (x)] != 0 752718334Speter && reg_last_set_mode[REGNO (x)] == mode 752850397Sobrien && (REG_N_SETS (REGNO (x)) == 1 752918334Speter || reg_last_set_label[REGNO (x)] == label_tick) 753018334Speter && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid) 753118334Speter return reg_last_set_nonzero_bits[REGNO (x)]; 753218334Speter 753318334Speter tem = get_last_value (x); 753418334Speter 753518334Speter if (tem) 753618334Speter { 753718334Speter#ifdef SHORT_IMMEDIATES_SIGN_EXTEND 753818334Speter /* If X is narrower than MODE and TEM is a non-negative 753918334Speter constant that would appear negative in the mode of X, 754018334Speter sign-extend it for use in reg_nonzero_bits because some 754118334Speter machines (maybe most) will actually do the sign-extension 754218334Speter and this is the conservative approach. 754318334Speter 754418334Speter ??? For 2.5, try to tighten up the MD files in this regard 754518334Speter instead of this kludge. */ 754618334Speter 754718334Speter if (GET_MODE_BITSIZE (GET_MODE (x)) < mode_width 754818334Speter && GET_CODE (tem) == CONST_INT 754918334Speter && INTVAL (tem) > 0 755018334Speter && 0 != (INTVAL (tem) 755118334Speter & ((HOST_WIDE_INT) 1 755218334Speter << (GET_MODE_BITSIZE (GET_MODE (x)) - 1)))) 755318334Speter tem = GEN_INT (INTVAL (tem) 755418334Speter | ((HOST_WIDE_INT) (-1) 755518334Speter << GET_MODE_BITSIZE (GET_MODE (x)))); 755618334Speter#endif 755718334Speter return nonzero_bits (tem, mode); 755818334Speter } 755918334Speter else if (nonzero_sign_valid && reg_nonzero_bits[REGNO (x)]) 756018334Speter return reg_nonzero_bits[REGNO (x)] & nonzero; 756118334Speter else 756218334Speter return nonzero; 756318334Speter 756418334Speter case CONST_INT: 756518334Speter#ifdef SHORT_IMMEDIATES_SIGN_EXTEND 756618334Speter /* If X is negative in MODE, sign-extend the value. */ 756718334Speter if (INTVAL (x) > 0 && mode_width < BITS_PER_WORD 756818334Speter && 0 != (INTVAL (x) & ((HOST_WIDE_INT) 1 << (mode_width - 1)))) 756918334Speter return (INTVAL (x) | ((HOST_WIDE_INT) (-1) << mode_width)); 757018334Speter#endif 757118334Speter 757218334Speter return INTVAL (x); 757318334Speter 757418334Speter case MEM: 757518334Speter#ifdef LOAD_EXTEND_OP 757618334Speter /* In many, if not most, RISC machines, reading a byte from memory 757718334Speter zeros the rest of the register. Noticing that fact saves a lot 757818334Speter of extra zero-extends. */ 757918334Speter if (LOAD_EXTEND_OP (GET_MODE (x)) == ZERO_EXTEND) 758018334Speter nonzero &= GET_MODE_MASK (GET_MODE (x)); 758118334Speter#endif 758218334Speter break; 758318334Speter 758418334Speter case EQ: case NE: 758518334Speter case GT: case GTU: 758618334Speter case LT: case LTU: 758718334Speter case GE: case GEU: 758818334Speter case LE: case LEU: 758918334Speter 759018334Speter /* If this produces an integer result, we know which bits are set. 759118334Speter Code here used to clear bits outside the mode of X, but that is 759218334Speter now done above. */ 759318334Speter 759418334Speter if (GET_MODE_CLASS (mode) == MODE_INT 759518334Speter && mode_width <= HOST_BITS_PER_WIDE_INT) 759618334Speter nonzero = STORE_FLAG_VALUE; 759718334Speter break; 759818334Speter 759918334Speter case NEG: 760050397Sobrien#if 0 760150397Sobrien /* Disabled to avoid exponential mutual recursion between nonzero_bits 760250397Sobrien and num_sign_bit_copies. */ 760318334Speter if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (x)) 760418334Speter == GET_MODE_BITSIZE (GET_MODE (x))) 760518334Speter nonzero = 1; 760650397Sobrien#endif 760718334Speter 760818334Speter if (GET_MODE_SIZE (GET_MODE (x)) < mode_width) 760918334Speter nonzero |= (GET_MODE_MASK (mode) & ~ GET_MODE_MASK (GET_MODE (x))); 761018334Speter break; 761118334Speter 761218334Speter case ABS: 761350397Sobrien#if 0 761450397Sobrien /* Disabled to avoid exponential mutual recursion between nonzero_bits 761550397Sobrien and num_sign_bit_copies. */ 761618334Speter if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (x)) 761718334Speter == GET_MODE_BITSIZE (GET_MODE (x))) 761818334Speter nonzero = 1; 761950397Sobrien#endif 762018334Speter break; 762118334Speter 762218334Speter case TRUNCATE: 762318334Speter nonzero &= (nonzero_bits (XEXP (x, 0), mode) & GET_MODE_MASK (mode)); 762418334Speter break; 762518334Speter 762618334Speter case ZERO_EXTEND: 762718334Speter nonzero &= nonzero_bits (XEXP (x, 0), mode); 762818334Speter if (GET_MODE (XEXP (x, 0)) != VOIDmode) 762918334Speter nonzero &= GET_MODE_MASK (GET_MODE (XEXP (x, 0))); 763018334Speter break; 763118334Speter 763218334Speter case SIGN_EXTEND: 763318334Speter /* If the sign bit is known clear, this is the same as ZERO_EXTEND. 763418334Speter Otherwise, show all the bits in the outer mode but not the inner 763518334Speter may be non-zero. */ 763618334Speter inner_nz = nonzero_bits (XEXP (x, 0), mode); 763718334Speter if (GET_MODE (XEXP (x, 0)) != VOIDmode) 763818334Speter { 763918334Speter inner_nz &= GET_MODE_MASK (GET_MODE (XEXP (x, 0))); 764050397Sobrien if (inner_nz 764150397Sobrien & (((HOST_WIDE_INT) 1 764250397Sobrien << (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - 1)))) 764318334Speter inner_nz |= (GET_MODE_MASK (mode) 764418334Speter & ~ GET_MODE_MASK (GET_MODE (XEXP (x, 0)))); 764518334Speter } 764618334Speter 764718334Speter nonzero &= inner_nz; 764818334Speter break; 764918334Speter 765018334Speter case AND: 765118334Speter nonzero &= (nonzero_bits (XEXP (x, 0), mode) 765218334Speter & nonzero_bits (XEXP (x, 1), mode)); 765318334Speter break; 765418334Speter 765518334Speter case XOR: case IOR: 765618334Speter case UMIN: case UMAX: case SMIN: case SMAX: 765718334Speter nonzero &= (nonzero_bits (XEXP (x, 0), mode) 765818334Speter | nonzero_bits (XEXP (x, 1), mode)); 765918334Speter break; 766018334Speter 766118334Speter case PLUS: case MINUS: 766218334Speter case MULT: 766318334Speter case DIV: case UDIV: 766418334Speter case MOD: case UMOD: 766518334Speter /* We can apply the rules of arithmetic to compute the number of 766618334Speter high- and low-order zero bits of these operations. We start by 766718334Speter computing the width (position of the highest-order non-zero bit) 766818334Speter and the number of low-order zero bits for each value. */ 766918334Speter { 767018334Speter unsigned HOST_WIDE_INT nz0 = nonzero_bits (XEXP (x, 0), mode); 767118334Speter unsigned HOST_WIDE_INT nz1 = nonzero_bits (XEXP (x, 1), mode); 767218334Speter int width0 = floor_log2 (nz0) + 1; 767318334Speter int width1 = floor_log2 (nz1) + 1; 767418334Speter int low0 = floor_log2 (nz0 & -nz0); 767518334Speter int low1 = floor_log2 (nz1 & -nz1); 767618334Speter HOST_WIDE_INT op0_maybe_minusp 767718334Speter = (nz0 & ((HOST_WIDE_INT) 1 << (mode_width - 1))); 767818334Speter HOST_WIDE_INT op1_maybe_minusp 767918334Speter = (nz1 & ((HOST_WIDE_INT) 1 << (mode_width - 1))); 768018334Speter int result_width = mode_width; 768118334Speter int result_low = 0; 768218334Speter 768318334Speter switch (code) 768418334Speter { 768518334Speter case PLUS: 768650397Sobrien#ifdef STACK_BIAS 768750397Sobrien if (STACK_BIAS 768850397Sobrien && (XEXP (x, 0) == stack_pointer_rtx 768950397Sobrien || XEXP (x, 0) == frame_pointer_rtx) 769050397Sobrien && GET_CODE (XEXP (x, 1)) == CONST_INT) 769150397Sobrien { 769250397Sobrien int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT; 769350397Sobrien 769450397Sobrien nz0 = (GET_MODE_MASK (mode) & ~ (sp_alignment - 1)); 769550397Sobrien nz1 = INTVAL (XEXP (x, 1)) - STACK_BIAS; 769650397Sobrien width0 = floor_log2 (nz0) + 1; 769750397Sobrien width1 = floor_log2 (nz1) + 1; 769850397Sobrien low0 = floor_log2 (nz0 & -nz0); 769950397Sobrien low1 = floor_log2 (nz1 & -nz1); 770050397Sobrien } 770150397Sobrien#endif 770218334Speter result_width = MAX (width0, width1) + 1; 770318334Speter result_low = MIN (low0, low1); 770418334Speter break; 770518334Speter case MINUS: 770618334Speter result_low = MIN (low0, low1); 770718334Speter break; 770818334Speter case MULT: 770918334Speter result_width = width0 + width1; 771018334Speter result_low = low0 + low1; 771118334Speter break; 771218334Speter case DIV: 771318334Speter if (! op0_maybe_minusp && ! op1_maybe_minusp) 771418334Speter result_width = width0; 771518334Speter break; 771618334Speter case UDIV: 771718334Speter result_width = width0; 771818334Speter break; 771918334Speter case MOD: 772018334Speter if (! op0_maybe_minusp && ! op1_maybe_minusp) 772118334Speter result_width = MIN (width0, width1); 772218334Speter result_low = MIN (low0, low1); 772318334Speter break; 772418334Speter case UMOD: 772518334Speter result_width = MIN (width0, width1); 772618334Speter result_low = MIN (low0, low1); 772718334Speter break; 772850397Sobrien default: 772950397Sobrien abort (); 773018334Speter } 773118334Speter 773218334Speter if (result_width < mode_width) 773318334Speter nonzero &= ((HOST_WIDE_INT) 1 << result_width) - 1; 773418334Speter 773518334Speter if (result_low > 0) 773618334Speter nonzero &= ~ (((HOST_WIDE_INT) 1 << result_low) - 1); 773718334Speter } 773818334Speter break; 773918334Speter 774018334Speter case ZERO_EXTRACT: 774118334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 774218334Speter && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT) 774318334Speter nonzero &= ((HOST_WIDE_INT) 1 << INTVAL (XEXP (x, 1))) - 1; 774418334Speter break; 774518334Speter 774618334Speter case SUBREG: 774718334Speter /* If this is a SUBREG formed for a promoted variable that has 774818334Speter been zero-extended, we know that at least the high-order bits 774918334Speter are zero, though others might be too. */ 775018334Speter 775118334Speter if (SUBREG_PROMOTED_VAR_P (x) && SUBREG_PROMOTED_UNSIGNED_P (x)) 775218334Speter nonzero = (GET_MODE_MASK (GET_MODE (x)) 775318334Speter & nonzero_bits (SUBREG_REG (x), GET_MODE (x))); 775418334Speter 775518334Speter /* If the inner mode is a single word for both the host and target 775618334Speter machines, we can compute this from which bits of the inner 775718334Speter object might be nonzero. */ 775818334Speter if (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) <= BITS_PER_WORD 775918334Speter && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) 776018334Speter <= HOST_BITS_PER_WIDE_INT)) 776118334Speter { 776218334Speter nonzero &= nonzero_bits (SUBREG_REG (x), mode); 776318334Speter 776450397Sobrien#if defined (WORD_REGISTER_OPERATIONS) && defined (LOAD_EXTEND_OP) 776550397Sobrien /* If this is a typical RISC machine, we only have to worry 776650397Sobrien about the way loads are extended. */ 776750397Sobrien if (LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND 776850397Sobrien ? (nonzero 776950397Sobrien & (1L << (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) - 1))) 777050397Sobrien : LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) != ZERO_EXTEND) 777118334Speter#endif 777250397Sobrien { 777350397Sobrien /* On many CISC machines, accessing an object in a wider mode 777450397Sobrien causes the high-order bits to become undefined. So they are 777550397Sobrien not known to be zero. */ 777650397Sobrien if (GET_MODE_SIZE (GET_MODE (x)) 777750397Sobrien > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) 777850397Sobrien nonzero |= (GET_MODE_MASK (GET_MODE (x)) 777950397Sobrien & ~ GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))); 778050397Sobrien } 778118334Speter } 778218334Speter break; 778318334Speter 778418334Speter case ASHIFTRT: 778518334Speter case LSHIFTRT: 778618334Speter case ASHIFT: 778718334Speter case ROTATE: 778818334Speter /* The nonzero bits are in two classes: any bits within MODE 778918334Speter that aren't in GET_MODE (x) are always significant. The rest of the 779018334Speter nonzero bits are those that are significant in the operand of 779118334Speter the shift when shifted the appropriate number of bits. This 779218334Speter shows that high-order bits are cleared by the right shift and 779318334Speter low-order bits by left shifts. */ 779418334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 779518334Speter && INTVAL (XEXP (x, 1)) >= 0 779618334Speter && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT) 779718334Speter { 779818334Speter enum machine_mode inner_mode = GET_MODE (x); 779918334Speter int width = GET_MODE_BITSIZE (inner_mode); 780018334Speter int count = INTVAL (XEXP (x, 1)); 780118334Speter unsigned HOST_WIDE_INT mode_mask = GET_MODE_MASK (inner_mode); 780218334Speter unsigned HOST_WIDE_INT op_nonzero = nonzero_bits (XEXP (x, 0), mode); 780318334Speter unsigned HOST_WIDE_INT inner = op_nonzero & mode_mask; 780418334Speter unsigned HOST_WIDE_INT outer = 0; 780518334Speter 780618334Speter if (mode_width > width) 780718334Speter outer = (op_nonzero & nonzero & ~ mode_mask); 780818334Speter 780918334Speter if (code == LSHIFTRT) 781018334Speter inner >>= count; 781118334Speter else if (code == ASHIFTRT) 781218334Speter { 781318334Speter inner >>= count; 781418334Speter 781518334Speter /* If the sign bit may have been nonzero before the shift, we 781618334Speter need to mark all the places it could have been copied to 781718334Speter by the shift as possibly nonzero. */ 781818334Speter if (inner & ((HOST_WIDE_INT) 1 << (width - 1 - count))) 781918334Speter inner |= (((HOST_WIDE_INT) 1 << count) - 1) << (width - count); 782018334Speter } 782118334Speter else if (code == ASHIFT) 782218334Speter inner <<= count; 782318334Speter else 782418334Speter inner = ((inner << (count % width) 782518334Speter | (inner >> (width - (count % width)))) & mode_mask); 782618334Speter 782718334Speter nonzero &= (outer | inner); 782818334Speter } 782918334Speter break; 783018334Speter 783118334Speter case FFS: 783218334Speter /* This is at most the number of bits in the mode. */ 783318334Speter nonzero = ((HOST_WIDE_INT) 1 << (floor_log2 (mode_width) + 1)) - 1; 783418334Speter break; 783518334Speter 783618334Speter case IF_THEN_ELSE: 783718334Speter nonzero &= (nonzero_bits (XEXP (x, 1), mode) 783818334Speter | nonzero_bits (XEXP (x, 2), mode)); 783918334Speter break; 784050397Sobrien 784150397Sobrien default: 784250397Sobrien break; 784318334Speter } 784418334Speter 784518334Speter return nonzero; 784618334Speter} 784750397Sobrien 784850397Sobrien/* See the macro definition above. */ 784950397Sobrien#undef num_sign_bit_copies 785018334Speter 785118334Speter/* Return the number of bits at the high-order end of X that are known to 785218334Speter be equal to the sign bit. X will be used in mode MODE; if MODE is 785318334Speter VOIDmode, X will be used in its own mode. The returned value will always 785418334Speter be between 1 and the number of bits in MODE. */ 785518334Speter 785618334Speterstatic int 785718334Speternum_sign_bit_copies (x, mode) 785818334Speter rtx x; 785918334Speter enum machine_mode mode; 786018334Speter{ 786118334Speter enum rtx_code code = GET_CODE (x); 786218334Speter int bitwidth; 786318334Speter int num0, num1, result; 786418334Speter unsigned HOST_WIDE_INT nonzero; 786518334Speter rtx tem; 786618334Speter 786718334Speter /* If we weren't given a mode, use the mode of X. If the mode is still 786818334Speter VOIDmode, we don't know anything. Likewise if one of the modes is 786918334Speter floating-point. */ 787018334Speter 787118334Speter if (mode == VOIDmode) 787218334Speter mode = GET_MODE (x); 787318334Speter 787418334Speter if (mode == VOIDmode || FLOAT_MODE_P (mode) || FLOAT_MODE_P (GET_MODE (x))) 787518334Speter return 1; 787618334Speter 787718334Speter bitwidth = GET_MODE_BITSIZE (mode); 787818334Speter 787950397Sobrien /* For a smaller object, just ignore the high bits. */ 788018334Speter if (bitwidth < GET_MODE_BITSIZE (GET_MODE (x))) 788118334Speter return MAX (1, (num_sign_bit_copies (x, GET_MODE (x)) 788218334Speter - (GET_MODE_BITSIZE (GET_MODE (x)) - bitwidth))); 788318334Speter 788450397Sobrien if (GET_MODE (x) != VOIDmode && bitwidth > GET_MODE_BITSIZE (GET_MODE (x))) 788550397Sobrien { 788618334Speter#ifndef WORD_REGISTER_OPERATIONS 788718334Speter /* If this machine does not do all register operations on the entire 788818334Speter register and MODE is wider than the mode of X, we can say nothing 788918334Speter at all about the high-order bits. */ 789050397Sobrien return 1; 789150397Sobrien#else 789250397Sobrien /* Likewise on machines that do, if the mode of the object is smaller 789350397Sobrien than a word and loads of that size don't sign extend, we can say 789450397Sobrien nothing about the high order bits. */ 789550397Sobrien if (GET_MODE_BITSIZE (GET_MODE (x)) < BITS_PER_WORD 789650397Sobrien#ifdef LOAD_EXTEND_OP 789750397Sobrien && LOAD_EXTEND_OP (GET_MODE (x)) != SIGN_EXTEND 789818334Speter#endif 789950397Sobrien ) 790050397Sobrien return 1; 790150397Sobrien#endif 790250397Sobrien } 790318334Speter 790418334Speter switch (code) 790518334Speter { 790618334Speter case REG: 790718334Speter 790818334Speter#ifdef POINTERS_EXTEND_UNSIGNED 790918334Speter /* If pointers extend signed and this is a pointer in Pmode, say that 791018334Speter all the bits above ptr_mode are known to be sign bit copies. */ 791118334Speter if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode && mode == Pmode 791218334Speter && REGNO_POINTER_FLAG (REGNO (x))) 791318334Speter return GET_MODE_BITSIZE (Pmode) - GET_MODE_BITSIZE (ptr_mode) + 1; 791418334Speter#endif 791518334Speter 791618334Speter if (reg_last_set_value[REGNO (x)] != 0 791718334Speter && reg_last_set_mode[REGNO (x)] == mode 791850397Sobrien && (REG_N_SETS (REGNO (x)) == 1 791918334Speter || reg_last_set_label[REGNO (x)] == label_tick) 792018334Speter && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid) 792118334Speter return reg_last_set_sign_bit_copies[REGNO (x)]; 792218334Speter 792318334Speter tem = get_last_value (x); 792418334Speter if (tem != 0) 792518334Speter return num_sign_bit_copies (tem, mode); 792618334Speter 792718334Speter if (nonzero_sign_valid && reg_sign_bit_copies[REGNO (x)] != 0) 792818334Speter return reg_sign_bit_copies[REGNO (x)]; 792918334Speter break; 793018334Speter 793118334Speter case MEM: 793218334Speter#ifdef LOAD_EXTEND_OP 793318334Speter /* Some RISC machines sign-extend all loads of smaller than a word. */ 793418334Speter if (LOAD_EXTEND_OP (GET_MODE (x)) == SIGN_EXTEND) 793518334Speter return MAX (1, bitwidth - GET_MODE_BITSIZE (GET_MODE (x)) + 1); 793618334Speter#endif 793718334Speter break; 793818334Speter 793918334Speter case CONST_INT: 794018334Speter /* If the constant is negative, take its 1's complement and remask. 794118334Speter Then see how many zero bits we have. */ 794218334Speter nonzero = INTVAL (x) & GET_MODE_MASK (mode); 794318334Speter if (bitwidth <= HOST_BITS_PER_WIDE_INT 794418334Speter && (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) 794518334Speter nonzero = (~ nonzero) & GET_MODE_MASK (mode); 794618334Speter 794718334Speter return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1); 794818334Speter 794918334Speter case SUBREG: 795018334Speter /* If this is a SUBREG for a promoted object that is sign-extended 795118334Speter and we are looking at it in a wider mode, we know that at least the 795218334Speter high-order bits are known to be sign bit copies. */ 795318334Speter 795418334Speter if (SUBREG_PROMOTED_VAR_P (x) && ! SUBREG_PROMOTED_UNSIGNED_P (x)) 795518334Speter return MAX (bitwidth - GET_MODE_BITSIZE (GET_MODE (x)) + 1, 795618334Speter num_sign_bit_copies (SUBREG_REG (x), mode)); 795718334Speter 795850397Sobrien /* For a smaller object, just ignore the high bits. */ 795918334Speter if (bitwidth <= GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))) 796018334Speter { 796118334Speter num0 = num_sign_bit_copies (SUBREG_REG (x), VOIDmode); 796218334Speter return MAX (1, (num0 796318334Speter - (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) 796418334Speter - bitwidth))); 796518334Speter } 796618334Speter 796718334Speter#ifdef WORD_REGISTER_OPERATIONS 796818334Speter#ifdef LOAD_EXTEND_OP 796918334Speter /* For paradoxical SUBREGs on machines where all register operations 797018334Speter affect the entire register, just look inside. Note that we are 797118334Speter passing MODE to the recursive call, so the number of sign bit copies 797218334Speter will remain relative to that mode, not the inner mode. */ 797318334Speter 797418334Speter /* This works only if loads sign extend. Otherwise, if we get a 797518334Speter reload for the inner part, it may be loaded from the stack, and 797618334Speter then we lose all sign bit copies that existed before the store 797718334Speter to the stack. */ 797818334Speter 797918334Speter if ((GET_MODE_SIZE (GET_MODE (x)) 798018334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) 798118334Speter && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND) 798218334Speter return num_sign_bit_copies (SUBREG_REG (x), mode); 798318334Speter#endif 798418334Speter#endif 798518334Speter break; 798618334Speter 798718334Speter case SIGN_EXTRACT: 798818334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT) 798918334Speter return MAX (1, bitwidth - INTVAL (XEXP (x, 1))); 799018334Speter break; 799118334Speter 799218334Speter case SIGN_EXTEND: 799318334Speter return (bitwidth - GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) 799418334Speter + num_sign_bit_copies (XEXP (x, 0), VOIDmode)); 799518334Speter 799618334Speter case TRUNCATE: 799750397Sobrien /* For a smaller object, just ignore the high bits. */ 799818334Speter num0 = num_sign_bit_copies (XEXP (x, 0), VOIDmode); 799918334Speter return MAX (1, (num0 - (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) 800018334Speter - bitwidth))); 800118334Speter 800218334Speter case NOT: 800318334Speter return num_sign_bit_copies (XEXP (x, 0), mode); 800418334Speter 800518334Speter case ROTATE: case ROTATERT: 800618334Speter /* If we are rotating left by a number of bits less than the number 800718334Speter of sign bit copies, we can just subtract that amount from the 800818334Speter number. */ 800918334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 801018334Speter && INTVAL (XEXP (x, 1)) >= 0 && INTVAL (XEXP (x, 1)) < bitwidth) 801118334Speter { 801218334Speter num0 = num_sign_bit_copies (XEXP (x, 0), mode); 801318334Speter return MAX (1, num0 - (code == ROTATE ? INTVAL (XEXP (x, 1)) 801418334Speter : bitwidth - INTVAL (XEXP (x, 1)))); 801518334Speter } 801618334Speter break; 801718334Speter 801818334Speter case NEG: 801918334Speter /* In general, this subtracts one sign bit copy. But if the value 802018334Speter is known to be positive, the number of sign bit copies is the 802118334Speter same as that of the input. Finally, if the input has just one bit 802218334Speter that might be nonzero, all the bits are copies of the sign bit. */ 802350397Sobrien num0 = num_sign_bit_copies (XEXP (x, 0), mode); 802450397Sobrien if (bitwidth > HOST_BITS_PER_WIDE_INT) 802550397Sobrien return num0 > 1 ? num0 - 1 : 1; 802650397Sobrien 802718334Speter nonzero = nonzero_bits (XEXP (x, 0), mode); 802818334Speter if (nonzero == 1) 802918334Speter return bitwidth; 803018334Speter 803118334Speter if (num0 > 1 803218334Speter && (((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero)) 803318334Speter num0--; 803418334Speter 803518334Speter return num0; 803618334Speter 803718334Speter case IOR: case AND: case XOR: 803818334Speter case SMIN: case SMAX: case UMIN: case UMAX: 803918334Speter /* Logical operations will preserve the number of sign-bit copies. 804018334Speter MIN and MAX operations always return one of the operands. */ 804118334Speter num0 = num_sign_bit_copies (XEXP (x, 0), mode); 804218334Speter num1 = num_sign_bit_copies (XEXP (x, 1), mode); 804318334Speter return MIN (num0, num1); 804418334Speter 804518334Speter case PLUS: case MINUS: 804618334Speter /* For addition and subtraction, we can have a 1-bit carry. However, 804718334Speter if we are subtracting 1 from a positive number, there will not 804818334Speter be such a carry. Furthermore, if the positive number is known to 804918334Speter be 0 or 1, we know the result is either -1 or 0. */ 805018334Speter 805118334Speter if (code == PLUS && XEXP (x, 1) == constm1_rtx 805218334Speter && bitwidth <= HOST_BITS_PER_WIDE_INT) 805318334Speter { 805418334Speter nonzero = nonzero_bits (XEXP (x, 0), mode); 805518334Speter if ((((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero) == 0) 805618334Speter return (nonzero == 1 || nonzero == 0 ? bitwidth 805718334Speter : bitwidth - floor_log2 (nonzero) - 1); 805818334Speter } 805918334Speter 806018334Speter num0 = num_sign_bit_copies (XEXP (x, 0), mode); 806118334Speter num1 = num_sign_bit_copies (XEXP (x, 1), mode); 806218334Speter return MAX (1, MIN (num0, num1) - 1); 806318334Speter 806418334Speter case MULT: 806518334Speter /* The number of bits of the product is the sum of the number of 806618334Speter bits of both terms. However, unless one of the terms if known 806718334Speter to be positive, we must allow for an additional bit since negating 806818334Speter a negative number can remove one sign bit copy. */ 806918334Speter 807018334Speter num0 = num_sign_bit_copies (XEXP (x, 0), mode); 807118334Speter num1 = num_sign_bit_copies (XEXP (x, 1), mode); 807218334Speter 807318334Speter result = bitwidth - (bitwidth - num0) - (bitwidth - num1); 807418334Speter if (result > 0 807550397Sobrien && (bitwidth > HOST_BITS_PER_WIDE_INT 807650397Sobrien || (((nonzero_bits (XEXP (x, 0), mode) 807750397Sobrien & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) 807850397Sobrien && ((nonzero_bits (XEXP (x, 1), mode) 807950397Sobrien & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)))) 808018334Speter result--; 808118334Speter 808218334Speter return MAX (1, result); 808318334Speter 808418334Speter case UDIV: 808550397Sobrien /* The result must be <= the first operand. If the first operand 808650397Sobrien has the high bit set, we know nothing about the number of sign 808750397Sobrien bit copies. */ 808850397Sobrien if (bitwidth > HOST_BITS_PER_WIDE_INT) 808950397Sobrien return 1; 809050397Sobrien else if ((nonzero_bits (XEXP (x, 0), mode) 809150397Sobrien & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) 809250397Sobrien return 1; 809350397Sobrien else 809450397Sobrien return num_sign_bit_copies (XEXP (x, 0), mode); 809550397Sobrien 809618334Speter case UMOD: 809718334Speter /* The result must be <= the scond operand. */ 809818334Speter return num_sign_bit_copies (XEXP (x, 1), mode); 809918334Speter 810018334Speter case DIV: 810118334Speter /* Similar to unsigned division, except that we have to worry about 810218334Speter the case where the divisor is negative, in which case we have 810318334Speter to add 1. */ 810418334Speter result = num_sign_bit_copies (XEXP (x, 0), mode); 810518334Speter if (result > 1 810650397Sobrien && (bitwidth > HOST_BITS_PER_WIDE_INT 810750397Sobrien || (nonzero_bits (XEXP (x, 1), mode) 810850397Sobrien & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)) 810950397Sobrien result--; 811018334Speter 811118334Speter return result; 811218334Speter 811318334Speter case MOD: 811418334Speter result = num_sign_bit_copies (XEXP (x, 1), mode); 811518334Speter if (result > 1 811650397Sobrien && (bitwidth > HOST_BITS_PER_WIDE_INT 811750397Sobrien || (nonzero_bits (XEXP (x, 1), mode) 811850397Sobrien & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)) 811950397Sobrien result--; 812018334Speter 812118334Speter return result; 812218334Speter 812318334Speter case ASHIFTRT: 812418334Speter /* Shifts by a constant add to the number of bits equal to the 812518334Speter sign bit. */ 812618334Speter num0 = num_sign_bit_copies (XEXP (x, 0), mode); 812718334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 812818334Speter && INTVAL (XEXP (x, 1)) > 0) 812918334Speter num0 = MIN (bitwidth, num0 + INTVAL (XEXP (x, 1))); 813018334Speter 813118334Speter return num0; 813218334Speter 813318334Speter case ASHIFT: 813418334Speter /* Left shifts destroy copies. */ 813518334Speter if (GET_CODE (XEXP (x, 1)) != CONST_INT 813618334Speter || INTVAL (XEXP (x, 1)) < 0 813718334Speter || INTVAL (XEXP (x, 1)) >= bitwidth) 813818334Speter return 1; 813918334Speter 814018334Speter num0 = num_sign_bit_copies (XEXP (x, 0), mode); 814118334Speter return MAX (1, num0 - INTVAL (XEXP (x, 1))); 814218334Speter 814318334Speter case IF_THEN_ELSE: 814418334Speter num0 = num_sign_bit_copies (XEXP (x, 1), mode); 814518334Speter num1 = num_sign_bit_copies (XEXP (x, 2), mode); 814618334Speter return MIN (num0, num1); 814718334Speter 814818334Speter case EQ: case NE: case GE: case GT: case LE: case LT: 814918334Speter case GEU: case GTU: case LEU: case LTU: 815050397Sobrien if (STORE_FLAG_VALUE == -1) 815150397Sobrien return bitwidth; 815250397Sobrien break; 815350397Sobrien 815450397Sobrien default: 815550397Sobrien break; 815618334Speter } 815718334Speter 815818334Speter /* If we haven't been able to figure it out by one of the above rules, 815918334Speter see if some of the high-order bits are known to be zero. If so, 816018334Speter count those bits and return one less than that amount. If we can't 816118334Speter safely compute the mask for this mode, always return BITWIDTH. */ 816218334Speter 816318334Speter if (bitwidth > HOST_BITS_PER_WIDE_INT) 816418334Speter return 1; 816518334Speter 816618334Speter nonzero = nonzero_bits (x, mode); 816718334Speter return (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1)) 816818334Speter ? 1 : bitwidth - floor_log2 (nonzero) - 1); 816918334Speter} 817018334Speter 817118334Speter/* Return the number of "extended" bits there are in X, when interpreted 817218334Speter as a quantity in MODE whose signedness is indicated by UNSIGNEDP. For 817318334Speter unsigned quantities, this is the number of high-order zero bits. 817418334Speter For signed quantities, this is the number of copies of the sign bit 817518334Speter minus 1. In both case, this function returns the number of "spare" 817618334Speter bits. For example, if two quantities for which this function returns 817718334Speter at least 1 are added, the addition is known not to overflow. 817818334Speter 817918334Speter This function will always return 0 unless called during combine, which 818018334Speter implies that it must be called from a define_split. */ 818118334Speter 818218334Speterint 818318334Speterextended_count (x, mode, unsignedp) 818418334Speter rtx x; 818518334Speter enum machine_mode mode; 818618334Speter int unsignedp; 818718334Speter{ 818818334Speter if (nonzero_sign_valid == 0) 818918334Speter return 0; 819018334Speter 819118334Speter return (unsignedp 819218334Speter ? (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 819318334Speter && (GET_MODE_BITSIZE (mode) - 1 819418334Speter - floor_log2 (nonzero_bits (x, mode)))) 819518334Speter : num_sign_bit_copies (x, mode) - 1); 819618334Speter} 819718334Speter 819818334Speter/* This function is called from `simplify_shift_const' to merge two 819918334Speter outer operations. Specifically, we have already found that we need 820018334Speter to perform operation *POP0 with constant *PCONST0 at the outermost 820118334Speter position. We would now like to also perform OP1 with constant CONST1 820218334Speter (with *POP0 being done last). 820318334Speter 820418334Speter Return 1 if we can do the operation and update *POP0 and *PCONST0 with 820518334Speter the resulting operation. *PCOMP_P is set to 1 if we would need to 820618334Speter complement the innermost operand, otherwise it is unchanged. 820718334Speter 820818334Speter MODE is the mode in which the operation will be done. No bits outside 820918334Speter the width of this mode matter. It is assumed that the width of this mode 821018334Speter is smaller than or equal to HOST_BITS_PER_WIDE_INT. 821118334Speter 821218334Speter If *POP0 or OP1 are NIL, it means no operation is required. Only NEG, PLUS, 821318334Speter IOR, XOR, and AND are supported. We may set *POP0 to SET if the proper 821418334Speter result is simply *PCONST0. 821518334Speter 821618334Speter If the resulting operation cannot be expressed as one operation, we 821718334Speter return 0 and do not change *POP0, *PCONST0, and *PCOMP_P. */ 821818334Speter 821918334Speterstatic int 822018334Spetermerge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p) 822118334Speter enum rtx_code *pop0; 822218334Speter HOST_WIDE_INT *pconst0; 822318334Speter enum rtx_code op1; 822418334Speter HOST_WIDE_INT const1; 822518334Speter enum machine_mode mode; 822618334Speter int *pcomp_p; 822718334Speter{ 822818334Speter enum rtx_code op0 = *pop0; 822918334Speter HOST_WIDE_INT const0 = *pconst0; 823018334Speter int width = GET_MODE_BITSIZE (mode); 823118334Speter 823218334Speter const0 &= GET_MODE_MASK (mode); 823318334Speter const1 &= GET_MODE_MASK (mode); 823418334Speter 823518334Speter /* If OP0 is an AND, clear unimportant bits in CONST1. */ 823618334Speter if (op0 == AND) 823718334Speter const1 &= const0; 823818334Speter 823918334Speter /* If OP0 or OP1 is NIL, this is easy. Similarly if they are the same or 824018334Speter if OP0 is SET. */ 824118334Speter 824218334Speter if (op1 == NIL || op0 == SET) 824318334Speter return 1; 824418334Speter 824518334Speter else if (op0 == NIL) 824618334Speter op0 = op1, const0 = const1; 824718334Speter 824818334Speter else if (op0 == op1) 824918334Speter { 825018334Speter switch (op0) 825118334Speter { 825218334Speter case AND: 825318334Speter const0 &= const1; 825418334Speter break; 825518334Speter case IOR: 825618334Speter const0 |= const1; 825718334Speter break; 825818334Speter case XOR: 825918334Speter const0 ^= const1; 826018334Speter break; 826118334Speter case PLUS: 826218334Speter const0 += const1; 826318334Speter break; 826418334Speter case NEG: 826518334Speter op0 = NIL; 826618334Speter break; 826750397Sobrien default: 826850397Sobrien break; 826918334Speter } 827018334Speter } 827118334Speter 827218334Speter /* Otherwise, if either is a PLUS or NEG, we can't do anything. */ 827318334Speter else if (op0 == PLUS || op1 == PLUS || op0 == NEG || op1 == NEG) 827418334Speter return 0; 827518334Speter 827618334Speter /* If the two constants aren't the same, we can't do anything. The 827718334Speter remaining six cases can all be done. */ 827818334Speter else if (const0 != const1) 827918334Speter return 0; 828018334Speter 828118334Speter else 828218334Speter switch (op0) 828318334Speter { 828418334Speter case IOR: 828518334Speter if (op1 == AND) 828618334Speter /* (a & b) | b == b */ 828718334Speter op0 = SET; 828818334Speter else /* op1 == XOR */ 828918334Speter /* (a ^ b) | b == a | b */ 829050397Sobrien {;} 829118334Speter break; 829218334Speter 829318334Speter case XOR: 829418334Speter if (op1 == AND) 829518334Speter /* (a & b) ^ b == (~a) & b */ 829618334Speter op0 = AND, *pcomp_p = 1; 829718334Speter else /* op1 == IOR */ 829818334Speter /* (a | b) ^ b == a & ~b */ 829918334Speter op0 = AND, *pconst0 = ~ const0; 830018334Speter break; 830118334Speter 830218334Speter case AND: 830318334Speter if (op1 == IOR) 830418334Speter /* (a | b) & b == b */ 830518334Speter op0 = SET; 830618334Speter else /* op1 == XOR */ 830718334Speter /* (a ^ b) & b) == (~a) & b */ 830818334Speter *pcomp_p = 1; 830918334Speter break; 831050397Sobrien default: 831150397Sobrien break; 831218334Speter } 831318334Speter 831418334Speter /* Check for NO-OP cases. */ 831518334Speter const0 &= GET_MODE_MASK (mode); 831618334Speter if (const0 == 0 831718334Speter && (op0 == IOR || op0 == XOR || op0 == PLUS)) 831818334Speter op0 = NIL; 831918334Speter else if (const0 == 0 && op0 == AND) 832018334Speter op0 = SET; 832152284Sobrien else if ((unsigned HOST_WIDE_INT) const0 == GET_MODE_MASK (mode) 832252284Sobrien && op0 == AND) 832318334Speter op0 = NIL; 832418334Speter 832518334Speter /* If this would be an entire word for the target, but is not for 832618334Speter the host, then sign-extend on the host so that the number will look 832718334Speter the same way on the host that it would on the target. 832818334Speter 832918334Speter For example, when building a 64 bit alpha hosted 32 bit sparc 833018334Speter targeted compiler, then we want the 32 bit unsigned value -1 to be 833118334Speter represented as a 64 bit value -1, and not as 0x00000000ffffffff. 833218334Speter The later confuses the sparc backend. */ 833318334Speter 833418334Speter if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width 833518334Speter && (const0 & ((HOST_WIDE_INT) 1 << (width - 1)))) 833618334Speter const0 |= ((HOST_WIDE_INT) (-1) << width); 833718334Speter 833818334Speter *pop0 = op0; 833918334Speter *pconst0 = const0; 834018334Speter 834118334Speter return 1; 834218334Speter} 834318334Speter 834418334Speter/* Simplify a shift of VAROP by COUNT bits. CODE says what kind of shift. 834518334Speter The result of the shift is RESULT_MODE. X, if non-zero, is an expression 834618334Speter that we started with. 834718334Speter 834818334Speter The shift is normally computed in the widest mode we find in VAROP, as 834918334Speter long as it isn't a different number of words than RESULT_MODE. Exceptions 835018334Speter are ASHIFTRT and ROTATE, which are always done in their original mode, */ 835118334Speter 835218334Speterstatic rtx 835318334Spetersimplify_shift_const (x, code, result_mode, varop, count) 835418334Speter rtx x; 835518334Speter enum rtx_code code; 835618334Speter enum machine_mode result_mode; 835718334Speter rtx varop; 835818334Speter int count; 835918334Speter{ 836018334Speter enum rtx_code orig_code = code; 836118334Speter int orig_count = count; 836218334Speter enum machine_mode mode = result_mode; 836318334Speter enum machine_mode shift_mode, tmode; 836418334Speter int mode_words 836518334Speter = (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD; 836618334Speter /* We form (outer_op (code varop count) (outer_const)). */ 836718334Speter enum rtx_code outer_op = NIL; 836818334Speter HOST_WIDE_INT outer_const = 0; 836918334Speter rtx const_rtx; 837018334Speter int complement_p = 0; 837118334Speter rtx new; 837218334Speter 837318334Speter /* If we were given an invalid count, don't do anything except exactly 837418334Speter what was requested. */ 837518334Speter 837618334Speter if (count < 0 || count > GET_MODE_BITSIZE (mode)) 837718334Speter { 837818334Speter if (x) 837918334Speter return x; 838018334Speter 838150397Sobrien return gen_rtx_fmt_ee (code, mode, varop, GEN_INT (count)); 838218334Speter } 838318334Speter 838418334Speter /* Unless one of the branches of the `if' in this loop does a `continue', 838518334Speter we will `break' the loop after the `if'. */ 838618334Speter 838718334Speter while (count != 0) 838818334Speter { 838918334Speter /* If we have an operand of (clobber (const_int 0)), just return that 839018334Speter value. */ 839118334Speter if (GET_CODE (varop) == CLOBBER) 839218334Speter return varop; 839318334Speter 839418334Speter /* If we discovered we had to complement VAROP, leave. Making a NOT 839518334Speter here would cause an infinite loop. */ 839618334Speter if (complement_p) 839718334Speter break; 839818334Speter 839918334Speter /* Convert ROTATERT to ROTATE. */ 840018334Speter if (code == ROTATERT) 840118334Speter code = ROTATE, count = GET_MODE_BITSIZE (result_mode) - count; 840218334Speter 840318334Speter /* We need to determine what mode we will do the shift in. If the 840418334Speter shift is a right shift or a ROTATE, we must always do it in the mode 840518334Speter it was originally done in. Otherwise, we can do it in MODE, the 840650397Sobrien widest mode encountered. */ 840718334Speter shift_mode 840818334Speter = (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE 840918334Speter ? result_mode : mode); 841018334Speter 841118334Speter /* Handle cases where the count is greater than the size of the mode 841218334Speter minus 1. For ASHIFT, use the size minus one as the count (this can 841318334Speter occur when simplifying (lshiftrt (ashiftrt ..))). For rotates, 841418334Speter take the count modulo the size. For other shifts, the result is 841518334Speter zero. 841618334Speter 841718334Speter Since these shifts are being produced by the compiler by combining 841818334Speter multiple operations, each of which are defined, we know what the 841918334Speter result is supposed to be. */ 842018334Speter 842118334Speter if (count > GET_MODE_BITSIZE (shift_mode) - 1) 842218334Speter { 842318334Speter if (code == ASHIFTRT) 842418334Speter count = GET_MODE_BITSIZE (shift_mode) - 1; 842518334Speter else if (code == ROTATE || code == ROTATERT) 842618334Speter count %= GET_MODE_BITSIZE (shift_mode); 842718334Speter else 842818334Speter { 842918334Speter /* We can't simply return zero because there may be an 843018334Speter outer op. */ 843118334Speter varop = const0_rtx; 843218334Speter count = 0; 843318334Speter break; 843418334Speter } 843518334Speter } 843618334Speter 843718334Speter /* Negative counts are invalid and should not have been made (a 843818334Speter programmer-specified negative count should have been handled 843950397Sobrien above). */ 844018334Speter else if (count < 0) 844118334Speter abort (); 844218334Speter 844318334Speter /* An arithmetic right shift of a quantity known to be -1 or 0 844418334Speter is a no-op. */ 844518334Speter if (code == ASHIFTRT 844618334Speter && (num_sign_bit_copies (varop, shift_mode) 844718334Speter == GET_MODE_BITSIZE (shift_mode))) 844818334Speter { 844918334Speter count = 0; 845018334Speter break; 845118334Speter } 845218334Speter 845318334Speter /* If we are doing an arithmetic right shift and discarding all but 845418334Speter the sign bit copies, this is equivalent to doing a shift by the 845518334Speter bitsize minus one. Convert it into that shift because it will often 845618334Speter allow other simplifications. */ 845718334Speter 845818334Speter if (code == ASHIFTRT 845918334Speter && (count + num_sign_bit_copies (varop, shift_mode) 846018334Speter >= GET_MODE_BITSIZE (shift_mode))) 846118334Speter count = GET_MODE_BITSIZE (shift_mode) - 1; 846218334Speter 846318334Speter /* We simplify the tests below and elsewhere by converting 846418334Speter ASHIFTRT to LSHIFTRT if we know the sign bit is clear. 846518334Speter `make_compound_operation' will convert it to a ASHIFTRT for 846618334Speter those machines (such as Vax) that don't have a LSHIFTRT. */ 846718334Speter if (GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT 846818334Speter && code == ASHIFTRT 846918334Speter && ((nonzero_bits (varop, shift_mode) 847018334Speter & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (shift_mode) - 1))) 847118334Speter == 0)) 847218334Speter code = LSHIFTRT; 847318334Speter 847418334Speter switch (GET_CODE (varop)) 847518334Speter { 847618334Speter case SIGN_EXTEND: 847718334Speter case ZERO_EXTEND: 847818334Speter case SIGN_EXTRACT: 847918334Speter case ZERO_EXTRACT: 848018334Speter new = expand_compound_operation (varop); 848118334Speter if (new != varop) 848218334Speter { 848318334Speter varop = new; 848418334Speter continue; 848518334Speter } 848618334Speter break; 848718334Speter 848818334Speter case MEM: 848918334Speter /* If we have (xshiftrt (mem ...) C) and C is MODE_WIDTH 849018334Speter minus the width of a smaller mode, we can do this with a 849118334Speter SIGN_EXTEND or ZERO_EXTEND from the narrower memory location. */ 849218334Speter if ((code == ASHIFTRT || code == LSHIFTRT) 849318334Speter && ! mode_dependent_address_p (XEXP (varop, 0)) 849418334Speter && ! MEM_VOLATILE_P (varop) 849518334Speter && (tmode = mode_for_size (GET_MODE_BITSIZE (mode) - count, 849618334Speter MODE_INT, 1)) != BLKmode) 849718334Speter { 849818334Speter if (BYTES_BIG_ENDIAN) 849950397Sobrien new = gen_rtx_MEM (tmode, XEXP (varop, 0)); 850018334Speter else 850150397Sobrien new = gen_rtx_MEM (tmode, 850250397Sobrien plus_constant (XEXP (varop, 0), 850350397Sobrien count / BITS_PER_UNIT)); 850418334Speter RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (varop); 850552284Sobrien MEM_COPY_ATTRIBUTES (new, varop); 850618334Speter varop = gen_rtx_combine (code == ASHIFTRT ? SIGN_EXTEND 850718334Speter : ZERO_EXTEND, mode, new); 850818334Speter count = 0; 850918334Speter continue; 851018334Speter } 851118334Speter break; 851218334Speter 851318334Speter case USE: 851418334Speter /* Similar to the case above, except that we can only do this if 851518334Speter the resulting mode is the same as that of the underlying 851618334Speter MEM and adjust the address depending on the *bits* endianness 851718334Speter because of the way that bit-field extract insns are defined. */ 851818334Speter if ((code == ASHIFTRT || code == LSHIFTRT) 851918334Speter && (tmode = mode_for_size (GET_MODE_BITSIZE (mode) - count, 852018334Speter MODE_INT, 1)) != BLKmode 852118334Speter && tmode == GET_MODE (XEXP (varop, 0))) 852218334Speter { 852318334Speter if (BITS_BIG_ENDIAN) 852418334Speter new = XEXP (varop, 0); 852518334Speter else 852618334Speter { 852718334Speter new = copy_rtx (XEXP (varop, 0)); 852818334Speter SUBST (XEXP (new, 0), 852918334Speter plus_constant (XEXP (new, 0), 853018334Speter count / BITS_PER_UNIT)); 853118334Speter } 853218334Speter 853318334Speter varop = gen_rtx_combine (code == ASHIFTRT ? SIGN_EXTEND 853418334Speter : ZERO_EXTEND, mode, new); 853518334Speter count = 0; 853618334Speter continue; 853718334Speter } 853818334Speter break; 853918334Speter 854018334Speter case SUBREG: 854118334Speter /* If VAROP is a SUBREG, strip it as long as the inner operand has 854218334Speter the same number of words as what we've seen so far. Then store 854318334Speter the widest mode in MODE. */ 854418334Speter if (subreg_lowpart_p (varop) 854518334Speter && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (varop))) 854618334Speter > GET_MODE_SIZE (GET_MODE (varop))) 854718334Speter && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (varop))) 854818334Speter + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) 854918334Speter == mode_words)) 855018334Speter { 855118334Speter varop = SUBREG_REG (varop); 855218334Speter if (GET_MODE_SIZE (GET_MODE (varop)) > GET_MODE_SIZE (mode)) 855318334Speter mode = GET_MODE (varop); 855418334Speter continue; 855518334Speter } 855618334Speter break; 855718334Speter 855818334Speter case MULT: 855918334Speter /* Some machines use MULT instead of ASHIFT because MULT 856018334Speter is cheaper. But it is still better on those machines to 856118334Speter merge two shifts into one. */ 856218334Speter if (GET_CODE (XEXP (varop, 1)) == CONST_INT 856318334Speter && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0) 856418334Speter { 856518334Speter varop = gen_binary (ASHIFT, GET_MODE (varop), XEXP (varop, 0), 856618334Speter GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));; 856718334Speter continue; 856818334Speter } 856918334Speter break; 857018334Speter 857118334Speter case UDIV: 857218334Speter /* Similar, for when divides are cheaper. */ 857318334Speter if (GET_CODE (XEXP (varop, 1)) == CONST_INT 857418334Speter && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0) 857518334Speter { 857618334Speter varop = gen_binary (LSHIFTRT, GET_MODE (varop), XEXP (varop, 0), 857718334Speter GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1))))); 857818334Speter continue; 857918334Speter } 858018334Speter break; 858118334Speter 858218334Speter case ASHIFTRT: 858318334Speter /* If we are extracting just the sign bit of an arithmetic right 858418334Speter shift, that shift is not needed. */ 858518334Speter if (code == LSHIFTRT && count == GET_MODE_BITSIZE (result_mode) - 1) 858618334Speter { 858718334Speter varop = XEXP (varop, 0); 858818334Speter continue; 858918334Speter } 859018334Speter 859150397Sobrien /* ... fall through ... */ 859218334Speter 859318334Speter case LSHIFTRT: 859418334Speter case ASHIFT: 859518334Speter case ROTATE: 859618334Speter /* Here we have two nested shifts. The result is usually the 859718334Speter AND of a new shift with a mask. We compute the result below. */ 859818334Speter if (GET_CODE (XEXP (varop, 1)) == CONST_INT 859918334Speter && INTVAL (XEXP (varop, 1)) >= 0 860018334Speter && INTVAL (XEXP (varop, 1)) < GET_MODE_BITSIZE (GET_MODE (varop)) 860118334Speter && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT 860218334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) 860318334Speter { 860418334Speter enum rtx_code first_code = GET_CODE (varop); 860518334Speter int first_count = INTVAL (XEXP (varop, 1)); 860618334Speter unsigned HOST_WIDE_INT mask; 860718334Speter rtx mask_rtx; 860818334Speter 860918334Speter /* We have one common special case. We can't do any merging if 861018334Speter the inner code is an ASHIFTRT of a smaller mode. However, if 861118334Speter we have (ashift:M1 (subreg:M1 (ashiftrt:M2 FOO C1) 0) C2) 861218334Speter with C2 == GET_MODE_BITSIZE (M1) - GET_MODE_BITSIZE (M2), 861318334Speter we can convert it to 861418334Speter (ashiftrt:M1 (ashift:M1 (and:M1 (subreg:M1 FOO 0 C2) C3) C1). 861518334Speter This simplifies certain SIGN_EXTEND operations. */ 861618334Speter if (code == ASHIFT && first_code == ASHIFTRT 861718334Speter && (GET_MODE_BITSIZE (result_mode) 861818334Speter - GET_MODE_BITSIZE (GET_MODE (varop))) == count) 861918334Speter { 862018334Speter /* C3 has the low-order C1 bits zero. */ 862118334Speter 862218334Speter mask = (GET_MODE_MASK (mode) 862318334Speter & ~ (((HOST_WIDE_INT) 1 << first_count) - 1)); 862418334Speter 862518334Speter varop = simplify_and_const_int (NULL_RTX, result_mode, 862618334Speter XEXP (varop, 0), mask); 862718334Speter varop = simplify_shift_const (NULL_RTX, ASHIFT, result_mode, 862818334Speter varop, count); 862918334Speter count = first_count; 863018334Speter code = ASHIFTRT; 863118334Speter continue; 863218334Speter } 863318334Speter 863418334Speter /* If this was (ashiftrt (ashift foo C1) C2) and FOO has more 863518334Speter than C1 high-order bits equal to the sign bit, we can convert 863618334Speter this to either an ASHIFT or a ASHIFTRT depending on the 863718334Speter two counts. 863818334Speter 863918334Speter We cannot do this if VAROP's mode is not SHIFT_MODE. */ 864018334Speter 864118334Speter if (code == ASHIFTRT && first_code == ASHIFT 864218334Speter && GET_MODE (varop) == shift_mode 864318334Speter && (num_sign_bit_copies (XEXP (varop, 0), shift_mode) 864418334Speter > first_count)) 864518334Speter { 864618334Speter count -= first_count; 864718334Speter if (count < 0) 864818334Speter count = - count, code = ASHIFT; 864918334Speter varop = XEXP (varop, 0); 865018334Speter continue; 865118334Speter } 865218334Speter 865318334Speter /* There are some cases we can't do. If CODE is ASHIFTRT, 865418334Speter we can only do this if FIRST_CODE is also ASHIFTRT. 865518334Speter 865618334Speter We can't do the case when CODE is ROTATE and FIRST_CODE is 865718334Speter ASHIFTRT. 865818334Speter 865918334Speter If the mode of this shift is not the mode of the outer shift, 866018334Speter we can't do this if either shift is a right shift or ROTATE. 866118334Speter 866218334Speter Finally, we can't do any of these if the mode is too wide 866318334Speter unless the codes are the same. 866418334Speter 866518334Speter Handle the case where the shift codes are the same 866618334Speter first. */ 866718334Speter 866818334Speter if (code == first_code) 866918334Speter { 867018334Speter if (GET_MODE (varop) != result_mode 867118334Speter && (code == ASHIFTRT || code == LSHIFTRT 867218334Speter || code == ROTATE)) 867318334Speter break; 867418334Speter 867518334Speter count += first_count; 867618334Speter varop = XEXP (varop, 0); 867718334Speter continue; 867818334Speter } 867918334Speter 868018334Speter if (code == ASHIFTRT 868118334Speter || (code == ROTATE && first_code == ASHIFTRT) 868218334Speter || GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT 868318334Speter || (GET_MODE (varop) != result_mode 868418334Speter && (first_code == ASHIFTRT || first_code == LSHIFTRT 868518334Speter || first_code == ROTATE 868618334Speter || code == ROTATE))) 868718334Speter break; 868818334Speter 868918334Speter /* To compute the mask to apply after the shift, shift the 869018334Speter nonzero bits of the inner shift the same way the 869118334Speter outer shift will. */ 869218334Speter 869318334Speter mask_rtx = GEN_INT (nonzero_bits (varop, GET_MODE (varop))); 869418334Speter 869518334Speter mask_rtx 869618334Speter = simplify_binary_operation (code, result_mode, mask_rtx, 869718334Speter GEN_INT (count)); 869818334Speter 869918334Speter /* Give up if we can't compute an outer operation to use. */ 870018334Speter if (mask_rtx == 0 870118334Speter || GET_CODE (mask_rtx) != CONST_INT 870218334Speter || ! merge_outer_ops (&outer_op, &outer_const, AND, 870318334Speter INTVAL (mask_rtx), 870418334Speter result_mode, &complement_p)) 870518334Speter break; 870618334Speter 870718334Speter /* If the shifts are in the same direction, we add the 870818334Speter counts. Otherwise, we subtract them. */ 870918334Speter if ((code == ASHIFTRT || code == LSHIFTRT) 871018334Speter == (first_code == ASHIFTRT || first_code == LSHIFTRT)) 871118334Speter count += first_count; 871218334Speter else 871318334Speter count -= first_count; 871418334Speter 871518334Speter /* If COUNT is positive, the new shift is usually CODE, 871618334Speter except for the two exceptions below, in which case it is 871718334Speter FIRST_CODE. If the count is negative, FIRST_CODE should 871818334Speter always be used */ 871918334Speter if (count > 0 872018334Speter && ((first_code == ROTATE && code == ASHIFT) 872118334Speter || (first_code == ASHIFTRT && code == LSHIFTRT))) 872218334Speter code = first_code; 872318334Speter else if (count < 0) 872418334Speter code = first_code, count = - count; 872518334Speter 872618334Speter varop = XEXP (varop, 0); 872718334Speter continue; 872818334Speter } 872918334Speter 873018334Speter /* If we have (A << B << C) for any shift, we can convert this to 873118334Speter (A << C << B). This wins if A is a constant. Only try this if 873218334Speter B is not a constant. */ 873318334Speter 873418334Speter else if (GET_CODE (varop) == code 873518334Speter && GET_CODE (XEXP (varop, 1)) != CONST_INT 873618334Speter && 0 != (new 873718334Speter = simplify_binary_operation (code, mode, 873818334Speter XEXP (varop, 0), 873918334Speter GEN_INT (count)))) 874018334Speter { 874118334Speter varop = gen_rtx_combine (code, mode, new, XEXP (varop, 1)); 874218334Speter count = 0; 874318334Speter continue; 874418334Speter } 874518334Speter break; 874618334Speter 874718334Speter case NOT: 874818334Speter /* Make this fit the case below. */ 874918334Speter varop = gen_rtx_combine (XOR, mode, XEXP (varop, 0), 875018334Speter GEN_INT (GET_MODE_MASK (mode))); 875118334Speter continue; 875218334Speter 875318334Speter case IOR: 875418334Speter case AND: 875518334Speter case XOR: 875618334Speter /* If we have (xshiftrt (ior (plus X (const_int -1)) X) C) 875718334Speter with C the size of VAROP - 1 and the shift is logical if 875818334Speter STORE_FLAG_VALUE is 1 and arithmetic if STORE_FLAG_VALUE is -1, 875918334Speter we have an (le X 0) operation. If we have an arithmetic shift 876018334Speter and STORE_FLAG_VALUE is 1 or we have a logical shift with 876118334Speter STORE_FLAG_VALUE of -1, we have a (neg (le X 0)) operation. */ 876218334Speter 876318334Speter if (GET_CODE (varop) == IOR && GET_CODE (XEXP (varop, 0)) == PLUS 876418334Speter && XEXP (XEXP (varop, 0), 1) == constm1_rtx 876518334Speter && (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1) 876618334Speter && (code == LSHIFTRT || code == ASHIFTRT) 876718334Speter && count == GET_MODE_BITSIZE (GET_MODE (varop)) - 1 876818334Speter && rtx_equal_p (XEXP (XEXP (varop, 0), 0), XEXP (varop, 1))) 876918334Speter { 877018334Speter count = 0; 877118334Speter varop = gen_rtx_combine (LE, GET_MODE (varop), XEXP (varop, 1), 877218334Speter const0_rtx); 877318334Speter 877418334Speter if (STORE_FLAG_VALUE == 1 ? code == ASHIFTRT : code == LSHIFTRT) 877518334Speter varop = gen_rtx_combine (NEG, GET_MODE (varop), varop); 877618334Speter 877718334Speter continue; 877818334Speter } 877918334Speter 878018334Speter /* If we have (shift (logical)), move the logical to the outside 878118334Speter to allow it to possibly combine with another logical and the 878218334Speter shift to combine with another shift. This also canonicalizes to 878318334Speter what a ZERO_EXTRACT looks like. Also, some machines have 878418334Speter (and (shift)) insns. */ 878518334Speter 878618334Speter if (GET_CODE (XEXP (varop, 1)) == CONST_INT 878718334Speter && (new = simplify_binary_operation (code, result_mode, 878818334Speter XEXP (varop, 1), 878918334Speter GEN_INT (count))) != 0 879018334Speter && GET_CODE(new) == CONST_INT 879118334Speter && merge_outer_ops (&outer_op, &outer_const, GET_CODE (varop), 879218334Speter INTVAL (new), result_mode, &complement_p)) 879318334Speter { 879418334Speter varop = XEXP (varop, 0); 879518334Speter continue; 879618334Speter } 879718334Speter 879818334Speter /* If we can't do that, try to simplify the shift in each arm of the 879918334Speter logical expression, make a new logical expression, and apply 880018334Speter the inverse distributive law. */ 880118334Speter { 880218334Speter rtx lhs = simplify_shift_const (NULL_RTX, code, shift_mode, 880318334Speter XEXP (varop, 0), count); 880418334Speter rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode, 880518334Speter XEXP (varop, 1), count); 880618334Speter 880718334Speter varop = gen_binary (GET_CODE (varop), shift_mode, lhs, rhs); 880818334Speter varop = apply_distributive_law (varop); 880918334Speter 881018334Speter count = 0; 881118334Speter } 881218334Speter break; 881318334Speter 881418334Speter case EQ: 881518334Speter /* convert (lshiftrt (eq FOO 0) C) to (xor FOO 1) if STORE_FLAG_VALUE 881618334Speter says that the sign bit can be tested, FOO has mode MODE, C is 881718334Speter GET_MODE_BITSIZE (MODE) - 1, and FOO has only its low-order bit 881818334Speter that may be nonzero. */ 881918334Speter if (code == LSHIFTRT 882018334Speter && XEXP (varop, 1) == const0_rtx 882118334Speter && GET_MODE (XEXP (varop, 0)) == result_mode 882218334Speter && count == GET_MODE_BITSIZE (result_mode) - 1 882318334Speter && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT 882418334Speter && ((STORE_FLAG_VALUE 882518334Speter & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (result_mode) - 1)))) 882618334Speter && nonzero_bits (XEXP (varop, 0), result_mode) == 1 882718334Speter && merge_outer_ops (&outer_op, &outer_const, XOR, 882818334Speter (HOST_WIDE_INT) 1, result_mode, 882918334Speter &complement_p)) 883018334Speter { 883118334Speter varop = XEXP (varop, 0); 883218334Speter count = 0; 883318334Speter continue; 883418334Speter } 883518334Speter break; 883618334Speter 883718334Speter case NEG: 883818334Speter /* (lshiftrt (neg A) C) where A is either 0 or 1 and C is one less 883918334Speter than the number of bits in the mode is equivalent to A. */ 884018334Speter if (code == LSHIFTRT && count == GET_MODE_BITSIZE (result_mode) - 1 884118334Speter && nonzero_bits (XEXP (varop, 0), result_mode) == 1) 884218334Speter { 884318334Speter varop = XEXP (varop, 0); 884418334Speter count = 0; 884518334Speter continue; 884618334Speter } 884718334Speter 884818334Speter /* NEG commutes with ASHIFT since it is multiplication. Move the 884918334Speter NEG outside to allow shifts to combine. */ 885018334Speter if (code == ASHIFT 885118334Speter && merge_outer_ops (&outer_op, &outer_const, NEG, 885218334Speter (HOST_WIDE_INT) 0, result_mode, 885318334Speter &complement_p)) 885418334Speter { 885518334Speter varop = XEXP (varop, 0); 885618334Speter continue; 885718334Speter } 885818334Speter break; 885918334Speter 886018334Speter case PLUS: 886118334Speter /* (lshiftrt (plus A -1) C) where A is either 0 or 1 and C 886218334Speter is one less than the number of bits in the mode is 886318334Speter equivalent to (xor A 1). */ 886418334Speter if (code == LSHIFTRT && count == GET_MODE_BITSIZE (result_mode) - 1 886518334Speter && XEXP (varop, 1) == constm1_rtx 886618334Speter && nonzero_bits (XEXP (varop, 0), result_mode) == 1 886718334Speter && merge_outer_ops (&outer_op, &outer_const, XOR, 886818334Speter (HOST_WIDE_INT) 1, result_mode, 886918334Speter &complement_p)) 887018334Speter { 887118334Speter count = 0; 887218334Speter varop = XEXP (varop, 0); 887318334Speter continue; 887418334Speter } 887518334Speter 887618334Speter /* If we have (xshiftrt (plus FOO BAR) C), and the only bits 887718334Speter that might be nonzero in BAR are those being shifted out and those 887818334Speter bits are known zero in FOO, we can replace the PLUS with FOO. 887918334Speter Similarly in the other operand order. This code occurs when 888018334Speter we are computing the size of a variable-size array. */ 888118334Speter 888218334Speter if ((code == ASHIFTRT || code == LSHIFTRT) 888318334Speter && count < HOST_BITS_PER_WIDE_INT 888418334Speter && nonzero_bits (XEXP (varop, 1), result_mode) >> count == 0 888518334Speter && (nonzero_bits (XEXP (varop, 1), result_mode) 888618334Speter & nonzero_bits (XEXP (varop, 0), result_mode)) == 0) 888718334Speter { 888818334Speter varop = XEXP (varop, 0); 888918334Speter continue; 889018334Speter } 889118334Speter else if ((code == ASHIFTRT || code == LSHIFTRT) 889218334Speter && count < HOST_BITS_PER_WIDE_INT 889318334Speter && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT 889418334Speter && 0 == (nonzero_bits (XEXP (varop, 0), result_mode) 889518334Speter >> count) 889618334Speter && 0 == (nonzero_bits (XEXP (varop, 0), result_mode) 889718334Speter & nonzero_bits (XEXP (varop, 1), 889818334Speter result_mode))) 889918334Speter { 890018334Speter varop = XEXP (varop, 1); 890118334Speter continue; 890218334Speter } 890318334Speter 890418334Speter /* (ashift (plus foo C) N) is (plus (ashift foo N) C'). */ 890518334Speter if (code == ASHIFT 890618334Speter && GET_CODE (XEXP (varop, 1)) == CONST_INT 890718334Speter && (new = simplify_binary_operation (ASHIFT, result_mode, 890818334Speter XEXP (varop, 1), 890918334Speter GEN_INT (count))) != 0 891018334Speter && GET_CODE(new) == CONST_INT 891118334Speter && merge_outer_ops (&outer_op, &outer_const, PLUS, 891218334Speter INTVAL (new), result_mode, &complement_p)) 891318334Speter { 891418334Speter varop = XEXP (varop, 0); 891518334Speter continue; 891618334Speter } 891718334Speter break; 891818334Speter 891918334Speter case MINUS: 892018334Speter /* If we have (xshiftrt (minus (ashiftrt X C)) X) C) 892118334Speter with C the size of VAROP - 1 and the shift is logical if 892218334Speter STORE_FLAG_VALUE is 1 and arithmetic if STORE_FLAG_VALUE is -1, 892318334Speter we have a (gt X 0) operation. If the shift is arithmetic with 892418334Speter STORE_FLAG_VALUE of 1 or logical with STORE_FLAG_VALUE == -1, 892518334Speter we have a (neg (gt X 0)) operation. */ 892618334Speter 892750397Sobrien if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1) 892850397Sobrien && GET_CODE (XEXP (varop, 0)) == ASHIFTRT 892918334Speter && count == GET_MODE_BITSIZE (GET_MODE (varop)) - 1 893018334Speter && (code == LSHIFTRT || code == ASHIFTRT) 893118334Speter && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT 893218334Speter && INTVAL (XEXP (XEXP (varop, 0), 1)) == count 893318334Speter && rtx_equal_p (XEXP (XEXP (varop, 0), 0), XEXP (varop, 1))) 893418334Speter { 893518334Speter count = 0; 893618334Speter varop = gen_rtx_combine (GT, GET_MODE (varop), XEXP (varop, 1), 893718334Speter const0_rtx); 893818334Speter 893918334Speter if (STORE_FLAG_VALUE == 1 ? code == ASHIFTRT : code == LSHIFTRT) 894018334Speter varop = gen_rtx_combine (NEG, GET_MODE (varop), varop); 894118334Speter 894218334Speter continue; 894318334Speter } 894418334Speter break; 894550397Sobrien 894650397Sobrien case TRUNCATE: 894750397Sobrien /* Change (lshiftrt (truncate (lshiftrt))) to (truncate (lshiftrt)) 894850397Sobrien if the truncate does not affect the value. */ 894950397Sobrien if (code == LSHIFTRT 895050397Sobrien && GET_CODE (XEXP (varop, 0)) == LSHIFTRT 895150397Sobrien && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT 895250397Sobrien && (INTVAL (XEXP (XEXP (varop, 0), 1)) 895350397Sobrien >= (GET_MODE_BITSIZE (GET_MODE (XEXP (varop, 0))) 895450397Sobrien - GET_MODE_BITSIZE (GET_MODE (varop))))) 895550397Sobrien { 895650397Sobrien rtx varop_inner = XEXP (varop, 0); 895750397Sobrien 895850397Sobrien varop_inner = gen_rtx_combine (LSHIFTRT, 895950397Sobrien GET_MODE (varop_inner), 896050397Sobrien XEXP (varop_inner, 0), 896150397Sobrien GEN_INT (count + INTVAL (XEXP (varop_inner, 1)))); 896250397Sobrien varop = gen_rtx_combine (TRUNCATE, GET_MODE (varop), 896350397Sobrien varop_inner); 896450397Sobrien count = 0; 896550397Sobrien continue; 896650397Sobrien } 896750397Sobrien break; 896850397Sobrien 896950397Sobrien default: 897050397Sobrien break; 897118334Speter } 897218334Speter 897318334Speter break; 897418334Speter } 897518334Speter 897618334Speter /* We need to determine what mode to do the shift in. If the shift is 897718334Speter a right shift or ROTATE, we must always do it in the mode it was 897818334Speter originally done in. Otherwise, we can do it in MODE, the widest mode 897918334Speter encountered. The code we care about is that of the shift that will 898018334Speter actually be done, not the shift that was originally requested. */ 898118334Speter shift_mode 898218334Speter = (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE 898318334Speter ? result_mode : mode); 898418334Speter 898518334Speter /* We have now finished analyzing the shift. The result should be 898618334Speter a shift of type CODE with SHIFT_MODE shifting VAROP COUNT places. If 898718334Speter OUTER_OP is non-NIL, it is an operation that needs to be applied 898818334Speter to the result of the shift. OUTER_CONST is the relevant constant, 898918334Speter but we must turn off all bits turned off in the shift. 899018334Speter 899118334Speter If we were passed a value for X, see if we can use any pieces of 899218334Speter it. If not, make new rtx. */ 899318334Speter 899418334Speter if (x && GET_RTX_CLASS (GET_CODE (x)) == '2' 899518334Speter && GET_CODE (XEXP (x, 1)) == CONST_INT 899618334Speter && INTVAL (XEXP (x, 1)) == count) 899718334Speter const_rtx = XEXP (x, 1); 899818334Speter else 899918334Speter const_rtx = GEN_INT (count); 900018334Speter 900118334Speter if (x && GET_CODE (XEXP (x, 0)) == SUBREG 900218334Speter && GET_MODE (XEXP (x, 0)) == shift_mode 900318334Speter && SUBREG_REG (XEXP (x, 0)) == varop) 900418334Speter varop = XEXP (x, 0); 900518334Speter else if (GET_MODE (varop) != shift_mode) 900618334Speter varop = gen_lowpart_for_combine (shift_mode, varop); 900718334Speter 900850397Sobrien /* If we can't make the SUBREG, try to return what we were given. */ 900918334Speter if (GET_CODE (varop) == CLOBBER) 901018334Speter return x ? x : varop; 901118334Speter 901218334Speter new = simplify_binary_operation (code, shift_mode, varop, const_rtx); 901318334Speter if (new != 0) 901418334Speter x = new; 901518334Speter else 901618334Speter { 901718334Speter if (x == 0 || GET_CODE (x) != code || GET_MODE (x) != shift_mode) 901818334Speter x = gen_rtx_combine (code, shift_mode, varop, const_rtx); 901918334Speter 902018334Speter SUBST (XEXP (x, 0), varop); 902118334Speter SUBST (XEXP (x, 1), const_rtx); 902218334Speter } 902318334Speter 902418334Speter /* If we have an outer operation and we just made a shift, it is 902518334Speter possible that we could have simplified the shift were it not 902618334Speter for the outer operation. So try to do the simplification 902718334Speter recursively. */ 902818334Speter 902918334Speter if (outer_op != NIL && GET_CODE (x) == code 903018334Speter && GET_CODE (XEXP (x, 1)) == CONST_INT) 903118334Speter x = simplify_shift_const (x, code, shift_mode, XEXP (x, 0), 903218334Speter INTVAL (XEXP (x, 1))); 903318334Speter 903418334Speter /* If we were doing a LSHIFTRT in a wider mode than it was originally, 903518334Speter turn off all the bits that the shift would have turned off. */ 903618334Speter if (orig_code == LSHIFTRT && result_mode != shift_mode) 903718334Speter x = simplify_and_const_int (NULL_RTX, shift_mode, x, 903818334Speter GET_MODE_MASK (result_mode) >> orig_count); 903918334Speter 904018334Speter /* Do the remainder of the processing in RESULT_MODE. */ 904118334Speter x = gen_lowpart_for_combine (result_mode, x); 904218334Speter 904318334Speter /* If COMPLEMENT_P is set, we have to complement X before doing the outer 904418334Speter operation. */ 904518334Speter if (complement_p) 904618334Speter x = gen_unary (NOT, result_mode, result_mode, x); 904718334Speter 904818334Speter if (outer_op != NIL) 904918334Speter { 905018334Speter if (GET_MODE_BITSIZE (result_mode) < HOST_BITS_PER_WIDE_INT) 905118334Speter { 905218334Speter int width = GET_MODE_BITSIZE (result_mode); 905318334Speter 905418334Speter outer_const &= GET_MODE_MASK (result_mode); 905518334Speter 905618334Speter /* If this would be an entire word for the target, but is not for 905718334Speter the host, then sign-extend on the host so that the number will 905818334Speter look the same way on the host that it would on the target. 905918334Speter 906018334Speter For example, when building a 64 bit alpha hosted 32 bit sparc 906118334Speter targeted compiler, then we want the 32 bit unsigned value -1 to be 906218334Speter represented as a 64 bit value -1, and not as 0x00000000ffffffff. 906318334Speter The later confuses the sparc backend. */ 906418334Speter 906518334Speter if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width 906618334Speter && (outer_const & ((HOST_WIDE_INT) 1 << (width - 1)))) 906718334Speter outer_const |= ((HOST_WIDE_INT) (-1) << width); 906818334Speter } 906918334Speter 907018334Speter if (outer_op == AND) 907118334Speter x = simplify_and_const_int (NULL_RTX, result_mode, x, outer_const); 907218334Speter else if (outer_op == SET) 907318334Speter /* This means that we have determined that the result is 907418334Speter equivalent to a constant. This should be rare. */ 907518334Speter x = GEN_INT (outer_const); 907618334Speter else if (GET_RTX_CLASS (outer_op) == '1') 907718334Speter x = gen_unary (outer_op, result_mode, result_mode, x); 907818334Speter else 907918334Speter x = gen_binary (outer_op, result_mode, x, GEN_INT (outer_const)); 908018334Speter } 908118334Speter 908218334Speter return x; 908318334Speter} 908418334Speter 908518334Speter/* Like recog, but we receive the address of a pointer to a new pattern. 908618334Speter We try to match the rtx that the pointer points to. 908718334Speter If that fails, we may try to modify or replace the pattern, 908818334Speter storing the replacement into the same pointer object. 908918334Speter 909018334Speter Modifications include deletion or addition of CLOBBERs. 909118334Speter 909218334Speter PNOTES is a pointer to a location where any REG_UNUSED notes added for 909318334Speter the CLOBBERs are placed. 909418334Speter 909518334Speter The value is the final insn code from the pattern ultimately matched, 909618334Speter or -1. */ 909718334Speter 909818334Speterstatic int 909952284Sobrienrecog_for_combine (pnewpat, insn, pnotes) 910018334Speter rtx *pnewpat; 910118334Speter rtx insn; 910218334Speter rtx *pnotes; 910318334Speter{ 910418334Speter register rtx pat = *pnewpat; 910518334Speter int insn_code_number; 910618334Speter int num_clobbers_to_add = 0; 910718334Speter int i; 910818334Speter rtx notes = 0; 910918334Speter 911018334Speter /* If PAT is a PARALLEL, check to see if it contains the CLOBBER 911118334Speter we use to indicate that something didn't match. If we find such a 911218334Speter thing, force rejection. */ 911318334Speter if (GET_CODE (pat) == PARALLEL) 911418334Speter for (i = XVECLEN (pat, 0) - 1; i >= 0; i--) 911518334Speter if (GET_CODE (XVECEXP (pat, 0, i)) == CLOBBER 911618334Speter && XEXP (XVECEXP (pat, 0, i), 0) == const0_rtx) 911718334Speter return -1; 911818334Speter 911918334Speter /* Is the result of combination a valid instruction? */ 912018334Speter insn_code_number = recog (pat, insn, &num_clobbers_to_add); 912118334Speter 912218334Speter /* If it isn't, there is the possibility that we previously had an insn 912318334Speter that clobbered some register as a side effect, but the combined 912418334Speter insn doesn't need to do that. So try once more without the clobbers 912518334Speter unless this represents an ASM insn. */ 912618334Speter 912718334Speter if (insn_code_number < 0 && ! check_asm_operands (pat) 912818334Speter && GET_CODE (pat) == PARALLEL) 912918334Speter { 913018334Speter int pos; 913118334Speter 913218334Speter for (pos = 0, i = 0; i < XVECLEN (pat, 0); i++) 913318334Speter if (GET_CODE (XVECEXP (pat, 0, i)) != CLOBBER) 913418334Speter { 913518334Speter if (i != pos) 913618334Speter SUBST (XVECEXP (pat, 0, pos), XVECEXP (pat, 0, i)); 913718334Speter pos++; 913818334Speter } 913918334Speter 914018334Speter SUBST_INT (XVECLEN (pat, 0), pos); 914118334Speter 914218334Speter if (pos == 1) 914318334Speter pat = XVECEXP (pat, 0, 0); 914418334Speter 914518334Speter insn_code_number = recog (pat, insn, &num_clobbers_to_add); 914618334Speter } 914718334Speter 914818334Speter /* If we had any clobbers to add, make a new pattern than contains 914918334Speter them. Then check to make sure that all of them are dead. */ 915018334Speter if (num_clobbers_to_add) 915118334Speter { 915250397Sobrien rtx newpat = gen_rtx_PARALLEL (VOIDmode, 915350397Sobrien gen_rtvec (GET_CODE (pat) == PARALLEL 915450397Sobrien ? XVECLEN (pat, 0) + num_clobbers_to_add 915550397Sobrien : num_clobbers_to_add + 1)); 915618334Speter 915718334Speter if (GET_CODE (pat) == PARALLEL) 915818334Speter for (i = 0; i < XVECLEN (pat, 0); i++) 915918334Speter XVECEXP (newpat, 0, i) = XVECEXP (pat, 0, i); 916018334Speter else 916118334Speter XVECEXP (newpat, 0, 0) = pat; 916218334Speter 916318334Speter add_clobbers (newpat, insn_code_number); 916418334Speter 916518334Speter for (i = XVECLEN (newpat, 0) - num_clobbers_to_add; 916618334Speter i < XVECLEN (newpat, 0); i++) 916718334Speter { 916818334Speter if (GET_CODE (XEXP (XVECEXP (newpat, 0, i), 0)) == REG 916918334Speter && ! reg_dead_at_p (XEXP (XVECEXP (newpat, 0, i), 0), insn)) 917018334Speter return -1; 917150397Sobrien notes = gen_rtx_EXPR_LIST (REG_UNUSED, 917250397Sobrien XEXP (XVECEXP (newpat, 0, i), 0), notes); 917318334Speter } 917418334Speter pat = newpat; 917518334Speter } 917618334Speter 917718334Speter *pnewpat = pat; 917818334Speter *pnotes = notes; 917918334Speter 918018334Speter return insn_code_number; 918118334Speter} 918218334Speter 918318334Speter/* Like gen_lowpart but for use by combine. In combine it is not possible 918418334Speter to create any new pseudoregs. However, it is safe to create 918518334Speter invalid memory addresses, because combine will try to recognize 918618334Speter them and all they will do is make the combine attempt fail. 918718334Speter 918818334Speter If for some reason this cannot do its job, an rtx 918918334Speter (clobber (const_int 0)) is returned. 919018334Speter An insn containing that will not be recognized. */ 919118334Speter 919218334Speter#undef gen_lowpart 919318334Speter 919418334Speterstatic rtx 919518334Spetergen_lowpart_for_combine (mode, x) 919618334Speter enum machine_mode mode; 919718334Speter register rtx x; 919818334Speter{ 919918334Speter rtx result; 920018334Speter 920118334Speter if (GET_MODE (x) == mode) 920218334Speter return x; 920318334Speter 920418334Speter /* We can only support MODE being wider than a word if X is a 920518334Speter constant integer or has a mode the same size. */ 920618334Speter 920718334Speter if (GET_MODE_SIZE (mode) > UNITS_PER_WORD 920818334Speter && ! ((GET_MODE (x) == VOIDmode 920918334Speter && (GET_CODE (x) == CONST_INT 921018334Speter || GET_CODE (x) == CONST_DOUBLE)) 921118334Speter || GET_MODE_SIZE (GET_MODE (x)) == GET_MODE_SIZE (mode))) 921250397Sobrien return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx); 921318334Speter 921418334Speter /* X might be a paradoxical (subreg (mem)). In that case, gen_lowpart 921518334Speter won't know what to do. So we will strip off the SUBREG here and 921618334Speter process normally. */ 921718334Speter if (GET_CODE (x) == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM) 921818334Speter { 921918334Speter x = SUBREG_REG (x); 922018334Speter if (GET_MODE (x) == mode) 922118334Speter return x; 922218334Speter } 922318334Speter 922418334Speter result = gen_lowpart_common (mode, x); 922518334Speter if (result != 0 922618334Speter && GET_CODE (result) == SUBREG 922718334Speter && GET_CODE (SUBREG_REG (result)) == REG 922818334Speter && REGNO (SUBREG_REG (result)) >= FIRST_PSEUDO_REGISTER 922918334Speter && (GET_MODE_SIZE (GET_MODE (result)) 923018334Speter != GET_MODE_SIZE (GET_MODE (SUBREG_REG (result))))) 923150397Sobrien REG_CHANGES_SIZE (REGNO (SUBREG_REG (result))) = 1; 923218334Speter 923318334Speter if (result) 923418334Speter return result; 923518334Speter 923618334Speter if (GET_CODE (x) == MEM) 923718334Speter { 923818334Speter register int offset = 0; 923918334Speter rtx new; 924018334Speter 924118334Speter /* Refuse to work on a volatile memory ref or one with a mode-dependent 924218334Speter address. */ 924318334Speter if (MEM_VOLATILE_P (x) || mode_dependent_address_p (XEXP (x, 0))) 924450397Sobrien return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx); 924518334Speter 924618334Speter /* If we want to refer to something bigger than the original memref, 924718334Speter generate a perverse subreg instead. That will force a reload 924818334Speter of the original memref X. */ 924918334Speter if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode)) 925050397Sobrien return gen_rtx_SUBREG (mode, x, 0); 925118334Speter 925218334Speter if (WORDS_BIG_ENDIAN) 925318334Speter offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD) 925418334Speter - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)); 925518334Speter if (BYTES_BIG_ENDIAN) 925618334Speter { 925718334Speter /* Adjust the address so that the address-after-the-data is 925818334Speter unchanged. */ 925918334Speter offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)) 926018334Speter - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))); 926118334Speter } 926250397Sobrien new = gen_rtx_MEM (mode, plus_constant (XEXP (x, 0), offset)); 926318334Speter RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x); 926452284Sobrien MEM_COPY_ATTRIBUTES (new, x); 926518334Speter return new; 926618334Speter } 926718334Speter 926818334Speter /* If X is a comparison operator, rewrite it in a new mode. This 926918334Speter probably won't match, but may allow further simplifications. */ 927018334Speter else if (GET_RTX_CLASS (GET_CODE (x)) == '<') 927118334Speter return gen_rtx_combine (GET_CODE (x), mode, XEXP (x, 0), XEXP (x, 1)); 927218334Speter 927318334Speter /* If we couldn't simplify X any other way, just enclose it in a 927418334Speter SUBREG. Normally, this SUBREG won't match, but some patterns may 927518334Speter include an explicit SUBREG or we may simplify it further in combine. */ 927618334Speter else 927718334Speter { 927818334Speter int word = 0; 927918334Speter 928018334Speter if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) 928118334Speter word = ((GET_MODE_SIZE (GET_MODE (x)) 928218334Speter - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)) 928318334Speter / UNITS_PER_WORD); 928450397Sobrien return gen_rtx_SUBREG (mode, x, word); 928518334Speter } 928618334Speter} 928718334Speter 928818334Speter/* Make an rtx expression. This is a subset of gen_rtx and only supports 928918334Speter expressions of 1, 2, or 3 operands, each of which are rtx expressions. 929018334Speter 929118334Speter If the identical expression was previously in the insn (in the undobuf), 929218334Speter it will be returned. Only if it is not found will a new expression 929318334Speter be made. */ 929418334Speter 929518334Speter/*VARARGS2*/ 929618334Speterstatic rtx 929718334Spetergen_rtx_combine VPROTO((enum rtx_code code, enum machine_mode mode, ...)) 929818334Speter{ 929952284Sobrien#ifndef ANSI_PROTOTYPES 930018334Speter enum rtx_code code; 930118334Speter enum machine_mode mode; 930218334Speter#endif 930318334Speter va_list p; 930418334Speter int n_args; 930518334Speter rtx args[3]; 930650397Sobrien int j; 930718334Speter char *fmt; 930818334Speter rtx rt; 930950397Sobrien struct undo *undo; 931018334Speter 931118334Speter VA_START (p, mode); 931218334Speter 931352284Sobrien#ifndef ANSI_PROTOTYPES 931418334Speter code = va_arg (p, enum rtx_code); 931518334Speter mode = va_arg (p, enum machine_mode); 931618334Speter#endif 931718334Speter 931818334Speter n_args = GET_RTX_LENGTH (code); 931918334Speter fmt = GET_RTX_FORMAT (code); 932018334Speter 932118334Speter if (n_args == 0 || n_args > 3) 932218334Speter abort (); 932318334Speter 932418334Speter /* Get each arg and verify that it is supposed to be an expression. */ 932518334Speter for (j = 0; j < n_args; j++) 932618334Speter { 932718334Speter if (*fmt++ != 'e') 932818334Speter abort (); 932918334Speter 933018334Speter args[j] = va_arg (p, rtx); 933118334Speter } 933218334Speter 933318334Speter /* See if this is in undobuf. Be sure we don't use objects that came 933418334Speter from another insn; this could produce circular rtl structures. */ 933518334Speter 933650397Sobrien for (undo = undobuf.undos; undo != undobuf.previous_undos; undo = undo->next) 933750397Sobrien if (!undo->is_int 933850397Sobrien && GET_CODE (undo->old_contents.r) == code 933950397Sobrien && GET_MODE (undo->old_contents.r) == mode) 934018334Speter { 934118334Speter for (j = 0; j < n_args; j++) 934250397Sobrien if (XEXP (undo->old_contents.r, j) != args[j]) 934318334Speter break; 934418334Speter 934518334Speter if (j == n_args) 934650397Sobrien return undo->old_contents.r; 934718334Speter } 934818334Speter 934918334Speter /* Otherwise make a new rtx. We know we have 1, 2, or 3 args. 935018334Speter Use rtx_alloc instead of gen_rtx because it's faster on RISC. */ 935118334Speter rt = rtx_alloc (code); 935218334Speter PUT_MODE (rt, mode); 935318334Speter XEXP (rt, 0) = args[0]; 935418334Speter if (n_args > 1) 935518334Speter { 935618334Speter XEXP (rt, 1) = args[1]; 935718334Speter if (n_args > 2) 935818334Speter XEXP (rt, 2) = args[2]; 935918334Speter } 936018334Speter return rt; 936118334Speter} 936218334Speter 936318334Speter/* These routines make binary and unary operations by first seeing if they 936418334Speter fold; if not, a new expression is allocated. */ 936518334Speter 936618334Speterstatic rtx 936718334Spetergen_binary (code, mode, op0, op1) 936818334Speter enum rtx_code code; 936918334Speter enum machine_mode mode; 937018334Speter rtx op0, op1; 937118334Speter{ 937218334Speter rtx result; 937318334Speter rtx tem; 937418334Speter 937518334Speter if (GET_RTX_CLASS (code) == 'c' 937618334Speter && (GET_CODE (op0) == CONST_INT 937718334Speter || (CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT))) 937818334Speter tem = op0, op0 = op1, op1 = tem; 937918334Speter 938018334Speter if (GET_RTX_CLASS (code) == '<') 938118334Speter { 938218334Speter enum machine_mode op_mode = GET_MODE (op0); 938318334Speter 938418334Speter /* Strip the COMPARE from (REL_OP (compare X Y) 0) to get 938550397Sobrien just (REL_OP X Y). */ 938618334Speter if (GET_CODE (op0) == COMPARE && op1 == const0_rtx) 938718334Speter { 938818334Speter op1 = XEXP (op0, 1); 938918334Speter op0 = XEXP (op0, 0); 939018334Speter op_mode = GET_MODE (op0); 939118334Speter } 939218334Speter 939318334Speter if (op_mode == VOIDmode) 939418334Speter op_mode = GET_MODE (op1); 939518334Speter result = simplify_relational_operation (code, op_mode, op0, op1); 939618334Speter } 939718334Speter else 939818334Speter result = simplify_binary_operation (code, mode, op0, op1); 939918334Speter 940018334Speter if (result) 940118334Speter return result; 940218334Speter 940318334Speter /* Put complex operands first and constants second. */ 940418334Speter if (GET_RTX_CLASS (code) == 'c' 940518334Speter && ((CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT) 940618334Speter || (GET_RTX_CLASS (GET_CODE (op0)) == 'o' 940718334Speter && GET_RTX_CLASS (GET_CODE (op1)) != 'o') 940818334Speter || (GET_CODE (op0) == SUBREG 940918334Speter && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op0))) == 'o' 941018334Speter && GET_RTX_CLASS (GET_CODE (op1)) != 'o'))) 941118334Speter return gen_rtx_combine (code, mode, op1, op0); 941218334Speter 941350397Sobrien /* If we are turning off bits already known off in OP0, we need not do 941450397Sobrien an AND. */ 941550397Sobrien else if (code == AND && GET_CODE (op1) == CONST_INT 941650397Sobrien && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 941750397Sobrien && (nonzero_bits (op0, mode) & ~ INTVAL (op1)) == 0) 941850397Sobrien return op0; 941950397Sobrien 942018334Speter return gen_rtx_combine (code, mode, op0, op1); 942118334Speter} 942218334Speter 942318334Speterstatic rtx 942418334Spetergen_unary (code, mode, op0_mode, op0) 942518334Speter enum rtx_code code; 942618334Speter enum machine_mode mode, op0_mode; 942718334Speter rtx op0; 942818334Speter{ 942918334Speter rtx result = simplify_unary_operation (code, mode, op0, op0_mode); 943018334Speter 943118334Speter if (result) 943218334Speter return result; 943318334Speter 943418334Speter return gen_rtx_combine (code, mode, op0); 943518334Speter} 943618334Speter 943718334Speter/* Simplify a comparison between *POP0 and *POP1 where CODE is the 943818334Speter comparison code that will be tested. 943918334Speter 944018334Speter The result is a possibly different comparison code to use. *POP0 and 944118334Speter *POP1 may be updated. 944218334Speter 944318334Speter It is possible that we might detect that a comparison is either always 944418334Speter true or always false. However, we do not perform general constant 944518334Speter folding in combine, so this knowledge isn't useful. Such tautologies 944618334Speter should have been detected earlier. Hence we ignore all such cases. */ 944718334Speter 944818334Speterstatic enum rtx_code 944918334Spetersimplify_comparison (code, pop0, pop1) 945018334Speter enum rtx_code code; 945118334Speter rtx *pop0; 945218334Speter rtx *pop1; 945318334Speter{ 945418334Speter rtx op0 = *pop0; 945518334Speter rtx op1 = *pop1; 945618334Speter rtx tem, tem1; 945718334Speter int i; 945818334Speter enum machine_mode mode, tmode; 945918334Speter 946018334Speter /* Try a few ways of applying the same transformation to both operands. */ 946118334Speter while (1) 946218334Speter { 946318334Speter#ifndef WORD_REGISTER_OPERATIONS 946418334Speter /* The test below this one won't handle SIGN_EXTENDs on these machines, 946518334Speter so check specially. */ 946618334Speter if (code != GTU && code != GEU && code != LTU && code != LEU 946718334Speter && GET_CODE (op0) == ASHIFTRT && GET_CODE (op1) == ASHIFTRT 946818334Speter && GET_CODE (XEXP (op0, 0)) == ASHIFT 946918334Speter && GET_CODE (XEXP (op1, 0)) == ASHIFT 947018334Speter && GET_CODE (XEXP (XEXP (op0, 0), 0)) == SUBREG 947118334Speter && GET_CODE (XEXP (XEXP (op1, 0), 0)) == SUBREG 947218334Speter && (GET_MODE (SUBREG_REG (XEXP (XEXP (op0, 0), 0))) 947318334Speter == GET_MODE (SUBREG_REG (XEXP (XEXP (op1, 0), 0)))) 947418334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 947518334Speter && GET_CODE (XEXP (op1, 1)) == CONST_INT 947618334Speter && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT 947718334Speter && GET_CODE (XEXP (XEXP (op1, 0), 1)) == CONST_INT 947818334Speter && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (op1, 1)) 947918334Speter && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (XEXP (op0, 0), 1)) 948018334Speter && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (XEXP (op1, 0), 1)) 948118334Speter && (INTVAL (XEXP (op0, 1)) 948218334Speter == (GET_MODE_BITSIZE (GET_MODE (op0)) 948318334Speter - (GET_MODE_BITSIZE 948418334Speter (GET_MODE (SUBREG_REG (XEXP (XEXP (op0, 0), 0)))))))) 948518334Speter { 948618334Speter op0 = SUBREG_REG (XEXP (XEXP (op0, 0), 0)); 948718334Speter op1 = SUBREG_REG (XEXP (XEXP (op1, 0), 0)); 948818334Speter } 948918334Speter#endif 949018334Speter 949118334Speter /* If both operands are the same constant shift, see if we can ignore the 949218334Speter shift. We can if the shift is a rotate or if the bits shifted out of 949318334Speter this shift are known to be zero for both inputs and if the type of 949418334Speter comparison is compatible with the shift. */ 949518334Speter if (GET_CODE (op0) == GET_CODE (op1) 949618334Speter && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT 949718334Speter && ((GET_CODE (op0) == ROTATE && (code == NE || code == EQ)) 949818334Speter || ((GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFT) 949918334Speter && (code != GT && code != LT && code != GE && code != LE)) 950018334Speter || (GET_CODE (op0) == ASHIFTRT 950118334Speter && (code != GTU && code != LTU 950218334Speter && code != GEU && code != GEU))) 950318334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 950418334Speter && INTVAL (XEXP (op0, 1)) >= 0 950518334Speter && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT 950618334Speter && XEXP (op0, 1) == XEXP (op1, 1)) 950718334Speter { 950818334Speter enum machine_mode mode = GET_MODE (op0); 950918334Speter unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode); 951018334Speter int shift_count = INTVAL (XEXP (op0, 1)); 951118334Speter 951218334Speter if (GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFTRT) 951318334Speter mask &= (mask >> shift_count) << shift_count; 951418334Speter else if (GET_CODE (op0) == ASHIFT) 951518334Speter mask = (mask & (mask << shift_count)) >> shift_count; 951618334Speter 951718334Speter if ((nonzero_bits (XEXP (op0, 0), mode) & ~ mask) == 0 951818334Speter && (nonzero_bits (XEXP (op1, 0), mode) & ~ mask) == 0) 951918334Speter op0 = XEXP (op0, 0), op1 = XEXP (op1, 0); 952018334Speter else 952118334Speter break; 952218334Speter } 952318334Speter 952418334Speter /* If both operands are AND's of a paradoxical SUBREG by constant, the 952518334Speter SUBREGs are of the same mode, and, in both cases, the AND would 952618334Speter be redundant if the comparison was done in the narrower mode, 952718334Speter do the comparison in the narrower mode (e.g., we are AND'ing with 1 952818334Speter and the operand's possibly nonzero bits are 0xffffff01; in that case 952918334Speter if we only care about QImode, we don't need the AND). This case 953018334Speter occurs if the output mode of an scc insn is not SImode and 953118334Speter STORE_FLAG_VALUE == 1 (e.g., the 386). 953218334Speter 953318334Speter Similarly, check for a case where the AND's are ZERO_EXTEND 953418334Speter operations from some narrower mode even though a SUBREG is not 953518334Speter present. */ 953618334Speter 953718334Speter else if (GET_CODE (op0) == AND && GET_CODE (op1) == AND 953818334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 953918334Speter && GET_CODE (XEXP (op1, 1)) == CONST_INT) 954018334Speter { 954118334Speter rtx inner_op0 = XEXP (op0, 0); 954218334Speter rtx inner_op1 = XEXP (op1, 0); 954318334Speter HOST_WIDE_INT c0 = INTVAL (XEXP (op0, 1)); 954418334Speter HOST_WIDE_INT c1 = INTVAL (XEXP (op1, 1)); 954518334Speter int changed = 0; 954618334Speter 954718334Speter if (GET_CODE (inner_op0) == SUBREG && GET_CODE (inner_op1) == SUBREG 954818334Speter && (GET_MODE_SIZE (GET_MODE (inner_op0)) 954918334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner_op0)))) 955018334Speter && (GET_MODE (SUBREG_REG (inner_op0)) 955118334Speter == GET_MODE (SUBREG_REG (inner_op1))) 955250397Sobrien && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (inner_op0))) 955318334Speter <= HOST_BITS_PER_WIDE_INT) 955450397Sobrien && (0 == ((~c0) & nonzero_bits (SUBREG_REG (inner_op0), 955550397Sobrien GET_MODE (SUBREG_REG (inner_op0))))) 955650397Sobrien && (0 == ((~c1) & nonzero_bits (SUBREG_REG (inner_op1), 955750397Sobrien GET_MODE (SUBREG_REG (inner_op1)))))) 955818334Speter { 955918334Speter op0 = SUBREG_REG (inner_op0); 956018334Speter op1 = SUBREG_REG (inner_op1); 956118334Speter 956218334Speter /* The resulting comparison is always unsigned since we masked 956350397Sobrien off the original sign bit. */ 956418334Speter code = unsigned_condition (code); 956518334Speter 956618334Speter changed = 1; 956718334Speter } 956818334Speter 956918334Speter else if (c0 == c1) 957018334Speter for (tmode = GET_CLASS_NARROWEST_MODE 957118334Speter (GET_MODE_CLASS (GET_MODE (op0))); 957218334Speter tmode != GET_MODE (op0); tmode = GET_MODE_WIDER_MODE (tmode)) 957352284Sobrien if ((unsigned HOST_WIDE_INT) c0 == GET_MODE_MASK (tmode)) 957418334Speter { 957518334Speter op0 = gen_lowpart_for_combine (tmode, inner_op0); 957618334Speter op1 = gen_lowpart_for_combine (tmode, inner_op1); 957718334Speter code = unsigned_condition (code); 957818334Speter changed = 1; 957918334Speter break; 958018334Speter } 958118334Speter 958218334Speter if (! changed) 958318334Speter break; 958418334Speter } 958518334Speter 958618334Speter /* If both operands are NOT, we can strip off the outer operation 958718334Speter and adjust the comparison code for swapped operands; similarly for 958818334Speter NEG, except that this must be an equality comparison. */ 958918334Speter else if ((GET_CODE (op0) == NOT && GET_CODE (op1) == NOT) 959018334Speter || (GET_CODE (op0) == NEG && GET_CODE (op1) == NEG 959118334Speter && (code == EQ || code == NE))) 959218334Speter op0 = XEXP (op0, 0), op1 = XEXP (op1, 0), code = swap_condition (code); 959318334Speter 959418334Speter else 959518334Speter break; 959618334Speter } 959718334Speter 959818334Speter /* If the first operand is a constant, swap the operands and adjust the 959950397Sobrien comparison code appropriately, but don't do this if the second operand 960050397Sobrien is already a constant integer. */ 960150397Sobrien if (CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT) 960218334Speter { 960318334Speter tem = op0, op0 = op1, op1 = tem; 960418334Speter code = swap_condition (code); 960518334Speter } 960618334Speter 960718334Speter /* We now enter a loop during which we will try to simplify the comparison. 960818334Speter For the most part, we only are concerned with comparisons with zero, 960918334Speter but some things may really be comparisons with zero but not start 961018334Speter out looking that way. */ 961118334Speter 961218334Speter while (GET_CODE (op1) == CONST_INT) 961318334Speter { 961418334Speter enum machine_mode mode = GET_MODE (op0); 961518334Speter int mode_width = GET_MODE_BITSIZE (mode); 961618334Speter unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode); 961718334Speter int equality_comparison_p; 961818334Speter int sign_bit_comparison_p; 961918334Speter int unsigned_comparison_p; 962018334Speter HOST_WIDE_INT const_op; 962118334Speter 962218334Speter /* We only want to handle integral modes. This catches VOIDmode, 962318334Speter CCmode, and the floating-point modes. An exception is that we 962418334Speter can handle VOIDmode if OP0 is a COMPARE or a comparison 962518334Speter operation. */ 962618334Speter 962718334Speter if (GET_MODE_CLASS (mode) != MODE_INT 962818334Speter && ! (mode == VOIDmode 962918334Speter && (GET_CODE (op0) == COMPARE 963018334Speter || GET_RTX_CLASS (GET_CODE (op0)) == '<'))) 963118334Speter break; 963218334Speter 963318334Speter /* Get the constant we are comparing against and turn off all bits 963418334Speter not on in our mode. */ 963518334Speter const_op = INTVAL (op1); 963618334Speter if (mode_width <= HOST_BITS_PER_WIDE_INT) 963718334Speter const_op &= mask; 963818334Speter 963918334Speter /* If we are comparing against a constant power of two and the value 964018334Speter being compared can only have that single bit nonzero (e.g., it was 964118334Speter `and'ed with that bit), we can replace this with a comparison 964218334Speter with zero. */ 964318334Speter if (const_op 964418334Speter && (code == EQ || code == NE || code == GE || code == GEU 964518334Speter || code == LT || code == LTU) 964618334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 964718334Speter && exact_log2 (const_op) >= 0 964852284Sobrien && nonzero_bits (op0, mode) == (unsigned HOST_WIDE_INT) const_op) 964918334Speter { 965018334Speter code = (code == EQ || code == GE || code == GEU ? NE : EQ); 965118334Speter op1 = const0_rtx, const_op = 0; 965218334Speter } 965318334Speter 965418334Speter /* Similarly, if we are comparing a value known to be either -1 or 965518334Speter 0 with -1, change it to the opposite comparison against zero. */ 965618334Speter 965718334Speter if (const_op == -1 965818334Speter && (code == EQ || code == NE || code == GT || code == LE 965918334Speter || code == GEU || code == LTU) 966018334Speter && num_sign_bit_copies (op0, mode) == mode_width) 966118334Speter { 966218334Speter code = (code == EQ || code == LE || code == GEU ? NE : EQ); 966318334Speter op1 = const0_rtx, const_op = 0; 966418334Speter } 966518334Speter 966618334Speter /* Do some canonicalizations based on the comparison code. We prefer 966718334Speter comparisons against zero and then prefer equality comparisons. 966818334Speter If we can reduce the size of a constant, we will do that too. */ 966918334Speter 967018334Speter switch (code) 967118334Speter { 967218334Speter case LT: 967318334Speter /* < C is equivalent to <= (C - 1) */ 967418334Speter if (const_op > 0) 967518334Speter { 967618334Speter const_op -= 1; 967718334Speter op1 = GEN_INT (const_op); 967818334Speter code = LE; 967918334Speter /* ... fall through to LE case below. */ 968018334Speter } 968118334Speter else 968218334Speter break; 968318334Speter 968418334Speter case LE: 968518334Speter /* <= C is equivalent to < (C + 1); we do this for C < 0 */ 968618334Speter if (const_op < 0) 968718334Speter { 968818334Speter const_op += 1; 968918334Speter op1 = GEN_INT (const_op); 969018334Speter code = LT; 969118334Speter } 969218334Speter 969318334Speter /* If we are doing a <= 0 comparison on a value known to have 969418334Speter a zero sign bit, we can replace this with == 0. */ 969518334Speter else if (const_op == 0 969618334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 969718334Speter && (nonzero_bits (op0, mode) 969818334Speter & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0) 969918334Speter code = EQ; 970018334Speter break; 970118334Speter 970218334Speter case GE: 970350397Sobrien /* >= C is equivalent to > (C - 1). */ 970418334Speter if (const_op > 0) 970518334Speter { 970618334Speter const_op -= 1; 970718334Speter op1 = GEN_INT (const_op); 970818334Speter code = GT; 970918334Speter /* ... fall through to GT below. */ 971018334Speter } 971118334Speter else 971218334Speter break; 971318334Speter 971418334Speter case GT: 971518334Speter /* > C is equivalent to >= (C + 1); we do this for C < 0*/ 971618334Speter if (const_op < 0) 971718334Speter { 971818334Speter const_op += 1; 971918334Speter op1 = GEN_INT (const_op); 972018334Speter code = GE; 972118334Speter } 972218334Speter 972318334Speter /* If we are doing a > 0 comparison on a value known to have 972418334Speter a zero sign bit, we can replace this with != 0. */ 972518334Speter else if (const_op == 0 972618334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 972718334Speter && (nonzero_bits (op0, mode) 972818334Speter & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0) 972918334Speter code = NE; 973018334Speter break; 973118334Speter 973218334Speter case LTU: 973318334Speter /* < C is equivalent to <= (C - 1). */ 973418334Speter if (const_op > 0) 973518334Speter { 973618334Speter const_op -= 1; 973718334Speter op1 = GEN_INT (const_op); 973818334Speter code = LEU; 973950397Sobrien /* ... fall through ... */ 974018334Speter } 974118334Speter 974218334Speter /* (unsigned) < 0x80000000 is equivalent to >= 0. */ 974350397Sobrien else if ((mode_width <= HOST_BITS_PER_WIDE_INT) 974450397Sobrien && (const_op == (HOST_WIDE_INT) 1 << (mode_width - 1))) 974518334Speter { 974618334Speter const_op = 0, op1 = const0_rtx; 974718334Speter code = GE; 974818334Speter break; 974918334Speter } 975018334Speter else 975118334Speter break; 975218334Speter 975318334Speter case LEU: 975418334Speter /* unsigned <= 0 is equivalent to == 0 */ 975518334Speter if (const_op == 0) 975618334Speter code = EQ; 975718334Speter 975850397Sobrien /* (unsigned) <= 0x7fffffff is equivalent to >= 0. */ 975950397Sobrien else if ((mode_width <= HOST_BITS_PER_WIDE_INT) 976050397Sobrien && (const_op == ((HOST_WIDE_INT) 1 << (mode_width - 1)) - 1)) 976118334Speter { 976218334Speter const_op = 0, op1 = const0_rtx; 976318334Speter code = GE; 976418334Speter } 976518334Speter break; 976618334Speter 976718334Speter case GEU: 976818334Speter /* >= C is equivalent to < (C - 1). */ 976918334Speter if (const_op > 1) 977018334Speter { 977118334Speter const_op -= 1; 977218334Speter op1 = GEN_INT (const_op); 977318334Speter code = GTU; 977450397Sobrien /* ... fall through ... */ 977518334Speter } 977618334Speter 977718334Speter /* (unsigned) >= 0x80000000 is equivalent to < 0. */ 977850397Sobrien else if ((mode_width <= HOST_BITS_PER_WIDE_INT) 977950397Sobrien && (const_op == (HOST_WIDE_INT) 1 << (mode_width - 1))) 978018334Speter { 978118334Speter const_op = 0, op1 = const0_rtx; 978218334Speter code = LT; 978318334Speter break; 978418334Speter } 978518334Speter else 978618334Speter break; 978718334Speter 978818334Speter case GTU: 978918334Speter /* unsigned > 0 is equivalent to != 0 */ 979018334Speter if (const_op == 0) 979118334Speter code = NE; 979218334Speter 979318334Speter /* (unsigned) > 0x7fffffff is equivalent to < 0. */ 979450397Sobrien else if ((mode_width <= HOST_BITS_PER_WIDE_INT) 979550397Sobrien && (const_op == ((HOST_WIDE_INT) 1 << (mode_width - 1)) - 1)) 979618334Speter { 979718334Speter const_op = 0, op1 = const0_rtx; 979818334Speter code = LT; 979918334Speter } 980018334Speter break; 980150397Sobrien 980250397Sobrien default: 980350397Sobrien break; 980418334Speter } 980518334Speter 980618334Speter /* Compute some predicates to simplify code below. */ 980718334Speter 980818334Speter equality_comparison_p = (code == EQ || code == NE); 980918334Speter sign_bit_comparison_p = ((code == LT || code == GE) && const_op == 0); 981018334Speter unsigned_comparison_p = (code == LTU || code == LEU || code == GTU 981118334Speter || code == LEU); 981218334Speter 981318334Speter /* If this is a sign bit comparison and we can do arithmetic in 981418334Speter MODE, say that we will only be needing the sign bit of OP0. */ 981518334Speter if (sign_bit_comparison_p 981618334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) 981718334Speter op0 = force_to_mode (op0, mode, 981818334Speter ((HOST_WIDE_INT) 1 981918334Speter << (GET_MODE_BITSIZE (mode) - 1)), 982018334Speter NULL_RTX, 0); 982118334Speter 982218334Speter /* Now try cases based on the opcode of OP0. If none of the cases 982318334Speter does a "continue", we exit this loop immediately after the 982418334Speter switch. */ 982518334Speter 982618334Speter switch (GET_CODE (op0)) 982718334Speter { 982818334Speter case ZERO_EXTRACT: 982918334Speter /* If we are extracting a single bit from a variable position in 983018334Speter a constant that has only a single bit set and are comparing it 983118334Speter with zero, we can convert this into an equality comparison 983250397Sobrien between the position and the location of the single bit. */ 983318334Speter 983418334Speter if (GET_CODE (XEXP (op0, 0)) == CONST_INT 983518334Speter && XEXP (op0, 1) == const1_rtx 983618334Speter && equality_comparison_p && const_op == 0 983750397Sobrien && (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0) 983818334Speter { 983950397Sobrien if (BITS_BIG_ENDIAN) 984052284Sobrien { 984118334Speter#ifdef HAVE_extzv 984252284Sobrien mode = insn_operand_mode[(int) CODE_FOR_extzv][1]; 984352284Sobrien if (mode == VOIDmode) 984452284Sobrien mode = word_mode; 984552284Sobrien i = (GET_MODE_BITSIZE (mode) - 1 - i); 984650397Sobrien#else 984752284Sobrien i = BITS_PER_WORD - 1 - i; 984818334Speter#endif 984952284Sobrien } 985018334Speter 985118334Speter op0 = XEXP (op0, 2); 985218334Speter op1 = GEN_INT (i); 985318334Speter const_op = i; 985418334Speter 985518334Speter /* Result is nonzero iff shift count is equal to I. */ 985618334Speter code = reverse_condition (code); 985718334Speter continue; 985818334Speter } 985918334Speter 986050397Sobrien /* ... fall through ... */ 986118334Speter 986218334Speter case SIGN_EXTRACT: 986318334Speter tem = expand_compound_operation (op0); 986418334Speter if (tem != op0) 986518334Speter { 986618334Speter op0 = tem; 986718334Speter continue; 986818334Speter } 986918334Speter break; 987018334Speter 987118334Speter case NOT: 987218334Speter /* If testing for equality, we can take the NOT of the constant. */ 987318334Speter if (equality_comparison_p 987418334Speter && (tem = simplify_unary_operation (NOT, mode, op1, mode)) != 0) 987518334Speter { 987618334Speter op0 = XEXP (op0, 0); 987718334Speter op1 = tem; 987818334Speter continue; 987918334Speter } 988018334Speter 988118334Speter /* If just looking at the sign bit, reverse the sense of the 988218334Speter comparison. */ 988318334Speter if (sign_bit_comparison_p) 988418334Speter { 988518334Speter op0 = XEXP (op0, 0); 988618334Speter code = (code == GE ? LT : GE); 988718334Speter continue; 988818334Speter } 988918334Speter break; 989018334Speter 989118334Speter case NEG: 989218334Speter /* If testing for equality, we can take the NEG of the constant. */ 989318334Speter if (equality_comparison_p 989418334Speter && (tem = simplify_unary_operation (NEG, mode, op1, mode)) != 0) 989518334Speter { 989618334Speter op0 = XEXP (op0, 0); 989718334Speter op1 = tem; 989818334Speter continue; 989918334Speter } 990018334Speter 990118334Speter /* The remaining cases only apply to comparisons with zero. */ 990218334Speter if (const_op != 0) 990318334Speter break; 990418334Speter 990518334Speter /* When X is ABS or is known positive, 990618334Speter (neg X) is < 0 if and only if X != 0. */ 990718334Speter 990818334Speter if (sign_bit_comparison_p 990918334Speter && (GET_CODE (XEXP (op0, 0)) == ABS 991018334Speter || (mode_width <= HOST_BITS_PER_WIDE_INT 991118334Speter && (nonzero_bits (XEXP (op0, 0), mode) 991218334Speter & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0))) 991318334Speter { 991418334Speter op0 = XEXP (op0, 0); 991518334Speter code = (code == LT ? NE : EQ); 991618334Speter continue; 991718334Speter } 991818334Speter 991918334Speter /* If we have NEG of something whose two high-order bits are the 992050397Sobrien same, we know that "(-a) < 0" is equivalent to "a > 0". */ 992118334Speter if (num_sign_bit_copies (op0, mode) >= 2) 992218334Speter { 992318334Speter op0 = XEXP (op0, 0); 992418334Speter code = swap_condition (code); 992518334Speter continue; 992618334Speter } 992718334Speter break; 992818334Speter 992918334Speter case ROTATE: 993018334Speter /* If we are testing equality and our count is a constant, we 993118334Speter can perform the inverse operation on our RHS. */ 993218334Speter if (equality_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT 993318334Speter && (tem = simplify_binary_operation (ROTATERT, mode, 993418334Speter op1, XEXP (op0, 1))) != 0) 993518334Speter { 993618334Speter op0 = XEXP (op0, 0); 993718334Speter op1 = tem; 993818334Speter continue; 993918334Speter } 994018334Speter 994118334Speter /* If we are doing a < 0 or >= 0 comparison, it means we are testing 994218334Speter a particular bit. Convert it to an AND of a constant of that 994318334Speter bit. This will be converted into a ZERO_EXTRACT. */ 994418334Speter if (const_op == 0 && sign_bit_comparison_p 994518334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 994618334Speter && mode_width <= HOST_BITS_PER_WIDE_INT) 994718334Speter { 994818334Speter op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0), 994918334Speter ((HOST_WIDE_INT) 1 995018334Speter << (mode_width - 1 995118334Speter - INTVAL (XEXP (op0, 1))))); 995218334Speter code = (code == LT ? NE : EQ); 995318334Speter continue; 995418334Speter } 995518334Speter 995650397Sobrien /* ... fall through ... */ 995718334Speter 995818334Speter case ABS: 995918334Speter /* ABS is ignorable inside an equality comparison with zero. */ 996018334Speter if (const_op == 0 && equality_comparison_p) 996118334Speter { 996218334Speter op0 = XEXP (op0, 0); 996318334Speter continue; 996418334Speter } 996518334Speter break; 996618334Speter 996718334Speter 996818334Speter case SIGN_EXTEND: 996918334Speter /* Can simplify (compare (zero/sign_extend FOO) CONST) 997018334Speter to (compare FOO CONST) if CONST fits in FOO's mode and we 997118334Speter are either testing inequality or have an unsigned comparison 997218334Speter with ZERO_EXTEND or a signed comparison with SIGN_EXTEND. */ 997318334Speter if (! unsigned_comparison_p 997418334Speter && (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))) 997518334Speter <= HOST_BITS_PER_WIDE_INT) 997618334Speter && ((unsigned HOST_WIDE_INT) const_op 997752284Sobrien < (((unsigned HOST_WIDE_INT) 1 997818334Speter << (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))) - 1))))) 997918334Speter { 998018334Speter op0 = XEXP (op0, 0); 998118334Speter continue; 998218334Speter } 998318334Speter break; 998418334Speter 998518334Speter case SUBREG: 998618334Speter /* Check for the case where we are comparing A - C1 with C2, 998718334Speter both constants are smaller than 1/2 the maximum positive 998818334Speter value in MODE, and the comparison is equality or unsigned. 998918334Speter In that case, if A is either zero-extended to MODE or has 999018334Speter sufficient sign bits so that the high-order bit in MODE 999118334Speter is a copy of the sign in the inner mode, we can prove that it is 999218334Speter safe to do the operation in the wider mode. This simplifies 999318334Speter many range checks. */ 999418334Speter 999518334Speter if (mode_width <= HOST_BITS_PER_WIDE_INT 999618334Speter && subreg_lowpart_p (op0) 999718334Speter && GET_CODE (SUBREG_REG (op0)) == PLUS 999818334Speter && GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT 999918334Speter && INTVAL (XEXP (SUBREG_REG (op0), 1)) < 0 1000018334Speter && (- INTVAL (XEXP (SUBREG_REG (op0), 1)) 1000152284Sobrien < (HOST_WIDE_INT)(GET_MODE_MASK (mode) / 2)) 1000218334Speter && (unsigned HOST_WIDE_INT) const_op < GET_MODE_MASK (mode) / 2 1000318334Speter && (0 == (nonzero_bits (XEXP (SUBREG_REG (op0), 0), 1000418334Speter GET_MODE (SUBREG_REG (op0))) 1000518334Speter & ~ GET_MODE_MASK (mode)) 1000618334Speter || (num_sign_bit_copies (XEXP (SUBREG_REG (op0), 0), 1000718334Speter GET_MODE (SUBREG_REG (op0))) 1000818334Speter > (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) 1000918334Speter - GET_MODE_BITSIZE (mode))))) 1001018334Speter { 1001118334Speter op0 = SUBREG_REG (op0); 1001218334Speter continue; 1001318334Speter } 1001418334Speter 1001518334Speter /* If the inner mode is narrower and we are extracting the low part, 1001618334Speter we can treat the SUBREG as if it were a ZERO_EXTEND. */ 1001718334Speter if (subreg_lowpart_p (op0) 1001818334Speter && GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) < mode_width) 1001918334Speter /* Fall through */ ; 1002018334Speter else 1002118334Speter break; 1002218334Speter 1002350397Sobrien /* ... fall through ... */ 1002418334Speter 1002518334Speter case ZERO_EXTEND: 1002618334Speter if ((unsigned_comparison_p || equality_comparison_p) 1002718334Speter && (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))) 1002818334Speter <= HOST_BITS_PER_WIDE_INT) 1002918334Speter && ((unsigned HOST_WIDE_INT) const_op 1003018334Speter < GET_MODE_MASK (GET_MODE (XEXP (op0, 0))))) 1003118334Speter { 1003218334Speter op0 = XEXP (op0, 0); 1003318334Speter continue; 1003418334Speter } 1003518334Speter break; 1003618334Speter 1003718334Speter case PLUS: 1003818334Speter /* (eq (plus X A) B) -> (eq X (minus B A)). We can only do 1003918334Speter this for equality comparisons due to pathological cases involving 1004018334Speter overflows. */ 1004118334Speter if (equality_comparison_p 1004218334Speter && 0 != (tem = simplify_binary_operation (MINUS, mode, 1004318334Speter op1, XEXP (op0, 1)))) 1004418334Speter { 1004518334Speter op0 = XEXP (op0, 0); 1004618334Speter op1 = tem; 1004718334Speter continue; 1004818334Speter } 1004918334Speter 1005018334Speter /* (plus (abs X) (const_int -1)) is < 0 if and only if X == 0. */ 1005118334Speter if (const_op == 0 && XEXP (op0, 1) == constm1_rtx 1005218334Speter && GET_CODE (XEXP (op0, 0)) == ABS && sign_bit_comparison_p) 1005318334Speter { 1005418334Speter op0 = XEXP (XEXP (op0, 0), 0); 1005518334Speter code = (code == LT ? EQ : NE); 1005618334Speter continue; 1005718334Speter } 1005818334Speter break; 1005918334Speter 1006018334Speter case MINUS: 1006118334Speter /* (eq (minus A B) C) -> (eq A (plus B C)) or 1006218334Speter (eq B (minus A C)), whichever simplifies. We can only do 1006318334Speter this for equality comparisons due to pathological cases involving 1006418334Speter overflows. */ 1006518334Speter if (equality_comparison_p 1006618334Speter && 0 != (tem = simplify_binary_operation (PLUS, mode, 1006718334Speter XEXP (op0, 1), op1))) 1006818334Speter { 1006918334Speter op0 = XEXP (op0, 0); 1007018334Speter op1 = tem; 1007118334Speter continue; 1007218334Speter } 1007318334Speter 1007418334Speter if (equality_comparison_p 1007518334Speter && 0 != (tem = simplify_binary_operation (MINUS, mode, 1007618334Speter XEXP (op0, 0), op1))) 1007718334Speter { 1007818334Speter op0 = XEXP (op0, 1); 1007918334Speter op1 = tem; 1008018334Speter continue; 1008118334Speter } 1008218334Speter 1008318334Speter /* The sign bit of (minus (ashiftrt X C) X), where C is the number 1008418334Speter of bits in X minus 1, is one iff X > 0. */ 1008518334Speter if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 0)) == ASHIFTRT 1008618334Speter && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT 1008718334Speter && INTVAL (XEXP (XEXP (op0, 0), 1)) == mode_width - 1 1008818334Speter && rtx_equal_p (XEXP (XEXP (op0, 0), 0), XEXP (op0, 1))) 1008918334Speter { 1009018334Speter op0 = XEXP (op0, 1); 1009118334Speter code = (code == GE ? LE : GT); 1009218334Speter continue; 1009318334Speter } 1009418334Speter break; 1009518334Speter 1009618334Speter case XOR: 1009718334Speter /* (eq (xor A B) C) -> (eq A (xor B C)). This is a simplification 1009818334Speter if C is zero or B is a constant. */ 1009918334Speter if (equality_comparison_p 1010018334Speter && 0 != (tem = simplify_binary_operation (XOR, mode, 1010118334Speter XEXP (op0, 1), op1))) 1010218334Speter { 1010318334Speter op0 = XEXP (op0, 0); 1010418334Speter op1 = tem; 1010518334Speter continue; 1010618334Speter } 1010718334Speter break; 1010818334Speter 1010918334Speter case EQ: case NE: 1011018334Speter case LT: case LTU: case LE: case LEU: 1011118334Speter case GT: case GTU: case GE: case GEU: 1011218334Speter /* We can't do anything if OP0 is a condition code value, rather 1011318334Speter than an actual data value. */ 1011418334Speter if (const_op != 0 1011518334Speter#ifdef HAVE_cc0 1011618334Speter || XEXP (op0, 0) == cc0_rtx 1011718334Speter#endif 1011818334Speter || GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC) 1011918334Speter break; 1012018334Speter 1012118334Speter /* Get the two operands being compared. */ 1012218334Speter if (GET_CODE (XEXP (op0, 0)) == COMPARE) 1012318334Speter tem = XEXP (XEXP (op0, 0), 0), tem1 = XEXP (XEXP (op0, 0), 1); 1012418334Speter else 1012518334Speter tem = XEXP (op0, 0), tem1 = XEXP (op0, 1); 1012618334Speter 1012718334Speter /* Check for the cases where we simply want the result of the 1012818334Speter earlier test or the opposite of that result. */ 1012918334Speter if (code == NE 1013018334Speter || (code == EQ && reversible_comparison_p (op0)) 1013118334Speter || (GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT 1013218334Speter && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT 1013318334Speter && (STORE_FLAG_VALUE 1013418334Speter & (((HOST_WIDE_INT) 1 1013518334Speter << (GET_MODE_BITSIZE (GET_MODE (op0)) - 1)))) 1013618334Speter && (code == LT 1013718334Speter || (code == GE && reversible_comparison_p (op0))))) 1013818334Speter { 1013918334Speter code = (code == LT || code == NE 1014018334Speter ? GET_CODE (op0) : reverse_condition (GET_CODE (op0))); 1014118334Speter op0 = tem, op1 = tem1; 1014218334Speter continue; 1014318334Speter } 1014418334Speter break; 1014518334Speter 1014618334Speter case IOR: 1014718334Speter /* The sign bit of (ior (plus X (const_int -1)) X) is non-zero 1014818334Speter iff X <= 0. */ 1014918334Speter if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 0)) == PLUS 1015018334Speter && XEXP (XEXP (op0, 0), 1) == constm1_rtx 1015118334Speter && rtx_equal_p (XEXP (XEXP (op0, 0), 0), XEXP (op0, 1))) 1015218334Speter { 1015318334Speter op0 = XEXP (op0, 1); 1015418334Speter code = (code == GE ? GT : LE); 1015518334Speter continue; 1015618334Speter } 1015718334Speter break; 1015818334Speter 1015918334Speter case AND: 1016018334Speter /* Convert (and (xshift 1 X) Y) to (and (lshiftrt Y X) 1). This 1016118334Speter will be converted to a ZERO_EXTRACT later. */ 1016218334Speter if (const_op == 0 && equality_comparison_p 1016318334Speter && GET_CODE (XEXP (op0, 0)) == ASHIFT 1016418334Speter && XEXP (XEXP (op0, 0), 0) == const1_rtx) 1016518334Speter { 1016618334Speter op0 = simplify_and_const_int 1016718334Speter (op0, mode, gen_rtx_combine (LSHIFTRT, mode, 1016818334Speter XEXP (op0, 1), 1016918334Speter XEXP (XEXP (op0, 0), 1)), 1017018334Speter (HOST_WIDE_INT) 1); 1017118334Speter continue; 1017218334Speter } 1017318334Speter 1017418334Speter /* If we are comparing (and (lshiftrt X C1) C2) for equality with 1017518334Speter zero and X is a comparison and C1 and C2 describe only bits set 1017618334Speter in STORE_FLAG_VALUE, we can compare with X. */ 1017718334Speter if (const_op == 0 && equality_comparison_p 1017818334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 1017918334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 1018018334Speter && GET_CODE (XEXP (op0, 0)) == LSHIFTRT 1018118334Speter && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT 1018218334Speter && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0 1018318334Speter && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT) 1018418334Speter { 1018518334Speter mask = ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode)) 1018618334Speter << INTVAL (XEXP (XEXP (op0, 0), 1))); 1018718334Speter if ((~ STORE_FLAG_VALUE & mask) == 0 1018818334Speter && (GET_RTX_CLASS (GET_CODE (XEXP (XEXP (op0, 0), 0))) == '<' 1018918334Speter || ((tem = get_last_value (XEXP (XEXP (op0, 0), 0))) != 0 1019018334Speter && GET_RTX_CLASS (GET_CODE (tem)) == '<'))) 1019118334Speter { 1019218334Speter op0 = XEXP (XEXP (op0, 0), 0); 1019318334Speter continue; 1019418334Speter } 1019518334Speter } 1019618334Speter 1019718334Speter /* If we are doing an equality comparison of an AND of a bit equal 1019818334Speter to the sign bit, replace this with a LT or GE comparison of 1019918334Speter the underlying value. */ 1020018334Speter if (equality_comparison_p 1020118334Speter && const_op == 0 1020218334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 1020318334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 1020418334Speter && ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode)) 1020552284Sobrien == (unsigned HOST_WIDE_INT) 1 << (mode_width - 1))) 1020618334Speter { 1020718334Speter op0 = XEXP (op0, 0); 1020818334Speter code = (code == EQ ? GE : LT); 1020918334Speter continue; 1021018334Speter } 1021118334Speter 1021218334Speter /* If this AND operation is really a ZERO_EXTEND from a narrower 1021318334Speter mode, the constant fits within that mode, and this is either an 1021418334Speter equality or unsigned comparison, try to do this comparison in 1021518334Speter the narrower mode. */ 1021618334Speter if ((equality_comparison_p || unsigned_comparison_p) 1021718334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 1021818334Speter && (i = exact_log2 ((INTVAL (XEXP (op0, 1)) 1021918334Speter & GET_MODE_MASK (mode)) 1022018334Speter + 1)) >= 0 1022118334Speter && const_op >> i == 0 1022218334Speter && (tmode = mode_for_size (i, MODE_INT, 1)) != BLKmode) 1022318334Speter { 1022418334Speter op0 = gen_lowpart_for_combine (tmode, XEXP (op0, 0)); 1022518334Speter continue; 1022618334Speter } 1022750397Sobrien 1022850397Sobrien /* If this is (and:M1 (subreg:M2 X 0) (const_int C1)) where C1 fits 1022950397Sobrien in both M1 and M2 and the SUBREG is either paradoxical or 1023050397Sobrien represents the low part, permute the SUBREG and the AND and 1023150397Sobrien try again. */ 1023250397Sobrien if (GET_CODE (XEXP (op0, 0)) == SUBREG 1023350397Sobrien && ((mode_width 1023450397Sobrien >= GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0))))) 1023550397Sobrien#ifdef WORD_REGISTER_OPERATIONS 1023650397Sobrien || subreg_lowpart_p (XEXP (op0, 0)) 1023750397Sobrien#endif 1023850397Sobrien ) 1023950397Sobrien#ifndef WORD_REGISTER_OPERATIONS 1024050397Sobrien /* It is unsafe to commute the AND into the SUBREG if the SUBREG 1024150397Sobrien is paradoxical and WORD_REGISTER_OPERATIONS is not defined. 1024250397Sobrien As originally written the upper bits have a defined value 1024350397Sobrien due to the AND operation. However, if we commute the AND 1024450397Sobrien inside the SUBREG then they no longer have defined values 1024550397Sobrien and the meaning of the code has been changed. */ 1024650397Sobrien && (GET_MODE_SIZE (GET_MODE (XEXP (op0, 0))) 1024750397Sobrien <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0))))) 1024850397Sobrien#endif 1024950397Sobrien && GET_CODE (XEXP (op0, 1)) == CONST_INT 1025050397Sobrien && mode_width <= HOST_BITS_PER_WIDE_INT 1025150397Sobrien && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0)))) 1025250397Sobrien <= HOST_BITS_PER_WIDE_INT) 1025350397Sobrien && (INTVAL (XEXP (op0, 1)) & ~ mask) == 0 1025450397Sobrien && 0 == (~ GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0)))) 1025550397Sobrien & INTVAL (XEXP (op0, 1))) 1025652284Sobrien && (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1)) != mask 1025752284Sobrien && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1)) 1025850397Sobrien != GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0)))))) 1025950397Sobrien 1026050397Sobrien { 1026150397Sobrien op0 1026250397Sobrien = gen_lowpart_for_combine 1026350397Sobrien (mode, 1026450397Sobrien gen_binary (AND, GET_MODE (SUBREG_REG (XEXP (op0, 0))), 1026550397Sobrien SUBREG_REG (XEXP (op0, 0)), XEXP (op0, 1))); 1026650397Sobrien continue; 1026750397Sobrien } 1026850397Sobrien 1026918334Speter break; 1027018334Speter 1027118334Speter case ASHIFT: 1027218334Speter /* If we have (compare (ashift FOO N) (const_int C)) and 1027318334Speter the high order N bits of FOO (N+1 if an inequality comparison) 1027418334Speter are known to be zero, we can do this by comparing FOO with C 1027518334Speter shifted right N bits so long as the low-order N bits of C are 1027618334Speter zero. */ 1027718334Speter if (GET_CODE (XEXP (op0, 1)) == CONST_INT 1027818334Speter && INTVAL (XEXP (op0, 1)) >= 0 1027918334Speter && ((INTVAL (XEXP (op0, 1)) + ! equality_comparison_p) 1028018334Speter < HOST_BITS_PER_WIDE_INT) 1028118334Speter && ((const_op 1028218334Speter & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0) 1028318334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 1028418334Speter && (nonzero_bits (XEXP (op0, 0), mode) 1028518334Speter & ~ (mask >> (INTVAL (XEXP (op0, 1)) 1028618334Speter + ! equality_comparison_p))) == 0) 1028718334Speter { 1028818334Speter const_op >>= INTVAL (XEXP (op0, 1)); 1028918334Speter op1 = GEN_INT (const_op); 1029018334Speter op0 = XEXP (op0, 0); 1029118334Speter continue; 1029218334Speter } 1029318334Speter 1029418334Speter /* If we are doing a sign bit comparison, it means we are testing 1029518334Speter a particular bit. Convert it to the appropriate AND. */ 1029618334Speter if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT 1029718334Speter && mode_width <= HOST_BITS_PER_WIDE_INT) 1029818334Speter { 1029918334Speter op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0), 1030018334Speter ((HOST_WIDE_INT) 1 1030118334Speter << (mode_width - 1 1030218334Speter - INTVAL (XEXP (op0, 1))))); 1030318334Speter code = (code == LT ? NE : EQ); 1030418334Speter continue; 1030518334Speter } 1030618334Speter 1030718334Speter /* If this an equality comparison with zero and we are shifting 1030818334Speter the low bit to the sign bit, we can convert this to an AND of the 1030918334Speter low-order bit. */ 1031018334Speter if (const_op == 0 && equality_comparison_p 1031118334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 1031218334Speter && INTVAL (XEXP (op0, 1)) == mode_width - 1) 1031318334Speter { 1031418334Speter op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0), 1031518334Speter (HOST_WIDE_INT) 1); 1031618334Speter continue; 1031718334Speter } 1031818334Speter break; 1031918334Speter 1032018334Speter case ASHIFTRT: 1032118334Speter /* If this is an equality comparison with zero, we can do this 1032218334Speter as a logical shift, which might be much simpler. */ 1032318334Speter if (equality_comparison_p && const_op == 0 1032418334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT) 1032518334Speter { 1032618334Speter op0 = simplify_shift_const (NULL_RTX, LSHIFTRT, mode, 1032718334Speter XEXP (op0, 0), 1032818334Speter INTVAL (XEXP (op0, 1))); 1032918334Speter continue; 1033018334Speter } 1033118334Speter 1033218334Speter /* If OP0 is a sign extension and CODE is not an unsigned comparison, 1033318334Speter do the comparison in a narrower mode. */ 1033418334Speter if (! unsigned_comparison_p 1033518334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 1033618334Speter && GET_CODE (XEXP (op0, 0)) == ASHIFT 1033718334Speter && XEXP (op0, 1) == XEXP (XEXP (op0, 0), 1) 1033818334Speter && (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)), 1033918334Speter MODE_INT, 1)) != BLKmode 1034018334Speter && ((unsigned HOST_WIDE_INT) const_op <= GET_MODE_MASK (tmode) 1034118334Speter || ((unsigned HOST_WIDE_INT) - const_op 1034218334Speter <= GET_MODE_MASK (tmode)))) 1034318334Speter { 1034418334Speter op0 = gen_lowpart_for_combine (tmode, XEXP (XEXP (op0, 0), 0)); 1034518334Speter continue; 1034618334Speter } 1034718334Speter 1034850397Sobrien /* ... fall through ... */ 1034918334Speter case LSHIFTRT: 1035018334Speter /* If we have (compare (xshiftrt FOO N) (const_int C)) and 1035118334Speter the low order N bits of FOO are known to be zero, we can do this 1035218334Speter by comparing FOO with C shifted left N bits so long as no 1035318334Speter overflow occurs. */ 1035418334Speter if (GET_CODE (XEXP (op0, 1)) == CONST_INT 1035518334Speter && INTVAL (XEXP (op0, 1)) >= 0 1035618334Speter && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT 1035718334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 1035818334Speter && (nonzero_bits (XEXP (op0, 0), mode) 1035918334Speter & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0 1036018334Speter && (const_op == 0 1036118334Speter || (floor_log2 (const_op) + INTVAL (XEXP (op0, 1)) 1036218334Speter < mode_width))) 1036318334Speter { 1036418334Speter const_op <<= INTVAL (XEXP (op0, 1)); 1036518334Speter op1 = GEN_INT (const_op); 1036618334Speter op0 = XEXP (op0, 0); 1036718334Speter continue; 1036818334Speter } 1036918334Speter 1037018334Speter /* If we are using this shift to extract just the sign bit, we 1037118334Speter can replace this with an LT or GE comparison. */ 1037218334Speter if (const_op == 0 1037318334Speter && (equality_comparison_p || sign_bit_comparison_p) 1037418334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 1037518334Speter && INTVAL (XEXP (op0, 1)) == mode_width - 1) 1037618334Speter { 1037718334Speter op0 = XEXP (op0, 0); 1037818334Speter code = (code == NE || code == GT ? LT : GE); 1037918334Speter continue; 1038018334Speter } 1038118334Speter break; 1038250397Sobrien 1038350397Sobrien default: 1038450397Sobrien break; 1038518334Speter } 1038618334Speter 1038718334Speter break; 1038818334Speter } 1038918334Speter 1039018334Speter /* Now make any compound operations involved in this comparison. Then, 1039150397Sobrien check for an outmost SUBREG on OP0 that is not doing anything or is 1039218334Speter paradoxical. The latter case can only occur when it is known that the 1039318334Speter "extra" bits will be zero. Therefore, it is safe to remove the SUBREG. 1039418334Speter We can never remove a SUBREG for a non-equality comparison because the 1039518334Speter sign bit is in a different place in the underlying object. */ 1039618334Speter 1039718334Speter op0 = make_compound_operation (op0, op1 == const0_rtx ? COMPARE : SET); 1039818334Speter op1 = make_compound_operation (op1, SET); 1039918334Speter 1040018334Speter if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0) 1040118334Speter && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT 1040218334Speter && (code == NE || code == EQ) 1040318334Speter && ((GET_MODE_SIZE (GET_MODE (op0)) 1040418334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))) 1040518334Speter { 1040618334Speter op0 = SUBREG_REG (op0); 1040718334Speter op1 = gen_lowpart_for_combine (GET_MODE (op0), op1); 1040818334Speter } 1040918334Speter 1041018334Speter else if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0) 1041118334Speter && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT 1041218334Speter && (code == NE || code == EQ) 1041318334Speter && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) 1041418334Speter <= HOST_BITS_PER_WIDE_INT) 1041518334Speter && (nonzero_bits (SUBREG_REG (op0), GET_MODE (SUBREG_REG (op0))) 1041618334Speter & ~ GET_MODE_MASK (GET_MODE (op0))) == 0 1041718334Speter && (tem = gen_lowpart_for_combine (GET_MODE (SUBREG_REG (op0)), 1041818334Speter op1), 1041918334Speter (nonzero_bits (tem, GET_MODE (SUBREG_REG (op0))) 1042018334Speter & ~ GET_MODE_MASK (GET_MODE (op0))) == 0)) 1042118334Speter op0 = SUBREG_REG (op0), op1 = tem; 1042218334Speter 1042318334Speter /* We now do the opposite procedure: Some machines don't have compare 1042418334Speter insns in all modes. If OP0's mode is an integer mode smaller than a 1042518334Speter word and we can't do a compare in that mode, see if there is a larger 1042618334Speter mode for which we can do the compare. There are a number of cases in 1042718334Speter which we can use the wider mode. */ 1042818334Speter 1042918334Speter mode = GET_MODE (op0); 1043018334Speter if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT 1043118334Speter && GET_MODE_SIZE (mode) < UNITS_PER_WORD 1043218334Speter && cmp_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) 1043318334Speter for (tmode = GET_MODE_WIDER_MODE (mode); 1043418334Speter (tmode != VOIDmode 1043518334Speter && GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT); 1043618334Speter tmode = GET_MODE_WIDER_MODE (tmode)) 1043718334Speter if (cmp_optab->handlers[(int) tmode].insn_code != CODE_FOR_nothing) 1043818334Speter { 1043918334Speter /* If the only nonzero bits in OP0 and OP1 are those in the 1044018334Speter narrower mode and this is an equality or unsigned comparison, 1044118334Speter we can use the wider mode. Similarly for sign-extended 1044218334Speter values, in which case it is true for all comparisons. */ 1044318334Speter if (((code == EQ || code == NE 1044418334Speter || code == GEU || code == GTU || code == LEU || code == LTU) 1044518334Speter && (nonzero_bits (op0, tmode) & ~ GET_MODE_MASK (mode)) == 0 1044618334Speter && (nonzero_bits (op1, tmode) & ~ GET_MODE_MASK (mode)) == 0) 1044718334Speter || ((num_sign_bit_copies (op0, tmode) 1044818334Speter > GET_MODE_BITSIZE (tmode) - GET_MODE_BITSIZE (mode)) 1044918334Speter && (num_sign_bit_copies (op1, tmode) 1045018334Speter > GET_MODE_BITSIZE (tmode) - GET_MODE_BITSIZE (mode)))) 1045118334Speter { 1045218334Speter op0 = gen_lowpart_for_combine (tmode, op0); 1045318334Speter op1 = gen_lowpart_for_combine (tmode, op1); 1045418334Speter break; 1045518334Speter } 1045618334Speter 1045718334Speter /* If this is a test for negative, we can make an explicit 1045818334Speter test of the sign bit. */ 1045918334Speter 1046018334Speter if (op1 == const0_rtx && (code == LT || code == GE) 1046118334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) 1046218334Speter { 1046318334Speter op0 = gen_binary (AND, tmode, 1046418334Speter gen_lowpart_for_combine (tmode, op0), 1046518334Speter GEN_INT ((HOST_WIDE_INT) 1 1046618334Speter << (GET_MODE_BITSIZE (mode) - 1))); 1046718334Speter code = (code == LT) ? NE : EQ; 1046818334Speter break; 1046918334Speter } 1047018334Speter } 1047118334Speter 1047218334Speter#ifdef CANONICALIZE_COMPARISON 1047318334Speter /* If this machine only supports a subset of valid comparisons, see if we 1047418334Speter can convert an unsupported one into a supported one. */ 1047518334Speter CANONICALIZE_COMPARISON (code, op0, op1); 1047618334Speter#endif 1047718334Speter 1047818334Speter *pop0 = op0; 1047918334Speter *pop1 = op1; 1048018334Speter 1048118334Speter return code; 1048218334Speter} 1048318334Speter 1048418334Speter/* Return 1 if we know that X, a comparison operation, is not operating 1048518334Speter on a floating-point value or is EQ or NE, meaning that we can safely 1048618334Speter reverse it. */ 1048718334Speter 1048818334Speterstatic int 1048918334Speterreversible_comparison_p (x) 1049018334Speter rtx x; 1049118334Speter{ 1049218334Speter if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT 1049318334Speter || flag_fast_math 1049418334Speter || GET_CODE (x) == NE || GET_CODE (x) == EQ) 1049518334Speter return 1; 1049618334Speter 1049718334Speter switch (GET_MODE_CLASS (GET_MODE (XEXP (x, 0)))) 1049818334Speter { 1049918334Speter case MODE_INT: 1050018334Speter case MODE_PARTIAL_INT: 1050118334Speter case MODE_COMPLEX_INT: 1050218334Speter return 1; 1050318334Speter 1050418334Speter case MODE_CC: 1050518334Speter /* If the mode of the condition codes tells us that this is safe, 1050618334Speter we need look no further. */ 1050718334Speter if (REVERSIBLE_CC_MODE (GET_MODE (XEXP (x, 0)))) 1050818334Speter return 1; 1050918334Speter 1051018334Speter /* Otherwise try and find where the condition codes were last set and 1051118334Speter use that. */ 1051218334Speter x = get_last_value (XEXP (x, 0)); 1051318334Speter return (x && GET_CODE (x) == COMPARE 1051418334Speter && ! FLOAT_MODE_P (GET_MODE (XEXP (x, 0)))); 1051550397Sobrien 1051650397Sobrien default: 1051750397Sobrien return 0; 1051818334Speter } 1051918334Speter} 1052018334Speter 1052118334Speter/* Utility function for following routine. Called when X is part of a value 1052218334Speter being stored into reg_last_set_value. Sets reg_last_set_table_tick 1052318334Speter for each register mentioned. Similar to mention_regs in cse.c */ 1052418334Speter 1052518334Speterstatic void 1052618334Speterupdate_table_tick (x) 1052718334Speter rtx x; 1052818334Speter{ 1052918334Speter register enum rtx_code code = GET_CODE (x); 1053018334Speter register char *fmt = GET_RTX_FORMAT (code); 1053118334Speter register int i; 1053218334Speter 1053318334Speter if (code == REG) 1053418334Speter { 1053518334Speter int regno = REGNO (x); 1053618334Speter int endregno = regno + (regno < FIRST_PSEUDO_REGISTER 1053718334Speter ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1); 1053818334Speter 1053918334Speter for (i = regno; i < endregno; i++) 1054018334Speter reg_last_set_table_tick[i] = label_tick; 1054118334Speter 1054218334Speter return; 1054318334Speter } 1054418334Speter 1054518334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 1054618334Speter /* Note that we can't have an "E" in values stored; see 1054718334Speter get_last_value_validate. */ 1054818334Speter if (fmt[i] == 'e') 1054918334Speter update_table_tick (XEXP (x, i)); 1055018334Speter} 1055118334Speter 1055218334Speter/* Record that REG is set to VALUE in insn INSN. If VALUE is zero, we 1055318334Speter are saying that the register is clobbered and we no longer know its 1055418334Speter value. If INSN is zero, don't update reg_last_set; this is only permitted 1055518334Speter with VALUE also zero and is used to invalidate the register. */ 1055618334Speter 1055718334Speterstatic void 1055818334Speterrecord_value_for_reg (reg, insn, value) 1055918334Speter rtx reg; 1056018334Speter rtx insn; 1056118334Speter rtx value; 1056218334Speter{ 1056318334Speter int regno = REGNO (reg); 1056418334Speter int endregno = regno + (regno < FIRST_PSEUDO_REGISTER 1056518334Speter ? HARD_REGNO_NREGS (regno, GET_MODE (reg)) : 1); 1056618334Speter int i; 1056718334Speter 1056818334Speter /* If VALUE contains REG and we have a previous value for REG, substitute 1056918334Speter the previous value. */ 1057018334Speter if (value && insn && reg_overlap_mentioned_p (reg, value)) 1057118334Speter { 1057218334Speter rtx tem; 1057318334Speter 1057418334Speter /* Set things up so get_last_value is allowed to see anything set up to 1057518334Speter our insn. */ 1057618334Speter subst_low_cuid = INSN_CUID (insn); 1057718334Speter tem = get_last_value (reg); 1057818334Speter 1057918334Speter if (tem) 1058018334Speter value = replace_rtx (copy_rtx (value), reg, tem); 1058118334Speter } 1058218334Speter 1058318334Speter /* For each register modified, show we don't know its value, that 1058418334Speter we don't know about its bitwise content, that its value has been 1058518334Speter updated, and that we don't know the location of the death of the 1058618334Speter register. */ 1058718334Speter for (i = regno; i < endregno; i ++) 1058818334Speter { 1058918334Speter if (insn) 1059018334Speter reg_last_set[i] = insn; 1059118334Speter reg_last_set_value[i] = 0; 1059218334Speter reg_last_set_mode[i] = 0; 1059318334Speter reg_last_set_nonzero_bits[i] = 0; 1059418334Speter reg_last_set_sign_bit_copies[i] = 0; 1059518334Speter reg_last_death[i] = 0; 1059618334Speter } 1059718334Speter 1059818334Speter /* Mark registers that are being referenced in this value. */ 1059918334Speter if (value) 1060018334Speter update_table_tick (value); 1060118334Speter 1060218334Speter /* Now update the status of each register being set. 1060318334Speter If someone is using this register in this block, set this register 1060418334Speter to invalid since we will get confused between the two lives in this 1060518334Speter basic block. This makes using this register always invalid. In cse, we 1060618334Speter scan the table to invalidate all entries using this register, but this 1060718334Speter is too much work for us. */ 1060818334Speter 1060918334Speter for (i = regno; i < endregno; i++) 1061018334Speter { 1061118334Speter reg_last_set_label[i] = label_tick; 1061218334Speter if (value && reg_last_set_table_tick[i] == label_tick) 1061318334Speter reg_last_set_invalid[i] = 1; 1061418334Speter else 1061518334Speter reg_last_set_invalid[i] = 0; 1061618334Speter } 1061718334Speter 1061818334Speter /* The value being assigned might refer to X (like in "x++;"). In that 1061918334Speter case, we must replace it with (clobber (const_int 0)) to prevent 1062018334Speter infinite loops. */ 1062150397Sobrien if (value && ! get_last_value_validate (&value, insn, 1062218334Speter reg_last_set_label[regno], 0)) 1062318334Speter { 1062418334Speter value = copy_rtx (value); 1062550397Sobrien if (! get_last_value_validate (&value, insn, 1062650397Sobrien reg_last_set_label[regno], 1)) 1062718334Speter value = 0; 1062818334Speter } 1062918334Speter 1063018334Speter /* For the main register being modified, update the value, the mode, the 1063118334Speter nonzero bits, and the number of sign bit copies. */ 1063218334Speter 1063318334Speter reg_last_set_value[regno] = value; 1063418334Speter 1063518334Speter if (value) 1063618334Speter { 1063718334Speter subst_low_cuid = INSN_CUID (insn); 1063818334Speter reg_last_set_mode[regno] = GET_MODE (reg); 1063918334Speter reg_last_set_nonzero_bits[regno] = nonzero_bits (value, GET_MODE (reg)); 1064018334Speter reg_last_set_sign_bit_copies[regno] 1064118334Speter = num_sign_bit_copies (value, GET_MODE (reg)); 1064218334Speter } 1064318334Speter} 1064418334Speter 1064518334Speter/* Used for communication between the following two routines. */ 1064618334Speterstatic rtx record_dead_insn; 1064718334Speter 1064818334Speter/* Called via note_stores from record_dead_and_set_regs to handle one 1064918334Speter SET or CLOBBER in an insn. */ 1065018334Speter 1065118334Speterstatic void 1065218334Speterrecord_dead_and_set_regs_1 (dest, setter) 1065318334Speter rtx dest, setter; 1065418334Speter{ 1065518334Speter if (GET_CODE (dest) == SUBREG) 1065618334Speter dest = SUBREG_REG (dest); 1065718334Speter 1065818334Speter if (GET_CODE (dest) == REG) 1065918334Speter { 1066018334Speter /* If we are setting the whole register, we know its value. Otherwise 1066118334Speter show that we don't know the value. We can handle SUBREG in 1066218334Speter some cases. */ 1066318334Speter if (GET_CODE (setter) == SET && dest == SET_DEST (setter)) 1066418334Speter record_value_for_reg (dest, record_dead_insn, SET_SRC (setter)); 1066518334Speter else if (GET_CODE (setter) == SET 1066618334Speter && GET_CODE (SET_DEST (setter)) == SUBREG 1066718334Speter && SUBREG_REG (SET_DEST (setter)) == dest 1066818334Speter && GET_MODE_BITSIZE (GET_MODE (dest)) <= BITS_PER_WORD 1066918334Speter && subreg_lowpart_p (SET_DEST (setter))) 1067018334Speter record_value_for_reg (dest, record_dead_insn, 1067118334Speter gen_lowpart_for_combine (GET_MODE (dest), 1067218334Speter SET_SRC (setter))); 1067318334Speter else 1067418334Speter record_value_for_reg (dest, record_dead_insn, NULL_RTX); 1067518334Speter } 1067618334Speter else if (GET_CODE (dest) == MEM 1067718334Speter /* Ignore pushes, they clobber nothing. */ 1067818334Speter && ! push_operand (dest, GET_MODE (dest))) 1067918334Speter mem_last_set = INSN_CUID (record_dead_insn); 1068018334Speter} 1068118334Speter 1068218334Speter/* Update the records of when each REG was most recently set or killed 1068318334Speter for the things done by INSN. This is the last thing done in processing 1068418334Speter INSN in the combiner loop. 1068518334Speter 1068618334Speter We update reg_last_set, reg_last_set_value, reg_last_set_mode, 1068718334Speter reg_last_set_nonzero_bits, reg_last_set_sign_bit_copies, reg_last_death, 1068818334Speter and also the similar information mem_last_set (which insn most recently 1068918334Speter modified memory) and last_call_cuid (which insn was the most recent 1069018334Speter subroutine call). */ 1069118334Speter 1069218334Speterstatic void 1069318334Speterrecord_dead_and_set_regs (insn) 1069418334Speter rtx insn; 1069518334Speter{ 1069618334Speter register rtx link; 1069718334Speter int i; 1069818334Speter 1069918334Speter for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) 1070018334Speter { 1070118334Speter if (REG_NOTE_KIND (link) == REG_DEAD 1070218334Speter && GET_CODE (XEXP (link, 0)) == REG) 1070318334Speter { 1070418334Speter int regno = REGNO (XEXP (link, 0)); 1070518334Speter int endregno 1070618334Speter = regno + (regno < FIRST_PSEUDO_REGISTER 1070718334Speter ? HARD_REGNO_NREGS (regno, GET_MODE (XEXP (link, 0))) 1070818334Speter : 1); 1070918334Speter 1071018334Speter for (i = regno; i < endregno; i++) 1071118334Speter reg_last_death[i] = insn; 1071218334Speter } 1071318334Speter else if (REG_NOTE_KIND (link) == REG_INC) 1071418334Speter record_value_for_reg (XEXP (link, 0), insn, NULL_RTX); 1071518334Speter } 1071618334Speter 1071718334Speter if (GET_CODE (insn) == CALL_INSN) 1071818334Speter { 1071918334Speter for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 1072018334Speter if (call_used_regs[i]) 1072118334Speter { 1072218334Speter reg_last_set_value[i] = 0; 1072318334Speter reg_last_set_mode[i] = 0; 1072418334Speter reg_last_set_nonzero_bits[i] = 0; 1072518334Speter reg_last_set_sign_bit_copies[i] = 0; 1072618334Speter reg_last_death[i] = 0; 1072718334Speter } 1072818334Speter 1072918334Speter last_call_cuid = mem_last_set = INSN_CUID (insn); 1073018334Speter } 1073118334Speter 1073218334Speter record_dead_insn = insn; 1073318334Speter note_stores (PATTERN (insn), record_dead_and_set_regs_1); 1073418334Speter} 1073518334Speter 1073618334Speter/* Utility routine for the following function. Verify that all the registers 1073718334Speter mentioned in *LOC are valid when *LOC was part of a value set when 1073818334Speter label_tick == TICK. Return 0 if some are not. 1073918334Speter 1074018334Speter If REPLACE is non-zero, replace the invalid reference with 1074118334Speter (clobber (const_int 0)) and return 1. This replacement is useful because 1074218334Speter we often can get useful information about the form of a value (e.g., if 1074318334Speter it was produced by a shift that always produces -1 or 0) even though 1074418334Speter we don't know exactly what registers it was produced from. */ 1074518334Speter 1074618334Speterstatic int 1074750397Sobrienget_last_value_validate (loc, insn, tick, replace) 1074818334Speter rtx *loc; 1074950397Sobrien rtx insn; 1075018334Speter int tick; 1075118334Speter int replace; 1075218334Speter{ 1075318334Speter rtx x = *loc; 1075418334Speter char *fmt = GET_RTX_FORMAT (GET_CODE (x)); 1075518334Speter int len = GET_RTX_LENGTH (GET_CODE (x)); 1075618334Speter int i; 1075718334Speter 1075818334Speter if (GET_CODE (x) == REG) 1075918334Speter { 1076018334Speter int regno = REGNO (x); 1076118334Speter int endregno = regno + (regno < FIRST_PSEUDO_REGISTER 1076218334Speter ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1); 1076318334Speter int j; 1076418334Speter 1076518334Speter for (j = regno; j < endregno; j++) 1076618334Speter if (reg_last_set_invalid[j] 1076718334Speter /* If this is a pseudo-register that was only set once, it is 1076818334Speter always valid. */ 1076950397Sobrien || (! (regno >= FIRST_PSEUDO_REGISTER && REG_N_SETS (regno) == 1) 1077018334Speter && reg_last_set_label[j] > tick)) 1077118334Speter { 1077218334Speter if (replace) 1077350397Sobrien *loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx); 1077418334Speter return replace; 1077518334Speter } 1077618334Speter 1077718334Speter return 1; 1077818334Speter } 1077950397Sobrien /* If this is a memory reference, make sure that there were 1078050397Sobrien no stores after it that might have clobbered the value. We don't 1078150397Sobrien have alias info, so we assume any store invalidates it. */ 1078250397Sobrien else if (GET_CODE (x) == MEM && ! RTX_UNCHANGING_P (x) 1078350397Sobrien && INSN_CUID (insn) <= mem_last_set) 1078450397Sobrien { 1078550397Sobrien if (replace) 1078650397Sobrien *loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx); 1078750397Sobrien return replace; 1078850397Sobrien } 1078918334Speter 1079018334Speter for (i = 0; i < len; i++) 1079118334Speter if ((fmt[i] == 'e' 1079250397Sobrien && get_last_value_validate (&XEXP (x, i), insn, tick, replace) == 0) 1079318334Speter /* Don't bother with these. They shouldn't occur anyway. */ 1079418334Speter || fmt[i] == 'E') 1079518334Speter return 0; 1079618334Speter 1079718334Speter /* If we haven't found a reason for it to be invalid, it is valid. */ 1079818334Speter return 1; 1079918334Speter} 1080018334Speter 1080118334Speter/* Get the last value assigned to X, if known. Some registers 1080218334Speter in the value may be replaced with (clobber (const_int 0)) if their value 1080318334Speter is known longer known reliably. */ 1080418334Speter 1080518334Speterstatic rtx 1080618334Speterget_last_value (x) 1080718334Speter rtx x; 1080818334Speter{ 1080918334Speter int regno; 1081018334Speter rtx value; 1081118334Speter 1081218334Speter /* If this is a non-paradoxical SUBREG, get the value of its operand and 1081318334Speter then convert it to the desired mode. If this is a paradoxical SUBREG, 1081450397Sobrien we cannot predict what values the "extra" bits might have. */ 1081518334Speter if (GET_CODE (x) == SUBREG 1081618334Speter && subreg_lowpart_p (x) 1081718334Speter && (GET_MODE_SIZE (GET_MODE (x)) 1081818334Speter <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) 1081918334Speter && (value = get_last_value (SUBREG_REG (x))) != 0) 1082018334Speter return gen_lowpart_for_combine (GET_MODE (x), value); 1082118334Speter 1082218334Speter if (GET_CODE (x) != REG) 1082318334Speter return 0; 1082418334Speter 1082518334Speter regno = REGNO (x); 1082618334Speter value = reg_last_set_value[regno]; 1082718334Speter 1082850397Sobrien /* If we don't have a value or if it isn't for this basic block, 1082950397Sobrien return 0. */ 1083018334Speter 1083118334Speter if (value == 0 1083250397Sobrien || (REG_N_SETS (regno) != 1 1083318334Speter && reg_last_set_label[regno] != label_tick)) 1083418334Speter return 0; 1083518334Speter 1083618334Speter /* If the value was set in a later insn than the ones we are processing, 1083718334Speter we can't use it even if the register was only set once, but make a quick 1083818334Speter check to see if the previous insn set it to something. This is commonly 1083918334Speter the case when the same pseudo is used by repeated insns. 1084018334Speter 1084118334Speter This does not work if there exists an instruction which is temporarily 1084218334Speter not on the insn chain. */ 1084318334Speter 1084418334Speter if (INSN_CUID (reg_last_set[regno]) >= subst_low_cuid) 1084518334Speter { 1084618334Speter rtx insn, set; 1084718334Speter 1084818334Speter /* We can not do anything useful in this case, because there is 1084918334Speter an instruction which is not on the insn chain. */ 1085018334Speter if (subst_prev_insn) 1085118334Speter return 0; 1085218334Speter 1085318334Speter /* Skip over USE insns. They are not useful here, and they may have 1085418334Speter been made by combine, in which case they do not have a INSN_CUID 1085518334Speter value. We can't use prev_real_insn, because that would incorrectly 1085618334Speter take us backwards across labels. Skip over BARRIERs also, since 1085718334Speter they could have been made by combine. If we see one, we must be 1085818334Speter optimizing dead code, so it doesn't matter what we do. */ 1085918334Speter for (insn = prev_nonnote_insn (subst_insn); 1086018334Speter insn && ((GET_CODE (insn) == INSN 1086118334Speter && GET_CODE (PATTERN (insn)) == USE) 1086218334Speter || GET_CODE (insn) == BARRIER 1086318334Speter || INSN_CUID (insn) >= subst_low_cuid); 1086418334Speter insn = prev_nonnote_insn (insn)) 1086518334Speter ; 1086618334Speter 1086718334Speter if (insn 1086818334Speter && (set = single_set (insn)) != 0 1086918334Speter && rtx_equal_p (SET_DEST (set), x)) 1087018334Speter { 1087118334Speter value = SET_SRC (set); 1087218334Speter 1087318334Speter /* Make sure that VALUE doesn't reference X. Replace any 1087418334Speter explicit references with a CLOBBER. If there are any remaining 1087518334Speter references (rare), don't use the value. */ 1087618334Speter 1087718334Speter if (reg_mentioned_p (x, value)) 1087818334Speter value = replace_rtx (copy_rtx (value), x, 1087950397Sobrien gen_rtx_CLOBBER (GET_MODE (x), const0_rtx)); 1088018334Speter 1088118334Speter if (reg_overlap_mentioned_p (x, value)) 1088218334Speter return 0; 1088318334Speter } 1088418334Speter else 1088518334Speter return 0; 1088618334Speter } 1088718334Speter 1088818334Speter /* If the value has all its registers valid, return it. */ 1088950397Sobrien if (get_last_value_validate (&value, reg_last_set[regno], 1089050397Sobrien reg_last_set_label[regno], 0)) 1089118334Speter return value; 1089218334Speter 1089318334Speter /* Otherwise, make a copy and replace any invalid register with 1089418334Speter (clobber (const_int 0)). If that fails for some reason, return 0. */ 1089518334Speter 1089618334Speter value = copy_rtx (value); 1089750397Sobrien if (get_last_value_validate (&value, reg_last_set[regno], 1089850397Sobrien reg_last_set_label[regno], 1)) 1089918334Speter return value; 1090018334Speter 1090118334Speter return 0; 1090218334Speter} 1090318334Speter 1090418334Speter/* Return nonzero if expression X refers to a REG or to memory 1090518334Speter that is set in an instruction more recent than FROM_CUID. */ 1090618334Speter 1090718334Speterstatic int 1090818334Speteruse_crosses_set_p (x, from_cuid) 1090918334Speter register rtx x; 1091018334Speter int from_cuid; 1091118334Speter{ 1091218334Speter register char *fmt; 1091318334Speter register int i; 1091418334Speter register enum rtx_code code = GET_CODE (x); 1091518334Speter 1091618334Speter if (code == REG) 1091718334Speter { 1091818334Speter register int regno = REGNO (x); 1091918334Speter int endreg = regno + (regno < FIRST_PSEUDO_REGISTER 1092018334Speter ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1); 1092118334Speter 1092218334Speter#ifdef PUSH_ROUNDING 1092318334Speter /* Don't allow uses of the stack pointer to be moved, 1092418334Speter because we don't know whether the move crosses a push insn. */ 1092518334Speter if (regno == STACK_POINTER_REGNUM) 1092618334Speter return 1; 1092718334Speter#endif 1092818334Speter for (;regno < endreg; regno++) 1092918334Speter if (reg_last_set[regno] 1093018334Speter && INSN_CUID (reg_last_set[regno]) > from_cuid) 1093118334Speter return 1; 1093218334Speter return 0; 1093318334Speter } 1093418334Speter 1093518334Speter if (code == MEM && mem_last_set > from_cuid) 1093618334Speter return 1; 1093718334Speter 1093818334Speter fmt = GET_RTX_FORMAT (code); 1093918334Speter 1094018334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 1094118334Speter { 1094218334Speter if (fmt[i] == 'E') 1094318334Speter { 1094418334Speter register int j; 1094518334Speter for (j = XVECLEN (x, i) - 1; j >= 0; j--) 1094618334Speter if (use_crosses_set_p (XVECEXP (x, i, j), from_cuid)) 1094718334Speter return 1; 1094818334Speter } 1094918334Speter else if (fmt[i] == 'e' 1095018334Speter && use_crosses_set_p (XEXP (x, i), from_cuid)) 1095118334Speter return 1; 1095218334Speter } 1095318334Speter return 0; 1095418334Speter} 1095518334Speter 1095618334Speter/* Define three variables used for communication between the following 1095718334Speter routines. */ 1095818334Speter 1095918334Speterstatic int reg_dead_regno, reg_dead_endregno; 1096018334Speterstatic int reg_dead_flag; 1096118334Speter 1096218334Speter/* Function called via note_stores from reg_dead_at_p. 1096318334Speter 1096418334Speter If DEST is within [reg_dead_regno, reg_dead_endregno), set 1096518334Speter reg_dead_flag to 1 if X is a CLOBBER and to -1 it is a SET. */ 1096618334Speter 1096718334Speterstatic void 1096818334Speterreg_dead_at_p_1 (dest, x) 1096918334Speter rtx dest; 1097018334Speter rtx x; 1097118334Speter{ 1097218334Speter int regno, endregno; 1097318334Speter 1097418334Speter if (GET_CODE (dest) != REG) 1097518334Speter return; 1097618334Speter 1097718334Speter regno = REGNO (dest); 1097818334Speter endregno = regno + (regno < FIRST_PSEUDO_REGISTER 1097918334Speter ? HARD_REGNO_NREGS (regno, GET_MODE (dest)) : 1); 1098018334Speter 1098118334Speter if (reg_dead_endregno > regno && reg_dead_regno < endregno) 1098218334Speter reg_dead_flag = (GET_CODE (x) == CLOBBER) ? 1 : -1; 1098318334Speter} 1098418334Speter 1098518334Speter/* Return non-zero if REG is known to be dead at INSN. 1098618334Speter 1098718334Speter We scan backwards from INSN. If we hit a REG_DEAD note or a CLOBBER 1098818334Speter referencing REG, it is dead. If we hit a SET referencing REG, it is 1098918334Speter live. Otherwise, see if it is live or dead at the start of the basic 1099018334Speter block we are in. Hard regs marked as being live in NEWPAT_USED_REGS 1099118334Speter must be assumed to be always live. */ 1099218334Speter 1099318334Speterstatic int 1099418334Speterreg_dead_at_p (reg, insn) 1099518334Speter rtx reg; 1099618334Speter rtx insn; 1099718334Speter{ 1099818334Speter int block, i; 1099918334Speter 1100018334Speter /* Set variables for reg_dead_at_p_1. */ 1100118334Speter reg_dead_regno = REGNO (reg); 1100218334Speter reg_dead_endregno = reg_dead_regno + (reg_dead_regno < FIRST_PSEUDO_REGISTER 1100318334Speter ? HARD_REGNO_NREGS (reg_dead_regno, 1100418334Speter GET_MODE (reg)) 1100518334Speter : 1); 1100618334Speter 1100718334Speter reg_dead_flag = 0; 1100818334Speter 1100918334Speter /* Check that reg isn't mentioned in NEWPAT_USED_REGS. */ 1101018334Speter if (reg_dead_regno < FIRST_PSEUDO_REGISTER) 1101118334Speter { 1101218334Speter for (i = reg_dead_regno; i < reg_dead_endregno; i++) 1101318334Speter if (TEST_HARD_REG_BIT (newpat_used_regs, i)) 1101418334Speter return 0; 1101518334Speter } 1101618334Speter 1101718334Speter /* Scan backwards until we find a REG_DEAD note, SET, CLOBBER, label, or 1101818334Speter beginning of function. */ 1101918334Speter for (; insn && GET_CODE (insn) != CODE_LABEL && GET_CODE (insn) != BARRIER; 1102018334Speter insn = prev_nonnote_insn (insn)) 1102118334Speter { 1102218334Speter note_stores (PATTERN (insn), reg_dead_at_p_1); 1102318334Speter if (reg_dead_flag) 1102418334Speter return reg_dead_flag == 1 ? 1 : 0; 1102518334Speter 1102618334Speter if (find_regno_note (insn, REG_DEAD, reg_dead_regno)) 1102718334Speter return 1; 1102818334Speter } 1102918334Speter 1103018334Speter /* Get the basic block number that we were in. */ 1103118334Speter if (insn == 0) 1103218334Speter block = 0; 1103318334Speter else 1103418334Speter { 1103518334Speter for (block = 0; block < n_basic_blocks; block++) 1103652284Sobrien if (insn == BLOCK_HEAD (block)) 1103718334Speter break; 1103818334Speter 1103918334Speter if (block == n_basic_blocks) 1104018334Speter return 0; 1104118334Speter } 1104218334Speter 1104318334Speter for (i = reg_dead_regno; i < reg_dead_endregno; i++) 1104452284Sobrien if (REGNO_REG_SET_P (BASIC_BLOCK (block)->global_live_at_start, i)) 1104518334Speter return 0; 1104618334Speter 1104718334Speter return 1; 1104818334Speter} 1104918334Speter 1105018334Speter/* Note hard registers in X that are used. This code is similar to 1105118334Speter that in flow.c, but much simpler since we don't care about pseudos. */ 1105218334Speter 1105318334Speterstatic void 1105418334Spetermark_used_regs_combine (x) 1105518334Speter rtx x; 1105618334Speter{ 1105718334Speter register RTX_CODE code = GET_CODE (x); 1105818334Speter register int regno; 1105918334Speter int i; 1106018334Speter 1106118334Speter switch (code) 1106218334Speter { 1106318334Speter case LABEL_REF: 1106418334Speter case SYMBOL_REF: 1106518334Speter case CONST_INT: 1106618334Speter case CONST: 1106718334Speter case CONST_DOUBLE: 1106818334Speter case PC: 1106918334Speter case ADDR_VEC: 1107018334Speter case ADDR_DIFF_VEC: 1107118334Speter case ASM_INPUT: 1107218334Speter#ifdef HAVE_cc0 1107318334Speter /* CC0 must die in the insn after it is set, so we don't need to take 1107418334Speter special note of it here. */ 1107518334Speter case CC0: 1107618334Speter#endif 1107718334Speter return; 1107818334Speter 1107918334Speter case CLOBBER: 1108018334Speter /* If we are clobbering a MEM, mark any hard registers inside the 1108118334Speter address as used. */ 1108218334Speter if (GET_CODE (XEXP (x, 0)) == MEM) 1108318334Speter mark_used_regs_combine (XEXP (XEXP (x, 0), 0)); 1108418334Speter return; 1108518334Speter 1108618334Speter case REG: 1108718334Speter regno = REGNO (x); 1108818334Speter /* A hard reg in a wide mode may really be multiple registers. 1108918334Speter If so, mark all of them just like the first. */ 1109018334Speter if (regno < FIRST_PSEUDO_REGISTER) 1109118334Speter { 1109218334Speter /* None of this applies to the stack, frame or arg pointers */ 1109318334Speter if (regno == STACK_POINTER_REGNUM 1109418334Speter#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM 1109518334Speter || regno == HARD_FRAME_POINTER_REGNUM 1109618334Speter#endif 1109718334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM 1109818334Speter || (regno == ARG_POINTER_REGNUM && fixed_regs[regno]) 1109918334Speter#endif 1110018334Speter || regno == FRAME_POINTER_REGNUM) 1110118334Speter return; 1110218334Speter 1110318334Speter i = HARD_REGNO_NREGS (regno, GET_MODE (x)); 1110418334Speter while (i-- > 0) 1110518334Speter SET_HARD_REG_BIT (newpat_used_regs, regno + i); 1110618334Speter } 1110718334Speter return; 1110818334Speter 1110918334Speter case SET: 1111018334Speter { 1111118334Speter /* If setting a MEM, or a SUBREG of a MEM, then note any hard regs in 1111218334Speter the address. */ 1111318334Speter register rtx testreg = SET_DEST (x); 1111418334Speter 1111518334Speter while (GET_CODE (testreg) == SUBREG 1111618334Speter || GET_CODE (testreg) == ZERO_EXTRACT 1111718334Speter || GET_CODE (testreg) == SIGN_EXTRACT 1111818334Speter || GET_CODE (testreg) == STRICT_LOW_PART) 1111918334Speter testreg = XEXP (testreg, 0); 1112018334Speter 1112118334Speter if (GET_CODE (testreg) == MEM) 1112218334Speter mark_used_regs_combine (XEXP (testreg, 0)); 1112318334Speter 1112418334Speter mark_used_regs_combine (SET_SRC (x)); 1112518334Speter } 1112650397Sobrien return; 1112750397Sobrien 1112850397Sobrien default: 1112950397Sobrien break; 1113018334Speter } 1113118334Speter 1113218334Speter /* Recursively scan the operands of this expression. */ 1113318334Speter 1113418334Speter { 1113518334Speter register char *fmt = GET_RTX_FORMAT (code); 1113618334Speter 1113718334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 1113818334Speter { 1113918334Speter if (fmt[i] == 'e') 1114018334Speter mark_used_regs_combine (XEXP (x, i)); 1114118334Speter else if (fmt[i] == 'E') 1114218334Speter { 1114318334Speter register int j; 1114418334Speter 1114518334Speter for (j = 0; j < XVECLEN (x, i); j++) 1114618334Speter mark_used_regs_combine (XVECEXP (x, i, j)); 1114718334Speter } 1114818334Speter } 1114918334Speter } 1115018334Speter} 1115118334Speter 1115218334Speter 1115318334Speter/* Remove register number REGNO from the dead registers list of INSN. 1115418334Speter 1115518334Speter Return the note used to record the death, if there was one. */ 1115618334Speter 1115718334Speterrtx 1115818334Speterremove_death (regno, insn) 1115918334Speter int regno; 1116018334Speter rtx insn; 1116118334Speter{ 1116218334Speter register rtx note = find_regno_note (insn, REG_DEAD, regno); 1116318334Speter 1116418334Speter if (note) 1116518334Speter { 1116650397Sobrien REG_N_DEATHS (regno)--; 1116718334Speter remove_note (insn, note); 1116818334Speter } 1116918334Speter 1117018334Speter return note; 1117118334Speter} 1117218334Speter 1117318334Speter/* For each register (hardware or pseudo) used within expression X, if its 1117418334Speter death is in an instruction with cuid between FROM_CUID (inclusive) and 1117518334Speter TO_INSN (exclusive), put a REG_DEAD note for that register in the 1117618334Speter list headed by PNOTES. 1117718334Speter 1117850397Sobrien That said, don't move registers killed by maybe_kill_insn. 1117950397Sobrien 1118018334Speter This is done when X is being merged by combination into TO_INSN. These 1118118334Speter notes will then be distributed as needed. */ 1118218334Speter 1118318334Speterstatic void 1118450397Sobrienmove_deaths (x, maybe_kill_insn, from_cuid, to_insn, pnotes) 1118518334Speter rtx x; 1118650397Sobrien rtx maybe_kill_insn; 1118718334Speter int from_cuid; 1118818334Speter rtx to_insn; 1118918334Speter rtx *pnotes; 1119018334Speter{ 1119118334Speter register char *fmt; 1119218334Speter register int len, i; 1119318334Speter register enum rtx_code code = GET_CODE (x); 1119418334Speter 1119518334Speter if (code == REG) 1119618334Speter { 1119718334Speter register int regno = REGNO (x); 1119818334Speter register rtx where_dead = reg_last_death[regno]; 1119918334Speter register rtx before_dead, after_dead; 1120018334Speter 1120150397Sobrien /* Don't move the register if it gets killed in between from and to */ 1120250397Sobrien if (maybe_kill_insn && reg_set_p (x, maybe_kill_insn) 1120350397Sobrien && !reg_referenced_p (x, maybe_kill_insn)) 1120450397Sobrien return; 1120550397Sobrien 1120618334Speter /* WHERE_DEAD could be a USE insn made by combine, so first we 1120718334Speter make sure that we have insns with valid INSN_CUID values. */ 1120818334Speter before_dead = where_dead; 1120918334Speter while (before_dead && INSN_UID (before_dead) > max_uid_cuid) 1121018334Speter before_dead = PREV_INSN (before_dead); 1121118334Speter after_dead = where_dead; 1121218334Speter while (after_dead && INSN_UID (after_dead) > max_uid_cuid) 1121318334Speter after_dead = NEXT_INSN (after_dead); 1121418334Speter 1121518334Speter if (before_dead && after_dead 1121618334Speter && INSN_CUID (before_dead) >= from_cuid 1121718334Speter && (INSN_CUID (after_dead) < INSN_CUID (to_insn) 1121818334Speter || (where_dead != after_dead 1121918334Speter && INSN_CUID (after_dead) == INSN_CUID (to_insn)))) 1122018334Speter { 1122118334Speter rtx note = remove_death (regno, where_dead); 1122218334Speter 1122318334Speter /* It is possible for the call above to return 0. This can occur 1122418334Speter when reg_last_death points to I2 or I1 that we combined with. 1122518334Speter In that case make a new note. 1122618334Speter 1122718334Speter We must also check for the case where X is a hard register 1122818334Speter and NOTE is a death note for a range of hard registers 1122918334Speter including X. In that case, we must put REG_DEAD notes for 1123018334Speter the remaining registers in place of NOTE. */ 1123118334Speter 1123218334Speter if (note != 0 && regno < FIRST_PSEUDO_REGISTER 1123318334Speter && (GET_MODE_SIZE (GET_MODE (XEXP (note, 0))) 1123450397Sobrien > GET_MODE_SIZE (GET_MODE (x)))) 1123518334Speter { 1123618334Speter int deadregno = REGNO (XEXP (note, 0)); 1123718334Speter int deadend 1123818334Speter = (deadregno + HARD_REGNO_NREGS (deadregno, 1123918334Speter GET_MODE (XEXP (note, 0)))); 1124018334Speter int ourend = regno + HARD_REGNO_NREGS (regno, GET_MODE (x)); 1124118334Speter int i; 1124218334Speter 1124318334Speter for (i = deadregno; i < deadend; i++) 1124418334Speter if (i < regno || i >= ourend) 1124518334Speter REG_NOTES (where_dead) 1124650397Sobrien = gen_rtx_EXPR_LIST (REG_DEAD, 1124750397Sobrien gen_rtx_REG (reg_raw_mode[i], i), 1124850397Sobrien REG_NOTES (where_dead)); 1124918334Speter } 1125050397Sobrien /* If we didn't find any note, or if we found a REG_DEAD note that 1125150397Sobrien covers only part of the given reg, and we have a multi-reg hard 1125218334Speter register, then to be safe we must check for REG_DEAD notes 1125318334Speter for each register other than the first. They could have 1125418334Speter their own REG_DEAD notes lying around. */ 1125550397Sobrien else if ((note == 0 1125650397Sobrien || (note != 0 1125750397Sobrien && (GET_MODE_SIZE (GET_MODE (XEXP (note, 0))) 1125850397Sobrien < GET_MODE_SIZE (GET_MODE (x))))) 1125950397Sobrien && regno < FIRST_PSEUDO_REGISTER 1126018334Speter && HARD_REGNO_NREGS (regno, GET_MODE (x)) > 1) 1126118334Speter { 1126218334Speter int ourend = regno + HARD_REGNO_NREGS (regno, GET_MODE (x)); 1126350397Sobrien int i, offset; 1126418334Speter rtx oldnotes = 0; 1126518334Speter 1126650397Sobrien if (note) 1126750397Sobrien offset = HARD_REGNO_NREGS (regno, GET_MODE (XEXP (note, 0))); 1126850397Sobrien else 1126950397Sobrien offset = 1; 1127050397Sobrien 1127150397Sobrien for (i = regno + offset; i < ourend; i++) 1127250397Sobrien move_deaths (gen_rtx_REG (reg_raw_mode[i], i), 1127350397Sobrien maybe_kill_insn, from_cuid, to_insn, &oldnotes); 1127418334Speter } 1127518334Speter 1127618334Speter if (note != 0 && GET_MODE (XEXP (note, 0)) == GET_MODE (x)) 1127718334Speter { 1127818334Speter XEXP (note, 1) = *pnotes; 1127918334Speter *pnotes = note; 1128018334Speter } 1128118334Speter else 1128250397Sobrien *pnotes = gen_rtx_EXPR_LIST (REG_DEAD, x, *pnotes); 1128318334Speter 1128450397Sobrien REG_N_DEATHS (regno)++; 1128518334Speter } 1128618334Speter 1128718334Speter return; 1128818334Speter } 1128918334Speter 1129018334Speter else if (GET_CODE (x) == SET) 1129118334Speter { 1129218334Speter rtx dest = SET_DEST (x); 1129318334Speter 1129450397Sobrien move_deaths (SET_SRC (x), maybe_kill_insn, from_cuid, to_insn, pnotes); 1129518334Speter 1129618334Speter /* In the case of a ZERO_EXTRACT, a STRICT_LOW_PART, or a SUBREG 1129718334Speter that accesses one word of a multi-word item, some 1129818334Speter piece of everything register in the expression is used by 1129918334Speter this insn, so remove any old death. */ 1130018334Speter 1130118334Speter if (GET_CODE (dest) == ZERO_EXTRACT 1130218334Speter || GET_CODE (dest) == STRICT_LOW_PART 1130318334Speter || (GET_CODE (dest) == SUBREG 1130418334Speter && (((GET_MODE_SIZE (GET_MODE (dest)) 1130518334Speter + UNITS_PER_WORD - 1) / UNITS_PER_WORD) 1130618334Speter == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) 1130718334Speter + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))) 1130818334Speter { 1130950397Sobrien move_deaths (dest, maybe_kill_insn, from_cuid, to_insn, pnotes); 1131018334Speter return; 1131118334Speter } 1131218334Speter 1131318334Speter /* If this is some other SUBREG, we know it replaces the entire 1131418334Speter value, so use that as the destination. */ 1131518334Speter if (GET_CODE (dest) == SUBREG) 1131618334Speter dest = SUBREG_REG (dest); 1131718334Speter 1131818334Speter /* If this is a MEM, adjust deaths of anything used in the address. 1131918334Speter For a REG (the only other possibility), the entire value is 1132018334Speter being replaced so the old value is not used in this insn. */ 1132118334Speter 1132218334Speter if (GET_CODE (dest) == MEM) 1132350397Sobrien move_deaths (XEXP (dest, 0), maybe_kill_insn, from_cuid, 1132450397Sobrien to_insn, pnotes); 1132518334Speter return; 1132618334Speter } 1132718334Speter 1132818334Speter else if (GET_CODE (x) == CLOBBER) 1132918334Speter return; 1133018334Speter 1133118334Speter len = GET_RTX_LENGTH (code); 1133218334Speter fmt = GET_RTX_FORMAT (code); 1133318334Speter 1133418334Speter for (i = 0; i < len; i++) 1133518334Speter { 1133618334Speter if (fmt[i] == 'E') 1133718334Speter { 1133818334Speter register int j; 1133918334Speter for (j = XVECLEN (x, i) - 1; j >= 0; j--) 1134050397Sobrien move_deaths (XVECEXP (x, i, j), maybe_kill_insn, from_cuid, 1134150397Sobrien to_insn, pnotes); 1134218334Speter } 1134318334Speter else if (fmt[i] == 'e') 1134450397Sobrien move_deaths (XEXP (x, i), maybe_kill_insn, from_cuid, to_insn, pnotes); 1134518334Speter } 1134618334Speter} 1134718334Speter 1134818334Speter/* Return 1 if X is the target of a bit-field assignment in BODY, the 1134918334Speter pattern of an insn. X must be a REG. */ 1135018334Speter 1135118334Speterstatic int 1135218334Speterreg_bitfield_target_p (x, body) 1135318334Speter rtx x; 1135418334Speter rtx body; 1135518334Speter{ 1135618334Speter int i; 1135718334Speter 1135818334Speter if (GET_CODE (body) == SET) 1135918334Speter { 1136018334Speter rtx dest = SET_DEST (body); 1136118334Speter rtx target; 1136218334Speter int regno, tregno, endregno, endtregno; 1136318334Speter 1136418334Speter if (GET_CODE (dest) == ZERO_EXTRACT) 1136518334Speter target = XEXP (dest, 0); 1136618334Speter else if (GET_CODE (dest) == STRICT_LOW_PART) 1136718334Speter target = SUBREG_REG (XEXP (dest, 0)); 1136818334Speter else 1136918334Speter return 0; 1137018334Speter 1137118334Speter if (GET_CODE (target) == SUBREG) 1137218334Speter target = SUBREG_REG (target); 1137318334Speter 1137418334Speter if (GET_CODE (target) != REG) 1137518334Speter return 0; 1137618334Speter 1137718334Speter tregno = REGNO (target), regno = REGNO (x); 1137818334Speter if (tregno >= FIRST_PSEUDO_REGISTER || regno >= FIRST_PSEUDO_REGISTER) 1137918334Speter return target == x; 1138018334Speter 1138118334Speter endtregno = tregno + HARD_REGNO_NREGS (tregno, GET_MODE (target)); 1138218334Speter endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x)); 1138318334Speter 1138418334Speter return endregno > tregno && regno < endtregno; 1138518334Speter } 1138618334Speter 1138718334Speter else if (GET_CODE (body) == PARALLEL) 1138818334Speter for (i = XVECLEN (body, 0) - 1; i >= 0; i--) 1138918334Speter if (reg_bitfield_target_p (x, XVECEXP (body, 0, i))) 1139018334Speter return 1; 1139118334Speter 1139218334Speter return 0; 1139318334Speter} 1139418334Speter 1139518334Speter/* Given a chain of REG_NOTES originally from FROM_INSN, try to place them 1139618334Speter as appropriate. I3 and I2 are the insns resulting from the combination 1139718334Speter insns including FROM (I2 may be zero). 1139818334Speter 1139918334Speter ELIM_I2 and ELIM_I1 are either zero or registers that we know will 1140018334Speter not need REG_DEAD notes because they are being substituted for. This 1140118334Speter saves searching in the most common cases. 1140218334Speter 1140318334Speter Each note in the list is either ignored or placed on some insns, depending 1140418334Speter on the type of note. */ 1140518334Speter 1140618334Speterstatic void 1140718334Speterdistribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) 1140818334Speter rtx notes; 1140918334Speter rtx from_insn; 1141018334Speter rtx i3, i2; 1141118334Speter rtx elim_i2, elim_i1; 1141218334Speter{ 1141318334Speter rtx note, next_note; 1141418334Speter rtx tem; 1141518334Speter 1141618334Speter for (note = notes; note; note = next_note) 1141718334Speter { 1141818334Speter rtx place = 0, place2 = 0; 1141918334Speter 1142018334Speter /* If this NOTE references a pseudo register, ensure it references 1142118334Speter the latest copy of that register. */ 1142218334Speter if (XEXP (note, 0) && GET_CODE (XEXP (note, 0)) == REG 1142318334Speter && REGNO (XEXP (note, 0)) >= FIRST_PSEUDO_REGISTER) 1142418334Speter XEXP (note, 0) = regno_reg_rtx[REGNO (XEXP (note, 0))]; 1142518334Speter 1142618334Speter next_note = XEXP (note, 1); 1142718334Speter switch (REG_NOTE_KIND (note)) 1142818334Speter { 1142950397Sobrien case REG_BR_PROB: 1143050397Sobrien case REG_EXEC_COUNT: 1143150397Sobrien /* Doesn't matter much where we put this, as long as it's somewhere. 1143250397Sobrien It is preferable to keep these notes on branches, which is most 1143350397Sobrien likely to be i3. */ 1143450397Sobrien place = i3; 1143550397Sobrien break; 1143650397Sobrien 1143752284Sobrien case REG_EH_REGION: 1143852284Sobrien /* This note must remain with the call. It should not be possible 1143952284Sobrien for both I2 and I3 to be a call. */ 1144052284Sobrien if (GET_CODE (i3) == CALL_INSN) 1144152284Sobrien place = i3; 1144252284Sobrien else if (i2 && GET_CODE (i2) == CALL_INSN) 1144352284Sobrien place = i2; 1144452284Sobrien else 1144552284Sobrien abort (); 1144652284Sobrien break; 1144752284Sobrien 1144818334Speter case REG_UNUSED: 1144918334Speter /* Any clobbers for i3 may still exist, and so we must process 1145018334Speter REG_UNUSED notes from that insn. 1145118334Speter 1145218334Speter Any clobbers from i2 or i1 can only exist if they were added by 1145318334Speter recog_for_combine. In that case, recog_for_combine created the 1145418334Speter necessary REG_UNUSED notes. Trying to keep any original 1145518334Speter REG_UNUSED notes from these insns can cause incorrect output 1145618334Speter if it is for the same register as the original i3 dest. 1145718334Speter In that case, we will notice that the register is set in i3, 1145818334Speter and then add a REG_UNUSED note for the destination of i3, which 1145918334Speter is wrong. However, it is possible to have REG_UNUSED notes from 1146018334Speter i2 or i1 for register which were both used and clobbered, so 1146118334Speter we keep notes from i2 or i1 if they will turn into REG_DEAD 1146218334Speter notes. */ 1146318334Speter 1146418334Speter /* If this register is set or clobbered in I3, put the note there 1146518334Speter unless there is one already. */ 1146618334Speter if (reg_set_p (XEXP (note, 0), PATTERN (i3))) 1146718334Speter { 1146818334Speter if (from_insn != i3) 1146918334Speter break; 1147018334Speter 1147118334Speter if (! (GET_CODE (XEXP (note, 0)) == REG 1147218334Speter ? find_regno_note (i3, REG_UNUSED, REGNO (XEXP (note, 0))) 1147318334Speter : find_reg_note (i3, REG_UNUSED, XEXP (note, 0)))) 1147418334Speter place = i3; 1147518334Speter } 1147618334Speter /* Otherwise, if this register is used by I3, then this register 1147718334Speter now dies here, so we must put a REG_DEAD note here unless there 1147818334Speter is one already. */ 1147918334Speter else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)) 1148018334Speter && ! (GET_CODE (XEXP (note, 0)) == REG 1148118334Speter ? find_regno_note (i3, REG_DEAD, REGNO (XEXP (note, 0))) 1148218334Speter : find_reg_note (i3, REG_DEAD, XEXP (note, 0)))) 1148318334Speter { 1148418334Speter PUT_REG_NOTE_KIND (note, REG_DEAD); 1148518334Speter place = i3; 1148618334Speter } 1148718334Speter break; 1148818334Speter 1148918334Speter case REG_EQUAL: 1149018334Speter case REG_EQUIV: 1149118334Speter case REG_NONNEG: 1149250397Sobrien case REG_NOALIAS: 1149318334Speter /* These notes say something about results of an insn. We can 1149418334Speter only support them if they used to be on I3 in which case they 1149518334Speter remain on I3. Otherwise they are ignored. 1149618334Speter 1149718334Speter If the note refers to an expression that is not a constant, we 1149818334Speter must also ignore the note since we cannot tell whether the 1149918334Speter equivalence is still true. It might be possible to do 1150018334Speter slightly better than this (we only have a problem if I2DEST 1150118334Speter or I1DEST is present in the expression), but it doesn't 1150218334Speter seem worth the trouble. */ 1150318334Speter 1150418334Speter if (from_insn == i3 1150518334Speter && (XEXP (note, 0) == 0 || CONSTANT_P (XEXP (note, 0)))) 1150618334Speter place = i3; 1150718334Speter break; 1150818334Speter 1150918334Speter case REG_INC: 1151018334Speter case REG_NO_CONFLICT: 1151118334Speter /* These notes say something about how a register is used. They must 1151218334Speter be present on any use of the register in I2 or I3. */ 1151318334Speter if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3))) 1151418334Speter place = i3; 1151518334Speter 1151618334Speter if (i2 && reg_mentioned_p (XEXP (note, 0), PATTERN (i2))) 1151718334Speter { 1151818334Speter if (place) 1151918334Speter place2 = i2; 1152018334Speter else 1152118334Speter place = i2; 1152218334Speter } 1152318334Speter break; 1152418334Speter 1152552284Sobrien case REG_LABEL: 1152652284Sobrien /* This can show up in several ways -- either directly in the 1152752284Sobrien pattern, or hidden off in the constant pool with (or without?) 1152852284Sobrien a REG_EQUAL note. */ 1152952284Sobrien /* ??? Ignore the without-reg_equal-note problem for now. */ 1153052284Sobrien if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3)) 1153152284Sobrien || ((tem = find_reg_note (i3, REG_EQUAL, NULL_RTX)) 1153252284Sobrien && GET_CODE (XEXP (tem, 0)) == LABEL_REF 1153352284Sobrien && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0))) 1153452284Sobrien place = i3; 1153552284Sobrien 1153652284Sobrien if (i2 1153752284Sobrien && (reg_mentioned_p (XEXP (note, 0), PATTERN (i2)) 1153852284Sobrien || ((tem = find_reg_note (i2, REG_EQUAL, NULL_RTX)) 1153952284Sobrien && GET_CODE (XEXP (tem, 0)) == LABEL_REF 1154052284Sobrien && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0)))) 1154152284Sobrien { 1154252284Sobrien if (place) 1154352284Sobrien place2 = i2; 1154452284Sobrien else 1154552284Sobrien place = i2; 1154652284Sobrien } 1154752284Sobrien break; 1154852284Sobrien 1154918334Speter case REG_WAS_0: 1155018334Speter /* It is too much trouble to try to see if this note is still 1155118334Speter correct in all situations. It is better to simply delete it. */ 1155218334Speter break; 1155318334Speter 1155418334Speter case REG_RETVAL: 1155518334Speter /* If the insn previously containing this note still exists, 1155618334Speter put it back where it was. Otherwise move it to the previous 1155718334Speter insn. Adjust the corresponding REG_LIBCALL note. */ 1155818334Speter if (GET_CODE (from_insn) != NOTE) 1155918334Speter place = from_insn; 1156018334Speter else 1156118334Speter { 1156218334Speter tem = find_reg_note (XEXP (note, 0), REG_LIBCALL, NULL_RTX); 1156318334Speter place = prev_real_insn (from_insn); 1156418334Speter if (tem && place) 1156518334Speter XEXP (tem, 0) = place; 1156618334Speter } 1156718334Speter break; 1156818334Speter 1156918334Speter case REG_LIBCALL: 1157018334Speter /* This is handled similarly to REG_RETVAL. */ 1157118334Speter if (GET_CODE (from_insn) != NOTE) 1157218334Speter place = from_insn; 1157318334Speter else 1157418334Speter { 1157518334Speter tem = find_reg_note (XEXP (note, 0), REG_RETVAL, NULL_RTX); 1157618334Speter place = next_real_insn (from_insn); 1157718334Speter if (tem && place) 1157818334Speter XEXP (tem, 0) = place; 1157918334Speter } 1158018334Speter break; 1158118334Speter 1158218334Speter case REG_DEAD: 1158318334Speter /* If the register is used as an input in I3, it dies there. 1158418334Speter Similarly for I2, if it is non-zero and adjacent to I3. 1158518334Speter 1158618334Speter If the register is not used as an input in either I3 or I2 1158718334Speter and it is not one of the registers we were supposed to eliminate, 1158818334Speter there are two possibilities. We might have a non-adjacent I2 1158918334Speter or we might have somehow eliminated an additional register 1159018334Speter from a computation. For example, we might have had A & B where 1159118334Speter we discover that B will always be zero. In this case we will 1159218334Speter eliminate the reference to A. 1159318334Speter 1159418334Speter In both cases, we must search to see if we can find a previous 1159518334Speter use of A and put the death note there. */ 1159618334Speter 1159718334Speter if (from_insn 1159818334Speter && GET_CODE (from_insn) == CALL_INSN 1159918334Speter && find_reg_fusage (from_insn, USE, XEXP (note, 0))) 1160018334Speter place = from_insn; 1160118334Speter else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3))) 1160218334Speter place = i3; 1160318334Speter else if (i2 != 0 && next_nonnote_insn (i2) == i3 1160418334Speter && reg_referenced_p (XEXP (note, 0), PATTERN (i2))) 1160518334Speter place = i2; 1160618334Speter 1160718334Speter if (XEXP (note, 0) == elim_i2 || XEXP (note, 0) == elim_i1) 1160818334Speter break; 1160918334Speter 1161018334Speter /* If the register is used in both I2 and I3 and it dies in I3, 1161118334Speter we might have added another reference to it. If reg_n_refs 1161218334Speter was 2, bump it to 3. This has to be correct since the 1161318334Speter register must have been set somewhere. The reason this is 1161418334Speter done is because local-alloc.c treats 2 references as a 1161518334Speter special case. */ 1161618334Speter 1161718334Speter if (place == i3 && i2 != 0 && GET_CODE (XEXP (note, 0)) == REG 1161850397Sobrien && REG_N_REFS (REGNO (XEXP (note, 0)))== 2 1161918334Speter && reg_referenced_p (XEXP (note, 0), PATTERN (i2))) 1162050397Sobrien REG_N_REFS (REGNO (XEXP (note, 0))) = 3; 1162118334Speter 1162218334Speter if (place == 0) 1162318334Speter { 1162418334Speter for (tem = prev_nonnote_insn (i3); 1162518334Speter place == 0 && tem 1162618334Speter && (GET_CODE (tem) == INSN || GET_CODE (tem) == CALL_INSN); 1162718334Speter tem = prev_nonnote_insn (tem)) 1162818334Speter { 1162918334Speter /* If the register is being set at TEM, see if that is all 1163018334Speter TEM is doing. If so, delete TEM. Otherwise, make this 1163118334Speter into a REG_UNUSED note instead. */ 1163218334Speter if (reg_set_p (XEXP (note, 0), PATTERN (tem))) 1163318334Speter { 1163418334Speter rtx set = single_set (tem); 1163550397Sobrien rtx inner_dest = 0; 1163652284Sobrien#ifdef HAVE_cc0 1163752284Sobrien rtx cc0_setter = NULL_RTX; 1163852284Sobrien#endif 1163918334Speter 1164050397Sobrien if (set != 0) 1164150397Sobrien for (inner_dest = SET_DEST (set); 1164250397Sobrien GET_CODE (inner_dest) == STRICT_LOW_PART 1164350397Sobrien || GET_CODE (inner_dest) == SUBREG 1164450397Sobrien || GET_CODE (inner_dest) == ZERO_EXTRACT; 1164550397Sobrien inner_dest = XEXP (inner_dest, 0)) 1164650397Sobrien ; 1164750397Sobrien 1164818334Speter /* Verify that it was the set, and not a clobber that 1164952284Sobrien modified the register. 1165018334Speter 1165152284Sobrien CC0 targets must be careful to maintain setter/user 1165252284Sobrien pairs. If we cannot delete the setter due to side 1165352284Sobrien effects, mark the user with an UNUSED note instead 1165452284Sobrien of deleting it. */ 1165552284Sobrien 1165618334Speter if (set != 0 && ! side_effects_p (SET_SRC (set)) 1165752284Sobrien && rtx_equal_p (XEXP (note, 0), inner_dest) 1165852284Sobrien#ifdef HAVE_cc0 1165952284Sobrien && (! reg_mentioned_p (cc0_rtx, SET_SRC (set)) 1166052284Sobrien || ((cc0_setter = prev_cc0_setter (tem)) != NULL 1166152284Sobrien && sets_cc0_p (PATTERN (cc0_setter)) > 0)) 1166252284Sobrien#endif 1166352284Sobrien ) 1166418334Speter { 1166518334Speter /* Move the notes and links of TEM elsewhere. 1166618334Speter This might delete other dead insns recursively. 1166718334Speter First set the pattern to something that won't use 1166818334Speter any register. */ 1166918334Speter 1167018334Speter PATTERN (tem) = pc_rtx; 1167118334Speter 1167218334Speter distribute_notes (REG_NOTES (tem), tem, tem, 1167318334Speter NULL_RTX, NULL_RTX, NULL_RTX); 1167418334Speter distribute_links (LOG_LINKS (tem)); 1167518334Speter 1167618334Speter PUT_CODE (tem, NOTE); 1167718334Speter NOTE_LINE_NUMBER (tem) = NOTE_INSN_DELETED; 1167818334Speter NOTE_SOURCE_FILE (tem) = 0; 1167952284Sobrien 1168052284Sobrien#ifdef HAVE_cc0 1168152284Sobrien /* Delete the setter too. */ 1168252284Sobrien if (cc0_setter) 1168352284Sobrien { 1168452284Sobrien PATTERN (cc0_setter) = pc_rtx; 1168552284Sobrien 1168652284Sobrien distribute_notes (REG_NOTES (cc0_setter), 1168752284Sobrien cc0_setter, cc0_setter, 1168852284Sobrien NULL_RTX, NULL_RTX, NULL_RTX); 1168952284Sobrien distribute_links (LOG_LINKS (cc0_setter)); 1169052284Sobrien 1169152284Sobrien PUT_CODE (cc0_setter, NOTE); 1169252284Sobrien NOTE_LINE_NUMBER (cc0_setter) = NOTE_INSN_DELETED; 1169352284Sobrien NOTE_SOURCE_FILE (cc0_setter) = 0; 1169452284Sobrien } 1169552284Sobrien#endif 1169618334Speter } 1169750397Sobrien /* If the register is both set and used here, put the 1169850397Sobrien REG_DEAD note here, but place a REG_UNUSED note 1169950397Sobrien here too unless there already is one. */ 1170050397Sobrien else if (reg_referenced_p (XEXP (note, 0), 1170150397Sobrien PATTERN (tem))) 1170250397Sobrien { 1170350397Sobrien place = tem; 1170450397Sobrien 1170550397Sobrien if (! find_regno_note (tem, REG_UNUSED, 1170650397Sobrien REGNO (XEXP (note, 0)))) 1170750397Sobrien REG_NOTES (tem) 1170850397Sobrien = gen_rtx_EXPR_LIST (REG_UNUSED, 1170950397Sobrien XEXP (note, 0), 1171050397Sobrien REG_NOTES (tem)); 1171150397Sobrien } 1171218334Speter else 1171318334Speter { 1171418334Speter PUT_REG_NOTE_KIND (note, REG_UNUSED); 1171518334Speter 1171618334Speter /* If there isn't already a REG_UNUSED note, put one 1171718334Speter here. */ 1171818334Speter if (! find_regno_note (tem, REG_UNUSED, 1171918334Speter REGNO (XEXP (note, 0)))) 1172018334Speter place = tem; 1172118334Speter break; 1172218334Speter } 1172318334Speter } 1172418334Speter else if (reg_referenced_p (XEXP (note, 0), PATTERN (tem)) 1172518334Speter || (GET_CODE (tem) == CALL_INSN 1172618334Speter && find_reg_fusage (tem, USE, XEXP (note, 0)))) 1172718334Speter { 1172818334Speter place = tem; 1172918334Speter 1173018334Speter /* If we are doing a 3->2 combination, and we have a 1173118334Speter register which formerly died in i3 and was not used 1173218334Speter by i2, which now no longer dies in i3 and is used in 1173318334Speter i2 but does not die in i2, and place is between i2 1173418334Speter and i3, then we may need to move a link from place to 1173518334Speter i2. */ 1173618334Speter if (i2 && INSN_UID (place) <= max_uid_cuid 1173718334Speter && INSN_CUID (place) > INSN_CUID (i2) 1173818334Speter && from_insn && INSN_CUID (from_insn) > INSN_CUID (i2) 1173918334Speter && reg_referenced_p (XEXP (note, 0), PATTERN (i2))) 1174018334Speter { 1174118334Speter rtx links = LOG_LINKS (place); 1174218334Speter LOG_LINKS (place) = 0; 1174318334Speter distribute_links (links); 1174418334Speter } 1174518334Speter break; 1174618334Speter } 1174718334Speter } 1174818334Speter 1174918334Speter /* If we haven't found an insn for the death note and it 1175018334Speter is still a REG_DEAD note, but we have hit a CODE_LABEL, 1175118334Speter insert a USE insn for the register at that label and 1175218334Speter put the death node there. This prevents problems with 1175318334Speter call-state tracking in caller-save.c. */ 1175418334Speter if (REG_NOTE_KIND (note) == REG_DEAD && place == 0 && tem != 0) 1175518334Speter { 1175618334Speter place 1175750397Sobrien = emit_insn_after (gen_rtx_USE (VOIDmode, XEXP (note, 0)), 1175818334Speter tem); 1175918334Speter 1176018334Speter /* If this insn was emitted between blocks, then update 1176152284Sobrien BLOCK_HEAD of the current block to include it. */ 1176252284Sobrien if (BLOCK_END (this_basic_block - 1) == tem) 1176352284Sobrien BLOCK_HEAD (this_basic_block) = place; 1176418334Speter } 1176518334Speter } 1176618334Speter 1176718334Speter /* If the register is set or already dead at PLACE, we needn't do 1176850397Sobrien anything with this note if it is still a REG_DEAD note. 1176950397Sobrien We can here if it is set at all, not if is it totally replace, 1177050397Sobrien which is what `dead_or_set_p' checks, so also check for it being 1177150397Sobrien set partially. */ 1177218334Speter 1177350397Sobrien 1177418334Speter if (place && REG_NOTE_KIND (note) == REG_DEAD) 1177518334Speter { 1177618334Speter int regno = REGNO (XEXP (note, 0)); 1177718334Speter 1177818334Speter if (dead_or_set_p (place, XEXP (note, 0)) 1177918334Speter || reg_bitfield_target_p (XEXP (note, 0), PATTERN (place))) 1178018334Speter { 1178118334Speter /* Unless the register previously died in PLACE, clear 1178218334Speter reg_last_death. [I no longer understand why this is 1178318334Speter being done.] */ 1178418334Speter if (reg_last_death[regno] != place) 1178518334Speter reg_last_death[regno] = 0; 1178618334Speter place = 0; 1178718334Speter } 1178818334Speter else 1178918334Speter reg_last_death[regno] = place; 1179018334Speter 1179118334Speter /* If this is a death note for a hard reg that is occupying 1179218334Speter multiple registers, ensure that we are still using all 1179318334Speter parts of the object. If we find a piece of the object 1179418334Speter that is unused, we must add a USE for that piece before 1179518334Speter PLACE and put the appropriate REG_DEAD note on it. 1179618334Speter 1179718334Speter An alternative would be to put a REG_UNUSED for the pieces 1179818334Speter on the insn that set the register, but that can't be done if 1179918334Speter it is not in the same block. It is simpler, though less 1180018334Speter efficient, to add the USE insns. */ 1180118334Speter 1180218334Speter if (place && regno < FIRST_PSEUDO_REGISTER 1180318334Speter && HARD_REGNO_NREGS (regno, GET_MODE (XEXP (note, 0))) > 1) 1180418334Speter { 1180518334Speter int endregno 1180618334Speter = regno + HARD_REGNO_NREGS (regno, 1180718334Speter GET_MODE (XEXP (note, 0))); 1180818334Speter int all_used = 1; 1180918334Speter int i; 1181018334Speter 1181118334Speter for (i = regno; i < endregno; i++) 1181218334Speter if (! refers_to_regno_p (i, i + 1, PATTERN (place), 0) 1181318334Speter && ! find_regno_fusage (place, USE, i)) 1181418334Speter { 1181550397Sobrien rtx piece = gen_rtx_REG (reg_raw_mode[i], i); 1181618334Speter rtx p; 1181718334Speter 1181818334Speter /* See if we already placed a USE note for this 1181918334Speter register in front of PLACE. */ 1182018334Speter for (p = place; 1182118334Speter GET_CODE (PREV_INSN (p)) == INSN 1182218334Speter && GET_CODE (PATTERN (PREV_INSN (p))) == USE; 1182318334Speter p = PREV_INSN (p)) 1182418334Speter if (rtx_equal_p (piece, 1182518334Speter XEXP (PATTERN (PREV_INSN (p)), 0))) 1182618334Speter { 1182718334Speter p = 0; 1182818334Speter break; 1182918334Speter } 1183018334Speter 1183118334Speter if (p) 1183218334Speter { 1183318334Speter rtx use_insn 1183450397Sobrien = emit_insn_before (gen_rtx_USE (VOIDmode, 1183550397Sobrien piece), 1183618334Speter p); 1183718334Speter REG_NOTES (use_insn) 1183850397Sobrien = gen_rtx_EXPR_LIST (REG_DEAD, piece, 1183950397Sobrien REG_NOTES (use_insn)); 1184018334Speter } 1184118334Speter 1184218334Speter all_used = 0; 1184318334Speter } 1184418334Speter 1184518334Speter /* Check for the case where the register dying partially 1184618334Speter overlaps the register set by this insn. */ 1184718334Speter if (all_used) 1184818334Speter for (i = regno; i < endregno; i++) 1184918334Speter if (dead_or_set_regno_p (place, i)) 1185018334Speter { 1185118334Speter all_used = 0; 1185218334Speter break; 1185318334Speter } 1185418334Speter 1185518334Speter if (! all_used) 1185618334Speter { 1185718334Speter /* Put only REG_DEAD notes for pieces that are 1185818334Speter still used and that are not already dead or set. */ 1185918334Speter 1186018334Speter for (i = regno; i < endregno; i++) 1186118334Speter { 1186250397Sobrien rtx piece = gen_rtx_REG (reg_raw_mode[i], i); 1186318334Speter 1186418334Speter if ((reg_referenced_p (piece, PATTERN (place)) 1186518334Speter || (GET_CODE (place) == CALL_INSN 1186618334Speter && find_reg_fusage (place, USE, piece))) 1186718334Speter && ! dead_or_set_p (place, piece) 1186818334Speter && ! reg_bitfield_target_p (piece, 1186918334Speter PATTERN (place))) 1187050397Sobrien REG_NOTES (place) 1187150397Sobrien = gen_rtx_EXPR_LIST (REG_DEAD, 1187250397Sobrien piece, REG_NOTES (place)); 1187318334Speter } 1187418334Speter 1187518334Speter place = 0; 1187618334Speter } 1187718334Speter } 1187818334Speter } 1187918334Speter break; 1188018334Speter 1188118334Speter default: 1188218334Speter /* Any other notes should not be present at this point in the 1188318334Speter compilation. */ 1188418334Speter abort (); 1188518334Speter } 1188618334Speter 1188718334Speter if (place) 1188818334Speter { 1188918334Speter XEXP (note, 1) = REG_NOTES (place); 1189018334Speter REG_NOTES (place) = note; 1189118334Speter } 1189218334Speter else if ((REG_NOTE_KIND (note) == REG_DEAD 1189318334Speter || REG_NOTE_KIND (note) == REG_UNUSED) 1189418334Speter && GET_CODE (XEXP (note, 0)) == REG) 1189550397Sobrien REG_N_DEATHS (REGNO (XEXP (note, 0)))--; 1189618334Speter 1189718334Speter if (place2) 1189818334Speter { 1189918334Speter if ((REG_NOTE_KIND (note) == REG_DEAD 1190018334Speter || REG_NOTE_KIND (note) == REG_UNUSED) 1190118334Speter && GET_CODE (XEXP (note, 0)) == REG) 1190250397Sobrien REG_N_DEATHS (REGNO (XEXP (note, 0)))++; 1190318334Speter 1190450397Sobrien REG_NOTES (place2) = gen_rtx_fmt_ee (GET_CODE (note), 1190550397Sobrien REG_NOTE_KIND (note), 1190650397Sobrien XEXP (note, 0), 1190750397Sobrien REG_NOTES (place2)); 1190818334Speter } 1190918334Speter } 1191018334Speter} 1191118334Speter 1191218334Speter/* Similarly to above, distribute the LOG_LINKS that used to be present on 1191318334Speter I3, I2, and I1 to new locations. This is also called in one case to 1191418334Speter add a link pointing at I3 when I3's destination is changed. */ 1191518334Speter 1191618334Speterstatic void 1191718334Speterdistribute_links (links) 1191818334Speter rtx links; 1191918334Speter{ 1192018334Speter rtx link, next_link; 1192118334Speter 1192218334Speter for (link = links; link; link = next_link) 1192318334Speter { 1192418334Speter rtx place = 0; 1192518334Speter rtx insn; 1192618334Speter rtx set, reg; 1192718334Speter 1192818334Speter next_link = XEXP (link, 1); 1192918334Speter 1193018334Speter /* If the insn that this link points to is a NOTE or isn't a single 1193118334Speter set, ignore it. In the latter case, it isn't clear what we 1193218334Speter can do other than ignore the link, since we can't tell which 1193318334Speter register it was for. Such links wouldn't be used by combine 1193418334Speter anyway. 1193518334Speter 1193618334Speter It is not possible for the destination of the target of the link to 1193718334Speter have been changed by combine. The only potential of this is if we 1193818334Speter replace I3, I2, and I1 by I3 and I2. But in that case the 1193918334Speter destination of I2 also remains unchanged. */ 1194018334Speter 1194118334Speter if (GET_CODE (XEXP (link, 0)) == NOTE 1194218334Speter || (set = single_set (XEXP (link, 0))) == 0) 1194318334Speter continue; 1194418334Speter 1194518334Speter reg = SET_DEST (set); 1194618334Speter while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT 1194718334Speter || GET_CODE (reg) == SIGN_EXTRACT 1194818334Speter || GET_CODE (reg) == STRICT_LOW_PART) 1194918334Speter reg = XEXP (reg, 0); 1195018334Speter 1195118334Speter /* A LOG_LINK is defined as being placed on the first insn that uses 1195218334Speter a register and points to the insn that sets the register. Start 1195318334Speter searching at the next insn after the target of the link and stop 1195418334Speter when we reach a set of the register or the end of the basic block. 1195518334Speter 1195618334Speter Note that this correctly handles the link that used to point from 1195718334Speter I3 to I2. Also note that not much searching is typically done here 1195818334Speter since most links don't point very far away. */ 1195918334Speter 1196018334Speter for (insn = NEXT_INSN (XEXP (link, 0)); 1196118334Speter (insn && (this_basic_block == n_basic_blocks - 1 1196252284Sobrien || BLOCK_HEAD (this_basic_block + 1) != insn)); 1196318334Speter insn = NEXT_INSN (insn)) 1196418334Speter if (GET_RTX_CLASS (GET_CODE (insn)) == 'i' 1196518334Speter && reg_overlap_mentioned_p (reg, PATTERN (insn))) 1196618334Speter { 1196718334Speter if (reg_referenced_p (reg, PATTERN (insn))) 1196818334Speter place = insn; 1196918334Speter break; 1197018334Speter } 1197118334Speter else if (GET_CODE (insn) == CALL_INSN 1197218334Speter && find_reg_fusage (insn, USE, reg)) 1197318334Speter { 1197418334Speter place = insn; 1197518334Speter break; 1197618334Speter } 1197718334Speter 1197818334Speter /* If we found a place to put the link, place it there unless there 1197918334Speter is already a link to the same insn as LINK at that point. */ 1198018334Speter 1198118334Speter if (place) 1198218334Speter { 1198318334Speter rtx link2; 1198418334Speter 1198518334Speter for (link2 = LOG_LINKS (place); link2; link2 = XEXP (link2, 1)) 1198618334Speter if (XEXP (link2, 0) == XEXP (link, 0)) 1198718334Speter break; 1198818334Speter 1198918334Speter if (link2 == 0) 1199018334Speter { 1199118334Speter XEXP (link, 1) = LOG_LINKS (place); 1199218334Speter LOG_LINKS (place) = link; 1199318334Speter 1199418334Speter /* Set added_links_insn to the earliest insn we added a 1199518334Speter link to. */ 1199618334Speter if (added_links_insn == 0 1199718334Speter || INSN_CUID (added_links_insn) > INSN_CUID (place)) 1199818334Speter added_links_insn = place; 1199918334Speter } 1200018334Speter } 1200118334Speter } 1200218334Speter} 1200318334Speter 1200450397Sobrien/* Compute INSN_CUID for INSN, which is an insn made by combine. */ 1200550397Sobrien 1200650397Sobrienstatic int 1200750397Sobrieninsn_cuid (insn) 1200850397Sobrien rtx insn; 1200950397Sobrien{ 1201050397Sobrien while (insn != 0 && INSN_UID (insn) > max_uid_cuid 1201150397Sobrien && GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == USE) 1201250397Sobrien insn = NEXT_INSN (insn); 1201350397Sobrien 1201450397Sobrien if (INSN_UID (insn) > max_uid_cuid) 1201550397Sobrien abort (); 1201650397Sobrien 1201750397Sobrien return INSN_CUID (insn); 1201850397Sobrien} 1201950397Sobrien 1202018334Spetervoid 1202118334Speterdump_combine_stats (file) 1202218334Speter FILE *file; 1202318334Speter{ 1202452284Sobrien fnotice 1202518334Speter (file, 1202618334Speter ";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n", 1202718334Speter combine_attempts, combine_merges, combine_extras, combine_successes); 1202818334Speter} 1202918334Speter 1203018334Spetervoid 1203118334Speterdump_combine_total_stats (file) 1203218334Speter FILE *file; 1203318334Speter{ 1203452284Sobrien fnotice 1203518334Speter (file, 1203618334Speter "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n", 1203718334Speter total_attempts, total_merges, total_extras, total_successes); 1203818334Speter} 12039