combine.c revision 117395
118334Speter/* Optimize by combining instructions for GNU compiler. 272562Sobrien Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 3117395Skan 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. 418334Speter 590075SobrienThis file is part of GCC. 618334Speter 790075SobrienGCC is free software; you can redistribute it and/or modify it under 890075Sobrienthe terms of the GNU General Public License as published by the Free 990075SobrienSoftware Foundation; either version 2, or (at your option) any later 1090075Sobrienversion. 1118334Speter 1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1490075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1590075Sobrienfor more details. 1618334Speter 1718334SpeterYou should have received a copy of the GNU General Public License 1890075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 1990075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 2090075Sobrien02111-1307, USA. */ 2118334Speter 2218334Speter/* This module is essentially the "combiner" phase of the U. of Arizona 2318334Speter Portable Optimizer, but redone to work on our list-structured 2418334Speter representation for RTL instead of their string representation. 2518334Speter 2618334Speter The LOG_LINKS of each insn identify the most recent assignment 2718334Speter to each REG used in the insn. It is a list of previous insns, 2818334Speter each of which contains a SET for a REG that is used in this insn 2918334Speter and not used or set in between. LOG_LINKs never cross basic blocks. 3018334Speter They were set up by the preceding pass (lifetime analysis). 3118334Speter 3218334Speter We try to combine each pair of insns joined by a logical link. 3318334Speter We also try to combine triples of insns A, B and C when 3418334Speter C has a link back to B and B has a link back to A. 3518334Speter 3618334Speter LOG_LINKS does not have links for use of the CC0. They don't 3718334Speter need to, because the insn that sets the CC0 is always immediately 3818334Speter before the insn that tests it. So we always regard a branch 3918334Speter insn as having a logical link to the preceding insn. The same is true 4018334Speter for an insn explicitly using CC0. 4118334Speter 4218334Speter We check (with use_crosses_set_p) to avoid combining in such a way 4318334Speter as to move a computation to a place where its value would be different. 4418334Speter 4518334Speter Combination is done by mathematically substituting the previous 4618334Speter insn(s) values for the regs they set into the expressions in 4718334Speter the later insns that refer to these regs. If the result is a valid insn 4818334Speter for our target machine, according to the machine description, 4918334Speter we install it, delete the earlier insns, and update the data flow 5018334Speter information (LOG_LINKS and REG_NOTES) for what we did. 5118334Speter 5218334Speter There are a few exceptions where the dataflow information created by 5318334Speter flow.c aren't completely updated: 5418334Speter 5518334Speter - reg_live_length is not updated 5618334Speter - reg_n_refs is not adjusted in the rare case when a register is 5718334Speter no longer required in a computation 5818334Speter - there are extremely rare cases (see distribute_regnotes) when a 5918334Speter REG_DEAD note is lost 6018334Speter - a LOG_LINKS entry that refers to an insn with multiple SETs may be 6190075Sobrien removed because there is no way to know which register it was 6218334Speter linking 6318334Speter 6418334Speter To simplify substitution, we combine only when the earlier insn(s) 6518334Speter consist of only a single assignment. To simplify updating afterward, 6618334Speter we never combine when a subroutine call appears in the middle. 6718334Speter 6818334Speter Since we do not represent assignments to CC0 explicitly except when that 6918334Speter is all an insn does, there is no LOG_LINKS entry in an insn that uses 7018334Speter the condition code for the insn that set the condition code. 7118334Speter Fortunately, these two insns must be consecutive. 7218334Speter Therefore, every JUMP_INSN is taken to have an implicit logical link 7318334Speter to the preceding insn. This is not quite right, since non-jumps can 7418334Speter also use the condition code; but in practice such insns would not 7518334Speter combine anyway. */ 7618334Speter 7718334Speter#include "config.h" 7850397Sobrien#include "system.h" 7990075Sobrien#include "rtl.h" 8090075Sobrien#include "tm_p.h" 8118334Speter#include "flags.h" 8218334Speter#include "regs.h" 8318334Speter#include "hard-reg-set.h" 8418334Speter#include "basic-block.h" 8518334Speter#include "insn-config.h" 8690075Sobrien#include "function.h" 8790075Sobrien/* Include expr.h after insn-config.h so we get HAVE_conditional_move. */ 8850397Sobrien#include "expr.h" 8918334Speter#include "insn-attr.h" 9018334Speter#include "recog.h" 9118334Speter#include "real.h" 9250397Sobrien#include "toplev.h" 9318334Speter 9418334Speter/* It is not safe to use ordinary gen_lowpart in combine. 9518334Speter Use gen_lowpart_for_combine instead. See comments there. */ 9618334Speter#define gen_lowpart dont_use_gen_lowpart_you_dummy 9718334Speter 9818334Speter/* Number of attempts to combine instructions in this function. */ 9918334Speter 10018334Speterstatic int combine_attempts; 10118334Speter 10218334Speter/* Number of attempts that got as far as substitution in this function. */ 10318334Speter 10418334Speterstatic int combine_merges; 10518334Speter 10618334Speter/* Number of instructions combined with added SETs in this function. */ 10718334Speter 10818334Speterstatic int combine_extras; 10918334Speter 11018334Speter/* Number of instructions combined in this function. */ 11118334Speter 11218334Speterstatic int combine_successes; 11318334Speter 11418334Speter/* Totals over entire compilation. */ 11518334Speter 11618334Speterstatic int total_attempts, total_merges, total_extras, total_successes; 11718334Speter 11818334Speter 11918334Speter/* Vector mapping INSN_UIDs to cuids. 12018334Speter The cuids are like uids but increase monotonically always. 12118334Speter Combine always uses cuids so that it can compare them. 12218334Speter But actually renumbering the uids, which we used to do, 12318334Speter proves to be a bad idea because it makes it hard to compare 12418334Speter the dumps produced by earlier passes with those from later passes. */ 12518334Speter 12618334Speterstatic int *uid_cuid; 12718334Speterstatic int max_uid_cuid; 12818334Speter 12918334Speter/* Get the cuid of an insn. */ 13018334Speter 13150397Sobrien#define INSN_CUID(INSN) \ 13250397Sobrien(INSN_UID (INSN) > max_uid_cuid ? insn_cuid (INSN) : uid_cuid[INSN_UID (INSN)]) 13318334Speter 13490075Sobrien/* In case BITS_PER_WORD == HOST_BITS_PER_WIDE_INT, shifting by 13590075Sobrien BITS_PER_WORD would invoke undefined behavior. Work around it. */ 13690075Sobrien 13790075Sobrien#define UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD(val) \ 13890075Sobrien (((unsigned HOST_WIDE_INT) (val) << (BITS_PER_WORD - 1)) << 1) 13990075Sobrien 140117395Skan#define nonzero_bits(X, M) \ 141117395Skan cached_nonzero_bits (X, M, NULL_RTX, VOIDmode, 0) 142117395Skan 143117395Skan#define num_sign_bit_copies(X, M) \ 144117395Skan cached_num_sign_bit_copies (X, M, NULL_RTX, VOIDmode, 0) 145117395Skan 14618334Speter/* Maximum register number, which is the size of the tables below. */ 14718334Speter 14890075Sobrienstatic unsigned int combine_max_regno; 14918334Speter 15018334Speter/* Record last point of death of (hard or pseudo) register n. */ 15118334Speter 15218334Speterstatic rtx *reg_last_death; 15318334Speter 15418334Speter/* Record last point of modification of (hard or pseudo) register n. */ 15518334Speter 15618334Speterstatic rtx *reg_last_set; 15718334Speter 15818334Speter/* Record the cuid of the last insn that invalidated memory 15918334Speter (anything that writes memory, and subroutine calls, but not pushes). */ 16018334Speter 16118334Speterstatic int mem_last_set; 16218334Speter 16318334Speter/* Record the cuid of the last CALL_INSN 16418334Speter so we can tell whether a potential combination crosses any calls. */ 16518334Speter 16618334Speterstatic int last_call_cuid; 16718334Speter 16818334Speter/* When `subst' is called, this is the insn that is being modified 16918334Speter (by combining in a previous insn). The PATTERN of this insn 17018334Speter is still the old pattern partially modified and it should not be 17118334Speter looked at, but this may be used to examine the successors of the insn 17218334Speter to judge whether a simplification is valid. */ 17318334Speter 17418334Speterstatic rtx subst_insn; 17518334Speter 17618334Speter/* This is an insn that belongs before subst_insn, but is not currently 17718334Speter on the insn chain. */ 17818334Speter 17918334Speterstatic rtx subst_prev_insn; 18018334Speter 18118334Speter/* This is the lowest CUID that `subst' is currently dealing with. 18218334Speter get_last_value will not return a value if the register was set at or 18318334Speter after this CUID. If not for this mechanism, we could get confused if 18418334Speter I2 or I1 in try_combine were an insn that used the old value of a register 18518334Speter to obtain a new value. In that case, we might erroneously get the 18618334Speter new value of the register when we wanted the old one. */ 18718334Speter 18818334Speterstatic int subst_low_cuid; 18918334Speter 19018334Speter/* This contains any hard registers that are used in newpat; reg_dead_at_p 19118334Speter must consider all these registers to be always live. */ 19218334Speter 19318334Speterstatic HARD_REG_SET newpat_used_regs; 19418334Speter 19518334Speter/* This is an insn to which a LOG_LINKS entry has been added. If this 19618334Speter insn is the earlier than I2 or I3, combine should rescan starting at 19718334Speter that location. */ 19818334Speter 19918334Speterstatic rtx added_links_insn; 20018334Speter 201117395Skan/* Basic block in which we are performing combines. */ 202117395Skanstatic basic_block this_basic_block; 20390075Sobrien 20490075Sobrien/* A bitmap indicating which blocks had registers go dead at entry. 20590075Sobrien After combine, we'll need to re-do global life analysis with 20690075Sobrien those blocks as starting points. */ 20790075Sobrienstatic sbitmap refresh_blocks; 20890075Sobrienstatic int need_refresh; 20918334Speter 21018334Speter/* The next group of arrays allows the recording of the last value assigned 211117395Skan to (hard or pseudo) register n. We use this information to see if an 21218334Speter operation being processed is redundant given a prior operation performed 21318334Speter on the register. For example, an `and' with a constant is redundant if 21418334Speter all the zero bits are already known to be turned off. 21518334Speter 21618334Speter We use an approach similar to that used by cse, but change it in the 21718334Speter following ways: 21818334Speter 21918334Speter (1) We do not want to reinitialize at each label. 22018334Speter (2) It is useful, but not critical, to know the actual value assigned 22118334Speter to a register. Often just its form is helpful. 22218334Speter 22318334Speter Therefore, we maintain the following arrays: 22418334Speter 22518334Speter reg_last_set_value the last value assigned 22618334Speter reg_last_set_label records the value of label_tick when the 22718334Speter register was assigned 22818334Speter reg_last_set_table_tick records the value of label_tick when a 22918334Speter value using the register is assigned 230117395Skan reg_last_set_invalid set to nonzero when it is not valid 23118334Speter to use the value of this register in some 23218334Speter register's value 23318334Speter 23418334Speter To understand the usage of these tables, it is important to understand 23518334Speter the distinction between the value in reg_last_set_value being valid 23618334Speter and the register being validly contained in some other expression in the 23718334Speter table. 23818334Speter 239117395Skan Entry I in reg_last_set_value is valid if it is nonzero, and either 24018334Speter reg_n_sets[i] is 1 or reg_last_set_label[i] == label_tick. 24118334Speter 24218334Speter Register I may validly appear in any expression returned for the value 24318334Speter of another register if reg_n_sets[i] is 1. It may also appear in the 24418334Speter value for register J if reg_last_set_label[i] < reg_last_set_label[j] or 24518334Speter reg_last_set_invalid[j] is zero. 24618334Speter 24718334Speter If an expression is found in the table containing a register which may 24818334Speter not validly appear in an expression, the register is replaced by 24918334Speter something that won't match, (clobber (const_int 0)). 25018334Speter 251117395Skan reg_last_set_invalid[i] is set nonzero when register I is being assigned 25218334Speter to and reg_last_set_table_tick[i] == label_tick. */ 25318334Speter 25450397Sobrien/* Record last value assigned to (hard or pseudo) register n. */ 25518334Speter 25618334Speterstatic rtx *reg_last_set_value; 25718334Speter 25818334Speter/* Record the value of label_tick when the value for register n is placed in 25918334Speter reg_last_set_value[n]. */ 26018334Speter 26118334Speterstatic int *reg_last_set_label; 26218334Speter 26318334Speter/* Record the value of label_tick when an expression involving register n 26450397Sobrien is placed in reg_last_set_value. */ 26518334Speter 26618334Speterstatic int *reg_last_set_table_tick; 26718334Speter 268117395Skan/* Set nonzero if references to register n in expressions should not be 26918334Speter used. */ 27018334Speter 27118334Speterstatic char *reg_last_set_invalid; 27218334Speter 27350397Sobrien/* Incremented for each label. */ 27418334Speter 27518334Speterstatic int label_tick; 27618334Speter 27718334Speter/* Some registers that are set more than once and used in more than one 27818334Speter basic block are nevertheless always set in similar ways. For example, 27918334Speter a QImode register may be loaded from memory in two places on a machine 28018334Speter where byte loads zero extend. 28118334Speter 28218334Speter We record in the following array what we know about the nonzero 28318334Speter bits of a register, specifically which bits are known to be zero. 28418334Speter 28518334Speter If an entry is zero, it means that we don't know anything special. */ 28618334Speter 28718334Speterstatic unsigned HOST_WIDE_INT *reg_nonzero_bits; 28818334Speter 28918334Speter/* Mode used to compute significance in reg_nonzero_bits. It is the largest 29018334Speter integer mode that can fit in HOST_BITS_PER_WIDE_INT. */ 29118334Speter 29218334Speterstatic enum machine_mode nonzero_bits_mode; 29318334Speter 29418334Speter/* Nonzero if we know that a register has some leading bits that are always 29518334Speter equal to the sign bit. */ 29618334Speter 29790075Sobrienstatic unsigned char *reg_sign_bit_copies; 29818334Speter 29918334Speter/* Nonzero when reg_nonzero_bits and reg_sign_bit_copies can be safely used. 30018334Speter It is zero while computing them and after combine has completed. This 30118334Speter former test prevents propagating values based on previously set values, 30218334Speter which can be incorrect if a variable is modified in a loop. */ 30318334Speter 30418334Speterstatic int nonzero_sign_valid; 30518334Speter 30618334Speter/* These arrays are maintained in parallel with reg_last_set_value 30718334Speter and are used to store the mode in which the register was last set, 30818334Speter the bits that were known to be zero when it was last set, and the 30918334Speter number of sign bits copies it was known to have when it was last set. */ 31018334Speter 31118334Speterstatic enum machine_mode *reg_last_set_mode; 31218334Speterstatic unsigned HOST_WIDE_INT *reg_last_set_nonzero_bits; 31318334Speterstatic char *reg_last_set_sign_bit_copies; 31418334Speter 31518334Speter/* Record one modification to rtl structure 31618334Speter to be undone by storing old_contents into *where. 31718334Speter is_int is 1 if the contents are an int. */ 31818334Speter 31918334Speterstruct undo 32018334Speter{ 32150397Sobrien struct undo *next; 32218334Speter int is_int; 323117395Skan union {rtx r; int i;} old_contents; 324117395Skan union {rtx *r; int *i;} where; 32518334Speter}; 32618334Speter 32718334Speter/* Record a bunch of changes to be undone, up to MAX_UNDO of them. 32818334Speter num_undo says how many are currently recorded. 32918334Speter 33018334Speter other_insn is nonzero if we have modified some other insn in the process 33190075Sobrien of working on subst_insn. It must be verified too. */ 33218334Speter 33318334Speterstruct undobuf 33418334Speter{ 33550397Sobrien struct undo *undos; 33650397Sobrien struct undo *frees; 33718334Speter rtx other_insn; 33818334Speter}; 33918334Speter 34018334Speterstatic struct undobuf undobuf; 34118334Speter 34290075Sobrien/* Number of times the pseudo being substituted for 34390075Sobrien was found and replaced. */ 34490075Sobrien 34590075Sobrienstatic int n_occurrences; 34690075Sobrien 34790075Sobrienstatic void do_SUBST PARAMS ((rtx *, rtx)); 348117395Skanstatic void do_SUBST_INT PARAMS ((int *, int)); 34990075Sobrienstatic void init_reg_last_arrays PARAMS ((void)); 35090075Sobrienstatic void setup_incoming_promotions PARAMS ((void)); 35190075Sobrienstatic void set_nonzero_bits_and_sign_copies PARAMS ((rtx, rtx, void *)); 35290075Sobrienstatic int cant_combine_insn_p PARAMS ((rtx)); 35390075Sobrienstatic int can_combine_p PARAMS ((rtx, rtx, rtx, rtx, rtx *, rtx *)); 35490075Sobrienstatic int sets_function_arg_p PARAMS ((rtx)); 35590075Sobrienstatic int combinable_i3pat PARAMS ((rtx, rtx *, rtx, rtx, int, rtx *)); 35690075Sobrienstatic int contains_muldiv PARAMS ((rtx)); 35790075Sobrienstatic rtx try_combine PARAMS ((rtx, rtx, rtx, int *)); 35890075Sobrienstatic void undo_all PARAMS ((void)); 35990075Sobrienstatic void undo_commit PARAMS ((void)); 36090075Sobrienstatic rtx *find_split_point PARAMS ((rtx *, rtx)); 36190075Sobrienstatic rtx subst PARAMS ((rtx, rtx, rtx, int, int)); 36290075Sobrienstatic rtx combine_simplify_rtx PARAMS ((rtx, enum machine_mode, int, int)); 36390075Sobrienstatic rtx simplify_if_then_else PARAMS ((rtx)); 36490075Sobrienstatic rtx simplify_set PARAMS ((rtx)); 36590075Sobrienstatic rtx simplify_logical PARAMS ((rtx, int)); 36690075Sobrienstatic rtx expand_compound_operation PARAMS ((rtx)); 36790075Sobrienstatic rtx expand_field_assignment PARAMS ((rtx)); 36890075Sobrienstatic rtx make_extraction PARAMS ((enum machine_mode, rtx, HOST_WIDE_INT, 36990075Sobrien rtx, unsigned HOST_WIDE_INT, int, 37090075Sobrien int, int)); 37190075Sobrienstatic rtx extract_left_shift PARAMS ((rtx, int)); 37290075Sobrienstatic rtx make_compound_operation PARAMS ((rtx, enum rtx_code)); 37390075Sobrienstatic int get_pos_from_mask PARAMS ((unsigned HOST_WIDE_INT, 37490075Sobrien unsigned HOST_WIDE_INT *)); 37590075Sobrienstatic rtx force_to_mode PARAMS ((rtx, enum machine_mode, 37690075Sobrien unsigned HOST_WIDE_INT, rtx, int)); 37790075Sobrienstatic rtx if_then_else_cond PARAMS ((rtx, rtx *, rtx *)); 37890075Sobrienstatic rtx known_cond PARAMS ((rtx, enum rtx_code, rtx, rtx)); 37990075Sobrienstatic int rtx_equal_for_field_assignment_p PARAMS ((rtx, rtx)); 38090075Sobrienstatic rtx make_field_assignment PARAMS ((rtx)); 38190075Sobrienstatic rtx apply_distributive_law PARAMS ((rtx)); 38290075Sobrienstatic rtx simplify_and_const_int PARAMS ((rtx, enum machine_mode, rtx, 38390075Sobrien unsigned HOST_WIDE_INT)); 384117395Skanstatic unsigned HOST_WIDE_INT cached_nonzero_bits 385117395Skan PARAMS ((rtx, enum machine_mode, rtx, 386117395Skan enum machine_mode, 387117395Skan unsigned HOST_WIDE_INT)); 388117395Skanstatic unsigned HOST_WIDE_INT nonzero_bits1 389117395Skan PARAMS ((rtx, enum machine_mode, rtx, 390117395Skan enum machine_mode, 391117395Skan unsigned HOST_WIDE_INT)); 392117395Skanstatic unsigned int cached_num_sign_bit_copies 393117395Skan PARAMS ((rtx, enum machine_mode, rtx, 394117395Skan enum machine_mode, unsigned int)); 395117395Skanstatic unsigned int num_sign_bit_copies1 396117395Skan PARAMS ((rtx, enum machine_mode, rtx, 397117395Skan enum machine_mode, unsigned int)); 39890075Sobrienstatic int merge_outer_ops PARAMS ((enum rtx_code *, HOST_WIDE_INT *, 39990075Sobrien enum rtx_code, HOST_WIDE_INT, 40090075Sobrien enum machine_mode, int *)); 40190075Sobrienstatic rtx simplify_shift_const PARAMS ((rtx, enum rtx_code, enum machine_mode, 40290075Sobrien rtx, int)); 40390075Sobrienstatic int recog_for_combine PARAMS ((rtx *, rtx, rtx *)); 40490075Sobrienstatic rtx gen_lowpart_for_combine PARAMS ((enum machine_mode, rtx)); 40590075Sobrienstatic rtx gen_binary PARAMS ((enum rtx_code, enum machine_mode, 40690075Sobrien rtx, rtx)); 40790075Sobrienstatic enum rtx_code simplify_comparison PARAMS ((enum rtx_code, rtx *, rtx *)); 40890075Sobrienstatic void update_table_tick PARAMS ((rtx)); 40990075Sobrienstatic void record_value_for_reg PARAMS ((rtx, rtx, rtx)); 41090075Sobrienstatic void check_promoted_subreg PARAMS ((rtx, rtx)); 41190075Sobrienstatic void record_dead_and_set_regs_1 PARAMS ((rtx, rtx, void *)); 41290075Sobrienstatic void record_dead_and_set_regs PARAMS ((rtx)); 41390075Sobrienstatic int get_last_value_validate PARAMS ((rtx *, rtx, int, int)); 41490075Sobrienstatic rtx get_last_value PARAMS ((rtx)); 41590075Sobrienstatic int use_crosses_set_p PARAMS ((rtx, int)); 41690075Sobrienstatic void reg_dead_at_p_1 PARAMS ((rtx, rtx, void *)); 41790075Sobrienstatic int reg_dead_at_p PARAMS ((rtx, rtx)); 41890075Sobrienstatic void move_deaths PARAMS ((rtx, rtx, int, rtx, rtx *)); 41990075Sobrienstatic int reg_bitfield_target_p PARAMS ((rtx, rtx)); 42090075Sobrienstatic void distribute_notes PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx)); 42190075Sobrienstatic void distribute_links PARAMS ((rtx)); 42290075Sobrienstatic void mark_used_regs_combine PARAMS ((rtx)); 42390075Sobrienstatic int insn_cuid PARAMS ((rtx)); 42490075Sobrienstatic void record_promoted_value PARAMS ((rtx, rtx)); 42590075Sobrienstatic rtx reversed_comparison PARAMS ((rtx, enum machine_mode, rtx, rtx)); 42690075Sobrienstatic enum rtx_code combine_reversed_comparison_code PARAMS ((rtx)); 42790075Sobrien 42818334Speter/* Substitute NEWVAL, an rtx expression, into INTO, a place in some 42918334Speter insn. The substitution can be undone by undo_all. If INTO is already 43018334Speter set to NEWVAL, do not record this change. Because computing NEWVAL might 43118334Speter also call SUBST, we have to compute it before we put anything into 43218334Speter the undo table. */ 43318334Speter 43490075Sobrienstatic void 43590075Sobriendo_SUBST (into, newval) 43690075Sobrien rtx *into, newval; 43790075Sobrien{ 43890075Sobrien struct undo *buf; 43990075Sobrien rtx oldval = *into; 44018334Speter 44190075Sobrien if (oldval == newval) 44290075Sobrien return; 44390075Sobrien 44496263Sobrien /* We'd like to catch as many invalid transformations here as 44596263Sobrien possible. Unfortunately, there are way too many mode changes 44696263Sobrien that are perfectly valid, so we'd waste too much effort for 44796263Sobrien little gain doing the checks here. Focus on catching invalid 44896263Sobrien transformations involving integer constants. */ 44996263Sobrien if (GET_MODE_CLASS (GET_MODE (oldval)) == MODE_INT 45096263Sobrien && GET_CODE (newval) == CONST_INT) 45196263Sobrien { 45296263Sobrien /* Sanity check that we're replacing oldval with a CONST_INT 45396263Sobrien that is a valid sign-extension for the original mode. */ 45496263Sobrien if (INTVAL (newval) != trunc_int_for_mode (INTVAL (newval), 45596263Sobrien GET_MODE (oldval))) 45696263Sobrien abort (); 45796263Sobrien 45896263Sobrien /* Replacing the operand of a SUBREG or a ZERO_EXTEND with a 45996263Sobrien CONST_INT is not valid, because after the replacement, the 46096263Sobrien original mode would be gone. Unfortunately, we can't tell 46196263Sobrien when do_SUBST is called to replace the operand thereof, so we 46296263Sobrien perform this test on oldval instead, checking whether an 46396263Sobrien invalid replacement took place before we got here. */ 46496263Sobrien if ((GET_CODE (oldval) == SUBREG 46596263Sobrien && GET_CODE (SUBREG_REG (oldval)) == CONST_INT) 46696263Sobrien || (GET_CODE (oldval) == ZERO_EXTEND 46796263Sobrien && GET_CODE (XEXP (oldval, 0)) == CONST_INT)) 46896263Sobrien abort (); 46996263Sobrien } 47096263Sobrien 47190075Sobrien if (undobuf.frees) 47290075Sobrien buf = undobuf.frees, undobuf.frees = buf->next; 47390075Sobrien else 47490075Sobrien buf = (struct undo *) xmalloc (sizeof (struct undo)); 47590075Sobrien 47690075Sobrien buf->is_int = 0; 47790075Sobrien buf->where.r = into; 47890075Sobrien buf->old_contents.r = oldval; 47990075Sobrien *into = newval; 48090075Sobrien 48190075Sobrien buf->next = undobuf.undos, undobuf.undos = buf; 48290075Sobrien} 48390075Sobrien 48490075Sobrien#define SUBST(INTO, NEWVAL) do_SUBST(&(INTO), (NEWVAL)) 48590075Sobrien 48650397Sobrien/* Similar to SUBST, but NEWVAL is an int expression. Note that substitution 48750397Sobrien for the value of a HOST_WIDE_INT value (including CONST_INT) is 48850397Sobrien not safe. */ 48918334Speter 49090075Sobrienstatic void 49190075Sobriendo_SUBST_INT (into, newval) 492117395Skan int *into, newval; 49390075Sobrien{ 49490075Sobrien struct undo *buf; 495117395Skan int oldval = *into; 49618334Speter 49790075Sobrien if (oldval == newval) 49890075Sobrien return; 49918334Speter 50090075Sobrien if (undobuf.frees) 50190075Sobrien buf = undobuf.frees, undobuf.frees = buf->next; 50290075Sobrien else 50390075Sobrien buf = (struct undo *) xmalloc (sizeof (struct undo)); 50418334Speter 50590075Sobrien buf->is_int = 1; 50690075Sobrien buf->where.i = into; 50790075Sobrien buf->old_contents.i = oldval; 50890075Sobrien *into = newval; 50990075Sobrien 51090075Sobrien buf->next = undobuf.undos, undobuf.undos = buf; 51190075Sobrien} 51290075Sobrien 51390075Sobrien#define SUBST_INT(INTO, NEWVAL) do_SUBST_INT(&(INTO), (NEWVAL)) 51418334Speter 51518334Speter/* Main entry point for combiner. F is the first insn of the function. 51690075Sobrien NREGS is the first unused pseudo-reg number. 51718334Speter 518117395Skan Return nonzero if the combiner has turned an indirect jump 51990075Sobrien instruction into a direct jump. */ 52090075Sobrienint 52118334Spetercombine_instructions (f, nregs) 52218334Speter rtx f; 52390075Sobrien unsigned int nregs; 52418334Speter{ 52590075Sobrien rtx insn, next; 52650397Sobrien#ifdef HAVE_cc0 52790075Sobrien rtx prev; 52850397Sobrien#endif 52990075Sobrien int i; 53090075Sobrien rtx links, nextlinks; 53118334Speter 53290075Sobrien int new_direct_jump_p = 0; 53390075Sobrien 53418334Speter combine_attempts = 0; 53518334Speter combine_merges = 0; 53618334Speter combine_extras = 0; 53718334Speter combine_successes = 0; 53818334Speter 53918334Speter combine_max_regno = nregs; 54018334Speter 54190075Sobrien reg_nonzero_bits = ((unsigned HOST_WIDE_INT *) 54290075Sobrien xcalloc (nregs, sizeof (unsigned HOST_WIDE_INT))); 54390075Sobrien reg_sign_bit_copies 54490075Sobrien = (unsigned char *) xcalloc (nregs, sizeof (unsigned char)); 54518334Speter 54690075Sobrien reg_last_death = (rtx *) xmalloc (nregs * sizeof (rtx)); 54790075Sobrien reg_last_set = (rtx *) xmalloc (nregs * sizeof (rtx)); 54890075Sobrien reg_last_set_value = (rtx *) xmalloc (nregs * sizeof (rtx)); 54990075Sobrien reg_last_set_table_tick = (int *) xmalloc (nregs * sizeof (int)); 55090075Sobrien reg_last_set_label = (int *) xmalloc (nregs * sizeof (int)); 55190075Sobrien reg_last_set_invalid = (char *) xmalloc (nregs * sizeof (char)); 55218334Speter reg_last_set_mode 55390075Sobrien = (enum machine_mode *) xmalloc (nregs * sizeof (enum machine_mode)); 55418334Speter reg_last_set_nonzero_bits 55590075Sobrien = (unsigned HOST_WIDE_INT *) xmalloc (nregs * sizeof (HOST_WIDE_INT)); 55618334Speter reg_last_set_sign_bit_copies 55790075Sobrien = (char *) xmalloc (nregs * sizeof (char)); 55818334Speter 55918334Speter init_reg_last_arrays (); 56018334Speter 56118334Speter init_recog_no_volatile (); 56218334Speter 56318334Speter /* Compute maximum uid value so uid_cuid can be allocated. */ 56418334Speter 56518334Speter for (insn = f, i = 0; insn; insn = NEXT_INSN (insn)) 56618334Speter if (INSN_UID (insn) > i) 56718334Speter i = INSN_UID (insn); 56818334Speter 56990075Sobrien uid_cuid = (int *) xmalloc ((i + 1) * sizeof (int)); 57018334Speter max_uid_cuid = i; 57118334Speter 57218334Speter nonzero_bits_mode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0); 57318334Speter 57418334Speter /* Don't use reg_nonzero_bits when computing it. This can cause problems 57518334Speter when, for example, we have j <<= 1 in a loop. */ 57618334Speter 57718334Speter nonzero_sign_valid = 0; 57818334Speter 57918334Speter /* Compute the mapping from uids to cuids. 58018334Speter Cuids are numbers assigned to insns, like uids, 58190075Sobrien except that cuids increase monotonically through the code. 58218334Speter 58318334Speter Scan all SETs and see if we can deduce anything about what 58418334Speter bits are known to be zero for some registers and how many copies 58518334Speter of the sign bit are known to exist for those registers. 58618334Speter 58718334Speter Also set any known values so that we can use it while searching 58818334Speter for what bits are known to be set. */ 58918334Speter 59018334Speter label_tick = 1; 59118334Speter 59218334Speter /* We need to initialize it here, because record_dead_and_set_regs may call 59318334Speter get_last_value. */ 59418334Speter subst_prev_insn = NULL_RTX; 59518334Speter 59618334Speter setup_incoming_promotions (); 59718334Speter 598117395Skan refresh_blocks = sbitmap_alloc (last_basic_block); 59990075Sobrien sbitmap_zero (refresh_blocks); 60090075Sobrien need_refresh = 0; 60190075Sobrien 60218334Speter for (insn = f, i = 0; insn; insn = NEXT_INSN (insn)) 60318334Speter { 60418334Speter uid_cuid[INSN_UID (insn)] = ++i; 60518334Speter subst_low_cuid = i; 60618334Speter subst_insn = insn; 60718334Speter 60890075Sobrien if (INSN_P (insn)) 60918334Speter { 61090075Sobrien note_stores (PATTERN (insn), set_nonzero_bits_and_sign_copies, 61190075Sobrien NULL); 61218334Speter record_dead_and_set_regs (insn); 61350397Sobrien 61450397Sobrien#ifdef AUTO_INC_DEC 61550397Sobrien for (links = REG_NOTES (insn); links; links = XEXP (links, 1)) 61650397Sobrien if (REG_NOTE_KIND (links) == REG_INC) 61790075Sobrien set_nonzero_bits_and_sign_copies (XEXP (links, 0), NULL_RTX, 61890075Sobrien NULL); 61950397Sobrien#endif 62018334Speter } 62118334Speter 62218334Speter if (GET_CODE (insn) == CODE_LABEL) 62318334Speter label_tick++; 62418334Speter } 62518334Speter 62618334Speter nonzero_sign_valid = 1; 62718334Speter 62818334Speter /* Now scan all the insns in forward order. */ 62918334Speter 63018334Speter label_tick = 1; 63118334Speter last_call_cuid = 0; 63218334Speter mem_last_set = 0; 63318334Speter init_reg_last_arrays (); 63418334Speter setup_incoming_promotions (); 63518334Speter 636117395Skan FOR_EACH_BB (this_basic_block) 63718334Speter { 638117395Skan for (insn = this_basic_block->head; 639117395Skan insn != NEXT_INSN (this_basic_block->end); 640117395Skan insn = next ? next : NEXT_INSN (insn)) 641117395Skan { 642117395Skan next = 0; 64318334Speter 644117395Skan if (GET_CODE (insn) == CODE_LABEL) 645117395Skan label_tick++; 64618334Speter 647117395Skan else if (INSN_P (insn)) 648117395Skan { 649117395Skan /* See if we know about function return values before this 650117395Skan insn based upon SUBREG flags. */ 651117395Skan check_promoted_subreg (insn, PATTERN (insn)); 65218334Speter 653117395Skan /* Try this insn with each insn it links back to. */ 65490075Sobrien 655117395Skan for (links = LOG_LINKS (insn); links; links = XEXP (links, 1)) 656117395Skan if ((next = try_combine (insn, XEXP (links, 0), 657117395Skan NULL_RTX, &new_direct_jump_p)) != 0) 658117395Skan goto retry; 65918334Speter 660117395Skan /* Try each sequence of three linked insns ending with this one. */ 66118334Speter 662117395Skan for (links = LOG_LINKS (insn); links; links = XEXP (links, 1)) 663117395Skan { 664117395Skan rtx link = XEXP (links, 0); 66518334Speter 666117395Skan /* If the linked insn has been replaced by a note, then there 667117395Skan is no point in pursuing this chain any further. */ 668117395Skan if (GET_CODE (link) == NOTE) 669117395Skan continue; 67018334Speter 671117395Skan for (nextlinks = LOG_LINKS (link); 672117395Skan nextlinks; 673117395Skan nextlinks = XEXP (nextlinks, 1)) 674117395Skan if ((next = try_combine (insn, link, 675117395Skan XEXP (nextlinks, 0), 676117395Skan &new_direct_jump_p)) != 0) 677117395Skan goto retry; 678117395Skan } 67990075Sobrien 68018334Speter#ifdef HAVE_cc0 681117395Skan /* Try to combine a jump insn that uses CC0 682117395Skan with a preceding insn that sets CC0, and maybe with its 683117395Skan logical predecessor as well. 684117395Skan This is how we make decrement-and-branch insns. 685117395Skan We need this special code because data flow connections 686117395Skan via CC0 do not get entered in LOG_LINKS. */ 68718334Speter 688117395Skan if (GET_CODE (insn) == JUMP_INSN 689117395Skan && (prev = prev_nonnote_insn (insn)) != 0 690117395Skan && GET_CODE (prev) == INSN 691117395Skan && sets_cc0_p (PATTERN (prev))) 692117395Skan { 693117395Skan if ((next = try_combine (insn, prev, 694117395Skan NULL_RTX, &new_direct_jump_p)) != 0) 695117395Skan goto retry; 69618334Speter 697117395Skan for (nextlinks = LOG_LINKS (prev); nextlinks; 698117395Skan nextlinks = XEXP (nextlinks, 1)) 699117395Skan if ((next = try_combine (insn, prev, 700117395Skan XEXP (nextlinks, 0), 701117395Skan &new_direct_jump_p)) != 0) 702117395Skan goto retry; 703117395Skan } 70418334Speter 705117395Skan /* Do the same for an insn that explicitly references CC0. */ 706117395Skan if (GET_CODE (insn) == INSN 707117395Skan && (prev = prev_nonnote_insn (insn)) != 0 708117395Skan && GET_CODE (prev) == INSN 709117395Skan && sets_cc0_p (PATTERN (prev)) 710117395Skan && GET_CODE (PATTERN (insn)) == SET 711117395Skan && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (insn)))) 712117395Skan { 713117395Skan if ((next = try_combine (insn, prev, 714117395Skan NULL_RTX, &new_direct_jump_p)) != 0) 715117395Skan goto retry; 71618334Speter 717117395Skan for (nextlinks = LOG_LINKS (prev); nextlinks; 718117395Skan nextlinks = XEXP (nextlinks, 1)) 719117395Skan if ((next = try_combine (insn, prev, 720117395Skan XEXP (nextlinks, 0), 721117395Skan &new_direct_jump_p)) != 0) 722117395Skan goto retry; 723117395Skan } 724117395Skan 725117395Skan /* Finally, see if any of the insns that this insn links to 726117395Skan explicitly references CC0. If so, try this insn, that insn, 727117395Skan and its predecessor if it sets CC0. */ 728117395Skan for (links = LOG_LINKS (insn); links; links = XEXP (links, 1)) 729117395Skan if (GET_CODE (XEXP (links, 0)) == INSN 730117395Skan && GET_CODE (PATTERN (XEXP (links, 0))) == SET 731117395Skan && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (XEXP (links, 0)))) 732117395Skan && (prev = prev_nonnote_insn (XEXP (links, 0))) != 0 733117395Skan && GET_CODE (prev) == INSN 734117395Skan && sets_cc0_p (PATTERN (prev)) 735117395Skan && (next = try_combine (insn, XEXP (links, 0), 736117395Skan prev, &new_direct_jump_p)) != 0) 73718334Speter goto retry; 73818334Speter#endif 73918334Speter 740117395Skan /* Try combining an insn with two different insns whose results it 741117395Skan uses. */ 742117395Skan for (links = LOG_LINKS (insn); links; links = XEXP (links, 1)) 743117395Skan for (nextlinks = XEXP (links, 1); nextlinks; 744117395Skan nextlinks = XEXP (nextlinks, 1)) 745117395Skan if ((next = try_combine (insn, XEXP (links, 0), 746117395Skan XEXP (nextlinks, 0), 747117395Skan &new_direct_jump_p)) != 0) 748117395Skan goto retry; 74918334Speter 750117395Skan if (GET_CODE (insn) != NOTE) 751117395Skan record_dead_and_set_regs (insn); 75218334Speter 753117395Skan retry: 754117395Skan ; 755117395Skan } 75618334Speter } 75718334Speter } 758117395Skan clear_bb_flags (); 75918334Speter 760117395Skan EXECUTE_IF_SET_IN_SBITMAP (refresh_blocks, 0, i, 761117395Skan BASIC_BLOCK (i)->flags |= BB_DIRTY); 762117395Skan new_direct_jump_p |= purge_all_dead_edges (0); 76390075Sobrien delete_noop_moves (f); 76490075Sobrien 765117395Skan update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES, 766117395Skan PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE 767117395Skan | PROP_KILL_DEAD_CODE); 76890075Sobrien 76990075Sobrien /* Clean up. */ 77090075Sobrien sbitmap_free (refresh_blocks); 77190075Sobrien free (reg_nonzero_bits); 77290075Sobrien free (reg_sign_bit_copies); 77390075Sobrien free (reg_last_death); 77490075Sobrien free (reg_last_set); 77590075Sobrien free (reg_last_set_value); 77690075Sobrien free (reg_last_set_table_tick); 77790075Sobrien free (reg_last_set_label); 77890075Sobrien free (reg_last_set_invalid); 77990075Sobrien free (reg_last_set_mode); 78090075Sobrien free (reg_last_set_nonzero_bits); 78190075Sobrien free (reg_last_set_sign_bit_copies); 78290075Sobrien free (uid_cuid); 78390075Sobrien 78490075Sobrien { 78590075Sobrien struct undo *undo, *next; 78690075Sobrien for (undo = undobuf.frees; undo; undo = next) 78790075Sobrien { 78890075Sobrien next = undo->next; 78990075Sobrien free (undo); 79090075Sobrien } 79190075Sobrien undobuf.frees = 0; 79290075Sobrien } 79390075Sobrien 79418334Speter total_attempts += combine_attempts; 79518334Speter total_merges += combine_merges; 79618334Speter total_extras += combine_extras; 79718334Speter total_successes += combine_successes; 79818334Speter 79918334Speter nonzero_sign_valid = 0; 80052284Sobrien 80152284Sobrien /* Make recognizer allow volatile MEMs again. */ 80252284Sobrien init_recog (); 80390075Sobrien 80490075Sobrien return new_direct_jump_p; 80518334Speter} 80618334Speter 80718334Speter/* Wipe the reg_last_xxx arrays in preparation for another pass. */ 80818334Speter 80918334Speterstatic void 81018334Speterinit_reg_last_arrays () 81118334Speter{ 81290075Sobrien unsigned int nregs = combine_max_regno; 81318334Speter 81490075Sobrien memset ((char *) reg_last_death, 0, nregs * sizeof (rtx)); 81590075Sobrien memset ((char *) reg_last_set, 0, nregs * sizeof (rtx)); 81690075Sobrien memset ((char *) reg_last_set_value, 0, nregs * sizeof (rtx)); 81790075Sobrien memset ((char *) reg_last_set_table_tick, 0, nregs * sizeof (int)); 81890075Sobrien memset ((char *) reg_last_set_label, 0, nregs * sizeof (int)); 81990075Sobrien memset (reg_last_set_invalid, 0, nregs * sizeof (char)); 82090075Sobrien memset ((char *) reg_last_set_mode, 0, nregs * sizeof (enum machine_mode)); 82190075Sobrien memset ((char *) reg_last_set_nonzero_bits, 0, nregs * sizeof (HOST_WIDE_INT)); 82290075Sobrien memset (reg_last_set_sign_bit_copies, 0, nregs * sizeof (char)); 82318334Speter} 82418334Speter 82518334Speter/* Set up any promoted values for incoming argument registers. */ 82618334Speter 82718334Speterstatic void 82818334Spetersetup_incoming_promotions () 82918334Speter{ 83018334Speter#ifdef PROMOTE_FUNCTION_ARGS 83190075Sobrien unsigned int regno; 83218334Speter rtx reg; 83318334Speter enum machine_mode mode; 83418334Speter int unsignedp; 83518334Speter rtx first = get_insns (); 83618334Speter 83790075Sobrien#ifndef OUTGOING_REGNO 83890075Sobrien#define OUTGOING_REGNO(N) N 83990075Sobrien#endif 84018334Speter for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 84190075Sobrien /* Check whether this register can hold an incoming pointer 84290075Sobrien argument. FUNCTION_ARG_REGNO_P tests outgoing register 84390075Sobrien numbers, so translate if necessary due to register windows. */ 84490075Sobrien if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (regno)) 84518334Speter && (reg = promoted_input_arg (regno, &mode, &unsignedp)) != 0) 84650397Sobrien { 84750397Sobrien record_value_for_reg 84850397Sobrien (reg, first, gen_rtx_fmt_e ((unsignedp ? ZERO_EXTEND 84950397Sobrien : SIGN_EXTEND), 85050397Sobrien GET_MODE (reg), 85150397Sobrien gen_rtx_CLOBBER (mode, const0_rtx))); 85250397Sobrien } 85318334Speter#endif 85418334Speter} 85518334Speter 85650397Sobrien/* Called via note_stores. If X is a pseudo that is narrower than 85750397Sobrien HOST_BITS_PER_WIDE_INT and is being set, record what bits are known zero. 85818334Speter 85918334Speter If we are setting only a portion of X and we can't figure out what 86018334Speter portion, assume all bits will be used since we don't know what will 86118334Speter be happening. 86218334Speter 86318334Speter Similarly, set how many bits of X are known to be copies of the sign bit 86490075Sobrien at all locations in the function. This is the smallest number implied 86518334Speter by any set of X. */ 86618334Speter 86718334Speterstatic void 86890075Sobrienset_nonzero_bits_and_sign_copies (x, set, data) 86918334Speter rtx x; 87018334Speter rtx set; 87190075Sobrien void *data ATTRIBUTE_UNUSED; 87218334Speter{ 87390075Sobrien unsigned int num; 87418334Speter 87518334Speter if (GET_CODE (x) == REG 87618334Speter && REGNO (x) >= FIRST_PSEUDO_REGISTER 87718334Speter /* If this register is undefined at the start of the file, we can't 87818334Speter say what its contents were. */ 879117395Skan && ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, REGNO (x)) 88018334Speter && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT) 88118334Speter { 88250397Sobrien if (set == 0 || GET_CODE (set) == CLOBBER) 88318334Speter { 88418334Speter reg_nonzero_bits[REGNO (x)] = GET_MODE_MASK (GET_MODE (x)); 88550397Sobrien reg_sign_bit_copies[REGNO (x)] = 1; 88618334Speter return; 88718334Speter } 88818334Speter 88918334Speter /* If this is a complex assignment, see if we can convert it into a 89018334Speter simple assignment. */ 89118334Speter set = expand_field_assignment (set); 89218334Speter 89318334Speter /* If this is a simple assignment, or we have a paradoxical SUBREG, 89418334Speter set what we know about X. */ 89518334Speter 89618334Speter if (SET_DEST (set) == x 89718334Speter || (GET_CODE (SET_DEST (set)) == SUBREG 89818334Speter && (GET_MODE_SIZE (GET_MODE (SET_DEST (set))) 89918334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (set))))) 90018334Speter && SUBREG_REG (SET_DEST (set)) == x)) 90118334Speter { 90218334Speter rtx src = SET_SRC (set); 90318334Speter 90418334Speter#ifdef SHORT_IMMEDIATES_SIGN_EXTEND 90518334Speter /* If X is narrower than a word and SRC is a non-negative 90618334Speter constant that would appear negative in the mode of X, 90718334Speter sign-extend it for use in reg_nonzero_bits because some 90818334Speter machines (maybe most) will actually do the sign-extension 90990075Sobrien and this is the conservative approach. 91018334Speter 91118334Speter ??? For 2.5, try to tighten up the MD files in this regard 91218334Speter instead of this kludge. */ 91318334Speter 91418334Speter if (GET_MODE_BITSIZE (GET_MODE (x)) < BITS_PER_WORD 91518334Speter && GET_CODE (src) == CONST_INT 91618334Speter && INTVAL (src) > 0 91718334Speter && 0 != (INTVAL (src) 91818334Speter & ((HOST_WIDE_INT) 1 91918334Speter << (GET_MODE_BITSIZE (GET_MODE (x)) - 1)))) 92018334Speter src = GEN_INT (INTVAL (src) 92118334Speter | ((HOST_WIDE_INT) (-1) 92218334Speter << GET_MODE_BITSIZE (GET_MODE (x)))); 92318334Speter#endif 92418334Speter 92596263Sobrien /* Don't call nonzero_bits if it cannot change anything. */ 92696263Sobrien if (reg_nonzero_bits[REGNO (x)] != ~(unsigned HOST_WIDE_INT) 0) 92796263Sobrien reg_nonzero_bits[REGNO (x)] 92896263Sobrien |= nonzero_bits (src, nonzero_bits_mode); 92918334Speter num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x)); 93018334Speter if (reg_sign_bit_copies[REGNO (x)] == 0 93118334Speter || reg_sign_bit_copies[REGNO (x)] > num) 93218334Speter reg_sign_bit_copies[REGNO (x)] = num; 93318334Speter } 93418334Speter else 93518334Speter { 93618334Speter reg_nonzero_bits[REGNO (x)] = GET_MODE_MASK (GET_MODE (x)); 93750397Sobrien reg_sign_bit_copies[REGNO (x)] = 1; 93818334Speter } 93918334Speter } 94018334Speter} 94118334Speter 94218334Speter/* See if INSN can be combined into I3. PRED and SUCC are optionally 94318334Speter insns that were previously combined into I3 or that will be combined 94418334Speter into the merger of INSN and I3. 94518334Speter 94618334Speter Return 0 if the combination is not allowed for any reason. 94718334Speter 94890075Sobrien If the combination is allowed, *PDEST will be set to the single 94918334Speter destination of INSN and *PSRC to the single source, and this function 95018334Speter will return 1. */ 95118334Speter 95218334Speterstatic int 95318334Spetercan_combine_p (insn, i3, pred, succ, pdest, psrc) 95418334Speter rtx insn; 95518334Speter rtx i3; 95652284Sobrien rtx pred ATTRIBUTE_UNUSED; 95752284Sobrien rtx succ; 95818334Speter rtx *pdest, *psrc; 95918334Speter{ 96018334Speter int i; 96118334Speter rtx set = 0, src, dest; 96250397Sobrien rtx p; 96350397Sobrien#ifdef AUTO_INC_DEC 96450397Sobrien rtx link; 96550397Sobrien#endif 96618334Speter int all_adjacent = (succ ? (next_active_insn (insn) == succ 96718334Speter && next_active_insn (succ) == i3) 96818334Speter : next_active_insn (insn) == i3); 96918334Speter 97018334Speter /* Can combine only if previous insn is a SET of a REG, a SUBREG or CC0. 97190075Sobrien or a PARALLEL consisting of such a SET and CLOBBERs. 97218334Speter 97318334Speter If INSN has CLOBBER parallel parts, ignore them for our processing. 97418334Speter By definition, these happen during the execution of the insn. When it 97518334Speter is merged with another insn, all bets are off. If they are, in fact, 97618334Speter needed and aren't also supplied in I3, they may be added by 97790075Sobrien recog_for_combine. Otherwise, it won't match. 97818334Speter 97918334Speter We can also ignore a SET whose SET_DEST is mentioned in a REG_UNUSED 98018334Speter note. 98118334Speter 98290075Sobrien Get the source and destination of INSN. If more than one, can't 98318334Speter combine. */ 98490075Sobrien 98518334Speter if (GET_CODE (PATTERN (insn)) == SET) 98618334Speter set = PATTERN (insn); 98718334Speter else if (GET_CODE (PATTERN (insn)) == PARALLEL 98818334Speter && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET) 98918334Speter { 99018334Speter for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++) 99118334Speter { 99218334Speter rtx elt = XVECEXP (PATTERN (insn), 0, i); 99318334Speter 99418334Speter switch (GET_CODE (elt)) 99518334Speter { 99650397Sobrien /* This is important to combine floating point insns 99750397Sobrien for the SH4 port. */ 99850397Sobrien case USE: 99950397Sobrien /* Combining an isolated USE doesn't make sense. 100090075Sobrien We depend here on combinable_i3pat to reject them. */ 100150397Sobrien /* The code below this loop only verifies that the inputs of 100250397Sobrien the SET in INSN do not change. We call reg_set_between_p 100390075Sobrien to verify that the REG in the USE does not change between 100450397Sobrien I3 and INSN. 100550397Sobrien If the USE in INSN was for a pseudo register, the matching 100650397Sobrien insn pattern will likely match any register; combining this 100750397Sobrien with any other USE would only be safe if we knew that the 100850397Sobrien used registers have identical values, or if there was 100950397Sobrien something to tell them apart, e.g. different modes. For 101090075Sobrien now, we forgo such complicated tests and simply disallow 101150397Sobrien combining of USES of pseudo registers with any other USE. */ 101250397Sobrien if (GET_CODE (XEXP (elt, 0)) == REG 101350397Sobrien && GET_CODE (PATTERN (i3)) == PARALLEL) 101450397Sobrien { 101550397Sobrien rtx i3pat = PATTERN (i3); 101650397Sobrien int i = XVECLEN (i3pat, 0) - 1; 101790075Sobrien unsigned int regno = REGNO (XEXP (elt, 0)); 101890075Sobrien 101950397Sobrien do 102050397Sobrien { 102150397Sobrien rtx i3elt = XVECEXP (i3pat, 0, i); 102290075Sobrien 102350397Sobrien if (GET_CODE (i3elt) == USE 102450397Sobrien && GET_CODE (XEXP (i3elt, 0)) == REG 102550397Sobrien && (REGNO (XEXP (i3elt, 0)) == regno 102650397Sobrien ? reg_set_between_p (XEXP (elt, 0), 102750397Sobrien PREV_INSN (insn), i3) 102850397Sobrien : regno >= FIRST_PSEUDO_REGISTER)) 102950397Sobrien return 0; 103050397Sobrien } 103150397Sobrien while (--i >= 0); 103250397Sobrien } 103350397Sobrien break; 103450397Sobrien 103518334Speter /* We can ignore CLOBBERs. */ 103618334Speter case CLOBBER: 103718334Speter break; 103818334Speter 103918334Speter case SET: 104018334Speter /* Ignore SETs whose result isn't used but not those that 104118334Speter have side-effects. */ 104218334Speter if (find_reg_note (insn, REG_UNUSED, SET_DEST (elt)) 104318334Speter && ! side_effects_p (elt)) 104418334Speter break; 104518334Speter 104618334Speter /* If we have already found a SET, this is a second one and 104718334Speter so we cannot combine with this insn. */ 104818334Speter if (set) 104918334Speter return 0; 105018334Speter 105118334Speter set = elt; 105218334Speter break; 105318334Speter 105418334Speter default: 105518334Speter /* Anything else means we can't combine. */ 105618334Speter return 0; 105718334Speter } 105818334Speter } 105918334Speter 106018334Speter if (set == 0 106118334Speter /* If SET_SRC is an ASM_OPERANDS we can't throw away these CLOBBERs, 106218334Speter so don't do anything with it. */ 106318334Speter || GET_CODE (SET_SRC (set)) == ASM_OPERANDS) 106418334Speter return 0; 106518334Speter } 106618334Speter else 106718334Speter return 0; 106818334Speter 106918334Speter if (set == 0) 107018334Speter return 0; 107118334Speter 107218334Speter set = expand_field_assignment (set); 107318334Speter src = SET_SRC (set), dest = SET_DEST (set); 107418334Speter 107518334Speter /* Don't eliminate a store in the stack pointer. */ 107618334Speter if (dest == stack_pointer_rtx 107718334Speter /* If we couldn't eliminate a field assignment, we can't combine. */ 107818334Speter || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == STRICT_LOW_PART 107918334Speter /* Don't combine with an insn that sets a register to itself if it has 108018334Speter a REG_EQUAL note. This may be part of a REG_NO_CONFLICT sequence. */ 108118334Speter || (rtx_equal_p (src, dest) && find_reg_note (insn, REG_EQUAL, NULL_RTX)) 108290075Sobrien /* Can't merge an ASM_OPERANDS. */ 108390075Sobrien || GET_CODE (src) == ASM_OPERANDS 108418334Speter /* Can't merge a function call. */ 108518334Speter || GET_CODE (src) == CALL 108618334Speter /* Don't eliminate a function call argument. */ 108718334Speter || (GET_CODE (i3) == CALL_INSN 108818334Speter && (find_reg_fusage (i3, USE, dest) 108918334Speter || (GET_CODE (dest) == REG 109018334Speter && REGNO (dest) < FIRST_PSEUDO_REGISTER 109118334Speter && global_regs[REGNO (dest)]))) 109218334Speter /* Don't substitute into an incremented register. */ 109318334Speter || FIND_REG_INC_NOTE (i3, dest) 109418334Speter || (succ && FIND_REG_INC_NOTE (succ, dest)) 109552284Sobrien#if 0 109618334Speter /* Don't combine the end of a libcall into anything. */ 109752284Sobrien /* ??? This gives worse code, and appears to be unnecessary, since no 109852284Sobrien pass after flow uses REG_LIBCALL/REG_RETVAL notes. Local-alloc does 109952284Sobrien use REG_RETVAL notes for noconflict blocks, but other code here 110052284Sobrien makes sure that those insns don't disappear. */ 110118334Speter || find_reg_note (insn, REG_RETVAL, NULL_RTX) 110252284Sobrien#endif 110318334Speter /* Make sure that DEST is not used after SUCC but before I3. */ 110418334Speter || (succ && ! all_adjacent 110518334Speter && reg_used_between_p (dest, succ, i3)) 110618334Speter /* Make sure that the value that is to be substituted for the register 110718334Speter does not use any registers whose values alter in between. However, 110818334Speter If the insns are adjacent, a use can't cross a set even though we 110918334Speter think it might (this can happen for a sequence of insns each setting 111018334Speter the same destination; reg_last_set of that register might point to 111118334Speter a NOTE). If INSN has a REG_EQUIV note, the register is always 111218334Speter equivalent to the memory so the substitution is valid even if there 111318334Speter are intervening stores. Also, don't move a volatile asm or 111418334Speter UNSPEC_VOLATILE across any other insns. */ 111518334Speter || (! all_adjacent 111618334Speter && (((GET_CODE (src) != MEM 111718334Speter || ! find_reg_note (insn, REG_EQUIV, src)) 111818334Speter && use_crosses_set_p (src, INSN_CUID (insn))) 111918334Speter || (GET_CODE (src) == ASM_OPERANDS && MEM_VOLATILE_P (src)) 112018334Speter || GET_CODE (src) == UNSPEC_VOLATILE)) 112118334Speter /* If there is a REG_NO_CONFLICT note for DEST in I3 or SUCC, we get 112218334Speter better register allocation by not doing the combine. */ 112318334Speter || find_reg_note (i3, REG_NO_CONFLICT, dest) 112418334Speter || (succ && find_reg_note (succ, REG_NO_CONFLICT, dest)) 112518334Speter /* Don't combine across a CALL_INSN, because that would possibly 112618334Speter change whether the life span of some REGs crosses calls or not, 112718334Speter and it is a pain to update that information. 112818334Speter Exception: if source is a constant, moving it later can't hurt. 112918334Speter Accept that special case, because it helps -fforce-addr a lot. */ 113018334Speter || (INSN_CUID (insn) < last_call_cuid && ! CONSTANT_P (src))) 113118334Speter return 0; 113218334Speter 113318334Speter /* DEST must either be a REG or CC0. */ 113418334Speter if (GET_CODE (dest) == REG) 113518334Speter { 113618334Speter /* If register alignment is being enforced for multi-word items in all 113718334Speter cases except for parameters, it is possible to have a register copy 113818334Speter insn referencing a hard register that is not allowed to contain the 113918334Speter mode being copied and which would not be valid as an operand of most 114018334Speter insns. Eliminate this problem by not combining with such an insn. 114118334Speter 114218334Speter Also, on some machines we don't want to extend the life of a hard 114390075Sobrien register. */ 114418334Speter 114518334Speter if (GET_CODE (src) == REG 114618334Speter && ((REGNO (dest) < FIRST_PSEUDO_REGISTER 114718334Speter && ! HARD_REGNO_MODE_OK (REGNO (dest), GET_MODE (dest))) 114818334Speter /* Don't extend the life of a hard register unless it is 114918334Speter user variable (if we have few registers) or it can't 115018334Speter fit into the desired register (meaning something special 115150397Sobrien is going on). 115250397Sobrien Also avoid substituting a return register into I3, because 115350397Sobrien reload can't handle a conflict with constraints of other 115450397Sobrien inputs. */ 115518334Speter || (REGNO (src) < FIRST_PSEUDO_REGISTER 115690075Sobrien && ! HARD_REGNO_MODE_OK (REGNO (src), GET_MODE (src))))) 115718334Speter return 0; 115818334Speter } 115918334Speter else if (GET_CODE (dest) != CC0) 116018334Speter return 0; 116118334Speter 116218334Speter /* Don't substitute for a register intended as a clobberable operand. 116318334Speter Similarly, don't substitute an expression containing a register that 116418334Speter will be clobbered in I3. */ 116518334Speter if (GET_CODE (PATTERN (i3)) == PARALLEL) 116618334Speter for (i = XVECLEN (PATTERN (i3), 0) - 1; i >= 0; i--) 116718334Speter if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER 116818334Speter && (reg_overlap_mentioned_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0), 116918334Speter src) 117018334Speter || rtx_equal_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0), dest))) 117118334Speter return 0; 117218334Speter 117318334Speter /* If INSN contains anything volatile, or is an `asm' (whether volatile 117450397Sobrien or not), reject, unless nothing volatile comes between it and I3 */ 117518334Speter 117618334Speter if (GET_CODE (src) == ASM_OPERANDS || volatile_refs_p (src)) 117750397Sobrien { 117850397Sobrien /* Make sure succ doesn't contain a volatile reference. */ 117950397Sobrien if (succ != 0 && volatile_refs_p (PATTERN (succ))) 118050397Sobrien return 0; 118190075Sobrien 118250397Sobrien for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p)) 118390075Sobrien if (INSN_P (p) && p != succ && volatile_refs_p (PATTERN (p))) 118490075Sobrien return 0; 118550397Sobrien } 118618334Speter 118750397Sobrien /* If INSN is an asm, and DEST is a hard register, reject, since it has 118850397Sobrien to be an explicit register variable, and was chosen for a reason. */ 118950397Sobrien 119050397Sobrien if (GET_CODE (src) == ASM_OPERANDS 119150397Sobrien && GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER) 119250397Sobrien return 0; 119350397Sobrien 119418334Speter /* If there are any volatile insns between INSN and I3, reject, because 119518334Speter they might affect machine state. */ 119618334Speter 119718334Speter for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p)) 119890075Sobrien if (INSN_P (p) && p != succ && volatile_insn_p (PATTERN (p))) 119918334Speter return 0; 120018334Speter 120118334Speter /* If INSN or I2 contains an autoincrement or autodecrement, 120218334Speter make sure that register is not used between there and I3, 120318334Speter and not already used in I3 either. 120418334Speter Also insist that I3 not be a jump; if it were one 120518334Speter and the incremented register were spilled, we would lose. */ 120618334Speter 120718334Speter#ifdef AUTO_INC_DEC 120818334Speter for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) 120918334Speter if (REG_NOTE_KIND (link) == REG_INC 121018334Speter && (GET_CODE (i3) == JUMP_INSN 121118334Speter || reg_used_between_p (XEXP (link, 0), insn, i3) 121218334Speter || reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i3)))) 121318334Speter return 0; 121418334Speter#endif 121518334Speter 121618334Speter#ifdef HAVE_cc0 121718334Speter /* Don't combine an insn that follows a CC0-setting insn. 121818334Speter An insn that uses CC0 must not be separated from the one that sets it. 121918334Speter We do, however, allow I2 to follow a CC0-setting insn if that insn 122018334Speter is passed as I1; in that case it will be deleted also. 122118334Speter We also allow combining in this case if all the insns are adjacent 122218334Speter because that would leave the two CC0 insns adjacent as well. 122318334Speter It would be more logical to test whether CC0 occurs inside I1 or I2, 122418334Speter but that would be much slower, and this ought to be equivalent. */ 122518334Speter 122618334Speter p = prev_nonnote_insn (insn); 122718334Speter if (p && p != pred && GET_CODE (p) == INSN && sets_cc0_p (PATTERN (p)) 122818334Speter && ! all_adjacent) 122918334Speter return 0; 123018334Speter#endif 123118334Speter 123218334Speter /* If we get here, we have passed all the tests and the combination is 123318334Speter to be allowed. */ 123418334Speter 123518334Speter *pdest = dest; 123618334Speter *psrc = src; 123718334Speter 123818334Speter return 1; 123918334Speter} 124018334Speter 124150397Sobrien/* Check if PAT is an insn - or a part of it - used to set up an 124250397Sobrien argument for a function in a hard register. */ 124350397Sobrien 124450397Sobrienstatic int 124550397Sobriensets_function_arg_p (pat) 124650397Sobrien rtx pat; 124750397Sobrien{ 124850397Sobrien int i; 124950397Sobrien rtx inner_dest; 125050397Sobrien 125150397Sobrien switch (GET_CODE (pat)) 125250397Sobrien { 125350397Sobrien case INSN: 125450397Sobrien return sets_function_arg_p (PATTERN (pat)); 125550397Sobrien 125650397Sobrien case PARALLEL: 125750397Sobrien for (i = XVECLEN (pat, 0); --i >= 0;) 125850397Sobrien if (sets_function_arg_p (XVECEXP (pat, 0, i))) 125950397Sobrien return 1; 126050397Sobrien 126150397Sobrien break; 126250397Sobrien 126350397Sobrien case SET: 126450397Sobrien inner_dest = SET_DEST (pat); 126550397Sobrien while (GET_CODE (inner_dest) == STRICT_LOW_PART 126650397Sobrien || GET_CODE (inner_dest) == SUBREG 126750397Sobrien || GET_CODE (inner_dest) == ZERO_EXTRACT) 126850397Sobrien inner_dest = XEXP (inner_dest, 0); 126950397Sobrien 127050397Sobrien return (GET_CODE (inner_dest) == REG 127150397Sobrien && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER 127250397Sobrien && FUNCTION_ARG_REGNO_P (REGNO (inner_dest))); 127350397Sobrien 127450397Sobrien default: 127550397Sobrien break; 127650397Sobrien } 127750397Sobrien 127850397Sobrien return 0; 127950397Sobrien} 128050397Sobrien 128118334Speter/* LOC is the location within I3 that contains its pattern or the component 128218334Speter of a PARALLEL of the pattern. We validate that it is valid for combining. 128318334Speter 128418334Speter One problem is if I3 modifies its output, as opposed to replacing it 128518334Speter entirely, we can't allow the output to contain I2DEST or I1DEST as doing 128618334Speter so would produce an insn that is not equivalent to the original insns. 128718334Speter 128818334Speter Consider: 128918334Speter 129018334Speter (set (reg:DI 101) (reg:DI 100)) 129118334Speter (set (subreg:SI (reg:DI 101) 0) <foo>) 129218334Speter 129318334Speter This is NOT equivalent to: 129418334Speter 129518334Speter (parallel [(set (subreg:SI (reg:DI 100) 0) <foo>) 129690075Sobrien (set (reg:DI 101) (reg:DI 100))]) 129718334Speter 129818334Speter Not only does this modify 100 (in which case it might still be valid 129990075Sobrien if 100 were dead in I2), it sets 101 to the ORIGINAL value of 100. 130018334Speter 130118334Speter We can also run into a problem if I2 sets a register that I1 130218334Speter uses and I1 gets directly substituted into I3 (not via I2). In that 130318334Speter case, we would be getting the wrong value of I2DEST into I3, so we 130418334Speter must reject the combination. This case occurs when I2 and I1 both 130518334Speter feed into I3, rather than when I1 feeds into I2, which feeds into I3. 1306117395Skan If I1_NOT_IN_SRC is nonzero, it means that finding I1 in the source 130718334Speter of a SET must prevent combination from occurring. 130818334Speter 130918334Speter Before doing the above check, we first try to expand a field assignment 131018334Speter into a set of logical operations. 131118334Speter 1312117395Skan If PI3_DEST_KILLED is nonzero, it is a pointer to a location in which 131318334Speter we place a register that is both set and used within I3. If more than one 131418334Speter such register is detected, we fail. 131518334Speter 131618334Speter Return 1 if the combination is valid, zero otherwise. */ 131718334Speter 131818334Speterstatic int 131918334Spetercombinable_i3pat (i3, loc, i2dest, i1dest, i1_not_in_src, pi3dest_killed) 132018334Speter rtx i3; 132118334Speter rtx *loc; 132218334Speter rtx i2dest; 132318334Speter rtx i1dest; 132418334Speter int i1_not_in_src; 132518334Speter rtx *pi3dest_killed; 132618334Speter{ 132718334Speter rtx x = *loc; 132818334Speter 132918334Speter if (GET_CODE (x) == SET) 133018334Speter { 133118334Speter rtx set = expand_field_assignment (x); 133218334Speter rtx dest = SET_DEST (set); 133318334Speter rtx src = SET_SRC (set); 133450397Sobrien rtx inner_dest = dest; 133590075Sobrien 133650397Sobrien#if 0 133750397Sobrien rtx inner_src = src; 133850397Sobrien#endif 133918334Speter 134018334Speter SUBST (*loc, set); 134118334Speter 134218334Speter while (GET_CODE (inner_dest) == STRICT_LOW_PART 134318334Speter || GET_CODE (inner_dest) == SUBREG 134418334Speter || GET_CODE (inner_dest) == ZERO_EXTRACT) 134518334Speter inner_dest = XEXP (inner_dest, 0); 134618334Speter 134718334Speter /* We probably don't need this any more now that LIMIT_RELOAD_CLASS 134818334Speter was added. */ 134918334Speter#if 0 135018334Speter while (GET_CODE (inner_src) == STRICT_LOW_PART 135118334Speter || GET_CODE (inner_src) == SUBREG 135218334Speter || GET_CODE (inner_src) == ZERO_EXTRACT) 135318334Speter inner_src = XEXP (inner_src, 0); 135418334Speter 135518334Speter /* If it is better that two different modes keep two different pseudos, 135618334Speter avoid combining them. This avoids producing the following pattern 135718334Speter on a 386: 135818334Speter (set (subreg:SI (reg/v:QI 21) 0) 135918334Speter (lshiftrt:SI (reg/v:SI 20) 136018334Speter (const_int 24))) 136118334Speter If that were made, reload could not handle the pair of 136218334Speter reg 20/21, since it would try to get any GENERAL_REGS 136318334Speter but some of them don't handle QImode. */ 136418334Speter 136518334Speter if (rtx_equal_p (inner_src, i2dest) 136618334Speter && GET_CODE (inner_dest) == REG 136718334Speter && ! MODES_TIEABLE_P (GET_MODE (i2dest), GET_MODE (inner_dest))) 136818334Speter return 0; 136918334Speter#endif 137018334Speter 137118334Speter /* Check for the case where I3 modifies its output, as 137218334Speter discussed above. */ 137318334Speter if ((inner_dest != dest 137418334Speter && (reg_overlap_mentioned_p (i2dest, inner_dest) 137518334Speter || (i1dest && reg_overlap_mentioned_p (i1dest, inner_dest)))) 137650397Sobrien 137790075Sobrien /* This is the same test done in can_combine_p except we can't test 137890075Sobrien all_adjacent; we don't have to, since this instruction will stay 137990075Sobrien in place, thus we are not considering increasing the lifetime of 138090075Sobrien INNER_DEST. 138150397Sobrien 138250397Sobrien Also, if this insn sets a function argument, combining it with 138350397Sobrien something that might need a spill could clobber a previous 138450397Sobrien function argument; the all_adjacent test in can_combine_p also 138550397Sobrien checks this; here, we do a more specific test for this case. */ 138690075Sobrien 138718334Speter || (GET_CODE (inner_dest) == REG 138818334Speter && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER 138918334Speter && (! HARD_REGNO_MODE_OK (REGNO (inner_dest), 139090075Sobrien GET_MODE (inner_dest)))) 139118334Speter || (i1_not_in_src && reg_overlap_mentioned_p (i1dest, src))) 139218334Speter return 0; 139318334Speter 139418334Speter /* If DEST is used in I3, it is being killed in this insn, 139590075Sobrien so record that for later. 139618334Speter Never add REG_DEAD notes for the FRAME_POINTER_REGNUM or the 139718334Speter STACK_POINTER_REGNUM, since these are always considered to be 139818334Speter live. Similarly for ARG_POINTER_REGNUM if it is fixed. */ 139918334Speter if (pi3dest_killed && GET_CODE (dest) == REG 140018334Speter && reg_referenced_p (dest, PATTERN (i3)) 140118334Speter && REGNO (dest) != FRAME_POINTER_REGNUM 140218334Speter#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM 140318334Speter && REGNO (dest) != HARD_FRAME_POINTER_REGNUM 140418334Speter#endif 140518334Speter#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM 140618334Speter && (REGNO (dest) != ARG_POINTER_REGNUM 140718334Speter || ! fixed_regs [REGNO (dest)]) 140818334Speter#endif 140918334Speter && REGNO (dest) != STACK_POINTER_REGNUM) 141018334Speter { 141118334Speter if (*pi3dest_killed) 141218334Speter return 0; 141318334Speter 141418334Speter *pi3dest_killed = dest; 141518334Speter } 141618334Speter } 141718334Speter 141818334Speter else if (GET_CODE (x) == PARALLEL) 141918334Speter { 142018334Speter int i; 142118334Speter 142218334Speter for (i = 0; i < XVECLEN (x, 0); i++) 142318334Speter if (! combinable_i3pat (i3, &XVECEXP (x, 0, i), i2dest, i1dest, 142418334Speter i1_not_in_src, pi3dest_killed)) 142518334Speter return 0; 142618334Speter } 142718334Speter 142818334Speter return 1; 142918334Speter} 143018334Speter 143190075Sobrien/* Return 1 if X is an arithmetic expression that contains a multiplication 143290075Sobrien and division. We don't count multiplications by powers of two here. */ 143390075Sobrien 143490075Sobrienstatic int 143590075Sobriencontains_muldiv (x) 143690075Sobrien rtx x; 143790075Sobrien{ 143890075Sobrien switch (GET_CODE (x)) 143990075Sobrien { 144090075Sobrien case MOD: case DIV: case UMOD: case UDIV: 144190075Sobrien return 1; 144290075Sobrien 144390075Sobrien case MULT: 144490075Sobrien return ! (GET_CODE (XEXP (x, 1)) == CONST_INT 144590075Sobrien && exact_log2 (INTVAL (XEXP (x, 1))) >= 0); 144690075Sobrien default: 144790075Sobrien switch (GET_RTX_CLASS (GET_CODE (x))) 144890075Sobrien { 144990075Sobrien case 'c': case '<': case '2': 145090075Sobrien return contains_muldiv (XEXP (x, 0)) 145190075Sobrien || contains_muldiv (XEXP (x, 1)); 145290075Sobrien 145390075Sobrien case '1': 145490075Sobrien return contains_muldiv (XEXP (x, 0)); 145590075Sobrien 145690075Sobrien default: 145790075Sobrien return 0; 145890075Sobrien } 145990075Sobrien } 146090075Sobrien} 146190075Sobrien 146270635Sobrien/* Determine whether INSN can be used in a combination. Return nonzero if 146370635Sobrien not. This is used in try_combine to detect early some cases where we 146470635Sobrien can't perform combinations. */ 146570635Sobrien 146670635Sobrienstatic int 146770635Sobriencant_combine_insn_p (insn) 146870635Sobrien rtx insn; 146970635Sobrien{ 147070635Sobrien rtx set; 147170635Sobrien rtx src, dest; 147290075Sobrien 147370635Sobrien /* If this isn't really an insn, we can't do anything. 147470635Sobrien This can occur when flow deletes an insn that it has merged into an 147570635Sobrien auto-increment address. */ 147690075Sobrien if (! INSN_P (insn)) 147770635Sobrien return 1; 147870635Sobrien 147970635Sobrien /* Never combine loads and stores involving hard regs. The register 148070635Sobrien allocator can usually handle such reg-reg moves by tying. If we allow 148170635Sobrien the combiner to make substitutions of hard regs, we risk aborting in 148270635Sobrien reload on machines that have SMALL_REGISTER_CLASSES. 148370635Sobrien As an exception, we allow combinations involving fixed regs; these are 148470635Sobrien not available to the register allocator so there's no risk involved. */ 148570635Sobrien 148670635Sobrien set = single_set (insn); 148770635Sobrien if (! set) 148870635Sobrien return 0; 148970635Sobrien src = SET_SRC (set); 149070635Sobrien dest = SET_DEST (set); 149170635Sobrien if (GET_CODE (src) == SUBREG) 149270635Sobrien src = SUBREG_REG (src); 149370635Sobrien if (GET_CODE (dest) == SUBREG) 149470635Sobrien dest = SUBREG_REG (dest); 149570635Sobrien if (REG_P (src) && REG_P (dest) 149670635Sobrien && ((REGNO (src) < FIRST_PSEUDO_REGISTER 149770635Sobrien && ! fixed_regs[REGNO (src)]) 149870635Sobrien || (REGNO (dest) < FIRST_PSEUDO_REGISTER 149970635Sobrien && ! fixed_regs[REGNO (dest)]))) 150070635Sobrien return 1; 150170635Sobrien 150270635Sobrien return 0; 150370635Sobrien} 150470635Sobrien 150518334Speter/* Try to combine the insns I1 and I2 into I3. 150618334Speter Here I1 and I2 appear earlier than I3. 150718334Speter I1 can be zero; then we combine just I2 into I3. 150890075Sobrien 150990075Sobrien If we are combining three insns and the resulting insn is not recognized, 151018334Speter try splitting it into two insns. If that happens, I2 and I3 are retained 151118334Speter and I1 is pseudo-deleted by turning it into a NOTE. Otherwise, I1 and I2 151218334Speter are pseudo-deleted. 151318334Speter 151490075Sobrien Return 0 if the combination does not work. Then nothing is changed. 151518334Speter If we did the combination, return the insn at which combine should 151690075Sobrien resume scanning. 151718334Speter 1518117395Skan Set NEW_DIRECT_JUMP_P to a nonzero value if try_combine creates a 151990075Sobrien new direct jump instruction. */ 152090075Sobrien 152118334Speterstatic rtx 152290075Sobrientry_combine (i3, i2, i1, new_direct_jump_p) 152390075Sobrien rtx i3, i2, i1; 152490075Sobrien int *new_direct_jump_p; 152518334Speter{ 152690075Sobrien /* New patterns for I3 and I2, respectively. */ 152718334Speter rtx newpat, newi2pat = 0; 152896263Sobrien int substed_i2 = 0, substed_i1 = 0; 152918334Speter /* Indicates need to preserve SET in I1 or I2 in I3 if it is not dead. */ 153018334Speter int added_sets_1, added_sets_2; 153118334Speter /* Total number of SETs to put into I3. */ 153218334Speter int total_sets; 153318334Speter /* Nonzero is I2's body now appears in I3. */ 153418334Speter int i2_is_used; 153518334Speter /* INSN_CODEs for new I3, new I2, and user of condition code. */ 153690075Sobrien int insn_code_number, i2_code_number = 0, other_code_number = 0; 153718334Speter /* Contains I3 if the destination of I3 is used in its source, which means 153818334Speter that the old life of I3 is being killed. If that usage is placed into 153918334Speter I2 and not in I3, a REG_DEAD note must be made. */ 154018334Speter rtx i3dest_killed = 0; 154118334Speter /* SET_DEST and SET_SRC of I2 and I1. */ 154218334Speter rtx i2dest, i2src, i1dest = 0, i1src = 0; 154318334Speter /* PATTERN (I2), or a copy of it in certain cases. */ 154418334Speter rtx i2pat; 154518334Speter /* Indicates if I2DEST or I1DEST is in I2SRC or I1_SRC. */ 154618334Speter int i2dest_in_i2src = 0, i1dest_in_i1src = 0, i2dest_in_i1src = 0; 154718334Speter int i1_feeds_i3 = 0; 154818334Speter /* Notes that must be added to REG_NOTES in I3 and I2. */ 154918334Speter rtx new_i3_notes, new_i2_notes; 155018334Speter /* Notes that we substituted I3 into I2 instead of the normal case. */ 155118334Speter int i3_subst_into_i2 = 0; 155218334Speter /* Notes that I1, I2 or I3 is a MULT operation. */ 155318334Speter int have_mult = 0; 155418334Speter 155518334Speter int maxreg; 155618334Speter rtx temp; 155790075Sobrien rtx link; 155818334Speter int i; 155918334Speter 156070635Sobrien /* Exit early if one of the insns involved can't be used for 156170635Sobrien combinations. */ 156270635Sobrien if (cant_combine_insn_p (i3) 156370635Sobrien || cant_combine_insn_p (i2) 156470635Sobrien || (i1 && cant_combine_insn_p (i1)) 156570635Sobrien /* We also can't do anything if I3 has a 156670635Sobrien REG_LIBCALL note since we don't want to disrupt the contiguity of a 156770635Sobrien libcall. */ 156852284Sobrien#if 0 156952284Sobrien /* ??? This gives worse code, and appears to be unnecessary, since no 157052284Sobrien pass after flow uses REG_LIBCALL/REG_RETVAL notes. */ 157152284Sobrien || find_reg_note (i3, REG_LIBCALL, NULL_RTX) 157252284Sobrien#endif 157370635Sobrien ) 157418334Speter return 0; 157518334Speter 157618334Speter combine_attempts++; 157718334Speter undobuf.other_insn = 0; 157818334Speter 157918334Speter /* Reset the hard register usage information. */ 158018334Speter CLEAR_HARD_REG_SET (newpat_used_regs); 158118334Speter 158218334Speter /* If I1 and I2 both feed I3, they can be in any order. To simplify the 158318334Speter code below, set I1 to be the earlier of the two insns. */ 158418334Speter if (i1 && INSN_CUID (i1) > INSN_CUID (i2)) 158518334Speter temp = i1, i1 = i2, i2 = temp; 158618334Speter 158718334Speter added_links_insn = 0; 158818334Speter 158918334Speter /* First check for one important special-case that the code below will 159090075Sobrien not handle. Namely, the case where I1 is zero, I2 is a PARALLEL 159118334Speter and I3 is a SET whose SET_SRC is a SET_DEST in I2. In that case, 159218334Speter we may be able to replace that destination with the destination of I3. 159318334Speter This occurs in the common code where we compute both a quotient and 159418334Speter remainder into a structure, in which case we want to do the computation 159518334Speter directly into the structure to avoid register-register copies. 159618334Speter 159790075Sobrien Note that this case handles both multiple sets in I2 and also 159890075Sobrien cases where I2 has a number of CLOBBER or PARALLELs. 159990075Sobrien 160018334Speter We make very conservative checks below and only try to handle the 160118334Speter most common cases of this. For example, we only handle the case 160218334Speter where I2 and I3 are adjacent to avoid making difficult register 160318334Speter usage tests. */ 160418334Speter 160518334Speter if (i1 == 0 && GET_CODE (i3) == INSN && GET_CODE (PATTERN (i3)) == SET 160618334Speter && GET_CODE (SET_SRC (PATTERN (i3))) == REG 160718334Speter && REGNO (SET_SRC (PATTERN (i3))) >= FIRST_PSEUDO_REGISTER 160818334Speter && find_reg_note (i3, REG_DEAD, SET_SRC (PATTERN (i3))) 160918334Speter && GET_CODE (PATTERN (i2)) == PARALLEL 161018334Speter && ! side_effects_p (SET_DEST (PATTERN (i3))) 161118334Speter /* If the dest of I3 is a ZERO_EXTRACT or STRICT_LOW_PART, the code 161218334Speter below would need to check what is inside (and reg_overlap_mentioned_p 161318334Speter doesn't support those codes anyway). Don't allow those destinations; 161418334Speter the resulting insn isn't likely to be recognized anyway. */ 161518334Speter && GET_CODE (SET_DEST (PATTERN (i3))) != ZERO_EXTRACT 161618334Speter && GET_CODE (SET_DEST (PATTERN (i3))) != STRICT_LOW_PART 161718334Speter && ! reg_overlap_mentioned_p (SET_SRC (PATTERN (i3)), 161818334Speter SET_DEST (PATTERN (i3))) 161918334Speter && next_real_insn (i2) == i3) 162018334Speter { 162118334Speter rtx p2 = PATTERN (i2); 162218334Speter 162318334Speter /* Make sure that the destination of I3, 162418334Speter which we are going to substitute into one output of I2, 162518334Speter is not used within another output of I2. We must avoid making this: 162618334Speter (parallel [(set (mem (reg 69)) ...) 162718334Speter (set (reg 69) ...)]) 162818334Speter which is not well-defined as to order of actions. 162918334Speter (Besides, reload can't handle output reloads for this.) 163018334Speter 163118334Speter The problem can also happen if the dest of I3 is a memory ref, 163218334Speter if another dest in I2 is an indirect memory ref. */ 163318334Speter for (i = 0; i < XVECLEN (p2, 0); i++) 163450397Sobrien if ((GET_CODE (XVECEXP (p2, 0, i)) == SET 163550397Sobrien || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER) 163618334Speter && reg_overlap_mentioned_p (SET_DEST (PATTERN (i3)), 163718334Speter SET_DEST (XVECEXP (p2, 0, i)))) 163818334Speter break; 163918334Speter 164018334Speter if (i == XVECLEN (p2, 0)) 164118334Speter for (i = 0; i < XVECLEN (p2, 0); i++) 164290075Sobrien if ((GET_CODE (XVECEXP (p2, 0, i)) == SET 164390075Sobrien || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER) 164490075Sobrien && SET_DEST (XVECEXP (p2, 0, i)) == SET_SRC (PATTERN (i3))) 164518334Speter { 164618334Speter combine_merges++; 164718334Speter 164818334Speter subst_insn = i3; 164918334Speter subst_low_cuid = INSN_CUID (i2); 165018334Speter 165118334Speter added_sets_2 = added_sets_1 = 0; 165218334Speter i2dest = SET_SRC (PATTERN (i3)); 165318334Speter 165418334Speter /* Replace the dest in I2 with our dest and make the resulting 165518334Speter insn the new pattern for I3. Then skip to where we 165618334Speter validate the pattern. Everything was set up above. */ 165790075Sobrien SUBST (SET_DEST (XVECEXP (p2, 0, i)), 165818334Speter SET_DEST (PATTERN (i3))); 165918334Speter 166018334Speter newpat = p2; 166118334Speter i3_subst_into_i2 = 1; 166218334Speter goto validate_replacement; 166318334Speter } 166418334Speter } 166518334Speter 166690075Sobrien /* If I2 is setting a double-word pseudo to a constant and I3 is setting 166790075Sobrien one of those words to another constant, merge them by making a new 166890075Sobrien constant. */ 166990075Sobrien if (i1 == 0 167090075Sobrien && (temp = single_set (i2)) != 0 167190075Sobrien && (GET_CODE (SET_SRC (temp)) == CONST_INT 167290075Sobrien || GET_CODE (SET_SRC (temp)) == CONST_DOUBLE) 167390075Sobrien && GET_CODE (SET_DEST (temp)) == REG 167490075Sobrien && GET_MODE_CLASS (GET_MODE (SET_DEST (temp))) == MODE_INT 167590075Sobrien && GET_MODE_SIZE (GET_MODE (SET_DEST (temp))) == 2 * UNITS_PER_WORD 167690075Sobrien && GET_CODE (PATTERN (i3)) == SET 167790075Sobrien && GET_CODE (SET_DEST (PATTERN (i3))) == SUBREG 167890075Sobrien && SUBREG_REG (SET_DEST (PATTERN (i3))) == SET_DEST (temp) 167990075Sobrien && GET_MODE_CLASS (GET_MODE (SET_DEST (PATTERN (i3)))) == MODE_INT 168090075Sobrien && GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (i3)))) == UNITS_PER_WORD 168190075Sobrien && GET_CODE (SET_SRC (PATTERN (i3))) == CONST_INT) 168290075Sobrien { 168390075Sobrien HOST_WIDE_INT lo, hi; 168490075Sobrien 168590075Sobrien if (GET_CODE (SET_SRC (temp)) == CONST_INT) 168690075Sobrien lo = INTVAL (SET_SRC (temp)), hi = lo < 0 ? -1 : 0; 168790075Sobrien else 168890075Sobrien { 168990075Sobrien lo = CONST_DOUBLE_LOW (SET_SRC (temp)); 169090075Sobrien hi = CONST_DOUBLE_HIGH (SET_SRC (temp)); 169190075Sobrien } 169290075Sobrien 169390075Sobrien if (subreg_lowpart_p (SET_DEST (PATTERN (i3)))) 169490075Sobrien { 169590075Sobrien /* We don't handle the case of the target word being wider 169690075Sobrien than a host wide int. */ 169790075Sobrien if (HOST_BITS_PER_WIDE_INT < BITS_PER_WORD) 169890075Sobrien abort (); 169990075Sobrien 170090075Sobrien lo &= ~(UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD (1) - 1); 170190075Sobrien lo |= (INTVAL (SET_SRC (PATTERN (i3))) 170290075Sobrien & (UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD (1) - 1)); 170390075Sobrien } 170490075Sobrien else if (HOST_BITS_PER_WIDE_INT == BITS_PER_WORD) 170590075Sobrien hi = INTVAL (SET_SRC (PATTERN (i3))); 170690075Sobrien else if (HOST_BITS_PER_WIDE_INT >= 2 * BITS_PER_WORD) 170790075Sobrien { 170890075Sobrien int sign = -(int) ((unsigned HOST_WIDE_INT) lo 170990075Sobrien >> (HOST_BITS_PER_WIDE_INT - 1)); 171090075Sobrien 171190075Sobrien lo &= ~ (UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD 171290075Sobrien (UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD (1) - 1)); 171390075Sobrien lo |= (UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD 171490075Sobrien (INTVAL (SET_SRC (PATTERN (i3))))); 171590075Sobrien if (hi == sign) 171690075Sobrien hi = lo < 0 ? -1 : 0; 171790075Sobrien } 171890075Sobrien else 171990075Sobrien /* We don't handle the case of the higher word not fitting 172090075Sobrien entirely in either hi or lo. */ 172190075Sobrien abort (); 172290075Sobrien 172390075Sobrien combine_merges++; 172490075Sobrien subst_insn = i3; 172590075Sobrien subst_low_cuid = INSN_CUID (i2); 172690075Sobrien added_sets_2 = added_sets_1 = 0; 172790075Sobrien i2dest = SET_DEST (temp); 172890075Sobrien 172990075Sobrien SUBST (SET_SRC (temp), 173090075Sobrien immed_double_const (lo, hi, GET_MODE (SET_DEST (temp)))); 173190075Sobrien 173290075Sobrien newpat = PATTERN (i2); 173390075Sobrien goto validate_replacement; 173490075Sobrien } 173590075Sobrien 173618334Speter#ifndef HAVE_cc0 173718334Speter /* If we have no I1 and I2 looks like: 173818334Speter (parallel [(set (reg:CC X) (compare:CC OP (const_int 0))) 173918334Speter (set Y OP)]) 174018334Speter make up a dummy I1 that is 174118334Speter (set Y OP) 174218334Speter and change I2 to be 174318334Speter (set (reg:CC X) (compare:CC Y (const_int 0))) 174418334Speter 174518334Speter (We can ignore any trailing CLOBBERs.) 174618334Speter 174718334Speter This undoes a previous combination and allows us to match a branch-and- 174818334Speter decrement insn. */ 174918334Speter 175018334Speter if (i1 == 0 && GET_CODE (PATTERN (i2)) == PARALLEL 175118334Speter && XVECLEN (PATTERN (i2), 0) >= 2 175218334Speter && GET_CODE (XVECEXP (PATTERN (i2), 0, 0)) == SET 175318334Speter && (GET_MODE_CLASS (GET_MODE (SET_DEST (XVECEXP (PATTERN (i2), 0, 0)))) 175418334Speter == MODE_CC) 175518334Speter && GET_CODE (SET_SRC (XVECEXP (PATTERN (i2), 0, 0))) == COMPARE 175618334Speter && XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 1) == const0_rtx 175718334Speter && GET_CODE (XVECEXP (PATTERN (i2), 0, 1)) == SET 175818334Speter && GET_CODE (SET_DEST (XVECEXP (PATTERN (i2), 0, 1))) == REG 175918334Speter && rtx_equal_p (XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 0), 176018334Speter SET_SRC (XVECEXP (PATTERN (i2), 0, 1)))) 176118334Speter { 176290075Sobrien for (i = XVECLEN (PATTERN (i2), 0) - 1; i >= 2; i--) 176318334Speter if (GET_CODE (XVECEXP (PATTERN (i2), 0, i)) != CLOBBER) 176418334Speter break; 176518334Speter 176618334Speter if (i == 1) 176718334Speter { 176818334Speter /* We make I1 with the same INSN_UID as I2. This gives it 176918334Speter the same INSN_CUID for value tracking. Our fake I1 will 177018334Speter never appear in the insn stream so giving it the same INSN_UID 177118334Speter as I2 will not cause a problem. */ 177218334Speter 177318334Speter subst_prev_insn = i1 177450397Sobrien = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2, 1775117395Skan BLOCK_FOR_INSN (i2), INSN_SCOPE (i2), 177650397Sobrien XVECEXP (PATTERN (i2), 0, 1), -1, NULL_RTX, 177750397Sobrien NULL_RTX); 177818334Speter 177918334Speter SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0)); 178018334Speter SUBST (XEXP (SET_SRC (PATTERN (i2)), 0), 178118334Speter SET_DEST (PATTERN (i1))); 178218334Speter } 178318334Speter } 178418334Speter#endif 178518334Speter 178618334Speter /* Verify that I2 and I1 are valid for combining. */ 178718334Speter if (! can_combine_p (i2, i3, i1, NULL_RTX, &i2dest, &i2src) 178818334Speter || (i1 && ! can_combine_p (i1, i3, NULL_RTX, i2, &i1dest, &i1src))) 178918334Speter { 179018334Speter undo_all (); 179118334Speter return 0; 179218334Speter } 179318334Speter 179418334Speter /* Record whether I2DEST is used in I2SRC and similarly for the other 179518334Speter cases. Knowing this will help in register status updating below. */ 179618334Speter i2dest_in_i2src = reg_overlap_mentioned_p (i2dest, i2src); 179718334Speter i1dest_in_i1src = i1 && reg_overlap_mentioned_p (i1dest, i1src); 179818334Speter i2dest_in_i1src = i1 && reg_overlap_mentioned_p (i2dest, i1src); 179918334Speter 180018334Speter /* See if I1 directly feeds into I3. It does if I1DEST is not used 180118334Speter in I2SRC. */ 180218334Speter i1_feeds_i3 = i1 && ! reg_overlap_mentioned_p (i1dest, i2src); 180318334Speter 180418334Speter /* Ensure that I3's pattern can be the destination of combines. */ 180518334Speter if (! combinable_i3pat (i3, &PATTERN (i3), i2dest, i1dest, 180618334Speter i1 && i2dest_in_i1src && i1_feeds_i3, 180718334Speter &i3dest_killed)) 180818334Speter { 180918334Speter undo_all (); 181018334Speter return 0; 181118334Speter } 181218334Speter 181318334Speter /* See if any of the insns is a MULT operation. Unless one is, we will 181418334Speter reject a combination that is, since it must be slower. Be conservative 181518334Speter here. */ 181618334Speter if (GET_CODE (i2src) == MULT 181718334Speter || (i1 != 0 && GET_CODE (i1src) == MULT) 181818334Speter || (GET_CODE (PATTERN (i3)) == SET 181918334Speter && GET_CODE (SET_SRC (PATTERN (i3))) == MULT)) 182018334Speter have_mult = 1; 182118334Speter 182218334Speter /* If I3 has an inc, then give up if I1 or I2 uses the reg that is inc'd. 182318334Speter We used to do this EXCEPT in one case: I3 has a post-inc in an 182418334Speter output operand. However, that exception can give rise to insns like 182590075Sobrien mov r3,(r3)+ 182618334Speter which is a famous insn on the PDP-11 where the value of r3 used as the 182718334Speter source was model-dependent. Avoid this sort of thing. */ 182818334Speter 182918334Speter#if 0 183018334Speter if (!(GET_CODE (PATTERN (i3)) == SET 183118334Speter && GET_CODE (SET_SRC (PATTERN (i3))) == REG 183218334Speter && GET_CODE (SET_DEST (PATTERN (i3))) == MEM 183318334Speter && (GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_INC 183418334Speter || GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_DEC))) 183518334Speter /* It's not the exception. */ 183618334Speter#endif 183718334Speter#ifdef AUTO_INC_DEC 183818334Speter for (link = REG_NOTES (i3); link; link = XEXP (link, 1)) 183918334Speter if (REG_NOTE_KIND (link) == REG_INC 184018334Speter && (reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i2)) 184118334Speter || (i1 != 0 184218334Speter && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i1))))) 184318334Speter { 184418334Speter undo_all (); 184518334Speter return 0; 184618334Speter } 184718334Speter#endif 184818334Speter 184918334Speter /* See if the SETs in I1 or I2 need to be kept around in the merged 185018334Speter instruction: whenever the value set there is still needed past I3. 185118334Speter For the SETs in I2, this is easy: we see if I2DEST dies or is set in I3. 185218334Speter 185318334Speter For the SET in I1, we have two cases: If I1 and I2 independently 185418334Speter feed into I3, the set in I1 needs to be kept around if I1DEST dies 185518334Speter or is set in I3. Otherwise (if I1 feeds I2 which feeds I3), the set 185618334Speter in I1 needs to be kept around unless I1DEST dies or is set in either 185718334Speter I2 or I3. We can distinguish these cases by seeing if I2SRC mentions 185818334Speter I1DEST. If so, we know I1 feeds into I2. */ 185918334Speter 186018334Speter added_sets_2 = ! dead_or_set_p (i3, i2dest); 186118334Speter 186218334Speter added_sets_1 186318334Speter = i1 && ! (i1_feeds_i3 ? dead_or_set_p (i3, i1dest) 186418334Speter : (dead_or_set_p (i3, i1dest) || dead_or_set_p (i2, i1dest))); 186518334Speter 186618334Speter /* If the set in I2 needs to be kept around, we must make a copy of 186718334Speter PATTERN (I2), so that when we substitute I1SRC for I1DEST in 186818334Speter PATTERN (I2), we are only substituting for the original I1DEST, not into 186918334Speter an already-substituted copy. This also prevents making self-referential 187018334Speter rtx. If I2 is a PARALLEL, we just need the piece that assigns I2SRC to 187118334Speter I2DEST. */ 187218334Speter 187318334Speter i2pat = (GET_CODE (PATTERN (i2)) == PARALLEL 187450397Sobrien ? gen_rtx_SET (VOIDmode, i2dest, i2src) 187518334Speter : PATTERN (i2)); 187618334Speter 187718334Speter if (added_sets_2) 187818334Speter i2pat = copy_rtx (i2pat); 187918334Speter 188018334Speter combine_merges++; 188118334Speter 188218334Speter /* Substitute in the latest insn for the regs set by the earlier ones. */ 188318334Speter 188418334Speter maxreg = max_reg_num (); 188518334Speter 188618334Speter subst_insn = i3; 188718334Speter 188818334Speter /* It is possible that the source of I2 or I1 may be performing an 188918334Speter unneeded operation, such as a ZERO_EXTEND of something that is known 189018334Speter to have the high part zero. Handle that case by letting subst look at 189118334Speter the innermost one of them. 189218334Speter 189318334Speter Another way to do this would be to have a function that tries to 189418334Speter simplify a single insn instead of merging two or more insns. We don't 189518334Speter do this because of the potential of infinite loops and because 189618334Speter of the potential extra memory required. However, doing it the way 189718334Speter we are is a bit of a kludge and doesn't catch all cases. 189818334Speter 189918334Speter But only do this if -fexpensive-optimizations since it slows things down 190018334Speter and doesn't usually win. */ 190118334Speter 190218334Speter if (flag_expensive_optimizations) 190318334Speter { 190418334Speter /* Pass pc_rtx so no substitutions are done, just simplifications. 190518334Speter The cases that we are interested in here do not involve the few 190618334Speter cases were is_replaced is checked. */ 190718334Speter if (i1) 190818334Speter { 190918334Speter subst_low_cuid = INSN_CUID (i1); 191018334Speter i1src = subst (i1src, pc_rtx, pc_rtx, 0, 0); 191118334Speter } 191218334Speter else 191318334Speter { 191418334Speter subst_low_cuid = INSN_CUID (i2); 191518334Speter i2src = subst (i2src, pc_rtx, pc_rtx, 0, 0); 191618334Speter } 191718334Speter } 191818334Speter 191918334Speter#ifndef HAVE_cc0 192018334Speter /* Many machines that don't use CC0 have insns that can both perform an 192118334Speter arithmetic operation and set the condition code. These operations will 192218334Speter be represented as a PARALLEL with the first element of the vector 192318334Speter being a COMPARE of an arithmetic operation with the constant zero. 192418334Speter The second element of the vector will set some pseudo to the result 192518334Speter of the same arithmetic operation. If we simplify the COMPARE, we won't 192618334Speter match such a pattern and so will generate an extra insn. Here we test 192718334Speter for this case, where both the comparison and the operation result are 192818334Speter needed, and make the PARALLEL by just replacing I2DEST in I3SRC with 192918334Speter I2SRC. Later we will make the PARALLEL that contains I2. */ 193018334Speter 193118334Speter if (i1 == 0 && added_sets_2 && GET_CODE (PATTERN (i3)) == SET 193218334Speter && GET_CODE (SET_SRC (PATTERN (i3))) == COMPARE 193318334Speter && XEXP (SET_SRC (PATTERN (i3)), 1) == const0_rtx 193418334Speter && rtx_equal_p (XEXP (SET_SRC (PATTERN (i3)), 0), i2dest)) 193518334Speter { 193650397Sobrien#ifdef EXTRA_CC_MODES 193718334Speter rtx *cc_use; 193818334Speter enum machine_mode compare_mode; 193950397Sobrien#endif 194018334Speter 194118334Speter newpat = PATTERN (i3); 194218334Speter SUBST (XEXP (SET_SRC (newpat), 0), i2src); 194318334Speter 194418334Speter i2_is_used = 1; 194518334Speter 194618334Speter#ifdef EXTRA_CC_MODES 194718334Speter /* See if a COMPARE with the operand we substituted in should be done 194818334Speter with the mode that is currently being used. If not, do the same 194918334Speter processing we do in `subst' for a SET; namely, if the destination 195018334Speter is used only once, try to replace it with a register of the proper 195118334Speter mode and also replace the COMPARE. */ 195218334Speter if (undobuf.other_insn == 0 195318334Speter && (cc_use = find_single_use (SET_DEST (newpat), i3, 195418334Speter &undobuf.other_insn)) 195518334Speter && ((compare_mode = SELECT_CC_MODE (GET_CODE (*cc_use), 195618334Speter i2src, const0_rtx)) 195718334Speter != GET_MODE (SET_DEST (newpat)))) 195818334Speter { 195990075Sobrien unsigned int regno = REGNO (SET_DEST (newpat)); 196050397Sobrien rtx new_dest = gen_rtx_REG (compare_mode, regno); 196118334Speter 196218334Speter if (regno < FIRST_PSEUDO_REGISTER 196350397Sobrien || (REG_N_SETS (regno) == 1 && ! added_sets_2 196418334Speter && ! REG_USERVAR_P (SET_DEST (newpat)))) 196518334Speter { 196618334Speter if (regno >= FIRST_PSEUDO_REGISTER) 196718334Speter SUBST (regno_reg_rtx[regno], new_dest); 196818334Speter 196918334Speter SUBST (SET_DEST (newpat), new_dest); 197018334Speter SUBST (XEXP (*cc_use, 0), new_dest); 197118334Speter SUBST (SET_SRC (newpat), 197290075Sobrien gen_rtx_COMPARE (compare_mode, i2src, const0_rtx)); 197318334Speter } 197418334Speter else 197518334Speter undobuf.other_insn = 0; 197618334Speter } 197790075Sobrien#endif 197818334Speter } 197918334Speter else 198018334Speter#endif 198118334Speter { 198218334Speter n_occurrences = 0; /* `subst' counts here */ 198318334Speter 198418334Speter /* If I1 feeds into I2 (not into I3) and I1DEST is in I1SRC, we 198518334Speter need to make a unique copy of I2SRC each time we substitute it 198618334Speter to avoid self-referential rtl. */ 198718334Speter 198818334Speter subst_low_cuid = INSN_CUID (i2); 198918334Speter newpat = subst (PATTERN (i3), i2dest, i2src, 0, 199018334Speter ! i1_feeds_i3 && i1dest_in_i1src); 199196263Sobrien substed_i2 = 1; 199218334Speter 199318334Speter /* Record whether i2's body now appears within i3's body. */ 199418334Speter i2_is_used = n_occurrences; 199518334Speter } 199618334Speter 199718334Speter /* If we already got a failure, don't try to do more. Otherwise, 199818334Speter try to substitute in I1 if we have it. */ 199918334Speter 200018334Speter if (i1 && GET_CODE (newpat) != CLOBBER) 200118334Speter { 200218334Speter /* Before we can do this substitution, we must redo the test done 200318334Speter above (see detailed comments there) that ensures that I1DEST 200450397Sobrien isn't mentioned in any SETs in NEWPAT that are field assignments. */ 200518334Speter 200618334Speter if (! combinable_i3pat (NULL_RTX, &newpat, i1dest, NULL_RTX, 200790075Sobrien 0, (rtx*) 0)) 200818334Speter { 200918334Speter undo_all (); 201018334Speter return 0; 201118334Speter } 201218334Speter 201318334Speter n_occurrences = 0; 201418334Speter subst_low_cuid = INSN_CUID (i1); 201518334Speter newpat = subst (newpat, i1dest, i1src, 0, 0); 201696263Sobrien substed_i1 = 1; 201718334Speter } 201818334Speter 201918334Speter /* Fail if an autoincrement side-effect has been duplicated. Be careful 202018334Speter to count all the ways that I2SRC and I1SRC can be used. */ 202118334Speter if ((FIND_REG_INC_NOTE (i2, NULL_RTX) != 0 202218334Speter && i2_is_used + added_sets_2 > 1) 202318334Speter || (i1 != 0 && FIND_REG_INC_NOTE (i1, NULL_RTX) != 0 202418334Speter && (n_occurrences + added_sets_1 + (added_sets_2 && ! i1_feeds_i3) 202518334Speter > 1)) 202618334Speter /* Fail if we tried to make a new register (we used to abort, but there's 202718334Speter really no reason to). */ 202818334Speter || max_reg_num () != maxreg 202918334Speter /* Fail if we couldn't do something and have a CLOBBER. */ 203018334Speter || GET_CODE (newpat) == CLOBBER 203118334Speter /* Fail if this new pattern is a MULT and we didn't have one before 203218334Speter at the outer level. */ 203318334Speter || (GET_CODE (newpat) == SET && GET_CODE (SET_SRC (newpat)) == MULT 203418334Speter && ! have_mult)) 203518334Speter { 203618334Speter undo_all (); 203718334Speter return 0; 203818334Speter } 203918334Speter 204018334Speter /* If the actions of the earlier insns must be kept 204118334Speter in addition to substituting them into the latest one, 204218334Speter we must make a new PARALLEL for the latest insn 204318334Speter to hold additional the SETs. */ 204418334Speter 204518334Speter if (added_sets_1 || added_sets_2) 204618334Speter { 204718334Speter combine_extras++; 204818334Speter 204918334Speter if (GET_CODE (newpat) == PARALLEL) 205018334Speter { 205118334Speter rtvec old = XVEC (newpat, 0); 205218334Speter total_sets = XVECLEN (newpat, 0) + added_sets_1 + added_sets_2; 205350397Sobrien newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets)); 205490075Sobrien memcpy (XVEC (newpat, 0)->elem, &old->elem[0], 205590075Sobrien sizeof (old->elem[0]) * old->num_elem); 205618334Speter } 205718334Speter else 205818334Speter { 205918334Speter rtx old = newpat; 206018334Speter total_sets = 1 + added_sets_1 + added_sets_2; 206150397Sobrien newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets)); 206218334Speter XVECEXP (newpat, 0, 0) = old; 206318334Speter } 206418334Speter 206590075Sobrien if (added_sets_1) 206690075Sobrien XVECEXP (newpat, 0, --total_sets) 206790075Sobrien = (GET_CODE (PATTERN (i1)) == PARALLEL 206890075Sobrien ? gen_rtx_SET (VOIDmode, i1dest, i1src) : PATTERN (i1)); 206918334Speter 207090075Sobrien if (added_sets_2) 207118334Speter { 207218334Speter /* If there is no I1, use I2's body as is. We used to also not do 207318334Speter the subst call below if I2 was substituted into I3, 207418334Speter but that could lose a simplification. */ 207518334Speter if (i1 == 0) 207618334Speter XVECEXP (newpat, 0, --total_sets) = i2pat; 207718334Speter else 207818334Speter /* See comment where i2pat is assigned. */ 207918334Speter XVECEXP (newpat, 0, --total_sets) 208018334Speter = subst (i2pat, i1dest, i1src, 0, 0); 208118334Speter } 208218334Speter } 208318334Speter 208418334Speter /* We come here when we are replacing a destination in I2 with the 208518334Speter destination of I3. */ 208618334Speter validate_replacement: 208718334Speter 208818334Speter /* Note which hard regs this insn has as inputs. */ 208918334Speter mark_used_regs_combine (newpat); 209018334Speter 209118334Speter /* Is the result of combination a valid instruction? */ 209252284Sobrien insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); 209318334Speter 209418334Speter /* If the result isn't valid, see if it is a PARALLEL of two SETs where 209518334Speter the second SET's destination is a register that is unused. In that case, 209618334Speter we just need the first SET. This can occur when simplifying a divmod 209718334Speter insn. We *must* test for this case here because the code below that 209818334Speter splits two independent SETs doesn't handle this case correctly when it 209918334Speter updates the register status. Also check the case where the first 210018334Speter SET's destination is unused. That would not cause incorrect code, but 210118334Speter does cause an unneeded insn to remain. */ 210218334Speter 210318334Speter if (insn_code_number < 0 && GET_CODE (newpat) == PARALLEL 210418334Speter && XVECLEN (newpat, 0) == 2 210518334Speter && GET_CODE (XVECEXP (newpat, 0, 0)) == SET 210618334Speter && GET_CODE (XVECEXP (newpat, 0, 1)) == SET 210718334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == REG 210818334Speter && find_reg_note (i3, REG_UNUSED, SET_DEST (XVECEXP (newpat, 0, 1))) 210918334Speter && ! side_effects_p (SET_SRC (XVECEXP (newpat, 0, 1))) 211018334Speter && asm_noperands (newpat) < 0) 211118334Speter { 211218334Speter newpat = XVECEXP (newpat, 0, 0); 211352284Sobrien insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); 211418334Speter } 211518334Speter 211618334Speter else if (insn_code_number < 0 && GET_CODE (newpat) == PARALLEL 211718334Speter && XVECLEN (newpat, 0) == 2 211818334Speter && GET_CODE (XVECEXP (newpat, 0, 0)) == SET 211918334Speter && GET_CODE (XVECEXP (newpat, 0, 1)) == SET 212018334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) == REG 212118334Speter && find_reg_note (i3, REG_UNUSED, SET_DEST (XVECEXP (newpat, 0, 0))) 212218334Speter && ! side_effects_p (SET_SRC (XVECEXP (newpat, 0, 0))) 212318334Speter && asm_noperands (newpat) < 0) 212418334Speter { 212518334Speter newpat = XVECEXP (newpat, 0, 1); 212652284Sobrien insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); 212718334Speter } 212818334Speter 212918334Speter /* If we were combining three insns and the result is a simple SET 213018334Speter with no ASM_OPERANDS that wasn't recognized, try to split it into two 213190075Sobrien insns. There are two ways to do this. It can be split using a 213218334Speter machine-specific method (like when you have an addition of a large 213318334Speter constant) or by combine in the function find_split_point. */ 213418334Speter 213518334Speter if (i1 && insn_code_number < 0 && GET_CODE (newpat) == SET 213618334Speter && asm_noperands (newpat) < 0) 213718334Speter { 213818334Speter rtx m_split, *split; 213918334Speter rtx ni2dest = i2dest; 214018334Speter 214118334Speter /* See if the MD file can split NEWPAT. If it can't, see if letting it 214218334Speter use I2DEST as a scratch register will help. In the latter case, 214318334Speter convert I2DEST to the mode of the source of NEWPAT if we can. */ 214418334Speter 214518334Speter m_split = split_insns (newpat, i3); 214618334Speter 214718334Speter /* We can only use I2DEST as a scratch reg if it doesn't overlap any 214818334Speter inputs of NEWPAT. */ 214918334Speter 215018334Speter /* ??? If I2DEST is not safe, and I1DEST exists, then it would be 215118334Speter possible to try that as a scratch reg. This would require adding 215218334Speter more code to make it work though. */ 215318334Speter 215418334Speter if (m_split == 0 && ! reg_overlap_mentioned_p (ni2dest, newpat)) 215518334Speter { 215618334Speter /* If I2DEST is a hard register or the only use of a pseudo, 215718334Speter we can change its mode. */ 215818334Speter if (GET_MODE (SET_DEST (newpat)) != GET_MODE (i2dest) 215918334Speter && GET_MODE (SET_DEST (newpat)) != VOIDmode 216018334Speter && GET_CODE (i2dest) == REG 216118334Speter && (REGNO (i2dest) < FIRST_PSEUDO_REGISTER 216250397Sobrien || (REG_N_SETS (REGNO (i2dest)) == 1 && ! added_sets_2 216318334Speter && ! REG_USERVAR_P (i2dest)))) 216450397Sobrien ni2dest = gen_rtx_REG (GET_MODE (SET_DEST (newpat)), 216590075Sobrien REGNO (i2dest)); 216618334Speter 216790075Sobrien m_split = split_insns (gen_rtx_PARALLEL 216890075Sobrien (VOIDmode, 216990075Sobrien gen_rtvec (2, newpat, 217090075Sobrien gen_rtx_CLOBBER (VOIDmode, 217190075Sobrien ni2dest))), 217290075Sobrien i3); 217390075Sobrien /* If the split with the mode-changed register didn't work, try 217490075Sobrien the original register. */ 217590075Sobrien if (! m_split && ni2dest != i2dest) 217690075Sobrien { 217790075Sobrien ni2dest = i2dest; 217890075Sobrien m_split = split_insns (gen_rtx_PARALLEL 217990075Sobrien (VOIDmode, 218090075Sobrien gen_rtvec (2, newpat, 218190075Sobrien gen_rtx_CLOBBER (VOIDmode, 218290075Sobrien i2dest))), 218390075Sobrien i3); 218490075Sobrien } 218518334Speter } 218618334Speter 2187117395Skan if (m_split && NEXT_INSN (m_split) == NULL_RTX) 218818334Speter { 2189117395Skan m_split = PATTERN (m_split); 219090075Sobrien insn_code_number = recog_for_combine (&m_split, i3, &new_i3_notes); 219190075Sobrien if (insn_code_number >= 0) 219290075Sobrien newpat = m_split; 219390075Sobrien } 2194117395Skan else if (m_split && NEXT_INSN (NEXT_INSN (m_split)) == NULL_RTX 219590075Sobrien && (next_real_insn (i2) == i3 2196117395Skan || ! use_crosses_set_p (PATTERN (m_split), INSN_CUID (i2)))) 219790075Sobrien { 219818334Speter rtx i2set, i3set; 2199117395Skan rtx newi3pat = PATTERN (NEXT_INSN (m_split)); 2200117395Skan newi2pat = PATTERN (m_split); 220118334Speter 2202117395Skan i3set = single_set (NEXT_INSN (m_split)); 2203117395Skan i2set = single_set (m_split); 220418334Speter 220518334Speter /* In case we changed the mode of I2DEST, replace it in the 220618334Speter pseudo-register table here. We can't do it above in case this 220718334Speter code doesn't get executed and we do a split the other way. */ 220818334Speter 220918334Speter if (REGNO (i2dest) >= FIRST_PSEUDO_REGISTER) 221018334Speter SUBST (regno_reg_rtx[REGNO (i2dest)], ni2dest); 221118334Speter 221252284Sobrien i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes); 221318334Speter 221418334Speter /* If I2 or I3 has multiple SETs, we won't know how to track 221550397Sobrien register status, so don't use these insns. If I2's destination 221650397Sobrien is used between I2 and I3, we also can't use these insns. */ 221718334Speter 221850397Sobrien if (i2_code_number >= 0 && i2set && i3set 221950397Sobrien && (next_real_insn (i2) == i3 222050397Sobrien || ! reg_used_between_p (SET_DEST (i2set), i2, i3))) 222152284Sobrien insn_code_number = recog_for_combine (&newi3pat, i3, 222252284Sobrien &new_i3_notes); 222318334Speter if (insn_code_number >= 0) 222418334Speter newpat = newi3pat; 222518334Speter 222618334Speter /* It is possible that both insns now set the destination of I3. 222718334Speter If so, we must show an extra use of it. */ 222818334Speter 222950397Sobrien if (insn_code_number >= 0) 223050397Sobrien { 223150397Sobrien rtx new_i3_dest = SET_DEST (i3set); 223250397Sobrien rtx new_i2_dest = SET_DEST (i2set); 223350397Sobrien 223450397Sobrien while (GET_CODE (new_i3_dest) == ZERO_EXTRACT 223550397Sobrien || GET_CODE (new_i3_dest) == STRICT_LOW_PART 223650397Sobrien || GET_CODE (new_i3_dest) == SUBREG) 223750397Sobrien new_i3_dest = XEXP (new_i3_dest, 0); 223850397Sobrien 223950397Sobrien while (GET_CODE (new_i2_dest) == ZERO_EXTRACT 224050397Sobrien || GET_CODE (new_i2_dest) == STRICT_LOW_PART 224150397Sobrien || GET_CODE (new_i2_dest) == SUBREG) 224250397Sobrien new_i2_dest = XEXP (new_i2_dest, 0); 224350397Sobrien 224450397Sobrien if (GET_CODE (new_i3_dest) == REG 224550397Sobrien && GET_CODE (new_i2_dest) == REG 224650397Sobrien && REGNO (new_i3_dest) == REGNO (new_i2_dest)) 224750397Sobrien REG_N_SETS (REGNO (new_i2_dest))++; 224850397Sobrien } 224918334Speter } 225018334Speter 225118334Speter /* If we can split it and use I2DEST, go ahead and see if that 225218334Speter helps things be recognized. Verify that none of the registers 225318334Speter are set between I2 and I3. */ 225418334Speter if (insn_code_number < 0 && (split = find_split_point (&newpat, i3)) != 0 225518334Speter#ifdef HAVE_cc0 225618334Speter && GET_CODE (i2dest) == REG 225718334Speter#endif 225818334Speter /* We need I2DEST in the proper mode. If it is a hard register 225918334Speter or the only use of a pseudo, we can change its mode. */ 226018334Speter && (GET_MODE (*split) == GET_MODE (i2dest) 226118334Speter || GET_MODE (*split) == VOIDmode 226218334Speter || REGNO (i2dest) < FIRST_PSEUDO_REGISTER 226350397Sobrien || (REG_N_SETS (REGNO (i2dest)) == 1 && ! added_sets_2 226418334Speter && ! REG_USERVAR_P (i2dest))) 226518334Speter && (next_real_insn (i2) == i3 226618334Speter || ! use_crosses_set_p (*split, INSN_CUID (i2))) 226718334Speter /* We can't overwrite I2DEST if its value is still used by 226818334Speter NEWPAT. */ 226918334Speter && ! reg_referenced_p (i2dest, newpat)) 227018334Speter { 227118334Speter rtx newdest = i2dest; 227218334Speter enum rtx_code split_code = GET_CODE (*split); 227318334Speter enum machine_mode split_mode = GET_MODE (*split); 227418334Speter 227518334Speter /* Get NEWDEST as a register in the proper mode. We have already 227618334Speter validated that we can do this. */ 227718334Speter if (GET_MODE (i2dest) != split_mode && split_mode != VOIDmode) 227818334Speter { 227950397Sobrien newdest = gen_rtx_REG (split_mode, REGNO (i2dest)); 228018334Speter 228118334Speter if (REGNO (i2dest) >= FIRST_PSEUDO_REGISTER) 228218334Speter SUBST (regno_reg_rtx[REGNO (i2dest)], newdest); 228318334Speter } 228418334Speter 228518334Speter /* If *SPLIT is a (mult FOO (const_int pow2)), convert it to 228618334Speter an ASHIFT. This can occur if it was inside a PLUS and hence 228718334Speter appeared to be a memory address. This is a kludge. */ 228818334Speter if (split_code == MULT 228918334Speter && GET_CODE (XEXP (*split, 1)) == CONST_INT 229090075Sobrien && INTVAL (XEXP (*split, 1)) > 0 229118334Speter && (i = exact_log2 (INTVAL (XEXP (*split, 1)))) >= 0) 229218334Speter { 229390075Sobrien SUBST (*split, gen_rtx_ASHIFT (split_mode, 229490075Sobrien XEXP (*split, 0), GEN_INT (i))); 229518334Speter /* Update split_code because we may not have a multiply 229618334Speter anymore. */ 229718334Speter split_code = GET_CODE (*split); 229818334Speter } 229918334Speter 230018334Speter#ifdef INSN_SCHEDULING 230118334Speter /* If *SPLIT is a paradoxical SUBREG, when we split it, it should 230218334Speter be written as a ZERO_EXTEND. */ 230318334Speter if (split_code == SUBREG && GET_CODE (SUBREG_REG (*split)) == MEM) 2304117395Skan { 2305117395Skan#ifdef LOAD_EXTEND_OP 2306117395Skan /* Or as a SIGN_EXTEND if LOAD_EXTEND_OP says that that's 2307117395Skan what it really is. */ 2308117395Skan if (LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (*split))) 2309117395Skan == SIGN_EXTEND) 2310117395Skan SUBST (*split, gen_rtx_SIGN_EXTEND (split_mode, 2311117395Skan SUBREG_REG (*split))); 2312117395Skan else 231318334Speter#endif 2314117395Skan SUBST (*split, gen_rtx_ZERO_EXTEND (split_mode, 2315117395Skan SUBREG_REG (*split))); 2316117395Skan } 2317117395Skan#endif 231818334Speter 231990075Sobrien newi2pat = gen_rtx_SET (VOIDmode, newdest, *split); 232018334Speter SUBST (*split, newdest); 232152284Sobrien i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes); 232218334Speter 232318334Speter /* If the split point was a MULT and we didn't have one before, 232418334Speter don't use one now. */ 232518334Speter if (i2_code_number >= 0 && ! (split_code == MULT && ! have_mult)) 232652284Sobrien insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); 232718334Speter } 232818334Speter } 232918334Speter 233018334Speter /* Check for a case where we loaded from memory in a narrow mode and 233118334Speter then sign extended it, but we need both registers. In that case, 233218334Speter we have a PARALLEL with both loads from the same memory location. 233318334Speter We can split this into a load from memory followed by a register-register 233418334Speter copy. This saves at least one insn, more if register allocation can 233518334Speter eliminate the copy. 233618334Speter 2337117395Skan We cannot do this if the destination of the first assignment is a 2338117395Skan condition code register or cc0. We eliminate this case by making sure 2339117395Skan the SET_DEST and SET_SRC have the same mode. 2340117395Skan 234118334Speter We cannot do this if the destination of the second assignment is 234218334Speter a register that we have already assumed is zero-extended. Similarly 234318334Speter for a SUBREG of such a register. */ 234418334Speter 234518334Speter else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0 234618334Speter && GET_CODE (newpat) == PARALLEL 234718334Speter && XVECLEN (newpat, 0) == 2 234818334Speter && GET_CODE (XVECEXP (newpat, 0, 0)) == SET 234918334Speter && GET_CODE (SET_SRC (XVECEXP (newpat, 0, 0))) == SIGN_EXTEND 2350117395Skan && (GET_MODE (SET_DEST (XVECEXP (newpat, 0, 0))) 2351117395Skan == GET_MODE (SET_SRC (XVECEXP (newpat, 0, 0)))) 235218334Speter && GET_CODE (XVECEXP (newpat, 0, 1)) == SET 235318334Speter && rtx_equal_p (SET_SRC (XVECEXP (newpat, 0, 1)), 235418334Speter XEXP (SET_SRC (XVECEXP (newpat, 0, 0)), 0)) 235518334Speter && ! use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)), 235618334Speter INSN_CUID (i2)) 235718334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT 235818334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART 235918334Speter && ! (temp = SET_DEST (XVECEXP (newpat, 0, 1)), 236018334Speter (GET_CODE (temp) == REG 236118334Speter && reg_nonzero_bits[REGNO (temp)] != 0 236218334Speter && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD 236318334Speter && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT 236418334Speter && (reg_nonzero_bits[REGNO (temp)] 236518334Speter != GET_MODE_MASK (word_mode)))) 236618334Speter && ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == SUBREG 236718334Speter && (temp = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1))), 236818334Speter (GET_CODE (temp) == REG 236918334Speter && reg_nonzero_bits[REGNO (temp)] != 0 237018334Speter && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD 237118334Speter && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT 237218334Speter && (reg_nonzero_bits[REGNO (temp)] 237318334Speter != GET_MODE_MASK (word_mode))))) 237418334Speter && ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1)), 237518334Speter SET_SRC (XVECEXP (newpat, 0, 1))) 237618334Speter && ! find_reg_note (i3, REG_UNUSED, 237718334Speter SET_DEST (XVECEXP (newpat, 0, 0)))) 237818334Speter { 237918334Speter rtx ni2dest; 238018334Speter 238118334Speter newi2pat = XVECEXP (newpat, 0, 0); 238218334Speter ni2dest = SET_DEST (XVECEXP (newpat, 0, 0)); 238318334Speter newpat = XVECEXP (newpat, 0, 1); 238418334Speter SUBST (SET_SRC (newpat), 238518334Speter gen_lowpart_for_combine (GET_MODE (SET_SRC (newpat)), ni2dest)); 238652284Sobrien i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes); 238718334Speter 238818334Speter if (i2_code_number >= 0) 238952284Sobrien insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); 239018334Speter 239118334Speter if (insn_code_number >= 0) 239218334Speter { 239318334Speter rtx insn; 239418334Speter rtx link; 239518334Speter 239618334Speter /* If we will be able to accept this, we have made a change to the 239718334Speter destination of I3. This can invalidate a LOG_LINKS pointing 239818334Speter to I3. No other part of combine.c makes such a transformation. 239918334Speter 240018334Speter The new I3 will have a destination that was previously the 240118334Speter destination of I1 or I2 and which was used in i2 or I3. Call 240218334Speter distribute_links to make a LOG_LINK from the next use of 240318334Speter that destination. */ 240418334Speter 240518334Speter PATTERN (i3) = newpat; 240650397Sobrien distribute_links (gen_rtx_INSN_LIST (VOIDmode, i3, NULL_RTX)); 240718334Speter 240818334Speter /* I3 now uses what used to be its destination and which is 240918334Speter now I2's destination. That means we need a LOG_LINK from 241018334Speter I3 to I2. But we used to have one, so we still will. 241118334Speter 241218334Speter However, some later insn might be using I2's dest and have 241318334Speter a LOG_LINK pointing at I3. We must remove this link. 241418334Speter The simplest way to remove the link is to point it at I1, 241518334Speter which we know will be a NOTE. */ 241618334Speter 241718334Speter for (insn = NEXT_INSN (i3); 2418117395Skan insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR 2419117395Skan || insn != this_basic_block->next_bb->head); 242018334Speter insn = NEXT_INSN (insn)) 242118334Speter { 242290075Sobrien if (INSN_P (insn) && reg_referenced_p (ni2dest, PATTERN (insn))) 242318334Speter { 242418334Speter for (link = LOG_LINKS (insn); link; 242518334Speter link = XEXP (link, 1)) 242618334Speter if (XEXP (link, 0) == i3) 242718334Speter XEXP (link, 0) = i1; 242818334Speter 242918334Speter break; 243018334Speter } 243118334Speter } 243218334Speter } 243318334Speter } 243490075Sobrien 243518334Speter /* Similarly, check for a case where we have a PARALLEL of two independent 243618334Speter SETs but we started with three insns. In this case, we can do the sets 243718334Speter as two separate insns. This case occurs when some SET allows two 243818334Speter other insns to combine, but the destination of that SET is still live. */ 243918334Speter 244018334Speter else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0 244118334Speter && GET_CODE (newpat) == PARALLEL 244218334Speter && XVECLEN (newpat, 0) == 2 244318334Speter && GET_CODE (XVECEXP (newpat, 0, 0)) == SET 244418334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != ZERO_EXTRACT 244518334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != STRICT_LOW_PART 244618334Speter && GET_CODE (XVECEXP (newpat, 0, 1)) == SET 244718334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT 244818334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART 244918334Speter && ! use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)), 245018334Speter INSN_CUID (i2)) 245118334Speter /* Don't pass sets with (USE (MEM ...)) dests to the following. */ 245218334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != USE 245318334Speter && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != USE 245418334Speter && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 1)), 245518334Speter XVECEXP (newpat, 0, 0)) 245618334Speter && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 0)), 245790075Sobrien XVECEXP (newpat, 0, 1)) 245890075Sobrien && ! (contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 0))) 245990075Sobrien && contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 1))))) 246018334Speter { 246150397Sobrien /* Normally, it doesn't matter which of the two is done first, 246250397Sobrien but it does if one references cc0. In that case, it has to 246350397Sobrien be first. */ 246450397Sobrien#ifdef HAVE_cc0 246550397Sobrien if (reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0))) 246650397Sobrien { 246750397Sobrien newi2pat = XVECEXP (newpat, 0, 0); 246850397Sobrien newpat = XVECEXP (newpat, 0, 1); 246950397Sobrien } 247050397Sobrien else 247150397Sobrien#endif 247250397Sobrien { 247350397Sobrien newi2pat = XVECEXP (newpat, 0, 1); 247450397Sobrien newpat = XVECEXP (newpat, 0, 0); 247550397Sobrien } 247618334Speter 247752284Sobrien i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes); 247818334Speter 247918334Speter if (i2_code_number >= 0) 248052284Sobrien insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); 248118334Speter } 248218334Speter 248318334Speter /* If it still isn't recognized, fail and change things back the way they 248418334Speter were. */ 248518334Speter if ((insn_code_number < 0 248618334Speter /* Is the result a reasonable ASM_OPERANDS? */ 248718334Speter && (! check_asm_operands (newpat) || added_sets_1 || added_sets_2))) 248818334Speter { 248918334Speter undo_all (); 249018334Speter return 0; 249118334Speter } 249218334Speter 249318334Speter /* If we had to change another insn, make sure it is valid also. */ 249418334Speter if (undobuf.other_insn) 249518334Speter { 249618334Speter rtx other_pat = PATTERN (undobuf.other_insn); 249718334Speter rtx new_other_notes; 249818334Speter rtx note, next; 249918334Speter 250018334Speter CLEAR_HARD_REG_SET (newpat_used_regs); 250118334Speter 250252284Sobrien other_code_number = recog_for_combine (&other_pat, undobuf.other_insn, 250352284Sobrien &new_other_notes); 250418334Speter 250518334Speter if (other_code_number < 0 && ! check_asm_operands (other_pat)) 250618334Speter { 250718334Speter undo_all (); 250818334Speter return 0; 250918334Speter } 251018334Speter 251118334Speter PATTERN (undobuf.other_insn) = other_pat; 251218334Speter 251318334Speter /* If any of the notes in OTHER_INSN were REG_UNUSED, ensure that they 251418334Speter are still valid. Then add any non-duplicate notes added by 251518334Speter recog_for_combine. */ 251618334Speter for (note = REG_NOTES (undobuf.other_insn); note; note = next) 251718334Speter { 251818334Speter next = XEXP (note, 1); 251918334Speter 252018334Speter if (REG_NOTE_KIND (note) == REG_UNUSED 252118334Speter && ! reg_set_p (XEXP (note, 0), PATTERN (undobuf.other_insn))) 252218334Speter { 252318334Speter if (GET_CODE (XEXP (note, 0)) == REG) 252450397Sobrien REG_N_DEATHS (REGNO (XEXP (note, 0)))--; 252518334Speter 252618334Speter remove_note (undobuf.other_insn, note); 252718334Speter } 252818334Speter } 252918334Speter 253018334Speter for (note = new_other_notes; note; note = XEXP (note, 1)) 253118334Speter if (GET_CODE (XEXP (note, 0)) == REG) 253250397Sobrien REG_N_DEATHS (REGNO (XEXP (note, 0)))++; 253318334Speter 253418334Speter distribute_notes (new_other_notes, undobuf.other_insn, 253518334Speter undobuf.other_insn, NULL_RTX, NULL_RTX, NULL_RTX); 253618334Speter } 253790075Sobrien#ifdef HAVE_cc0 253890075Sobrien /* If I2 is the setter CC0 and I3 is the user CC0 then check whether 253990075Sobrien they are adjacent to each other or not. */ 254090075Sobrien { 254190075Sobrien rtx p = prev_nonnote_insn (i3); 254290075Sobrien if (p && p != i2 && GET_CODE (p) == INSN && newi2pat 254390075Sobrien && sets_cc0_p (newi2pat)) 254490075Sobrien { 254590075Sobrien undo_all (); 254690075Sobrien return 0; 254790075Sobrien } 254890075Sobrien } 254990075Sobrien#endif 255018334Speter 255190075Sobrien /* We now know that we can do this combination. Merge the insns and 255218334Speter update the status of registers and LOG_LINKS. */ 255318334Speter 255418334Speter { 255518334Speter rtx i3notes, i2notes, i1notes = 0; 255618334Speter rtx i3links, i2links, i1links = 0; 255718334Speter rtx midnotes = 0; 255890075Sobrien unsigned int regno; 255950397Sobrien /* Compute which registers we expect to eliminate. newi2pat may be setting 256050397Sobrien either i3dest or i2dest, so we must check it. Also, i1dest may be the 256150397Sobrien same as i3dest, in which case newi2pat may be setting i1dest. */ 256250397Sobrien rtx elim_i2 = ((newi2pat && reg_set_p (i2dest, newi2pat)) 256350397Sobrien || i2dest_in_i2src || i2dest_in_i1src 256418334Speter ? 0 : i2dest); 256550397Sobrien rtx elim_i1 = (i1 == 0 || i1dest_in_i1src 256650397Sobrien || (newi2pat && reg_set_p (i1dest, newi2pat)) 256750397Sobrien ? 0 : i1dest); 256818334Speter 256918334Speter /* Get the old REG_NOTES and LOG_LINKS from all our insns and 257018334Speter clear them. */ 257118334Speter i3notes = REG_NOTES (i3), i3links = LOG_LINKS (i3); 257218334Speter i2notes = REG_NOTES (i2), i2links = LOG_LINKS (i2); 257318334Speter if (i1) 257418334Speter i1notes = REG_NOTES (i1), i1links = LOG_LINKS (i1); 257518334Speter 257618334Speter /* Ensure that we do not have something that should not be shared but 257718334Speter occurs multiple times in the new insns. Check this by first 257818334Speter resetting all the `used' flags and then copying anything is shared. */ 257918334Speter 258018334Speter reset_used_flags (i3notes); 258118334Speter reset_used_flags (i2notes); 258218334Speter reset_used_flags (i1notes); 258318334Speter reset_used_flags (newpat); 258418334Speter reset_used_flags (newi2pat); 258518334Speter if (undobuf.other_insn) 258618334Speter reset_used_flags (PATTERN (undobuf.other_insn)); 258718334Speter 258818334Speter i3notes = copy_rtx_if_shared (i3notes); 258918334Speter i2notes = copy_rtx_if_shared (i2notes); 259018334Speter i1notes = copy_rtx_if_shared (i1notes); 259118334Speter newpat = copy_rtx_if_shared (newpat); 259218334Speter newi2pat = copy_rtx_if_shared (newi2pat); 259318334Speter if (undobuf.other_insn) 259418334Speter reset_used_flags (PATTERN (undobuf.other_insn)); 259518334Speter 259618334Speter INSN_CODE (i3) = insn_code_number; 259718334Speter PATTERN (i3) = newpat; 259896263Sobrien 259996263Sobrien if (GET_CODE (i3) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (i3)) 260096263Sobrien { 260196263Sobrien rtx call_usage = CALL_INSN_FUNCTION_USAGE (i3); 260296263Sobrien 260396263Sobrien reset_used_flags (call_usage); 260496263Sobrien call_usage = copy_rtx (call_usage); 260596263Sobrien 260696263Sobrien if (substed_i2) 260796263Sobrien replace_rtx (call_usage, i2dest, i2src); 260896263Sobrien 260996263Sobrien if (substed_i1) 261096263Sobrien replace_rtx (call_usage, i1dest, i1src); 261196263Sobrien 261296263Sobrien CALL_INSN_FUNCTION_USAGE (i3) = call_usage; 261396263Sobrien } 261496263Sobrien 261518334Speter if (undobuf.other_insn) 261618334Speter INSN_CODE (undobuf.other_insn) = other_code_number; 261718334Speter 261818334Speter /* We had one special case above where I2 had more than one set and 261918334Speter we replaced a destination of one of those sets with the destination 262018334Speter of I3. In that case, we have to update LOG_LINKS of insns later 262118334Speter in this basic block. Note that this (expensive) case is rare. 262218334Speter 262318334Speter Also, in this case, we must pretend that all REG_NOTEs for I2 262418334Speter actually came from I3, so that REG_UNUSED notes from I2 will be 262518334Speter properly handled. */ 262618334Speter 262718334Speter if (i3_subst_into_i2) 262818334Speter { 262918334Speter for (i = 0; i < XVECLEN (PATTERN (i2), 0); i++) 263090075Sobrien if (GET_CODE (XVECEXP (PATTERN (i2), 0, i)) != USE 263190075Sobrien && GET_CODE (SET_DEST (XVECEXP (PATTERN (i2), 0, i))) == REG 263218334Speter && SET_DEST (XVECEXP (PATTERN (i2), 0, i)) != i2dest 263318334Speter && ! find_reg_note (i2, REG_UNUSED, 263418334Speter SET_DEST (XVECEXP (PATTERN (i2), 0, i)))) 263518334Speter for (temp = NEXT_INSN (i2); 2636117395Skan temp && (this_basic_block->next_bb == EXIT_BLOCK_PTR 2637117395Skan || this_basic_block->head != temp); 263818334Speter temp = NEXT_INSN (temp)) 263990075Sobrien if (temp != i3 && INSN_P (temp)) 264018334Speter for (link = LOG_LINKS (temp); link; link = XEXP (link, 1)) 264118334Speter if (XEXP (link, 0) == i2) 264218334Speter XEXP (link, 0) = i3; 264318334Speter 264418334Speter if (i3notes) 264518334Speter { 264618334Speter rtx link = i3notes; 264718334Speter while (XEXP (link, 1)) 264818334Speter link = XEXP (link, 1); 264918334Speter XEXP (link, 1) = i2notes; 265018334Speter } 265118334Speter else 265218334Speter i3notes = i2notes; 265318334Speter i2notes = 0; 265418334Speter } 265518334Speter 265618334Speter LOG_LINKS (i3) = 0; 265718334Speter REG_NOTES (i3) = 0; 265818334Speter LOG_LINKS (i2) = 0; 265918334Speter REG_NOTES (i2) = 0; 266018334Speter 266118334Speter if (newi2pat) 266218334Speter { 266318334Speter INSN_CODE (i2) = i2_code_number; 266418334Speter PATTERN (i2) = newi2pat; 266518334Speter } 266618334Speter else 266718334Speter { 266818334Speter PUT_CODE (i2, NOTE); 266918334Speter NOTE_LINE_NUMBER (i2) = NOTE_INSN_DELETED; 267018334Speter NOTE_SOURCE_FILE (i2) = 0; 267118334Speter } 267218334Speter 267318334Speter if (i1) 267418334Speter { 267518334Speter LOG_LINKS (i1) = 0; 267618334Speter REG_NOTES (i1) = 0; 267718334Speter PUT_CODE (i1, NOTE); 267818334Speter NOTE_LINE_NUMBER (i1) = NOTE_INSN_DELETED; 267918334Speter NOTE_SOURCE_FILE (i1) = 0; 268018334Speter } 268118334Speter 268218334Speter /* Get death notes for everything that is now used in either I3 or 268390075Sobrien I2 and used to die in a previous insn. If we built two new 268450397Sobrien patterns, move from I1 to I2 then I2 to I3 so that we get the 268550397Sobrien proper movement on registers that I2 modifies. */ 268618334Speter 268718334Speter if (newi2pat) 268850397Sobrien { 268950397Sobrien move_deaths (newi2pat, NULL_RTX, INSN_CUID (i1), i2, &midnotes); 269050397Sobrien move_deaths (newpat, newi2pat, INSN_CUID (i1), i3, &midnotes); 269150397Sobrien } 269250397Sobrien else 269350397Sobrien move_deaths (newpat, NULL_RTX, i1 ? INSN_CUID (i1) : INSN_CUID (i2), 269450397Sobrien i3, &midnotes); 269518334Speter 269618334Speter /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3. */ 269718334Speter if (i3notes) 269818334Speter distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL_RTX, 269918334Speter elim_i2, elim_i1); 270018334Speter if (i2notes) 270118334Speter distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL_RTX, 270218334Speter elim_i2, elim_i1); 270318334Speter if (i1notes) 270418334Speter distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL_RTX, 270518334Speter elim_i2, elim_i1); 270618334Speter if (midnotes) 270718334Speter distribute_notes (midnotes, NULL_RTX, i3, newi2pat ? i2 : NULL_RTX, 270818334Speter elim_i2, elim_i1); 270918334Speter 271018334Speter /* Distribute any notes added to I2 or I3 by recog_for_combine. We 271118334Speter know these are REG_UNUSED and want them to go to the desired insn, 271290075Sobrien so we always pass it as i3. We have not counted the notes in 271318334Speter reg_n_deaths yet, so we need to do so now. */ 271418334Speter 271518334Speter if (newi2pat && new_i2_notes) 271618334Speter { 271718334Speter for (temp = new_i2_notes; temp; temp = XEXP (temp, 1)) 271818334Speter if (GET_CODE (XEXP (temp, 0)) == REG) 271950397Sobrien REG_N_DEATHS (REGNO (XEXP (temp, 0)))++; 272090075Sobrien 272118334Speter distribute_notes (new_i2_notes, i2, i2, NULL_RTX, NULL_RTX, NULL_RTX); 272218334Speter } 272318334Speter 272418334Speter if (new_i3_notes) 272518334Speter { 272618334Speter for (temp = new_i3_notes; temp; temp = XEXP (temp, 1)) 272718334Speter if (GET_CODE (XEXP (temp, 0)) == REG) 272850397Sobrien REG_N_DEATHS (REGNO (XEXP (temp, 0)))++; 272990075Sobrien 273018334Speter distribute_notes (new_i3_notes, i3, i3, NULL_RTX, NULL_RTX, NULL_RTX); 273118334Speter } 273218334Speter 273318334Speter /* If I3DEST was used in I3SRC, it really died in I3. We may need to 273450397Sobrien put a REG_DEAD note for it somewhere. If NEWI2PAT exists and sets 273550397Sobrien I3DEST, the death must be somewhere before I2, not I3. If we passed I3 273650397Sobrien in that case, it might delete I2. Similarly for I2 and I1. 273718334Speter Show an additional death due to the REG_DEAD note we make here. If 273818334Speter we discard it in distribute_notes, we will decrement it again. */ 273918334Speter 274018334Speter if (i3dest_killed) 274118334Speter { 274218334Speter if (GET_CODE (i3dest_killed) == REG) 274350397Sobrien REG_N_DEATHS (REGNO (i3dest_killed))++; 274418334Speter 274550397Sobrien if (newi2pat && reg_set_p (i3dest_killed, newi2pat)) 274650397Sobrien distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed, 274750397Sobrien NULL_RTX), 274850397Sobrien NULL_RTX, i2, NULL_RTX, elim_i2, elim_i1); 274950397Sobrien else 275050397Sobrien distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed, 275150397Sobrien NULL_RTX), 275250397Sobrien NULL_RTX, i3, newi2pat ? i2 : NULL_RTX, 275350397Sobrien elim_i2, elim_i1); 275418334Speter } 275518334Speter 275618334Speter if (i2dest_in_i2src) 275718334Speter { 275818334Speter if (GET_CODE (i2dest) == REG) 275950397Sobrien REG_N_DEATHS (REGNO (i2dest))++; 276018334Speter 276118334Speter if (newi2pat && reg_set_p (i2dest, newi2pat)) 276250397Sobrien distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX), 276318334Speter NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX); 276418334Speter else 276550397Sobrien distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX), 276618334Speter NULL_RTX, i3, newi2pat ? i2 : NULL_RTX, 276718334Speter NULL_RTX, NULL_RTX); 276818334Speter } 276918334Speter 277018334Speter if (i1dest_in_i1src) 277118334Speter { 277218334Speter if (GET_CODE (i1dest) == REG) 277350397Sobrien REG_N_DEATHS (REGNO (i1dest))++; 277418334Speter 277518334Speter if (newi2pat && reg_set_p (i1dest, newi2pat)) 277650397Sobrien distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX), 277718334Speter NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX); 277818334Speter else 277950397Sobrien distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX), 278018334Speter NULL_RTX, i3, newi2pat ? i2 : NULL_RTX, 278118334Speter NULL_RTX, NULL_RTX); 278218334Speter } 278318334Speter 278418334Speter distribute_links (i3links); 278518334Speter distribute_links (i2links); 278618334Speter distribute_links (i1links); 278718334Speter 278818334Speter if (GET_CODE (i2dest) == REG) 278918334Speter { 279018334Speter rtx link; 279118334Speter rtx i2_insn = 0, i2_val = 0, set; 279218334Speter 279318334Speter /* The insn that used to set this register doesn't exist, and 279418334Speter this life of the register may not exist either. See if one of 279590075Sobrien I3's links points to an insn that sets I2DEST. If it does, 279618334Speter that is now the last known value for I2DEST. If we don't update 279718334Speter this and I2 set the register to a value that depended on its old 279818334Speter contents, we will get confused. If this insn is used, thing 279918334Speter will be set correctly in combine_instructions. */ 280018334Speter 280118334Speter for (link = LOG_LINKS (i3); link; link = XEXP (link, 1)) 280218334Speter if ((set = single_set (XEXP (link, 0))) != 0 280318334Speter && rtx_equal_p (i2dest, SET_DEST (set))) 280418334Speter i2_insn = XEXP (link, 0), i2_val = SET_SRC (set); 280518334Speter 280618334Speter record_value_for_reg (i2dest, i2_insn, i2_val); 280718334Speter 280818334Speter /* If the reg formerly set in I2 died only once and that was in I3, 280918334Speter zero its use count so it won't make `reload' do any work. */ 281050397Sobrien if (! added_sets_2 281150397Sobrien && (newi2pat == 0 || ! reg_mentioned_p (i2dest, newi2pat)) 281250397Sobrien && ! i2dest_in_i2src) 281318334Speter { 281418334Speter regno = REGNO (i2dest); 281550397Sobrien REG_N_SETS (regno)--; 281618334Speter } 281718334Speter } 281818334Speter 281918334Speter if (i1 && GET_CODE (i1dest) == REG) 282018334Speter { 282118334Speter rtx link; 282218334Speter rtx i1_insn = 0, i1_val = 0, set; 282318334Speter 282418334Speter for (link = LOG_LINKS (i3); link; link = XEXP (link, 1)) 282518334Speter if ((set = single_set (XEXP (link, 0))) != 0 282618334Speter && rtx_equal_p (i1dest, SET_DEST (set))) 282718334Speter i1_insn = XEXP (link, 0), i1_val = SET_SRC (set); 282818334Speter 282918334Speter record_value_for_reg (i1dest, i1_insn, i1_val); 283018334Speter 283118334Speter regno = REGNO (i1dest); 283218334Speter if (! added_sets_1 && ! i1dest_in_i1src) 283390075Sobrien REG_N_SETS (regno)--; 283418334Speter } 283518334Speter 283618334Speter /* Update reg_nonzero_bits et al for any changes that may have been made 283790075Sobrien to this insn. The order of set_nonzero_bits_and_sign_copies() is 283890075Sobrien important. Because newi2pat can affect nonzero_bits of newpat */ 283918334Speter if (newi2pat) 284090075Sobrien note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL); 284190075Sobrien note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL); 284218334Speter 284390075Sobrien /* Set new_direct_jump_p if a new return or simple jump instruction 284490075Sobrien has been created. 284590075Sobrien 284690075Sobrien If I3 is now an unconditional jump, ensure that it has a 284718334Speter BARRIER following it since it may have initially been a 284818334Speter conditional jump. It may also be the last nonnote insn. */ 284918334Speter 2850117395Skan if (returnjump_p (i3) || any_uncondjump_p (i3)) 285190075Sobrien { 285290075Sobrien *new_direct_jump_p = 1; 285390075Sobrien 285490075Sobrien if ((temp = next_nonnote_insn (i3)) == NULL_RTX 285590075Sobrien || GET_CODE (temp) != BARRIER) 285690075Sobrien emit_barrier_after (i3); 285790075Sobrien } 2858117395Skan 2859117395Skan if (undobuf.other_insn != NULL_RTX 2860117395Skan && (returnjump_p (undobuf.other_insn) 2861117395Skan || any_uncondjump_p (undobuf.other_insn))) 2862117395Skan { 2863117395Skan *new_direct_jump_p = 1; 2864117395Skan 2865117395Skan if ((temp = next_nonnote_insn (undobuf.other_insn)) == NULL_RTX 2866117395Skan || GET_CODE (temp) != BARRIER) 2867117395Skan emit_barrier_after (undobuf.other_insn); 2868117395Skan } 2869117395Skan 287090075Sobrien /* An NOOP jump does not need barrier, but it does need cleaning up 287190075Sobrien of CFG. */ 287290075Sobrien if (GET_CODE (newpat) == SET 287390075Sobrien && SET_SRC (newpat) == pc_rtx 287490075Sobrien && SET_DEST (newpat) == pc_rtx) 287590075Sobrien *new_direct_jump_p = 1; 287618334Speter } 287718334Speter 287818334Speter combine_successes++; 287990075Sobrien undo_commit (); 288018334Speter 288118334Speter /* Clear this here, so that subsequent get_last_value calls are not 288218334Speter affected. */ 288318334Speter subst_prev_insn = NULL_RTX; 288418334Speter 288518334Speter if (added_links_insn 288618334Speter && (newi2pat == 0 || INSN_CUID (added_links_insn) < INSN_CUID (i2)) 288718334Speter && INSN_CUID (added_links_insn) < INSN_CUID (i3)) 288818334Speter return added_links_insn; 288918334Speter else 289018334Speter return newi2pat ? i2 : i3; 289118334Speter} 289218334Speter 289318334Speter/* Undo all the modifications recorded in undobuf. */ 289418334Speter 289518334Speterstatic void 289618334Speterundo_all () 289718334Speter{ 289850397Sobrien struct undo *undo, *next; 289950397Sobrien 290050397Sobrien for (undo = undobuf.undos; undo; undo = next) 290118334Speter { 290250397Sobrien next = undo->next; 290350397Sobrien if (undo->is_int) 290450397Sobrien *undo->where.i = undo->old_contents.i; 290518334Speter else 290650397Sobrien *undo->where.r = undo->old_contents.r; 290750397Sobrien 290850397Sobrien undo->next = undobuf.frees; 290950397Sobrien undobuf.frees = undo; 291018334Speter } 291118334Speter 291290075Sobrien undobuf.undos = 0; 291318334Speter 291418334Speter /* Clear this here, so that subsequent get_last_value calls are not 291518334Speter affected. */ 291618334Speter subst_prev_insn = NULL_RTX; 291718334Speter} 291890075Sobrien 291990075Sobrien/* We've committed to accepting the changes we made. Move all 292090075Sobrien of the undos to the free list. */ 292190075Sobrien 292290075Sobrienstatic void 292390075Sobrienundo_commit () 292490075Sobrien{ 292590075Sobrien struct undo *undo, *next; 292690075Sobrien 292790075Sobrien for (undo = undobuf.undos; undo; undo = next) 292890075Sobrien { 292990075Sobrien next = undo->next; 293090075Sobrien undo->next = undobuf.frees; 293190075Sobrien undobuf.frees = undo; 293290075Sobrien } 293390075Sobrien undobuf.undos = 0; 293490075Sobrien} 293590075Sobrien 293618334Speter 293718334Speter/* Find the innermost point within the rtx at LOC, possibly LOC itself, 293818334Speter where we have an arithmetic expression and return that point. LOC will 293918334Speter be inside INSN. 294018334Speter 294118334Speter try_combine will call this function to see if an insn can be split into 294218334Speter two insns. */ 294318334Speter 294418334Speterstatic rtx * 294518334Speterfind_split_point (loc, insn) 294618334Speter rtx *loc; 294718334Speter rtx insn; 294818334Speter{ 294918334Speter rtx x = *loc; 295018334Speter enum rtx_code code = GET_CODE (x); 295118334Speter rtx *split; 295290075Sobrien unsigned HOST_WIDE_INT len = 0; 295390075Sobrien HOST_WIDE_INT pos = 0; 295490075Sobrien int unsignedp = 0; 295590075Sobrien rtx inner = NULL_RTX; 295618334Speter 295718334Speter /* First special-case some codes. */ 295818334Speter switch (code) 295918334Speter { 296018334Speter case SUBREG: 296118334Speter#ifdef INSN_SCHEDULING 296218334Speter /* If we are making a paradoxical SUBREG invalid, it becomes a split 296318334Speter point. */ 296418334Speter if (GET_CODE (SUBREG_REG (x)) == MEM) 296518334Speter return loc; 296618334Speter#endif 296718334Speter return find_split_point (&SUBREG_REG (x), insn); 296818334Speter 296918334Speter case MEM: 297018334Speter#ifdef HAVE_lo_sum 297118334Speter /* If we have (mem (const ..)) or (mem (symbol_ref ...)), split it 297218334Speter using LO_SUM and HIGH. */ 297318334Speter if (GET_CODE (XEXP (x, 0)) == CONST 297418334Speter || GET_CODE (XEXP (x, 0)) == SYMBOL_REF) 297518334Speter { 297618334Speter SUBST (XEXP (x, 0), 297790075Sobrien gen_rtx_LO_SUM (Pmode, 297890075Sobrien gen_rtx_HIGH (Pmode, XEXP (x, 0)), 297990075Sobrien XEXP (x, 0))); 298018334Speter return &XEXP (XEXP (x, 0), 0); 298118334Speter } 298218334Speter#endif 298318334Speter 298418334Speter /* If we have a PLUS whose second operand is a constant and the 298518334Speter address is not valid, perhaps will can split it up using 298618334Speter the machine-specific way to split large constants. We use 298718334Speter the first pseudo-reg (one of the virtual regs) as a placeholder; 298818334Speter it will not remain in the result. */ 298918334Speter if (GET_CODE (XEXP (x, 0)) == PLUS 299018334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 299118334Speter && ! memory_address_p (GET_MODE (x), XEXP (x, 0))) 299218334Speter { 299318334Speter rtx reg = regno_reg_rtx[FIRST_PSEUDO_REGISTER]; 299450397Sobrien rtx seq = split_insns (gen_rtx_SET (VOIDmode, reg, XEXP (x, 0)), 299518334Speter subst_insn); 299618334Speter 299718334Speter /* This should have produced two insns, each of which sets our 299818334Speter placeholder. If the source of the second is a valid address, 299918334Speter we can make put both sources together and make a split point 300018334Speter in the middle. */ 300118334Speter 3002117395Skan if (seq 3003117395Skan && NEXT_INSN (seq) != NULL_RTX 3004117395Skan && NEXT_INSN (NEXT_INSN (seq)) == NULL_RTX 3005117395Skan && GET_CODE (seq) == INSN 3006117395Skan && GET_CODE (PATTERN (seq)) == SET 3007117395Skan && SET_DEST (PATTERN (seq)) == reg 300818334Speter && ! reg_mentioned_p (reg, 3009117395Skan SET_SRC (PATTERN (seq))) 3010117395Skan && GET_CODE (NEXT_INSN (seq)) == INSN 3011117395Skan && GET_CODE (PATTERN (NEXT_INSN (seq))) == SET 3012117395Skan && SET_DEST (PATTERN (NEXT_INSN (seq))) == reg 301318334Speter && memory_address_p (GET_MODE (x), 3014117395Skan SET_SRC (PATTERN (NEXT_INSN (seq))))) 301518334Speter { 3016117395Skan rtx src1 = SET_SRC (PATTERN (seq)); 3017117395Skan rtx src2 = SET_SRC (PATTERN (NEXT_INSN (seq))); 301818334Speter 301918334Speter /* Replace the placeholder in SRC2 with SRC1. If we can 302018334Speter find where in SRC2 it was placed, that can become our 302118334Speter split point and we can replace this address with SRC2. 302218334Speter Just try two obvious places. */ 302318334Speter 302418334Speter src2 = replace_rtx (src2, reg, src1); 302518334Speter split = 0; 302618334Speter if (XEXP (src2, 0) == src1) 302718334Speter split = &XEXP (src2, 0); 302818334Speter else if (GET_RTX_FORMAT (GET_CODE (XEXP (src2, 0)))[0] == 'e' 302918334Speter && XEXP (XEXP (src2, 0), 0) == src1) 303018334Speter split = &XEXP (XEXP (src2, 0), 0); 303118334Speter 303218334Speter if (split) 303318334Speter { 303418334Speter SUBST (XEXP (x, 0), src2); 303518334Speter return split; 303618334Speter } 303718334Speter } 303890075Sobrien 303918334Speter /* If that didn't work, perhaps the first operand is complex and 304018334Speter needs to be computed separately, so make a split point there. 304118334Speter This will occur on machines that just support REG + CONST 304218334Speter and have a constant moved through some previous computation. */ 304318334Speter 304418334Speter else if (GET_RTX_CLASS (GET_CODE (XEXP (XEXP (x, 0), 0))) != 'o' 304518334Speter && ! (GET_CODE (XEXP (XEXP (x, 0), 0)) == SUBREG 304618334Speter && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (XEXP (x, 0), 0)))) 304718334Speter == 'o'))) 304818334Speter return &XEXP (XEXP (x, 0), 0); 304918334Speter } 305018334Speter break; 305118334Speter 305218334Speter case SET: 305318334Speter#ifdef HAVE_cc0 305418334Speter /* If SET_DEST is CC0 and SET_SRC is not an operand, a COMPARE, or a 305518334Speter ZERO_EXTRACT, the most likely reason why this doesn't match is that 305618334Speter we need to put the operand into a register. So split at that 305718334Speter point. */ 305818334Speter 305918334Speter if (SET_DEST (x) == cc0_rtx 306018334Speter && GET_CODE (SET_SRC (x)) != COMPARE 306118334Speter && GET_CODE (SET_SRC (x)) != ZERO_EXTRACT 306218334Speter && GET_RTX_CLASS (GET_CODE (SET_SRC (x))) != 'o' 306318334Speter && ! (GET_CODE (SET_SRC (x)) == SUBREG 306418334Speter && GET_RTX_CLASS (GET_CODE (SUBREG_REG (SET_SRC (x)))) == 'o')) 306518334Speter return &SET_SRC (x); 306618334Speter#endif 306718334Speter 306818334Speter /* See if we can split SET_SRC as it stands. */ 306918334Speter split = find_split_point (&SET_SRC (x), insn); 307018334Speter if (split && split != &SET_SRC (x)) 307118334Speter return split; 307218334Speter 307350397Sobrien /* See if we can split SET_DEST as it stands. */ 307450397Sobrien split = find_split_point (&SET_DEST (x), insn); 307550397Sobrien if (split && split != &SET_DEST (x)) 307650397Sobrien return split; 307750397Sobrien 307818334Speter /* See if this is a bitfield assignment with everything constant. If 307918334Speter so, this is an IOR of an AND, so split it into that. */ 308018334Speter if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT 308118334Speter && (GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0))) 308218334Speter <= HOST_BITS_PER_WIDE_INT) 308318334Speter && GET_CODE (XEXP (SET_DEST (x), 1)) == CONST_INT 308418334Speter && GET_CODE (XEXP (SET_DEST (x), 2)) == CONST_INT 308518334Speter && GET_CODE (SET_SRC (x)) == CONST_INT 308618334Speter && ((INTVAL (XEXP (SET_DEST (x), 1)) 308790075Sobrien + INTVAL (XEXP (SET_DEST (x), 2))) 308818334Speter <= GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0)))) 308918334Speter && ! side_effects_p (XEXP (SET_DEST (x), 0))) 309018334Speter { 309190075Sobrien HOST_WIDE_INT pos = INTVAL (XEXP (SET_DEST (x), 2)); 309290075Sobrien unsigned HOST_WIDE_INT len = INTVAL (XEXP (SET_DEST (x), 1)); 309390075Sobrien unsigned HOST_WIDE_INT src = INTVAL (SET_SRC (x)); 309418334Speter rtx dest = XEXP (SET_DEST (x), 0); 309518334Speter enum machine_mode mode = GET_MODE (dest); 309618334Speter unsigned HOST_WIDE_INT mask = ((HOST_WIDE_INT) 1 << len) - 1; 309718334Speter 309818334Speter if (BITS_BIG_ENDIAN) 309918334Speter pos = GET_MODE_BITSIZE (mode) - len - pos; 310018334Speter 310190075Sobrien if (src == mask) 310218334Speter SUBST (SET_SRC (x), 310318334Speter gen_binary (IOR, mode, dest, GEN_INT (src << pos))); 310418334Speter else 310518334Speter SUBST (SET_SRC (x), 310618334Speter gen_binary (IOR, mode, 310790075Sobrien gen_binary (AND, mode, dest, 3108117395Skan gen_int_mode (~(mask << pos), 3109117395Skan mode)), 311018334Speter GEN_INT (src << pos))); 311118334Speter 311218334Speter SUBST (SET_DEST (x), dest); 311318334Speter 311418334Speter split = find_split_point (&SET_SRC (x), insn); 311518334Speter if (split && split != &SET_SRC (x)) 311618334Speter return split; 311718334Speter } 311818334Speter 311918334Speter /* Otherwise, see if this is an operation that we can split into two. 312018334Speter If so, try to split that. */ 312118334Speter code = GET_CODE (SET_SRC (x)); 312218334Speter 312318334Speter switch (code) 312418334Speter { 312518334Speter case AND: 312618334Speter /* If we are AND'ing with a large constant that is only a single 312718334Speter bit and the result is only being used in a context where we 3128117395Skan need to know if it is zero or nonzero, replace it with a bit 312918334Speter extraction. This will avoid the large constant, which might 313018334Speter have taken more than one insn to make. If the constant were 313118334Speter not a valid argument to the AND but took only one insn to make, 313218334Speter this is no worse, but if it took more than one insn, it will 313318334Speter be better. */ 313418334Speter 313518334Speter if (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT 313618334Speter && GET_CODE (XEXP (SET_SRC (x), 0)) == REG 313718334Speter && (pos = exact_log2 (INTVAL (XEXP (SET_SRC (x), 1)))) >= 7 313818334Speter && GET_CODE (SET_DEST (x)) == REG 313990075Sobrien && (split = find_single_use (SET_DEST (x), insn, (rtx*) 0)) != 0 314018334Speter && (GET_CODE (*split) == EQ || GET_CODE (*split) == NE) 314118334Speter && XEXP (*split, 0) == SET_DEST (x) 314218334Speter && XEXP (*split, 1) == const0_rtx) 314318334Speter { 314450397Sobrien rtx extraction = make_extraction (GET_MODE (SET_DEST (x)), 314550397Sobrien XEXP (SET_SRC (x), 0), 314650397Sobrien pos, NULL_RTX, 1, 1, 0, 0); 314750397Sobrien if (extraction != 0) 314850397Sobrien { 314950397Sobrien SUBST (SET_SRC (x), extraction); 315050397Sobrien return find_split_point (loc, insn); 315150397Sobrien } 315250397Sobrien } 315350397Sobrien break; 315450397Sobrien 315550397Sobrien case NE: 315650397Sobrien /* if STORE_FLAG_VALUE is -1, this is (NE X 0) and only one bit of X 315790075Sobrien is known to be on, this can be converted into a NEG of a shift. */ 315850397Sobrien if (STORE_FLAG_VALUE == -1 && XEXP (SET_SRC (x), 1) == const0_rtx 315950397Sobrien && GET_MODE (SET_SRC (x)) == GET_MODE (XEXP (SET_SRC (x), 0)) 316050397Sobrien && 1 <= (pos = exact_log2 316150397Sobrien (nonzero_bits (XEXP (SET_SRC (x), 0), 316250397Sobrien GET_MODE (XEXP (SET_SRC (x), 0)))))) 316350397Sobrien { 316450397Sobrien enum machine_mode mode = GET_MODE (XEXP (SET_SRC (x), 0)); 316550397Sobrien 316618334Speter SUBST (SET_SRC (x), 316790075Sobrien gen_rtx_NEG (mode, 316890075Sobrien gen_rtx_LSHIFTRT (mode, 316990075Sobrien XEXP (SET_SRC (x), 0), 317090075Sobrien GEN_INT (pos)))); 317150397Sobrien 317250397Sobrien split = find_split_point (&SET_SRC (x), insn); 317350397Sobrien if (split && split != &SET_SRC (x)) 317450397Sobrien return split; 317518334Speter } 317618334Speter break; 317718334Speter 317818334Speter case SIGN_EXTEND: 317918334Speter inner = XEXP (SET_SRC (x), 0); 318050397Sobrien 318150397Sobrien /* We can't optimize if either mode is a partial integer 318250397Sobrien mode as we don't know how many bits are significant 318350397Sobrien in those modes. */ 318450397Sobrien if (GET_MODE_CLASS (GET_MODE (inner)) == MODE_PARTIAL_INT 318550397Sobrien || GET_MODE_CLASS (GET_MODE (SET_SRC (x))) == MODE_PARTIAL_INT) 318650397Sobrien break; 318750397Sobrien 318818334Speter pos = 0; 318918334Speter len = GET_MODE_BITSIZE (GET_MODE (inner)); 319018334Speter unsignedp = 0; 319118334Speter break; 319218334Speter 319318334Speter case SIGN_EXTRACT: 319418334Speter case ZERO_EXTRACT: 319518334Speter if (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT 319618334Speter && GET_CODE (XEXP (SET_SRC (x), 2)) == CONST_INT) 319718334Speter { 319818334Speter inner = XEXP (SET_SRC (x), 0); 319918334Speter len = INTVAL (XEXP (SET_SRC (x), 1)); 320018334Speter pos = INTVAL (XEXP (SET_SRC (x), 2)); 320118334Speter 320218334Speter if (BITS_BIG_ENDIAN) 320318334Speter pos = GET_MODE_BITSIZE (GET_MODE (inner)) - len - pos; 320418334Speter unsignedp = (code == ZERO_EXTRACT); 320518334Speter } 320618334Speter break; 320750397Sobrien 320850397Sobrien default: 320950397Sobrien break; 321018334Speter } 321118334Speter 321218334Speter if (len && pos >= 0 && pos + len <= GET_MODE_BITSIZE (GET_MODE (inner))) 321318334Speter { 321418334Speter enum machine_mode mode = GET_MODE (SET_SRC (x)); 321518334Speter 321618334Speter /* For unsigned, we have a choice of a shift followed by an 321718334Speter AND or two shifts. Use two shifts for field sizes where the 321818334Speter constant might be too large. We assume here that we can 321918334Speter always at least get 8-bit constants in an AND insn, which is 322018334Speter true for every current RISC. */ 322118334Speter 322218334Speter if (unsignedp && len <= 8) 322318334Speter { 322418334Speter SUBST (SET_SRC (x), 322590075Sobrien gen_rtx_AND (mode, 322690075Sobrien gen_rtx_LSHIFTRT 322790075Sobrien (mode, gen_lowpart_for_combine (mode, inner), 322890075Sobrien GEN_INT (pos)), 322990075Sobrien GEN_INT (((HOST_WIDE_INT) 1 << len) - 1))); 323018334Speter 323118334Speter split = find_split_point (&SET_SRC (x), insn); 323218334Speter if (split && split != &SET_SRC (x)) 323318334Speter return split; 323418334Speter } 323518334Speter else 323618334Speter { 323718334Speter SUBST (SET_SRC (x), 323890075Sobrien gen_rtx_fmt_ee 323918334Speter (unsignedp ? LSHIFTRT : ASHIFTRT, mode, 324090075Sobrien gen_rtx_ASHIFT (mode, 324190075Sobrien gen_lowpart_for_combine (mode, inner), 324290075Sobrien GEN_INT (GET_MODE_BITSIZE (mode) 324390075Sobrien - len - pos)), 324418334Speter GEN_INT (GET_MODE_BITSIZE (mode) - len))); 324518334Speter 324618334Speter split = find_split_point (&SET_SRC (x), insn); 324718334Speter if (split && split != &SET_SRC (x)) 324818334Speter return split; 324918334Speter } 325018334Speter } 325118334Speter 325218334Speter /* See if this is a simple operation with a constant as the second 325318334Speter operand. It might be that this constant is out of range and hence 325418334Speter could be used as a split point. */ 325518334Speter if ((GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '2' 325618334Speter || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == 'c' 325718334Speter || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '<') 325818334Speter && CONSTANT_P (XEXP (SET_SRC (x), 1)) 325918334Speter && (GET_RTX_CLASS (GET_CODE (XEXP (SET_SRC (x), 0))) == 'o' 326018334Speter || (GET_CODE (XEXP (SET_SRC (x), 0)) == SUBREG 326118334Speter && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (SET_SRC (x), 0)))) 326218334Speter == 'o')))) 326318334Speter return &XEXP (SET_SRC (x), 1); 326418334Speter 326518334Speter /* Finally, see if this is a simple operation with its first operand 326618334Speter not in a register. The operation might require this operand in a 326718334Speter register, so return it as a split point. We can always do this 326818334Speter because if the first operand were another operation, we would have 326918334Speter already found it as a split point. */ 327018334Speter if ((GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '2' 327118334Speter || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == 'c' 327218334Speter || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '<' 327318334Speter || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '1') 327418334Speter && ! register_operand (XEXP (SET_SRC (x), 0), VOIDmode)) 327518334Speter return &XEXP (SET_SRC (x), 0); 327618334Speter 327718334Speter return 0; 327818334Speter 327918334Speter case AND: 328018334Speter case IOR: 328118334Speter /* We write NOR as (and (not A) (not B)), but if we don't have a NOR, 328218334Speter it is better to write this as (not (ior A B)) so we can split it. 328318334Speter Similarly for IOR. */ 328418334Speter if (GET_CODE (XEXP (x, 0)) == NOT && GET_CODE (XEXP (x, 1)) == NOT) 328518334Speter { 328618334Speter SUBST (*loc, 328790075Sobrien gen_rtx_NOT (GET_MODE (x), 328890075Sobrien gen_rtx_fmt_ee (code == IOR ? AND : IOR, 328990075Sobrien GET_MODE (x), 329090075Sobrien XEXP (XEXP (x, 0), 0), 329190075Sobrien XEXP (XEXP (x, 1), 0)))); 329218334Speter return find_split_point (loc, insn); 329318334Speter } 329418334Speter 329518334Speter /* Many RISC machines have a large set of logical insns. If the 329618334Speter second operand is a NOT, put it first so we will try to split the 329718334Speter other operand first. */ 329818334Speter if (GET_CODE (XEXP (x, 1)) == NOT) 329918334Speter { 330018334Speter rtx tem = XEXP (x, 0); 330118334Speter SUBST (XEXP (x, 0), XEXP (x, 1)); 330218334Speter SUBST (XEXP (x, 1), tem); 330318334Speter } 330418334Speter break; 330550397Sobrien 330650397Sobrien default: 330750397Sobrien break; 330818334Speter } 330918334Speter 331018334Speter /* Otherwise, select our actions depending on our rtx class. */ 331118334Speter switch (GET_RTX_CLASS (code)) 331218334Speter { 331318334Speter case 'b': /* This is ZERO_EXTRACT and SIGN_EXTRACT. */ 331418334Speter case '3': 331518334Speter split = find_split_point (&XEXP (x, 2), insn); 331618334Speter if (split) 331718334Speter return split; 331850397Sobrien /* ... fall through ... */ 331918334Speter case '2': 332018334Speter case 'c': 332118334Speter case '<': 332218334Speter split = find_split_point (&XEXP (x, 1), insn); 332318334Speter if (split) 332418334Speter return split; 332550397Sobrien /* ... fall through ... */ 332618334Speter case '1': 332718334Speter /* Some machines have (and (shift ...) ...) insns. If X is not 332818334Speter an AND, but XEXP (X, 0) is, use it as our split point. */ 332918334Speter if (GET_CODE (x) != AND && GET_CODE (XEXP (x, 0)) == AND) 333018334Speter return &XEXP (x, 0); 333118334Speter 333218334Speter split = find_split_point (&XEXP (x, 0), insn); 333318334Speter if (split) 333418334Speter return split; 333518334Speter return loc; 333618334Speter } 333718334Speter 333818334Speter /* Otherwise, we don't have a split point. */ 333918334Speter return 0; 334018334Speter} 334118334Speter 334218334Speter/* Throughout X, replace FROM with TO, and return the result. 334318334Speter The result is TO if X is FROM; 334418334Speter otherwise the result is X, but its contents may have been modified. 334518334Speter If they were modified, a record was made in undobuf so that 334618334Speter undo_all will (among other things) return X to its original state. 334718334Speter 334818334Speter If the number of changes necessary is too much to record to undo, 334918334Speter the excess changes are not made, so the result is invalid. 335018334Speter The changes already made can still be undone. 335118334Speter undobuf.num_undo is incremented for such changes, so by testing that 335218334Speter the caller can tell whether the result is valid. 335318334Speter 335418334Speter `n_occurrences' is incremented each time FROM is replaced. 335590075Sobrien 3356117395Skan IN_DEST is nonzero if we are processing the SET_DEST of a SET. 335718334Speter 3358117395Skan UNIQUE_COPY is nonzero if each substitution must be unique. We do this 3359117395Skan by copying if `n_occurrences' is nonzero. */ 336018334Speter 336118334Speterstatic rtx 336218334Spetersubst (x, from, to, in_dest, unique_copy) 336390075Sobrien rtx x, from, to; 336418334Speter int in_dest; 336518334Speter int unique_copy; 336618334Speter{ 336790075Sobrien enum rtx_code code = GET_CODE (x); 336818334Speter enum machine_mode op0_mode = VOIDmode; 336990075Sobrien const char *fmt; 337090075Sobrien int len, i; 337118334Speter rtx new; 337218334Speter 337318334Speter/* Two expressions are equal if they are identical copies of a shared 337418334Speter RTX or if they are both registers with the same register number 337518334Speter and mode. */ 337618334Speter 337718334Speter#define COMBINE_RTX_EQUAL_P(X,Y) \ 337818334Speter ((X) == (Y) \ 337918334Speter || (GET_CODE (X) == REG && GET_CODE (Y) == REG \ 338018334Speter && REGNO (X) == REGNO (Y) && GET_MODE (X) == GET_MODE (Y))) 338118334Speter 338218334Speter if (! in_dest && COMBINE_RTX_EQUAL_P (x, from)) 338318334Speter { 338418334Speter n_occurrences++; 338518334Speter return (unique_copy && n_occurrences > 1 ? copy_rtx (to) : to); 338618334Speter } 338718334Speter 338818334Speter /* If X and FROM are the same register but different modes, they will 338990075Sobrien not have been seen as equal above. However, flow.c will make a 339018334Speter LOG_LINKS entry for that case. If we do nothing, we will try to 339118334Speter rerecognize our original insn and, when it succeeds, we will 339218334Speter delete the feeding insn, which is incorrect. 339318334Speter 339418334Speter So force this insn not to match in this (rare) case. */ 339518334Speter if (! in_dest && code == REG && GET_CODE (from) == REG 339618334Speter && REGNO (x) == REGNO (from)) 339750397Sobrien return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx); 339818334Speter 339918334Speter /* If this is an object, we are done unless it is a MEM or LO_SUM, both 340018334Speter of which may contain things that can be combined. */ 340118334Speter if (code != MEM && code != LO_SUM && GET_RTX_CLASS (code) == 'o') 340218334Speter return x; 340318334Speter 340418334Speter /* It is possible to have a subexpression appear twice in the insn. 340518334Speter Suppose that FROM is a register that appears within TO. 340618334Speter Then, after that subexpression has been scanned once by `subst', 340718334Speter the second time it is scanned, TO may be found. If we were 340818334Speter to scan TO here, we would find FROM within it and create a 340918334Speter self-referent rtl structure which is completely wrong. */ 341018334Speter if (COMBINE_RTX_EQUAL_P (x, to)) 341118334Speter return to; 341218334Speter 341350397Sobrien /* Parallel asm_operands need special attention because all of the 341450397Sobrien inputs are shared across the arms. Furthermore, unsharing the 341550397Sobrien rtl results in recognition failures. Failure to handle this case 341650397Sobrien specially can result in circular rtl. 341718334Speter 341850397Sobrien Solve this by doing a normal pass across the first entry of the 341950397Sobrien parallel, and only processing the SET_DESTs of the subsequent 342050397Sobrien entries. Ug. */ 342118334Speter 342250397Sobrien if (code == PARALLEL 342350397Sobrien && GET_CODE (XVECEXP (x, 0, 0)) == SET 342450397Sobrien && GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS) 342550397Sobrien { 342650397Sobrien new = subst (XVECEXP (x, 0, 0), from, to, 0, unique_copy); 342718334Speter 342850397Sobrien /* If this substitution failed, this whole thing fails. */ 342950397Sobrien if (GET_CODE (new) == CLOBBER 343050397Sobrien && XEXP (new, 0) == const0_rtx) 343150397Sobrien return new; 343250397Sobrien 343350397Sobrien SUBST (XVECEXP (x, 0, 0), new); 343450397Sobrien 343550397Sobrien for (i = XVECLEN (x, 0) - 1; i >= 1; i--) 343618334Speter { 343750397Sobrien rtx dest = SET_DEST (XVECEXP (x, 0, i)); 343890075Sobrien 343950397Sobrien if (GET_CODE (dest) != REG 344050397Sobrien && GET_CODE (dest) != CC0 344150397Sobrien && GET_CODE (dest) != PC) 344218334Speter { 344350397Sobrien new = subst (dest, from, to, 0, unique_copy); 344418334Speter 344550397Sobrien /* If this substitution failed, this whole thing fails. */ 344650397Sobrien if (GET_CODE (new) == CLOBBER 344750397Sobrien && XEXP (new, 0) == const0_rtx) 344850397Sobrien return new; 344918334Speter 345050397Sobrien SUBST (SET_DEST (XVECEXP (x, 0, i)), new); 345118334Speter } 345218334Speter } 345350397Sobrien } 345450397Sobrien else 345550397Sobrien { 345650397Sobrien len = GET_RTX_LENGTH (code); 345750397Sobrien fmt = GET_RTX_FORMAT (code); 345850397Sobrien 345950397Sobrien /* We don't need to process a SET_DEST that is a register, CC0, 346050397Sobrien or PC, so set up to skip this common case. All other cases 346150397Sobrien where we want to suppress replacing something inside a 346250397Sobrien SET_SRC are handled via the IN_DEST operand. */ 346350397Sobrien if (code == SET 346450397Sobrien && (GET_CODE (SET_DEST (x)) == REG 346550397Sobrien || GET_CODE (SET_DEST (x)) == CC0 346650397Sobrien || GET_CODE (SET_DEST (x)) == PC)) 346750397Sobrien fmt = "ie"; 346850397Sobrien 346950397Sobrien /* Get the mode of operand 0 in case X is now a SIGN_EXTEND of a 347050397Sobrien constant. */ 347150397Sobrien if (fmt[0] == 'e') 347250397Sobrien op0_mode = GET_MODE (XEXP (x, 0)); 347350397Sobrien 347450397Sobrien for (i = 0; i < len; i++) 347518334Speter { 347650397Sobrien if (fmt[i] == 'E') 347718334Speter { 347890075Sobrien int j; 347950397Sobrien for (j = XVECLEN (x, i) - 1; j >= 0; j--) 348050397Sobrien { 348150397Sobrien if (COMBINE_RTX_EQUAL_P (XVECEXP (x, i, j), from)) 348250397Sobrien { 348350397Sobrien new = (unique_copy && n_occurrences 348450397Sobrien ? copy_rtx (to) : to); 348550397Sobrien n_occurrences++; 348650397Sobrien } 348750397Sobrien else 348850397Sobrien { 348950397Sobrien new = subst (XVECEXP (x, i, j), from, to, 0, 349050397Sobrien unique_copy); 349118334Speter 349250397Sobrien /* If this substitution failed, this whole thing 349350397Sobrien fails. */ 349450397Sobrien if (GET_CODE (new) == CLOBBER 349550397Sobrien && XEXP (new, 0) == const0_rtx) 349650397Sobrien return new; 349750397Sobrien } 349850397Sobrien 349950397Sobrien SUBST (XVECEXP (x, i, j), new); 350050397Sobrien } 350150397Sobrien } 350250397Sobrien else if (fmt[i] == 'e') 350350397Sobrien { 350490075Sobrien /* If this is a register being set, ignore it. */ 350590075Sobrien new = XEXP (x, i); 350690075Sobrien if (in_dest 350790075Sobrien && (code == SUBREG || code == STRICT_LOW_PART 350890075Sobrien || code == ZERO_EXTRACT) 350990075Sobrien && i == 0 351090075Sobrien && GET_CODE (new) == REG) 351190075Sobrien ; 351290075Sobrien 351390075Sobrien else if (COMBINE_RTX_EQUAL_P (XEXP (x, i), from)) 351450397Sobrien { 351550397Sobrien /* In general, don't install a subreg involving two 351650397Sobrien modes not tieable. It can worsen register 351750397Sobrien allocation, and can even make invalid reload 351850397Sobrien insns, since the reg inside may need to be copied 351950397Sobrien from in the outside mode, and that may be invalid 352050397Sobrien if it is an fp reg copied in integer mode. 352150397Sobrien 352250397Sobrien We allow two exceptions to this: It is valid if 352350397Sobrien it is inside another SUBREG and the mode of that 352450397Sobrien SUBREG and the mode of the inside of TO is 352550397Sobrien tieable and it is valid if X is a SET that copies 352650397Sobrien FROM to CC0. */ 352750397Sobrien 352850397Sobrien if (GET_CODE (to) == SUBREG 352950397Sobrien && ! MODES_TIEABLE_P (GET_MODE (to), 353050397Sobrien GET_MODE (SUBREG_REG (to))) 353150397Sobrien && ! (code == SUBREG 353250397Sobrien && MODES_TIEABLE_P (GET_MODE (x), 353350397Sobrien GET_MODE (SUBREG_REG (to)))) 353418334Speter#ifdef HAVE_cc0 353550397Sobrien && ! (code == SET && i == 1 && XEXP (x, 0) == cc0_rtx) 353618334Speter#endif 353750397Sobrien ) 353850397Sobrien return gen_rtx_CLOBBER (VOIDmode, const0_rtx); 353918334Speter 3540117395Skan#ifdef CANNOT_CHANGE_MODE_CLASS 354190075Sobrien if (code == SUBREG 354290075Sobrien && GET_CODE (to) == REG 354390075Sobrien && REGNO (to) < FIRST_PSEUDO_REGISTER 3544117395Skan && REG_CANNOT_CHANGE_MODE_P (REGNO (to), 3545117395Skan GET_MODE (to), 3546117395Skan GET_MODE (x))) 354790075Sobrien return gen_rtx_CLOBBER (VOIDmode, const0_rtx); 354890075Sobrien#endif 354990075Sobrien 355050397Sobrien new = (unique_copy && n_occurrences ? copy_rtx (to) : to); 355150397Sobrien n_occurrences++; 355250397Sobrien } 355350397Sobrien else 355450397Sobrien /* If we are in a SET_DEST, suppress most cases unless we 355550397Sobrien have gone inside a MEM, in which case we want to 355650397Sobrien simplify the address. We assume here that things that 355750397Sobrien are actually part of the destination have their inner 355890075Sobrien parts in the first expression. This is true for SUBREG, 355950397Sobrien STRICT_LOW_PART, and ZERO_EXTRACT, which are the only 356050397Sobrien things aside from REG and MEM that should appear in a 356150397Sobrien SET_DEST. */ 356250397Sobrien new = subst (XEXP (x, i), from, to, 356350397Sobrien (((in_dest 356450397Sobrien && (code == SUBREG || code == STRICT_LOW_PART 356550397Sobrien || code == ZERO_EXTRACT)) 356650397Sobrien || code == SET) 356750397Sobrien && i == 0), unique_copy); 356818334Speter 356950397Sobrien /* If we found that we will have to reject this combination, 357050397Sobrien indicate that by returning the CLOBBER ourselves, rather than 357150397Sobrien an expression containing it. This will speed things up as 357250397Sobrien well as prevent accidents where two CLOBBERs are considered 357350397Sobrien to be equal, thus producing an incorrect simplification. */ 357418334Speter 357550397Sobrien if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx) 357650397Sobrien return new; 357718334Speter 357896263Sobrien if (GET_CODE (new) == CONST_INT && GET_CODE (x) == SUBREG) 357996263Sobrien { 3580102780Skan enum machine_mode mode = GET_MODE (x); 3581117395Skan 3582117395Skan x = simplify_subreg (GET_MODE (x), new, 358396263Sobrien GET_MODE (SUBREG_REG (x)), 358496263Sobrien SUBREG_BYTE (x)); 358596263Sobrien if (! x) 3586102780Skan x = gen_rtx_CLOBBER (mode, const0_rtx); 358796263Sobrien } 358896263Sobrien else if (GET_CODE (new) == CONST_INT 358996263Sobrien && GET_CODE (x) == ZERO_EXTEND) 359096263Sobrien { 359196263Sobrien x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x), 359296263Sobrien new, GET_MODE (XEXP (x, 0))); 359396263Sobrien if (! x) 359496263Sobrien abort (); 359596263Sobrien } 359696263Sobrien else 359796263Sobrien SUBST (XEXP (x, i), new); 359850397Sobrien } 359918334Speter } 360018334Speter } 360118334Speter 360218334Speter /* Try to simplify X. If the simplification changed the code, it is likely 360318334Speter that further simplification will help, so loop, but limit the number 360418334Speter of repetitions that will be performed. */ 360518334Speter 360618334Speter for (i = 0; i < 4; i++) 360718334Speter { 360818334Speter /* If X is sufficiently simple, don't bother trying to do anything 360918334Speter with it. */ 361018334Speter if (code != CONST_INT && code != REG && code != CLOBBER) 361190075Sobrien x = combine_simplify_rtx (x, op0_mode, i == 3, in_dest); 361218334Speter 361318334Speter if (GET_CODE (x) == code) 361418334Speter break; 361518334Speter 361618334Speter code = GET_CODE (x); 361718334Speter 361818334Speter /* We no longer know the original mode of operand 0 since we 361918334Speter have changed the form of X) */ 362018334Speter op0_mode = VOIDmode; 362118334Speter } 362218334Speter 362318334Speter return x; 362418334Speter} 362518334Speter 362618334Speter/* Simplify X, a piece of RTL. We just operate on the expression at the 362718334Speter outer level; call `subst' to simplify recursively. Return the new 362818334Speter expression. 362918334Speter 363018334Speter OP0_MODE is the original mode of XEXP (x, 0); LAST is nonzero if this 363118334Speter will be the iteration even if an expression with a code different from 363218334Speter X is returned; IN_DEST is nonzero if we are inside a SET_DEST. */ 363318334Speter 363418334Speterstatic rtx 363590075Sobriencombine_simplify_rtx (x, op0_mode, last, in_dest) 363618334Speter rtx x; 363718334Speter enum machine_mode op0_mode; 363818334Speter int last; 363918334Speter int in_dest; 364018334Speter{ 364118334Speter enum rtx_code code = GET_CODE (x); 364218334Speter enum machine_mode mode = GET_MODE (x); 364318334Speter rtx temp; 364490075Sobrien rtx reversed; 364518334Speter int i; 364618334Speter 364718334Speter /* If this is a commutative operation, put a constant last and a complex 364818334Speter expression first. We don't need to do this for comparisons here. */ 364918334Speter if (GET_RTX_CLASS (code) == 'c' 365090075Sobrien && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1))) 365118334Speter { 365218334Speter temp = XEXP (x, 0); 365318334Speter SUBST (XEXP (x, 0), XEXP (x, 1)); 365418334Speter SUBST (XEXP (x, 1), temp); 365518334Speter } 365618334Speter 365718334Speter /* If this is a PLUS, MINUS, or MULT, and the first operand is the 365818334Speter sign extension of a PLUS with a constant, reverse the order of the sign 365918334Speter extension and the addition. Note that this not the same as the original 366018334Speter code, but overflow is undefined for signed values. Also note that the 366118334Speter PLUS will have been partially moved "inside" the sign-extension, so that 366218334Speter the first operand of X will really look like: 366318334Speter (ashiftrt (plus (ashift A C4) C5) C4). 366418334Speter We convert this to 366518334Speter (plus (ashiftrt (ashift A C4) C2) C4) 366618334Speter and replace the first operand of X with that expression. Later parts 366718334Speter of this function may simplify the expression further. 366818334Speter 366918334Speter For example, if we start with (mult (sign_extend (plus A C1)) C2), 367018334Speter we swap the SIGN_EXTEND and PLUS. Later code will apply the 367118334Speter distributive law to produce (plus (mult (sign_extend X) C1) C3). 367218334Speter 367318334Speter We do this to simplify address expressions. */ 367418334Speter 367518334Speter if ((code == PLUS || code == MINUS || code == MULT) 367618334Speter && GET_CODE (XEXP (x, 0)) == ASHIFTRT 367718334Speter && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS 367818334Speter && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ASHIFT 367918334Speter && GET_CODE (XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 1)) == CONST_INT 368018334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 368118334Speter && XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 1) == XEXP (XEXP (x, 0), 1) 368218334Speter && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT 368318334Speter && (temp = simplify_binary_operation (ASHIFTRT, mode, 368418334Speter XEXP (XEXP (XEXP (x, 0), 0), 1), 368518334Speter XEXP (XEXP (x, 0), 1))) != 0) 368618334Speter { 368718334Speter rtx new 368818334Speter = simplify_shift_const (NULL_RTX, ASHIFT, mode, 368918334Speter XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 0), 369018334Speter INTVAL (XEXP (XEXP (x, 0), 1))); 369118334Speter 369218334Speter new = simplify_shift_const (NULL_RTX, ASHIFTRT, mode, new, 369318334Speter INTVAL (XEXP (XEXP (x, 0), 1))); 369418334Speter 369518334Speter SUBST (XEXP (x, 0), gen_binary (PLUS, mode, new, temp)); 369618334Speter } 369718334Speter 369890075Sobrien /* If this is a simple operation applied to an IF_THEN_ELSE, try 369918334Speter applying it to the arms of the IF_THEN_ELSE. This often simplifies 370018334Speter things. Check for cases where both arms are testing the same 370118334Speter condition. 370218334Speter 370318334Speter Don't do anything if all operands are very simple. */ 370418334Speter 370518334Speter if (((GET_RTX_CLASS (code) == '2' || GET_RTX_CLASS (code) == 'c' 370618334Speter || GET_RTX_CLASS (code) == '<') 370718334Speter && ((GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) != 'o' 370818334Speter && ! (GET_CODE (XEXP (x, 0)) == SUBREG 370918334Speter && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0)))) 371018334Speter == 'o'))) 371118334Speter || (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) != 'o' 371218334Speter && ! (GET_CODE (XEXP (x, 1)) == SUBREG 371318334Speter && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 1)))) 371418334Speter == 'o'))))) 371518334Speter || (GET_RTX_CLASS (code) == '1' 371618334Speter && ((GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) != 'o' 371718334Speter && ! (GET_CODE (XEXP (x, 0)) == SUBREG 371818334Speter && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0)))) 371918334Speter == 'o')))))) 372018334Speter { 372190075Sobrien rtx cond, true_rtx, false_rtx; 372218334Speter 372390075Sobrien cond = if_then_else_cond (x, &true_rtx, &false_rtx); 372450397Sobrien if (cond != 0 372550397Sobrien /* If everything is a comparison, what we have is highly unlikely 372650397Sobrien to be simpler, so don't use it. */ 372750397Sobrien && ! (GET_RTX_CLASS (code) == '<' 372890075Sobrien && (GET_RTX_CLASS (GET_CODE (true_rtx)) == '<' 372990075Sobrien || GET_RTX_CLASS (GET_CODE (false_rtx)) == '<'))) 373018334Speter { 373118334Speter rtx cop1 = const0_rtx; 373218334Speter enum rtx_code cond_code = simplify_comparison (NE, &cond, &cop1); 373318334Speter 373418334Speter if (cond_code == NE && GET_RTX_CLASS (GET_CODE (cond)) == '<') 373518334Speter return x; 373618334Speter 373790075Sobrien /* Simplify the alternative arms; this may collapse the true and 373818334Speter false arms to store-flag values. */ 373990075Sobrien true_rtx = subst (true_rtx, pc_rtx, pc_rtx, 0, 0); 374090075Sobrien false_rtx = subst (false_rtx, pc_rtx, pc_rtx, 0, 0); 374118334Speter 374290075Sobrien /* If true_rtx and false_rtx are not general_operands, an if_then_else 374390075Sobrien is unlikely to be simpler. */ 374490075Sobrien if (general_operand (true_rtx, VOIDmode) 374590075Sobrien && general_operand (false_rtx, VOIDmode)) 374690075Sobrien { 374790075Sobrien /* Restarting if we generate a store-flag expression will cause 374890075Sobrien us to loop. Just drop through in this case. */ 374918334Speter 375090075Sobrien /* If the result values are STORE_FLAG_VALUE and zero, we can 375190075Sobrien just make the comparison operation. */ 375290075Sobrien if (true_rtx == const_true_rtx && false_rtx == const0_rtx) 375390075Sobrien x = gen_binary (cond_code, mode, cond, cop1); 375490075Sobrien else if (true_rtx == const0_rtx && false_rtx == const_true_rtx 375590075Sobrien && reverse_condition (cond_code) != UNKNOWN) 375690075Sobrien x = gen_binary (reverse_condition (cond_code), 375790075Sobrien mode, cond, cop1); 375818334Speter 375990075Sobrien /* Likewise, we can make the negate of a comparison operation 376090075Sobrien if the result values are - STORE_FLAG_VALUE and zero. */ 376190075Sobrien else if (GET_CODE (true_rtx) == CONST_INT 376290075Sobrien && INTVAL (true_rtx) == - STORE_FLAG_VALUE 376390075Sobrien && false_rtx == const0_rtx) 376490075Sobrien x = simplify_gen_unary (NEG, mode, 376590075Sobrien gen_binary (cond_code, mode, cond, 376690075Sobrien cop1), 376790075Sobrien mode); 376890075Sobrien else if (GET_CODE (false_rtx) == CONST_INT 376990075Sobrien && INTVAL (false_rtx) == - STORE_FLAG_VALUE 377090075Sobrien && true_rtx == const0_rtx) 377190075Sobrien x = simplify_gen_unary (NEG, mode, 377290075Sobrien gen_binary (reverse_condition 377390075Sobrien (cond_code), 377490075Sobrien mode, cond, cop1), 377590075Sobrien mode); 377690075Sobrien else 377790075Sobrien return gen_rtx_IF_THEN_ELSE (mode, 377890075Sobrien gen_binary (cond_code, VOIDmode, 377990075Sobrien cond, cop1), 378090075Sobrien true_rtx, false_rtx); 378118334Speter 378290075Sobrien code = GET_CODE (x); 378390075Sobrien op0_mode = VOIDmode; 378490075Sobrien } 378518334Speter } 378618334Speter } 378718334Speter 378818334Speter /* Try to fold this expression in case we have constants that weren't 378918334Speter present before. */ 379018334Speter temp = 0; 379118334Speter switch (GET_RTX_CLASS (code)) 379218334Speter { 379318334Speter case '1': 379418334Speter temp = simplify_unary_operation (code, mode, XEXP (x, 0), op0_mode); 379518334Speter break; 379618334Speter case '<': 379790075Sobrien { 379890075Sobrien enum machine_mode cmp_mode = GET_MODE (XEXP (x, 0)); 379990075Sobrien if (cmp_mode == VOIDmode) 380090075Sobrien { 380190075Sobrien cmp_mode = GET_MODE (XEXP (x, 1)); 380290075Sobrien if (cmp_mode == VOIDmode) 380390075Sobrien cmp_mode = op0_mode; 380490075Sobrien } 380590075Sobrien temp = simplify_relational_operation (code, cmp_mode, 380690075Sobrien XEXP (x, 0), XEXP (x, 1)); 380790075Sobrien } 380818334Speter#ifdef FLOAT_STORE_FLAG_VALUE 380990075Sobrien if (temp != 0 && GET_MODE_CLASS (mode) == MODE_FLOAT) 381090075Sobrien { 381190075Sobrien if (temp == const0_rtx) 381290075Sobrien temp = CONST0_RTX (mode); 381390075Sobrien else 3814117395Skan temp = CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE (mode), 3815117395Skan mode); 381690075Sobrien } 381718334Speter#endif 381818334Speter break; 381918334Speter case 'c': 382018334Speter case '2': 382118334Speter temp = simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1)); 382218334Speter break; 382318334Speter case 'b': 382418334Speter case '3': 382518334Speter temp = simplify_ternary_operation (code, mode, op0_mode, XEXP (x, 0), 382618334Speter XEXP (x, 1), XEXP (x, 2)); 382718334Speter break; 382818334Speter } 382918334Speter 383018334Speter if (temp) 383190075Sobrien { 383290075Sobrien x = temp; 383390075Sobrien code = GET_CODE (temp); 383490075Sobrien op0_mode = VOIDmode; 383590075Sobrien mode = GET_MODE (temp); 383690075Sobrien } 383718334Speter 383818334Speter /* First see if we can apply the inverse distributive law. */ 383918334Speter if (code == PLUS || code == MINUS 384018334Speter || code == AND || code == IOR || code == XOR) 384118334Speter { 384218334Speter x = apply_distributive_law (x); 384318334Speter code = GET_CODE (x); 384490075Sobrien op0_mode = VOIDmode; 384518334Speter } 384618334Speter 384718334Speter /* If CODE is an associative operation not otherwise handled, see if we 384818334Speter can associate some operands. This can win if they are constants or 384990075Sobrien if they are logically related (i.e. (a & b) & a). */ 385090075Sobrien if ((code == PLUS || code == MINUS || code == MULT || code == DIV 385190075Sobrien || code == AND || code == IOR || code == XOR 385218334Speter || code == SMAX || code == SMIN || code == UMAX || code == UMIN) 385390075Sobrien && ((INTEGRAL_MODE_P (mode) && code != DIV) 385490075Sobrien || (flag_unsafe_math_optimizations && FLOAT_MODE_P (mode)))) 385518334Speter { 385618334Speter if (GET_CODE (XEXP (x, 0)) == code) 385718334Speter { 385818334Speter rtx other = XEXP (XEXP (x, 0), 0); 385918334Speter rtx inner_op0 = XEXP (XEXP (x, 0), 1); 386018334Speter rtx inner_op1 = XEXP (x, 1); 386118334Speter rtx inner; 386290075Sobrien 386318334Speter /* Make sure we pass the constant operand if any as the second 386418334Speter one if this is a commutative operation. */ 386518334Speter if (CONSTANT_P (inner_op0) && GET_RTX_CLASS (code) == 'c') 386618334Speter { 386718334Speter rtx tem = inner_op0; 386818334Speter inner_op0 = inner_op1; 386918334Speter inner_op1 = tem; 387018334Speter } 387118334Speter inner = simplify_binary_operation (code == MINUS ? PLUS 387218334Speter : code == DIV ? MULT 387318334Speter : code, 387418334Speter mode, inner_op0, inner_op1); 387518334Speter 387618334Speter /* For commutative operations, try the other pair if that one 387718334Speter didn't simplify. */ 387818334Speter if (inner == 0 && GET_RTX_CLASS (code) == 'c') 387918334Speter { 388018334Speter other = XEXP (XEXP (x, 0), 1); 388118334Speter inner = simplify_binary_operation (code, mode, 388218334Speter XEXP (XEXP (x, 0), 0), 388318334Speter XEXP (x, 1)); 388418334Speter } 388518334Speter 388618334Speter if (inner) 388718334Speter return gen_binary (code, mode, other, inner); 388818334Speter } 388918334Speter } 389018334Speter 389118334Speter /* A little bit of algebraic simplification here. */ 389218334Speter switch (code) 389318334Speter { 389418334Speter case MEM: 389518334Speter /* Ensure that our address has any ASHIFTs converted to MULT in case 389618334Speter address-recognizing predicates are called later. */ 389718334Speter temp = make_compound_operation (XEXP (x, 0), MEM); 389818334Speter SUBST (XEXP (x, 0), temp); 389918334Speter break; 390018334Speter 390118334Speter case SUBREG: 390290075Sobrien if (op0_mode == VOIDmode) 390390075Sobrien op0_mode = GET_MODE (SUBREG_REG (x)); 390418334Speter 390590075Sobrien /* simplify_subreg can't use gen_lowpart_for_combine. */ 390650397Sobrien if (CONSTANT_P (SUBREG_REG (x)) 3907117395Skan && subreg_lowpart_offset (mode, op0_mode) == SUBREG_BYTE (x) 3908117395Skan /* Don't call gen_lowpart_for_combine if the inner mode 3909117395Skan is VOIDmode and we cannot simplify it, as SUBREG without 3910117395Skan inner mode is invalid. */ 3911117395Skan && (GET_MODE (SUBREG_REG (x)) != VOIDmode 3912117395Skan || gen_lowpart_common (mode, SUBREG_REG (x)))) 391318334Speter return gen_lowpart_for_combine (mode, SUBREG_REG (x)); 391418334Speter 391590075Sobrien if (GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_CC) 391690075Sobrien break; 391790075Sobrien { 391890075Sobrien rtx temp; 391990075Sobrien temp = simplify_subreg (mode, SUBREG_REG (x), op0_mode, 392090075Sobrien SUBREG_BYTE (x)); 392190075Sobrien if (temp) 392290075Sobrien return temp; 392390075Sobrien } 392418334Speter 392596263Sobrien /* Don't change the mode of the MEM if that would change the meaning 392696263Sobrien of the address. */ 392796263Sobrien if (GET_CODE (SUBREG_REG (x)) == MEM 392896263Sobrien && (MEM_VOLATILE_P (SUBREG_REG (x)) 392996263Sobrien || mode_dependent_address_p (XEXP (SUBREG_REG (x), 0)))) 393096263Sobrien return gen_rtx_CLOBBER (mode, const0_rtx); 393196263Sobrien 393218334Speter /* Note that we cannot do any narrowing for non-constants since 393318334Speter we might have been counting on using the fact that some bits were 393418334Speter zero. We now do this in the SET. */ 393518334Speter 393618334Speter break; 393718334Speter 393818334Speter case NOT: 393918334Speter /* (not (plus X -1)) can become (neg X). */ 394018334Speter if (GET_CODE (XEXP (x, 0)) == PLUS 394118334Speter && XEXP (XEXP (x, 0), 1) == constm1_rtx) 394290075Sobrien return gen_rtx_NEG (mode, XEXP (XEXP (x, 0), 0)); 394318334Speter 394418334Speter /* Similarly, (not (neg X)) is (plus X -1). */ 394518334Speter if (GET_CODE (XEXP (x, 0)) == NEG) 394690075Sobrien return gen_rtx_PLUS (mode, XEXP (XEXP (x, 0), 0), constm1_rtx); 394718334Speter 394890075Sobrien /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */ 394918334Speter if (GET_CODE (XEXP (x, 0)) == XOR 395018334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 395118334Speter && (temp = simplify_unary_operation (NOT, mode, 395218334Speter XEXP (XEXP (x, 0), 1), 395318334Speter mode)) != 0) 395418334Speter return gen_binary (XOR, mode, XEXP (XEXP (x, 0), 0), temp); 395590075Sobrien 395618334Speter /* (not (ashift 1 X)) is (rotate ~1 X). We used to do this for operands 395718334Speter other than 1, but that is not valid. We could do a similar 395818334Speter simplification for (not (lshiftrt C X)) where C is just the sign bit, 395918334Speter but this doesn't seem common enough to bother with. */ 396018334Speter if (GET_CODE (XEXP (x, 0)) == ASHIFT 396118334Speter && XEXP (XEXP (x, 0), 0) == const1_rtx) 396290075Sobrien return gen_rtx_ROTATE (mode, simplify_gen_unary (NOT, mode, 396390075Sobrien const1_rtx, mode), 396450397Sobrien XEXP (XEXP (x, 0), 1)); 396590075Sobrien 396618334Speter if (GET_CODE (XEXP (x, 0)) == SUBREG 396718334Speter && subreg_lowpart_p (XEXP (x, 0)) 396818334Speter && (GET_MODE_SIZE (GET_MODE (XEXP (x, 0))) 396918334Speter < GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (x, 0))))) 397018334Speter && GET_CODE (SUBREG_REG (XEXP (x, 0))) == ASHIFT 397118334Speter && XEXP (SUBREG_REG (XEXP (x, 0)), 0) == const1_rtx) 397218334Speter { 397318334Speter enum machine_mode inner_mode = GET_MODE (SUBREG_REG (XEXP (x, 0))); 397418334Speter 397550397Sobrien x = gen_rtx_ROTATE (inner_mode, 397690075Sobrien simplify_gen_unary (NOT, inner_mode, const1_rtx, 397790075Sobrien inner_mode), 397850397Sobrien XEXP (SUBREG_REG (XEXP (x, 0)), 1)); 397918334Speter return gen_lowpart_for_combine (mode, x); 398018334Speter } 398190075Sobrien 398250397Sobrien /* If STORE_FLAG_VALUE is -1, (not (comparison foo bar)) can be done by 398350397Sobrien reversing the comparison code if valid. */ 398450397Sobrien if (STORE_FLAG_VALUE == -1 398550397Sobrien && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<' 398690075Sobrien && (reversed = reversed_comparison (x, mode, XEXP (XEXP (x, 0), 0), 398790075Sobrien XEXP (XEXP (x, 0), 1)))) 398890075Sobrien return reversed; 398918334Speter 399090075Sobrien /* (not (ashiftrt foo C)) where C is the number of bits in FOO minus 1 399190075Sobrien is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1, so we can 399250397Sobrien perform the above simplification. */ 399318334Speter 399450397Sobrien if (STORE_FLAG_VALUE == -1 399518334Speter && GET_CODE (XEXP (x, 0)) == ASHIFTRT 399618334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 399718334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) == GET_MODE_BITSIZE (mode) - 1) 399890075Sobrien return gen_rtx_GE (mode, XEXP (XEXP (x, 0), 0), const0_rtx); 399918334Speter 400018334Speter /* Apply De Morgan's laws to reduce number of patterns for machines 400190075Sobrien with negating logical insns (and-not, nand, etc.). If result has 400290075Sobrien only one NOT, put it first, since that is how the patterns are 400390075Sobrien coded. */ 400418334Speter 400518334Speter if (GET_CODE (XEXP (x, 0)) == IOR || GET_CODE (XEXP (x, 0)) == AND) 400690075Sobrien { 400790075Sobrien rtx in1 = XEXP (XEXP (x, 0), 0), in2 = XEXP (XEXP (x, 0), 1); 400890075Sobrien enum machine_mode op_mode; 400918334Speter 401090075Sobrien op_mode = GET_MODE (in1); 401190075Sobrien in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode); 401218334Speter 401390075Sobrien op_mode = GET_MODE (in2); 401490075Sobrien if (op_mode == VOIDmode) 401590075Sobrien op_mode = mode; 401690075Sobrien in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode); 401718334Speter 401890075Sobrien if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT) 401990075Sobrien { 402090075Sobrien rtx tem = in2; 402190075Sobrien in2 = in1; in1 = tem; 402290075Sobrien } 402318334Speter 402490075Sobrien return gen_rtx_fmt_ee (GET_CODE (XEXP (x, 0)) == IOR ? AND : IOR, 402518334Speter mode, in1, in2); 402690075Sobrien } 402718334Speter break; 402818334Speter 402918334Speter case NEG: 403018334Speter /* (neg (plus X 1)) can become (not X). */ 403118334Speter if (GET_CODE (XEXP (x, 0)) == PLUS 403218334Speter && XEXP (XEXP (x, 0), 1) == const1_rtx) 403390075Sobrien return gen_rtx_NOT (mode, XEXP (XEXP (x, 0), 0)); 403418334Speter 403518334Speter /* Similarly, (neg (not X)) is (plus X 1). */ 403618334Speter if (GET_CODE (XEXP (x, 0)) == NOT) 403718334Speter return plus_constant (XEXP (XEXP (x, 0), 0), 1); 403818334Speter 4039117395Skan /* (neg (minus X Y)) can become (minus Y X). This transformation 4040117395Skan isn't safe for modes with signed zeros, since if X and Y are 4041117395Skan both +0, (minus Y X) is the same as (minus X Y). If the rounding 4042117395Skan mode is towards +infinity (or -infinity) then the two expressions 4043117395Skan will be rounded differently. */ 404418334Speter if (GET_CODE (XEXP (x, 0)) == MINUS 4045117395Skan && !HONOR_SIGNED_ZEROS (mode) 4046117395Skan && !HONOR_SIGN_DEPENDENT_ROUNDING (mode)) 404718334Speter return gen_binary (MINUS, mode, XEXP (XEXP (x, 0), 1), 404818334Speter XEXP (XEXP (x, 0), 0)); 404918334Speter 4050117395Skan /* (neg (plus A B)) is canonicalized to (minus (neg A) B). */ 4051117395Skan if (GET_CODE (XEXP (x, 0)) == PLUS 4052117395Skan && !HONOR_SIGNED_ZEROS (mode) 4053117395Skan && !HONOR_SIGN_DEPENDENT_ROUNDING (mode)) 4054117395Skan { 4055117395Skan temp = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 0), 0), mode); 4056117395Skan temp = combine_simplify_rtx (temp, mode, last, in_dest); 4057117395Skan return gen_binary (MINUS, mode, temp, XEXP (XEXP (x, 0), 1)); 4058117395Skan } 4059117395Skan 4060117395Skan /* (neg (mult A B)) becomes (mult (neg A) B). 4061117395Skan This works even for floating-point values. */ 4062117395Skan if (GET_CODE (XEXP (x, 0)) == MULT) 4063117395Skan { 4064117395Skan temp = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 0), 0), mode); 4065117395Skan return gen_binary (MULT, mode, temp, XEXP (XEXP (x, 0), 1)); 4066117395Skan } 4067117395Skan 406850397Sobrien /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */ 406918334Speter if (GET_CODE (XEXP (x, 0)) == XOR && XEXP (XEXP (x, 0), 1) == const1_rtx 407018334Speter && nonzero_bits (XEXP (XEXP (x, 0), 0), mode) == 1) 407118334Speter return gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0), constm1_rtx); 407218334Speter 407318334Speter /* NEG commutes with ASHIFT since it is multiplication. Only do this 407418334Speter if we can then eliminate the NEG (e.g., 407518334Speter if the operand is a constant). */ 407618334Speter 407718334Speter if (GET_CODE (XEXP (x, 0)) == ASHIFT) 407818334Speter { 407918334Speter temp = simplify_unary_operation (NEG, mode, 408018334Speter XEXP (XEXP (x, 0), 0), mode); 408118334Speter if (temp) 408290075Sobrien return gen_binary (ASHIFT, mode, temp, XEXP (XEXP (x, 0), 1)); 408318334Speter } 408418334Speter 408518334Speter temp = expand_compound_operation (XEXP (x, 0)); 408618334Speter 408718334Speter /* For C equal to the width of MODE minus 1, (neg (ashiftrt X C)) can be 408890075Sobrien replaced by (lshiftrt X C). This will convert 408918334Speter (neg (sign_extract X 1 Y)) to (zero_extract X 1 Y). */ 409018334Speter 409118334Speter if (GET_CODE (temp) == ASHIFTRT 409218334Speter && GET_CODE (XEXP (temp, 1)) == CONST_INT 409318334Speter && INTVAL (XEXP (temp, 1)) == GET_MODE_BITSIZE (mode) - 1) 409418334Speter return simplify_shift_const (temp, LSHIFTRT, mode, XEXP (temp, 0), 409518334Speter INTVAL (XEXP (temp, 1))); 409618334Speter 409718334Speter /* If X has only a single bit that might be nonzero, say, bit I, convert 409818334Speter (neg X) to (ashiftrt (ashift X C-I) C-I) where C is the bitsize of 409918334Speter MODE minus 1. This will convert (neg (zero_extract X 1 Y)) to 410018334Speter (sign_extract X 1 Y). But only do this if TEMP isn't a register 410118334Speter or a SUBREG of one since we'd be making the expression more 410218334Speter complex if it was just a register. */ 410318334Speter 410418334Speter if (GET_CODE (temp) != REG 410518334Speter && ! (GET_CODE (temp) == SUBREG 410618334Speter && GET_CODE (SUBREG_REG (temp)) == REG) 410718334Speter && (i = exact_log2 (nonzero_bits (temp, mode))) >= 0) 410818334Speter { 410918334Speter rtx temp1 = simplify_shift_const 411018334Speter (NULL_RTX, ASHIFTRT, mode, 411118334Speter simplify_shift_const (NULL_RTX, ASHIFT, mode, temp, 411218334Speter GET_MODE_BITSIZE (mode) - 1 - i), 411318334Speter GET_MODE_BITSIZE (mode) - 1 - i); 411418334Speter 411518334Speter /* If all we did was surround TEMP with the two shifts, we 411618334Speter haven't improved anything, so don't use it. Otherwise, 411718334Speter we are better off with TEMP1. */ 411818334Speter if (GET_CODE (temp1) != ASHIFTRT 411918334Speter || GET_CODE (XEXP (temp1, 0)) != ASHIFT 412018334Speter || XEXP (XEXP (temp1, 0), 0) != temp) 412118334Speter return temp1; 412218334Speter } 412318334Speter break; 412418334Speter 412518334Speter case TRUNCATE: 412650397Sobrien /* We can't handle truncation to a partial integer mode here 412750397Sobrien because we don't know the real bitsize of the partial 412850397Sobrien integer mode. */ 412950397Sobrien if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT) 413050397Sobrien break; 413150397Sobrien 413250397Sobrien if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 413350397Sobrien && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode), 413450397Sobrien GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))))) 413518334Speter SUBST (XEXP (x, 0), 413618334Speter force_to_mode (XEXP (x, 0), GET_MODE (XEXP (x, 0)), 413718334Speter GET_MODE_MASK (mode), NULL_RTX, 0)); 413850397Sobrien 413950397Sobrien /* (truncate:SI ({sign,zero}_extend:DI foo:SI)) == foo:SI. */ 414050397Sobrien if ((GET_CODE (XEXP (x, 0)) == SIGN_EXTEND 414150397Sobrien || GET_CODE (XEXP (x, 0)) == ZERO_EXTEND) 414250397Sobrien && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode) 414350397Sobrien return XEXP (XEXP (x, 0), 0); 414450397Sobrien 414550397Sobrien /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is 414650397Sobrien (OP:SI foo:SI) if OP is NEG or ABS. */ 414750397Sobrien if ((GET_CODE (XEXP (x, 0)) == ABS 414850397Sobrien || GET_CODE (XEXP (x, 0)) == NEG) 414950397Sobrien && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SIGN_EXTEND 415050397Sobrien || GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND) 415150397Sobrien && GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == mode) 415290075Sobrien return simplify_gen_unary (GET_CODE (XEXP (x, 0)), mode, 415390075Sobrien XEXP (XEXP (XEXP (x, 0), 0), 0), mode); 415450397Sobrien 415550397Sobrien /* (truncate:SI (subreg:DI (truncate:SI X) 0)) is 415650397Sobrien (truncate:SI x). */ 415750397Sobrien if (GET_CODE (XEXP (x, 0)) == SUBREG 415850397Sobrien && GET_CODE (SUBREG_REG (XEXP (x, 0))) == TRUNCATE 415950397Sobrien && subreg_lowpart_p (XEXP (x, 0))) 416050397Sobrien return SUBREG_REG (XEXP (x, 0)); 416150397Sobrien 416250397Sobrien /* If we know that the value is already truncated, we can 416390075Sobrien replace the TRUNCATE with a SUBREG if TRULY_NOOP_TRUNCATION 416490075Sobrien is nonzero for the corresponding modes. But don't do this 416590075Sobrien for an (LSHIFTRT (MULT ...)) since this will cause problems 416690075Sobrien with the umulXi3_highpart patterns. */ 416752284Sobrien if (TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode), 416852284Sobrien GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))) 416952284Sobrien && num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0))) 4170117395Skan >= (unsigned int) (GET_MODE_BITSIZE (mode) + 1) 417190075Sobrien && ! (GET_CODE (XEXP (x, 0)) == LSHIFTRT 417290075Sobrien && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT)) 417350397Sobrien return gen_lowpart_for_combine (mode, XEXP (x, 0)); 417450397Sobrien 417550397Sobrien /* A truncate of a comparison can be replaced with a subreg if 417650397Sobrien STORE_FLAG_VALUE permits. This is like the previous test, 417750397Sobrien but it works even if the comparison is done in a mode larger 417850397Sobrien than HOST_BITS_PER_WIDE_INT. */ 417950397Sobrien if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 418050397Sobrien && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<' 418190075Sobrien && ((HOST_WIDE_INT) STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0) 418250397Sobrien return gen_lowpart_for_combine (mode, XEXP (x, 0)); 418350397Sobrien 418450397Sobrien /* Similarly, a truncate of a register whose value is a 418550397Sobrien comparison can be replaced with a subreg if STORE_FLAG_VALUE 418650397Sobrien permits. */ 418750397Sobrien if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 418890075Sobrien && ((HOST_WIDE_INT) STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0 418950397Sobrien && (temp = get_last_value (XEXP (x, 0))) 419050397Sobrien && GET_RTX_CLASS (GET_CODE (temp)) == '<') 419150397Sobrien return gen_lowpart_for_combine (mode, XEXP (x, 0)); 419250397Sobrien 419318334Speter break; 419418334Speter 419518334Speter case FLOAT_TRUNCATE: 419618334Speter /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */ 419718334Speter if (GET_CODE (XEXP (x, 0)) == FLOAT_EXTEND 419818334Speter && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode) 419990075Sobrien return XEXP (XEXP (x, 0), 0); 420018334Speter 420118334Speter /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is 420218334Speter (OP:SF foo:SF) if OP is NEG or ABS. */ 420318334Speter if ((GET_CODE (XEXP (x, 0)) == ABS 420418334Speter || GET_CODE (XEXP (x, 0)) == NEG) 420518334Speter && GET_CODE (XEXP (XEXP (x, 0), 0)) == FLOAT_EXTEND 420618334Speter && GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == mode) 420790075Sobrien return simplify_gen_unary (GET_CODE (XEXP (x, 0)), mode, 420890075Sobrien XEXP (XEXP (XEXP (x, 0), 0), 0), mode); 420918334Speter 421018334Speter /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0)) 421118334Speter is (float_truncate:SF x). */ 421218334Speter if (GET_CODE (XEXP (x, 0)) == SUBREG 421318334Speter && subreg_lowpart_p (XEXP (x, 0)) 421418334Speter && GET_CODE (SUBREG_REG (XEXP (x, 0))) == FLOAT_TRUNCATE) 421518334Speter return SUBREG_REG (XEXP (x, 0)); 421690075Sobrien break; 421718334Speter 421818334Speter#ifdef HAVE_cc0 421918334Speter case COMPARE: 422018334Speter /* Convert (compare FOO (const_int 0)) to FOO unless we aren't 422118334Speter using cc0, in which case we want to leave it as a COMPARE 422218334Speter so we can distinguish it from a register-register-copy. */ 422318334Speter if (XEXP (x, 1) == const0_rtx) 422418334Speter return XEXP (x, 0); 422518334Speter 4226117395Skan /* x - 0 is the same as x unless x's mode has signed zeros and 4227117395Skan allows rounding towards -infinity. Under those conditions, 4228117395Skan 0 - 0 is -0. */ 4229117395Skan if (!(HONOR_SIGNED_ZEROS (GET_MODE (XEXP (x, 0))) 4230117395Skan && HONOR_SIGN_DEPENDENT_ROUNDING (GET_MODE (XEXP (x, 0)))) 423118334Speter && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 0)))) 423218334Speter return XEXP (x, 0); 423318334Speter break; 423418334Speter#endif 423518334Speter 423618334Speter case CONST: 423718334Speter /* (const (const X)) can become (const X). Do it this way rather than 423818334Speter returning the inner CONST since CONST can be shared with a 423918334Speter REG_EQUAL note. */ 424018334Speter if (GET_CODE (XEXP (x, 0)) == CONST) 424118334Speter SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0)); 424218334Speter break; 424318334Speter 424418334Speter#ifdef HAVE_lo_sum 424518334Speter case LO_SUM: 424618334Speter /* Convert (lo_sum (high FOO) FOO) to FOO. This is necessary so we 424718334Speter can add in an offset. find_split_point will split this address up 424818334Speter again if it doesn't match. */ 424918334Speter if (GET_CODE (XEXP (x, 0)) == HIGH 425018334Speter && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1))) 425118334Speter return XEXP (x, 1); 425218334Speter break; 425318334Speter#endif 425418334Speter 425518334Speter case PLUS: 4256117395Skan /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). 4257117395Skan */ 4258117395Skan if (GET_CODE (XEXP (x, 0)) == MULT 4259117395Skan && GET_CODE (XEXP (XEXP (x, 0), 0)) == NEG) 4260117395Skan { 4261117395Skan rtx in1, in2; 4262117395Skan 4263117395Skan in1 = XEXP (XEXP (XEXP (x, 0), 0), 0); 4264117395Skan in2 = XEXP (XEXP (x, 0), 1); 4265117395Skan return gen_binary (MINUS, mode, XEXP (x, 1), 4266117395Skan gen_binary (MULT, mode, in1, in2)); 4267117395Skan } 4268117395Skan 426918334Speter /* If we have (plus (plus (A const) B)), associate it so that CONST is 427018334Speter outermost. That's because that's the way indexed addresses are 427118334Speter supposed to appear. This code used to check many more cases, but 427218334Speter they are now checked elsewhere. */ 427318334Speter if (GET_CODE (XEXP (x, 0)) == PLUS 427418334Speter && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1))) 427518334Speter return gen_binary (PLUS, mode, 427618334Speter gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0), 427718334Speter XEXP (x, 1)), 427818334Speter XEXP (XEXP (x, 0), 1)); 427918334Speter 428018334Speter /* (plus (xor (and <foo> (const_int pow2 - 1)) <c>) <-c>) 428118334Speter when c is (const_int (pow2 + 1) / 2) is a sign extension of a 428218334Speter bit-field and can be replaced by either a sign_extend or a 428390075Sobrien sign_extract. The `and' may be a zero_extend and the two 428490075Sobrien <c>, -<c> constants may be reversed. */ 428518334Speter if (GET_CODE (XEXP (x, 0)) == XOR 428618334Speter && GET_CODE (XEXP (x, 1)) == CONST_INT 428718334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 428890075Sobrien && INTVAL (XEXP (x, 1)) == -INTVAL (XEXP (XEXP (x, 0), 1)) 428990075Sobrien && ((i = exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) >= 0 429090075Sobrien || (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0) 429118334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 429218334Speter && ((GET_CODE (XEXP (XEXP (x, 0), 0)) == AND 429318334Speter && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT 429418334Speter && (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)) 429518334Speter == ((HOST_WIDE_INT) 1 << (i + 1)) - 1)) 429618334Speter || (GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND 429718334Speter && (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0))) 429890075Sobrien == (unsigned int) i + 1)))) 429918334Speter return simplify_shift_const 430018334Speter (NULL_RTX, ASHIFTRT, mode, 430118334Speter simplify_shift_const (NULL_RTX, ASHIFT, mode, 430218334Speter XEXP (XEXP (XEXP (x, 0), 0), 0), 430318334Speter GET_MODE_BITSIZE (mode) - (i + 1)), 430418334Speter GET_MODE_BITSIZE (mode) - (i + 1)); 430518334Speter 430618334Speter /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if 430718334Speter C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE 430818334Speter is 1. This produces better code than the alternative immediately 430918334Speter below. */ 431018334Speter if (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<' 431118334Speter && ((STORE_FLAG_VALUE == -1 && XEXP (x, 1) == const1_rtx) 431290075Sobrien || (STORE_FLAG_VALUE == 1 && XEXP (x, 1) == constm1_rtx)) 431390075Sobrien && (reversed = reversed_comparison (XEXP (x, 0), mode, 431490075Sobrien XEXP (XEXP (x, 0), 0), 431590075Sobrien XEXP (XEXP (x, 0), 1)))) 431618334Speter return 431790075Sobrien simplify_gen_unary (NEG, mode, reversed, mode); 431818334Speter 431918334Speter /* If only the low-order bit of X is possibly nonzero, (plus x -1) 432018334Speter can become (ashiftrt (ashift (xor x 1) C) C) where C is 432118334Speter the bitsize of the mode - 1. This allows simplification of 432218334Speter "a = (b & 8) == 0;" */ 432318334Speter if (XEXP (x, 1) == constm1_rtx 432418334Speter && GET_CODE (XEXP (x, 0)) != REG 432518334Speter && ! (GET_CODE (XEXP (x,0)) == SUBREG 432618334Speter && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG) 432718334Speter && nonzero_bits (XEXP (x, 0), mode) == 1) 432818334Speter return simplify_shift_const (NULL_RTX, ASHIFTRT, mode, 432918334Speter simplify_shift_const (NULL_RTX, ASHIFT, mode, 433090075Sobrien gen_rtx_XOR (mode, XEXP (x, 0), const1_rtx), 433118334Speter GET_MODE_BITSIZE (mode) - 1), 433218334Speter GET_MODE_BITSIZE (mode) - 1); 433318334Speter 433418334Speter /* If we are adding two things that have no bits in common, convert 433518334Speter the addition into an IOR. This will often be further simplified, 433618334Speter for example in cases like ((a & 1) + (a & 2)), which can 433718334Speter become a & 3. */ 433818334Speter 433918334Speter if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 434018334Speter && (nonzero_bits (XEXP (x, 0), mode) 434118334Speter & nonzero_bits (XEXP (x, 1), mode)) == 0) 434290075Sobrien { 434390075Sobrien /* Try to simplify the expression further. */ 434490075Sobrien rtx tor = gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1)); 434590075Sobrien temp = combine_simplify_rtx (tor, mode, last, in_dest); 434690075Sobrien 434790075Sobrien /* If we could, great. If not, do not go ahead with the IOR 434890075Sobrien replacement, since PLUS appears in many special purpose 434990075Sobrien address arithmetic instructions. */ 435090075Sobrien if (GET_CODE (temp) != CLOBBER && temp != tor) 435190075Sobrien return temp; 435290075Sobrien } 435318334Speter break; 435418334Speter 435518334Speter case MINUS: 435650397Sobrien /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done 435750397Sobrien by reversing the comparison code if valid. */ 435850397Sobrien if (STORE_FLAG_VALUE == 1 435950397Sobrien && XEXP (x, 0) == const1_rtx 436018334Speter && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<' 436190075Sobrien && (reversed = reversed_comparison (XEXP (x, 1), mode, 436290075Sobrien XEXP (XEXP (x, 1), 0), 436390075Sobrien XEXP (XEXP (x, 1), 1)))) 436490075Sobrien return reversed; 436518334Speter 436618334Speter /* (minus <foo> (and <foo> (const_int -pow2))) becomes 436718334Speter (and <foo> (const_int pow2-1)) */ 436818334Speter if (GET_CODE (XEXP (x, 1)) == AND 436918334Speter && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT 437090075Sobrien && exact_log2 (-INTVAL (XEXP (XEXP (x, 1), 1))) >= 0 437118334Speter && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0))) 437218334Speter return simplify_and_const_int (NULL_RTX, mode, XEXP (x, 0), 437390075Sobrien -INTVAL (XEXP (XEXP (x, 1), 1)) - 1); 437418334Speter 4375117395Skan /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). 4376117395Skan */ 4377117395Skan if (GET_CODE (XEXP (x, 1)) == MULT 4378117395Skan && GET_CODE (XEXP (XEXP (x, 1), 0)) == NEG) 4379117395Skan { 4380117395Skan rtx in1, in2; 4381117395Skan 4382117395Skan in1 = XEXP (XEXP (XEXP (x, 1), 0), 0); 4383117395Skan in2 = XEXP (XEXP (x, 1), 1); 4384117395Skan return gen_binary (PLUS, mode, gen_binary (MULT, mode, in1, in2), 4385117395Skan XEXP (x, 0)); 4386117395Skan } 4387117395Skan 4388117395Skan /* Canonicalize (minus (neg A) (mult B C)) to 4389117395Skan (minus (mult (neg B) C) A). */ 4390117395Skan if (GET_CODE (XEXP (x, 1)) == MULT 4391117395Skan && GET_CODE (XEXP (x, 0)) == NEG) 4392117395Skan { 4393117395Skan rtx in1, in2; 4394117395Skan 4395117395Skan in1 = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 1), 0), mode); 4396117395Skan in2 = XEXP (XEXP (x, 1), 1); 4397117395Skan return gen_binary (MINUS, mode, gen_binary (MULT, mode, in1, in2), 4398117395Skan XEXP (XEXP (x, 0), 0)); 4399117395Skan } 4400117395Skan 440118334Speter /* Canonicalize (minus A (plus B C)) to (minus (minus A B) C) for 440218334Speter integers. */ 440318334Speter if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode)) 440418334Speter return gen_binary (MINUS, mode, 440518334Speter gen_binary (MINUS, mode, XEXP (x, 0), 440618334Speter XEXP (XEXP (x, 1), 0)), 440718334Speter XEXP (XEXP (x, 1), 1)); 440818334Speter break; 440918334Speter 441018334Speter case MULT: 441118334Speter /* If we have (mult (plus A B) C), apply the distributive law and then 441218334Speter the inverse distributive law to see if things simplify. This 441318334Speter occurs mostly in addresses, often when unrolling loops. */ 441418334Speter 441518334Speter if (GET_CODE (XEXP (x, 0)) == PLUS) 441618334Speter { 441718334Speter x = apply_distributive_law 441818334Speter (gen_binary (PLUS, mode, 441918334Speter gen_binary (MULT, mode, 442018334Speter XEXP (XEXP (x, 0), 0), XEXP (x, 1)), 442118334Speter gen_binary (MULT, mode, 442270635Sobrien XEXP (XEXP (x, 0), 1), 442370635Sobrien copy_rtx (XEXP (x, 1))))); 442418334Speter 442518334Speter if (GET_CODE (x) != MULT) 442618334Speter return x; 442718334Speter } 442890075Sobrien /* Try simplify a*(b/c) as (a*b)/c. */ 442990075Sobrien if (FLOAT_MODE_P (mode) && flag_unsafe_math_optimizations 443090075Sobrien && GET_CODE (XEXP (x, 0)) == DIV) 443190075Sobrien { 443290075Sobrien rtx tem = simplify_binary_operation (MULT, mode, 443390075Sobrien XEXP (XEXP (x, 0), 0), 443490075Sobrien XEXP (x, 1)); 443590075Sobrien if (tem) 443690075Sobrien return gen_binary (DIV, mode, tem, XEXP (XEXP (x, 0), 1)); 443790075Sobrien } 443818334Speter break; 443918334Speter 444018334Speter case UDIV: 444118334Speter /* If this is a divide by a power of two, treat it as a shift if 444218334Speter its first operand is a shift. */ 444318334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 444418334Speter && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0 444518334Speter && (GET_CODE (XEXP (x, 0)) == ASHIFT 444618334Speter || GET_CODE (XEXP (x, 0)) == LSHIFTRT 444718334Speter || GET_CODE (XEXP (x, 0)) == ASHIFTRT 444818334Speter || GET_CODE (XEXP (x, 0)) == ROTATE 444918334Speter || GET_CODE (XEXP (x, 0)) == ROTATERT)) 445018334Speter return simplify_shift_const (NULL_RTX, LSHIFTRT, mode, XEXP (x, 0), i); 445118334Speter break; 445218334Speter 445318334Speter case EQ: case NE: 445418334Speter case GT: case GTU: case GE: case GEU: 445518334Speter case LT: case LTU: case LE: case LEU: 445690075Sobrien case UNEQ: case LTGT: 445790075Sobrien case UNGT: case UNGE: 445890075Sobrien case UNLT: case UNLE: 445990075Sobrien case UNORDERED: case ORDERED: 446018334Speter /* If the first operand is a condition code, we can't do anything 446118334Speter with it. */ 446218334Speter if (GET_CODE (XEXP (x, 0)) == COMPARE 446318334Speter || (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_CC 446418334Speter#ifdef HAVE_cc0 446518334Speter && XEXP (x, 0) != cc0_rtx 446618334Speter#endif 446790075Sobrien )) 446818334Speter { 446918334Speter rtx op0 = XEXP (x, 0); 447018334Speter rtx op1 = XEXP (x, 1); 447118334Speter enum rtx_code new_code; 447218334Speter 447318334Speter if (GET_CODE (op0) == COMPARE) 447418334Speter op1 = XEXP (op0, 1), op0 = XEXP (op0, 0); 447518334Speter 447618334Speter /* Simplify our comparison, if possible. */ 447718334Speter new_code = simplify_comparison (code, &op0, &op1); 447818334Speter 447918334Speter /* If STORE_FLAG_VALUE is 1, we can convert (ne x 0) to simply X 448018334Speter if only the low-order bit is possibly nonzero in X (such as when 448118334Speter X is a ZERO_EXTRACT of one bit). Similarly, we can convert EQ to 448218334Speter (xor X 1) or (minus 1 X); we use the former. Finally, if X is 448318334Speter known to be either 0 or -1, NE becomes a NEG and EQ becomes 448418334Speter (plus X 1). 448518334Speter 448618334Speter Remove any ZERO_EXTRACT we made when thinking this was a 448718334Speter comparison. It may now be simpler to use, e.g., an AND. If a 448818334Speter ZERO_EXTRACT is indeed appropriate, it will be placed back by 448918334Speter the call to make_compound_operation in the SET case. */ 449018334Speter 449150397Sobrien if (STORE_FLAG_VALUE == 1 449250397Sobrien && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT 449390075Sobrien && op1 == const0_rtx 449490075Sobrien && mode == GET_MODE (op0) 449590075Sobrien && nonzero_bits (op0, mode) == 1) 449618334Speter return gen_lowpart_for_combine (mode, 449718334Speter expand_compound_operation (op0)); 449818334Speter 449950397Sobrien else if (STORE_FLAG_VALUE == 1 450050397Sobrien && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT 450118334Speter && op1 == const0_rtx 450290075Sobrien && mode == GET_MODE (op0) 450318334Speter && (num_sign_bit_copies (op0, mode) 450418334Speter == GET_MODE_BITSIZE (mode))) 450518334Speter { 450618334Speter op0 = expand_compound_operation (op0); 450790075Sobrien return simplify_gen_unary (NEG, mode, 450890075Sobrien gen_lowpart_for_combine (mode, op0), 450990075Sobrien mode); 451018334Speter } 451118334Speter 451250397Sobrien else if (STORE_FLAG_VALUE == 1 451350397Sobrien && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT 451418334Speter && op1 == const0_rtx 451590075Sobrien && mode == GET_MODE (op0) 451618334Speter && nonzero_bits (op0, mode) == 1) 451718334Speter { 451818334Speter op0 = expand_compound_operation (op0); 451918334Speter return gen_binary (XOR, mode, 452018334Speter gen_lowpart_for_combine (mode, op0), 452118334Speter const1_rtx); 452218334Speter } 452318334Speter 452450397Sobrien else if (STORE_FLAG_VALUE == 1 452550397Sobrien && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT 452618334Speter && op1 == const0_rtx 452790075Sobrien && mode == GET_MODE (op0) 452818334Speter && (num_sign_bit_copies (op0, mode) 452918334Speter == GET_MODE_BITSIZE (mode))) 453018334Speter { 453118334Speter op0 = expand_compound_operation (op0); 453218334Speter return plus_constant (gen_lowpart_for_combine (mode, op0), 1); 453318334Speter } 453418334Speter 453518334Speter /* If STORE_FLAG_VALUE is -1, we have cases similar to 453618334Speter those above. */ 453750397Sobrien if (STORE_FLAG_VALUE == -1 453850397Sobrien && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT 453918334Speter && op1 == const0_rtx 454018334Speter && (num_sign_bit_copies (op0, mode) 454118334Speter == GET_MODE_BITSIZE (mode))) 454218334Speter return gen_lowpart_for_combine (mode, 454318334Speter expand_compound_operation (op0)); 454418334Speter 454550397Sobrien else if (STORE_FLAG_VALUE == -1 454650397Sobrien && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT 454718334Speter && op1 == const0_rtx 454890075Sobrien && mode == GET_MODE (op0) 454918334Speter && nonzero_bits (op0, mode) == 1) 455018334Speter { 455118334Speter op0 = expand_compound_operation (op0); 455290075Sobrien return simplify_gen_unary (NEG, mode, 455390075Sobrien gen_lowpart_for_combine (mode, op0), 455490075Sobrien mode); 455518334Speter } 455618334Speter 455750397Sobrien else if (STORE_FLAG_VALUE == -1 455850397Sobrien && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT 455918334Speter && op1 == const0_rtx 456090075Sobrien && mode == GET_MODE (op0) 456118334Speter && (num_sign_bit_copies (op0, mode) 456218334Speter == GET_MODE_BITSIZE (mode))) 456318334Speter { 456418334Speter op0 = expand_compound_operation (op0); 456590075Sobrien return simplify_gen_unary (NOT, mode, 456690075Sobrien gen_lowpart_for_combine (mode, op0), 456790075Sobrien mode); 456818334Speter } 456918334Speter 457018334Speter /* If X is 0/1, (eq X 0) is X-1. */ 457150397Sobrien else if (STORE_FLAG_VALUE == -1 457250397Sobrien && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT 457318334Speter && op1 == const0_rtx 457490075Sobrien && mode == GET_MODE (op0) 457518334Speter && nonzero_bits (op0, mode) == 1) 457618334Speter { 457718334Speter op0 = expand_compound_operation (op0); 457818334Speter return plus_constant (gen_lowpart_for_combine (mode, op0), -1); 457918334Speter } 458018334Speter 458118334Speter /* If STORE_FLAG_VALUE says to just test the sign bit and X has just 458218334Speter one bit that might be nonzero, we can convert (ne x 0) to 458318334Speter (ashift x c) where C puts the bit in the sign bit. Remove any 458418334Speter AND with STORE_FLAG_VALUE when we are done, since we are only 458518334Speter going to test the sign bit. */ 458618334Speter if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT 458718334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 458850397Sobrien && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode)) 458952284Sobrien == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE(mode)-1)) 459018334Speter && op1 == const0_rtx 459118334Speter && mode == GET_MODE (op0) 459218334Speter && (i = exact_log2 (nonzero_bits (op0, mode))) >= 0) 459318334Speter { 459418334Speter x = simplify_shift_const (NULL_RTX, ASHIFT, mode, 459518334Speter expand_compound_operation (op0), 459618334Speter GET_MODE_BITSIZE (mode) - 1 - i); 459718334Speter if (GET_CODE (x) == AND && XEXP (x, 1) == const_true_rtx) 459818334Speter return XEXP (x, 0); 459918334Speter else 460018334Speter return x; 460118334Speter } 460218334Speter 460318334Speter /* If the code changed, return a whole new comparison. */ 460418334Speter if (new_code != code) 460590075Sobrien return gen_rtx_fmt_ee (new_code, mode, op0, op1); 460618334Speter 460790075Sobrien /* Otherwise, keep this operation, but maybe change its operands. 460818334Speter This also converts (ne (compare FOO BAR) 0) to (ne FOO BAR). */ 460918334Speter SUBST (XEXP (x, 0), op0); 461018334Speter SUBST (XEXP (x, 1), op1); 461118334Speter } 461218334Speter break; 461390075Sobrien 461418334Speter case IF_THEN_ELSE: 461518334Speter return simplify_if_then_else (x); 461618334Speter 461718334Speter case ZERO_EXTRACT: 461818334Speter case SIGN_EXTRACT: 461918334Speter case ZERO_EXTEND: 462018334Speter case SIGN_EXTEND: 462150397Sobrien /* If we are processing SET_DEST, we are done. */ 462218334Speter if (in_dest) 462318334Speter return x; 462418334Speter 462518334Speter return expand_compound_operation (x); 462618334Speter 462718334Speter case SET: 462818334Speter return simplify_set (x); 462918334Speter 463018334Speter case AND: 463118334Speter case IOR: 463218334Speter case XOR: 463318334Speter return simplify_logical (x, last); 463418334Speter 463590075Sobrien case ABS: 463618334Speter /* (abs (neg <foo>)) -> (abs <foo>) */ 463718334Speter if (GET_CODE (XEXP (x, 0)) == NEG) 463818334Speter SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0)); 463918334Speter 464050397Sobrien /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS), 464150397Sobrien do nothing. */ 464250397Sobrien if (GET_MODE (XEXP (x, 0)) == VOIDmode) 464350397Sobrien break; 464450397Sobrien 464518334Speter /* If operand is something known to be positive, ignore the ABS. */ 464618334Speter if (GET_CODE (XEXP (x, 0)) == FFS || GET_CODE (XEXP (x, 0)) == ABS 464718334Speter || ((GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) 464818334Speter <= HOST_BITS_PER_WIDE_INT) 464918334Speter && ((nonzero_bits (XEXP (x, 0), GET_MODE (XEXP (x, 0))) 465018334Speter & ((HOST_WIDE_INT) 1 465118334Speter << (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - 1))) 465218334Speter == 0))) 465318334Speter return XEXP (x, 0); 465418334Speter 465518334Speter /* If operand is known to be only -1 or 0, convert ABS to NEG. */ 465618334Speter if (num_sign_bit_copies (XEXP (x, 0), mode) == GET_MODE_BITSIZE (mode)) 465790075Sobrien return gen_rtx_NEG (mode, XEXP (x, 0)); 465818334Speter 465918334Speter break; 466018334Speter 466118334Speter case FFS: 466218334Speter /* (ffs (*_extend <X>)) = (ffs <X>) */ 466318334Speter if (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND 466418334Speter || GET_CODE (XEXP (x, 0)) == ZERO_EXTEND) 466518334Speter SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0)); 466618334Speter break; 466718334Speter 466818334Speter case FLOAT: 466918334Speter /* (float (sign_extend <X>)) = (float <X>). */ 467018334Speter if (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND) 467118334Speter SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0)); 467218334Speter break; 467318334Speter 467418334Speter case ASHIFT: 467518334Speter case LSHIFTRT: 467618334Speter case ASHIFTRT: 467718334Speter case ROTATE: 467818334Speter case ROTATERT: 467918334Speter /* If this is a shift by a constant amount, simplify it. */ 468018334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT) 468190075Sobrien return simplify_shift_const (x, code, mode, XEXP (x, 0), 468218334Speter INTVAL (XEXP (x, 1))); 468318334Speter 468418334Speter#ifdef SHIFT_COUNT_TRUNCATED 468518334Speter else if (SHIFT_COUNT_TRUNCATED && GET_CODE (XEXP (x, 1)) != REG) 468618334Speter SUBST (XEXP (x, 1), 4687117395Skan force_to_mode (XEXP (x, 1), GET_MODE (XEXP (x, 1)), 468890075Sobrien ((HOST_WIDE_INT) 1 468918334Speter << exact_log2 (GET_MODE_BITSIZE (GET_MODE (x)))) 469018334Speter - 1, 469118334Speter NULL_RTX, 0)); 469218334Speter#endif 469318334Speter 469418334Speter break; 469550397Sobrien 469690075Sobrien case VEC_SELECT: 469790075Sobrien { 469890075Sobrien rtx op0 = XEXP (x, 0); 469990075Sobrien rtx op1 = XEXP (x, 1); 470090075Sobrien int len; 470190075Sobrien 470290075Sobrien if (GET_CODE (op1) != PARALLEL) 470390075Sobrien abort (); 470490075Sobrien len = XVECLEN (op1, 0); 470590075Sobrien if (len == 1 470690075Sobrien && GET_CODE (XVECEXP (op1, 0, 0)) == CONST_INT 470790075Sobrien && GET_CODE (op0) == VEC_CONCAT) 470890075Sobrien { 470990075Sobrien int offset = INTVAL (XVECEXP (op1, 0, 0)) * GET_MODE_SIZE (GET_MODE (x)); 471090075Sobrien 471190075Sobrien /* Try to find the element in the VEC_CONCAT. */ 471290075Sobrien for (;;) 471390075Sobrien { 471490075Sobrien if (GET_MODE (op0) == GET_MODE (x)) 471590075Sobrien return op0; 471690075Sobrien if (GET_CODE (op0) == VEC_CONCAT) 471790075Sobrien { 471890075Sobrien HOST_WIDE_INT op0_size = GET_MODE_SIZE (GET_MODE (XEXP (op0, 0))); 471990075Sobrien if (op0_size < offset) 472090075Sobrien op0 = XEXP (op0, 0); 472190075Sobrien else 472290075Sobrien { 472390075Sobrien offset -= op0_size; 472490075Sobrien op0 = XEXP (op0, 1); 472590075Sobrien } 472690075Sobrien } 472790075Sobrien else 472890075Sobrien break; 472990075Sobrien } 473090075Sobrien } 473190075Sobrien } 473290075Sobrien 473390075Sobrien break; 473490075Sobrien 473550397Sobrien default: 473650397Sobrien break; 473718334Speter } 473818334Speter 473918334Speter return x; 474018334Speter} 474118334Speter 474218334Speter/* Simplify X, an IF_THEN_ELSE expression. Return the new expression. */ 474318334Speter 474418334Speterstatic rtx 474518334Spetersimplify_if_then_else (x) 474618334Speter rtx x; 474718334Speter{ 474818334Speter enum machine_mode mode = GET_MODE (x); 474918334Speter rtx cond = XEXP (x, 0); 475090075Sobrien rtx true_rtx = XEXP (x, 1); 475190075Sobrien rtx false_rtx = XEXP (x, 2); 475218334Speter enum rtx_code true_code = GET_CODE (cond); 475318334Speter int comparison_p = GET_RTX_CLASS (true_code) == '<'; 475418334Speter rtx temp; 475518334Speter int i; 475690075Sobrien enum rtx_code false_code; 475790075Sobrien rtx reversed; 475818334Speter 475950397Sobrien /* Simplify storing of the truth value. */ 476090075Sobrien if (comparison_p && true_rtx == const_true_rtx && false_rtx == const0_rtx) 476118334Speter return gen_binary (true_code, mode, XEXP (cond, 0), XEXP (cond, 1)); 476290075Sobrien 476350397Sobrien /* Also when the truth value has to be reversed. */ 476490075Sobrien if (comparison_p 476590075Sobrien && true_rtx == const0_rtx && false_rtx == const_true_rtx 476690075Sobrien && (reversed = reversed_comparison (cond, mode, XEXP (cond, 0), 476790075Sobrien XEXP (cond, 1)))) 476890075Sobrien return reversed; 476918334Speter 477018334Speter /* Sometimes we can simplify the arm of an IF_THEN_ELSE if a register used 477118334Speter in it is being compared against certain values. Get the true and false 477218334Speter comparisons and see if that says anything about the value of each arm. */ 477318334Speter 477490075Sobrien if (comparison_p 477590075Sobrien && ((false_code = combine_reversed_comparison_code (cond)) 477690075Sobrien != UNKNOWN) 477718334Speter && GET_CODE (XEXP (cond, 0)) == REG) 477818334Speter { 477918334Speter HOST_WIDE_INT nzb; 478018334Speter rtx from = XEXP (cond, 0); 478118334Speter rtx true_val = XEXP (cond, 1); 478218334Speter rtx false_val = true_val; 478318334Speter int swapped = 0; 478418334Speter 478518334Speter /* If FALSE_CODE is EQ, swap the codes and arms. */ 478618334Speter 478718334Speter if (false_code == EQ) 478818334Speter { 478918334Speter swapped = 1, true_code = EQ, false_code = NE; 479090075Sobrien temp = true_rtx, true_rtx = false_rtx, false_rtx = temp; 479118334Speter } 479218334Speter 479318334Speter /* If we are comparing against zero and the expression being tested has 479418334Speter only a single bit that might be nonzero, that is its value when it is 479518334Speter not equal to zero. Similarly if it is known to be -1 or 0. */ 479618334Speter 479718334Speter if (true_code == EQ && true_val == const0_rtx 479818334Speter && exact_log2 (nzb = nonzero_bits (from, GET_MODE (from))) >= 0) 479918334Speter false_code = EQ, false_val = GEN_INT (nzb); 480018334Speter else if (true_code == EQ && true_val == const0_rtx 480118334Speter && (num_sign_bit_copies (from, GET_MODE (from)) 480218334Speter == GET_MODE_BITSIZE (GET_MODE (from)))) 480318334Speter false_code = EQ, false_val = constm1_rtx; 480418334Speter 480518334Speter /* Now simplify an arm if we know the value of the register in the 480618334Speter branch and it is used in the arm. Be careful due to the potential 480718334Speter of locally-shared RTL. */ 480818334Speter 480990075Sobrien if (reg_mentioned_p (from, true_rtx)) 481090075Sobrien true_rtx = subst (known_cond (copy_rtx (true_rtx), true_code, 481190075Sobrien from, true_val), 481218334Speter pc_rtx, pc_rtx, 0, 0); 481390075Sobrien if (reg_mentioned_p (from, false_rtx)) 481490075Sobrien false_rtx = subst (known_cond (copy_rtx (false_rtx), false_code, 481518334Speter from, false_val), 481618334Speter pc_rtx, pc_rtx, 0, 0); 481718334Speter 481890075Sobrien SUBST (XEXP (x, 1), swapped ? false_rtx : true_rtx); 481990075Sobrien SUBST (XEXP (x, 2), swapped ? true_rtx : false_rtx); 482018334Speter 482190075Sobrien true_rtx = XEXP (x, 1); 482290075Sobrien false_rtx = XEXP (x, 2); 482390075Sobrien true_code = GET_CODE (cond); 482418334Speter } 482518334Speter 482618334Speter /* If we have (if_then_else FOO (pc) (label_ref BAR)) and FOO can be 482718334Speter reversed, do so to avoid needing two sets of patterns for 482818334Speter subtract-and-branch insns. Similarly if we have a constant in the true 482918334Speter arm, the false arm is the same as the first operand of the comparison, or 483018334Speter the false arm is more complicated than the true arm. */ 483118334Speter 483290075Sobrien if (comparison_p 483390075Sobrien && combine_reversed_comparison_code (cond) != UNKNOWN 483490075Sobrien && (true_rtx == pc_rtx 483590075Sobrien || (CONSTANT_P (true_rtx) 483690075Sobrien && GET_CODE (false_rtx) != CONST_INT && false_rtx != pc_rtx) 483790075Sobrien || true_rtx == const0_rtx 483890075Sobrien || (GET_RTX_CLASS (GET_CODE (true_rtx)) == 'o' 483990075Sobrien && GET_RTX_CLASS (GET_CODE (false_rtx)) != 'o') 484090075Sobrien || (GET_CODE (true_rtx) == SUBREG 484190075Sobrien && GET_RTX_CLASS (GET_CODE (SUBREG_REG (true_rtx))) == 'o' 484290075Sobrien && GET_RTX_CLASS (GET_CODE (false_rtx)) != 'o') 484390075Sobrien || reg_mentioned_p (true_rtx, false_rtx) 484490075Sobrien || rtx_equal_p (false_rtx, XEXP (cond, 0)))) 484518334Speter { 484690075Sobrien true_code = reversed_comparison_code (cond, NULL); 484718334Speter SUBST (XEXP (x, 0), 484890075Sobrien reversed_comparison (cond, GET_MODE (cond), XEXP (cond, 0), 484990075Sobrien XEXP (cond, 1))); 485018334Speter 485190075Sobrien SUBST (XEXP (x, 1), false_rtx); 485290075Sobrien SUBST (XEXP (x, 2), true_rtx); 485318334Speter 485490075Sobrien temp = true_rtx, true_rtx = false_rtx, false_rtx = temp; 485590075Sobrien cond = XEXP (x, 0); 485650397Sobrien 485750397Sobrien /* It is possible that the conditional has been simplified out. */ 485850397Sobrien true_code = GET_CODE (cond); 485950397Sobrien comparison_p = GET_RTX_CLASS (true_code) == '<'; 486018334Speter } 486118334Speter 486218334Speter /* If the two arms are identical, we don't need the comparison. */ 486318334Speter 486490075Sobrien if (rtx_equal_p (true_rtx, false_rtx) && ! side_effects_p (cond)) 486590075Sobrien return true_rtx; 486618334Speter 486750397Sobrien /* Convert a == b ? b : a to "a". */ 486850397Sobrien if (true_code == EQ && ! side_effects_p (cond) 4869117395Skan && !HONOR_NANS (mode) 487090075Sobrien && rtx_equal_p (XEXP (cond, 0), false_rtx) 487190075Sobrien && rtx_equal_p (XEXP (cond, 1), true_rtx)) 487290075Sobrien return false_rtx; 487350397Sobrien else if (true_code == NE && ! side_effects_p (cond) 4874117395Skan && !HONOR_NANS (mode) 487590075Sobrien && rtx_equal_p (XEXP (cond, 0), true_rtx) 487690075Sobrien && rtx_equal_p (XEXP (cond, 1), false_rtx)) 487790075Sobrien return true_rtx; 487850397Sobrien 487918334Speter /* Look for cases where we have (abs x) or (neg (abs X)). */ 488018334Speter 488118334Speter if (GET_MODE_CLASS (mode) == MODE_INT 488290075Sobrien && GET_CODE (false_rtx) == NEG 488390075Sobrien && rtx_equal_p (true_rtx, XEXP (false_rtx, 0)) 488418334Speter && comparison_p 488590075Sobrien && rtx_equal_p (true_rtx, XEXP (cond, 0)) 488690075Sobrien && ! side_effects_p (true_rtx)) 488718334Speter switch (true_code) 488818334Speter { 488918334Speter case GT: 489018334Speter case GE: 489190075Sobrien return simplify_gen_unary (ABS, mode, true_rtx, mode); 489218334Speter case LT: 489318334Speter case LE: 489490075Sobrien return 489590075Sobrien simplify_gen_unary (NEG, mode, 489690075Sobrien simplify_gen_unary (ABS, mode, true_rtx, mode), 489790075Sobrien mode); 489890075Sobrien default: 489990075Sobrien break; 490018334Speter } 490118334Speter 490218334Speter /* Look for MIN or MAX. */ 490318334Speter 490490075Sobrien if ((! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations) 490518334Speter && comparison_p 490690075Sobrien && rtx_equal_p (XEXP (cond, 0), true_rtx) 490790075Sobrien && rtx_equal_p (XEXP (cond, 1), false_rtx) 490818334Speter && ! side_effects_p (cond)) 490918334Speter switch (true_code) 491018334Speter { 491118334Speter case GE: 491218334Speter case GT: 491390075Sobrien return gen_binary (SMAX, mode, true_rtx, false_rtx); 491418334Speter case LE: 491518334Speter case LT: 491690075Sobrien return gen_binary (SMIN, mode, true_rtx, false_rtx); 491718334Speter case GEU: 491818334Speter case GTU: 491990075Sobrien return gen_binary (UMAX, mode, true_rtx, false_rtx); 492018334Speter case LEU: 492118334Speter case LTU: 492290075Sobrien return gen_binary (UMIN, mode, true_rtx, false_rtx); 492350397Sobrien default: 492450397Sobrien break; 492518334Speter } 492690075Sobrien 492718334Speter /* If we have (if_then_else COND (OP Z C1) Z) and OP is an identity when its 492818334Speter second operand is zero, this can be done as (OP Z (mult COND C2)) where 492918334Speter C2 = C1 * STORE_FLAG_VALUE. Similarly if OP has an outer ZERO_EXTEND or 493018334Speter SIGN_EXTEND as long as Z is already extended (so we don't destroy it). 493118334Speter We can do this kind of thing in some cases when STORE_FLAG_VALUE is 493250397Sobrien neither 1 or -1, but it isn't worth checking for. */ 493318334Speter 493450397Sobrien if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1) 4935117395Skan && comparison_p 4936117395Skan && GET_MODE_CLASS (mode) == MODE_INT 4937117395Skan && ! side_effects_p (x)) 493818334Speter { 493990075Sobrien rtx t = make_compound_operation (true_rtx, SET); 494090075Sobrien rtx f = make_compound_operation (false_rtx, SET); 494118334Speter rtx cond_op0 = XEXP (cond, 0); 494218334Speter rtx cond_op1 = XEXP (cond, 1); 494390075Sobrien enum rtx_code op = NIL, extend_op = NIL; 494418334Speter enum machine_mode m = mode; 494590075Sobrien rtx z = 0, c1 = NULL_RTX; 494618334Speter 494718334Speter if ((GET_CODE (t) == PLUS || GET_CODE (t) == MINUS 494818334Speter || GET_CODE (t) == IOR || GET_CODE (t) == XOR 494918334Speter || GET_CODE (t) == ASHIFT 495018334Speter || GET_CODE (t) == LSHIFTRT || GET_CODE (t) == ASHIFTRT) 495118334Speter && rtx_equal_p (XEXP (t, 0), f)) 495218334Speter c1 = XEXP (t, 1), op = GET_CODE (t), z = f; 495318334Speter 495418334Speter /* If an identity-zero op is commutative, check whether there 495550397Sobrien would be a match if we swapped the operands. */ 495618334Speter else if ((GET_CODE (t) == PLUS || GET_CODE (t) == IOR 495718334Speter || GET_CODE (t) == XOR) 495818334Speter && rtx_equal_p (XEXP (t, 1), f)) 495918334Speter c1 = XEXP (t, 0), op = GET_CODE (t), z = f; 496018334Speter else if (GET_CODE (t) == SIGN_EXTEND 496118334Speter && (GET_CODE (XEXP (t, 0)) == PLUS 496218334Speter || GET_CODE (XEXP (t, 0)) == MINUS 496318334Speter || GET_CODE (XEXP (t, 0)) == IOR 496418334Speter || GET_CODE (XEXP (t, 0)) == XOR 496518334Speter || GET_CODE (XEXP (t, 0)) == ASHIFT 496618334Speter || GET_CODE (XEXP (t, 0)) == LSHIFTRT 496718334Speter || GET_CODE (XEXP (t, 0)) == ASHIFTRT) 496818334Speter && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG 496918334Speter && subreg_lowpart_p (XEXP (XEXP (t, 0), 0)) 497018334Speter && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f) 497118334Speter && (num_sign_bit_copies (f, GET_MODE (f)) 4972117395Skan > (unsigned int) 4973117395Skan (GET_MODE_BITSIZE (mode) 497418334Speter - GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (t, 0), 0)))))) 497518334Speter { 497618334Speter c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0)); 497718334Speter extend_op = SIGN_EXTEND; 497818334Speter m = GET_MODE (XEXP (t, 0)); 497918334Speter } 498018334Speter else if (GET_CODE (t) == SIGN_EXTEND 498118334Speter && (GET_CODE (XEXP (t, 0)) == PLUS 498218334Speter || GET_CODE (XEXP (t, 0)) == IOR 498318334Speter || GET_CODE (XEXP (t, 0)) == XOR) 498418334Speter && GET_CODE (XEXP (XEXP (t, 0), 1)) == SUBREG 498518334Speter && subreg_lowpart_p (XEXP (XEXP (t, 0), 1)) 498618334Speter && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 1)), f) 498718334Speter && (num_sign_bit_copies (f, GET_MODE (f)) 4988117395Skan > (unsigned int) 4989117395Skan (GET_MODE_BITSIZE (mode) 499018334Speter - GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (t, 0), 1)))))) 499118334Speter { 499218334Speter c1 = XEXP (XEXP (t, 0), 0); z = f; op = GET_CODE (XEXP (t, 0)); 499318334Speter extend_op = SIGN_EXTEND; 499418334Speter m = GET_MODE (XEXP (t, 0)); 499518334Speter } 499618334Speter else if (GET_CODE (t) == ZERO_EXTEND 499718334Speter && (GET_CODE (XEXP (t, 0)) == PLUS 499818334Speter || GET_CODE (XEXP (t, 0)) == MINUS 499918334Speter || GET_CODE (XEXP (t, 0)) == IOR 500018334Speter || GET_CODE (XEXP (t, 0)) == XOR 500118334Speter || GET_CODE (XEXP (t, 0)) == ASHIFT 500218334Speter || GET_CODE (XEXP (t, 0)) == LSHIFTRT 500318334Speter || GET_CODE (XEXP (t, 0)) == ASHIFTRT) 500418334Speter && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG 500518334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 500618334Speter && subreg_lowpart_p (XEXP (XEXP (t, 0), 0)) 500718334Speter && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f) 500818334Speter && ((nonzero_bits (f, GET_MODE (f)) 500990075Sobrien & ~GET_MODE_MASK (GET_MODE (XEXP (XEXP (t, 0), 0)))) 501018334Speter == 0)) 501118334Speter { 501218334Speter c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0)); 501318334Speter extend_op = ZERO_EXTEND; 501418334Speter m = GET_MODE (XEXP (t, 0)); 501518334Speter } 501618334Speter else if (GET_CODE (t) == ZERO_EXTEND 501718334Speter && (GET_CODE (XEXP (t, 0)) == PLUS 501818334Speter || GET_CODE (XEXP (t, 0)) == IOR 501918334Speter || GET_CODE (XEXP (t, 0)) == XOR) 502018334Speter && GET_CODE (XEXP (XEXP (t, 0), 1)) == SUBREG 502118334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 502218334Speter && subreg_lowpart_p (XEXP (XEXP (t, 0), 1)) 502318334Speter && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 1)), f) 502418334Speter && ((nonzero_bits (f, GET_MODE (f)) 502590075Sobrien & ~GET_MODE_MASK (GET_MODE (XEXP (XEXP (t, 0), 1)))) 502618334Speter == 0)) 502718334Speter { 502818334Speter c1 = XEXP (XEXP (t, 0), 0); z = f; op = GET_CODE (XEXP (t, 0)); 502918334Speter extend_op = ZERO_EXTEND; 503018334Speter m = GET_MODE (XEXP (t, 0)); 503118334Speter } 503290075Sobrien 503318334Speter if (z) 503418334Speter { 503518334Speter temp = subst (gen_binary (true_code, m, cond_op0, cond_op1), 503618334Speter pc_rtx, pc_rtx, 0, 0); 503718334Speter temp = gen_binary (MULT, m, temp, 503818334Speter gen_binary (MULT, m, c1, const_true_rtx)); 503918334Speter temp = subst (temp, pc_rtx, pc_rtx, 0, 0); 504018334Speter temp = gen_binary (op, m, gen_lowpart_for_combine (m, z), temp); 504118334Speter 504218334Speter if (extend_op != NIL) 504390075Sobrien temp = simplify_gen_unary (extend_op, mode, temp, m); 504418334Speter 504518334Speter return temp; 504618334Speter } 504718334Speter } 504818334Speter 504918334Speter /* If we have (if_then_else (ne A 0) C1 0) and either A is known to be 0 or 505018334Speter 1 and C1 is a single bit or A is known to be 0 or -1 and C1 is the 505118334Speter negation of a single bit, we can convert this operation to a shift. We 505218334Speter can actually do this more generally, but it doesn't seem worth it. */ 505318334Speter 505418334Speter if (true_code == NE && XEXP (cond, 1) == const0_rtx 505590075Sobrien && false_rtx == const0_rtx && GET_CODE (true_rtx) == CONST_INT 505618334Speter && ((1 == nonzero_bits (XEXP (cond, 0), mode) 505790075Sobrien && (i = exact_log2 (INTVAL (true_rtx))) >= 0) 505818334Speter || ((num_sign_bit_copies (XEXP (cond, 0), mode) 505918334Speter == GET_MODE_BITSIZE (mode)) 506090075Sobrien && (i = exact_log2 (-INTVAL (true_rtx))) >= 0))) 506118334Speter return 506218334Speter simplify_shift_const (NULL_RTX, ASHIFT, mode, 506318334Speter gen_lowpart_for_combine (mode, XEXP (cond, 0)), i); 506418334Speter 506518334Speter return x; 506618334Speter} 506718334Speter 506818334Speter/* Simplify X, a SET expression. Return the new expression. */ 506918334Speter 507018334Speterstatic rtx 507118334Spetersimplify_set (x) 507218334Speter rtx x; 507318334Speter{ 507418334Speter rtx src = SET_SRC (x); 507518334Speter rtx dest = SET_DEST (x); 507618334Speter enum machine_mode mode 507718334Speter = GET_MODE (src) != VOIDmode ? GET_MODE (src) : GET_MODE (dest); 507818334Speter rtx other_insn; 507918334Speter rtx *cc_use; 508018334Speter 508118334Speter /* (set (pc) (return)) gets written as (return). */ 508218334Speter if (GET_CODE (dest) == PC && GET_CODE (src) == RETURN) 508318334Speter return src; 508418334Speter 508518334Speter /* Now that we know for sure which bits of SRC we are using, see if we can 508618334Speter simplify the expression for the object knowing that we only need the 508718334Speter low-order bits. */ 508818334Speter 5089117395Skan if (GET_MODE_CLASS (mode) == MODE_INT 5090117395Skan && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) 509190075Sobrien { 509290075Sobrien src = force_to_mode (src, mode, ~(HOST_WIDE_INT) 0, NULL_RTX, 0); 509390075Sobrien SUBST (SET_SRC (x), src); 509490075Sobrien } 509518334Speter 509618334Speter /* If we are setting CC0 or if the source is a COMPARE, look for the use of 509718334Speter the comparison result and try to simplify it unless we already have used 509818334Speter undobuf.other_insn. */ 5099117395Skan if ((GET_MODE_CLASS (mode) == MODE_CC 5100117395Skan || GET_CODE (src) == COMPARE 5101117395Skan || CC0_P (dest)) 510218334Speter && (cc_use = find_single_use (dest, subst_insn, &other_insn)) != 0 510318334Speter && (undobuf.other_insn == 0 || other_insn == undobuf.other_insn) 510418334Speter && GET_RTX_CLASS (GET_CODE (*cc_use)) == '<' 510518334Speter && rtx_equal_p (XEXP (*cc_use, 0), dest)) 510618334Speter { 510718334Speter enum rtx_code old_code = GET_CODE (*cc_use); 510818334Speter enum rtx_code new_code; 5109117395Skan rtx op0, op1, tmp; 511018334Speter int other_changed = 0; 511118334Speter enum machine_mode compare_mode = GET_MODE (dest); 5112117395Skan enum machine_mode tmp_mode; 511318334Speter 511418334Speter if (GET_CODE (src) == COMPARE) 511518334Speter op0 = XEXP (src, 0), op1 = XEXP (src, 1); 511618334Speter else 511718334Speter op0 = src, op1 = const0_rtx; 511818334Speter 5119117395Skan /* Check whether the comparison is known at compile time. */ 5120117395Skan if (GET_MODE (op0) != VOIDmode) 5121117395Skan tmp_mode = GET_MODE (op0); 5122117395Skan else if (GET_MODE (op1) != VOIDmode) 5123117395Skan tmp_mode = GET_MODE (op1); 5124117395Skan else 5125117395Skan tmp_mode = compare_mode; 5126117395Skan tmp = simplify_relational_operation (old_code, tmp_mode, op0, op1); 5127117395Skan if (tmp != NULL_RTX) 5128117395Skan { 5129117395Skan rtx pat = PATTERN (other_insn); 5130117395Skan undobuf.other_insn = other_insn; 5131117395Skan SUBST (*cc_use, tmp); 5132117395Skan 5133117395Skan /* Attempt to simplify CC user. */ 5134117395Skan if (GET_CODE (pat) == SET) 5135117395Skan { 5136117395Skan rtx new = simplify_rtx (SET_SRC (pat)); 5137117395Skan if (new != NULL_RTX) 5138117395Skan SUBST (SET_SRC (pat), new); 5139117395Skan } 5140117395Skan 5141117395Skan /* Convert X into a no-op move. */ 5142117395Skan SUBST (SET_DEST (x), pc_rtx); 5143117395Skan SUBST (SET_SRC (x), pc_rtx); 5144117395Skan return x; 5145117395Skan } 5146117395Skan 514718334Speter /* Simplify our comparison, if possible. */ 514818334Speter new_code = simplify_comparison (old_code, &op0, &op1); 514918334Speter 515018334Speter#ifdef EXTRA_CC_MODES 515118334Speter /* If this machine has CC modes other than CCmode, check to see if we 515218334Speter need to use a different CC mode here. */ 515318334Speter compare_mode = SELECT_CC_MODE (new_code, op0, op1); 515418334Speter#endif /* EXTRA_CC_MODES */ 515518334Speter 515618334Speter#if !defined (HAVE_cc0) && defined (EXTRA_CC_MODES) 515718334Speter /* If the mode changed, we have to change SET_DEST, the mode in the 515818334Speter compare, and the mode in the place SET_DEST is used. If SET_DEST is 515918334Speter a hard register, just build new versions with the proper mode. If it 516018334Speter is a pseudo, we lose unless it is only time we set the pseudo, in 516118334Speter which case we can safely change its mode. */ 516218334Speter if (compare_mode != GET_MODE (dest)) 516318334Speter { 516490075Sobrien unsigned int regno = REGNO (dest); 516550397Sobrien rtx new_dest = gen_rtx_REG (compare_mode, regno); 516618334Speter 516718334Speter if (regno < FIRST_PSEUDO_REGISTER 516850397Sobrien || (REG_N_SETS (regno) == 1 && ! REG_USERVAR_P (dest))) 516918334Speter { 517018334Speter if (regno >= FIRST_PSEUDO_REGISTER) 517118334Speter SUBST (regno_reg_rtx[regno], new_dest); 517218334Speter 517318334Speter SUBST (SET_DEST (x), new_dest); 517418334Speter SUBST (XEXP (*cc_use, 0), new_dest); 517518334Speter other_changed = 1; 517618334Speter 517718334Speter dest = new_dest; 517818334Speter } 517918334Speter } 518018334Speter#endif 518118334Speter 518218334Speter /* If the code changed, we have to build a new comparison in 518318334Speter undobuf.other_insn. */ 518418334Speter if (new_code != old_code) 518518334Speter { 518618334Speter unsigned HOST_WIDE_INT mask; 518718334Speter 518890075Sobrien SUBST (*cc_use, gen_rtx_fmt_ee (new_code, GET_MODE (*cc_use), 518990075Sobrien dest, const0_rtx)); 519018334Speter 519118334Speter /* If the only change we made was to change an EQ into an NE or 519218334Speter vice versa, OP0 has only one bit that might be nonzero, and OP1 519318334Speter is zero, check if changing the user of the condition code will 519418334Speter produce a valid insn. If it won't, we can keep the original code 519518334Speter in that insn by surrounding our operation with an XOR. */ 519618334Speter 519718334Speter if (((old_code == NE && new_code == EQ) 519818334Speter || (old_code == EQ && new_code == NE)) 519918334Speter && ! other_changed && op1 == const0_rtx 520018334Speter && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT 520118334Speter && exact_log2 (mask = nonzero_bits (op0, GET_MODE (op0))) >= 0) 520218334Speter { 520318334Speter rtx pat = PATTERN (other_insn), note = 0; 520418334Speter 520552284Sobrien if ((recog_for_combine (&pat, other_insn, ¬e) < 0 520618334Speter && ! check_asm_operands (pat))) 520718334Speter { 520818334Speter PUT_CODE (*cc_use, old_code); 520918334Speter other_insn = 0; 521018334Speter 521118334Speter op0 = gen_binary (XOR, GET_MODE (op0), op0, GEN_INT (mask)); 521218334Speter } 521318334Speter } 521418334Speter 521518334Speter other_changed = 1; 521618334Speter } 521718334Speter 521818334Speter if (other_changed) 521918334Speter undobuf.other_insn = other_insn; 522018334Speter 522118334Speter#ifdef HAVE_cc0 522218334Speter /* If we are now comparing against zero, change our source if 522318334Speter needed. If we do not use cc0, we always have a COMPARE. */ 522418334Speter if (op1 == const0_rtx && dest == cc0_rtx) 522518334Speter { 522618334Speter SUBST (SET_SRC (x), op0); 522718334Speter src = op0; 522818334Speter } 522918334Speter else 523018334Speter#endif 523118334Speter 523218334Speter /* Otherwise, if we didn't previously have a COMPARE in the 523318334Speter correct mode, we need one. */ 523418334Speter if (GET_CODE (src) != COMPARE || GET_MODE (src) != compare_mode) 523518334Speter { 523690075Sobrien SUBST (SET_SRC (x), gen_rtx_COMPARE (compare_mode, op0, op1)); 523718334Speter src = SET_SRC (x); 523818334Speter } 523918334Speter else 524018334Speter { 524118334Speter /* Otherwise, update the COMPARE if needed. */ 524218334Speter SUBST (XEXP (src, 0), op0); 524318334Speter SUBST (XEXP (src, 1), op1); 524418334Speter } 524518334Speter } 524618334Speter else 524718334Speter { 524818334Speter /* Get SET_SRC in a form where we have placed back any 524918334Speter compound expressions. Then do the checks below. */ 525018334Speter src = make_compound_operation (src, SET); 525118334Speter SUBST (SET_SRC (x), src); 525218334Speter } 525318334Speter 525418334Speter /* If we have (set x (subreg:m1 (op:m2 ...) 0)) with OP being some operation, 525518334Speter and X being a REG or (subreg (reg)), we may be able to convert this to 525690075Sobrien (set (subreg:m2 x) (op)). 525718334Speter 525818334Speter We can always do this if M1 is narrower than M2 because that means that 525918334Speter we only care about the low bits of the result. 526018334Speter 526118334Speter However, on machines without WORD_REGISTER_OPERATIONS defined, we cannot 526250397Sobrien perform a narrower operation than requested since the high-order bits will 526318334Speter be undefined. On machine where it is defined, this transformation is safe 526418334Speter as long as M1 and M2 have the same number of words. */ 526590075Sobrien 526618334Speter if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src) 526718334Speter && GET_RTX_CLASS (GET_CODE (SUBREG_REG (src))) != 'o' 526818334Speter && (((GET_MODE_SIZE (GET_MODE (src)) + (UNITS_PER_WORD - 1)) 526918334Speter / UNITS_PER_WORD) 527018334Speter == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))) 527118334Speter + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)) 527218334Speter#ifndef WORD_REGISTER_OPERATIONS 527318334Speter && (GET_MODE_SIZE (GET_MODE (src)) 527418334Speter < GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))) 527518334Speter#endif 5276117395Skan#ifdef CANNOT_CHANGE_MODE_CLASS 527718334Speter && ! (GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER 5278117395Skan && REG_CANNOT_CHANGE_MODE_P (REGNO (dest), 5279117395Skan GET_MODE (SUBREG_REG (src)), 5280117395Skan GET_MODE (src))) 528190075Sobrien#endif 528218334Speter && (GET_CODE (dest) == REG 528318334Speter || (GET_CODE (dest) == SUBREG 528418334Speter && GET_CODE (SUBREG_REG (dest)) == REG))) 528518334Speter { 528618334Speter SUBST (SET_DEST (x), 528718334Speter gen_lowpart_for_combine (GET_MODE (SUBREG_REG (src)), 528818334Speter dest)); 528918334Speter SUBST (SET_SRC (x), SUBREG_REG (src)); 529018334Speter 529118334Speter src = SET_SRC (x), dest = SET_DEST (x); 529218334Speter } 529318334Speter 5294117395Skan#ifdef HAVE_cc0 5295117395Skan /* If we have (set (cc0) (subreg ...)), we try to remove the subreg 5296117395Skan in SRC. */ 5297117395Skan if (dest == cc0_rtx 5298117395Skan && GET_CODE (src) == SUBREG 5299117395Skan && subreg_lowpart_p (src) 5300117395Skan && (GET_MODE_BITSIZE (GET_MODE (src)) 5301117395Skan < GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (src))))) 5302117395Skan { 5303117395Skan rtx inner = SUBREG_REG (src); 5304117395Skan enum machine_mode inner_mode = GET_MODE (inner); 5305117395Skan 5306117395Skan /* Here we make sure that we don't have a sign bit on. */ 5307117395Skan if (GET_MODE_BITSIZE (inner_mode) <= HOST_BITS_PER_WIDE_INT 5308117395Skan && (nonzero_bits (inner, inner_mode) 5309117395Skan < ((unsigned HOST_WIDE_INT) 1 5310117395Skan << (GET_MODE_BITSIZE (GET_MODE (src)) - 1)))) 5311117395Skan { 5312117395Skan SUBST (SET_SRC (x), inner); 5313117395Skan src = SET_SRC (x); 5314117395Skan } 5315117395Skan } 5316117395Skan#endif 5317117395Skan 531818334Speter#ifdef LOAD_EXTEND_OP 531918334Speter /* If we have (set FOO (subreg:M (mem:N BAR) 0)) with M wider than N, this 532018334Speter would require a paradoxical subreg. Replace the subreg with a 532150397Sobrien zero_extend to avoid the reload that would otherwise be required. */ 532218334Speter 532318334Speter if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src) 532418334Speter && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (src))) != NIL 532590075Sobrien && SUBREG_BYTE (src) == 0 532618334Speter && (GET_MODE_SIZE (GET_MODE (src)) 532718334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))) 532818334Speter && GET_CODE (SUBREG_REG (src)) == MEM) 532918334Speter { 533018334Speter SUBST (SET_SRC (x), 533190075Sobrien gen_rtx (LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (src))), 533290075Sobrien GET_MODE (src), SUBREG_REG (src))); 533318334Speter 533418334Speter src = SET_SRC (x); 533518334Speter } 533618334Speter#endif 533718334Speter 533818334Speter /* If we don't have a conditional move, SET_SRC is an IF_THEN_ELSE, and we 533918334Speter are comparing an item known to be 0 or -1 against 0, use a logical 534018334Speter operation instead. Check for one of the arms being an IOR of the other 534118334Speter arm with some value. We compute three terms to be IOR'ed together. In 534218334Speter practice, at most two will be nonzero. Then we do the IOR's. */ 534318334Speter 534418334Speter if (GET_CODE (dest) != PC 534518334Speter && GET_CODE (src) == IF_THEN_ELSE 534618334Speter && GET_MODE_CLASS (GET_MODE (src)) == MODE_INT 534718334Speter && (GET_CODE (XEXP (src, 0)) == EQ || GET_CODE (XEXP (src, 0)) == NE) 534818334Speter && XEXP (XEXP (src, 0), 1) == const0_rtx 534918334Speter && GET_MODE (src) == GET_MODE (XEXP (XEXP (src, 0), 0)) 535018334Speter#ifdef HAVE_conditional_move 535118334Speter && ! can_conditionally_move_p (GET_MODE (src)) 535218334Speter#endif 535318334Speter && (num_sign_bit_copies (XEXP (XEXP (src, 0), 0), 535418334Speter GET_MODE (XEXP (XEXP (src, 0), 0))) 535518334Speter == GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (src, 0), 0)))) 535618334Speter && ! side_effects_p (src)) 535718334Speter { 535890075Sobrien rtx true_rtx = (GET_CODE (XEXP (src, 0)) == NE 535918334Speter ? XEXP (src, 1) : XEXP (src, 2)); 536090075Sobrien rtx false_rtx = (GET_CODE (XEXP (src, 0)) == NE 536118334Speter ? XEXP (src, 2) : XEXP (src, 1)); 536218334Speter rtx term1 = const0_rtx, term2, term3; 536318334Speter 536490075Sobrien if (GET_CODE (true_rtx) == IOR 536590075Sobrien && rtx_equal_p (XEXP (true_rtx, 0), false_rtx)) 536690075Sobrien term1 = false_rtx, true_rtx = XEXP(true_rtx, 1), false_rtx = const0_rtx; 536790075Sobrien else if (GET_CODE (true_rtx) == IOR 536890075Sobrien && rtx_equal_p (XEXP (true_rtx, 1), false_rtx)) 536990075Sobrien term1 = false_rtx, true_rtx = XEXP(true_rtx, 0), false_rtx = const0_rtx; 537090075Sobrien else if (GET_CODE (false_rtx) == IOR 537190075Sobrien && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)) 537290075Sobrien term1 = true_rtx, false_rtx = XEXP(false_rtx, 1), true_rtx = const0_rtx; 537390075Sobrien else if (GET_CODE (false_rtx) == IOR 537490075Sobrien && rtx_equal_p (XEXP (false_rtx, 1), true_rtx)) 537590075Sobrien term1 = true_rtx, false_rtx = XEXP(false_rtx, 0), true_rtx = const0_rtx; 537618334Speter 537790075Sobrien term2 = gen_binary (AND, GET_MODE (src), 537890075Sobrien XEXP (XEXP (src, 0), 0), true_rtx); 537918334Speter term3 = gen_binary (AND, GET_MODE (src), 538090075Sobrien simplify_gen_unary (NOT, GET_MODE (src), 538190075Sobrien XEXP (XEXP (src, 0), 0), 538290075Sobrien GET_MODE (src)), 538390075Sobrien false_rtx); 538418334Speter 538518334Speter SUBST (SET_SRC (x), 538618334Speter gen_binary (IOR, GET_MODE (src), 538718334Speter gen_binary (IOR, GET_MODE (src), term1, term2), 538818334Speter term3)); 538918334Speter 539018334Speter src = SET_SRC (x); 539118334Speter } 539218334Speter 539318334Speter /* If either SRC or DEST is a CLOBBER of (const_int 0), make this 539418334Speter whole thing fail. */ 539518334Speter if (GET_CODE (src) == CLOBBER && XEXP (src, 0) == const0_rtx) 539618334Speter return src; 539718334Speter else if (GET_CODE (dest) == CLOBBER && XEXP (dest, 0) == const0_rtx) 539818334Speter return dest; 539918334Speter else 540018334Speter /* Convert this into a field assignment operation, if possible. */ 540118334Speter return make_field_assignment (x); 540218334Speter} 540318334Speter 540418334Speter/* Simplify, X, and AND, IOR, or XOR operation, and return the simplified 540518334Speter result. LAST is nonzero if this is the last retry. */ 540618334Speter 540718334Speterstatic rtx 540818334Spetersimplify_logical (x, last) 540918334Speter rtx x; 541018334Speter int last; 541118334Speter{ 541218334Speter enum machine_mode mode = GET_MODE (x); 541318334Speter rtx op0 = XEXP (x, 0); 541418334Speter rtx op1 = XEXP (x, 1); 541590075Sobrien rtx reversed; 541618334Speter 541718334Speter switch (GET_CODE (x)) 541818334Speter { 541918334Speter case AND: 542090075Sobrien /* Convert (A ^ B) & A to A & (~B) since the latter is often a single 542118334Speter insn (and may simplify more). */ 542218334Speter if (GET_CODE (op0) == XOR 542318334Speter && rtx_equal_p (XEXP (op0, 0), op1) 542418334Speter && ! side_effects_p (op1)) 542518334Speter x = gen_binary (AND, mode, 542690075Sobrien simplify_gen_unary (NOT, mode, XEXP (op0, 1), mode), 542790075Sobrien op1); 542818334Speter 542918334Speter if (GET_CODE (op0) == XOR 543018334Speter && rtx_equal_p (XEXP (op0, 1), op1) 543118334Speter && ! side_effects_p (op1)) 543218334Speter x = gen_binary (AND, mode, 543390075Sobrien simplify_gen_unary (NOT, mode, XEXP (op0, 0), mode), 543490075Sobrien op1); 543518334Speter 543690075Sobrien /* Similarly for (~(A ^ B)) & A. */ 543718334Speter if (GET_CODE (op0) == NOT 543818334Speter && GET_CODE (XEXP (op0, 0)) == XOR 543918334Speter && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1) 544018334Speter && ! side_effects_p (op1)) 544118334Speter x = gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1); 544218334Speter 544318334Speter if (GET_CODE (op0) == NOT 544418334Speter && GET_CODE (XEXP (op0, 0)) == XOR 544518334Speter && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1) 544618334Speter && ! side_effects_p (op1)) 544718334Speter x = gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1); 544818334Speter 544990075Sobrien /* We can call simplify_and_const_int only if we don't lose 545090075Sobrien any (sign) bits when converting INTVAL (op1) to 545190075Sobrien "unsigned HOST_WIDE_INT". */ 545290075Sobrien if (GET_CODE (op1) == CONST_INT 545390075Sobrien && (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 545490075Sobrien || INTVAL (op1) > 0)) 545518334Speter { 545618334Speter x = simplify_and_const_int (x, mode, op0, INTVAL (op1)); 545718334Speter 545818334Speter /* If we have (ior (and (X C1) C2)) and the next restart would be 545918334Speter the last, simplify this by making C1 as small as possible 546050397Sobrien and then exit. */ 546118334Speter if (last 546218334Speter && GET_CODE (x) == IOR && GET_CODE (op0) == AND 546318334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 546418334Speter && GET_CODE (op1) == CONST_INT) 546518334Speter return gen_binary (IOR, mode, 546618334Speter gen_binary (AND, mode, XEXP (op0, 0), 546718334Speter GEN_INT (INTVAL (XEXP (op0, 1)) 546890075Sobrien & ~INTVAL (op1))), op1); 546918334Speter 547018334Speter if (GET_CODE (x) != AND) 547118334Speter return x; 547218334Speter 547390075Sobrien if (GET_RTX_CLASS (GET_CODE (x)) == 'c' 547418334Speter || GET_RTX_CLASS (GET_CODE (x)) == '2') 547518334Speter op0 = XEXP (x, 0), op1 = XEXP (x, 1); 547618334Speter } 547718334Speter 547818334Speter /* Convert (A | B) & A to A. */ 547918334Speter if (GET_CODE (op0) == IOR 548018334Speter && (rtx_equal_p (XEXP (op0, 0), op1) 548118334Speter || rtx_equal_p (XEXP (op0, 1), op1)) 548218334Speter && ! side_effects_p (XEXP (op0, 0)) 548318334Speter && ! side_effects_p (XEXP (op0, 1))) 548418334Speter return op1; 548518334Speter 548618334Speter /* In the following group of tests (and those in case IOR below), 548718334Speter we start with some combination of logical operations and apply 548818334Speter the distributive law followed by the inverse distributive law. 548918334Speter Most of the time, this results in no change. However, if some of 549018334Speter the operands are the same or inverses of each other, simplifications 549118334Speter will result. 549218334Speter 549318334Speter For example, (and (ior A B) (not B)) can occur as the result of 549418334Speter expanding a bit field assignment. When we apply the distributive 549518334Speter law to this, we get (ior (and (A (not B))) (and (B (not B)))), 549690075Sobrien which then simplifies to (and (A (not B))). 549718334Speter 549818334Speter If we have (and (ior A B) C), apply the distributive law and then 549918334Speter the inverse distributive law to see if things simplify. */ 550018334Speter 550118334Speter if (GET_CODE (op0) == IOR || GET_CODE (op0) == XOR) 550218334Speter { 550318334Speter x = apply_distributive_law 550418334Speter (gen_binary (GET_CODE (op0), mode, 550518334Speter gen_binary (AND, mode, XEXP (op0, 0), op1), 550670635Sobrien gen_binary (AND, mode, XEXP (op0, 1), 550770635Sobrien copy_rtx (op1)))); 550818334Speter if (GET_CODE (x) != AND) 550918334Speter return x; 551018334Speter } 551118334Speter 551218334Speter if (GET_CODE (op1) == IOR || GET_CODE (op1) == XOR) 551318334Speter return apply_distributive_law 551418334Speter (gen_binary (GET_CODE (op1), mode, 551518334Speter gen_binary (AND, mode, XEXP (op1, 0), op0), 551670635Sobrien gen_binary (AND, mode, XEXP (op1, 1), 551770635Sobrien copy_rtx (op0)))); 551818334Speter 551918334Speter /* Similarly, taking advantage of the fact that 552018334Speter (and (not A) (xor B C)) == (xor (ior A B) (ior A C)) */ 552118334Speter 552218334Speter if (GET_CODE (op0) == NOT && GET_CODE (op1) == XOR) 552318334Speter return apply_distributive_law 552418334Speter (gen_binary (XOR, mode, 552518334Speter gen_binary (IOR, mode, XEXP (op0, 0), XEXP (op1, 0)), 552670635Sobrien gen_binary (IOR, mode, copy_rtx (XEXP (op0, 0)), 552770635Sobrien XEXP (op1, 1)))); 552890075Sobrien 552918334Speter else if (GET_CODE (op1) == NOT && GET_CODE (op0) == XOR) 553018334Speter return apply_distributive_law 553118334Speter (gen_binary (XOR, mode, 553218334Speter gen_binary (IOR, mode, XEXP (op1, 0), XEXP (op0, 0)), 553370635Sobrien gen_binary (IOR, mode, copy_rtx (XEXP (op1, 0)), XEXP (op0, 1)))); 553418334Speter break; 553518334Speter 553618334Speter case IOR: 553718334Speter /* (ior A C) is C if all bits of A that might be nonzero are on in C. */ 553818334Speter if (GET_CODE (op1) == CONST_INT 553918334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 554090075Sobrien && (nonzero_bits (op0, mode) & ~INTVAL (op1)) == 0) 554118334Speter return op1; 554218334Speter 554318334Speter /* Convert (A & B) | A to A. */ 554418334Speter if (GET_CODE (op0) == AND 554518334Speter && (rtx_equal_p (XEXP (op0, 0), op1) 554618334Speter || rtx_equal_p (XEXP (op0, 1), op1)) 554718334Speter && ! side_effects_p (XEXP (op0, 0)) 554818334Speter && ! side_effects_p (XEXP (op0, 1))) 554918334Speter return op1; 555018334Speter 555118334Speter /* If we have (ior (and A B) C), apply the distributive law and then 555218334Speter the inverse distributive law to see if things simplify. */ 555318334Speter 555418334Speter if (GET_CODE (op0) == AND) 555518334Speter { 555618334Speter x = apply_distributive_law 555718334Speter (gen_binary (AND, mode, 555818334Speter gen_binary (IOR, mode, XEXP (op0, 0), op1), 555970635Sobrien gen_binary (IOR, mode, XEXP (op0, 1), 556070635Sobrien copy_rtx (op1)))); 556118334Speter 556218334Speter if (GET_CODE (x) != IOR) 556318334Speter return x; 556418334Speter } 556518334Speter 556618334Speter if (GET_CODE (op1) == AND) 556718334Speter { 556818334Speter x = apply_distributive_law 556918334Speter (gen_binary (AND, mode, 557018334Speter gen_binary (IOR, mode, XEXP (op1, 0), op0), 557170635Sobrien gen_binary (IOR, mode, XEXP (op1, 1), 557270635Sobrien copy_rtx (op0)))); 557318334Speter 557418334Speter if (GET_CODE (x) != IOR) 557518334Speter return x; 557618334Speter } 557718334Speter 557818334Speter /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the 557918334Speter mode size to (rotate A CX). */ 558018334Speter 558118334Speter if (((GET_CODE (op0) == ASHIFT && GET_CODE (op1) == LSHIFTRT) 558218334Speter || (GET_CODE (op1) == ASHIFT && GET_CODE (op0) == LSHIFTRT)) 558318334Speter && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)) 558418334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 558518334Speter && GET_CODE (XEXP (op1, 1)) == CONST_INT 558618334Speter && (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)) 558718334Speter == GET_MODE_BITSIZE (mode))) 558850397Sobrien return gen_rtx_ROTATE (mode, XEXP (op0, 0), 558950397Sobrien (GET_CODE (op0) == ASHIFT 559050397Sobrien ? XEXP (op0, 1) : XEXP (op1, 1))); 559118334Speter 559218334Speter /* If OP0 is (ashiftrt (plus ...) C), it might actually be 559318334Speter a (sign_extend (plus ...)). If so, OP1 is a CONST_INT, and the PLUS 559418334Speter does not affect any of the bits in OP1, it can really be done 559518334Speter as a PLUS and we can associate. We do this by seeing if OP1 559618334Speter can be safely shifted left C bits. */ 559718334Speter if (GET_CODE (op1) == CONST_INT && GET_CODE (op0) == ASHIFTRT 559818334Speter && GET_CODE (XEXP (op0, 0)) == PLUS 559918334Speter && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT 560018334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 560118334Speter && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT) 560218334Speter { 560318334Speter int count = INTVAL (XEXP (op0, 1)); 560418334Speter HOST_WIDE_INT mask = INTVAL (op1) << count; 560518334Speter 560618334Speter if (mask >> count == INTVAL (op1) 560718334Speter && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0) 560818334Speter { 560918334Speter SUBST (XEXP (XEXP (op0, 0), 1), 561018334Speter GEN_INT (INTVAL (XEXP (XEXP (op0, 0), 1)) | mask)); 561118334Speter return op0; 561218334Speter } 561318334Speter } 561418334Speter break; 561518334Speter 561618334Speter case XOR: 561790075Sobrien /* If we are XORing two things that have no bits in common, 561890075Sobrien convert them into an IOR. This helps to detect rotation encoded 561990075Sobrien using those methods and possibly other simplifications. */ 562090075Sobrien 562190075Sobrien if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 562290075Sobrien && (nonzero_bits (op0, mode) 562390075Sobrien & nonzero_bits (op1, mode)) == 0) 562490075Sobrien return (gen_binary (IOR, mode, op0, op1)); 562590075Sobrien 562618334Speter /* Convert (XOR (NOT x) (NOT y)) to (XOR x y). 562718334Speter Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for 562818334Speter (NOT y). */ 562918334Speter { 563018334Speter int num_negated = 0; 563118334Speter 563218334Speter if (GET_CODE (op0) == NOT) 563318334Speter num_negated++, op0 = XEXP (op0, 0); 563418334Speter if (GET_CODE (op1) == NOT) 563518334Speter num_negated++, op1 = XEXP (op1, 0); 563618334Speter 563718334Speter if (num_negated == 2) 563818334Speter { 563918334Speter SUBST (XEXP (x, 0), op0); 564018334Speter SUBST (XEXP (x, 1), op1); 564118334Speter } 564218334Speter else if (num_negated == 1) 564390075Sobrien return 564490075Sobrien simplify_gen_unary (NOT, mode, gen_binary (XOR, mode, op0, op1), 564590075Sobrien mode); 564618334Speter } 564718334Speter 564818334Speter /* Convert (xor (and A B) B) to (and (not A) B). The latter may 564918334Speter correspond to a machine insn or result in further simplifications 565018334Speter if B is a constant. */ 565118334Speter 565218334Speter if (GET_CODE (op0) == AND 565318334Speter && rtx_equal_p (XEXP (op0, 1), op1) 565418334Speter && ! side_effects_p (op1)) 565518334Speter return gen_binary (AND, mode, 565690075Sobrien simplify_gen_unary (NOT, mode, XEXP (op0, 0), mode), 565718334Speter op1); 565818334Speter 565918334Speter else if (GET_CODE (op0) == AND 566018334Speter && rtx_equal_p (XEXP (op0, 0), op1) 566118334Speter && ! side_effects_p (op1)) 566218334Speter return gen_binary (AND, mode, 566390075Sobrien simplify_gen_unary (NOT, mode, XEXP (op0, 1), mode), 566418334Speter op1); 566518334Speter 566618334Speter /* (xor (comparison foo bar) (const_int 1)) can become the reversed 566750397Sobrien comparison if STORE_FLAG_VALUE is 1. */ 566850397Sobrien if (STORE_FLAG_VALUE == 1 566950397Sobrien && op1 == const1_rtx 567018334Speter && GET_RTX_CLASS (GET_CODE (op0)) == '<' 567190075Sobrien && (reversed = reversed_comparison (op0, mode, XEXP (op0, 0), 567290075Sobrien XEXP (op0, 1)))) 567390075Sobrien return reversed; 567418334Speter 567518334Speter /* (lshiftrt foo C) where C is the number of bits in FOO minus 1 567618334Speter is (lt foo (const_int 0)), so we can perform the above 567750397Sobrien simplification if STORE_FLAG_VALUE is 1. */ 567818334Speter 567950397Sobrien if (STORE_FLAG_VALUE == 1 568050397Sobrien && op1 == const1_rtx 568118334Speter && GET_CODE (op0) == LSHIFTRT 568218334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 568318334Speter && INTVAL (XEXP (op0, 1)) == GET_MODE_BITSIZE (mode) - 1) 568490075Sobrien return gen_rtx_GE (mode, XEXP (op0, 0), const0_rtx); 568518334Speter 568618334Speter /* (xor (comparison foo bar) (const_int sign-bit)) 568718334Speter when STORE_FLAG_VALUE is the sign bit. */ 568818334Speter if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 568950397Sobrien && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode)) 569052284Sobrien == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)) 569118334Speter && op1 == const_true_rtx 569218334Speter && GET_RTX_CLASS (GET_CODE (op0)) == '<' 569390075Sobrien && (reversed = reversed_comparison (op0, mode, XEXP (op0, 0), 569490075Sobrien XEXP (op0, 1)))) 569590075Sobrien return reversed; 569690075Sobrien 569718334Speter break; 569850397Sobrien 569950397Sobrien default: 570050397Sobrien abort (); 570118334Speter } 570218334Speter 570318334Speter return x; 570418334Speter} 570518334Speter 570618334Speter/* We consider ZERO_EXTRACT, SIGN_EXTRACT, and SIGN_EXTEND as "compound 570718334Speter operations" because they can be replaced with two more basic operations. 570818334Speter ZERO_EXTEND is also considered "compound" because it can be replaced with 570918334Speter an AND operation, which is simpler, though only one operation. 571018334Speter 571118334Speter The function expand_compound_operation is called with an rtx expression 571290075Sobrien and will convert it to the appropriate shifts and AND operations, 571318334Speter simplifying at each stage. 571418334Speter 571518334Speter The function make_compound_operation is called to convert an expression 571618334Speter consisting of shifts and ANDs into the equivalent compound expression. 571718334Speter It is the inverse of this function, loosely speaking. */ 571818334Speter 571918334Speterstatic rtx 572018334Speterexpand_compound_operation (x) 572118334Speter rtx x; 572218334Speter{ 572390075Sobrien unsigned HOST_WIDE_INT pos = 0, len; 572418334Speter int unsignedp = 0; 572590075Sobrien unsigned int modewidth; 572618334Speter rtx tem; 572718334Speter 572818334Speter switch (GET_CODE (x)) 572918334Speter { 573018334Speter case ZERO_EXTEND: 573118334Speter unsignedp = 1; 573218334Speter case SIGN_EXTEND: 573318334Speter /* We can't necessarily use a const_int for a multiword mode; 573418334Speter it depends on implicitly extending the value. 573518334Speter Since we don't know the right way to extend it, 573618334Speter we can't tell whether the implicit way is right. 573718334Speter 573818334Speter Even for a mode that is no wider than a const_int, 573918334Speter we can't win, because we need to sign extend one of its bits through 574018334Speter the rest of it, and we don't know which bit. */ 574118334Speter if (GET_CODE (XEXP (x, 0)) == CONST_INT) 574218334Speter return x; 574318334Speter 574418334Speter /* Return if (subreg:MODE FROM 0) is not a safe replacement for 574518334Speter (zero_extend:MODE FROM) or (sign_extend:MODE FROM). It is for any MEM 574618334Speter because (SUBREG (MEM...)) is guaranteed to cause the MEM to be 574718334Speter reloaded. If not for that, MEM's would very rarely be safe. 574818334Speter 574918334Speter Reject MODEs bigger than a word, because we might not be able 575018334Speter to reference a two-register group starting with an arbitrary register 575118334Speter (and currently gen_lowpart might crash for a SUBREG). */ 575290075Sobrien 575318334Speter if (GET_MODE_SIZE (GET_MODE (XEXP (x, 0))) > UNITS_PER_WORD) 575418334Speter return x; 575518334Speter 5756117395Skan /* Reject MODEs that aren't scalar integers because turning vector 5757117395Skan or complex modes into shifts causes problems. */ 5758117395Skan 5759117395Skan if (! SCALAR_INT_MODE_P (GET_MODE (XEXP (x, 0)))) 5760117395Skan return x; 5761117395Skan 576218334Speter len = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))); 576318334Speter /* If the inner object has VOIDmode (the only way this can happen 5764117395Skan is if it is an ASM_OPERANDS), we can't do anything since we don't 576518334Speter know how much masking to do. */ 576618334Speter if (len == 0) 576718334Speter return x; 576818334Speter 576918334Speter break; 577018334Speter 577118334Speter case ZERO_EXTRACT: 577218334Speter unsignedp = 1; 577318334Speter case SIGN_EXTRACT: 577418334Speter /* If the operand is a CLOBBER, just return it. */ 577518334Speter if (GET_CODE (XEXP (x, 0)) == CLOBBER) 577618334Speter return XEXP (x, 0); 577718334Speter 577818334Speter if (GET_CODE (XEXP (x, 1)) != CONST_INT 577918334Speter || GET_CODE (XEXP (x, 2)) != CONST_INT 578018334Speter || GET_MODE (XEXP (x, 0)) == VOIDmode) 578118334Speter return x; 578218334Speter 5783117395Skan /* Reject MODEs that aren't scalar integers because turning vector 5784117395Skan or complex modes into shifts causes problems. */ 5785117395Skan 5786117395Skan if (! SCALAR_INT_MODE_P (GET_MODE (XEXP (x, 0)))) 5787117395Skan return x; 5788117395Skan 578918334Speter len = INTVAL (XEXP (x, 1)); 579018334Speter pos = INTVAL (XEXP (x, 2)); 579118334Speter 579218334Speter /* If this goes outside the object being extracted, replace the object 579318334Speter with a (use (mem ...)) construct that only combine understands 579418334Speter and is used only for this purpose. */ 579518334Speter if (len + pos > GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))) 579650397Sobrien SUBST (XEXP (x, 0), gen_rtx_USE (GET_MODE (x), XEXP (x, 0))); 579718334Speter 579818334Speter if (BITS_BIG_ENDIAN) 579918334Speter pos = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - len - pos; 580018334Speter 580118334Speter break; 580218334Speter 580318334Speter default: 580418334Speter return x; 580518334Speter } 580690075Sobrien /* Convert sign extension to zero extension, if we know that the high 580790075Sobrien bit is not set, as this is easier to optimize. It will be converted 580890075Sobrien back to cheaper alternative in make_extraction. */ 580990075Sobrien if (GET_CODE (x) == SIGN_EXTEND 581090075Sobrien && (GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT 581190075Sobrien && ((nonzero_bits (XEXP (x, 0), GET_MODE (XEXP (x, 0))) 581290075Sobrien & ~(((unsigned HOST_WIDE_INT) 581390075Sobrien GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) 581490075Sobrien >> 1)) 581590075Sobrien == 0))) 581690075Sobrien { 581790075Sobrien rtx temp = gen_rtx_ZERO_EXTEND (GET_MODE (x), XEXP (x, 0)); 581890075Sobrien return expand_compound_operation (temp); 581990075Sobrien } 582018334Speter 582150397Sobrien /* We can optimize some special cases of ZERO_EXTEND. */ 582250397Sobrien if (GET_CODE (x) == ZERO_EXTEND) 582350397Sobrien { 582450397Sobrien /* (zero_extend:DI (truncate:SI foo:DI)) is just foo:DI if we 582550397Sobrien know that the last value didn't have any inappropriate bits 582650397Sobrien set. */ 582750397Sobrien if (GET_CODE (XEXP (x, 0)) == TRUNCATE 582850397Sobrien && GET_MODE (XEXP (XEXP (x, 0), 0)) == GET_MODE (x) 582950397Sobrien && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT 583050397Sobrien && (nonzero_bits (XEXP (XEXP (x, 0), 0), GET_MODE (x)) 583190075Sobrien & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0) 583250397Sobrien return XEXP (XEXP (x, 0), 0); 583350397Sobrien 583450397Sobrien /* Likewise for (zero_extend:DI (subreg:SI foo:DI 0)). */ 583550397Sobrien if (GET_CODE (XEXP (x, 0)) == SUBREG 583650397Sobrien && GET_MODE (SUBREG_REG (XEXP (x, 0))) == GET_MODE (x) 583750397Sobrien && subreg_lowpart_p (XEXP (x, 0)) 583850397Sobrien && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT 583950397Sobrien && (nonzero_bits (SUBREG_REG (XEXP (x, 0)), GET_MODE (x)) 584090075Sobrien & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0) 584150397Sobrien return SUBREG_REG (XEXP (x, 0)); 584250397Sobrien 584350397Sobrien /* (zero_extend:DI (truncate:SI foo:DI)) is just foo:DI when foo 584450397Sobrien is a comparison and STORE_FLAG_VALUE permits. This is like 584550397Sobrien the first case, but it works even when GET_MODE (x) is larger 584650397Sobrien than HOST_WIDE_INT. */ 584750397Sobrien if (GET_CODE (XEXP (x, 0)) == TRUNCATE 584850397Sobrien && GET_MODE (XEXP (XEXP (x, 0), 0)) == GET_MODE (x) 584950397Sobrien && GET_RTX_CLASS (GET_CODE (XEXP (XEXP (x, 0), 0))) == '<' 585050397Sobrien && (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) 585150397Sobrien <= HOST_BITS_PER_WIDE_INT) 585290075Sobrien && ((HOST_WIDE_INT) STORE_FLAG_VALUE 585390075Sobrien & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0) 585450397Sobrien return XEXP (XEXP (x, 0), 0); 585550397Sobrien 585650397Sobrien /* Likewise for (zero_extend:DI (subreg:SI foo:DI 0)). */ 585750397Sobrien if (GET_CODE (XEXP (x, 0)) == SUBREG 585850397Sobrien && GET_MODE (SUBREG_REG (XEXP (x, 0))) == GET_MODE (x) 585950397Sobrien && subreg_lowpart_p (XEXP (x, 0)) 586050397Sobrien && GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0)))) == '<' 586150397Sobrien && (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) 586250397Sobrien <= HOST_BITS_PER_WIDE_INT) 586350397Sobrien && ((HOST_WIDE_INT) STORE_FLAG_VALUE 586490075Sobrien & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0) 586550397Sobrien return SUBREG_REG (XEXP (x, 0)); 586650397Sobrien 586750397Sobrien } 586850397Sobrien 586918334Speter /* If we reach here, we want to return a pair of shifts. The inner 587018334Speter shift is a left shift of BITSIZE - POS - LEN bits. The outer 587118334Speter shift is a right shift of BITSIZE - LEN bits. It is arithmetic or 587218334Speter logical depending on the value of UNSIGNEDP. 587318334Speter 587418334Speter If this was a ZERO_EXTEND or ZERO_EXTRACT, this pair of shifts will be 587518334Speter converted into an AND of a shift. 587618334Speter 587718334Speter We must check for the case where the left shift would have a negative 587818334Speter count. This can happen in a case like (x >> 31) & 255 on machines 587918334Speter that can't shift by a constant. On those machines, we would first 588090075Sobrien combine the shift with the AND to produce a variable-position 588118334Speter extraction. Then the constant of 31 would be substituted in to produce 588218334Speter a such a position. */ 588318334Speter 588418334Speter modewidth = GET_MODE_BITSIZE (GET_MODE (x)); 588590075Sobrien if (modewidth + len >= pos) 588618334Speter tem = simplify_shift_const (NULL_RTX, unsignedp ? LSHIFTRT : ASHIFTRT, 588718334Speter GET_MODE (x), 588818334Speter simplify_shift_const (NULL_RTX, ASHIFT, 588918334Speter GET_MODE (x), 589018334Speter XEXP (x, 0), 589118334Speter modewidth - pos - len), 589218334Speter modewidth - len); 589318334Speter 589418334Speter else if (unsignedp && len < HOST_BITS_PER_WIDE_INT) 589518334Speter tem = simplify_and_const_int (NULL_RTX, GET_MODE (x), 589618334Speter simplify_shift_const (NULL_RTX, LSHIFTRT, 589718334Speter GET_MODE (x), 589818334Speter XEXP (x, 0), pos), 589918334Speter ((HOST_WIDE_INT) 1 << len) - 1); 590018334Speter else 590118334Speter /* Any other cases we can't handle. */ 590218334Speter return x; 590318334Speter 590418334Speter /* If we couldn't do this for some reason, return the original 590518334Speter expression. */ 590618334Speter if (GET_CODE (tem) == CLOBBER) 590718334Speter return x; 590818334Speter 590918334Speter return tem; 591018334Speter} 591118334Speter 591218334Speter/* X is a SET which contains an assignment of one object into 591318334Speter a part of another (such as a bit-field assignment, STRICT_LOW_PART, 591418334Speter or certain SUBREGS). If possible, convert it into a series of 591518334Speter logical operations. 591618334Speter 591718334Speter We half-heartedly support variable positions, but do not at all 591818334Speter support variable lengths. */ 591918334Speter 592018334Speterstatic rtx 592118334Speterexpand_field_assignment (x) 592218334Speter rtx x; 592318334Speter{ 592418334Speter rtx inner; 592550397Sobrien rtx pos; /* Always counts from low bit. */ 592618334Speter int len; 592718334Speter rtx mask; 592818334Speter enum machine_mode compute_mode; 592918334Speter 593018334Speter /* Loop until we find something we can't simplify. */ 593118334Speter while (1) 593218334Speter { 593318334Speter if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART 593418334Speter && GET_CODE (XEXP (SET_DEST (x), 0)) == SUBREG) 593518334Speter { 593618334Speter inner = SUBREG_REG (XEXP (SET_DEST (x), 0)); 593718334Speter len = GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0))); 593890075Sobrien pos = GEN_INT (subreg_lsb (XEXP (SET_DEST (x), 0))); 593918334Speter } 594018334Speter else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT 594118334Speter && GET_CODE (XEXP (SET_DEST (x), 1)) == CONST_INT) 594218334Speter { 594318334Speter inner = XEXP (SET_DEST (x), 0); 594418334Speter len = INTVAL (XEXP (SET_DEST (x), 1)); 594518334Speter pos = XEXP (SET_DEST (x), 2); 594618334Speter 594718334Speter /* If the position is constant and spans the width of INNER, 594818334Speter surround INNER with a USE to indicate this. */ 594918334Speter if (GET_CODE (pos) == CONST_INT 595018334Speter && INTVAL (pos) + len > GET_MODE_BITSIZE (GET_MODE (inner))) 595150397Sobrien inner = gen_rtx_USE (GET_MODE (SET_DEST (x)), inner); 595218334Speter 595318334Speter if (BITS_BIG_ENDIAN) 595418334Speter { 595518334Speter if (GET_CODE (pos) == CONST_INT) 595618334Speter pos = GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner)) - len 595718334Speter - INTVAL (pos)); 595818334Speter else if (GET_CODE (pos) == MINUS 595918334Speter && GET_CODE (XEXP (pos, 1)) == CONST_INT 596018334Speter && (INTVAL (XEXP (pos, 1)) 596118334Speter == GET_MODE_BITSIZE (GET_MODE (inner)) - len)) 596218334Speter /* If position is ADJUST - X, new position is X. */ 596318334Speter pos = XEXP (pos, 0); 596418334Speter else 596518334Speter pos = gen_binary (MINUS, GET_MODE (pos), 596618334Speter GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner)) 596718334Speter - len), 596818334Speter pos); 596918334Speter } 597018334Speter } 597118334Speter 597218334Speter /* A SUBREG between two modes that occupy the same numbers of words 597318334Speter can be done by moving the SUBREG to the source. */ 597418334Speter else if (GET_CODE (SET_DEST (x)) == SUBREG 597590075Sobrien /* We need SUBREGs to compute nonzero_bits properly. */ 597690075Sobrien && nonzero_sign_valid 597718334Speter && (((GET_MODE_SIZE (GET_MODE (SET_DEST (x))) 597818334Speter + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) 597918334Speter == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x)))) 598018334Speter + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))) 598118334Speter { 598250397Sobrien x = gen_rtx_SET (VOIDmode, SUBREG_REG (SET_DEST (x)), 598390075Sobrien gen_lowpart_for_combine 598490075Sobrien (GET_MODE (SUBREG_REG (SET_DEST (x))), 598590075Sobrien SET_SRC (x))); 598618334Speter continue; 598718334Speter } 598818334Speter else 598918334Speter break; 599018334Speter 599118334Speter while (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner)) 599218334Speter inner = SUBREG_REG (inner); 599318334Speter 599418334Speter compute_mode = GET_MODE (inner); 599518334Speter 5996117395Skan /* Don't attempt bitwise arithmetic on non scalar integer modes. */ 5997117395Skan if (! SCALAR_INT_MODE_P (compute_mode)) 599852284Sobrien { 599952284Sobrien enum machine_mode imode; 600052284Sobrien 6001117395Skan /* Don't do anything for vector or complex integral types. */ 600252284Sobrien if (! FLOAT_MODE_P (compute_mode)) 600352284Sobrien break; 600452284Sobrien 600552284Sobrien /* Try to find an integral mode to pun with. */ 600652284Sobrien imode = mode_for_size (GET_MODE_BITSIZE (compute_mode), MODE_INT, 0); 600752284Sobrien if (imode == BLKmode) 600852284Sobrien break; 600952284Sobrien 601052284Sobrien compute_mode = imode; 601152284Sobrien inner = gen_lowpart_for_combine (imode, inner); 601252284Sobrien } 601352284Sobrien 601418334Speter /* Compute a mask of LEN bits, if we can do this on the host machine. */ 601518334Speter if (len < HOST_BITS_PER_WIDE_INT) 601618334Speter mask = GEN_INT (((HOST_WIDE_INT) 1 << len) - 1); 601718334Speter else 601818334Speter break; 601918334Speter 602018334Speter /* Now compute the equivalent expression. Make a copy of INNER 602118334Speter for the SET_DEST in case it is a MEM into which we will substitute; 602218334Speter we don't want shared RTL in that case. */ 602390075Sobrien x = gen_rtx_SET 602490075Sobrien (VOIDmode, copy_rtx (inner), 602590075Sobrien gen_binary (IOR, compute_mode, 602690075Sobrien gen_binary (AND, compute_mode, 602790075Sobrien simplify_gen_unary (NOT, compute_mode, 602890075Sobrien gen_binary (ASHIFT, 602990075Sobrien compute_mode, 603090075Sobrien mask, pos), 603190075Sobrien compute_mode), 603290075Sobrien inner), 603390075Sobrien gen_binary (ASHIFT, compute_mode, 603490075Sobrien gen_binary (AND, compute_mode, 603590075Sobrien gen_lowpart_for_combine 603690075Sobrien (compute_mode, SET_SRC (x)), 603790075Sobrien mask), 603890075Sobrien pos))); 603918334Speter } 604018334Speter 604118334Speter return x; 604218334Speter} 604318334Speter 604418334Speter/* Return an RTX for a reference to LEN bits of INNER. If POS_RTX is nonzero, 604518334Speter it is an RTX that represents a variable starting position; otherwise, 604618334Speter POS is the (constant) starting bit position (counted from the LSB). 604718334Speter 604818334Speter INNER may be a USE. This will occur when we started with a bitfield 604918334Speter that went outside the boundary of the object in memory, which is 605018334Speter allowed on most machines. To isolate this case, we produce a USE 605118334Speter whose mode is wide enough and surround the MEM with it. The only 605218334Speter code that understands the USE is this routine. If it is not removed, 605318334Speter it will cause the resulting insn not to match. 605418334Speter 6055117395Skan UNSIGNEDP is nonzero for an unsigned reference and zero for a 605618334Speter signed reference. 605718334Speter 6058117395Skan IN_DEST is nonzero if this is a reference in the destination of a 6059117395Skan SET. This is used when a ZERO_ or SIGN_EXTRACT isn't needed. If nonzero, 606018334Speter a STRICT_LOW_PART will be used, if zero, ZERO_EXTEND or SIGN_EXTEND will 606118334Speter be used. 606218334Speter 6063117395Skan IN_COMPARE is nonzero if we are in a COMPARE. This means that a 606418334Speter ZERO_EXTRACT should be built even for bits starting at bit 0. 606518334Speter 606650397Sobrien MODE is the desired mode of the result (if IN_DEST == 0). 606718334Speter 606850397Sobrien The result is an RTX for the extraction or NULL_RTX if the target 606950397Sobrien can't handle it. */ 607050397Sobrien 607118334Speterstatic rtx 607218334Spetermake_extraction (mode, inner, pos, pos_rtx, len, 607318334Speter unsignedp, in_dest, in_compare) 607418334Speter enum machine_mode mode; 607518334Speter rtx inner; 607690075Sobrien HOST_WIDE_INT pos; 607718334Speter rtx pos_rtx; 607890075Sobrien unsigned HOST_WIDE_INT len; 607918334Speter int unsignedp; 608018334Speter int in_dest, in_compare; 608118334Speter{ 608218334Speter /* This mode describes the size of the storage area 608318334Speter to fetch the overall value from. Within that, we 608418334Speter ignore the POS lowest bits, etc. */ 608518334Speter enum machine_mode is_mode = GET_MODE (inner); 608618334Speter enum machine_mode inner_mode; 608750397Sobrien enum machine_mode wanted_inner_mode = byte_mode; 608850397Sobrien enum machine_mode wanted_inner_reg_mode = word_mode; 608918334Speter enum machine_mode pos_mode = word_mode; 609018334Speter enum machine_mode extraction_mode = word_mode; 609118334Speter enum machine_mode tmode = mode_for_size (len, MODE_INT, 1); 609218334Speter int spans_byte = 0; 609318334Speter rtx new = 0; 609418334Speter rtx orig_pos_rtx = pos_rtx; 609590075Sobrien HOST_WIDE_INT orig_pos; 609618334Speter 609718334Speter /* Get some information about INNER and get the innermost object. */ 609818334Speter if (GET_CODE (inner) == USE) 609918334Speter /* (use:SI (mem:QI foo)) stands for (mem:SI foo). */ 610018334Speter /* We don't need to adjust the position because we set up the USE 610118334Speter to pretend that it was a full-word object. */ 610218334Speter spans_byte = 1, inner = XEXP (inner, 0); 610318334Speter else if (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner)) 610418334Speter { 610518334Speter /* If going from (subreg:SI (mem:QI ...)) to (mem:QI ...), 610618334Speter consider just the QI as the memory to extract from. 610718334Speter The subreg adds or removes high bits; its mode is 610818334Speter irrelevant to the meaning of this extraction, 610918334Speter since POS and LEN count from the lsb. */ 611018334Speter if (GET_CODE (SUBREG_REG (inner)) == MEM) 611118334Speter is_mode = GET_MODE (SUBREG_REG (inner)); 611218334Speter inner = SUBREG_REG (inner); 611318334Speter } 6114117395Skan else if (GET_CODE (inner) == ASHIFT 6115117395Skan && GET_CODE (XEXP (inner, 1)) == CONST_INT 6116117395Skan && pos_rtx == 0 && pos == 0 6117117395Skan && len > (unsigned HOST_WIDE_INT) INTVAL (XEXP (inner, 1))) 6118117395Skan { 6119117395Skan /* We're extracting the least significant bits of an rtx 6120117395Skan (ashift X (const_int C)), where LEN > C. Extract the 6121117395Skan least significant (LEN - C) bits of X, giving an rtx 6122117395Skan whose mode is MODE, then shift it left C times. */ 6123117395Skan new = make_extraction (mode, XEXP (inner, 0), 6124117395Skan 0, 0, len - INTVAL (XEXP (inner, 1)), 6125117395Skan unsignedp, in_dest, in_compare); 6126117395Skan if (new != 0) 6127117395Skan return gen_rtx_ASHIFT (mode, new, XEXP (inner, 1)); 6128117395Skan } 612918334Speter 613018334Speter inner_mode = GET_MODE (inner); 613118334Speter 613218334Speter if (pos_rtx && GET_CODE (pos_rtx) == CONST_INT) 613318334Speter pos = INTVAL (pos_rtx), pos_rtx = 0; 613418334Speter 613518334Speter /* See if this can be done without an extraction. We never can if the 613618334Speter width of the field is not the same as that of some integer mode. For 613718334Speter registers, we can only avoid the extraction if the position is at the 613818334Speter low-order bit and this is either not in the destination or we have the 613918334Speter appropriate STRICT_LOW_PART operation available. 614018334Speter 614118334Speter For MEM, we can avoid an extract if the field starts on an appropriate 614218334Speter boundary and we can change the mode of the memory reference. However, 614318334Speter we cannot directly access the MEM if we have a USE and the underlying 614418334Speter MEM is not TMODE. This combination means that MEM was being used in a 614518334Speter context where bits outside its mode were being referenced; that is only 614618334Speter valid in bit-field insns. */ 614718334Speter 614818334Speter if (tmode != BLKmode 614918334Speter && ! (spans_byte && inner_mode != tmode) 615050397Sobrien && ((pos_rtx == 0 && (pos % BITS_PER_WORD) == 0 615150397Sobrien && GET_CODE (inner) != MEM 615218334Speter && (! in_dest 615318334Speter || (GET_CODE (inner) == REG 615490075Sobrien && have_insn_for (STRICT_LOW_PART, tmode)))) 615518334Speter || (GET_CODE (inner) == MEM && pos_rtx == 0 615618334Speter && (pos 615718334Speter % (STRICT_ALIGNMENT ? GET_MODE_ALIGNMENT (tmode) 615818334Speter : BITS_PER_UNIT)) == 0 615918334Speter /* We can't do this if we are widening INNER_MODE (it 616018334Speter may not be aligned, for one thing). */ 616118334Speter && GET_MODE_BITSIZE (inner_mode) >= GET_MODE_BITSIZE (tmode) 616218334Speter && (inner_mode == tmode 616318334Speter || (! mode_dependent_address_p (XEXP (inner, 0)) 616418334Speter && ! MEM_VOLATILE_P (inner)))))) 616518334Speter { 616618334Speter /* If INNER is a MEM, make a new MEM that encompasses just the desired 616718334Speter field. If the original and current mode are the same, we need not 616890075Sobrien adjust the offset. Otherwise, we do if bytes big endian. 616918334Speter 617050397Sobrien If INNER is not a MEM, get a piece consisting of just the field 617150397Sobrien of interest (in this case POS % BITS_PER_WORD must be 0). */ 617218334Speter 617318334Speter if (GET_CODE (inner) == MEM) 617418334Speter { 617590075Sobrien HOST_WIDE_INT offset; 617690075Sobrien 617718334Speter /* POS counts from lsb, but make OFFSET count in memory order. */ 617818334Speter if (BYTES_BIG_ENDIAN) 617918334Speter offset = (GET_MODE_BITSIZE (is_mode) - len - pos) / BITS_PER_UNIT; 618018334Speter else 618118334Speter offset = pos / BITS_PER_UNIT; 618218334Speter 618390075Sobrien new = adjust_address_nv (inner, tmode, offset); 618418334Speter } 618518334Speter else if (GET_CODE (inner) == REG) 618618334Speter { 618718334Speter /* We can't call gen_lowpart_for_combine here since we always want 618818334Speter a SUBREG and it would sometimes return a new hard register. */ 618918334Speter if (tmode != inner_mode) 619090075Sobrien { 619190075Sobrien HOST_WIDE_INT final_word = pos / BITS_PER_WORD; 619290075Sobrien 619390075Sobrien if (WORDS_BIG_ENDIAN 619490075Sobrien && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD) 619590075Sobrien final_word = ((GET_MODE_SIZE (inner_mode) 619690075Sobrien - GET_MODE_SIZE (tmode)) 619790075Sobrien / UNITS_PER_WORD) - final_word; 619890075Sobrien 619990075Sobrien final_word *= UNITS_PER_WORD; 620090075Sobrien if (BYTES_BIG_ENDIAN && 620190075Sobrien GET_MODE_SIZE (inner_mode) > GET_MODE_SIZE (tmode)) 620290075Sobrien final_word += (GET_MODE_SIZE (inner_mode) 620390075Sobrien - GET_MODE_SIZE (tmode)) % UNITS_PER_WORD; 620490075Sobrien 6205110611Skan /* Avoid creating invalid subregs, for example when 6206117395Skan simplifying (x>>32)&255. */ 6207110611Skan if (final_word >= GET_MODE_SIZE (inner_mode)) 6208110611Skan return NULL_RTX; 6209110611Skan 621090075Sobrien new = gen_rtx_SUBREG (tmode, inner, final_word); 621190075Sobrien } 621218334Speter else 621318334Speter new = inner; 621418334Speter } 621518334Speter else 621618334Speter new = force_to_mode (inner, tmode, 621718334Speter len >= HOST_BITS_PER_WIDE_INT 621890075Sobrien ? ~(unsigned HOST_WIDE_INT) 0 621990075Sobrien : ((unsigned HOST_WIDE_INT) 1 << len) - 1, 622018334Speter NULL_RTX, 0); 622118334Speter 622290075Sobrien /* If this extraction is going into the destination of a SET, 622318334Speter make a STRICT_LOW_PART unless we made a MEM. */ 622418334Speter 622518334Speter if (in_dest) 622618334Speter return (GET_CODE (new) == MEM ? new 622718334Speter : (GET_CODE (new) != SUBREG 622850397Sobrien ? gen_rtx_CLOBBER (tmode, const0_rtx) 622990075Sobrien : gen_rtx_STRICT_LOW_PART (VOIDmode, new))); 623018334Speter 623190075Sobrien if (mode == tmode) 623290075Sobrien return new; 623390075Sobrien 623496263Sobrien if (GET_CODE (new) == CONST_INT) 6235117395Skan return gen_int_mode (INTVAL (new), mode); 623696263Sobrien 623790075Sobrien /* If we know that no extraneous bits are set, and that the high 623890075Sobrien bit is not set, convert the extraction to the cheaper of 623990075Sobrien sign and zero extension, that are equivalent in these cases. */ 624090075Sobrien if (flag_expensive_optimizations 624190075Sobrien && (GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT 624290075Sobrien && ((nonzero_bits (new, tmode) 624390075Sobrien & ~(((unsigned HOST_WIDE_INT) 624490075Sobrien GET_MODE_MASK (tmode)) 624590075Sobrien >> 1)) 624690075Sobrien == 0))) 624790075Sobrien { 624890075Sobrien rtx temp = gen_rtx_ZERO_EXTEND (mode, new); 624990075Sobrien rtx temp1 = gen_rtx_SIGN_EXTEND (mode, new); 625090075Sobrien 625190075Sobrien /* Prefer ZERO_EXTENSION, since it gives more information to 625290075Sobrien backends. */ 625390075Sobrien if (rtx_cost (temp, SET) <= rtx_cost (temp1, SET)) 625490075Sobrien return temp; 625590075Sobrien return temp1; 625690075Sobrien } 625790075Sobrien 625818334Speter /* Otherwise, sign- or zero-extend unless we already are in the 625918334Speter proper mode. */ 626018334Speter 626190075Sobrien return (gen_rtx_fmt_e (unsignedp ? ZERO_EXTEND : SIGN_EXTEND, 626290075Sobrien mode, new)); 626318334Speter } 626418334Speter 626518334Speter /* Unless this is a COMPARE or we have a funny memory reference, 626618334Speter don't do anything with zero-extending field extracts starting at 626718334Speter the low-order bit since they are simple AND operations. */ 626818334Speter if (pos_rtx == 0 && pos == 0 && ! in_dest 626918334Speter && ! in_compare && ! spans_byte && unsignedp) 627018334Speter return 0; 627118334Speter 627290075Sobrien /* Unless we are allowed to span bytes or INNER is not MEM, reject this if 627390075Sobrien we would be spanning bytes or if the position is not a constant and the 627490075Sobrien length is not 1. In all other cases, we would only be going outside 627590075Sobrien our object in cases when an original shift would have been 627618334Speter undefined. */ 627790075Sobrien if (! spans_byte && GET_CODE (inner) == MEM 627818334Speter && ((pos_rtx == 0 && pos + len > GET_MODE_BITSIZE (is_mode)) 627918334Speter || (pos_rtx != 0 && len != 1))) 628018334Speter return 0; 628118334Speter 628250397Sobrien /* Get the mode to use should INNER not be a MEM, the mode for the position, 628318334Speter and the mode for the result. */ 628490075Sobrien if (in_dest && mode_for_extraction (EP_insv, -1) != MAX_MACHINE_MODE) 628518334Speter { 628690075Sobrien wanted_inner_reg_mode = mode_for_extraction (EP_insv, 0); 628790075Sobrien pos_mode = mode_for_extraction (EP_insv, 2); 628890075Sobrien extraction_mode = mode_for_extraction (EP_insv, 3); 628918334Speter } 629018334Speter 629190075Sobrien if (! in_dest && unsignedp 629290075Sobrien && mode_for_extraction (EP_extzv, -1) != MAX_MACHINE_MODE) 629318334Speter { 629490075Sobrien wanted_inner_reg_mode = mode_for_extraction (EP_extzv, 1); 629590075Sobrien pos_mode = mode_for_extraction (EP_extzv, 3); 629690075Sobrien extraction_mode = mode_for_extraction (EP_extzv, 0); 629718334Speter } 629818334Speter 629990075Sobrien if (! in_dest && ! unsignedp 630090075Sobrien && mode_for_extraction (EP_extv, -1) != MAX_MACHINE_MODE) 630118334Speter { 630290075Sobrien wanted_inner_reg_mode = mode_for_extraction (EP_extv, 1); 630390075Sobrien pos_mode = mode_for_extraction (EP_extv, 3); 630490075Sobrien extraction_mode = mode_for_extraction (EP_extv, 0); 630518334Speter } 630618334Speter 630718334Speter /* Never narrow an object, since that might not be safe. */ 630818334Speter 630918334Speter if (mode != VOIDmode 631018334Speter && GET_MODE_SIZE (extraction_mode) < GET_MODE_SIZE (mode)) 631118334Speter extraction_mode = mode; 631218334Speter 631318334Speter if (pos_rtx && GET_MODE (pos_rtx) != VOIDmode 631418334Speter && GET_MODE_SIZE (pos_mode) < GET_MODE_SIZE (GET_MODE (pos_rtx))) 631518334Speter pos_mode = GET_MODE (pos_rtx); 631618334Speter 631750397Sobrien /* If this is not from memory, the desired mode is wanted_inner_reg_mode; 631850397Sobrien if we have to change the mode of memory and cannot, the desired mode is 631950397Sobrien EXTRACTION_MODE. */ 632050397Sobrien if (GET_CODE (inner) != MEM) 632150397Sobrien wanted_inner_mode = wanted_inner_reg_mode; 632250397Sobrien else if (inner_mode != wanted_inner_mode 632350397Sobrien && (mode_dependent_address_p (XEXP (inner, 0)) 632450397Sobrien || MEM_VOLATILE_P (inner))) 632550397Sobrien wanted_inner_mode = extraction_mode; 632618334Speter 632718334Speter orig_pos = pos; 632818334Speter 632918334Speter if (BITS_BIG_ENDIAN) 633018334Speter { 633150397Sobrien /* POS is passed as if BITS_BIG_ENDIAN == 0, so we need to convert it to 633250397Sobrien BITS_BIG_ENDIAN style. If position is constant, compute new 633350397Sobrien position. Otherwise, build subtraction. 633450397Sobrien Note that POS is relative to the mode of the original argument. 633550397Sobrien If it's a MEM we need to recompute POS relative to that. 633650397Sobrien However, if we're extracting from (or inserting into) a register, 633750397Sobrien we want to recompute POS relative to wanted_inner_mode. */ 633850397Sobrien int width = (GET_CODE (inner) == MEM 633950397Sobrien ? GET_MODE_BITSIZE (is_mode) 634050397Sobrien : GET_MODE_BITSIZE (wanted_inner_mode)); 634150397Sobrien 634218334Speter if (pos_rtx == 0) 634350397Sobrien pos = width - len - pos; 634418334Speter else 634518334Speter pos_rtx 634690075Sobrien = gen_rtx_MINUS (GET_MODE (pos_rtx), GEN_INT (width - len), pos_rtx); 634750397Sobrien /* POS may be less than 0 now, but we check for that below. 634850397Sobrien Note that it can only be less than 0 if GET_CODE (inner) != MEM. */ 634918334Speter } 635018334Speter 635118334Speter /* If INNER has a wider mode, make it smaller. If this is a constant 635218334Speter extract, try to adjust the byte to point to the byte containing 635318334Speter the value. */ 635450397Sobrien if (wanted_inner_mode != VOIDmode 635550397Sobrien && GET_MODE_SIZE (wanted_inner_mode) < GET_MODE_SIZE (is_mode) 635618334Speter && ((GET_CODE (inner) == MEM 635750397Sobrien && (inner_mode == wanted_inner_mode 635818334Speter || (! mode_dependent_address_p (XEXP (inner, 0)) 635918334Speter && ! MEM_VOLATILE_P (inner)))))) 636018334Speter { 636118334Speter int offset = 0; 636218334Speter 636318334Speter /* The computations below will be correct if the machine is big 636418334Speter endian in both bits and bytes or little endian in bits and bytes. 636518334Speter If it is mixed, we must adjust. */ 636690075Sobrien 636718334Speter /* If bytes are big endian and we had a paradoxical SUBREG, we must 636850397Sobrien adjust OFFSET to compensate. */ 636918334Speter if (BYTES_BIG_ENDIAN 637018334Speter && ! spans_byte 637118334Speter && GET_MODE_SIZE (inner_mode) < GET_MODE_SIZE (is_mode)) 637218334Speter offset -= GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (inner_mode); 637318334Speter 637418334Speter /* If this is a constant position, we can move to the desired byte. */ 637518334Speter if (pos_rtx == 0) 637618334Speter { 637718334Speter offset += pos / BITS_PER_UNIT; 637850397Sobrien pos %= GET_MODE_BITSIZE (wanted_inner_mode); 637918334Speter } 638018334Speter 638118334Speter if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN 638218334Speter && ! spans_byte 638350397Sobrien && is_mode != wanted_inner_mode) 638418334Speter offset = (GET_MODE_SIZE (is_mode) 638550397Sobrien - GET_MODE_SIZE (wanted_inner_mode) - offset); 638618334Speter 638750397Sobrien if (offset != 0 || inner_mode != wanted_inner_mode) 638890075Sobrien inner = adjust_address_nv (inner, wanted_inner_mode, offset); 638918334Speter } 639018334Speter 639150397Sobrien /* If INNER is not memory, we can always get it into the proper mode. If we 639250397Sobrien are changing its mode, POS must be a constant and smaller than the size 639350397Sobrien of the new mode. */ 639418334Speter else if (GET_CODE (inner) != MEM) 639550397Sobrien { 639650397Sobrien if (GET_MODE (inner) != wanted_inner_mode 639750397Sobrien && (pos_rtx != 0 639850397Sobrien || orig_pos + len > GET_MODE_BITSIZE (wanted_inner_mode))) 639950397Sobrien return 0; 640018334Speter 640150397Sobrien inner = force_to_mode (inner, wanted_inner_mode, 640250397Sobrien pos_rtx 640350397Sobrien || len + orig_pos >= HOST_BITS_PER_WIDE_INT 640490075Sobrien ? ~(unsigned HOST_WIDE_INT) 0 640590075Sobrien : ((((unsigned HOST_WIDE_INT) 1 << len) - 1) 640690075Sobrien << orig_pos), 640750397Sobrien NULL_RTX, 0); 640850397Sobrien } 640950397Sobrien 641018334Speter /* Adjust mode of POS_RTX, if needed. If we want a wider mode, we 641118334Speter have to zero extend. Otherwise, we can just use a SUBREG. */ 641218334Speter if (pos_rtx != 0 641318334Speter && GET_MODE_SIZE (pos_mode) > GET_MODE_SIZE (GET_MODE (pos_rtx))) 641490075Sobrien { 641590075Sobrien rtx temp = gen_rtx_ZERO_EXTEND (pos_mode, pos_rtx); 641690075Sobrien 641790075Sobrien /* If we know that no extraneous bits are set, and that the high 641890075Sobrien bit is not set, convert extraction to cheaper one - either 641990075Sobrien SIGN_EXTENSION or ZERO_EXTENSION, that are equivalent in these 642090075Sobrien cases. */ 642190075Sobrien if (flag_expensive_optimizations 642290075Sobrien && (GET_MODE_BITSIZE (GET_MODE (pos_rtx)) <= HOST_BITS_PER_WIDE_INT 642390075Sobrien && ((nonzero_bits (pos_rtx, GET_MODE (pos_rtx)) 642490075Sobrien & ~(((unsigned HOST_WIDE_INT) 642590075Sobrien GET_MODE_MASK (GET_MODE (pos_rtx))) 642690075Sobrien >> 1)) 642790075Sobrien == 0))) 642890075Sobrien { 642990075Sobrien rtx temp1 = gen_rtx_SIGN_EXTEND (pos_mode, pos_rtx); 643090075Sobrien 643190075Sobrien /* Prefer ZERO_EXTENSION, since it gives more information to 643290075Sobrien backends. */ 643390075Sobrien if (rtx_cost (temp1, SET) < rtx_cost (temp, SET)) 643490075Sobrien temp = temp1; 643590075Sobrien } 643690075Sobrien pos_rtx = temp; 643790075Sobrien } 643818334Speter else if (pos_rtx != 0 643918334Speter && GET_MODE_SIZE (pos_mode) < GET_MODE_SIZE (GET_MODE (pos_rtx))) 644018334Speter pos_rtx = gen_lowpart_for_combine (pos_mode, pos_rtx); 644118334Speter 644218334Speter /* Make POS_RTX unless we already have it and it is correct. If we don't 644318334Speter have a POS_RTX but we do have an ORIG_POS_RTX, the latter must 644450397Sobrien be a CONST_INT. */ 644518334Speter if (pos_rtx == 0 && orig_pos_rtx != 0 && INTVAL (orig_pos_rtx) == pos) 644618334Speter pos_rtx = orig_pos_rtx; 644718334Speter 644818334Speter else if (pos_rtx == 0) 644918334Speter pos_rtx = GEN_INT (pos); 645018334Speter 645118334Speter /* Make the required operation. See if we can use existing rtx. */ 645290075Sobrien new = gen_rtx_fmt_eee (unsignedp ? ZERO_EXTRACT : SIGN_EXTRACT, 645318334Speter extraction_mode, inner, GEN_INT (len), pos_rtx); 645418334Speter if (! in_dest) 645518334Speter new = gen_lowpart_for_combine (mode, new); 645618334Speter 645718334Speter return new; 645818334Speter} 645918334Speter 646018334Speter/* See if X contains an ASHIFT of COUNT or more bits that can be commuted 646118334Speter with any other operations in X. Return X without that shift if so. */ 646218334Speter 646318334Speterstatic rtx 646418334Speterextract_left_shift (x, count) 646518334Speter rtx x; 646618334Speter int count; 646718334Speter{ 646818334Speter enum rtx_code code = GET_CODE (x); 646918334Speter enum machine_mode mode = GET_MODE (x); 647018334Speter rtx tem; 647118334Speter 647218334Speter switch (code) 647318334Speter { 647418334Speter case ASHIFT: 647518334Speter /* This is the shift itself. If it is wide enough, we will return 647618334Speter either the value being shifted if the shift count is equal to 647718334Speter COUNT or a shift for the difference. */ 647818334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 647918334Speter && INTVAL (XEXP (x, 1)) >= count) 648018334Speter return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (x, 0), 648118334Speter INTVAL (XEXP (x, 1)) - count); 648218334Speter break; 648318334Speter 648418334Speter case NEG: case NOT: 648518334Speter if ((tem = extract_left_shift (XEXP (x, 0), count)) != 0) 648690075Sobrien return simplify_gen_unary (code, mode, tem, mode); 648718334Speter 648818334Speter break; 648918334Speter 649018334Speter case PLUS: case IOR: case XOR: case AND: 649118334Speter /* If we can safely shift this constant and we find the inner shift, 649218334Speter make a new operation. */ 649318334Speter if (GET_CODE (XEXP (x,1)) == CONST_INT 649450397Sobrien && (INTVAL (XEXP (x, 1)) & ((((HOST_WIDE_INT) 1 << count)) - 1)) == 0 649518334Speter && (tem = extract_left_shift (XEXP (x, 0), count)) != 0) 649690075Sobrien return gen_binary (code, mode, tem, 649718334Speter GEN_INT (INTVAL (XEXP (x, 1)) >> count)); 649818334Speter 649918334Speter break; 650090075Sobrien 650150397Sobrien default: 650250397Sobrien break; 650318334Speter } 650418334Speter 650518334Speter return 0; 650618334Speter} 650718334Speter 650818334Speter/* Look at the expression rooted at X. Look for expressions 650918334Speter equivalent to ZERO_EXTRACT, SIGN_EXTRACT, ZERO_EXTEND, SIGN_EXTEND. 651018334Speter Form these expressions. 651118334Speter 651218334Speter Return the new rtx, usually just X. 651318334Speter 651490075Sobrien Also, for machines like the VAX that don't have logical shift insns, 651518334Speter try to convert logical to arithmetic shift operations in cases where 651618334Speter they are equivalent. This undoes the canonicalizations to logical 651718334Speter shifts done elsewhere. 651818334Speter 651918334Speter We try, as much as possible, to re-use rtl expressions to save memory. 652018334Speter 652118334Speter IN_CODE says what kind of expression we are processing. Normally, it is 652218334Speter SET. In a memory address (inside a MEM, PLUS or minus, the latter two 652318334Speter being kludges), it is MEM. When processing the arguments of a comparison 652418334Speter or a COMPARE against zero, it is COMPARE. */ 652518334Speter 652618334Speterstatic rtx 652718334Spetermake_compound_operation (x, in_code) 652818334Speter rtx x; 652918334Speter enum rtx_code in_code; 653018334Speter{ 653118334Speter enum rtx_code code = GET_CODE (x); 653218334Speter enum machine_mode mode = GET_MODE (x); 653318334Speter int mode_width = GET_MODE_BITSIZE (mode); 653418334Speter rtx rhs, lhs; 653518334Speter enum rtx_code next_code; 653618334Speter int i; 653718334Speter rtx new = 0; 653818334Speter rtx tem; 653990075Sobrien const char *fmt; 654018334Speter 654118334Speter /* Select the code to be used in recursive calls. Once we are inside an 654218334Speter address, we stay there. If we have a comparison, set to COMPARE, 654318334Speter but once inside, go back to our default of SET. */ 654418334Speter 654518334Speter next_code = (code == MEM || code == PLUS || code == MINUS ? MEM 654618334Speter : ((code == COMPARE || GET_RTX_CLASS (code) == '<') 654718334Speter && XEXP (x, 1) == const0_rtx) ? COMPARE 654818334Speter : in_code == COMPARE ? SET : in_code); 654918334Speter 655018334Speter /* Process depending on the code of this operation. If NEW is set 6551117395Skan nonzero, it will be returned. */ 655218334Speter 655318334Speter switch (code) 655418334Speter { 655518334Speter case ASHIFT: 655618334Speter /* Convert shifts by constants into multiplications if inside 655718334Speter an address. */ 655818334Speter if (in_code == MEM && GET_CODE (XEXP (x, 1)) == CONST_INT 655918334Speter && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT 656018334Speter && INTVAL (XEXP (x, 1)) >= 0) 656118334Speter { 656218334Speter new = make_compound_operation (XEXP (x, 0), next_code); 656390075Sobrien new = gen_rtx_MULT (mode, new, 656490075Sobrien GEN_INT ((HOST_WIDE_INT) 1 656590075Sobrien << INTVAL (XEXP (x, 1)))); 656618334Speter } 656718334Speter break; 656818334Speter 656918334Speter case AND: 657018334Speter /* If the second operand is not a constant, we can't do anything 657118334Speter with it. */ 657218334Speter if (GET_CODE (XEXP (x, 1)) != CONST_INT) 657318334Speter break; 657418334Speter 657518334Speter /* If the constant is a power of two minus one and the first operand 657618334Speter is a logical right shift, make an extraction. */ 657718334Speter if (GET_CODE (XEXP (x, 0)) == LSHIFTRT 657818334Speter && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0) 657918334Speter { 658018334Speter new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code); 658118334Speter new = make_extraction (mode, new, 0, XEXP (XEXP (x, 0), 1), i, 1, 658218334Speter 0, in_code == COMPARE); 658318334Speter } 658418334Speter 658518334Speter /* Same as previous, but for (subreg (lshiftrt ...)) in first op. */ 658618334Speter else if (GET_CODE (XEXP (x, 0)) == SUBREG 658718334Speter && subreg_lowpart_p (XEXP (x, 0)) 658818334Speter && GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT 658918334Speter && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0) 659018334Speter { 659118334Speter new = make_compound_operation (XEXP (SUBREG_REG (XEXP (x, 0)), 0), 659218334Speter next_code); 659318334Speter new = make_extraction (GET_MODE (SUBREG_REG (XEXP (x, 0))), new, 0, 659418334Speter XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1, 659518334Speter 0, in_code == COMPARE); 659618334Speter } 659718334Speter /* Same as previous, but for (xor/ior (lshiftrt...) (lshiftrt...)). */ 659818334Speter else if ((GET_CODE (XEXP (x, 0)) == XOR 659918334Speter || GET_CODE (XEXP (x, 0)) == IOR) 660018334Speter && GET_CODE (XEXP (XEXP (x, 0), 0)) == LSHIFTRT 660118334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == LSHIFTRT 660218334Speter && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0) 660318334Speter { 660418334Speter /* Apply the distributive law, and then try to make extractions. */ 660590075Sobrien new = gen_rtx_fmt_ee (GET_CODE (XEXP (x, 0)), mode, 660690075Sobrien gen_rtx_AND (mode, XEXP (XEXP (x, 0), 0), 660790075Sobrien XEXP (x, 1)), 660890075Sobrien gen_rtx_AND (mode, XEXP (XEXP (x, 0), 1), 660990075Sobrien XEXP (x, 1))); 661018334Speter new = make_compound_operation (new, in_code); 661118334Speter } 661218334Speter 661318334Speter /* If we are have (and (rotate X C) M) and C is larger than the number 661418334Speter of bits in M, this is an extraction. */ 661518334Speter 661618334Speter else if (GET_CODE (XEXP (x, 0)) == ROTATE 661718334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 661818334Speter && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0 661918334Speter && i <= INTVAL (XEXP (XEXP (x, 0), 1))) 662018334Speter { 662118334Speter new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code); 662218334Speter new = make_extraction (mode, new, 662318334Speter (GET_MODE_BITSIZE (mode) 662418334Speter - INTVAL (XEXP (XEXP (x, 0), 1))), 662518334Speter NULL_RTX, i, 1, 0, in_code == COMPARE); 662618334Speter } 662718334Speter 662818334Speter /* On machines without logical shifts, if the operand of the AND is 662918334Speter a logical shift and our mask turns off all the propagated sign 663018334Speter bits, we can replace the logical shift with an arithmetic shift. */ 663190075Sobrien else if (GET_CODE (XEXP (x, 0)) == LSHIFTRT 663290075Sobrien && !have_insn_for (LSHIFTRT, mode) 663390075Sobrien && have_insn_for (ASHIFTRT, mode) 663418334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 663518334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0 663618334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT 663718334Speter && mode_width <= HOST_BITS_PER_WIDE_INT) 663818334Speter { 663918334Speter unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode); 664018334Speter 664118334Speter mask >>= INTVAL (XEXP (XEXP (x, 0), 1)); 664218334Speter if ((INTVAL (XEXP (x, 1)) & ~mask) == 0) 664318334Speter SUBST (XEXP (x, 0), 664490075Sobrien gen_rtx_ASHIFTRT (mode, 664590075Sobrien make_compound_operation 664690075Sobrien (XEXP (XEXP (x, 0), 0), next_code), 664790075Sobrien XEXP (XEXP (x, 0), 1))); 664818334Speter } 664918334Speter 665018334Speter /* If the constant is one less than a power of two, this might be 665118334Speter representable by an extraction even if no shift is present. 665218334Speter If it doesn't end up being a ZERO_EXTEND, we will ignore it unless 665318334Speter we are in a COMPARE. */ 665418334Speter else if ((i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0) 665518334Speter new = make_extraction (mode, 665618334Speter make_compound_operation (XEXP (x, 0), 665718334Speter next_code), 665818334Speter 0, NULL_RTX, i, 1, 0, in_code == COMPARE); 665918334Speter 666018334Speter /* If we are in a comparison and this is an AND with a power of two, 666118334Speter convert this into the appropriate bit extract. */ 666218334Speter else if (in_code == COMPARE 666318334Speter && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0) 666418334Speter new = make_extraction (mode, 666518334Speter make_compound_operation (XEXP (x, 0), 666618334Speter next_code), 666718334Speter i, NULL_RTX, 1, 1, 0, 1); 666818334Speter 666918334Speter break; 667018334Speter 667118334Speter case LSHIFTRT: 667218334Speter /* If the sign bit is known to be zero, replace this with an 667318334Speter arithmetic shift. */ 667490075Sobrien if (have_insn_for (ASHIFTRT, mode) 667590075Sobrien && ! have_insn_for (LSHIFTRT, mode) 667618334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 667718334Speter && (nonzero_bits (XEXP (x, 0), mode) & (1 << (mode_width - 1))) == 0) 667818334Speter { 667990075Sobrien new = gen_rtx_ASHIFTRT (mode, 668090075Sobrien make_compound_operation (XEXP (x, 0), 668190075Sobrien next_code), 668290075Sobrien XEXP (x, 1)); 668318334Speter break; 668418334Speter } 668518334Speter 668650397Sobrien /* ... fall through ... */ 668718334Speter 668818334Speter case ASHIFTRT: 668918334Speter lhs = XEXP (x, 0); 669018334Speter rhs = XEXP (x, 1); 669118334Speter 669218334Speter /* If we have (ashiftrt (ashift foo C1) C2) with C2 >= C1, 669318334Speter this is a SIGN_EXTRACT. */ 669418334Speter if (GET_CODE (rhs) == CONST_INT 669518334Speter && GET_CODE (lhs) == ASHIFT 669618334Speter && GET_CODE (XEXP (lhs, 1)) == CONST_INT 669718334Speter && INTVAL (rhs) >= INTVAL (XEXP (lhs, 1))) 669818334Speter { 669918334Speter new = make_compound_operation (XEXP (lhs, 0), next_code); 670018334Speter new = make_extraction (mode, new, 670118334Speter INTVAL (rhs) - INTVAL (XEXP (lhs, 1)), 670218334Speter NULL_RTX, mode_width - INTVAL (rhs), 670318334Speter code == LSHIFTRT, 0, in_code == COMPARE); 670490075Sobrien break; 670518334Speter } 670618334Speter 670718334Speter /* See if we have operations between an ASHIFTRT and an ASHIFT. 670818334Speter If so, try to merge the shifts into a SIGN_EXTEND. We could 670918334Speter also do this for some cases of SIGN_EXTRACT, but it doesn't 671018334Speter seem worth the effort; the case checked for occurs on Alpha. */ 671190075Sobrien 671218334Speter if (GET_RTX_CLASS (GET_CODE (lhs)) != 'o' 671318334Speter && ! (GET_CODE (lhs) == SUBREG 671418334Speter && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (lhs))) == 'o')) 671518334Speter && GET_CODE (rhs) == CONST_INT 671618334Speter && INTVAL (rhs) < HOST_BITS_PER_WIDE_INT 671718334Speter && (new = extract_left_shift (lhs, INTVAL (rhs))) != 0) 671818334Speter new = make_extraction (mode, make_compound_operation (new, next_code), 671918334Speter 0, NULL_RTX, mode_width - INTVAL (rhs), 672018334Speter code == LSHIFTRT, 0, in_code == COMPARE); 672190075Sobrien 672218334Speter break; 672318334Speter 672418334Speter case SUBREG: 672518334Speter /* Call ourselves recursively on the inner expression. If we are 672618334Speter narrowing the object and it has a different RTL code from 672718334Speter what it originally did, do this SUBREG as a force_to_mode. */ 672818334Speter 672918334Speter tem = make_compound_operation (SUBREG_REG (x), in_code); 673018334Speter if (GET_CODE (tem) != GET_CODE (SUBREG_REG (x)) 673118334Speter && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (tem)) 673218334Speter && subreg_lowpart_p (x)) 673318334Speter { 673490075Sobrien rtx newer = force_to_mode (tem, mode, ~(HOST_WIDE_INT) 0, 673590075Sobrien NULL_RTX, 0); 673618334Speter 673718334Speter /* If we have something other than a SUBREG, we might have 673890075Sobrien done an expansion, so rerun ourselves. */ 673918334Speter if (GET_CODE (newer) != SUBREG) 674018334Speter newer = make_compound_operation (newer, in_code); 674118334Speter 674218334Speter return newer; 674318334Speter } 674450397Sobrien 674550397Sobrien /* If this is a paradoxical subreg, and the new code is a sign or 674650397Sobrien zero extension, omit the subreg and widen the extension. If it 674750397Sobrien is a regular subreg, we can still get rid of the subreg by not 674850397Sobrien widening so much, or in fact removing the extension entirely. */ 674950397Sobrien if ((GET_CODE (tem) == SIGN_EXTEND 675050397Sobrien || GET_CODE (tem) == ZERO_EXTEND) 675150397Sobrien && subreg_lowpart_p (x)) 675250397Sobrien { 675350397Sobrien if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (tem)) 675450397Sobrien || (GET_MODE_SIZE (mode) > 675550397Sobrien GET_MODE_SIZE (GET_MODE (XEXP (tem, 0))))) 6756117395Skan { 6757117395Skan if (! SCALAR_INT_MODE_P (mode)) 6758117395Skan break; 6759117395Skan tem = gen_rtx_fmt_e (GET_CODE (tem), mode, XEXP (tem, 0)); 6760117395Skan } 676150397Sobrien else 676250397Sobrien tem = gen_lowpart_for_combine (mode, XEXP (tem, 0)); 676350397Sobrien return tem; 676450397Sobrien } 676550397Sobrien break; 676690075Sobrien 676750397Sobrien default: 676850397Sobrien break; 676918334Speter } 677018334Speter 677118334Speter if (new) 677218334Speter { 677318334Speter x = gen_lowpart_for_combine (mode, new); 677418334Speter code = GET_CODE (x); 677518334Speter } 677618334Speter 677718334Speter /* Now recursively process each operand of this operation. */ 677818334Speter fmt = GET_RTX_FORMAT (code); 677918334Speter for (i = 0; i < GET_RTX_LENGTH (code); i++) 678018334Speter if (fmt[i] == 'e') 678118334Speter { 678218334Speter new = make_compound_operation (XEXP (x, i), next_code); 678318334Speter SUBST (XEXP (x, i), new); 678418334Speter } 678518334Speter 678618334Speter return x; 678718334Speter} 678818334Speter 678918334Speter/* Given M see if it is a value that would select a field of bits 679090075Sobrien within an item, but not the entire word. Return -1 if not. 679190075Sobrien Otherwise, return the starting position of the field, where 0 is the 679290075Sobrien low-order bit. 679318334Speter 679418334Speter *PLEN is set to the length of the field. */ 679518334Speter 679618334Speterstatic int 679718334Speterget_pos_from_mask (m, plen) 679818334Speter unsigned HOST_WIDE_INT m; 679990075Sobrien unsigned HOST_WIDE_INT *plen; 680018334Speter{ 680118334Speter /* Get the bit number of the first 1 bit from the right, -1 if none. */ 680290075Sobrien int pos = exact_log2 (m & -m); 680390075Sobrien int len; 680418334Speter 680518334Speter if (pos < 0) 680618334Speter return -1; 680718334Speter 680818334Speter /* Now shift off the low-order zero bits and see if we have a power of 680918334Speter two minus 1. */ 681090075Sobrien len = exact_log2 ((m >> pos) + 1); 681118334Speter 681290075Sobrien if (len <= 0) 681318334Speter return -1; 681418334Speter 681590075Sobrien *plen = len; 681618334Speter return pos; 681718334Speter} 681818334Speter 681918334Speter/* See if X can be simplified knowing that we will only refer to it in 682018334Speter MODE and will only refer to those bits that are nonzero in MASK. 682118334Speter If other bits are being computed or if masking operations are done 682218334Speter that select a superset of the bits in MASK, they can sometimes be 682318334Speter ignored. 682418334Speter 682518334Speter Return a possibly simplified expression, but always convert X to 682618334Speter MODE. If X is a CONST_INT, AND the CONST_INT with MASK. 682718334Speter 6828117395Skan Also, if REG is nonzero and X is a register equal in value to REG, 682918334Speter replace X with REG. 683018334Speter 683118334Speter If JUST_SELECT is nonzero, don't optimize by noticing that bits in MASK 683218334Speter are all off in X. This is used when X will be complemented, by either 683318334Speter NOT, NEG, or XOR. */ 683418334Speter 683518334Speterstatic rtx 683618334Speterforce_to_mode (x, mode, mask, reg, just_select) 683718334Speter rtx x; 683818334Speter enum machine_mode mode; 683918334Speter unsigned HOST_WIDE_INT mask; 684018334Speter rtx reg; 684118334Speter int just_select; 684218334Speter{ 684318334Speter enum rtx_code code = GET_CODE (x); 684418334Speter int next_select = just_select || code == XOR || code == NOT || code == NEG; 684518334Speter enum machine_mode op_mode; 684618334Speter unsigned HOST_WIDE_INT fuller_mask, nonzero; 684718334Speter rtx op0, op1, temp; 684818334Speter 684950397Sobrien /* If this is a CALL or ASM_OPERANDS, don't do anything. Some of the 685050397Sobrien code below will do the wrong thing since the mode of such an 685190075Sobrien expression is VOIDmode. 685250397Sobrien 685350397Sobrien Also do nothing if X is a CLOBBER; this can happen if X was 685450397Sobrien the return value from a call to gen_lowpart_for_combine. */ 685550397Sobrien if (code == CALL || code == ASM_OPERANDS || code == CLOBBER) 685618334Speter return x; 685718334Speter 685818334Speter /* We want to perform the operation is its present mode unless we know 685918334Speter that the operation is valid in MODE, in which case we do the operation 686018334Speter in MODE. */ 686118334Speter op_mode = ((GET_MODE_CLASS (mode) == GET_MODE_CLASS (GET_MODE (x)) 686290075Sobrien && have_insn_for (code, mode)) 686318334Speter ? mode : GET_MODE (x)); 686418334Speter 686518334Speter /* It is not valid to do a right-shift in a narrower mode 686618334Speter than the one it came in with. */ 686718334Speter if ((code == LSHIFTRT || code == ASHIFTRT) 686818334Speter && GET_MODE_BITSIZE (mode) < GET_MODE_BITSIZE (GET_MODE (x))) 686918334Speter op_mode = GET_MODE (x); 687018334Speter 687118334Speter /* Truncate MASK to fit OP_MODE. */ 687218334Speter if (op_mode) 687318334Speter mask &= GET_MODE_MASK (op_mode); 687418334Speter 687518334Speter /* When we have an arithmetic operation, or a shift whose count we 687618334Speter do not know, we need to assume that all bit the up to the highest-order 687718334Speter bit in MASK will be needed. This is how we form such a mask. */ 687818334Speter if (op_mode) 687918334Speter fuller_mask = (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT 688018334Speter ? GET_MODE_MASK (op_mode) 688190075Sobrien : (((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1)) 688290075Sobrien - 1)); 688318334Speter else 688490075Sobrien fuller_mask = ~(HOST_WIDE_INT) 0; 688518334Speter 688618334Speter /* Determine what bits of X are guaranteed to be (non)zero. */ 688718334Speter nonzero = nonzero_bits (x, mode); 688818334Speter 688918334Speter /* If none of the bits in X are needed, return a zero. */ 689018334Speter if (! just_select && (nonzero & mask) == 0) 6891117395Skan x = const0_rtx; 689218334Speter 689318334Speter /* If X is a CONST_INT, return a new one. Do this here since the 689418334Speter test below will fail. */ 689518334Speter if (GET_CODE (x) == CONST_INT) 6896117395Skan { 6897117395Skan if (SCALAR_INT_MODE_P (mode)) 6898117395Skan return gen_int_mode (INTVAL (x) & mask, mode); 6899117395Skan else 6900117395Skan { 6901117395Skan x = GEN_INT (INTVAL (x) & mask); 6902117395Skan return gen_lowpart_common (mode, x); 6903117395Skan } 6904117395Skan } 690518334Speter 690618334Speter /* If X is narrower than MODE and we want all the bits in X's mode, just 690718334Speter get X in the proper mode. */ 690818334Speter if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode) 690990075Sobrien && (GET_MODE_MASK (GET_MODE (x)) & ~mask) == 0) 691018334Speter return gen_lowpart_for_combine (mode, x); 691118334Speter 691218334Speter /* If we aren't changing the mode, X is not a SUBREG, and all zero bits in 691318334Speter MASK are already known to be zero in X, we need not do anything. */ 691490075Sobrien if (GET_MODE (x) == mode && code != SUBREG && (~mask & nonzero) == 0) 691518334Speter return x; 691618334Speter 691718334Speter switch (code) 691818334Speter { 691918334Speter case CLOBBER: 692018334Speter /* If X is a (clobber (const_int)), return it since we know we are 692150397Sobrien generating something that won't match. */ 692218334Speter return x; 692318334Speter 692418334Speter case USE: 692518334Speter /* X is a (use (mem ..)) that was made from a bit-field extraction that 692618334Speter spanned the boundary of the MEM. If we are now masking so it is 692718334Speter within that boundary, we don't need the USE any more. */ 692818334Speter if (! BITS_BIG_ENDIAN 692990075Sobrien && (mask & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0) 693018334Speter return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select); 693118334Speter break; 693218334Speter 693318334Speter case SIGN_EXTEND: 693418334Speter case ZERO_EXTEND: 693518334Speter case ZERO_EXTRACT: 693618334Speter case SIGN_EXTRACT: 693718334Speter x = expand_compound_operation (x); 693818334Speter if (GET_CODE (x) != code) 693918334Speter return force_to_mode (x, mode, mask, reg, next_select); 694018334Speter break; 694118334Speter 694218334Speter case REG: 694318334Speter if (reg != 0 && (rtx_equal_p (get_last_value (reg), x) 694418334Speter || rtx_equal_p (reg, get_last_value (x)))) 694518334Speter x = reg; 694618334Speter break; 694718334Speter 694818334Speter case SUBREG: 694918334Speter if (subreg_lowpart_p (x) 695018334Speter /* We can ignore the effect of this SUBREG if it narrows the mode or 695118334Speter if the constant masks to zero all the bits the mode doesn't 695218334Speter have. */ 695318334Speter && ((GET_MODE_SIZE (GET_MODE (x)) 695418334Speter < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) 695518334Speter || (0 == (mask 695618334Speter & GET_MODE_MASK (GET_MODE (x)) 695790075Sobrien & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x))))))) 695818334Speter return force_to_mode (SUBREG_REG (x), mode, mask, reg, next_select); 695918334Speter break; 696018334Speter 696118334Speter case AND: 696218334Speter /* If this is an AND with a constant, convert it into an AND 696318334Speter whose constant is the AND of that constant with MASK. If it 696418334Speter remains an AND of MASK, delete it since it is redundant. */ 696518334Speter 696618334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT) 696718334Speter { 696818334Speter x = simplify_and_const_int (x, op_mode, XEXP (x, 0), 696918334Speter mask & INTVAL (XEXP (x, 1))); 697018334Speter 697118334Speter /* If X is still an AND, see if it is an AND with a mask that 697218334Speter is just some low-order bits. If so, and it is MASK, we don't 697318334Speter need it. */ 697418334Speter 697518334Speter if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT 697690075Sobrien && ((INTVAL (XEXP (x, 1)) & GET_MODE_MASK (GET_MODE (x))) 6977117395Skan == mask)) 697818334Speter x = XEXP (x, 0); 697918334Speter 698018334Speter /* If it remains an AND, try making another AND with the bits 698118334Speter in the mode mask that aren't in MASK turned on. If the 698218334Speter constant in the AND is wide enough, this might make a 698318334Speter cheaper constant. */ 698418334Speter 698518334Speter if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT 698618334Speter && GET_MODE_MASK (GET_MODE (x)) != mask 698718334Speter && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT) 698818334Speter { 698918334Speter HOST_WIDE_INT cval = (INTVAL (XEXP (x, 1)) 699090075Sobrien | (GET_MODE_MASK (GET_MODE (x)) & ~mask)); 699118334Speter int width = GET_MODE_BITSIZE (GET_MODE (x)); 699218334Speter rtx y; 699318334Speter 699418334Speter /* If MODE is narrower that HOST_WIDE_INT and CVAL is a negative 699518334Speter number, sign extend it. */ 699618334Speter if (width > 0 && width < HOST_BITS_PER_WIDE_INT 699718334Speter && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0) 699818334Speter cval |= (HOST_WIDE_INT) -1 << width; 699918334Speter 700018334Speter y = gen_binary (AND, GET_MODE (x), XEXP (x, 0), GEN_INT (cval)); 700118334Speter if (rtx_cost (y, SET) < rtx_cost (x, SET)) 700218334Speter x = y; 700318334Speter } 700418334Speter 700518334Speter break; 700618334Speter } 700718334Speter 700818334Speter goto binop; 700918334Speter 701018334Speter case PLUS: 701118334Speter /* In (and (plus FOO C1) M), if M is a mask that just turns off 701218334Speter low-order bits (as in an alignment operation) and FOO is already 701318334Speter aligned to that boundary, mask C1 to that boundary as well. 701418334Speter This may eliminate that PLUS and, later, the AND. */ 701518334Speter 701618334Speter { 701790075Sobrien unsigned int width = GET_MODE_BITSIZE (mode); 701818334Speter unsigned HOST_WIDE_INT smask = mask; 701918334Speter 702018334Speter /* If MODE is narrower than HOST_WIDE_INT and mask is a negative 702118334Speter number, sign extend it. */ 702218334Speter 702318334Speter if (width < HOST_BITS_PER_WIDE_INT 702418334Speter && (smask & ((HOST_WIDE_INT) 1 << (width - 1))) != 0) 702518334Speter smask |= (HOST_WIDE_INT) -1 << width; 702618334Speter 702718334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 702896263Sobrien && exact_log2 (- smask) >= 0 702996263Sobrien && (nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0 703096263Sobrien && (INTVAL (XEXP (x, 1)) & ~smask) != 0) 703196263Sobrien return force_to_mode (plus_constant (XEXP (x, 0), 703296263Sobrien (INTVAL (XEXP (x, 1)) & smask)), 703396263Sobrien mode, smask, reg, next_select); 703418334Speter } 703518334Speter 703650397Sobrien /* ... fall through ... */ 703718334Speter 703818334Speter case MULT: 703918334Speter /* For PLUS, MINUS and MULT, we need any bits less significant than the 704018334Speter most significant bit in MASK since carries from those bits will 704118334Speter affect the bits we are interested in. */ 704218334Speter mask = fuller_mask; 704318334Speter goto binop; 704418334Speter 704590075Sobrien case MINUS: 704690075Sobrien /* If X is (minus C Y) where C's least set bit is larger than any bit 704790075Sobrien in the mask, then we may replace with (neg Y). */ 704890075Sobrien if (GET_CODE (XEXP (x, 0)) == CONST_INT 704990075Sobrien && (((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 0)) 705090075Sobrien & -INTVAL (XEXP (x, 0)))) 705190075Sobrien > mask)) 705290075Sobrien { 705390075Sobrien x = simplify_gen_unary (NEG, GET_MODE (x), XEXP (x, 1), 705490075Sobrien GET_MODE (x)); 705590075Sobrien return force_to_mode (x, mode, mask, reg, next_select); 705690075Sobrien } 705790075Sobrien 7058110611Skan /* Similarly, if C contains every bit in the fuller_mask, then we may 705990075Sobrien replace with (not Y). */ 706090075Sobrien if (GET_CODE (XEXP (x, 0)) == CONST_INT 7061110611Skan && ((INTVAL (XEXP (x, 0)) | (HOST_WIDE_INT) fuller_mask) 706290075Sobrien == INTVAL (XEXP (x, 0)))) 706390075Sobrien { 706490075Sobrien x = simplify_gen_unary (NOT, GET_MODE (x), 706590075Sobrien XEXP (x, 1), GET_MODE (x)); 706690075Sobrien return force_to_mode (x, mode, mask, reg, next_select); 706790075Sobrien } 706890075Sobrien 706990075Sobrien mask = fuller_mask; 707090075Sobrien goto binop; 707190075Sobrien 707218334Speter case IOR: 707318334Speter case XOR: 707418334Speter /* If X is (ior (lshiftrt FOO C1) C2), try to commute the IOR and 707518334Speter LSHIFTRT so we end up with an (and (lshiftrt (ior ...) ...) ...) 707618334Speter operation which may be a bitfield extraction. Ensure that the 707718334Speter constant we form is not wider than the mode of X. */ 707818334Speter 707918334Speter if (GET_CODE (XEXP (x, 0)) == LSHIFTRT 708018334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 708118334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0 708218334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT 708318334Speter && GET_CODE (XEXP (x, 1)) == CONST_INT 708418334Speter && ((INTVAL (XEXP (XEXP (x, 0), 1)) 708518334Speter + floor_log2 (INTVAL (XEXP (x, 1)))) 708618334Speter < GET_MODE_BITSIZE (GET_MODE (x))) 708718334Speter && (INTVAL (XEXP (x, 1)) 708890075Sobrien & ~nonzero_bits (XEXP (x, 0), GET_MODE (x))) == 0) 708918334Speter { 709018334Speter temp = GEN_INT ((INTVAL (XEXP (x, 1)) & mask) 709190075Sobrien << INTVAL (XEXP (XEXP (x, 0), 1))); 709218334Speter temp = gen_binary (GET_CODE (x), GET_MODE (x), 709318334Speter XEXP (XEXP (x, 0), 0), temp); 709450397Sobrien x = gen_binary (LSHIFTRT, GET_MODE (x), temp, 709550397Sobrien XEXP (XEXP (x, 0), 1)); 709618334Speter return force_to_mode (x, mode, mask, reg, next_select); 709718334Speter } 709818334Speter 709918334Speter binop: 710018334Speter /* For most binary operations, just propagate into the operation and 710190075Sobrien change the mode if we have an operation of that mode. */ 710218334Speter 710318334Speter op0 = gen_lowpart_for_combine (op_mode, 710418334Speter force_to_mode (XEXP (x, 0), mode, mask, 710518334Speter reg, next_select)); 710618334Speter op1 = gen_lowpart_for_combine (op_mode, 710718334Speter force_to_mode (XEXP (x, 1), mode, mask, 710818334Speter reg, next_select)); 710918334Speter 711018334Speter if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1)) 711118334Speter x = gen_binary (code, op_mode, op0, op1); 711218334Speter break; 711318334Speter 711418334Speter case ASHIFT: 711518334Speter /* For left shifts, do the same, but just for the first operand. 711618334Speter However, we cannot do anything with shifts where we cannot 711718334Speter guarantee that the counts are smaller than the size of the mode 711818334Speter because such a count will have a different meaning in a 711918334Speter wider mode. */ 712018334Speter 712118334Speter if (! (GET_CODE (XEXP (x, 1)) == CONST_INT 712218334Speter && INTVAL (XEXP (x, 1)) >= 0 712318334Speter && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (mode)) 712418334Speter && ! (GET_MODE (XEXP (x, 1)) != VOIDmode 712518334Speter && (nonzero_bits (XEXP (x, 1), GET_MODE (XEXP (x, 1))) 712618334Speter < (unsigned HOST_WIDE_INT) GET_MODE_BITSIZE (mode)))) 712718334Speter break; 712890075Sobrien 712918334Speter /* If the shift count is a constant and we can do arithmetic in 713018334Speter the mode of the shift, refine which bits we need. Otherwise, use the 713118334Speter conservative form of the mask. */ 713218334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 713318334Speter && INTVAL (XEXP (x, 1)) >= 0 713418334Speter && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (op_mode) 713518334Speter && GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT) 713618334Speter mask >>= INTVAL (XEXP (x, 1)); 713718334Speter else 713818334Speter mask = fuller_mask; 713918334Speter 714018334Speter op0 = gen_lowpart_for_combine (op_mode, 714118334Speter force_to_mode (XEXP (x, 0), op_mode, 714218334Speter mask, reg, next_select)); 714318334Speter 714418334Speter if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0)) 714590075Sobrien x = gen_binary (code, op_mode, op0, XEXP (x, 1)); 714618334Speter break; 714718334Speter 714818334Speter case LSHIFTRT: 714918334Speter /* Here we can only do something if the shift count is a constant, 715018334Speter this shift constant is valid for the host, and we can do arithmetic 715118334Speter in OP_MODE. */ 715218334Speter 715318334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 715418334Speter && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT 715518334Speter && GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT) 715618334Speter { 715718334Speter rtx inner = XEXP (x, 0); 715890075Sobrien unsigned HOST_WIDE_INT inner_mask; 715918334Speter 716018334Speter /* Select the mask of the bits we need for the shift operand. */ 716190075Sobrien inner_mask = mask << INTVAL (XEXP (x, 1)); 716218334Speter 716318334Speter /* We can only change the mode of the shift if we can do arithmetic 716490075Sobrien in the mode of the shift and INNER_MASK is no wider than the 716590075Sobrien width of OP_MODE. */ 716618334Speter if (GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT 716790075Sobrien || (inner_mask & ~GET_MODE_MASK (op_mode)) != 0) 716818334Speter op_mode = GET_MODE (x); 716918334Speter 717090075Sobrien inner = force_to_mode (inner, op_mode, inner_mask, reg, next_select); 717118334Speter 717218334Speter if (GET_MODE (x) != op_mode || inner != XEXP (x, 0)) 717318334Speter x = gen_binary (LSHIFTRT, op_mode, inner, XEXP (x, 1)); 717418334Speter } 717518334Speter 717618334Speter /* If we have (and (lshiftrt FOO C1) C2) where the combination of the 717718334Speter shift and AND produces only copies of the sign bit (C2 is one less 717818334Speter than a power of two), we can do this with just a shift. */ 717918334Speter 718018334Speter if (GET_CODE (x) == LSHIFTRT 718118334Speter && GET_CODE (XEXP (x, 1)) == CONST_INT 718290075Sobrien /* The shift puts one of the sign bit copies in the least significant 718390075Sobrien bit. */ 718418334Speter && ((INTVAL (XEXP (x, 1)) 718518334Speter + num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))) 718618334Speter >= GET_MODE_BITSIZE (GET_MODE (x))) 718718334Speter && exact_log2 (mask + 1) >= 0 718890075Sobrien /* Number of bits left after the shift must be more than the mask 718990075Sobrien needs. */ 719090075Sobrien && ((INTVAL (XEXP (x, 1)) + exact_log2 (mask + 1)) 719190075Sobrien <= GET_MODE_BITSIZE (GET_MODE (x))) 719290075Sobrien /* Must be more sign bit copies than the mask needs. */ 719390075Sobrien && ((int) num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0))) 719418334Speter >= exact_log2 (mask + 1))) 719518334Speter x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0), 719618334Speter GEN_INT (GET_MODE_BITSIZE (GET_MODE (x)) 719718334Speter - exact_log2 (mask + 1))); 719818334Speter 719990075Sobrien goto shiftrt; 720090075Sobrien 720118334Speter case ASHIFTRT: 720218334Speter /* If we are just looking for the sign bit, we don't need this shift at 720318334Speter all, even if it has a variable count. */ 720418334Speter if (GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT 720552284Sobrien && (mask == ((unsigned HOST_WIDE_INT) 1 720618334Speter << (GET_MODE_BITSIZE (GET_MODE (x)) - 1)))) 720718334Speter return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select); 720818334Speter 720918334Speter /* If this is a shift by a constant, get a mask that contains those bits 721018334Speter that are not copies of the sign bit. We then have two cases: If 721118334Speter MASK only includes those bits, this can be a logical shift, which may 721218334Speter allow simplifications. If MASK is a single-bit field not within 721318334Speter those bits, we are requesting a copy of the sign bit and hence can 721418334Speter shift the sign bit to the appropriate location. */ 721518334Speter 721618334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) >= 0 721718334Speter && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT) 721818334Speter { 721918334Speter int i = -1; 722018334Speter 722190075Sobrien /* If the considered data is wider than HOST_WIDE_INT, we can't 722218334Speter represent a mask for all its bits in a single scalar. 722318334Speter But we only care about the lower bits, so calculate these. */ 722418334Speter 722518334Speter if (GET_MODE_BITSIZE (GET_MODE (x)) > HOST_BITS_PER_WIDE_INT) 722618334Speter { 722790075Sobrien nonzero = ~(HOST_WIDE_INT) 0; 722818334Speter 722918334Speter /* GET_MODE_BITSIZE (GET_MODE (x)) - INTVAL (XEXP (x, 1)) 723018334Speter is the number of bits a full-width mask would have set. 723118334Speter We need only shift if these are fewer than nonzero can 723218334Speter hold. If not, we must keep all bits set in nonzero. */ 723318334Speter 723418334Speter if (GET_MODE_BITSIZE (GET_MODE (x)) - INTVAL (XEXP (x, 1)) 723518334Speter < HOST_BITS_PER_WIDE_INT) 723618334Speter nonzero >>= INTVAL (XEXP (x, 1)) 723718334Speter + HOST_BITS_PER_WIDE_INT 723818334Speter - GET_MODE_BITSIZE (GET_MODE (x)) ; 723918334Speter } 724018334Speter else 724118334Speter { 724218334Speter nonzero = GET_MODE_MASK (GET_MODE (x)); 724318334Speter nonzero >>= INTVAL (XEXP (x, 1)); 724418334Speter } 724518334Speter 724690075Sobrien if ((mask & ~nonzero) == 0 724718334Speter || (i = exact_log2 (mask)) >= 0) 724818334Speter { 724918334Speter x = simplify_shift_const 725018334Speter (x, LSHIFTRT, GET_MODE (x), XEXP (x, 0), 725118334Speter i < 0 ? INTVAL (XEXP (x, 1)) 725218334Speter : GET_MODE_BITSIZE (GET_MODE (x)) - 1 - i); 725318334Speter 725418334Speter if (GET_CODE (x) != ASHIFTRT) 725518334Speter return force_to_mode (x, mode, mask, reg, next_select); 725618334Speter } 725718334Speter } 725818334Speter 7259117395Skan /* If MASK is 1, convert this to an LSHIFTRT. This can be done 726018334Speter even if the shift count isn't a constant. */ 726118334Speter if (mask == 1) 726218334Speter x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0), XEXP (x, 1)); 726318334Speter 726490075Sobrien shiftrt: 726590075Sobrien 726690075Sobrien /* If this is a zero- or sign-extension operation that just affects bits 726718334Speter we don't care about, remove it. Be sure the call above returned 726818334Speter something that is still a shift. */ 726918334Speter 727018334Speter if ((GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ASHIFTRT) 727118334Speter && GET_CODE (XEXP (x, 1)) == CONST_INT 727218334Speter && INTVAL (XEXP (x, 1)) >= 0 727318334Speter && (INTVAL (XEXP (x, 1)) 727418334Speter <= GET_MODE_BITSIZE (GET_MODE (x)) - (floor_log2 (mask) + 1)) 727518334Speter && GET_CODE (XEXP (x, 0)) == ASHIFT 727618334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 727718334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) == INTVAL (XEXP (x, 1))) 727818334Speter return force_to_mode (XEXP (XEXP (x, 0), 0), mode, mask, 727918334Speter reg, next_select); 728018334Speter 728118334Speter break; 728218334Speter 728318334Speter case ROTATE: 728418334Speter case ROTATERT: 728518334Speter /* If the shift count is constant and we can do computations 728618334Speter in the mode of X, compute where the bits we care about are. 728718334Speter Otherwise, we can't do anything. Don't change the mode of 728818334Speter the shift or propagate MODE into the shift, though. */ 728918334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 729018334Speter && INTVAL (XEXP (x, 1)) >= 0) 729118334Speter { 729218334Speter temp = simplify_binary_operation (code == ROTATE ? ROTATERT : ROTATE, 729318334Speter GET_MODE (x), GEN_INT (mask), 729418334Speter XEXP (x, 1)); 729518334Speter if (temp && GET_CODE(temp) == CONST_INT) 729618334Speter SUBST (XEXP (x, 0), 729718334Speter force_to_mode (XEXP (x, 0), GET_MODE (x), 729818334Speter INTVAL (temp), reg, next_select)); 729918334Speter } 730018334Speter break; 730190075Sobrien 730218334Speter case NEG: 730318334Speter /* If we just want the low-order bit, the NEG isn't needed since it 730490075Sobrien won't change the low-order bit. */ 730518334Speter if (mask == 1) 730618334Speter return force_to_mode (XEXP (x, 0), mode, mask, reg, just_select); 730718334Speter 730818334Speter /* We need any bits less significant than the most significant bit in 730918334Speter MASK since carries from those bits will affect the bits we are 731018334Speter interested in. */ 731118334Speter mask = fuller_mask; 731218334Speter goto unop; 731318334Speter 731418334Speter case NOT: 731518334Speter /* (not FOO) is (xor FOO CONST), so if FOO is an LSHIFTRT, we can do the 731618334Speter same as the XOR case above. Ensure that the constant we form is not 731718334Speter wider than the mode of X. */ 731818334Speter 731918334Speter if (GET_CODE (XEXP (x, 0)) == LSHIFTRT 732018334Speter && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 732118334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0 732218334Speter && (INTVAL (XEXP (XEXP (x, 0), 1)) + floor_log2 (mask) 732318334Speter < GET_MODE_BITSIZE (GET_MODE (x))) 732418334Speter && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT) 732518334Speter { 7326117395Skan temp = gen_int_mode (mask << INTVAL (XEXP (XEXP (x, 0), 1)), 7327117395Skan GET_MODE (x)); 732818334Speter temp = gen_binary (XOR, GET_MODE (x), XEXP (XEXP (x, 0), 0), temp); 732918334Speter x = gen_binary (LSHIFTRT, GET_MODE (x), temp, XEXP (XEXP (x, 0), 1)); 733018334Speter 733118334Speter return force_to_mode (x, mode, mask, reg, next_select); 733218334Speter } 733318334Speter 733450397Sobrien /* (and (not FOO) CONST) is (not (or FOO (not CONST))), so we must 733550397Sobrien use the full mask inside the NOT. */ 733650397Sobrien mask = fuller_mask; 733750397Sobrien 733818334Speter unop: 733918334Speter op0 = gen_lowpart_for_combine (op_mode, 734018334Speter force_to_mode (XEXP (x, 0), mode, mask, 734118334Speter reg, next_select)); 734218334Speter if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0)) 734390075Sobrien x = simplify_gen_unary (code, op_mode, op0, op_mode); 734418334Speter break; 734518334Speter 734618334Speter case NE: 734718334Speter /* (and (ne FOO 0) CONST) can be (and FOO CONST) if CONST is included 734850397Sobrien in STORE_FLAG_VALUE and FOO has a single bit that might be nonzero, 734950397Sobrien which is equal to STORE_FLAG_VALUE. */ 735090075Sobrien if ((mask & ~STORE_FLAG_VALUE) == 0 && XEXP (x, 1) == const0_rtx 735150397Sobrien && exact_log2 (nonzero_bits (XEXP (x, 0), mode)) >= 0 735250397Sobrien && nonzero_bits (XEXP (x, 0), mode) == STORE_FLAG_VALUE) 735318334Speter return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select); 735418334Speter 735518334Speter break; 735618334Speter 735718334Speter case IF_THEN_ELSE: 735818334Speter /* We have no way of knowing if the IF_THEN_ELSE can itself be 735918334Speter written in a narrower mode. We play it safe and do not do so. */ 736018334Speter 736118334Speter SUBST (XEXP (x, 1), 736218334Speter gen_lowpart_for_combine (GET_MODE (x), 736318334Speter force_to_mode (XEXP (x, 1), mode, 736418334Speter mask, reg, next_select))); 736518334Speter SUBST (XEXP (x, 2), 736618334Speter gen_lowpart_for_combine (GET_MODE (x), 736718334Speter force_to_mode (XEXP (x, 2), mode, 736818334Speter mask, reg,next_select))); 736918334Speter break; 737090075Sobrien 737150397Sobrien default: 737250397Sobrien break; 737318334Speter } 737418334Speter 737518334Speter /* Ensure we return a value of the proper mode. */ 737618334Speter return gen_lowpart_for_combine (mode, x); 737718334Speter} 737818334Speter 737918334Speter/* Return nonzero if X is an expression that has one of two values depending on 738018334Speter whether some other value is zero or nonzero. In that case, we return the 738118334Speter value that is being tested, *PTRUE is set to the value if the rtx being 738218334Speter returned has a nonzero value, and *PFALSE is set to the other alternative. 738318334Speter 738418334Speter If we return zero, we set *PTRUE and *PFALSE to X. */ 738518334Speter 738618334Speterstatic rtx 738718334Speterif_then_else_cond (x, ptrue, pfalse) 738818334Speter rtx x; 738918334Speter rtx *ptrue, *pfalse; 739018334Speter{ 739118334Speter enum machine_mode mode = GET_MODE (x); 739218334Speter enum rtx_code code = GET_CODE (x); 739318334Speter rtx cond0, cond1, true0, true1, false0, false1; 739418334Speter unsigned HOST_WIDE_INT nz; 739518334Speter 739690075Sobrien /* If we are comparing a value against zero, we are done. */ 739790075Sobrien if ((code == NE || code == EQ) 739890075Sobrien && GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 0) 739990075Sobrien { 740090075Sobrien *ptrue = (code == NE) ? const_true_rtx : const0_rtx; 740190075Sobrien *pfalse = (code == NE) ? const0_rtx : const_true_rtx; 740290075Sobrien return XEXP (x, 0); 740390075Sobrien } 740490075Sobrien 740518334Speter /* If this is a unary operation whose operand has one of two values, apply 740618334Speter our opcode to compute those values. */ 740790075Sobrien else if (GET_RTX_CLASS (code) == '1' 740890075Sobrien && (cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0)) != 0) 740918334Speter { 741090075Sobrien *ptrue = simplify_gen_unary (code, mode, true0, GET_MODE (XEXP (x, 0))); 741190075Sobrien *pfalse = simplify_gen_unary (code, mode, false0, 741290075Sobrien GET_MODE (XEXP (x, 0))); 741318334Speter return cond0; 741418334Speter } 741518334Speter 741618334Speter /* If this is a COMPARE, do nothing, since the IF_THEN_ELSE we would 741718334Speter make can't possibly match and would suppress other optimizations. */ 741818334Speter else if (code == COMPARE) 741918334Speter ; 742018334Speter 742118334Speter /* If this is a binary operation, see if either side has only one of two 742218334Speter values. If either one does or if both do and they are conditional on 742318334Speter the same value, compute the new true and false values. */ 742418334Speter else if (GET_RTX_CLASS (code) == 'c' || GET_RTX_CLASS (code) == '2' 742518334Speter || GET_RTX_CLASS (code) == '<') 742618334Speter { 742718334Speter cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0); 742818334Speter cond1 = if_then_else_cond (XEXP (x, 1), &true1, &false1); 742918334Speter 743018334Speter if ((cond0 != 0 || cond1 != 0) 743118334Speter && ! (cond0 != 0 && cond1 != 0 && ! rtx_equal_p (cond0, cond1))) 743218334Speter { 743350397Sobrien /* If if_then_else_cond returned zero, then true/false are the 743450397Sobrien same rtl. We must copy one of them to prevent invalid rtl 743550397Sobrien sharing. */ 743650397Sobrien if (cond0 == 0) 743750397Sobrien true0 = copy_rtx (true0); 743850397Sobrien else if (cond1 == 0) 743950397Sobrien true1 = copy_rtx (true1); 744050397Sobrien 744118334Speter *ptrue = gen_binary (code, mode, true0, true1); 744218334Speter *pfalse = gen_binary (code, mode, false0, false1); 744318334Speter return cond0 ? cond0 : cond1; 744418334Speter } 744518334Speter 744618334Speter /* See if we have PLUS, IOR, XOR, MINUS or UMAX, where one of the 7447117395Skan operands is zero when the other is nonzero, and vice-versa, 744850397Sobrien and STORE_FLAG_VALUE is 1 or -1. */ 744918334Speter 745050397Sobrien if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1) 745150397Sobrien && (code == PLUS || code == IOR || code == XOR || code == MINUS 745290075Sobrien || code == UMAX) 745318334Speter && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == MULT) 745418334Speter { 745518334Speter rtx op0 = XEXP (XEXP (x, 0), 1); 745618334Speter rtx op1 = XEXP (XEXP (x, 1), 1); 745718334Speter 745818334Speter cond0 = XEXP (XEXP (x, 0), 0); 745918334Speter cond1 = XEXP (XEXP (x, 1), 0); 746018334Speter 746118334Speter if (GET_RTX_CLASS (GET_CODE (cond0)) == '<' 746218334Speter && GET_RTX_CLASS (GET_CODE (cond1)) == '<' 746390075Sobrien && ((GET_CODE (cond0) == combine_reversed_comparison_code (cond1) 746418334Speter && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0)) 746518334Speter && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1))) 746618334Speter || ((swap_condition (GET_CODE (cond0)) 746790075Sobrien == combine_reversed_comparison_code (cond1)) 746818334Speter && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 1)) 746918334Speter && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0)))) 747018334Speter && ! side_effects_p (x)) 747118334Speter { 747218334Speter *ptrue = gen_binary (MULT, mode, op0, const_true_rtx); 747390075Sobrien *pfalse = gen_binary (MULT, mode, 747490075Sobrien (code == MINUS 747590075Sobrien ? simplify_gen_unary (NEG, mode, op1, 747690075Sobrien mode) 747790075Sobrien : op1), 747818334Speter const_true_rtx); 747918334Speter return cond0; 748018334Speter } 748118334Speter } 748218334Speter 748390075Sobrien /* Similarly for MULT, AND and UMIN, except that for these the result 748418334Speter is always zero. */ 748550397Sobrien if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1) 748650397Sobrien && (code == MULT || code == AND || code == UMIN) 748718334Speter && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == MULT) 748818334Speter { 748918334Speter cond0 = XEXP (XEXP (x, 0), 0); 749018334Speter cond1 = XEXP (XEXP (x, 1), 0); 749118334Speter 749218334Speter if (GET_RTX_CLASS (GET_CODE (cond0)) == '<' 749318334Speter && GET_RTX_CLASS (GET_CODE (cond1)) == '<' 749490075Sobrien && ((GET_CODE (cond0) == combine_reversed_comparison_code (cond1) 749518334Speter && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0)) 749618334Speter && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1))) 749718334Speter || ((swap_condition (GET_CODE (cond0)) 749890075Sobrien == combine_reversed_comparison_code (cond1)) 749918334Speter && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 1)) 750018334Speter && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0)))) 750118334Speter && ! side_effects_p (x)) 750218334Speter { 750318334Speter *ptrue = *pfalse = const0_rtx; 750418334Speter return cond0; 750518334Speter } 750618334Speter } 750718334Speter } 750818334Speter 750918334Speter else if (code == IF_THEN_ELSE) 751018334Speter { 751118334Speter /* If we have IF_THEN_ELSE already, extract the condition and 751218334Speter canonicalize it if it is NE or EQ. */ 751318334Speter cond0 = XEXP (x, 0); 751418334Speter *ptrue = XEXP (x, 1), *pfalse = XEXP (x, 2); 751518334Speter if (GET_CODE (cond0) == NE && XEXP (cond0, 1) == const0_rtx) 751618334Speter return XEXP (cond0, 0); 751718334Speter else if (GET_CODE (cond0) == EQ && XEXP (cond0, 1) == const0_rtx) 751818334Speter { 751918334Speter *ptrue = XEXP (x, 2), *pfalse = XEXP (x, 1); 752018334Speter return XEXP (cond0, 0); 752118334Speter } 752218334Speter else 752318334Speter return cond0; 752418334Speter } 752518334Speter 752690075Sobrien /* If X is a SUBREG, we can narrow both the true and false values 752790075Sobrien if the inner expression, if there is a condition. */ 752890075Sobrien else if (code == SUBREG 752918334Speter && 0 != (cond0 = if_then_else_cond (SUBREG_REG (x), 753018334Speter &true0, &false0))) 753118334Speter { 753290075Sobrien *ptrue = simplify_gen_subreg (mode, true0, 753390075Sobrien GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x)); 753490075Sobrien *pfalse = simplify_gen_subreg (mode, false0, 753590075Sobrien GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x)); 753618334Speter 753718334Speter return cond0; 753818334Speter } 753918334Speter 754018334Speter /* If X is a constant, this isn't special and will cause confusions 754118334Speter if we treat it as such. Likewise if it is equivalent to a constant. */ 754218334Speter else if (CONSTANT_P (x) 754318334Speter || ((cond0 = get_last_value (x)) != 0 && CONSTANT_P (cond0))) 754418334Speter ; 754518334Speter 754690075Sobrien /* If we're in BImode, canonicalize on 0 and STORE_FLAG_VALUE, as that 754790075Sobrien will be least confusing to the rest of the compiler. */ 754890075Sobrien else if (mode == BImode) 754990075Sobrien { 755090075Sobrien *ptrue = GEN_INT (STORE_FLAG_VALUE), *pfalse = const0_rtx; 755190075Sobrien return x; 755290075Sobrien } 755390075Sobrien 755490075Sobrien /* If X is known to be either 0 or -1, those are the true and 755518334Speter false values when testing X. */ 755690075Sobrien else if (x == constm1_rtx || x == const0_rtx 755790075Sobrien || (mode != VOIDmode 755890075Sobrien && num_sign_bit_copies (x, mode) == GET_MODE_BITSIZE (mode))) 755918334Speter { 756018334Speter *ptrue = constm1_rtx, *pfalse = const0_rtx; 756118334Speter return x; 756218334Speter } 756318334Speter 756418334Speter /* Likewise for 0 or a single bit. */ 756590075Sobrien else if (mode != VOIDmode 756690075Sobrien && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 756790075Sobrien && exact_log2 (nz = nonzero_bits (x, mode)) >= 0) 756818334Speter { 7569117395Skan *ptrue = gen_int_mode (nz, mode), *pfalse = const0_rtx; 757018334Speter return x; 757118334Speter } 757218334Speter 757318334Speter /* Otherwise fail; show no condition with true and false values the same. */ 757418334Speter *ptrue = *pfalse = x; 757518334Speter return 0; 757618334Speter} 757718334Speter 757818334Speter/* Return the value of expression X given the fact that condition COND 757918334Speter is known to be true when applied to REG as its first operand and VAL 758018334Speter as its second. X is known to not be shared and so can be modified in 758118334Speter place. 758218334Speter 758318334Speter We only handle the simplest cases, and specifically those cases that 758418334Speter arise with IF_THEN_ELSE expressions. */ 758518334Speter 758618334Speterstatic rtx 758718334Speterknown_cond (x, cond, reg, val) 758818334Speter rtx x; 758918334Speter enum rtx_code cond; 759018334Speter rtx reg, val; 759118334Speter{ 759218334Speter enum rtx_code code = GET_CODE (x); 759318334Speter rtx temp; 759490075Sobrien const char *fmt; 759518334Speter int i, j; 759618334Speter 759718334Speter if (side_effects_p (x)) 759818334Speter return x; 759918334Speter 760090075Sobrien /* If either operand of the condition is a floating point value, 760190075Sobrien then we have to avoid collapsing an EQ comparison. */ 760290075Sobrien if (cond == EQ 760390075Sobrien && rtx_equal_p (x, reg) 760490075Sobrien && ! FLOAT_MODE_P (GET_MODE (x)) 760590075Sobrien && ! FLOAT_MODE_P (GET_MODE (val))) 760618334Speter return val; 760718334Speter 760890075Sobrien if (cond == UNEQ && rtx_equal_p (x, reg)) 760990075Sobrien return val; 761090075Sobrien 761118334Speter /* If X is (abs REG) and we know something about REG's relationship 761218334Speter with zero, we may be able to simplify this. */ 761318334Speter 761418334Speter if (code == ABS && rtx_equal_p (XEXP (x, 0), reg) && val == const0_rtx) 761518334Speter switch (cond) 761618334Speter { 761718334Speter case GE: case GT: case EQ: 761818334Speter return XEXP (x, 0); 761918334Speter case LT: case LE: 762090075Sobrien return simplify_gen_unary (NEG, GET_MODE (XEXP (x, 0)), 762190075Sobrien XEXP (x, 0), 762290075Sobrien GET_MODE (XEXP (x, 0))); 762350397Sobrien default: 762450397Sobrien break; 762518334Speter } 762618334Speter 762718334Speter /* The only other cases we handle are MIN, MAX, and comparisons if the 762818334Speter operands are the same as REG and VAL. */ 762918334Speter 763018334Speter else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == 'c') 763118334Speter { 763218334Speter if (rtx_equal_p (XEXP (x, 0), val)) 763318334Speter cond = swap_condition (cond), temp = val, val = reg, reg = temp; 763418334Speter 763518334Speter if (rtx_equal_p (XEXP (x, 0), reg) && rtx_equal_p (XEXP (x, 1), val)) 763618334Speter { 763718334Speter if (GET_RTX_CLASS (code) == '<') 763890075Sobrien { 763990075Sobrien if (comparison_dominates_p (cond, code)) 764090075Sobrien return const_true_rtx; 764118334Speter 764290075Sobrien code = combine_reversed_comparison_code (x); 764390075Sobrien if (code != UNKNOWN 764490075Sobrien && comparison_dominates_p (cond, code)) 764590075Sobrien return const0_rtx; 764690075Sobrien else 764790075Sobrien return x; 764890075Sobrien } 764918334Speter else if (code == SMAX || code == SMIN 765018334Speter || code == UMIN || code == UMAX) 765118334Speter { 765218334Speter int unsignedp = (code == UMIN || code == UMAX); 765318334Speter 765490075Sobrien /* Do not reverse the condition when it is NE or EQ. 765590075Sobrien This is because we cannot conclude anything about 765690075Sobrien the value of 'SMAX (x, y)' when x is not equal to y, 765790075Sobrien but we can when x equals y. */ 765890075Sobrien if ((code == SMAX || code == UMAX) 765990075Sobrien && ! (cond == EQ || cond == NE)) 766018334Speter cond = reverse_condition (cond); 766118334Speter 766218334Speter switch (cond) 766318334Speter { 766418334Speter case GE: case GT: 766518334Speter return unsignedp ? x : XEXP (x, 1); 766618334Speter case LE: case LT: 766718334Speter return unsignedp ? x : XEXP (x, 0); 766818334Speter case GEU: case GTU: 766918334Speter return unsignedp ? XEXP (x, 1) : x; 767018334Speter case LEU: case LTU: 767118334Speter return unsignedp ? XEXP (x, 0) : x; 767250397Sobrien default: 767350397Sobrien break; 767418334Speter } 767518334Speter } 767618334Speter } 767718334Speter } 767896263Sobrien else if (code == SUBREG) 767996263Sobrien { 768096263Sobrien enum machine_mode inner_mode = GET_MODE (SUBREG_REG (x)); 768196263Sobrien rtx new, r = known_cond (SUBREG_REG (x), cond, reg, val); 768218334Speter 768396263Sobrien if (SUBREG_REG (x) != r) 768496263Sobrien { 768596263Sobrien /* We must simplify subreg here, before we lose track of the 768696263Sobrien original inner_mode. */ 768796263Sobrien new = simplify_subreg (GET_MODE (x), r, 768896263Sobrien inner_mode, SUBREG_BYTE (x)); 768996263Sobrien if (new) 769096263Sobrien return new; 769196263Sobrien else 769296263Sobrien SUBST (SUBREG_REG (x), r); 769396263Sobrien } 769496263Sobrien 769596263Sobrien return x; 769696263Sobrien } 769796263Sobrien /* We don't have to handle SIGN_EXTEND here, because even in the 769896263Sobrien case of replacing something with a modeless CONST_INT, a 769996263Sobrien CONST_INT is already (supposed to be) a valid sign extension for 770096263Sobrien its narrower mode, which implies it's already properly 770196263Sobrien sign-extended for the wider mode. Now, for ZERO_EXTEND, the 770296263Sobrien story is different. */ 770396263Sobrien else if (code == ZERO_EXTEND) 770496263Sobrien { 770596263Sobrien enum machine_mode inner_mode = GET_MODE (XEXP (x, 0)); 770696263Sobrien rtx new, r = known_cond (XEXP (x, 0), cond, reg, val); 770796263Sobrien 770896263Sobrien if (XEXP (x, 0) != r) 770996263Sobrien { 771096263Sobrien /* We must simplify the zero_extend here, before we lose 771196263Sobrien track of the original inner_mode. */ 771296263Sobrien new = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x), 771396263Sobrien r, inner_mode); 771496263Sobrien if (new) 771596263Sobrien return new; 771696263Sobrien else 771796263Sobrien SUBST (XEXP (x, 0), r); 771896263Sobrien } 771996263Sobrien 772096263Sobrien return x; 772196263Sobrien } 772296263Sobrien 772318334Speter fmt = GET_RTX_FORMAT (code); 772418334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 772518334Speter { 772618334Speter if (fmt[i] == 'e') 772718334Speter SUBST (XEXP (x, i), known_cond (XEXP (x, i), cond, reg, val)); 772818334Speter else if (fmt[i] == 'E') 772918334Speter for (j = XVECLEN (x, i) - 1; j >= 0; j--) 773018334Speter SUBST (XVECEXP (x, i, j), known_cond (XVECEXP (x, i, j), 773118334Speter cond, reg, val)); 773218334Speter } 773318334Speter 773418334Speter return x; 773518334Speter} 773618334Speter 773750397Sobrien/* See if X and Y are equal for the purposes of seeing if we can rewrite an 773850397Sobrien assignment as a field assignment. */ 773950397Sobrien 774050397Sobrienstatic int 774150397Sobrienrtx_equal_for_field_assignment_p (x, y) 774250397Sobrien rtx x; 774350397Sobrien rtx y; 774450397Sobrien{ 774550397Sobrien if (x == y || rtx_equal_p (x, y)) 774650397Sobrien return 1; 774750397Sobrien 774850397Sobrien if (x == 0 || y == 0 || GET_MODE (x) != GET_MODE (y)) 774950397Sobrien return 0; 775050397Sobrien 775150397Sobrien /* Check for a paradoxical SUBREG of a MEM compared with the MEM. 775250397Sobrien Note that all SUBREGs of MEM are paradoxical; otherwise they 775350397Sobrien would have been rewritten. */ 775450397Sobrien if (GET_CODE (x) == MEM && GET_CODE (y) == SUBREG 775550397Sobrien && GET_CODE (SUBREG_REG (y)) == MEM 775650397Sobrien && rtx_equal_p (SUBREG_REG (y), 775750397Sobrien gen_lowpart_for_combine (GET_MODE (SUBREG_REG (y)), x))) 775850397Sobrien return 1; 775950397Sobrien 776050397Sobrien if (GET_CODE (y) == MEM && GET_CODE (x) == SUBREG 776150397Sobrien && GET_CODE (SUBREG_REG (x)) == MEM 776250397Sobrien && rtx_equal_p (SUBREG_REG (x), 776350397Sobrien gen_lowpart_for_combine (GET_MODE (SUBREG_REG (x)), y))) 776450397Sobrien return 1; 776550397Sobrien 776650397Sobrien /* We used to see if get_last_value of X and Y were the same but that's 776750397Sobrien not correct. In one direction, we'll cause the assignment to have 776850397Sobrien the wrong destination and in the case, we'll import a register into this 776950397Sobrien insn that might have already have been dead. So fail if none of the 777050397Sobrien above cases are true. */ 777150397Sobrien return 0; 777250397Sobrien} 777350397Sobrien 777418334Speter/* See if X, a SET operation, can be rewritten as a bit-field assignment. 777518334Speter Return that assignment if so. 777618334Speter 777718334Speter We only handle the most common cases. */ 777818334Speter 777918334Speterstatic rtx 778018334Spetermake_field_assignment (x) 778118334Speter rtx x; 778218334Speter{ 778318334Speter rtx dest = SET_DEST (x); 778418334Speter rtx src = SET_SRC (x); 778518334Speter rtx assign; 778650397Sobrien rtx rhs, lhs; 778718334Speter HOST_WIDE_INT c1; 778890075Sobrien HOST_WIDE_INT pos; 778990075Sobrien unsigned HOST_WIDE_INT len; 779018334Speter rtx other; 779118334Speter enum machine_mode mode; 779218334Speter 779318334Speter /* If SRC was (and (not (ashift (const_int 1) POS)) DEST), this is 779418334Speter a clear of a one-bit field. We will have changed it to 779518334Speter (and (rotate (const_int -2) POS) DEST), so check for that. Also check 779618334Speter for a SUBREG. */ 779718334Speter 779818334Speter if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == ROTATE 779918334Speter && GET_CODE (XEXP (XEXP (src, 0), 0)) == CONST_INT 780018334Speter && INTVAL (XEXP (XEXP (src, 0), 0)) == -2 780150397Sobrien && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1))) 780218334Speter { 780318334Speter assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1), 780418334Speter 1, 1, 1, 0); 780550397Sobrien if (assign != 0) 780650397Sobrien return gen_rtx_SET (VOIDmode, assign, const0_rtx); 780750397Sobrien return x; 780818334Speter } 780918334Speter 781018334Speter else if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == SUBREG 781118334Speter && subreg_lowpart_p (XEXP (src, 0)) 781290075Sobrien && (GET_MODE_SIZE (GET_MODE (XEXP (src, 0))) 781318334Speter < GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (src, 0))))) 781418334Speter && GET_CODE (SUBREG_REG (XEXP (src, 0))) == ROTATE 781518334Speter && INTVAL (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == -2 781650397Sobrien && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1))) 781718334Speter { 781818334Speter assign = make_extraction (VOIDmode, dest, 0, 781918334Speter XEXP (SUBREG_REG (XEXP (src, 0)), 1), 782018334Speter 1, 1, 1, 0); 782150397Sobrien if (assign != 0) 782250397Sobrien return gen_rtx_SET (VOIDmode, assign, const0_rtx); 782350397Sobrien return x; 782418334Speter } 782518334Speter 782650397Sobrien /* If SRC is (ior (ashift (const_int 1) POS) DEST), this is a set of a 782718334Speter one-bit field. */ 782818334Speter else if (GET_CODE (src) == IOR && GET_CODE (XEXP (src, 0)) == ASHIFT 782918334Speter && XEXP (XEXP (src, 0), 0) == const1_rtx 783050397Sobrien && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1))) 783118334Speter { 783218334Speter assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1), 783318334Speter 1, 1, 1, 0); 783450397Sobrien if (assign != 0) 783550397Sobrien return gen_rtx_SET (VOIDmode, assign, const1_rtx); 783650397Sobrien return x; 783718334Speter } 783818334Speter 783918334Speter /* The other case we handle is assignments into a constant-position 784050397Sobrien field. They look like (ior/xor (and DEST C1) OTHER). If C1 represents 784118334Speter a mask that has all one bits except for a group of zero bits and 784218334Speter OTHER is known to have zeros where C1 has ones, this is such an 784318334Speter assignment. Compute the position and length from C1. Shift OTHER 784418334Speter to the appropriate position, force it to the required mode, and 784518334Speter make the extraction. Check for the AND in both operands. */ 784618334Speter 784750397Sobrien if (GET_CODE (src) != IOR && GET_CODE (src) != XOR) 784850397Sobrien return x; 784950397Sobrien 785050397Sobrien rhs = expand_compound_operation (XEXP (src, 0)); 785150397Sobrien lhs = expand_compound_operation (XEXP (src, 1)); 785250397Sobrien 785350397Sobrien if (GET_CODE (rhs) == AND 785450397Sobrien && GET_CODE (XEXP (rhs, 1)) == CONST_INT 785550397Sobrien && rtx_equal_for_field_assignment_p (XEXP (rhs, 0), dest)) 785650397Sobrien c1 = INTVAL (XEXP (rhs, 1)), other = lhs; 785750397Sobrien else if (GET_CODE (lhs) == AND 785850397Sobrien && GET_CODE (XEXP (lhs, 1)) == CONST_INT 785950397Sobrien && rtx_equal_for_field_assignment_p (XEXP (lhs, 0), dest)) 786050397Sobrien c1 = INTVAL (XEXP (lhs, 1)), other = rhs; 786118334Speter else 786218334Speter return x; 786318334Speter 786490075Sobrien pos = get_pos_from_mask ((~c1) & GET_MODE_MASK (GET_MODE (dest)), &len); 786518334Speter if (pos < 0 || pos + len > GET_MODE_BITSIZE (GET_MODE (dest)) 786650397Sobrien || GET_MODE_BITSIZE (GET_MODE (dest)) > HOST_BITS_PER_WIDE_INT 786750397Sobrien || (c1 & nonzero_bits (other, GET_MODE (dest))) != 0) 786818334Speter return x; 786918334Speter 787018334Speter assign = make_extraction (VOIDmode, dest, pos, NULL_RTX, len, 1, 1, 0); 787150397Sobrien if (assign == 0) 787250397Sobrien return x; 787318334Speter 787418334Speter /* The mode to use for the source is the mode of the assignment, or of 787518334Speter what is inside a possible STRICT_LOW_PART. */ 787690075Sobrien mode = (GET_CODE (assign) == STRICT_LOW_PART 787718334Speter ? GET_MODE (XEXP (assign, 0)) : GET_MODE (assign)); 787818334Speter 787918334Speter /* Shift OTHER right POS places and make it the source, restricting it 788018334Speter to the proper length and mode. */ 788118334Speter 788218334Speter src = force_to_mode (simplify_shift_const (NULL_RTX, LSHIFTRT, 788318334Speter GET_MODE (src), other, pos), 788418334Speter mode, 788518334Speter GET_MODE_BITSIZE (mode) >= HOST_BITS_PER_WIDE_INT 788690075Sobrien ? ~(unsigned HOST_WIDE_INT) 0 788790075Sobrien : ((unsigned HOST_WIDE_INT) 1 << len) - 1, 788818334Speter dest, 0); 788918334Speter 789090075Sobrien return gen_rtx_SET (VOIDmode, assign, src); 789118334Speter} 789218334Speter 789318334Speter/* See if X is of the form (+ (* a c) (* b c)) and convert to (* (+ a b) c) 789418334Speter if so. */ 789518334Speter 789618334Speterstatic rtx 789718334Speterapply_distributive_law (x) 789818334Speter rtx x; 789918334Speter{ 790018334Speter enum rtx_code code = GET_CODE (x); 790118334Speter rtx lhs, rhs, other; 790218334Speter rtx tem; 790318334Speter enum rtx_code inner_code; 790418334Speter 790518334Speter /* Distributivity is not true for floating point. 790618334Speter It can change the value. So don't do it. 790718334Speter -- rms and moshier@world.std.com. */ 790818334Speter if (FLOAT_MODE_P (GET_MODE (x))) 790918334Speter return x; 791018334Speter 791118334Speter /* The outer operation can only be one of the following: */ 791218334Speter if (code != IOR && code != AND && code != XOR 791318334Speter && code != PLUS && code != MINUS) 791418334Speter return x; 791518334Speter 791618334Speter lhs = XEXP (x, 0), rhs = XEXP (x, 1); 791718334Speter 791850397Sobrien /* If either operand is a primitive we can't do anything, so get out 791950397Sobrien fast. */ 792018334Speter if (GET_RTX_CLASS (GET_CODE (lhs)) == 'o' 792118334Speter || GET_RTX_CLASS (GET_CODE (rhs)) == 'o') 792218334Speter return x; 792318334Speter 792418334Speter lhs = expand_compound_operation (lhs); 792518334Speter rhs = expand_compound_operation (rhs); 792618334Speter inner_code = GET_CODE (lhs); 792718334Speter if (inner_code != GET_CODE (rhs)) 792818334Speter return x; 792918334Speter 793018334Speter /* See if the inner and outer operations distribute. */ 793118334Speter switch (inner_code) 793218334Speter { 793318334Speter case LSHIFTRT: 793418334Speter case ASHIFTRT: 793518334Speter case AND: 793618334Speter case IOR: 793718334Speter /* These all distribute except over PLUS. */ 793818334Speter if (code == PLUS || code == MINUS) 793918334Speter return x; 794018334Speter break; 794118334Speter 794218334Speter case MULT: 794318334Speter if (code != PLUS && code != MINUS) 794418334Speter return x; 794518334Speter break; 794618334Speter 794718334Speter case ASHIFT: 794818334Speter /* This is also a multiply, so it distributes over everything. */ 794918334Speter break; 795018334Speter 795118334Speter case SUBREG: 795218334Speter /* Non-paradoxical SUBREGs distributes over all operations, provided 795390075Sobrien the inner modes and byte offsets are the same, this is an extraction 795418334Speter of a low-order part, we don't convert an fp operation to int or 795518334Speter vice versa, and we would not be converting a single-word 795618334Speter operation into a multi-word operation. The latter test is not 795718334Speter required, but it prevents generating unneeded multi-word operations. 795818334Speter Some of the previous tests are redundant given the latter test, but 795918334Speter are retained because they are required for correctness. 796018334Speter 796118334Speter We produce the result slightly differently in this case. */ 796218334Speter 796318334Speter if (GET_MODE (SUBREG_REG (lhs)) != GET_MODE (SUBREG_REG (rhs)) 796490075Sobrien || SUBREG_BYTE (lhs) != SUBREG_BYTE (rhs) 796518334Speter || ! subreg_lowpart_p (lhs) 796618334Speter || (GET_MODE_CLASS (GET_MODE (lhs)) 796718334Speter != GET_MODE_CLASS (GET_MODE (SUBREG_REG (lhs)))) 796818334Speter || (GET_MODE_SIZE (GET_MODE (lhs)) 796918334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs)))) 797018334Speter || GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))) > UNITS_PER_WORD) 797118334Speter return x; 797218334Speter 797318334Speter tem = gen_binary (code, GET_MODE (SUBREG_REG (lhs)), 797418334Speter SUBREG_REG (lhs), SUBREG_REG (rhs)); 797518334Speter return gen_lowpart_for_combine (GET_MODE (x), tem); 797618334Speter 797718334Speter default: 797818334Speter return x; 797918334Speter } 798018334Speter 798118334Speter /* Set LHS and RHS to the inner operands (A and B in the example 798218334Speter above) and set OTHER to the common operand (C in the example). 798318334Speter These is only one way to do this unless the inner operation is 798418334Speter commutative. */ 798518334Speter if (GET_RTX_CLASS (inner_code) == 'c' 798618334Speter && rtx_equal_p (XEXP (lhs, 0), XEXP (rhs, 0))) 798718334Speter other = XEXP (lhs, 0), lhs = XEXP (lhs, 1), rhs = XEXP (rhs, 1); 798818334Speter else if (GET_RTX_CLASS (inner_code) == 'c' 798918334Speter && rtx_equal_p (XEXP (lhs, 0), XEXP (rhs, 1))) 799018334Speter other = XEXP (lhs, 0), lhs = XEXP (lhs, 1), rhs = XEXP (rhs, 0); 799118334Speter else if (GET_RTX_CLASS (inner_code) == 'c' 799218334Speter && rtx_equal_p (XEXP (lhs, 1), XEXP (rhs, 0))) 799318334Speter other = XEXP (lhs, 1), lhs = XEXP (lhs, 0), rhs = XEXP (rhs, 1); 799418334Speter else if (rtx_equal_p (XEXP (lhs, 1), XEXP (rhs, 1))) 799518334Speter other = XEXP (lhs, 1), lhs = XEXP (lhs, 0), rhs = XEXP (rhs, 0); 799618334Speter else 799718334Speter return x; 799818334Speter 799918334Speter /* Form the new inner operation, seeing if it simplifies first. */ 800018334Speter tem = gen_binary (code, GET_MODE (x), lhs, rhs); 800118334Speter 800218334Speter /* There is one exception to the general way of distributing: 800318334Speter (a ^ b) | (a ^ c) -> (~a) & (b ^ c) */ 800418334Speter if (code == XOR && inner_code == IOR) 800518334Speter { 800618334Speter inner_code = AND; 800790075Sobrien other = simplify_gen_unary (NOT, GET_MODE (x), other, GET_MODE (x)); 800818334Speter } 800918334Speter 801018334Speter /* We may be able to continuing distributing the result, so call 801118334Speter ourselves recursively on the inner operation before forming the 801218334Speter outer operation, which we return. */ 801318334Speter return gen_binary (inner_code, GET_MODE (x), 801418334Speter apply_distributive_law (tem), other); 801518334Speter} 801618334Speter 801718334Speter/* We have X, a logical `and' of VAROP with the constant CONSTOP, to be done 801818334Speter in MODE. 801918334Speter 802018334Speter Return an equivalent form, if different from X. Otherwise, return X. If 802118334Speter X is zero, we are to always construct the equivalent form. */ 802218334Speter 802318334Speterstatic rtx 802418334Spetersimplify_and_const_int (x, mode, varop, constop) 802518334Speter rtx x; 802618334Speter enum machine_mode mode; 802718334Speter rtx varop; 802818334Speter unsigned HOST_WIDE_INT constop; 802918334Speter{ 803018334Speter unsigned HOST_WIDE_INT nonzero; 803118334Speter int i; 803218334Speter 803318334Speter /* Simplify VAROP knowing that we will be only looking at some of the 803496263Sobrien bits in it. 803596263Sobrien 803696263Sobrien Note by passing in CONSTOP, we guarantee that the bits not set in 803796263Sobrien CONSTOP are not significant and will never be examined. We must 803896263Sobrien ensure that is the case by explicitly masking out those bits 803996263Sobrien before returning. */ 804018334Speter varop = force_to_mode (varop, mode, constop, NULL_RTX, 0); 804118334Speter 804296263Sobrien /* If VAROP is a CLOBBER, we will fail so return it. */ 804396263Sobrien if (GET_CODE (varop) == CLOBBER) 804418334Speter return varop; 804518334Speter 804696263Sobrien /* If VAROP is a CONST_INT, then we need to apply the mask in CONSTOP 804796263Sobrien to VAROP and return the new constant. */ 804896263Sobrien if (GET_CODE (varop) == CONST_INT) 804996263Sobrien return GEN_INT (trunc_int_for_mode (INTVAL (varop) & constop, mode)); 805096263Sobrien 805118334Speter /* See what bits may be nonzero in VAROP. Unlike the general case of 805218334Speter a call to nonzero_bits, here we don't care about bits outside 805318334Speter MODE. */ 805418334Speter 805518334Speter nonzero = nonzero_bits (varop, mode) & GET_MODE_MASK (mode); 805618334Speter 805718334Speter /* Turn off all bits in the constant that are known to already be zero. 805818334Speter Thus, if the AND isn't needed at all, we will have CONSTOP == NONZERO_BITS 805918334Speter which is tested below. */ 806018334Speter 806118334Speter constop &= nonzero; 806218334Speter 806318334Speter /* If we don't have any bits left, return zero. */ 806418334Speter if (constop == 0) 806518334Speter return const0_rtx; 806618334Speter 806718334Speter /* If VAROP is a NEG of something known to be zero or 1 and CONSTOP is 8068117395Skan a power of two, we can replace this with an ASHIFT. */ 806918334Speter if (GET_CODE (varop) == NEG && nonzero_bits (XEXP (varop, 0), mode) == 1 807018334Speter && (i = exact_log2 (constop)) >= 0) 807118334Speter return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (varop, 0), i); 807290075Sobrien 807318334Speter /* If VAROP is an IOR or XOR, apply the AND to both branches of the IOR 807418334Speter or XOR, then try to apply the distributive law. This may eliminate 807518334Speter operations if either branch can be simplified because of the AND. 807618334Speter It may also make some cases more complex, but those cases probably 807718334Speter won't match a pattern either with or without this. */ 807818334Speter 807918334Speter if (GET_CODE (varop) == IOR || GET_CODE (varop) == XOR) 808018334Speter return 808118334Speter gen_lowpart_for_combine 808218334Speter (mode, 808318334Speter apply_distributive_law 808418334Speter (gen_binary (GET_CODE (varop), GET_MODE (varop), 808518334Speter simplify_and_const_int (NULL_RTX, GET_MODE (varop), 808618334Speter XEXP (varop, 0), constop), 808718334Speter simplify_and_const_int (NULL_RTX, GET_MODE (varop), 808818334Speter XEXP (varop, 1), constop)))); 808918334Speter 809090075Sobrien /* If VAROP is PLUS, and the constant is a mask of low bite, distribute 809190075Sobrien the AND and see if one of the operands simplifies to zero. If so, we 809290075Sobrien may eliminate it. */ 809390075Sobrien 809490075Sobrien if (GET_CODE (varop) == PLUS 809590075Sobrien && exact_log2 (constop + 1) >= 0) 809690075Sobrien { 809790075Sobrien rtx o0, o1; 809890075Sobrien 809990075Sobrien o0 = simplify_and_const_int (NULL_RTX, mode, XEXP (varop, 0), constop); 810090075Sobrien o1 = simplify_and_const_int (NULL_RTX, mode, XEXP (varop, 1), constop); 810190075Sobrien if (o0 == const0_rtx) 810290075Sobrien return o1; 810390075Sobrien if (o1 == const0_rtx) 810490075Sobrien return o0; 810590075Sobrien } 810690075Sobrien 810718334Speter /* Get VAROP in MODE. Try to get a SUBREG if not. Don't make a new SUBREG 810818334Speter if we already had one (just check for the simplest cases). */ 810918334Speter if (x && GET_CODE (XEXP (x, 0)) == SUBREG 811018334Speter && GET_MODE (XEXP (x, 0)) == mode 811118334Speter && SUBREG_REG (XEXP (x, 0)) == varop) 811218334Speter varop = XEXP (x, 0); 811318334Speter else 811418334Speter varop = gen_lowpart_for_combine (mode, varop); 811518334Speter 811650397Sobrien /* If we can't make the SUBREG, try to return what we were given. */ 811718334Speter if (GET_CODE (varop) == CLOBBER) 811818334Speter return x ? x : varop; 811918334Speter 812018334Speter /* If we are only masking insignificant bits, return VAROP. */ 812118334Speter if (constop == nonzero) 812218334Speter x = varop; 812318334Speter else 812418334Speter { 812590075Sobrien /* Otherwise, return an AND. */ 812690075Sobrien constop = trunc_int_for_mode (constop, mode); 812790075Sobrien /* See how much, if any, of X we can use. */ 812890075Sobrien if (x == 0 || GET_CODE (x) != AND || GET_MODE (x) != mode) 812990075Sobrien x = gen_binary (AND, mode, varop, GEN_INT (constop)); 813018334Speter 813190075Sobrien else 813290075Sobrien { 813390075Sobrien if (GET_CODE (XEXP (x, 1)) != CONST_INT 813490075Sobrien || (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) != constop) 813590075Sobrien SUBST (XEXP (x, 1), GEN_INT (constop)); 813690075Sobrien 813790075Sobrien SUBST (XEXP (x, 0), varop); 813890075Sobrien } 813918334Speter } 814018334Speter 814118334Speter return x; 814218334Speter} 814318334Speter 8144117395Skan#define nonzero_bits_with_known(X, MODE) \ 8145117395Skan cached_nonzero_bits (X, MODE, known_x, known_mode, known_ret) 8146117395Skan 8147117395Skan/* The function cached_nonzero_bits is a wrapper around nonzero_bits1. 8148117395Skan It avoids exponential behavior in nonzero_bits1 when X has 8149117395Skan identical subexpressions on the first or the second level. */ 8150117395Skan 8151117395Skanstatic unsigned HOST_WIDE_INT 8152117395Skancached_nonzero_bits (x, mode, known_x, known_mode, known_ret) 8153117395Skan rtx x; 8154117395Skan enum machine_mode mode; 8155117395Skan rtx known_x; 8156117395Skan enum machine_mode known_mode; 8157117395Skan unsigned HOST_WIDE_INT known_ret; 8158117395Skan{ 8159117395Skan if (x == known_x && mode == known_mode) 8160117395Skan return known_ret; 8161117395Skan 8162117395Skan /* Try to find identical subexpressions. If found call 8163117395Skan nonzero_bits1 on X with the subexpressions as KNOWN_X and the 8164117395Skan precomputed value for the subexpression as KNOWN_RET. */ 8165117395Skan 8166117395Skan if (GET_RTX_CLASS (GET_CODE (x)) == '2' 8167117395Skan || GET_RTX_CLASS (GET_CODE (x)) == 'c') 8168117395Skan { 8169117395Skan rtx x0 = XEXP (x, 0); 8170117395Skan rtx x1 = XEXP (x, 1); 8171117395Skan 8172117395Skan /* Check the first level. */ 8173117395Skan if (x0 == x1) 8174117395Skan return nonzero_bits1 (x, mode, x0, mode, 8175117395Skan nonzero_bits_with_known (x0, mode)); 8176117395Skan 8177117395Skan /* Check the second level. */ 8178117395Skan if ((GET_RTX_CLASS (GET_CODE (x0)) == '2' 8179117395Skan || GET_RTX_CLASS (GET_CODE (x0)) == 'c') 8180117395Skan && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1))) 8181117395Skan return nonzero_bits1 (x, mode, x1, mode, 8182117395Skan nonzero_bits_with_known (x1, mode)); 8183117395Skan 8184117395Skan if ((GET_RTX_CLASS (GET_CODE (x1)) == '2' 8185117395Skan || GET_RTX_CLASS (GET_CODE (x1)) == 'c') 8186117395Skan && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1))) 8187117395Skan return nonzero_bits1 (x, mode, x0, mode, 8188117395Skan nonzero_bits_with_known (x0, mode)); 8189117395Skan } 8190117395Skan 8191117395Skan return nonzero_bits1 (x, mode, known_x, known_mode, known_ret); 8192117395Skan} 8193117395Skan 819450397Sobrien/* We let num_sign_bit_copies recur into nonzero_bits as that is useful. 819550397Sobrien We don't let nonzero_bits recur into num_sign_bit_copies, because that 819650397Sobrien is less useful. We can't allow both, because that results in exponential 819750397Sobrien run time recursion. There is a nullstone testcase that triggered 819850397Sobrien this. This macro avoids accidental uses of num_sign_bit_copies. */ 8199117395Skan#define cached_num_sign_bit_copies() 820050397Sobrien 8201117395Skan/* Given an expression, X, compute which bits in X can be nonzero. 820218334Speter We don't care about bits outside of those defined in MODE. 820318334Speter 820418334Speter For most X this is simply GET_MODE_MASK (GET_MODE (MODE)), but if X is 820518334Speter a shift, AND, or zero_extract, we can do better. */ 820618334Speter 820718334Speterstatic unsigned HOST_WIDE_INT 8208117395Skannonzero_bits1 (x, mode, known_x, known_mode, known_ret) 820918334Speter rtx x; 821018334Speter enum machine_mode mode; 8211117395Skan rtx known_x; 8212117395Skan enum machine_mode known_mode; 8213117395Skan unsigned HOST_WIDE_INT known_ret; 821418334Speter{ 821518334Speter unsigned HOST_WIDE_INT nonzero = GET_MODE_MASK (mode); 821618334Speter unsigned HOST_WIDE_INT inner_nz; 821718334Speter enum rtx_code code; 821890075Sobrien unsigned int mode_width = GET_MODE_BITSIZE (mode); 821918334Speter rtx tem; 822018334Speter 822118334Speter /* For floating-point values, assume all bits are needed. */ 822218334Speter if (FLOAT_MODE_P (GET_MODE (x)) || FLOAT_MODE_P (mode)) 822318334Speter return nonzero; 822418334Speter 822518334Speter /* If X is wider than MODE, use its mode instead. */ 822618334Speter if (GET_MODE_BITSIZE (GET_MODE (x)) > mode_width) 822718334Speter { 822818334Speter mode = GET_MODE (x); 822918334Speter nonzero = GET_MODE_MASK (mode); 823018334Speter mode_width = GET_MODE_BITSIZE (mode); 823118334Speter } 823218334Speter 823318334Speter if (mode_width > HOST_BITS_PER_WIDE_INT) 823418334Speter /* Our only callers in this case look for single bit values. So 823518334Speter just return the mode mask. Those tests will then be false. */ 823618334Speter return nonzero; 823718334Speter 823818334Speter#ifndef WORD_REGISTER_OPERATIONS 823918334Speter /* If MODE is wider than X, but both are a single word for both the host 824090075Sobrien and target machines, we can compute this from which bits of the 824118334Speter object might be nonzero in its own mode, taking into account the fact 824218334Speter that on many CISC machines, accessing an object in a wider mode 824318334Speter causes the high-order bits to become undefined. So they are 824418334Speter not known to be zero. */ 824518334Speter 824618334Speter if (GET_MODE (x) != VOIDmode && GET_MODE (x) != mode 824718334Speter && GET_MODE_BITSIZE (GET_MODE (x)) <= BITS_PER_WORD 824818334Speter && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT 824918334Speter && GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (GET_MODE (x))) 825018334Speter { 8251117395Skan nonzero &= nonzero_bits_with_known (x, GET_MODE (x)); 825290075Sobrien nonzero |= GET_MODE_MASK (mode) & ~GET_MODE_MASK (GET_MODE (x)); 825318334Speter return nonzero; 825418334Speter } 825518334Speter#endif 825618334Speter 825718334Speter code = GET_CODE (x); 825818334Speter switch (code) 825918334Speter { 826018334Speter case REG: 826190075Sobrien#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend) 826218334Speter /* If pointers extend unsigned and this is a pointer in Pmode, say that 826318334Speter all the bits above ptr_mode are known to be zero. */ 826418334Speter if (POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode 826590075Sobrien && REG_POINTER (x)) 826618334Speter nonzero &= GET_MODE_MASK (ptr_mode); 826718334Speter#endif 826818334Speter 826996263Sobrien /* Include declared information about alignment of pointers. */ 827096263Sobrien /* ??? We don't properly preserve REG_POINTER changes across 827196263Sobrien pointer-to-integer casts, so we can't trust it except for 827296263Sobrien things that we know must be pointers. See execute/960116-1.c. */ 827396263Sobrien if ((x == stack_pointer_rtx 827496263Sobrien || x == frame_pointer_rtx 827596263Sobrien || x == arg_pointer_rtx) 827696263Sobrien && REGNO_POINTER_ALIGN (REGNO (x))) 827718334Speter { 827896263Sobrien unsigned HOST_WIDE_INT alignment 827996263Sobrien = REGNO_POINTER_ALIGN (REGNO (x)) / BITS_PER_UNIT; 828018334Speter 828118334Speter#ifdef PUSH_ROUNDING 828296263Sobrien /* If PUSH_ROUNDING is defined, it is possible for the 828396263Sobrien stack to be momentarily aligned only to that amount, 828496263Sobrien so we pick the least alignment. */ 828596263Sobrien if (x == stack_pointer_rtx && PUSH_ARGS) 828696263Sobrien alignment = MIN (PUSH_ROUNDING (1), alignment); 828718334Speter#endif 828818334Speter 828996263Sobrien nonzero &= ~(alignment - 1); 829018334Speter } 829118334Speter 829218334Speter /* If X is a register whose nonzero bits value is current, use it. 829318334Speter Otherwise, if X is a register whose value we can find, use that 829418334Speter value. Otherwise, use the previously-computed global nonzero bits 829518334Speter for this register. */ 829618334Speter 829718334Speter if (reg_last_set_value[REGNO (x)] != 0 829896263Sobrien && (reg_last_set_mode[REGNO (x)] == mode 829996263Sobrien || (GET_MODE_CLASS (reg_last_set_mode[REGNO (x)]) == MODE_INT 830096263Sobrien && GET_MODE_CLASS (mode) == MODE_INT)) 830190075Sobrien && (reg_last_set_label[REGNO (x)] == label_tick 830290075Sobrien || (REGNO (x) >= FIRST_PSEUDO_REGISTER 830390075Sobrien && REG_N_SETS (REGNO (x)) == 1 8304117395Skan && ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, 830590075Sobrien REGNO (x)))) 830618334Speter && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid) 830796263Sobrien return reg_last_set_nonzero_bits[REGNO (x)] & nonzero; 830818334Speter 830918334Speter tem = get_last_value (x); 831018334Speter 831118334Speter if (tem) 831218334Speter { 831318334Speter#ifdef SHORT_IMMEDIATES_SIGN_EXTEND 831418334Speter /* If X is narrower than MODE and TEM is a non-negative 831518334Speter constant that would appear negative in the mode of X, 831618334Speter sign-extend it for use in reg_nonzero_bits because some 831718334Speter machines (maybe most) will actually do the sign-extension 831890075Sobrien and this is the conservative approach. 831918334Speter 832018334Speter ??? For 2.5, try to tighten up the MD files in this regard 832118334Speter instead of this kludge. */ 832218334Speter 832318334Speter if (GET_MODE_BITSIZE (GET_MODE (x)) < mode_width 832418334Speter && GET_CODE (tem) == CONST_INT 832518334Speter && INTVAL (tem) > 0 832618334Speter && 0 != (INTVAL (tem) 832718334Speter & ((HOST_WIDE_INT) 1 832818334Speter << (GET_MODE_BITSIZE (GET_MODE (x)) - 1)))) 832918334Speter tem = GEN_INT (INTVAL (tem) 833018334Speter | ((HOST_WIDE_INT) (-1) 833118334Speter << GET_MODE_BITSIZE (GET_MODE (x)))); 833218334Speter#endif 8333117395Skan return nonzero_bits_with_known (tem, mode) & nonzero; 833418334Speter } 833518334Speter else if (nonzero_sign_valid && reg_nonzero_bits[REGNO (x)]) 833690075Sobrien { 833790075Sobrien unsigned HOST_WIDE_INT mask = reg_nonzero_bits[REGNO (x)]; 833890075Sobrien 833990075Sobrien if (GET_MODE_BITSIZE (GET_MODE (x)) < mode_width) 834090075Sobrien /* We don't know anything about the upper bits. */ 834190075Sobrien mask |= GET_MODE_MASK (mode) ^ GET_MODE_MASK (GET_MODE (x)); 834290075Sobrien return nonzero & mask; 834390075Sobrien } 834418334Speter else 834518334Speter return nonzero; 834618334Speter 834718334Speter case CONST_INT: 834818334Speter#ifdef SHORT_IMMEDIATES_SIGN_EXTEND 834918334Speter /* If X is negative in MODE, sign-extend the value. */ 835018334Speter if (INTVAL (x) > 0 && mode_width < BITS_PER_WORD 835118334Speter && 0 != (INTVAL (x) & ((HOST_WIDE_INT) 1 << (mode_width - 1)))) 835218334Speter return (INTVAL (x) | ((HOST_WIDE_INT) (-1) << mode_width)); 835318334Speter#endif 835418334Speter 835518334Speter return INTVAL (x); 835618334Speter 835718334Speter case MEM: 835818334Speter#ifdef LOAD_EXTEND_OP 835918334Speter /* In many, if not most, RISC machines, reading a byte from memory 836018334Speter zeros the rest of the register. Noticing that fact saves a lot 836118334Speter of extra zero-extends. */ 836218334Speter if (LOAD_EXTEND_OP (GET_MODE (x)) == ZERO_EXTEND) 836318334Speter nonzero &= GET_MODE_MASK (GET_MODE (x)); 836418334Speter#endif 836518334Speter break; 836618334Speter 836718334Speter case EQ: case NE: 836890075Sobrien case UNEQ: case LTGT: 836990075Sobrien case GT: case GTU: case UNGT: 837090075Sobrien case LT: case LTU: case UNLT: 837190075Sobrien case GE: case GEU: case UNGE: 837290075Sobrien case LE: case LEU: case UNLE: 837390075Sobrien case UNORDERED: case ORDERED: 837418334Speter 837518334Speter /* If this produces an integer result, we know which bits are set. 837618334Speter Code here used to clear bits outside the mode of X, but that is 837718334Speter now done above. */ 837818334Speter 837918334Speter if (GET_MODE_CLASS (mode) == MODE_INT 838018334Speter && mode_width <= HOST_BITS_PER_WIDE_INT) 838118334Speter nonzero = STORE_FLAG_VALUE; 838218334Speter break; 838318334Speter 838418334Speter case NEG: 838550397Sobrien#if 0 838650397Sobrien /* Disabled to avoid exponential mutual recursion between nonzero_bits 838750397Sobrien and num_sign_bit_copies. */ 838818334Speter if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (x)) 838918334Speter == GET_MODE_BITSIZE (GET_MODE (x))) 839018334Speter nonzero = 1; 839150397Sobrien#endif 839218334Speter 839318334Speter if (GET_MODE_SIZE (GET_MODE (x)) < mode_width) 839490075Sobrien nonzero |= (GET_MODE_MASK (mode) & ~GET_MODE_MASK (GET_MODE (x))); 839518334Speter break; 839618334Speter 839718334Speter case ABS: 839850397Sobrien#if 0 839950397Sobrien /* Disabled to avoid exponential mutual recursion between nonzero_bits 840050397Sobrien and num_sign_bit_copies. */ 840118334Speter if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (x)) 840218334Speter == GET_MODE_BITSIZE (GET_MODE (x))) 840318334Speter nonzero = 1; 840450397Sobrien#endif 840518334Speter break; 840618334Speter 840718334Speter case TRUNCATE: 8408117395Skan nonzero &= (nonzero_bits_with_known (XEXP (x, 0), mode) 8409117395Skan & GET_MODE_MASK (mode)); 841018334Speter break; 841118334Speter 841218334Speter case ZERO_EXTEND: 8413117395Skan nonzero &= nonzero_bits_with_known (XEXP (x, 0), mode); 841418334Speter if (GET_MODE (XEXP (x, 0)) != VOIDmode) 841518334Speter nonzero &= GET_MODE_MASK (GET_MODE (XEXP (x, 0))); 841618334Speter break; 841718334Speter 841818334Speter case SIGN_EXTEND: 841918334Speter /* If the sign bit is known clear, this is the same as ZERO_EXTEND. 842018334Speter Otherwise, show all the bits in the outer mode but not the inner 8421117395Skan may be nonzero. */ 8422117395Skan inner_nz = nonzero_bits_with_known (XEXP (x, 0), mode); 842318334Speter if (GET_MODE (XEXP (x, 0)) != VOIDmode) 842418334Speter { 842518334Speter inner_nz &= GET_MODE_MASK (GET_MODE (XEXP (x, 0))); 842650397Sobrien if (inner_nz 842750397Sobrien & (((HOST_WIDE_INT) 1 842850397Sobrien << (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - 1)))) 842918334Speter inner_nz |= (GET_MODE_MASK (mode) 843090075Sobrien & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))); 843118334Speter } 843218334Speter 843318334Speter nonzero &= inner_nz; 843418334Speter break; 843518334Speter 843618334Speter case AND: 8437117395Skan nonzero &= (nonzero_bits_with_known (XEXP (x, 0), mode) 8438117395Skan & nonzero_bits_with_known (XEXP (x, 1), mode)); 843918334Speter break; 844018334Speter 844118334Speter case XOR: case IOR: 844218334Speter case UMIN: case UMAX: case SMIN: case SMAX: 844396263Sobrien { 8444117395Skan unsigned HOST_WIDE_INT nonzero0 = 8445117395Skan nonzero_bits_with_known (XEXP (x, 0), mode); 844696263Sobrien 844796263Sobrien /* Don't call nonzero_bits for the second time if it cannot change 844896263Sobrien anything. */ 844996263Sobrien if ((nonzero & nonzero0) != nonzero) 8450117395Skan nonzero &= (nonzero0 8451117395Skan | nonzero_bits_with_known (XEXP (x, 1), mode)); 845296263Sobrien } 845318334Speter break; 845418334Speter 845518334Speter case PLUS: case MINUS: 845618334Speter case MULT: 845718334Speter case DIV: case UDIV: 845818334Speter case MOD: case UMOD: 845918334Speter /* We can apply the rules of arithmetic to compute the number of 846018334Speter high- and low-order zero bits of these operations. We start by 8461117395Skan computing the width (position of the highest-order nonzero bit) 846218334Speter and the number of low-order zero bits for each value. */ 846318334Speter { 8464117395Skan unsigned HOST_WIDE_INT nz0 = 8465117395Skan nonzero_bits_with_known (XEXP (x, 0), mode); 8466117395Skan unsigned HOST_WIDE_INT nz1 = 8467117395Skan nonzero_bits_with_known (XEXP (x, 1), mode); 846818334Speter int width0 = floor_log2 (nz0) + 1; 846918334Speter int width1 = floor_log2 (nz1) + 1; 847018334Speter int low0 = floor_log2 (nz0 & -nz0); 847118334Speter int low1 = floor_log2 (nz1 & -nz1); 847218334Speter HOST_WIDE_INT op0_maybe_minusp 847318334Speter = (nz0 & ((HOST_WIDE_INT) 1 << (mode_width - 1))); 847418334Speter HOST_WIDE_INT op1_maybe_minusp 847518334Speter = (nz1 & ((HOST_WIDE_INT) 1 << (mode_width - 1))); 847690075Sobrien unsigned int result_width = mode_width; 847718334Speter int result_low = 0; 847818334Speter 847918334Speter switch (code) 848018334Speter { 848118334Speter case PLUS: 848218334Speter result_width = MAX (width0, width1) + 1; 848318334Speter result_low = MIN (low0, low1); 848418334Speter break; 848518334Speter case MINUS: 848618334Speter result_low = MIN (low0, low1); 848718334Speter break; 848818334Speter case MULT: 848918334Speter result_width = width0 + width1; 849018334Speter result_low = low0 + low1; 849118334Speter break; 849218334Speter case DIV: 849390075Sobrien if (width1 == 0) 849490075Sobrien break; 849518334Speter if (! op0_maybe_minusp && ! op1_maybe_minusp) 849618334Speter result_width = width0; 849718334Speter break; 849818334Speter case UDIV: 849990075Sobrien if (width1 == 0) 850090075Sobrien break; 850118334Speter result_width = width0; 850218334Speter break; 850318334Speter case MOD: 850490075Sobrien if (width1 == 0) 850590075Sobrien break; 850618334Speter if (! op0_maybe_minusp && ! op1_maybe_minusp) 850718334Speter result_width = MIN (width0, width1); 850818334Speter result_low = MIN (low0, low1); 850918334Speter break; 851018334Speter case UMOD: 851190075Sobrien if (width1 == 0) 851290075Sobrien break; 851318334Speter result_width = MIN (width0, width1); 851418334Speter result_low = MIN (low0, low1); 851518334Speter break; 851650397Sobrien default: 851750397Sobrien abort (); 851818334Speter } 851918334Speter 852018334Speter if (result_width < mode_width) 852118334Speter nonzero &= ((HOST_WIDE_INT) 1 << result_width) - 1; 852218334Speter 852318334Speter if (result_low > 0) 852490075Sobrien nonzero &= ~(((HOST_WIDE_INT) 1 << result_low) - 1); 852590075Sobrien 852690075Sobrien#ifdef POINTERS_EXTEND_UNSIGNED 852790075Sobrien /* If pointers extend unsigned and this is an addition or subtraction 852890075Sobrien to a pointer in Pmode, all the bits above ptr_mode are known to be 852990075Sobrien zero. */ 853090075Sobrien if (POINTERS_EXTEND_UNSIGNED > 0 && GET_MODE (x) == Pmode 853190075Sobrien && (code == PLUS || code == MINUS) 853290075Sobrien && GET_CODE (XEXP (x, 0)) == REG && REG_POINTER (XEXP (x, 0))) 853390075Sobrien nonzero &= GET_MODE_MASK (ptr_mode); 853490075Sobrien#endif 853518334Speter } 853618334Speter break; 853718334Speter 853818334Speter case ZERO_EXTRACT: 853918334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 854018334Speter && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT) 854118334Speter nonzero &= ((HOST_WIDE_INT) 1 << INTVAL (XEXP (x, 1))) - 1; 854218334Speter break; 854318334Speter 854418334Speter case SUBREG: 854518334Speter /* If this is a SUBREG formed for a promoted variable that has 854618334Speter been zero-extended, we know that at least the high-order bits 854718334Speter are zero, though others might be too. */ 854818334Speter 8549117395Skan if (SUBREG_PROMOTED_VAR_P (x) && SUBREG_PROMOTED_UNSIGNED_P (x) > 0) 855018334Speter nonzero = (GET_MODE_MASK (GET_MODE (x)) 8551117395Skan & nonzero_bits_with_known (SUBREG_REG (x), GET_MODE (x))); 855218334Speter 855318334Speter /* If the inner mode is a single word for both the host and target 855418334Speter machines, we can compute this from which bits of the inner 855518334Speter object might be nonzero. */ 855618334Speter if (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) <= BITS_PER_WORD 855718334Speter && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) 855818334Speter <= HOST_BITS_PER_WIDE_INT)) 855918334Speter { 8560117395Skan nonzero &= nonzero_bits_with_known (SUBREG_REG (x), mode); 856118334Speter 856250397Sobrien#if defined (WORD_REGISTER_OPERATIONS) && defined (LOAD_EXTEND_OP) 856350397Sobrien /* If this is a typical RISC machine, we only have to worry 856450397Sobrien about the way loads are extended. */ 8565117395Skan if ((LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND 8566117395Skan ? (((nonzero 8567117395Skan & (((unsigned HOST_WIDE_INT) 1 8568117395Skan << (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) - 1)))) 8569117395Skan != 0)) 8570117395Skan : LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) != ZERO_EXTEND) 8571117395Skan || GET_CODE (SUBREG_REG (x)) != MEM) 857218334Speter#endif 857350397Sobrien { 857450397Sobrien /* On many CISC machines, accessing an object in a wider mode 857550397Sobrien causes the high-order bits to become undefined. So they are 857650397Sobrien not known to be zero. */ 857750397Sobrien if (GET_MODE_SIZE (GET_MODE (x)) 857850397Sobrien > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) 857950397Sobrien nonzero |= (GET_MODE_MASK (GET_MODE (x)) 858090075Sobrien & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))); 858150397Sobrien } 858218334Speter } 858318334Speter break; 858418334Speter 858518334Speter case ASHIFTRT: 858618334Speter case LSHIFTRT: 858718334Speter case ASHIFT: 858818334Speter case ROTATE: 858918334Speter /* The nonzero bits are in two classes: any bits within MODE 859018334Speter that aren't in GET_MODE (x) are always significant. The rest of the 859118334Speter nonzero bits are those that are significant in the operand of 859218334Speter the shift when shifted the appropriate number of bits. This 859318334Speter shows that high-order bits are cleared by the right shift and 859418334Speter low-order bits by left shifts. */ 859518334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 859618334Speter && INTVAL (XEXP (x, 1)) >= 0 859718334Speter && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT) 859818334Speter { 859918334Speter enum machine_mode inner_mode = GET_MODE (x); 860090075Sobrien unsigned int width = GET_MODE_BITSIZE (inner_mode); 860118334Speter int count = INTVAL (XEXP (x, 1)); 860218334Speter unsigned HOST_WIDE_INT mode_mask = GET_MODE_MASK (inner_mode); 8603117395Skan unsigned HOST_WIDE_INT op_nonzero = 8604117395Skan nonzero_bits_with_known (XEXP (x, 0), mode); 860518334Speter unsigned HOST_WIDE_INT inner = op_nonzero & mode_mask; 860618334Speter unsigned HOST_WIDE_INT outer = 0; 860718334Speter 860818334Speter if (mode_width > width) 860990075Sobrien outer = (op_nonzero & nonzero & ~mode_mask); 861018334Speter 861118334Speter if (code == LSHIFTRT) 861218334Speter inner >>= count; 861318334Speter else if (code == ASHIFTRT) 861418334Speter { 861518334Speter inner >>= count; 861618334Speter 861718334Speter /* If the sign bit may have been nonzero before the shift, we 861818334Speter need to mark all the places it could have been copied to 861918334Speter by the shift as possibly nonzero. */ 862018334Speter if (inner & ((HOST_WIDE_INT) 1 << (width - 1 - count))) 862118334Speter inner |= (((HOST_WIDE_INT) 1 << count) - 1) << (width - count); 862218334Speter } 862318334Speter else if (code == ASHIFT) 862418334Speter inner <<= count; 862518334Speter else 862618334Speter inner = ((inner << (count % width) 862718334Speter | (inner >> (width - (count % width)))) & mode_mask); 862818334Speter 862918334Speter nonzero &= (outer | inner); 863018334Speter } 863118334Speter break; 863218334Speter 863318334Speter case FFS: 863418334Speter /* This is at most the number of bits in the mode. */ 863518334Speter nonzero = ((HOST_WIDE_INT) 1 << (floor_log2 (mode_width) + 1)) - 1; 863618334Speter break; 863718334Speter 863818334Speter case IF_THEN_ELSE: 8639117395Skan nonzero &= (nonzero_bits_with_known (XEXP (x, 1), mode) 8640117395Skan | nonzero_bits_with_known (XEXP (x, 2), mode)); 864118334Speter break; 864290075Sobrien 864350397Sobrien default: 864450397Sobrien break; 864518334Speter } 864618334Speter 864718334Speter return nonzero; 864818334Speter} 864950397Sobrien 865050397Sobrien/* See the macro definition above. */ 8651117395Skan#undef cached_num_sign_bit_copies 865218334Speter 8653117395Skan#define num_sign_bit_copies_with_known(X, M) \ 8654117395Skan cached_num_sign_bit_copies (X, M, known_x, known_mode, known_ret) 8655117395Skan 8656117395Skan/* The function cached_num_sign_bit_copies is a wrapper around 8657117395Skan num_sign_bit_copies1. It avoids exponential behavior in 8658117395Skan num_sign_bit_copies1 when X has identical subexpressions on the 8659117395Skan first or the second level. */ 8660117395Skan 8661117395Skanstatic unsigned int 8662117395Skancached_num_sign_bit_copies (x, mode, known_x, known_mode, known_ret) 8663117395Skan rtx x; 8664117395Skan enum machine_mode mode; 8665117395Skan rtx known_x; 8666117395Skan enum machine_mode known_mode; 8667117395Skan unsigned int known_ret; 8668117395Skan{ 8669117395Skan if (x == known_x && mode == known_mode) 8670117395Skan return known_ret; 8671117395Skan 8672117395Skan /* Try to find identical subexpressions. If found call 8673117395Skan num_sign_bit_copies1 on X with the subexpressions as KNOWN_X and 8674117395Skan the precomputed value for the subexpression as KNOWN_RET. */ 8675117395Skan 8676117395Skan if (GET_RTX_CLASS (GET_CODE (x)) == '2' 8677117395Skan || GET_RTX_CLASS (GET_CODE (x)) == 'c') 8678117395Skan { 8679117395Skan rtx x0 = XEXP (x, 0); 8680117395Skan rtx x1 = XEXP (x, 1); 8681117395Skan 8682117395Skan /* Check the first level. */ 8683117395Skan if (x0 == x1) 8684117395Skan return 8685117395Skan num_sign_bit_copies1 (x, mode, x0, mode, 8686117395Skan num_sign_bit_copies_with_known (x0, mode)); 8687117395Skan 8688117395Skan /* Check the second level. */ 8689117395Skan if ((GET_RTX_CLASS (GET_CODE (x0)) == '2' 8690117395Skan || GET_RTX_CLASS (GET_CODE (x0)) == 'c') 8691117395Skan && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1))) 8692117395Skan return 8693117395Skan num_sign_bit_copies1 (x, mode, x1, mode, 8694117395Skan num_sign_bit_copies_with_known (x1, mode)); 8695117395Skan 8696117395Skan if ((GET_RTX_CLASS (GET_CODE (x1)) == '2' 8697117395Skan || GET_RTX_CLASS (GET_CODE (x1)) == 'c') 8698117395Skan && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1))) 8699117395Skan return 8700117395Skan num_sign_bit_copies1 (x, mode, x0, mode, 8701117395Skan num_sign_bit_copies_with_known (x0, mode)); 8702117395Skan } 8703117395Skan 8704117395Skan return num_sign_bit_copies1 (x, mode, known_x, known_mode, known_ret); 8705117395Skan} 8706117395Skan 870718334Speter/* Return the number of bits at the high-order end of X that are known to 870818334Speter be equal to the sign bit. X will be used in mode MODE; if MODE is 870918334Speter VOIDmode, X will be used in its own mode. The returned value will always 871018334Speter be between 1 and the number of bits in MODE. */ 871118334Speter 871290075Sobrienstatic unsigned int 8713117395Skannum_sign_bit_copies1 (x, mode, known_x, known_mode, known_ret) 871418334Speter rtx x; 871518334Speter enum machine_mode mode; 8716117395Skan rtx known_x; 8717117395Skan enum machine_mode known_mode; 8718117395Skan unsigned int known_ret; 871918334Speter{ 872018334Speter enum rtx_code code = GET_CODE (x); 872190075Sobrien unsigned int bitwidth; 872218334Speter int num0, num1, result; 872318334Speter unsigned HOST_WIDE_INT nonzero; 872418334Speter rtx tem; 872518334Speter 872618334Speter /* If we weren't given a mode, use the mode of X. If the mode is still 872718334Speter VOIDmode, we don't know anything. Likewise if one of the modes is 872818334Speter floating-point. */ 872918334Speter 873018334Speter if (mode == VOIDmode) 873118334Speter mode = GET_MODE (x); 873218334Speter 873318334Speter if (mode == VOIDmode || FLOAT_MODE_P (mode) || FLOAT_MODE_P (GET_MODE (x))) 873418334Speter return 1; 873518334Speter 873618334Speter bitwidth = GET_MODE_BITSIZE (mode); 873718334Speter 873850397Sobrien /* For a smaller object, just ignore the high bits. */ 873918334Speter if (bitwidth < GET_MODE_BITSIZE (GET_MODE (x))) 874090075Sobrien { 8741117395Skan num0 = num_sign_bit_copies_with_known (x, GET_MODE (x)); 874290075Sobrien return MAX (1, 874390075Sobrien num0 - (int) (GET_MODE_BITSIZE (GET_MODE (x)) - bitwidth)); 874490075Sobrien } 874590075Sobrien 874650397Sobrien if (GET_MODE (x) != VOIDmode && bitwidth > GET_MODE_BITSIZE (GET_MODE (x))) 874750397Sobrien { 874818334Speter#ifndef WORD_REGISTER_OPERATIONS 874918334Speter /* If this machine does not do all register operations on the entire 875018334Speter register and MODE is wider than the mode of X, we can say nothing 875118334Speter at all about the high-order bits. */ 875250397Sobrien return 1; 875350397Sobrien#else 875450397Sobrien /* Likewise on machines that do, if the mode of the object is smaller 875550397Sobrien than a word and loads of that size don't sign extend, we can say 875650397Sobrien nothing about the high order bits. */ 875750397Sobrien if (GET_MODE_BITSIZE (GET_MODE (x)) < BITS_PER_WORD 875850397Sobrien#ifdef LOAD_EXTEND_OP 875950397Sobrien && LOAD_EXTEND_OP (GET_MODE (x)) != SIGN_EXTEND 876018334Speter#endif 876150397Sobrien ) 876250397Sobrien return 1; 876350397Sobrien#endif 876450397Sobrien } 876518334Speter 876618334Speter switch (code) 876718334Speter { 876818334Speter case REG: 876918334Speter 877090075Sobrien#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend) 877118334Speter /* If pointers extend signed and this is a pointer in Pmode, say that 877218334Speter all the bits above ptr_mode are known to be sign bit copies. */ 877318334Speter if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode && mode == Pmode 877490075Sobrien && REG_POINTER (x)) 877518334Speter return GET_MODE_BITSIZE (Pmode) - GET_MODE_BITSIZE (ptr_mode) + 1; 877618334Speter#endif 877718334Speter 877818334Speter if (reg_last_set_value[REGNO (x)] != 0 877918334Speter && reg_last_set_mode[REGNO (x)] == mode 878090075Sobrien && (reg_last_set_label[REGNO (x)] == label_tick 878190075Sobrien || (REGNO (x) >= FIRST_PSEUDO_REGISTER 878290075Sobrien && REG_N_SETS (REGNO (x)) == 1 8783117395Skan && ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, 878490075Sobrien REGNO (x)))) 878518334Speter && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid) 878618334Speter return reg_last_set_sign_bit_copies[REGNO (x)]; 878718334Speter 878890075Sobrien tem = get_last_value (x); 878918334Speter if (tem != 0) 8790117395Skan return num_sign_bit_copies_with_known (tem, mode); 879118334Speter 879290075Sobrien if (nonzero_sign_valid && reg_sign_bit_copies[REGNO (x)] != 0 879390075Sobrien && GET_MODE_BITSIZE (GET_MODE (x)) == bitwidth) 879418334Speter return reg_sign_bit_copies[REGNO (x)]; 879518334Speter break; 879618334Speter 879718334Speter case MEM: 879818334Speter#ifdef LOAD_EXTEND_OP 879918334Speter /* Some RISC machines sign-extend all loads of smaller than a word. */ 880018334Speter if (LOAD_EXTEND_OP (GET_MODE (x)) == SIGN_EXTEND) 880190075Sobrien return MAX (1, ((int) bitwidth 880290075Sobrien - (int) GET_MODE_BITSIZE (GET_MODE (x)) + 1)); 880318334Speter#endif 880418334Speter break; 880518334Speter 880618334Speter case CONST_INT: 880718334Speter /* If the constant is negative, take its 1's complement and remask. 880818334Speter Then see how many zero bits we have. */ 880918334Speter nonzero = INTVAL (x) & GET_MODE_MASK (mode); 881018334Speter if (bitwidth <= HOST_BITS_PER_WIDE_INT 881118334Speter && (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) 881290075Sobrien nonzero = (~nonzero) & GET_MODE_MASK (mode); 881318334Speter 881418334Speter return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1); 881518334Speter 881618334Speter case SUBREG: 881718334Speter /* If this is a SUBREG for a promoted object that is sign-extended 881818334Speter and we are looking at it in a wider mode, we know that at least the 881918334Speter high-order bits are known to be sign bit copies. */ 882018334Speter 882118334Speter if (SUBREG_PROMOTED_VAR_P (x) && ! SUBREG_PROMOTED_UNSIGNED_P (x)) 882290075Sobrien { 8823117395Skan num0 = num_sign_bit_copies_with_known (SUBREG_REG (x), mode); 882490075Sobrien return MAX ((int) bitwidth 882590075Sobrien - (int) GET_MODE_BITSIZE (GET_MODE (x)) + 1, 882690075Sobrien num0); 882790075Sobrien } 882818334Speter 882950397Sobrien /* For a smaller object, just ignore the high bits. */ 883018334Speter if (bitwidth <= GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))) 883118334Speter { 8832117395Skan num0 = num_sign_bit_copies_with_known (SUBREG_REG (x), VOIDmode); 883318334Speter return MAX (1, (num0 883490075Sobrien - (int) (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) 883590075Sobrien - bitwidth))); 883618334Speter } 883718334Speter 883818334Speter#ifdef WORD_REGISTER_OPERATIONS 883918334Speter#ifdef LOAD_EXTEND_OP 884018334Speter /* For paradoxical SUBREGs on machines where all register operations 884118334Speter affect the entire register, just look inside. Note that we are 884218334Speter passing MODE to the recursive call, so the number of sign bit copies 884318334Speter will remain relative to that mode, not the inner mode. */ 884418334Speter 884518334Speter /* This works only if loads sign extend. Otherwise, if we get a 884618334Speter reload for the inner part, it may be loaded from the stack, and 884718334Speter then we lose all sign bit copies that existed before the store 884818334Speter to the stack. */ 884918334Speter 885018334Speter if ((GET_MODE_SIZE (GET_MODE (x)) 885118334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) 8852117395Skan && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND 8853117395Skan && GET_CODE (SUBREG_REG (x)) == MEM) 8854117395Skan return num_sign_bit_copies_with_known (SUBREG_REG (x), mode); 885518334Speter#endif 885618334Speter#endif 885718334Speter break; 885818334Speter 885918334Speter case SIGN_EXTRACT: 886018334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT) 886190075Sobrien return MAX (1, (int) bitwidth - INTVAL (XEXP (x, 1))); 886218334Speter break; 886318334Speter 886490075Sobrien case SIGN_EXTEND: 886518334Speter return (bitwidth - GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) 8866117395Skan + num_sign_bit_copies_with_known (XEXP (x, 0), VOIDmode)); 886718334Speter 886818334Speter case TRUNCATE: 886950397Sobrien /* For a smaller object, just ignore the high bits. */ 8870117395Skan num0 = num_sign_bit_copies_with_known (XEXP (x, 0), VOIDmode); 887190075Sobrien return MAX (1, (num0 - (int) (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) 887290075Sobrien - bitwidth))); 887318334Speter 887418334Speter case NOT: 8875117395Skan return num_sign_bit_copies_with_known (XEXP (x, 0), mode); 887618334Speter 887718334Speter case ROTATE: case ROTATERT: 887818334Speter /* If we are rotating left by a number of bits less than the number 887918334Speter of sign bit copies, we can just subtract that amount from the 888018334Speter number. */ 888118334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 888290075Sobrien && INTVAL (XEXP (x, 1)) >= 0 888390075Sobrien && INTVAL (XEXP (x, 1)) < (int) bitwidth) 888418334Speter { 8885117395Skan num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode); 888618334Speter return MAX (1, num0 - (code == ROTATE ? INTVAL (XEXP (x, 1)) 888790075Sobrien : (int) bitwidth - INTVAL (XEXP (x, 1)))); 888818334Speter } 888918334Speter break; 889018334Speter 889118334Speter case NEG: 889218334Speter /* In general, this subtracts one sign bit copy. But if the value 889318334Speter is known to be positive, the number of sign bit copies is the 889418334Speter same as that of the input. Finally, if the input has just one bit 889518334Speter that might be nonzero, all the bits are copies of the sign bit. */ 8896117395Skan num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode); 889750397Sobrien if (bitwidth > HOST_BITS_PER_WIDE_INT) 889850397Sobrien return num0 > 1 ? num0 - 1 : 1; 889950397Sobrien 890018334Speter nonzero = nonzero_bits (XEXP (x, 0), mode); 890118334Speter if (nonzero == 1) 890218334Speter return bitwidth; 890318334Speter 890418334Speter if (num0 > 1 890518334Speter && (((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero)) 890618334Speter num0--; 890718334Speter 890818334Speter return num0; 890918334Speter 891018334Speter case IOR: case AND: case XOR: 891118334Speter case SMIN: case SMAX: case UMIN: case UMAX: 891218334Speter /* Logical operations will preserve the number of sign-bit copies. 891318334Speter MIN and MAX operations always return one of the operands. */ 8914117395Skan num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode); 8915117395Skan num1 = num_sign_bit_copies_with_known (XEXP (x, 1), mode); 891618334Speter return MIN (num0, num1); 891718334Speter 891818334Speter case PLUS: case MINUS: 891918334Speter /* For addition and subtraction, we can have a 1-bit carry. However, 892018334Speter if we are subtracting 1 from a positive number, there will not 892118334Speter be such a carry. Furthermore, if the positive number is known to 892218334Speter be 0 or 1, we know the result is either -1 or 0. */ 892318334Speter 892418334Speter if (code == PLUS && XEXP (x, 1) == constm1_rtx 892518334Speter && bitwidth <= HOST_BITS_PER_WIDE_INT) 892618334Speter { 892718334Speter nonzero = nonzero_bits (XEXP (x, 0), mode); 892818334Speter if ((((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero) == 0) 892918334Speter return (nonzero == 1 || nonzero == 0 ? bitwidth 893018334Speter : bitwidth - floor_log2 (nonzero) - 1); 893118334Speter } 893218334Speter 8933117395Skan num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode); 8934117395Skan num1 = num_sign_bit_copies_with_known (XEXP (x, 1), mode); 893590075Sobrien result = MAX (1, MIN (num0, num1) - 1); 893690075Sobrien 893790075Sobrien#ifdef POINTERS_EXTEND_UNSIGNED 893890075Sobrien /* If pointers extend signed and this is an addition or subtraction 893990075Sobrien to a pointer in Pmode, all the bits above ptr_mode are known to be 894090075Sobrien sign bit copies. */ 894190075Sobrien if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode 894290075Sobrien && (code == PLUS || code == MINUS) 894390075Sobrien && GET_CODE (XEXP (x, 0)) == REG && REG_POINTER (XEXP (x, 0))) 894490075Sobrien result = MAX ((int) (GET_MODE_BITSIZE (Pmode) 894590075Sobrien - GET_MODE_BITSIZE (ptr_mode) + 1), 894690075Sobrien result); 894790075Sobrien#endif 894890075Sobrien return result; 894990075Sobrien 895018334Speter case MULT: 895118334Speter /* The number of bits of the product is the sum of the number of 895218334Speter bits of both terms. However, unless one of the terms if known 895318334Speter to be positive, we must allow for an additional bit since negating 895418334Speter a negative number can remove one sign bit copy. */ 895518334Speter 8956117395Skan num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode); 8957117395Skan num1 = num_sign_bit_copies_with_known (XEXP (x, 1), mode); 895818334Speter 895918334Speter result = bitwidth - (bitwidth - num0) - (bitwidth - num1); 896018334Speter if (result > 0 896150397Sobrien && (bitwidth > HOST_BITS_PER_WIDE_INT 896250397Sobrien || (((nonzero_bits (XEXP (x, 0), mode) 896350397Sobrien & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) 896450397Sobrien && ((nonzero_bits (XEXP (x, 1), mode) 896550397Sobrien & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)))) 896618334Speter result--; 896718334Speter 896818334Speter return MAX (1, result); 896918334Speter 897018334Speter case UDIV: 897150397Sobrien /* The result must be <= the first operand. If the first operand 897250397Sobrien has the high bit set, we know nothing about the number of sign 897350397Sobrien bit copies. */ 897450397Sobrien if (bitwidth > HOST_BITS_PER_WIDE_INT) 897550397Sobrien return 1; 897650397Sobrien else if ((nonzero_bits (XEXP (x, 0), mode) 897750397Sobrien & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) 897850397Sobrien return 1; 897950397Sobrien else 8980117395Skan return num_sign_bit_copies_with_known (XEXP (x, 0), mode); 898190075Sobrien 898218334Speter case UMOD: 898390075Sobrien /* The result must be <= the second operand. */ 8984117395Skan return num_sign_bit_copies_with_known (XEXP (x, 1), mode); 898518334Speter 898618334Speter case DIV: 898718334Speter /* Similar to unsigned division, except that we have to worry about 898818334Speter the case where the divisor is negative, in which case we have 898918334Speter to add 1. */ 8990117395Skan result = num_sign_bit_copies_with_known (XEXP (x, 0), mode); 899118334Speter if (result > 1 899250397Sobrien && (bitwidth > HOST_BITS_PER_WIDE_INT 899350397Sobrien || (nonzero_bits (XEXP (x, 1), mode) 899450397Sobrien & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)) 899550397Sobrien result--; 899618334Speter 899718334Speter return result; 899818334Speter 899918334Speter case MOD: 9000117395Skan result = num_sign_bit_copies_with_known (XEXP (x, 1), mode); 900118334Speter if (result > 1 900250397Sobrien && (bitwidth > HOST_BITS_PER_WIDE_INT 900350397Sobrien || (nonzero_bits (XEXP (x, 1), mode) 900450397Sobrien & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)) 900550397Sobrien result--; 900618334Speter 900718334Speter return result; 900818334Speter 900918334Speter case ASHIFTRT: 901018334Speter /* Shifts by a constant add to the number of bits equal to the 901118334Speter sign bit. */ 9012117395Skan num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode); 901318334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 901418334Speter && INTVAL (XEXP (x, 1)) > 0) 901590075Sobrien num0 = MIN ((int) bitwidth, num0 + INTVAL (XEXP (x, 1))); 901618334Speter 901718334Speter return num0; 901818334Speter 901918334Speter case ASHIFT: 902018334Speter /* Left shifts destroy copies. */ 902118334Speter if (GET_CODE (XEXP (x, 1)) != CONST_INT 902218334Speter || INTVAL (XEXP (x, 1)) < 0 902390075Sobrien || INTVAL (XEXP (x, 1)) >= (int) bitwidth) 902418334Speter return 1; 902518334Speter 9026117395Skan num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode); 902718334Speter return MAX (1, num0 - INTVAL (XEXP (x, 1))); 902818334Speter 902918334Speter case IF_THEN_ELSE: 9030117395Skan num0 = num_sign_bit_copies_with_known (XEXP (x, 1), mode); 9031117395Skan num1 = num_sign_bit_copies_with_known (XEXP (x, 2), mode); 903218334Speter return MIN (num0, num1); 903318334Speter 903418334Speter case EQ: case NE: case GE: case GT: case LE: case LT: 903590075Sobrien case UNEQ: case LTGT: case UNGE: case UNGT: case UNLE: case UNLT: 903618334Speter case GEU: case GTU: case LEU: case LTU: 903790075Sobrien case UNORDERED: case ORDERED: 903890075Sobrien /* If the constant is negative, take its 1's complement and remask. 903990075Sobrien Then see how many zero bits we have. */ 904090075Sobrien nonzero = STORE_FLAG_VALUE; 904190075Sobrien if (bitwidth <= HOST_BITS_PER_WIDE_INT 904290075Sobrien && (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) 904390075Sobrien nonzero = (~nonzero) & GET_MODE_MASK (mode); 904490075Sobrien 904590075Sobrien return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1); 904650397Sobrien break; 904790075Sobrien 904850397Sobrien default: 904950397Sobrien break; 905018334Speter } 905118334Speter 905218334Speter /* If we haven't been able to figure it out by one of the above rules, 905318334Speter see if some of the high-order bits are known to be zero. If so, 905418334Speter count those bits and return one less than that amount. If we can't 905518334Speter safely compute the mask for this mode, always return BITWIDTH. */ 905618334Speter 905718334Speter if (bitwidth > HOST_BITS_PER_WIDE_INT) 905818334Speter return 1; 905918334Speter 906018334Speter nonzero = nonzero_bits (x, mode); 906118334Speter return (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1)) 906218334Speter ? 1 : bitwidth - floor_log2 (nonzero) - 1); 906318334Speter} 906418334Speter 906518334Speter/* Return the number of "extended" bits there are in X, when interpreted 906618334Speter as a quantity in MODE whose signedness is indicated by UNSIGNEDP. For 906718334Speter unsigned quantities, this is the number of high-order zero bits. 906818334Speter For signed quantities, this is the number of copies of the sign bit 906918334Speter minus 1. In both case, this function returns the number of "spare" 907018334Speter bits. For example, if two quantities for which this function returns 907118334Speter at least 1 are added, the addition is known not to overflow. 907218334Speter 907318334Speter This function will always return 0 unless called during combine, which 907418334Speter implies that it must be called from a define_split. */ 907518334Speter 907690075Sobrienunsigned int 907718334Speterextended_count (x, mode, unsignedp) 907818334Speter rtx x; 907918334Speter enum machine_mode mode; 908018334Speter int unsignedp; 908118334Speter{ 908218334Speter if (nonzero_sign_valid == 0) 908318334Speter return 0; 908418334Speter 908518334Speter return (unsignedp 908618334Speter ? (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 9087117395Skan ? (unsigned int) (GET_MODE_BITSIZE (mode) - 1 9088117395Skan - floor_log2 (nonzero_bits (x, mode))) 908990075Sobrien : 0) 909018334Speter : num_sign_bit_copies (x, mode) - 1); 909118334Speter} 909218334Speter 909318334Speter/* This function is called from `simplify_shift_const' to merge two 909418334Speter outer operations. Specifically, we have already found that we need 909518334Speter to perform operation *POP0 with constant *PCONST0 at the outermost 909618334Speter position. We would now like to also perform OP1 with constant CONST1 909718334Speter (with *POP0 being done last). 909818334Speter 909918334Speter Return 1 if we can do the operation and update *POP0 and *PCONST0 with 910090075Sobrien the resulting operation. *PCOMP_P is set to 1 if we would need to 910118334Speter complement the innermost operand, otherwise it is unchanged. 910218334Speter 910318334Speter MODE is the mode in which the operation will be done. No bits outside 910418334Speter the width of this mode matter. It is assumed that the width of this mode 910518334Speter is smaller than or equal to HOST_BITS_PER_WIDE_INT. 910618334Speter 910718334Speter If *POP0 or OP1 are NIL, it means no operation is required. Only NEG, PLUS, 910818334Speter IOR, XOR, and AND are supported. We may set *POP0 to SET if the proper 910918334Speter result is simply *PCONST0. 911018334Speter 911118334Speter If the resulting operation cannot be expressed as one operation, we 911218334Speter return 0 and do not change *POP0, *PCONST0, and *PCOMP_P. */ 911318334Speter 911418334Speterstatic int 911518334Spetermerge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p) 911618334Speter enum rtx_code *pop0; 911718334Speter HOST_WIDE_INT *pconst0; 911818334Speter enum rtx_code op1; 911918334Speter HOST_WIDE_INT const1; 912018334Speter enum machine_mode mode; 912118334Speter int *pcomp_p; 912218334Speter{ 912318334Speter enum rtx_code op0 = *pop0; 912418334Speter HOST_WIDE_INT const0 = *pconst0; 912518334Speter 912618334Speter const0 &= GET_MODE_MASK (mode); 912718334Speter const1 &= GET_MODE_MASK (mode); 912818334Speter 912918334Speter /* If OP0 is an AND, clear unimportant bits in CONST1. */ 913018334Speter if (op0 == AND) 913118334Speter const1 &= const0; 913218334Speter 913318334Speter /* If OP0 or OP1 is NIL, this is easy. Similarly if they are the same or 913418334Speter if OP0 is SET. */ 913518334Speter 913618334Speter if (op1 == NIL || op0 == SET) 913718334Speter return 1; 913818334Speter 913918334Speter else if (op0 == NIL) 914018334Speter op0 = op1, const0 = const1; 914118334Speter 914218334Speter else if (op0 == op1) 914318334Speter { 914418334Speter switch (op0) 914518334Speter { 914618334Speter case AND: 914718334Speter const0 &= const1; 914818334Speter break; 914918334Speter case IOR: 915018334Speter const0 |= const1; 915118334Speter break; 915218334Speter case XOR: 915318334Speter const0 ^= const1; 915418334Speter break; 915518334Speter case PLUS: 915618334Speter const0 += const1; 915718334Speter break; 915818334Speter case NEG: 915918334Speter op0 = NIL; 916018334Speter break; 916150397Sobrien default: 916250397Sobrien break; 916318334Speter } 916418334Speter } 916518334Speter 916618334Speter /* Otherwise, if either is a PLUS or NEG, we can't do anything. */ 916718334Speter else if (op0 == PLUS || op1 == PLUS || op0 == NEG || op1 == NEG) 916818334Speter return 0; 916918334Speter 917018334Speter /* If the two constants aren't the same, we can't do anything. The 917118334Speter remaining six cases can all be done. */ 917218334Speter else if (const0 != const1) 917318334Speter return 0; 917418334Speter 917518334Speter else 917618334Speter switch (op0) 917718334Speter { 917818334Speter case IOR: 917918334Speter if (op1 == AND) 918018334Speter /* (a & b) | b == b */ 918118334Speter op0 = SET; 918218334Speter else /* op1 == XOR */ 918318334Speter /* (a ^ b) | b == a | b */ 918450397Sobrien {;} 918518334Speter break; 918618334Speter 918718334Speter case XOR: 918818334Speter if (op1 == AND) 918918334Speter /* (a & b) ^ b == (~a) & b */ 919018334Speter op0 = AND, *pcomp_p = 1; 919118334Speter else /* op1 == IOR */ 919218334Speter /* (a | b) ^ b == a & ~b */ 919390075Sobrien op0 = AND, *pconst0 = ~const0; 919418334Speter break; 919518334Speter 919618334Speter case AND: 919718334Speter if (op1 == IOR) 919818334Speter /* (a | b) & b == b */ 919918334Speter op0 = SET; 920018334Speter else /* op1 == XOR */ 920118334Speter /* (a ^ b) & b) == (~a) & b */ 920218334Speter *pcomp_p = 1; 920318334Speter break; 920450397Sobrien default: 920550397Sobrien break; 920618334Speter } 920718334Speter 920818334Speter /* Check for NO-OP cases. */ 920918334Speter const0 &= GET_MODE_MASK (mode); 921018334Speter if (const0 == 0 921118334Speter && (op0 == IOR || op0 == XOR || op0 == PLUS)) 921218334Speter op0 = NIL; 921318334Speter else if (const0 == 0 && op0 == AND) 921418334Speter op0 = SET; 921552284Sobrien else if ((unsigned HOST_WIDE_INT) const0 == GET_MODE_MASK (mode) 921652284Sobrien && op0 == AND) 921718334Speter op0 = NIL; 921818334Speter 921990075Sobrien /* ??? Slightly redundant with the above mask, but not entirely. 922090075Sobrien Moving this above means we'd have to sign-extend the mode mask 922190075Sobrien for the final test. */ 922290075Sobrien const0 = trunc_int_for_mode (const0, mode); 922318334Speter 922418334Speter *pop0 = op0; 922518334Speter *pconst0 = const0; 922618334Speter 922718334Speter return 1; 922818334Speter} 922918334Speter 923018334Speter/* Simplify a shift of VAROP by COUNT bits. CODE says what kind of shift. 9231117395Skan The result of the shift is RESULT_MODE. X, if nonzero, is an expression 923218334Speter that we started with. 923318334Speter 923418334Speter The shift is normally computed in the widest mode we find in VAROP, as 923518334Speter long as it isn't a different number of words than RESULT_MODE. Exceptions 923618334Speter are ASHIFTRT and ROTATE, which are always done in their original mode, */ 923718334Speter 923818334Speterstatic rtx 923990075Sobriensimplify_shift_const (x, code, result_mode, varop, orig_count) 924018334Speter rtx x; 924118334Speter enum rtx_code code; 924218334Speter enum machine_mode result_mode; 924318334Speter rtx varop; 924490075Sobrien int orig_count; 924518334Speter{ 924618334Speter enum rtx_code orig_code = code; 924790075Sobrien unsigned int count; 924890075Sobrien int signed_count; 924918334Speter enum machine_mode mode = result_mode; 925018334Speter enum machine_mode shift_mode, tmode; 925190075Sobrien unsigned int mode_words 925218334Speter = (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD; 925318334Speter /* We form (outer_op (code varop count) (outer_const)). */ 925418334Speter enum rtx_code outer_op = NIL; 925518334Speter HOST_WIDE_INT outer_const = 0; 925618334Speter rtx const_rtx; 925718334Speter int complement_p = 0; 925818334Speter rtx new; 925918334Speter 926090075Sobrien /* Make sure and truncate the "natural" shift on the way in. We don't 926190075Sobrien want to do this inside the loop as it makes it more difficult to 926290075Sobrien combine shifts. */ 926390075Sobrien#ifdef SHIFT_COUNT_TRUNCATED 926490075Sobrien if (SHIFT_COUNT_TRUNCATED) 926590075Sobrien orig_count &= GET_MODE_BITSIZE (mode) - 1; 926690075Sobrien#endif 926790075Sobrien 926818334Speter /* If we were given an invalid count, don't do anything except exactly 926918334Speter what was requested. */ 927018334Speter 927190075Sobrien if (orig_count < 0 || orig_count >= (int) GET_MODE_BITSIZE (mode)) 927218334Speter { 927318334Speter if (x) 927418334Speter return x; 927518334Speter 927690075Sobrien return gen_rtx_fmt_ee (code, mode, varop, GEN_INT (orig_count)); 927718334Speter } 927818334Speter 927990075Sobrien count = orig_count; 928090075Sobrien 928118334Speter /* Unless one of the branches of the `if' in this loop does a `continue', 928218334Speter we will `break' the loop after the `if'. */ 928318334Speter 928418334Speter while (count != 0) 928518334Speter { 928618334Speter /* If we have an operand of (clobber (const_int 0)), just return that 928718334Speter value. */ 928818334Speter if (GET_CODE (varop) == CLOBBER) 928918334Speter return varop; 929018334Speter 929118334Speter /* If we discovered we had to complement VAROP, leave. Making a NOT 929218334Speter here would cause an infinite loop. */ 929318334Speter if (complement_p) 929418334Speter break; 929518334Speter 929618334Speter /* Convert ROTATERT to ROTATE. */ 929718334Speter if (code == ROTATERT) 9298117395Skan { 9299117395Skan unsigned int bitsize = GET_MODE_BITSIZE (result_mode);; 9300117395Skan code = ROTATE; 9301117395Skan if (VECTOR_MODE_P (result_mode)) 9302117395Skan count = bitsize / GET_MODE_NUNITS (result_mode) - count; 9303117395Skan else 9304117395Skan count = bitsize - count; 9305117395Skan } 930618334Speter 930718334Speter /* We need to determine what mode we will do the shift in. If the 930818334Speter shift is a right shift or a ROTATE, we must always do it in the mode 930918334Speter it was originally done in. Otherwise, we can do it in MODE, the 931050397Sobrien widest mode encountered. */ 931118334Speter shift_mode 931218334Speter = (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE 931318334Speter ? result_mode : mode); 931418334Speter 931518334Speter /* Handle cases where the count is greater than the size of the mode 931618334Speter minus 1. For ASHIFT, use the size minus one as the count (this can 931718334Speter occur when simplifying (lshiftrt (ashiftrt ..))). For rotates, 931818334Speter take the count modulo the size. For other shifts, the result is 931918334Speter zero. 932018334Speter 932118334Speter Since these shifts are being produced by the compiler by combining 932218334Speter multiple operations, each of which are defined, we know what the 932318334Speter result is supposed to be. */ 932490075Sobrien 9325117395Skan if (count > (unsigned int) (GET_MODE_BITSIZE (shift_mode) - 1)) 932618334Speter { 932718334Speter if (code == ASHIFTRT) 932818334Speter count = GET_MODE_BITSIZE (shift_mode) - 1; 932918334Speter else if (code == ROTATE || code == ROTATERT) 933018334Speter count %= GET_MODE_BITSIZE (shift_mode); 933118334Speter else 933218334Speter { 933318334Speter /* We can't simply return zero because there may be an 933418334Speter outer op. */ 933518334Speter varop = const0_rtx; 933618334Speter count = 0; 933718334Speter break; 933818334Speter } 933918334Speter } 934018334Speter 934118334Speter /* An arithmetic right shift of a quantity known to be -1 or 0 934218334Speter is a no-op. */ 934318334Speter if (code == ASHIFTRT 934418334Speter && (num_sign_bit_copies (varop, shift_mode) 934518334Speter == GET_MODE_BITSIZE (shift_mode))) 934618334Speter { 934718334Speter count = 0; 934818334Speter break; 934918334Speter } 935018334Speter 935118334Speter /* If we are doing an arithmetic right shift and discarding all but 935218334Speter the sign bit copies, this is equivalent to doing a shift by the 935318334Speter bitsize minus one. Convert it into that shift because it will often 935418334Speter allow other simplifications. */ 935518334Speter 935618334Speter if (code == ASHIFTRT 935718334Speter && (count + num_sign_bit_copies (varop, shift_mode) 935818334Speter >= GET_MODE_BITSIZE (shift_mode))) 935918334Speter count = GET_MODE_BITSIZE (shift_mode) - 1; 936018334Speter 936118334Speter /* We simplify the tests below and elsewhere by converting 936218334Speter ASHIFTRT to LSHIFTRT if we know the sign bit is clear. 9363117395Skan `make_compound_operation' will convert it to an ASHIFTRT for 9364117395Skan those machines (such as VAX) that don't have an LSHIFTRT. */ 936518334Speter if (GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT 936618334Speter && code == ASHIFTRT 936718334Speter && ((nonzero_bits (varop, shift_mode) 936818334Speter & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (shift_mode) - 1))) 936918334Speter == 0)) 937018334Speter code = LSHIFTRT; 937118334Speter 937218334Speter switch (GET_CODE (varop)) 937318334Speter { 937418334Speter case SIGN_EXTEND: 937518334Speter case ZERO_EXTEND: 937618334Speter case SIGN_EXTRACT: 937718334Speter case ZERO_EXTRACT: 937818334Speter new = expand_compound_operation (varop); 937918334Speter if (new != varop) 938018334Speter { 938118334Speter varop = new; 938218334Speter continue; 938318334Speter } 938418334Speter break; 938518334Speter 938618334Speter case MEM: 938718334Speter /* If we have (xshiftrt (mem ...) C) and C is MODE_WIDTH 938818334Speter minus the width of a smaller mode, we can do this with a 938918334Speter SIGN_EXTEND or ZERO_EXTEND from the narrower memory location. */ 939018334Speter if ((code == ASHIFTRT || code == LSHIFTRT) 939118334Speter && ! mode_dependent_address_p (XEXP (varop, 0)) 939218334Speter && ! MEM_VOLATILE_P (varop) 939318334Speter && (tmode = mode_for_size (GET_MODE_BITSIZE (mode) - count, 939418334Speter MODE_INT, 1)) != BLKmode) 939518334Speter { 939690075Sobrien new = adjust_address_nv (varop, tmode, 939790075Sobrien BYTES_BIG_ENDIAN ? 0 939890075Sobrien : count / BITS_PER_UNIT); 939990075Sobrien 940090075Sobrien varop = gen_rtx_fmt_e (code == ASHIFTRT ? SIGN_EXTEND 940190075Sobrien : ZERO_EXTEND, mode, new); 940218334Speter count = 0; 940318334Speter continue; 940418334Speter } 940518334Speter break; 940618334Speter 940718334Speter case USE: 940818334Speter /* Similar to the case above, except that we can only do this if 940918334Speter the resulting mode is the same as that of the underlying 941018334Speter MEM and adjust the address depending on the *bits* endianness 941118334Speter because of the way that bit-field extract insns are defined. */ 941218334Speter if ((code == ASHIFTRT || code == LSHIFTRT) 941318334Speter && (tmode = mode_for_size (GET_MODE_BITSIZE (mode) - count, 941418334Speter MODE_INT, 1)) != BLKmode 941518334Speter && tmode == GET_MODE (XEXP (varop, 0))) 941618334Speter { 941718334Speter if (BITS_BIG_ENDIAN) 941818334Speter new = XEXP (varop, 0); 941918334Speter else 942018334Speter { 942118334Speter new = copy_rtx (XEXP (varop, 0)); 942290075Sobrien SUBST (XEXP (new, 0), 942318334Speter plus_constant (XEXP (new, 0), 942418334Speter count / BITS_PER_UNIT)); 942518334Speter } 942618334Speter 942790075Sobrien varop = gen_rtx_fmt_e (code == ASHIFTRT ? SIGN_EXTEND 942890075Sobrien : ZERO_EXTEND, mode, new); 942918334Speter count = 0; 943018334Speter continue; 943118334Speter } 943218334Speter break; 943318334Speter 943418334Speter case SUBREG: 943518334Speter /* If VAROP is a SUBREG, strip it as long as the inner operand has 943618334Speter the same number of words as what we've seen so far. Then store 943718334Speter the widest mode in MODE. */ 943818334Speter if (subreg_lowpart_p (varop) 943918334Speter && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (varop))) 944018334Speter > GET_MODE_SIZE (GET_MODE (varop))) 9441117395Skan && (unsigned int) ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (varop))) 9442117395Skan + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) 9443117395Skan == mode_words) 944418334Speter { 944518334Speter varop = SUBREG_REG (varop); 944618334Speter if (GET_MODE_SIZE (GET_MODE (varop)) > GET_MODE_SIZE (mode)) 944718334Speter mode = GET_MODE (varop); 944818334Speter continue; 944918334Speter } 945018334Speter break; 945118334Speter 945218334Speter case MULT: 945318334Speter /* Some machines use MULT instead of ASHIFT because MULT 945418334Speter is cheaper. But it is still better on those machines to 945518334Speter merge two shifts into one. */ 945618334Speter if (GET_CODE (XEXP (varop, 1)) == CONST_INT 945718334Speter && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0) 945818334Speter { 945990075Sobrien varop 946090075Sobrien = gen_binary (ASHIFT, GET_MODE (varop), XEXP (varop, 0), 946190075Sobrien GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1))))); 946218334Speter continue; 946318334Speter } 946418334Speter break; 946518334Speter 946618334Speter case UDIV: 946718334Speter /* Similar, for when divides are cheaper. */ 946818334Speter if (GET_CODE (XEXP (varop, 1)) == CONST_INT 946918334Speter && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0) 947018334Speter { 947190075Sobrien varop 947290075Sobrien = gen_binary (LSHIFTRT, GET_MODE (varop), XEXP (varop, 0), 947390075Sobrien GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1))))); 947418334Speter continue; 947518334Speter } 947618334Speter break; 947718334Speter 947818334Speter case ASHIFTRT: 947990075Sobrien /* If we are extracting just the sign bit of an arithmetic 948090075Sobrien right shift, that shift is not needed. However, the sign 948190075Sobrien bit of a wider mode may be different from what would be 948290075Sobrien interpreted as the sign bit in a narrower mode, so, if 948390075Sobrien the result is narrower, don't discard the shift. */ 9484117395Skan if (code == LSHIFTRT 9485117395Skan && count == (unsigned int) (GET_MODE_BITSIZE (result_mode) - 1) 948690075Sobrien && (GET_MODE_BITSIZE (result_mode) 948790075Sobrien >= GET_MODE_BITSIZE (GET_MODE (varop)))) 948818334Speter { 948918334Speter varop = XEXP (varop, 0); 949018334Speter continue; 949118334Speter } 949218334Speter 949350397Sobrien /* ... fall through ... */ 949418334Speter 949518334Speter case LSHIFTRT: 949618334Speter case ASHIFT: 949718334Speter case ROTATE: 949818334Speter /* Here we have two nested shifts. The result is usually the 949918334Speter AND of a new shift with a mask. We compute the result below. */ 950018334Speter if (GET_CODE (XEXP (varop, 1)) == CONST_INT 950118334Speter && INTVAL (XEXP (varop, 1)) >= 0 950218334Speter && INTVAL (XEXP (varop, 1)) < GET_MODE_BITSIZE (GET_MODE (varop)) 950318334Speter && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT 950418334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) 950518334Speter { 950618334Speter enum rtx_code first_code = GET_CODE (varop); 950790075Sobrien unsigned int first_count = INTVAL (XEXP (varop, 1)); 950818334Speter unsigned HOST_WIDE_INT mask; 950918334Speter rtx mask_rtx; 951018334Speter 951118334Speter /* We have one common special case. We can't do any merging if 951218334Speter the inner code is an ASHIFTRT of a smaller mode. However, if 951318334Speter we have (ashift:M1 (subreg:M1 (ashiftrt:M2 FOO C1) 0) C2) 951418334Speter with C2 == GET_MODE_BITSIZE (M1) - GET_MODE_BITSIZE (M2), 951518334Speter we can convert it to 951618334Speter (ashiftrt:M1 (ashift:M1 (and:M1 (subreg:M1 FOO 0 C2) C3) C1). 951718334Speter This simplifies certain SIGN_EXTEND operations. */ 951818334Speter if (code == ASHIFT && first_code == ASHIFTRT 9519117395Skan && count == (unsigned int) 9520117395Skan (GET_MODE_BITSIZE (result_mode) 9521117395Skan - GET_MODE_BITSIZE (GET_MODE (varop)))) 952218334Speter { 952318334Speter /* C3 has the low-order C1 bits zero. */ 952490075Sobrien 952518334Speter mask = (GET_MODE_MASK (mode) 952690075Sobrien & ~(((HOST_WIDE_INT) 1 << first_count) - 1)); 952718334Speter 952818334Speter varop = simplify_and_const_int (NULL_RTX, result_mode, 952918334Speter XEXP (varop, 0), mask); 953018334Speter varop = simplify_shift_const (NULL_RTX, ASHIFT, result_mode, 953118334Speter varop, count); 953218334Speter count = first_count; 953318334Speter code = ASHIFTRT; 953418334Speter continue; 953518334Speter } 953690075Sobrien 953718334Speter /* If this was (ashiftrt (ashift foo C1) C2) and FOO has more 953818334Speter than C1 high-order bits equal to the sign bit, we can convert 9539117395Skan this to either an ASHIFT or an ASHIFTRT depending on the 954090075Sobrien two counts. 954118334Speter 954218334Speter We cannot do this if VAROP's mode is not SHIFT_MODE. */ 954318334Speter 954418334Speter if (code == ASHIFTRT && first_code == ASHIFT 954518334Speter && GET_MODE (varop) == shift_mode 954618334Speter && (num_sign_bit_copies (XEXP (varop, 0), shift_mode) 954718334Speter > first_count)) 954818334Speter { 954918334Speter varop = XEXP (varop, 0); 955090075Sobrien 955190075Sobrien signed_count = count - first_count; 955290075Sobrien if (signed_count < 0) 955390075Sobrien count = -signed_count, code = ASHIFT; 955490075Sobrien else 955590075Sobrien count = signed_count; 955690075Sobrien 955718334Speter continue; 955818334Speter } 955918334Speter 956018334Speter /* There are some cases we can't do. If CODE is ASHIFTRT, 956118334Speter we can only do this if FIRST_CODE is also ASHIFTRT. 956218334Speter 956318334Speter We can't do the case when CODE is ROTATE and FIRST_CODE is 956418334Speter ASHIFTRT. 956518334Speter 956618334Speter If the mode of this shift is not the mode of the outer shift, 956718334Speter we can't do this if either shift is a right shift or ROTATE. 956818334Speter 956918334Speter Finally, we can't do any of these if the mode is too wide 957018334Speter unless the codes are the same. 957118334Speter 957218334Speter Handle the case where the shift codes are the same 957318334Speter first. */ 957418334Speter 957518334Speter if (code == first_code) 957618334Speter { 957718334Speter if (GET_MODE (varop) != result_mode 957818334Speter && (code == ASHIFTRT || code == LSHIFTRT 957918334Speter || code == ROTATE)) 958018334Speter break; 958118334Speter 958218334Speter count += first_count; 958318334Speter varop = XEXP (varop, 0); 958418334Speter continue; 958518334Speter } 958618334Speter 958718334Speter if (code == ASHIFTRT 958818334Speter || (code == ROTATE && first_code == ASHIFTRT) 958918334Speter || GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT 959018334Speter || (GET_MODE (varop) != result_mode 959118334Speter && (first_code == ASHIFTRT || first_code == LSHIFTRT 959218334Speter || first_code == ROTATE 959318334Speter || code == ROTATE))) 959418334Speter break; 959518334Speter 959618334Speter /* To compute the mask to apply after the shift, shift the 959790075Sobrien nonzero bits of the inner shift the same way the 959818334Speter outer shift will. */ 959918334Speter 960018334Speter mask_rtx = GEN_INT (nonzero_bits (varop, GET_MODE (varop))); 960118334Speter 960218334Speter mask_rtx 960318334Speter = simplify_binary_operation (code, result_mode, mask_rtx, 960418334Speter GEN_INT (count)); 960590075Sobrien 960618334Speter /* Give up if we can't compute an outer operation to use. */ 960718334Speter if (mask_rtx == 0 960818334Speter || GET_CODE (mask_rtx) != CONST_INT 960918334Speter || ! merge_outer_ops (&outer_op, &outer_const, AND, 961018334Speter INTVAL (mask_rtx), 961118334Speter result_mode, &complement_p)) 961218334Speter break; 961318334Speter 961418334Speter /* If the shifts are in the same direction, we add the 961518334Speter counts. Otherwise, we subtract them. */ 961690075Sobrien signed_count = count; 961718334Speter if ((code == ASHIFTRT || code == LSHIFTRT) 961818334Speter == (first_code == ASHIFTRT || first_code == LSHIFTRT)) 961990075Sobrien signed_count += first_count; 962018334Speter else 962190075Sobrien signed_count -= first_count; 962218334Speter 962390075Sobrien /* If COUNT is positive, the new shift is usually CODE, 962418334Speter except for the two exceptions below, in which case it is 962518334Speter FIRST_CODE. If the count is negative, FIRST_CODE should 962618334Speter always be used */ 962790075Sobrien if (signed_count > 0 962818334Speter && ((first_code == ROTATE && code == ASHIFT) 962918334Speter || (first_code == ASHIFTRT && code == LSHIFTRT))) 963090075Sobrien code = first_code, count = signed_count; 963190075Sobrien else if (signed_count < 0) 963290075Sobrien code = first_code, count = -signed_count; 963390075Sobrien else 963490075Sobrien count = signed_count; 963518334Speter 963618334Speter varop = XEXP (varop, 0); 963718334Speter continue; 963818334Speter } 963918334Speter 964018334Speter /* If we have (A << B << C) for any shift, we can convert this to 964118334Speter (A << C << B). This wins if A is a constant. Only try this if 964218334Speter B is not a constant. */ 964318334Speter 964418334Speter else if (GET_CODE (varop) == code 964518334Speter && GET_CODE (XEXP (varop, 1)) != CONST_INT 964618334Speter && 0 != (new 964718334Speter = simplify_binary_operation (code, mode, 964818334Speter XEXP (varop, 0), 964918334Speter GEN_INT (count)))) 965018334Speter { 965190075Sobrien varop = gen_rtx_fmt_ee (code, mode, new, XEXP (varop, 1)); 965218334Speter count = 0; 965318334Speter continue; 965418334Speter } 965518334Speter break; 965618334Speter 965718334Speter case NOT: 965818334Speter /* Make this fit the case below. */ 965990075Sobrien varop = gen_rtx_XOR (mode, XEXP (varop, 0), 966090075Sobrien GEN_INT (GET_MODE_MASK (mode))); 966118334Speter continue; 966218334Speter 966318334Speter case IOR: 966418334Speter case AND: 966518334Speter case XOR: 966618334Speter /* If we have (xshiftrt (ior (plus X (const_int -1)) X) C) 966718334Speter with C the size of VAROP - 1 and the shift is logical if 966818334Speter STORE_FLAG_VALUE is 1 and arithmetic if STORE_FLAG_VALUE is -1, 966918334Speter we have an (le X 0) operation. If we have an arithmetic shift 967018334Speter and STORE_FLAG_VALUE is 1 or we have a logical shift with 967118334Speter STORE_FLAG_VALUE of -1, we have a (neg (le X 0)) operation. */ 967218334Speter 967318334Speter if (GET_CODE (varop) == IOR && GET_CODE (XEXP (varop, 0)) == PLUS 967418334Speter && XEXP (XEXP (varop, 0), 1) == constm1_rtx 967518334Speter && (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1) 967618334Speter && (code == LSHIFTRT || code == ASHIFTRT) 9677117395Skan && count == (unsigned int) 9678117395Skan (GET_MODE_BITSIZE (GET_MODE (varop)) - 1) 967918334Speter && rtx_equal_p (XEXP (XEXP (varop, 0), 0), XEXP (varop, 1))) 968018334Speter { 968118334Speter count = 0; 968290075Sobrien varop = gen_rtx_LE (GET_MODE (varop), XEXP (varop, 1), 968390075Sobrien const0_rtx); 968418334Speter 968518334Speter if (STORE_FLAG_VALUE == 1 ? code == ASHIFTRT : code == LSHIFTRT) 968690075Sobrien varop = gen_rtx_NEG (GET_MODE (varop), varop); 968718334Speter 968818334Speter continue; 968918334Speter } 969018334Speter 969118334Speter /* If we have (shift (logical)), move the logical to the outside 969218334Speter to allow it to possibly combine with another logical and the 969318334Speter shift to combine with another shift. This also canonicalizes to 969418334Speter what a ZERO_EXTRACT looks like. Also, some machines have 969518334Speter (and (shift)) insns. */ 969618334Speter 969718334Speter if (GET_CODE (XEXP (varop, 1)) == CONST_INT 969818334Speter && (new = simplify_binary_operation (code, result_mode, 969918334Speter XEXP (varop, 1), 970018334Speter GEN_INT (count))) != 0 970190075Sobrien && GET_CODE (new) == CONST_INT 970218334Speter && merge_outer_ops (&outer_op, &outer_const, GET_CODE (varop), 970318334Speter INTVAL (new), result_mode, &complement_p)) 970418334Speter { 970518334Speter varop = XEXP (varop, 0); 970618334Speter continue; 970718334Speter } 970818334Speter 970918334Speter /* If we can't do that, try to simplify the shift in each arm of the 971018334Speter logical expression, make a new logical expression, and apply 971118334Speter the inverse distributive law. */ 971218334Speter { 971318334Speter rtx lhs = simplify_shift_const (NULL_RTX, code, shift_mode, 971418334Speter XEXP (varop, 0), count); 971518334Speter rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode, 971618334Speter XEXP (varop, 1), count); 971718334Speter 971818334Speter varop = gen_binary (GET_CODE (varop), shift_mode, lhs, rhs); 971918334Speter varop = apply_distributive_law (varop); 972018334Speter 972118334Speter count = 0; 972218334Speter } 972318334Speter break; 972418334Speter 972518334Speter case EQ: 972618334Speter /* convert (lshiftrt (eq FOO 0) C) to (xor FOO 1) if STORE_FLAG_VALUE 972718334Speter says that the sign bit can be tested, FOO has mode MODE, C is 972818334Speter GET_MODE_BITSIZE (MODE) - 1, and FOO has only its low-order bit 972918334Speter that may be nonzero. */ 973018334Speter if (code == LSHIFTRT 973118334Speter && XEXP (varop, 1) == const0_rtx 973218334Speter && GET_MODE (XEXP (varop, 0)) == result_mode 9733117395Skan && count == (unsigned int) (GET_MODE_BITSIZE (result_mode) - 1) 973418334Speter && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT 973518334Speter && ((STORE_FLAG_VALUE 973690075Sobrien & ((HOST_WIDE_INT) 1 973790075Sobrien < (GET_MODE_BITSIZE (result_mode) - 1)))) 973818334Speter && nonzero_bits (XEXP (varop, 0), result_mode) == 1 973918334Speter && merge_outer_ops (&outer_op, &outer_const, XOR, 974018334Speter (HOST_WIDE_INT) 1, result_mode, 974118334Speter &complement_p)) 974218334Speter { 974318334Speter varop = XEXP (varop, 0); 974418334Speter count = 0; 974518334Speter continue; 974618334Speter } 974718334Speter break; 974818334Speter 974918334Speter case NEG: 975018334Speter /* (lshiftrt (neg A) C) where A is either 0 or 1 and C is one less 975118334Speter than the number of bits in the mode is equivalent to A. */ 9752117395Skan if (code == LSHIFTRT 9753117395Skan && count == (unsigned int) (GET_MODE_BITSIZE (result_mode) - 1) 975418334Speter && nonzero_bits (XEXP (varop, 0), result_mode) == 1) 975518334Speter { 975618334Speter varop = XEXP (varop, 0); 975718334Speter count = 0; 975818334Speter continue; 975918334Speter } 976018334Speter 976118334Speter /* NEG commutes with ASHIFT since it is multiplication. Move the 976218334Speter NEG outside to allow shifts to combine. */ 976318334Speter if (code == ASHIFT 976418334Speter && merge_outer_ops (&outer_op, &outer_const, NEG, 976518334Speter (HOST_WIDE_INT) 0, result_mode, 976618334Speter &complement_p)) 976718334Speter { 976818334Speter varop = XEXP (varop, 0); 976918334Speter continue; 977018334Speter } 977118334Speter break; 977218334Speter 977318334Speter case PLUS: 977418334Speter /* (lshiftrt (plus A -1) C) where A is either 0 or 1 and C 977518334Speter is one less than the number of bits in the mode is 977618334Speter equivalent to (xor A 1). */ 9777117395Skan if (code == LSHIFTRT 9778117395Skan && count == (unsigned int) (GET_MODE_BITSIZE (result_mode) - 1) 977918334Speter && XEXP (varop, 1) == constm1_rtx 978018334Speter && nonzero_bits (XEXP (varop, 0), result_mode) == 1 978118334Speter && merge_outer_ops (&outer_op, &outer_const, XOR, 978218334Speter (HOST_WIDE_INT) 1, result_mode, 978318334Speter &complement_p)) 978418334Speter { 978518334Speter count = 0; 978618334Speter varop = XEXP (varop, 0); 978718334Speter continue; 978818334Speter } 978918334Speter 979018334Speter /* If we have (xshiftrt (plus FOO BAR) C), and the only bits 979118334Speter that might be nonzero in BAR are those being shifted out and those 979218334Speter bits are known zero in FOO, we can replace the PLUS with FOO. 979318334Speter Similarly in the other operand order. This code occurs when 979418334Speter we are computing the size of a variable-size array. */ 979518334Speter 979618334Speter if ((code == ASHIFTRT || code == LSHIFTRT) 979718334Speter && count < HOST_BITS_PER_WIDE_INT 979818334Speter && nonzero_bits (XEXP (varop, 1), result_mode) >> count == 0 979918334Speter && (nonzero_bits (XEXP (varop, 1), result_mode) 980018334Speter & nonzero_bits (XEXP (varop, 0), result_mode)) == 0) 980118334Speter { 980218334Speter varop = XEXP (varop, 0); 980318334Speter continue; 980418334Speter } 980518334Speter else if ((code == ASHIFTRT || code == LSHIFTRT) 980618334Speter && count < HOST_BITS_PER_WIDE_INT 980718334Speter && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT 980818334Speter && 0 == (nonzero_bits (XEXP (varop, 0), result_mode) 980918334Speter >> count) 981018334Speter && 0 == (nonzero_bits (XEXP (varop, 0), result_mode) 981118334Speter & nonzero_bits (XEXP (varop, 1), 981218334Speter result_mode))) 981318334Speter { 981418334Speter varop = XEXP (varop, 1); 981518334Speter continue; 981618334Speter } 981718334Speter 981818334Speter /* (ashift (plus foo C) N) is (plus (ashift foo N) C'). */ 981918334Speter if (code == ASHIFT 982018334Speter && GET_CODE (XEXP (varop, 1)) == CONST_INT 982118334Speter && (new = simplify_binary_operation (ASHIFT, result_mode, 982218334Speter XEXP (varop, 1), 982318334Speter GEN_INT (count))) != 0 982490075Sobrien && GET_CODE (new) == CONST_INT 982518334Speter && merge_outer_ops (&outer_op, &outer_const, PLUS, 982618334Speter INTVAL (new), result_mode, &complement_p)) 982718334Speter { 982818334Speter varop = XEXP (varop, 0); 982918334Speter continue; 983018334Speter } 983118334Speter break; 983218334Speter 983318334Speter case MINUS: 983418334Speter /* If we have (xshiftrt (minus (ashiftrt X C)) X) C) 983518334Speter with C the size of VAROP - 1 and the shift is logical if 983618334Speter STORE_FLAG_VALUE is 1 and arithmetic if STORE_FLAG_VALUE is -1, 983718334Speter we have a (gt X 0) operation. If the shift is arithmetic with 983818334Speter STORE_FLAG_VALUE of 1 or logical with STORE_FLAG_VALUE == -1, 983918334Speter we have a (neg (gt X 0)) operation. */ 984018334Speter 984150397Sobrien if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1) 984250397Sobrien && GET_CODE (XEXP (varop, 0)) == ASHIFTRT 9843117395Skan && count == (unsigned int) 9844117395Skan (GET_MODE_BITSIZE (GET_MODE (varop)) - 1) 984518334Speter && (code == LSHIFTRT || code == ASHIFTRT) 984618334Speter && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT 9847117395Skan && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (varop, 0), 1)) 9848117395Skan == count 984918334Speter && rtx_equal_p (XEXP (XEXP (varop, 0), 0), XEXP (varop, 1))) 985018334Speter { 985118334Speter count = 0; 985290075Sobrien varop = gen_rtx_GT (GET_MODE (varop), XEXP (varop, 1), 985390075Sobrien const0_rtx); 985418334Speter 985518334Speter if (STORE_FLAG_VALUE == 1 ? code == ASHIFTRT : code == LSHIFTRT) 985690075Sobrien varop = gen_rtx_NEG (GET_MODE (varop), varop); 985718334Speter 985818334Speter continue; 985918334Speter } 986018334Speter break; 986150397Sobrien 986250397Sobrien case TRUNCATE: 986350397Sobrien /* Change (lshiftrt (truncate (lshiftrt))) to (truncate (lshiftrt)) 986450397Sobrien if the truncate does not affect the value. */ 986550397Sobrien if (code == LSHIFTRT 986650397Sobrien && GET_CODE (XEXP (varop, 0)) == LSHIFTRT 986750397Sobrien && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT 986850397Sobrien && (INTVAL (XEXP (XEXP (varop, 0), 1)) 986950397Sobrien >= (GET_MODE_BITSIZE (GET_MODE (XEXP (varop, 0))) 987050397Sobrien - GET_MODE_BITSIZE (GET_MODE (varop))))) 987150397Sobrien { 987250397Sobrien rtx varop_inner = XEXP (varop, 0); 987350397Sobrien 987490075Sobrien varop_inner 987590075Sobrien = gen_rtx_LSHIFTRT (GET_MODE (varop_inner), 987690075Sobrien XEXP (varop_inner, 0), 987790075Sobrien GEN_INT 987890075Sobrien (count + INTVAL (XEXP (varop_inner, 1)))); 987990075Sobrien varop = gen_rtx_TRUNCATE (GET_MODE (varop), varop_inner); 988050397Sobrien count = 0; 988150397Sobrien continue; 988250397Sobrien } 988350397Sobrien break; 988490075Sobrien 988550397Sobrien default: 988650397Sobrien break; 988718334Speter } 988818334Speter 988918334Speter break; 989018334Speter } 989118334Speter 989218334Speter /* We need to determine what mode to do the shift in. If the shift is 989318334Speter a right shift or ROTATE, we must always do it in the mode it was 989418334Speter originally done in. Otherwise, we can do it in MODE, the widest mode 989518334Speter encountered. The code we care about is that of the shift that will 989618334Speter actually be done, not the shift that was originally requested. */ 989718334Speter shift_mode 989818334Speter = (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE 989918334Speter ? result_mode : mode); 990018334Speter 990118334Speter /* We have now finished analyzing the shift. The result should be 990218334Speter a shift of type CODE with SHIFT_MODE shifting VAROP COUNT places. If 990318334Speter OUTER_OP is non-NIL, it is an operation that needs to be applied 990418334Speter to the result of the shift. OUTER_CONST is the relevant constant, 990518334Speter but we must turn off all bits turned off in the shift. 990618334Speter 990718334Speter If we were passed a value for X, see if we can use any pieces of 990818334Speter it. If not, make new rtx. */ 990918334Speter 991018334Speter if (x && GET_RTX_CLASS (GET_CODE (x)) == '2' 991118334Speter && GET_CODE (XEXP (x, 1)) == CONST_INT 9912117395Skan && (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) == count) 991318334Speter const_rtx = XEXP (x, 1); 991418334Speter else 991518334Speter const_rtx = GEN_INT (count); 991618334Speter 991718334Speter if (x && GET_CODE (XEXP (x, 0)) == SUBREG 991818334Speter && GET_MODE (XEXP (x, 0)) == shift_mode 991918334Speter && SUBREG_REG (XEXP (x, 0)) == varop) 992018334Speter varop = XEXP (x, 0); 992118334Speter else if (GET_MODE (varop) != shift_mode) 992218334Speter varop = gen_lowpart_for_combine (shift_mode, varop); 992318334Speter 992450397Sobrien /* If we can't make the SUBREG, try to return what we were given. */ 992518334Speter if (GET_CODE (varop) == CLOBBER) 992618334Speter return x ? x : varop; 992718334Speter 992818334Speter new = simplify_binary_operation (code, shift_mode, varop, const_rtx); 992918334Speter if (new != 0) 993018334Speter x = new; 993118334Speter else 993290075Sobrien x = gen_rtx_fmt_ee (code, shift_mode, varop, const_rtx); 993318334Speter 993418334Speter /* If we have an outer operation and we just made a shift, it is 993518334Speter possible that we could have simplified the shift were it not 993618334Speter for the outer operation. So try to do the simplification 993718334Speter recursively. */ 993818334Speter 993918334Speter if (outer_op != NIL && GET_CODE (x) == code 994018334Speter && GET_CODE (XEXP (x, 1)) == CONST_INT) 994118334Speter x = simplify_shift_const (x, code, shift_mode, XEXP (x, 0), 994218334Speter INTVAL (XEXP (x, 1))); 994318334Speter 9944117395Skan /* If we were doing an LSHIFTRT in a wider mode than it was originally, 994518334Speter turn off all the bits that the shift would have turned off. */ 994618334Speter if (orig_code == LSHIFTRT && result_mode != shift_mode) 994718334Speter x = simplify_and_const_int (NULL_RTX, shift_mode, x, 994818334Speter GET_MODE_MASK (result_mode) >> orig_count); 994990075Sobrien 995018334Speter /* Do the remainder of the processing in RESULT_MODE. */ 995118334Speter x = gen_lowpart_for_combine (result_mode, x); 995218334Speter 995318334Speter /* If COMPLEMENT_P is set, we have to complement X before doing the outer 995418334Speter operation. */ 995518334Speter if (complement_p) 995690075Sobrien x =simplify_gen_unary (NOT, result_mode, x, result_mode); 995718334Speter 995818334Speter if (outer_op != NIL) 995918334Speter { 996018334Speter if (GET_MODE_BITSIZE (result_mode) < HOST_BITS_PER_WIDE_INT) 996190075Sobrien outer_const = trunc_int_for_mode (outer_const, result_mode); 996218334Speter 996318334Speter if (outer_op == AND) 996418334Speter x = simplify_and_const_int (NULL_RTX, result_mode, x, outer_const); 996518334Speter else if (outer_op == SET) 996618334Speter /* This means that we have determined that the result is 996718334Speter equivalent to a constant. This should be rare. */ 996818334Speter x = GEN_INT (outer_const); 996918334Speter else if (GET_RTX_CLASS (outer_op) == '1') 997090075Sobrien x = simplify_gen_unary (outer_op, result_mode, x, result_mode); 997118334Speter else 997218334Speter x = gen_binary (outer_op, result_mode, x, GEN_INT (outer_const)); 997318334Speter } 997418334Speter 997518334Speter return x; 997690075Sobrien} 997718334Speter 997818334Speter/* Like recog, but we receive the address of a pointer to a new pattern. 997918334Speter We try to match the rtx that the pointer points to. 998018334Speter If that fails, we may try to modify or replace the pattern, 998118334Speter storing the replacement into the same pointer object. 998218334Speter 998318334Speter Modifications include deletion or addition of CLOBBERs. 998418334Speter 998518334Speter PNOTES is a pointer to a location where any REG_UNUSED notes added for 998618334Speter the CLOBBERs are placed. 998718334Speter 998818334Speter The value is the final insn code from the pattern ultimately matched, 998918334Speter or -1. */ 999018334Speter 999118334Speterstatic int 999252284Sobrienrecog_for_combine (pnewpat, insn, pnotes) 999318334Speter rtx *pnewpat; 999418334Speter rtx insn; 999518334Speter rtx *pnotes; 999618334Speter{ 999790075Sobrien rtx pat = *pnewpat; 999818334Speter int insn_code_number; 999918334Speter int num_clobbers_to_add = 0; 1000018334Speter int i; 1000118334Speter rtx notes = 0; 1000296263Sobrien rtx dummy_insn; 1000318334Speter 1000418334Speter /* If PAT is a PARALLEL, check to see if it contains the CLOBBER 1000518334Speter we use to indicate that something didn't match. If we find such a 1000618334Speter thing, force rejection. */ 1000718334Speter if (GET_CODE (pat) == PARALLEL) 1000818334Speter for (i = XVECLEN (pat, 0) - 1; i >= 0; i--) 1000918334Speter if (GET_CODE (XVECEXP (pat, 0, i)) == CLOBBER 1001018334Speter && XEXP (XVECEXP (pat, 0, i), 0) == const0_rtx) 1001118334Speter return -1; 1001218334Speter 1001396263Sobrien /* *pnewpat does not have to be actual PATTERN (insn), so make a dummy 1001496263Sobrien instruction for pattern recognition. */ 1001596263Sobrien dummy_insn = shallow_copy_rtx (insn); 1001696263Sobrien PATTERN (dummy_insn) = pat; 1001796263Sobrien REG_NOTES (dummy_insn) = 0; 1001890075Sobrien 1001996263Sobrien insn_code_number = recog (pat, dummy_insn, &num_clobbers_to_add); 1002018334Speter 1002118334Speter /* If it isn't, there is the possibility that we previously had an insn 1002218334Speter that clobbered some register as a side effect, but the combined 1002318334Speter insn doesn't need to do that. So try once more without the clobbers 1002418334Speter unless this represents an ASM insn. */ 1002518334Speter 1002618334Speter if (insn_code_number < 0 && ! check_asm_operands (pat) 1002718334Speter && GET_CODE (pat) == PARALLEL) 1002818334Speter { 1002918334Speter int pos; 1003018334Speter 1003118334Speter for (pos = 0, i = 0; i < XVECLEN (pat, 0); i++) 1003218334Speter if (GET_CODE (XVECEXP (pat, 0, i)) != CLOBBER) 1003318334Speter { 1003418334Speter if (i != pos) 1003518334Speter SUBST (XVECEXP (pat, 0, pos), XVECEXP (pat, 0, i)); 1003618334Speter pos++; 1003718334Speter } 1003818334Speter 1003918334Speter SUBST_INT (XVECLEN (pat, 0), pos); 1004018334Speter 1004118334Speter if (pos == 1) 1004218334Speter pat = XVECEXP (pat, 0, 0); 1004318334Speter 1004496263Sobrien PATTERN (dummy_insn) = pat; 1004596263Sobrien insn_code_number = recog (pat, dummy_insn, &num_clobbers_to_add); 1004618334Speter } 1004718334Speter 1004890075Sobrien /* Recognize all noop sets, these will be killed by followup pass. */ 1004990075Sobrien if (insn_code_number < 0 && GET_CODE (pat) == SET && set_noop_p (pat)) 1005090075Sobrien insn_code_number = NOOP_MOVE_INSN_CODE, num_clobbers_to_add = 0; 1005190075Sobrien 1005218334Speter /* If we had any clobbers to add, make a new pattern than contains 1005318334Speter them. Then check to make sure that all of them are dead. */ 1005418334Speter if (num_clobbers_to_add) 1005518334Speter { 1005650397Sobrien rtx newpat = gen_rtx_PARALLEL (VOIDmode, 1005790075Sobrien rtvec_alloc (GET_CODE (pat) == PARALLEL 1005890075Sobrien ? (XVECLEN (pat, 0) 1005990075Sobrien + num_clobbers_to_add) 1006090075Sobrien : num_clobbers_to_add + 1)); 1006118334Speter 1006218334Speter if (GET_CODE (pat) == PARALLEL) 1006318334Speter for (i = 0; i < XVECLEN (pat, 0); i++) 1006418334Speter XVECEXP (newpat, 0, i) = XVECEXP (pat, 0, i); 1006518334Speter else 1006618334Speter XVECEXP (newpat, 0, 0) = pat; 1006718334Speter 1006818334Speter add_clobbers (newpat, insn_code_number); 1006918334Speter 1007018334Speter for (i = XVECLEN (newpat, 0) - num_clobbers_to_add; 1007118334Speter i < XVECLEN (newpat, 0); i++) 1007218334Speter { 1007318334Speter if (GET_CODE (XEXP (XVECEXP (newpat, 0, i), 0)) == REG 1007418334Speter && ! reg_dead_at_p (XEXP (XVECEXP (newpat, 0, i), 0), insn)) 1007518334Speter return -1; 1007650397Sobrien notes = gen_rtx_EXPR_LIST (REG_UNUSED, 1007750397Sobrien XEXP (XVECEXP (newpat, 0, i), 0), notes); 1007818334Speter } 1007918334Speter pat = newpat; 1008018334Speter } 1008118334Speter 1008218334Speter *pnewpat = pat; 1008318334Speter *pnotes = notes; 1008418334Speter 1008518334Speter return insn_code_number; 1008618334Speter} 1008718334Speter 1008818334Speter/* Like gen_lowpart but for use by combine. In combine it is not possible 1008918334Speter to create any new pseudoregs. However, it is safe to create 1009018334Speter invalid memory addresses, because combine will try to recognize 1009118334Speter them and all they will do is make the combine attempt fail. 1009218334Speter 1009318334Speter If for some reason this cannot do its job, an rtx 1009418334Speter (clobber (const_int 0)) is returned. 1009518334Speter An insn containing that will not be recognized. */ 1009618334Speter 1009718334Speter#undef gen_lowpart 1009818334Speter 1009918334Speterstatic rtx 1010018334Spetergen_lowpart_for_combine (mode, x) 1010118334Speter enum machine_mode mode; 1010290075Sobrien rtx x; 1010318334Speter{ 1010418334Speter rtx result; 1010518334Speter 1010618334Speter if (GET_MODE (x) == mode) 1010718334Speter return x; 1010818334Speter 1010918334Speter /* We can only support MODE being wider than a word if X is a 1011018334Speter constant integer or has a mode the same size. */ 1011118334Speter 1011218334Speter if (GET_MODE_SIZE (mode) > UNITS_PER_WORD 1011318334Speter && ! ((GET_MODE (x) == VOIDmode 1011418334Speter && (GET_CODE (x) == CONST_INT 1011518334Speter || GET_CODE (x) == CONST_DOUBLE)) 1011618334Speter || GET_MODE_SIZE (GET_MODE (x)) == GET_MODE_SIZE (mode))) 1011750397Sobrien return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx); 1011818334Speter 1011918334Speter /* X might be a paradoxical (subreg (mem)). In that case, gen_lowpart 1012018334Speter won't know what to do. So we will strip off the SUBREG here and 1012118334Speter process normally. */ 1012218334Speter if (GET_CODE (x) == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM) 1012318334Speter { 1012418334Speter x = SUBREG_REG (x); 1012518334Speter if (GET_MODE (x) == mode) 1012618334Speter return x; 1012718334Speter } 1012818334Speter 1012918334Speter result = gen_lowpart_common (mode, x); 10130117395Skan#ifdef CANNOT_CHANGE_MODE_CLASS 1013118334Speter if (result != 0 1013218334Speter && GET_CODE (result) == SUBREG 1013318334Speter && GET_CODE (SUBREG_REG (result)) == REG 10134117395Skan && REGNO (SUBREG_REG (result)) >= FIRST_PSEUDO_REGISTER) 10135117395Skan bitmap_set_bit (&subregs_of_mode, REGNO (SUBREG_REG (result)) 10136117395Skan * MAX_MACHINE_MODE 10137117395Skan + GET_MODE (result)); 1013890075Sobrien#endif 1013918334Speter 1014018334Speter if (result) 1014118334Speter return result; 1014218334Speter 1014318334Speter if (GET_CODE (x) == MEM) 1014418334Speter { 1014590075Sobrien int offset = 0; 1014618334Speter 1014718334Speter /* Refuse to work on a volatile memory ref or one with a mode-dependent 1014818334Speter address. */ 1014918334Speter if (MEM_VOLATILE_P (x) || mode_dependent_address_p (XEXP (x, 0))) 1015050397Sobrien return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx); 1015118334Speter 1015218334Speter /* If we want to refer to something bigger than the original memref, 1015318334Speter generate a perverse subreg instead. That will force a reload 1015418334Speter of the original memref X. */ 1015518334Speter if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode)) 1015650397Sobrien return gen_rtx_SUBREG (mode, x, 0); 1015718334Speter 1015818334Speter if (WORDS_BIG_ENDIAN) 1015918334Speter offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD) 1016018334Speter - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)); 1016190075Sobrien 1016218334Speter if (BYTES_BIG_ENDIAN) 1016318334Speter { 1016418334Speter /* Adjust the address so that the address-after-the-data is 1016518334Speter unchanged. */ 1016618334Speter offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)) 1016718334Speter - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))); 1016818334Speter } 1016990075Sobrien 1017090075Sobrien return adjust_address_nv (x, mode, offset); 1017118334Speter } 1017218334Speter 1017318334Speter /* If X is a comparison operator, rewrite it in a new mode. This 1017418334Speter probably won't match, but may allow further simplifications. */ 1017518334Speter else if (GET_RTX_CLASS (GET_CODE (x)) == '<') 1017690075Sobrien return gen_rtx_fmt_ee (GET_CODE (x), mode, XEXP (x, 0), XEXP (x, 1)); 1017718334Speter 1017818334Speter /* If we couldn't simplify X any other way, just enclose it in a 1017918334Speter SUBREG. Normally, this SUBREG won't match, but some patterns may 1018018334Speter include an explicit SUBREG or we may simplify it further in combine. */ 1018118334Speter else 1018218334Speter { 1018390075Sobrien int offset = 0; 1018490075Sobrien rtx res; 10185117395Skan enum machine_mode sub_mode = GET_MODE (x); 1018618334Speter 10187117395Skan offset = subreg_lowpart_offset (mode, sub_mode); 10188117395Skan if (sub_mode == VOIDmode) 10189117395Skan { 10190117395Skan sub_mode = int_mode_for_mode (mode); 10191117395Skan x = gen_lowpart_common (sub_mode, x); 10192117395Skan } 10193117395Skan res = simplify_gen_subreg (mode, x, sub_mode, offset); 1019490075Sobrien if (res) 1019590075Sobrien return res; 1019690075Sobrien return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx); 1019718334Speter } 1019818334Speter} 1019918334Speter 1020018334Speter/* These routines make binary and unary operations by first seeing if they 1020118334Speter fold; if not, a new expression is allocated. */ 1020218334Speter 1020318334Speterstatic rtx 1020418334Spetergen_binary (code, mode, op0, op1) 1020518334Speter enum rtx_code code; 1020618334Speter enum machine_mode mode; 1020718334Speter rtx op0, op1; 1020818334Speter{ 1020918334Speter rtx result; 1021018334Speter rtx tem; 1021118334Speter 1021218334Speter if (GET_RTX_CLASS (code) == 'c' 1021390075Sobrien && swap_commutative_operands_p (op0, op1)) 1021418334Speter tem = op0, op0 = op1, op1 = tem; 1021518334Speter 1021690075Sobrien if (GET_RTX_CLASS (code) == '<') 1021718334Speter { 1021818334Speter enum machine_mode op_mode = GET_MODE (op0); 1021918334Speter 1022090075Sobrien /* Strip the COMPARE from (REL_OP (compare X Y) 0) to get 1022150397Sobrien just (REL_OP X Y). */ 1022218334Speter if (GET_CODE (op0) == COMPARE && op1 == const0_rtx) 1022318334Speter { 1022418334Speter op1 = XEXP (op0, 1); 1022518334Speter op0 = XEXP (op0, 0); 1022618334Speter op_mode = GET_MODE (op0); 1022718334Speter } 1022818334Speter 1022918334Speter if (op_mode == VOIDmode) 1023018334Speter op_mode = GET_MODE (op1); 1023118334Speter result = simplify_relational_operation (code, op_mode, op0, op1); 1023218334Speter } 1023318334Speter else 1023418334Speter result = simplify_binary_operation (code, mode, op0, op1); 1023518334Speter 1023618334Speter if (result) 1023718334Speter return result; 1023818334Speter 1023918334Speter /* Put complex operands first and constants second. */ 1024018334Speter if (GET_RTX_CLASS (code) == 'c' 1024190075Sobrien && swap_commutative_operands_p (op0, op1)) 1024290075Sobrien return gen_rtx_fmt_ee (code, mode, op1, op0); 1024318334Speter 1024450397Sobrien /* If we are turning off bits already known off in OP0, we need not do 1024550397Sobrien an AND. */ 1024650397Sobrien else if (code == AND && GET_CODE (op1) == CONST_INT 1024750397Sobrien && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT 1024890075Sobrien && (nonzero_bits (op0, mode) & ~INTVAL (op1)) == 0) 1024950397Sobrien return op0; 1025050397Sobrien 1025190075Sobrien return gen_rtx_fmt_ee (code, mode, op0, op1); 1025218334Speter} 1025318334Speter 1025418334Speter/* Simplify a comparison between *POP0 and *POP1 where CODE is the 1025518334Speter comparison code that will be tested. 1025618334Speter 1025718334Speter The result is a possibly different comparison code to use. *POP0 and 1025818334Speter *POP1 may be updated. 1025918334Speter 1026018334Speter It is possible that we might detect that a comparison is either always 1026118334Speter true or always false. However, we do not perform general constant 1026218334Speter folding in combine, so this knowledge isn't useful. Such tautologies 1026318334Speter should have been detected earlier. Hence we ignore all such cases. */ 1026418334Speter 1026518334Speterstatic enum rtx_code 1026618334Spetersimplify_comparison (code, pop0, pop1) 1026718334Speter enum rtx_code code; 1026818334Speter rtx *pop0; 1026918334Speter rtx *pop1; 1027018334Speter{ 1027118334Speter rtx op0 = *pop0; 1027218334Speter rtx op1 = *pop1; 1027318334Speter rtx tem, tem1; 1027418334Speter int i; 1027518334Speter enum machine_mode mode, tmode; 1027618334Speter 1027718334Speter /* Try a few ways of applying the same transformation to both operands. */ 1027818334Speter while (1) 1027918334Speter { 1028018334Speter#ifndef WORD_REGISTER_OPERATIONS 1028118334Speter /* The test below this one won't handle SIGN_EXTENDs on these machines, 1028218334Speter so check specially. */ 1028318334Speter if (code != GTU && code != GEU && code != LTU && code != LEU 1028418334Speter && GET_CODE (op0) == ASHIFTRT && GET_CODE (op1) == ASHIFTRT 1028518334Speter && GET_CODE (XEXP (op0, 0)) == ASHIFT 1028618334Speter && GET_CODE (XEXP (op1, 0)) == ASHIFT 1028718334Speter && GET_CODE (XEXP (XEXP (op0, 0), 0)) == SUBREG 1028818334Speter && GET_CODE (XEXP (XEXP (op1, 0), 0)) == SUBREG 1028918334Speter && (GET_MODE (SUBREG_REG (XEXP (XEXP (op0, 0), 0))) 1029018334Speter == GET_MODE (SUBREG_REG (XEXP (XEXP (op1, 0), 0)))) 1029118334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 1029218334Speter && GET_CODE (XEXP (op1, 1)) == CONST_INT 1029318334Speter && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT 1029418334Speter && GET_CODE (XEXP (XEXP (op1, 0), 1)) == CONST_INT 1029518334Speter && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (op1, 1)) 1029618334Speter && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (XEXP (op0, 0), 1)) 1029718334Speter && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (XEXP (op1, 0), 1)) 1029818334Speter && (INTVAL (XEXP (op0, 1)) 1029918334Speter == (GET_MODE_BITSIZE (GET_MODE (op0)) 1030018334Speter - (GET_MODE_BITSIZE 1030118334Speter (GET_MODE (SUBREG_REG (XEXP (XEXP (op0, 0), 0)))))))) 1030218334Speter { 1030318334Speter op0 = SUBREG_REG (XEXP (XEXP (op0, 0), 0)); 1030418334Speter op1 = SUBREG_REG (XEXP (XEXP (op1, 0), 0)); 1030518334Speter } 1030618334Speter#endif 1030718334Speter 1030818334Speter /* If both operands are the same constant shift, see if we can ignore the 1030918334Speter shift. We can if the shift is a rotate or if the bits shifted out of 1031018334Speter this shift are known to be zero for both inputs and if the type of 1031118334Speter comparison is compatible with the shift. */ 1031218334Speter if (GET_CODE (op0) == GET_CODE (op1) 1031318334Speter && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT 1031418334Speter && ((GET_CODE (op0) == ROTATE && (code == NE || code == EQ)) 1031518334Speter || ((GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFT) 1031618334Speter && (code != GT && code != LT && code != GE && code != LE)) 1031718334Speter || (GET_CODE (op0) == ASHIFTRT 1031818334Speter && (code != GTU && code != LTU 1031990075Sobrien && code != GEU && code != LEU))) 1032018334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 1032118334Speter && INTVAL (XEXP (op0, 1)) >= 0 1032218334Speter && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT 1032318334Speter && XEXP (op0, 1) == XEXP (op1, 1)) 1032418334Speter { 1032518334Speter enum machine_mode mode = GET_MODE (op0); 1032618334Speter unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode); 1032718334Speter int shift_count = INTVAL (XEXP (op0, 1)); 1032818334Speter 1032918334Speter if (GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFTRT) 1033018334Speter mask &= (mask >> shift_count) << shift_count; 1033118334Speter else if (GET_CODE (op0) == ASHIFT) 1033218334Speter mask = (mask & (mask << shift_count)) >> shift_count; 1033318334Speter 1033490075Sobrien if ((nonzero_bits (XEXP (op0, 0), mode) & ~mask) == 0 1033590075Sobrien && (nonzero_bits (XEXP (op1, 0), mode) & ~mask) == 0) 1033618334Speter op0 = XEXP (op0, 0), op1 = XEXP (op1, 0); 1033718334Speter else 1033818334Speter break; 1033918334Speter } 1034018334Speter 1034118334Speter /* If both operands are AND's of a paradoxical SUBREG by constant, the 1034218334Speter SUBREGs are of the same mode, and, in both cases, the AND would 1034318334Speter be redundant if the comparison was done in the narrower mode, 1034418334Speter do the comparison in the narrower mode (e.g., we are AND'ing with 1 1034518334Speter and the operand's possibly nonzero bits are 0xffffff01; in that case 1034618334Speter if we only care about QImode, we don't need the AND). This case 1034718334Speter occurs if the output mode of an scc insn is not SImode and 1034818334Speter STORE_FLAG_VALUE == 1 (e.g., the 386). 1034918334Speter 1035018334Speter Similarly, check for a case where the AND's are ZERO_EXTEND 1035118334Speter operations from some narrower mode even though a SUBREG is not 1035218334Speter present. */ 1035318334Speter 1035490075Sobrien else if (GET_CODE (op0) == AND && GET_CODE (op1) == AND 1035590075Sobrien && GET_CODE (XEXP (op0, 1)) == CONST_INT 1035690075Sobrien && GET_CODE (XEXP (op1, 1)) == CONST_INT) 1035718334Speter { 1035818334Speter rtx inner_op0 = XEXP (op0, 0); 1035918334Speter rtx inner_op1 = XEXP (op1, 0); 1036018334Speter HOST_WIDE_INT c0 = INTVAL (XEXP (op0, 1)); 1036118334Speter HOST_WIDE_INT c1 = INTVAL (XEXP (op1, 1)); 1036218334Speter int changed = 0; 1036390075Sobrien 1036418334Speter if (GET_CODE (inner_op0) == SUBREG && GET_CODE (inner_op1) == SUBREG 1036518334Speter && (GET_MODE_SIZE (GET_MODE (inner_op0)) 1036618334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner_op0)))) 1036718334Speter && (GET_MODE (SUBREG_REG (inner_op0)) 1036818334Speter == GET_MODE (SUBREG_REG (inner_op1))) 1036950397Sobrien && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (inner_op0))) 1037018334Speter <= HOST_BITS_PER_WIDE_INT) 1037150397Sobrien && (0 == ((~c0) & nonzero_bits (SUBREG_REG (inner_op0), 1037250397Sobrien GET_MODE (SUBREG_REG (inner_op0))))) 1037350397Sobrien && (0 == ((~c1) & nonzero_bits (SUBREG_REG (inner_op1), 1037450397Sobrien GET_MODE (SUBREG_REG (inner_op1)))))) 1037518334Speter { 1037618334Speter op0 = SUBREG_REG (inner_op0); 1037718334Speter op1 = SUBREG_REG (inner_op1); 1037818334Speter 1037918334Speter /* The resulting comparison is always unsigned since we masked 1038050397Sobrien off the original sign bit. */ 1038118334Speter code = unsigned_condition (code); 1038218334Speter 1038318334Speter changed = 1; 1038418334Speter } 1038518334Speter 1038618334Speter else if (c0 == c1) 1038718334Speter for (tmode = GET_CLASS_NARROWEST_MODE 1038818334Speter (GET_MODE_CLASS (GET_MODE (op0))); 1038918334Speter tmode != GET_MODE (op0); tmode = GET_MODE_WIDER_MODE (tmode)) 1039052284Sobrien if ((unsigned HOST_WIDE_INT) c0 == GET_MODE_MASK (tmode)) 1039118334Speter { 1039218334Speter op0 = gen_lowpart_for_combine (tmode, inner_op0); 1039318334Speter op1 = gen_lowpart_for_combine (tmode, inner_op1); 1039418334Speter code = unsigned_condition (code); 1039518334Speter changed = 1; 1039618334Speter break; 1039718334Speter } 1039818334Speter 1039918334Speter if (! changed) 1040018334Speter break; 1040118334Speter } 1040218334Speter 1040318334Speter /* If both operands are NOT, we can strip off the outer operation 1040418334Speter and adjust the comparison code for swapped operands; similarly for 1040518334Speter NEG, except that this must be an equality comparison. */ 1040618334Speter else if ((GET_CODE (op0) == NOT && GET_CODE (op1) == NOT) 1040718334Speter || (GET_CODE (op0) == NEG && GET_CODE (op1) == NEG 1040818334Speter && (code == EQ || code == NE))) 1040918334Speter op0 = XEXP (op0, 0), op1 = XEXP (op1, 0), code = swap_condition (code); 1041018334Speter 1041118334Speter else 1041218334Speter break; 1041318334Speter } 1041490075Sobrien 1041518334Speter /* If the first operand is a constant, swap the operands and adjust the 1041650397Sobrien comparison code appropriately, but don't do this if the second operand 1041750397Sobrien is already a constant integer. */ 1041890075Sobrien if (swap_commutative_operands_p (op0, op1)) 1041918334Speter { 1042018334Speter tem = op0, op0 = op1, op1 = tem; 1042118334Speter code = swap_condition (code); 1042218334Speter } 1042318334Speter 1042418334Speter /* We now enter a loop during which we will try to simplify the comparison. 1042518334Speter For the most part, we only are concerned with comparisons with zero, 1042618334Speter but some things may really be comparisons with zero but not start 1042718334Speter out looking that way. */ 1042818334Speter 1042918334Speter while (GET_CODE (op1) == CONST_INT) 1043018334Speter { 1043118334Speter enum machine_mode mode = GET_MODE (op0); 1043290075Sobrien unsigned int mode_width = GET_MODE_BITSIZE (mode); 1043318334Speter unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode); 1043418334Speter int equality_comparison_p; 1043518334Speter int sign_bit_comparison_p; 1043618334Speter int unsigned_comparison_p; 1043718334Speter HOST_WIDE_INT const_op; 1043818334Speter 1043918334Speter /* We only want to handle integral modes. This catches VOIDmode, 1044018334Speter CCmode, and the floating-point modes. An exception is that we 1044118334Speter can handle VOIDmode if OP0 is a COMPARE or a comparison 1044218334Speter operation. */ 1044318334Speter 1044418334Speter if (GET_MODE_CLASS (mode) != MODE_INT 1044518334Speter && ! (mode == VOIDmode 1044618334Speter && (GET_CODE (op0) == COMPARE 1044718334Speter || GET_RTX_CLASS (GET_CODE (op0)) == '<'))) 1044818334Speter break; 1044918334Speter 1045018334Speter /* Get the constant we are comparing against and turn off all bits 1045118334Speter not on in our mode. */ 10452117395Skan const_op = INTVAL (op1); 10453117395Skan if (mode != VOIDmode) 10454117395Skan const_op = trunc_int_for_mode (const_op, mode); 1045590075Sobrien op1 = GEN_INT (const_op); 1045618334Speter 1045718334Speter /* If we are comparing against a constant power of two and the value 1045818334Speter being compared can only have that single bit nonzero (e.g., it was 1045918334Speter `and'ed with that bit), we can replace this with a comparison 1046018334Speter with zero. */ 1046118334Speter if (const_op 1046218334Speter && (code == EQ || code == NE || code == GE || code == GEU 1046318334Speter || code == LT || code == LTU) 1046418334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 1046518334Speter && exact_log2 (const_op) >= 0 1046652284Sobrien && nonzero_bits (op0, mode) == (unsigned HOST_WIDE_INT) const_op) 1046718334Speter { 1046818334Speter code = (code == EQ || code == GE || code == GEU ? NE : EQ); 1046918334Speter op1 = const0_rtx, const_op = 0; 1047018334Speter } 1047118334Speter 1047218334Speter /* Similarly, if we are comparing a value known to be either -1 or 1047318334Speter 0 with -1, change it to the opposite comparison against zero. */ 1047418334Speter 1047518334Speter if (const_op == -1 1047618334Speter && (code == EQ || code == NE || code == GT || code == LE 1047718334Speter || code == GEU || code == LTU) 1047818334Speter && num_sign_bit_copies (op0, mode) == mode_width) 1047918334Speter { 1048018334Speter code = (code == EQ || code == LE || code == GEU ? NE : EQ); 1048118334Speter op1 = const0_rtx, const_op = 0; 1048218334Speter } 1048318334Speter 1048418334Speter /* Do some canonicalizations based on the comparison code. We prefer 1048590075Sobrien comparisons against zero and then prefer equality comparisons. 1048618334Speter If we can reduce the size of a constant, we will do that too. */ 1048718334Speter 1048818334Speter switch (code) 1048918334Speter { 1049018334Speter case LT: 1049118334Speter /* < C is equivalent to <= (C - 1) */ 1049218334Speter if (const_op > 0) 1049318334Speter { 1049418334Speter const_op -= 1; 1049518334Speter op1 = GEN_INT (const_op); 1049618334Speter code = LE; 1049718334Speter /* ... fall through to LE case below. */ 1049818334Speter } 1049918334Speter else 1050018334Speter break; 1050118334Speter 1050218334Speter case LE: 1050318334Speter /* <= C is equivalent to < (C + 1); we do this for C < 0 */ 1050418334Speter if (const_op < 0) 1050518334Speter { 1050618334Speter const_op += 1; 1050718334Speter op1 = GEN_INT (const_op); 1050818334Speter code = LT; 1050918334Speter } 1051018334Speter 1051118334Speter /* If we are doing a <= 0 comparison on a value known to have 1051218334Speter a zero sign bit, we can replace this with == 0. */ 1051318334Speter else if (const_op == 0 1051418334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 1051518334Speter && (nonzero_bits (op0, mode) 1051618334Speter & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0) 1051718334Speter code = EQ; 1051818334Speter break; 1051918334Speter 1052018334Speter case GE: 1052150397Sobrien /* >= C is equivalent to > (C - 1). */ 1052218334Speter if (const_op > 0) 1052318334Speter { 1052418334Speter const_op -= 1; 1052518334Speter op1 = GEN_INT (const_op); 1052618334Speter code = GT; 1052718334Speter /* ... fall through to GT below. */ 1052818334Speter } 1052918334Speter else 1053018334Speter break; 1053118334Speter 1053218334Speter case GT: 1053390075Sobrien /* > C is equivalent to >= (C + 1); we do this for C < 0. */ 1053418334Speter if (const_op < 0) 1053518334Speter { 1053618334Speter const_op += 1; 1053718334Speter op1 = GEN_INT (const_op); 1053818334Speter code = GE; 1053918334Speter } 1054018334Speter 1054118334Speter /* If we are doing a > 0 comparison on a value known to have 1054218334Speter a zero sign bit, we can replace this with != 0. */ 1054318334Speter else if (const_op == 0 1054418334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 1054518334Speter && (nonzero_bits (op0, mode) 1054618334Speter & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0) 1054718334Speter code = NE; 1054818334Speter break; 1054918334Speter 1055018334Speter case LTU: 1055118334Speter /* < C is equivalent to <= (C - 1). */ 1055218334Speter if (const_op > 0) 1055318334Speter { 1055418334Speter const_op -= 1; 1055518334Speter op1 = GEN_INT (const_op); 1055618334Speter code = LEU; 1055750397Sobrien /* ... fall through ... */ 1055818334Speter } 1055918334Speter 1056018334Speter /* (unsigned) < 0x80000000 is equivalent to >= 0. */ 1056150397Sobrien else if ((mode_width <= HOST_BITS_PER_WIDE_INT) 1056250397Sobrien && (const_op == (HOST_WIDE_INT) 1 << (mode_width - 1))) 1056318334Speter { 1056418334Speter const_op = 0, op1 = const0_rtx; 1056518334Speter code = GE; 1056618334Speter break; 1056718334Speter } 1056818334Speter else 1056918334Speter break; 1057018334Speter 1057118334Speter case LEU: 1057218334Speter /* unsigned <= 0 is equivalent to == 0 */ 1057318334Speter if (const_op == 0) 1057418334Speter code = EQ; 1057518334Speter 1057650397Sobrien /* (unsigned) <= 0x7fffffff is equivalent to >= 0. */ 1057750397Sobrien else if ((mode_width <= HOST_BITS_PER_WIDE_INT) 1057850397Sobrien && (const_op == ((HOST_WIDE_INT) 1 << (mode_width - 1)) - 1)) 1057918334Speter { 1058018334Speter const_op = 0, op1 = const0_rtx; 1058118334Speter code = GE; 1058218334Speter } 1058318334Speter break; 1058418334Speter 1058518334Speter case GEU: 1058618334Speter /* >= C is equivalent to < (C - 1). */ 1058718334Speter if (const_op > 1) 1058818334Speter { 1058918334Speter const_op -= 1; 1059018334Speter op1 = GEN_INT (const_op); 1059118334Speter code = GTU; 1059250397Sobrien /* ... fall through ... */ 1059318334Speter } 1059418334Speter 1059518334Speter /* (unsigned) >= 0x80000000 is equivalent to < 0. */ 1059650397Sobrien else if ((mode_width <= HOST_BITS_PER_WIDE_INT) 1059750397Sobrien && (const_op == (HOST_WIDE_INT) 1 << (mode_width - 1))) 1059818334Speter { 1059918334Speter const_op = 0, op1 = const0_rtx; 1060018334Speter code = LT; 1060118334Speter break; 1060218334Speter } 1060318334Speter else 1060418334Speter break; 1060518334Speter 1060618334Speter case GTU: 1060718334Speter /* unsigned > 0 is equivalent to != 0 */ 1060818334Speter if (const_op == 0) 1060918334Speter code = NE; 1061018334Speter 1061118334Speter /* (unsigned) > 0x7fffffff is equivalent to < 0. */ 1061250397Sobrien else if ((mode_width <= HOST_BITS_PER_WIDE_INT) 1061350397Sobrien && (const_op == ((HOST_WIDE_INT) 1 << (mode_width - 1)) - 1)) 1061418334Speter { 1061518334Speter const_op = 0, op1 = const0_rtx; 1061618334Speter code = LT; 1061718334Speter } 1061818334Speter break; 1061950397Sobrien 1062050397Sobrien default: 1062150397Sobrien break; 1062218334Speter } 1062318334Speter 1062418334Speter /* Compute some predicates to simplify code below. */ 1062518334Speter 1062618334Speter equality_comparison_p = (code == EQ || code == NE); 1062718334Speter sign_bit_comparison_p = ((code == LT || code == GE) && const_op == 0); 1062818334Speter unsigned_comparison_p = (code == LTU || code == LEU || code == GTU 1062990075Sobrien || code == GEU); 1063018334Speter 1063118334Speter /* If this is a sign bit comparison and we can do arithmetic in 1063218334Speter MODE, say that we will only be needing the sign bit of OP0. */ 1063318334Speter if (sign_bit_comparison_p 1063418334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) 1063518334Speter op0 = force_to_mode (op0, mode, 1063618334Speter ((HOST_WIDE_INT) 1 1063718334Speter << (GET_MODE_BITSIZE (mode) - 1)), 1063818334Speter NULL_RTX, 0); 1063918334Speter 1064018334Speter /* Now try cases based on the opcode of OP0. If none of the cases 1064118334Speter does a "continue", we exit this loop immediately after the 1064218334Speter switch. */ 1064318334Speter 1064418334Speter switch (GET_CODE (op0)) 1064518334Speter { 1064618334Speter case ZERO_EXTRACT: 1064718334Speter /* If we are extracting a single bit from a variable position in 1064818334Speter a constant that has only a single bit set and are comparing it 1064990075Sobrien with zero, we can convert this into an equality comparison 1065050397Sobrien between the position and the location of the single bit. */ 1065118334Speter 1065218334Speter if (GET_CODE (XEXP (op0, 0)) == CONST_INT 1065318334Speter && XEXP (op0, 1) == const1_rtx 1065418334Speter && equality_comparison_p && const_op == 0 1065550397Sobrien && (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0) 1065618334Speter { 1065750397Sobrien if (BITS_BIG_ENDIAN) 1065852284Sobrien { 1065990075Sobrien enum machine_mode new_mode 1066090075Sobrien = mode_for_extraction (EP_extzv, 1); 1066190075Sobrien if (new_mode == MAX_MACHINE_MODE) 1066290075Sobrien i = BITS_PER_WORD - 1 - i; 1066390075Sobrien else 1066490075Sobrien { 1066590075Sobrien mode = new_mode; 1066690075Sobrien i = (GET_MODE_BITSIZE (mode) - 1 - i); 1066790075Sobrien } 1066852284Sobrien } 1066918334Speter 1067018334Speter op0 = XEXP (op0, 2); 1067118334Speter op1 = GEN_INT (i); 1067218334Speter const_op = i; 1067318334Speter 1067418334Speter /* Result is nonzero iff shift count is equal to I. */ 1067518334Speter code = reverse_condition (code); 1067618334Speter continue; 1067718334Speter } 1067818334Speter 1067950397Sobrien /* ... fall through ... */ 1068018334Speter 1068118334Speter case SIGN_EXTRACT: 1068218334Speter tem = expand_compound_operation (op0); 1068318334Speter if (tem != op0) 1068418334Speter { 1068518334Speter op0 = tem; 1068618334Speter continue; 1068718334Speter } 1068818334Speter break; 1068918334Speter 1069018334Speter case NOT: 1069118334Speter /* If testing for equality, we can take the NOT of the constant. */ 1069218334Speter if (equality_comparison_p 1069318334Speter && (tem = simplify_unary_operation (NOT, mode, op1, mode)) != 0) 1069418334Speter { 1069518334Speter op0 = XEXP (op0, 0); 1069618334Speter op1 = tem; 1069718334Speter continue; 1069818334Speter } 1069918334Speter 1070018334Speter /* If just looking at the sign bit, reverse the sense of the 1070118334Speter comparison. */ 1070218334Speter if (sign_bit_comparison_p) 1070318334Speter { 1070418334Speter op0 = XEXP (op0, 0); 1070518334Speter code = (code == GE ? LT : GE); 1070618334Speter continue; 1070718334Speter } 1070818334Speter break; 1070918334Speter 1071018334Speter case NEG: 1071118334Speter /* If testing for equality, we can take the NEG of the constant. */ 1071218334Speter if (equality_comparison_p 1071318334Speter && (tem = simplify_unary_operation (NEG, mode, op1, mode)) != 0) 1071418334Speter { 1071518334Speter op0 = XEXP (op0, 0); 1071618334Speter op1 = tem; 1071718334Speter continue; 1071818334Speter } 1071918334Speter 1072018334Speter /* The remaining cases only apply to comparisons with zero. */ 1072118334Speter if (const_op != 0) 1072218334Speter break; 1072318334Speter 1072418334Speter /* When X is ABS or is known positive, 1072518334Speter (neg X) is < 0 if and only if X != 0. */ 1072618334Speter 1072718334Speter if (sign_bit_comparison_p 1072818334Speter && (GET_CODE (XEXP (op0, 0)) == ABS 1072918334Speter || (mode_width <= HOST_BITS_PER_WIDE_INT 1073018334Speter && (nonzero_bits (XEXP (op0, 0), mode) 1073118334Speter & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0))) 1073218334Speter { 1073318334Speter op0 = XEXP (op0, 0); 1073418334Speter code = (code == LT ? NE : EQ); 1073518334Speter continue; 1073618334Speter } 1073718334Speter 1073818334Speter /* If we have NEG of something whose two high-order bits are the 1073950397Sobrien same, we know that "(-a) < 0" is equivalent to "a > 0". */ 1074018334Speter if (num_sign_bit_copies (op0, mode) >= 2) 1074118334Speter { 1074218334Speter op0 = XEXP (op0, 0); 1074318334Speter code = swap_condition (code); 1074418334Speter continue; 1074518334Speter } 1074618334Speter break; 1074718334Speter 1074818334Speter case ROTATE: 1074918334Speter /* If we are testing equality and our count is a constant, we 1075018334Speter can perform the inverse operation on our RHS. */ 1075118334Speter if (equality_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT 1075218334Speter && (tem = simplify_binary_operation (ROTATERT, mode, 1075318334Speter op1, XEXP (op0, 1))) != 0) 1075418334Speter { 1075518334Speter op0 = XEXP (op0, 0); 1075618334Speter op1 = tem; 1075718334Speter continue; 1075818334Speter } 1075918334Speter 1076018334Speter /* If we are doing a < 0 or >= 0 comparison, it means we are testing 1076118334Speter a particular bit. Convert it to an AND of a constant of that 1076218334Speter bit. This will be converted into a ZERO_EXTRACT. */ 1076318334Speter if (const_op == 0 && sign_bit_comparison_p 1076418334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 1076518334Speter && mode_width <= HOST_BITS_PER_WIDE_INT) 1076618334Speter { 1076718334Speter op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0), 1076818334Speter ((HOST_WIDE_INT) 1 1076918334Speter << (mode_width - 1 1077018334Speter - INTVAL (XEXP (op0, 1))))); 1077118334Speter code = (code == LT ? NE : EQ); 1077218334Speter continue; 1077318334Speter } 1077418334Speter 1077590075Sobrien /* Fall through. */ 1077618334Speter 1077718334Speter case ABS: 1077818334Speter /* ABS is ignorable inside an equality comparison with zero. */ 1077918334Speter if (const_op == 0 && equality_comparison_p) 1078018334Speter { 1078118334Speter op0 = XEXP (op0, 0); 1078218334Speter continue; 1078318334Speter } 1078418334Speter break; 1078518334Speter 1078618334Speter case SIGN_EXTEND: 1078718334Speter /* Can simplify (compare (zero/sign_extend FOO) CONST) 1078890075Sobrien to (compare FOO CONST) if CONST fits in FOO's mode and we 1078918334Speter are either testing inequality or have an unsigned comparison 1079018334Speter with ZERO_EXTEND or a signed comparison with SIGN_EXTEND. */ 1079118334Speter if (! unsigned_comparison_p 1079218334Speter && (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))) 1079318334Speter <= HOST_BITS_PER_WIDE_INT) 1079418334Speter && ((unsigned HOST_WIDE_INT) const_op 1079552284Sobrien < (((unsigned HOST_WIDE_INT) 1 1079618334Speter << (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))) - 1))))) 1079718334Speter { 1079818334Speter op0 = XEXP (op0, 0); 1079918334Speter continue; 1080018334Speter } 1080118334Speter break; 1080218334Speter 1080318334Speter case SUBREG: 1080418334Speter /* Check for the case where we are comparing A - C1 with C2, 1080518334Speter both constants are smaller than 1/2 the maximum positive 1080618334Speter value in MODE, and the comparison is equality or unsigned. 1080718334Speter In that case, if A is either zero-extended to MODE or has 1080818334Speter sufficient sign bits so that the high-order bit in MODE 1080918334Speter is a copy of the sign in the inner mode, we can prove that it is 1081018334Speter safe to do the operation in the wider mode. This simplifies 1081118334Speter many range checks. */ 1081218334Speter 1081318334Speter if (mode_width <= HOST_BITS_PER_WIDE_INT 1081418334Speter && subreg_lowpart_p (op0) 1081518334Speter && GET_CODE (SUBREG_REG (op0)) == PLUS 1081618334Speter && GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT 1081718334Speter && INTVAL (XEXP (SUBREG_REG (op0), 1)) < 0 1081890075Sobrien && (-INTVAL (XEXP (SUBREG_REG (op0), 1)) 1081990075Sobrien < (HOST_WIDE_INT) (GET_MODE_MASK (mode) / 2)) 1082018334Speter && (unsigned HOST_WIDE_INT) const_op < GET_MODE_MASK (mode) / 2 1082118334Speter && (0 == (nonzero_bits (XEXP (SUBREG_REG (op0), 0), 1082218334Speter GET_MODE (SUBREG_REG (op0))) 1082390075Sobrien & ~GET_MODE_MASK (mode)) 1082418334Speter || (num_sign_bit_copies (XEXP (SUBREG_REG (op0), 0), 1082518334Speter GET_MODE (SUBREG_REG (op0))) 10826117395Skan > (unsigned int) 10827117395Skan (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) 1082818334Speter - GET_MODE_BITSIZE (mode))))) 1082918334Speter { 1083018334Speter op0 = SUBREG_REG (op0); 1083118334Speter continue; 1083218334Speter } 1083318334Speter 1083418334Speter /* If the inner mode is narrower and we are extracting the low part, 1083518334Speter we can treat the SUBREG as if it were a ZERO_EXTEND. */ 1083618334Speter if (subreg_lowpart_p (op0) 1083718334Speter && GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) < mode_width) 1083818334Speter /* Fall through */ ; 1083918334Speter else 1084018334Speter break; 1084118334Speter 1084250397Sobrien /* ... fall through ... */ 1084318334Speter 1084418334Speter case ZERO_EXTEND: 1084518334Speter if ((unsigned_comparison_p || equality_comparison_p) 1084618334Speter && (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))) 1084718334Speter <= HOST_BITS_PER_WIDE_INT) 1084818334Speter && ((unsigned HOST_WIDE_INT) const_op 1084918334Speter < GET_MODE_MASK (GET_MODE (XEXP (op0, 0))))) 1085018334Speter { 1085118334Speter op0 = XEXP (op0, 0); 1085218334Speter continue; 1085318334Speter } 1085418334Speter break; 1085518334Speter 1085618334Speter case PLUS: 1085718334Speter /* (eq (plus X A) B) -> (eq X (minus B A)). We can only do 1085818334Speter this for equality comparisons due to pathological cases involving 1085918334Speter overflows. */ 1086018334Speter if (equality_comparison_p 1086118334Speter && 0 != (tem = simplify_binary_operation (MINUS, mode, 1086218334Speter op1, XEXP (op0, 1)))) 1086318334Speter { 1086418334Speter op0 = XEXP (op0, 0); 1086518334Speter op1 = tem; 1086618334Speter continue; 1086718334Speter } 1086818334Speter 1086918334Speter /* (plus (abs X) (const_int -1)) is < 0 if and only if X == 0. */ 1087018334Speter if (const_op == 0 && XEXP (op0, 1) == constm1_rtx 1087118334Speter && GET_CODE (XEXP (op0, 0)) == ABS && sign_bit_comparison_p) 1087218334Speter { 1087318334Speter op0 = XEXP (XEXP (op0, 0), 0); 1087418334Speter code = (code == LT ? EQ : NE); 1087518334Speter continue; 1087618334Speter } 1087718334Speter break; 1087818334Speter 1087918334Speter case MINUS: 1088090075Sobrien /* We used to optimize signed comparisons against zero, but that 1088190075Sobrien was incorrect. Unsigned comparisons against zero (GTU, LEU) 1088290075Sobrien arrive here as equality comparisons, or (GEU, LTU) are 1088390075Sobrien optimized away. No need to special-case them. */ 1088490075Sobrien 1088518334Speter /* (eq (minus A B) C) -> (eq A (plus B C)) or 1088618334Speter (eq B (minus A C)), whichever simplifies. We can only do 1088718334Speter this for equality comparisons due to pathological cases involving 1088818334Speter overflows. */ 1088918334Speter if (equality_comparison_p 1089018334Speter && 0 != (tem = simplify_binary_operation (PLUS, mode, 1089118334Speter XEXP (op0, 1), op1))) 1089218334Speter { 1089318334Speter op0 = XEXP (op0, 0); 1089418334Speter op1 = tem; 1089518334Speter continue; 1089618334Speter } 1089718334Speter 1089818334Speter if (equality_comparison_p 1089918334Speter && 0 != (tem = simplify_binary_operation (MINUS, mode, 1090018334Speter XEXP (op0, 0), op1))) 1090118334Speter { 1090218334Speter op0 = XEXP (op0, 1); 1090318334Speter op1 = tem; 1090418334Speter continue; 1090518334Speter } 1090618334Speter 1090718334Speter /* The sign bit of (minus (ashiftrt X C) X), where C is the number 1090818334Speter of bits in X minus 1, is one iff X > 0. */ 1090918334Speter if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 0)) == ASHIFTRT 1091018334Speter && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT 10911117395Skan && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (op0, 0), 1)) 10912117395Skan == mode_width - 1 1091318334Speter && rtx_equal_p (XEXP (XEXP (op0, 0), 0), XEXP (op0, 1))) 1091418334Speter { 1091518334Speter op0 = XEXP (op0, 1); 1091618334Speter code = (code == GE ? LE : GT); 1091718334Speter continue; 1091818334Speter } 1091918334Speter break; 1092018334Speter 1092118334Speter case XOR: 1092218334Speter /* (eq (xor A B) C) -> (eq A (xor B C)). This is a simplification 1092318334Speter if C is zero or B is a constant. */ 1092418334Speter if (equality_comparison_p 1092518334Speter && 0 != (tem = simplify_binary_operation (XOR, mode, 1092618334Speter XEXP (op0, 1), op1))) 1092718334Speter { 1092818334Speter op0 = XEXP (op0, 0); 1092918334Speter op1 = tem; 1093018334Speter continue; 1093118334Speter } 1093218334Speter break; 1093318334Speter 1093418334Speter case EQ: case NE: 1093590075Sobrien case UNEQ: case LTGT: 1093690075Sobrien case LT: case LTU: case UNLT: case LE: case LEU: case UNLE: 1093790075Sobrien case GT: case GTU: case UNGT: case GE: case GEU: case UNGE: 1093890075Sobrien case UNORDERED: case ORDERED: 1093918334Speter /* We can't do anything if OP0 is a condition code value, rather 1094018334Speter than an actual data value. */ 1094118334Speter if (const_op != 0 1094218334Speter#ifdef HAVE_cc0 1094318334Speter || XEXP (op0, 0) == cc0_rtx 1094418334Speter#endif 1094518334Speter || GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC) 1094618334Speter break; 1094718334Speter 1094818334Speter /* Get the two operands being compared. */ 1094918334Speter if (GET_CODE (XEXP (op0, 0)) == COMPARE) 1095018334Speter tem = XEXP (XEXP (op0, 0), 0), tem1 = XEXP (XEXP (op0, 0), 1); 1095118334Speter else 1095218334Speter tem = XEXP (op0, 0), tem1 = XEXP (op0, 1); 1095318334Speter 1095418334Speter /* Check for the cases where we simply want the result of the 1095518334Speter earlier test or the opposite of that result. */ 1095690075Sobrien if (code == NE || code == EQ 1095718334Speter || (GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT 1095818334Speter && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT 1095918334Speter && (STORE_FLAG_VALUE 1096018334Speter & (((HOST_WIDE_INT) 1 1096118334Speter << (GET_MODE_BITSIZE (GET_MODE (op0)) - 1)))) 1096290075Sobrien && (code == LT || code == GE))) 1096318334Speter { 1096490075Sobrien enum rtx_code new_code; 1096590075Sobrien if (code == LT || code == NE) 1096690075Sobrien new_code = GET_CODE (op0); 1096790075Sobrien else 1096890075Sobrien new_code = combine_reversed_comparison_code (op0); 1096990075Sobrien 1097090075Sobrien if (new_code != UNKNOWN) 1097190075Sobrien { 1097290075Sobrien code = new_code; 1097390075Sobrien op0 = tem; 1097490075Sobrien op1 = tem1; 1097590075Sobrien continue; 1097690075Sobrien } 1097718334Speter } 1097818334Speter break; 1097918334Speter 1098018334Speter case IOR: 10981117395Skan /* The sign bit of (ior (plus X (const_int -1)) X) is nonzero 1098218334Speter iff X <= 0. */ 1098318334Speter if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 0)) == PLUS 1098418334Speter && XEXP (XEXP (op0, 0), 1) == constm1_rtx 1098518334Speter && rtx_equal_p (XEXP (XEXP (op0, 0), 0), XEXP (op0, 1))) 1098618334Speter { 1098718334Speter op0 = XEXP (op0, 1); 1098818334Speter code = (code == GE ? GT : LE); 1098918334Speter continue; 1099018334Speter } 1099118334Speter break; 1099218334Speter 1099318334Speter case AND: 1099418334Speter /* Convert (and (xshift 1 X) Y) to (and (lshiftrt Y X) 1). This 1099518334Speter will be converted to a ZERO_EXTRACT later. */ 1099618334Speter if (const_op == 0 && equality_comparison_p 1099718334Speter && GET_CODE (XEXP (op0, 0)) == ASHIFT 1099818334Speter && XEXP (XEXP (op0, 0), 0) == const1_rtx) 1099918334Speter { 1100018334Speter op0 = simplify_and_const_int 1100190075Sobrien (op0, mode, gen_rtx_LSHIFTRT (mode, 1100290075Sobrien XEXP (op0, 1), 1100390075Sobrien XEXP (XEXP (op0, 0), 1)), 1100418334Speter (HOST_WIDE_INT) 1); 1100518334Speter continue; 1100618334Speter } 1100718334Speter 1100818334Speter /* If we are comparing (and (lshiftrt X C1) C2) for equality with 1100918334Speter zero and X is a comparison and C1 and C2 describe only bits set 1101018334Speter in STORE_FLAG_VALUE, we can compare with X. */ 1101118334Speter if (const_op == 0 && equality_comparison_p 1101218334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 1101318334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 1101418334Speter && GET_CODE (XEXP (op0, 0)) == LSHIFTRT 1101518334Speter && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT 1101618334Speter && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0 1101718334Speter && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT) 1101818334Speter { 1101918334Speter mask = ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode)) 1102018334Speter << INTVAL (XEXP (XEXP (op0, 0), 1))); 1102190075Sobrien if ((~STORE_FLAG_VALUE & mask) == 0 1102218334Speter && (GET_RTX_CLASS (GET_CODE (XEXP (XEXP (op0, 0), 0))) == '<' 1102318334Speter || ((tem = get_last_value (XEXP (XEXP (op0, 0), 0))) != 0 1102418334Speter && GET_RTX_CLASS (GET_CODE (tem)) == '<'))) 1102518334Speter { 1102618334Speter op0 = XEXP (XEXP (op0, 0), 0); 1102718334Speter continue; 1102818334Speter } 1102918334Speter } 1103018334Speter 1103118334Speter /* If we are doing an equality comparison of an AND of a bit equal 1103218334Speter to the sign bit, replace this with a LT or GE comparison of 1103318334Speter the underlying value. */ 1103418334Speter if (equality_comparison_p 1103518334Speter && const_op == 0 1103618334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 1103718334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 1103818334Speter && ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode)) 1103952284Sobrien == (unsigned HOST_WIDE_INT) 1 << (mode_width - 1))) 1104018334Speter { 1104118334Speter op0 = XEXP (op0, 0); 1104218334Speter code = (code == EQ ? GE : LT); 1104318334Speter continue; 1104418334Speter } 1104518334Speter 1104618334Speter /* If this AND operation is really a ZERO_EXTEND from a narrower 1104718334Speter mode, the constant fits within that mode, and this is either an 1104818334Speter equality or unsigned comparison, try to do this comparison in 1104918334Speter the narrower mode. */ 1105018334Speter if ((equality_comparison_p || unsigned_comparison_p) 1105118334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 1105218334Speter && (i = exact_log2 ((INTVAL (XEXP (op0, 1)) 1105318334Speter & GET_MODE_MASK (mode)) 1105418334Speter + 1)) >= 0 1105518334Speter && const_op >> i == 0 1105618334Speter && (tmode = mode_for_size (i, MODE_INT, 1)) != BLKmode) 1105718334Speter { 1105818334Speter op0 = gen_lowpart_for_combine (tmode, XEXP (op0, 0)); 1105918334Speter continue; 1106018334Speter } 1106150397Sobrien 1106250397Sobrien /* If this is (and:M1 (subreg:M2 X 0) (const_int C1)) where C1 fits 1106350397Sobrien in both M1 and M2 and the SUBREG is either paradoxical or 1106450397Sobrien represents the low part, permute the SUBREG and the AND and 1106550397Sobrien try again. */ 1106650397Sobrien if (GET_CODE (XEXP (op0, 0)) == SUBREG 11067117395Skan /* Require an integral mode, to avoid creating something like 11068117395Skan (AND:SF ...). */ 11069117395Skan && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (XEXP (op0, 0)))) 1107090075Sobrien && (0 1107150397Sobrien#ifdef WORD_REGISTER_OPERATIONS 1107290075Sobrien || ((mode_width 1107390075Sobrien > (GET_MODE_BITSIZE 1107490075Sobrien (GET_MODE (SUBREG_REG (XEXP (op0, 0)))))) 1107590075Sobrien && mode_width <= BITS_PER_WORD) 1107650397Sobrien#endif 1107790075Sobrien || ((mode_width 1107890075Sobrien <= (GET_MODE_BITSIZE 1107990075Sobrien (GET_MODE (SUBREG_REG (XEXP (op0, 0)))))) 1108090075Sobrien && subreg_lowpart_p (XEXP (op0, 0)))) 1108150397Sobrien#ifndef WORD_REGISTER_OPERATIONS 1108250397Sobrien /* It is unsafe to commute the AND into the SUBREG if the SUBREG 1108350397Sobrien is paradoxical and WORD_REGISTER_OPERATIONS is not defined. 1108450397Sobrien As originally written the upper bits have a defined value 1108550397Sobrien due to the AND operation. However, if we commute the AND 1108650397Sobrien inside the SUBREG then they no longer have defined values 1108750397Sobrien and the meaning of the code has been changed. */ 1108850397Sobrien && (GET_MODE_SIZE (GET_MODE (XEXP (op0, 0))) 1108950397Sobrien <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0))))) 1109050397Sobrien#endif 1109150397Sobrien && GET_CODE (XEXP (op0, 1)) == CONST_INT 1109250397Sobrien && mode_width <= HOST_BITS_PER_WIDE_INT 1109350397Sobrien && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0)))) 1109450397Sobrien <= HOST_BITS_PER_WIDE_INT) 1109590075Sobrien && (INTVAL (XEXP (op0, 1)) & ~mask) == 0 1109690075Sobrien && 0 == (~GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0)))) 1109750397Sobrien & INTVAL (XEXP (op0, 1))) 1109852284Sobrien && (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1)) != mask 1109952284Sobrien && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1)) 1110050397Sobrien != GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0)))))) 1110190075Sobrien 1110250397Sobrien { 1110350397Sobrien op0 1110450397Sobrien = gen_lowpart_for_combine 1110550397Sobrien (mode, 1110650397Sobrien gen_binary (AND, GET_MODE (SUBREG_REG (XEXP (op0, 0))), 1110750397Sobrien SUBREG_REG (XEXP (op0, 0)), XEXP (op0, 1))); 1110850397Sobrien continue; 1110950397Sobrien } 1111050397Sobrien 1111190075Sobrien /* Convert (ne (and (lshiftrt (not X)) 1) 0) to 1111290075Sobrien (eq (and (lshiftrt X) 1) 0). */ 1111390075Sobrien if (const_op == 0 && equality_comparison_p 1111490075Sobrien && XEXP (op0, 1) == const1_rtx 1111590075Sobrien && GET_CODE (XEXP (op0, 0)) == LSHIFTRT 1111690075Sobrien && GET_CODE (XEXP (XEXP (op0, 0), 0)) == NOT) 1111790075Sobrien { 1111890075Sobrien op0 = simplify_and_const_int 1111990075Sobrien (op0, mode, 1112090075Sobrien gen_rtx_LSHIFTRT (mode, XEXP (XEXP (XEXP (op0, 0), 0), 0), 1112190075Sobrien XEXP (XEXP (op0, 0), 1)), 1112290075Sobrien (HOST_WIDE_INT) 1); 1112390075Sobrien code = (code == NE ? EQ : NE); 1112490075Sobrien continue; 1112590075Sobrien } 1112618334Speter break; 1112718334Speter 1112818334Speter case ASHIFT: 1112918334Speter /* If we have (compare (ashift FOO N) (const_int C)) and 1113018334Speter the high order N bits of FOO (N+1 if an inequality comparison) 1113118334Speter are known to be zero, we can do this by comparing FOO with C 1113218334Speter shifted right N bits so long as the low-order N bits of C are 1113318334Speter zero. */ 1113418334Speter if (GET_CODE (XEXP (op0, 1)) == CONST_INT 1113518334Speter && INTVAL (XEXP (op0, 1)) >= 0 1113618334Speter && ((INTVAL (XEXP (op0, 1)) + ! equality_comparison_p) 1113718334Speter < HOST_BITS_PER_WIDE_INT) 1113818334Speter && ((const_op 1113918334Speter & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0) 1114018334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 1114118334Speter && (nonzero_bits (XEXP (op0, 0), mode) 1114290075Sobrien & ~(mask >> (INTVAL (XEXP (op0, 1)) 1114390075Sobrien + ! equality_comparison_p))) == 0) 1114418334Speter { 1114590075Sobrien /* We must perform a logical shift, not an arithmetic one, 1114690075Sobrien as we want the top N bits of C to be zero. */ 1114790075Sobrien unsigned HOST_WIDE_INT temp = const_op & GET_MODE_MASK (mode); 1114890075Sobrien 1114990075Sobrien temp >>= INTVAL (XEXP (op0, 1)); 11150117395Skan op1 = gen_int_mode (temp, mode); 1115118334Speter op0 = XEXP (op0, 0); 1115218334Speter continue; 1115318334Speter } 1115418334Speter 1115518334Speter /* If we are doing a sign bit comparison, it means we are testing 1115618334Speter a particular bit. Convert it to the appropriate AND. */ 1115718334Speter if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT 1115818334Speter && mode_width <= HOST_BITS_PER_WIDE_INT) 1115918334Speter { 1116018334Speter op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0), 1116118334Speter ((HOST_WIDE_INT) 1 1116218334Speter << (mode_width - 1 1116318334Speter - INTVAL (XEXP (op0, 1))))); 1116418334Speter code = (code == LT ? NE : EQ); 1116518334Speter continue; 1116618334Speter } 1116718334Speter 1116818334Speter /* If this an equality comparison with zero and we are shifting 1116918334Speter the low bit to the sign bit, we can convert this to an AND of the 1117018334Speter low-order bit. */ 1117118334Speter if (const_op == 0 && equality_comparison_p 1117218334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 11173117395Skan && (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1)) 11174117395Skan == mode_width - 1) 1117518334Speter { 1117618334Speter op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0), 1117718334Speter (HOST_WIDE_INT) 1); 1117818334Speter continue; 1117918334Speter } 1118018334Speter break; 1118118334Speter 1118218334Speter case ASHIFTRT: 1118318334Speter /* If this is an equality comparison with zero, we can do this 1118418334Speter as a logical shift, which might be much simpler. */ 1118518334Speter if (equality_comparison_p && const_op == 0 1118618334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT) 1118718334Speter { 1118818334Speter op0 = simplify_shift_const (NULL_RTX, LSHIFTRT, mode, 1118918334Speter XEXP (op0, 0), 1119018334Speter INTVAL (XEXP (op0, 1))); 1119118334Speter continue; 1119218334Speter } 1119318334Speter 1119418334Speter /* If OP0 is a sign extension and CODE is not an unsigned comparison, 1119518334Speter do the comparison in a narrower mode. */ 1119618334Speter if (! unsigned_comparison_p 1119718334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 1119818334Speter && GET_CODE (XEXP (op0, 0)) == ASHIFT 1119918334Speter && XEXP (op0, 1) == XEXP (XEXP (op0, 0), 1) 1120018334Speter && (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)), 1120118334Speter MODE_INT, 1)) != BLKmode 1120296263Sobrien && (((unsigned HOST_WIDE_INT) const_op 1120396263Sobrien + (GET_MODE_MASK (tmode) >> 1) + 1) 1120496263Sobrien <= GET_MODE_MASK (tmode))) 1120518334Speter { 1120618334Speter op0 = gen_lowpart_for_combine (tmode, XEXP (XEXP (op0, 0), 0)); 1120718334Speter continue; 1120818334Speter } 1120918334Speter 1121090075Sobrien /* Likewise if OP0 is a PLUS of a sign extension with a 1121190075Sobrien constant, which is usually represented with the PLUS 1121290075Sobrien between the shifts. */ 1121390075Sobrien if (! unsigned_comparison_p 1121490075Sobrien && GET_CODE (XEXP (op0, 1)) == CONST_INT 1121590075Sobrien && GET_CODE (XEXP (op0, 0)) == PLUS 1121690075Sobrien && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT 1121790075Sobrien && GET_CODE (XEXP (XEXP (op0, 0), 0)) == ASHIFT 1121890075Sobrien && XEXP (op0, 1) == XEXP (XEXP (XEXP (op0, 0), 0), 1) 1121990075Sobrien && (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)), 1122090075Sobrien MODE_INT, 1)) != BLKmode 1122196263Sobrien && (((unsigned HOST_WIDE_INT) const_op 1122296263Sobrien + (GET_MODE_MASK (tmode) >> 1) + 1) 1122396263Sobrien <= GET_MODE_MASK (tmode))) 1122490075Sobrien { 1122590075Sobrien rtx inner = XEXP (XEXP (XEXP (op0, 0), 0), 0); 1122690075Sobrien rtx add_const = XEXP (XEXP (op0, 0), 1); 1122790075Sobrien rtx new_const = gen_binary (ASHIFTRT, GET_MODE (op0), add_const, 1122890075Sobrien XEXP (op0, 1)); 1122990075Sobrien 1123090075Sobrien op0 = gen_binary (PLUS, tmode, 1123190075Sobrien gen_lowpart_for_combine (tmode, inner), 1123290075Sobrien new_const); 1123390075Sobrien continue; 1123490075Sobrien } 1123590075Sobrien 1123650397Sobrien /* ... fall through ... */ 1123718334Speter case LSHIFTRT: 1123818334Speter /* If we have (compare (xshiftrt FOO N) (const_int C)) and 1123918334Speter the low order N bits of FOO are known to be zero, we can do this 1124018334Speter by comparing FOO with C shifted left N bits so long as no 1124118334Speter overflow occurs. */ 1124218334Speter if (GET_CODE (XEXP (op0, 1)) == CONST_INT 1124318334Speter && INTVAL (XEXP (op0, 1)) >= 0 1124418334Speter && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT 1124518334Speter && mode_width <= HOST_BITS_PER_WIDE_INT 1124618334Speter && (nonzero_bits (XEXP (op0, 0), mode) 1124718334Speter & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0 1124896263Sobrien && (((unsigned HOST_WIDE_INT) const_op 1124996263Sobrien + (GET_CODE (op0) != LSHIFTRT 1125096263Sobrien ? ((GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1)) >> 1) 1125196263Sobrien + 1) 1125296263Sobrien : 0)) 1125396263Sobrien <= GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1)))) 1125418334Speter { 1125596263Sobrien /* If the shift was logical, then we must make the condition 1125696263Sobrien unsigned. */ 1125796263Sobrien if (GET_CODE (op0) == LSHIFTRT) 1125896263Sobrien code = unsigned_condition (code); 1125996263Sobrien 1126018334Speter const_op <<= INTVAL (XEXP (op0, 1)); 1126118334Speter op1 = GEN_INT (const_op); 1126218334Speter op0 = XEXP (op0, 0); 1126318334Speter continue; 1126418334Speter } 1126518334Speter 1126618334Speter /* If we are using this shift to extract just the sign bit, we 1126718334Speter can replace this with an LT or GE comparison. */ 1126818334Speter if (const_op == 0 1126918334Speter && (equality_comparison_p || sign_bit_comparison_p) 1127018334Speter && GET_CODE (XEXP (op0, 1)) == CONST_INT 11271117395Skan && (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1)) 11272117395Skan == mode_width - 1) 1127318334Speter { 1127418334Speter op0 = XEXP (op0, 0); 1127518334Speter code = (code == NE || code == GT ? LT : GE); 1127618334Speter continue; 1127718334Speter } 1127818334Speter break; 1127990075Sobrien 1128050397Sobrien default: 1128150397Sobrien break; 1128218334Speter } 1128318334Speter 1128418334Speter break; 1128518334Speter } 1128618334Speter 1128718334Speter /* Now make any compound operations involved in this comparison. Then, 1128850397Sobrien check for an outmost SUBREG on OP0 that is not doing anything or is 1128996263Sobrien paradoxical. The latter transformation must only be performed when 1129096263Sobrien it is known that the "extra" bits will be the same in op0 and op1 or 1129196263Sobrien that they don't matter. There are three cases to consider: 1129218334Speter 1129396263Sobrien 1. SUBREG_REG (op0) is a register. In this case the bits are don't 1129496263Sobrien care bits and we can assume they have any convenient value. So 1129596263Sobrien making the transformation is safe. 1129696263Sobrien 1129796263Sobrien 2. SUBREG_REG (op0) is a memory and LOAD_EXTEND_OP is not defined. 1129896263Sobrien In this case the upper bits of op0 are undefined. We should not make 1129996263Sobrien the simplification in that case as we do not know the contents of 1130096263Sobrien those bits. 1130196263Sobrien 1130296263Sobrien 3. SUBREG_REG (op0) is a memory and LOAD_EXTEND_OP is defined and not 1130396263Sobrien NIL. In that case we know those bits are zeros or ones. We must 1130496263Sobrien also be sure that they are the same as the upper bits of op1. 1130596263Sobrien 1130696263Sobrien We can never remove a SUBREG for a non-equality comparison because 1130796263Sobrien the sign bit is in a different place in the underlying object. */ 1130896263Sobrien 1130918334Speter op0 = make_compound_operation (op0, op1 == const0_rtx ? COMPARE : SET); 1131018334Speter op1 = make_compound_operation (op1, SET); 1131118334Speter 1131218334Speter if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0) 1131396263Sobrien /* Case 3 above, to sometimes allow (subreg (mem x)), isn't 1131496263Sobrien implemented. */ 1131596263Sobrien && GET_CODE (SUBREG_REG (op0)) == REG 1131618334Speter && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT 1131790075Sobrien && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT 1131896263Sobrien && (code == NE || code == EQ)) 1131918334Speter { 1132096263Sobrien if (GET_MODE_SIZE (GET_MODE (op0)) 1132196263Sobrien > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))) 1132296263Sobrien { 1132396263Sobrien op0 = SUBREG_REG (op0); 1132496263Sobrien op1 = gen_lowpart_for_combine (GET_MODE (op0), op1); 1132596263Sobrien } 1132696263Sobrien else if ((GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) 1132796263Sobrien <= HOST_BITS_PER_WIDE_INT) 1132896263Sobrien && (nonzero_bits (SUBREG_REG (op0), 1132996263Sobrien GET_MODE (SUBREG_REG (op0))) 1133096263Sobrien & ~GET_MODE_MASK (GET_MODE (op0))) == 0) 1133196263Sobrien { 1133296263Sobrien tem = gen_lowpart_for_combine (GET_MODE (SUBREG_REG (op0)), op1); 1133396263Sobrien 1133496263Sobrien if ((nonzero_bits (tem, GET_MODE (SUBREG_REG (op0))) 1133596263Sobrien & ~GET_MODE_MASK (GET_MODE (op0))) == 0) 1133696263Sobrien op0 = SUBREG_REG (op0), op1 = tem; 1133796263Sobrien } 1133818334Speter } 1133918334Speter 1134018334Speter /* We now do the opposite procedure: Some machines don't have compare 1134118334Speter insns in all modes. If OP0's mode is an integer mode smaller than a 1134218334Speter word and we can't do a compare in that mode, see if there is a larger 1134318334Speter mode for which we can do the compare. There are a number of cases in 1134418334Speter which we can use the wider mode. */ 1134518334Speter 1134618334Speter mode = GET_MODE (op0); 1134718334Speter if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT 1134818334Speter && GET_MODE_SIZE (mode) < UNITS_PER_WORD 1134990075Sobrien && ! have_insn_for (COMPARE, mode)) 1135018334Speter for (tmode = GET_MODE_WIDER_MODE (mode); 1135118334Speter (tmode != VOIDmode 1135218334Speter && GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT); 1135318334Speter tmode = GET_MODE_WIDER_MODE (tmode)) 1135490075Sobrien if (have_insn_for (COMPARE, tmode)) 1135518334Speter { 1135696263Sobrien int zero_extended; 1135796263Sobrien 1135818334Speter /* If the only nonzero bits in OP0 and OP1 are those in the 1135918334Speter narrower mode and this is an equality or unsigned comparison, 1136018334Speter we can use the wider mode. Similarly for sign-extended 1136118334Speter values, in which case it is true for all comparisons. */ 1136296263Sobrien zero_extended = ((code == EQ || code == NE 1136396263Sobrien || code == GEU || code == GTU 1136496263Sobrien || code == LEU || code == LTU) 1136596263Sobrien && (nonzero_bits (op0, tmode) 1136696263Sobrien & ~GET_MODE_MASK (mode)) == 0 1136796263Sobrien && ((GET_CODE (op1) == CONST_INT 1136896263Sobrien || (nonzero_bits (op1, tmode) 1136996263Sobrien & ~GET_MODE_MASK (mode)) == 0))); 1137096263Sobrien 1137196263Sobrien if (zero_extended 1137218334Speter || ((num_sign_bit_copies (op0, tmode) 11373117395Skan > (unsigned int) (GET_MODE_BITSIZE (tmode) 11374117395Skan - GET_MODE_BITSIZE (mode))) 1137518334Speter && (num_sign_bit_copies (op1, tmode) 11376117395Skan > (unsigned int) (GET_MODE_BITSIZE (tmode) 11377117395Skan - GET_MODE_BITSIZE (mode))))) 1137818334Speter { 1137990075Sobrien /* If OP0 is an AND and we don't have an AND in MODE either, 1138090075Sobrien make a new AND in the proper mode. */ 1138190075Sobrien if (GET_CODE (op0) == AND 1138290075Sobrien && !have_insn_for (AND, mode)) 1138390075Sobrien op0 = gen_binary (AND, tmode, 1138490075Sobrien gen_lowpart_for_combine (tmode, 1138590075Sobrien XEXP (op0, 0)), 1138690075Sobrien gen_lowpart_for_combine (tmode, 1138790075Sobrien XEXP (op0, 1))); 1138890075Sobrien 1138918334Speter op0 = gen_lowpart_for_combine (tmode, op0); 1139096263Sobrien if (zero_extended && GET_CODE (op1) == CONST_INT) 1139196263Sobrien op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (mode)); 1139218334Speter op1 = gen_lowpart_for_combine (tmode, op1); 1139318334Speter break; 1139418334Speter } 1139518334Speter 1139618334Speter /* If this is a test for negative, we can make an explicit 1139718334Speter test of the sign bit. */ 1139818334Speter 1139918334Speter if (op1 == const0_rtx && (code == LT || code == GE) 1140018334Speter && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) 1140118334Speter { 1140218334Speter op0 = gen_binary (AND, tmode, 1140318334Speter gen_lowpart_for_combine (tmode, op0), 1140418334Speter GEN_INT ((HOST_WIDE_INT) 1 1140518334Speter << (GET_MODE_BITSIZE (mode) - 1))); 1140618334Speter code = (code == LT) ? NE : EQ; 1140718334Speter break; 1140818334Speter } 1140918334Speter } 1141018334Speter 1141118334Speter#ifdef CANONICALIZE_COMPARISON 1141218334Speter /* If this machine only supports a subset of valid comparisons, see if we 1141318334Speter can convert an unsupported one into a supported one. */ 1141418334Speter CANONICALIZE_COMPARISON (code, op0, op1); 1141518334Speter#endif 1141618334Speter 1141718334Speter *pop0 = op0; 1141818334Speter *pop1 = op1; 1141918334Speter 1142018334Speter return code; 1142118334Speter} 1142218334Speter 1142390075Sobrien/* Like jump.c' reversed_comparison_code, but use combine infrastructure for 1142490075Sobrien searching backward. */ 1142590075Sobrienstatic enum rtx_code 1142690075Sobriencombine_reversed_comparison_code (exp) 1142790075Sobrien rtx exp; 1142818334Speter{ 1142990075Sobrien enum rtx_code code1 = reversed_comparison_code (exp, NULL); 1143090075Sobrien rtx x; 1143118334Speter 1143290075Sobrien if (code1 != UNKNOWN 1143390075Sobrien || GET_MODE_CLASS (GET_MODE (XEXP (exp, 0))) != MODE_CC) 1143490075Sobrien return code1; 1143590075Sobrien /* Otherwise try and find where the condition codes were last set and 1143690075Sobrien use that. */ 1143790075Sobrien x = get_last_value (XEXP (exp, 0)); 1143890075Sobrien if (!x || GET_CODE (x) != COMPARE) 1143990075Sobrien return UNKNOWN; 1144090075Sobrien return reversed_comparison_code_parts (GET_CODE (exp), 1144190075Sobrien XEXP (x, 0), XEXP (x, 1), NULL); 1144218334Speter} 1144390075Sobrien/* Return comparison with reversed code of EXP and operands OP0 and OP1. 1144490075Sobrien Return NULL_RTX in case we fail to do the reversal. */ 1144590075Sobrienstatic rtx 1144690075Sobrienreversed_comparison (exp, mode, op0, op1) 1144790075Sobrien rtx exp, op0, op1; 1144890075Sobrien enum machine_mode mode; 1144990075Sobrien{ 1145090075Sobrien enum rtx_code reversed_code = combine_reversed_comparison_code (exp); 1145190075Sobrien if (reversed_code == UNKNOWN) 1145290075Sobrien return NULL_RTX; 1145390075Sobrien else 1145490075Sobrien return gen_binary (reversed_code, mode, op0, op1); 1145590075Sobrien} 1145618334Speter 1145718334Speter/* Utility function for following routine. Called when X is part of a value 1145818334Speter being stored into reg_last_set_value. Sets reg_last_set_table_tick 1145918334Speter for each register mentioned. Similar to mention_regs in cse.c */ 1146018334Speter 1146118334Speterstatic void 1146218334Speterupdate_table_tick (x) 1146318334Speter rtx x; 1146418334Speter{ 1146590075Sobrien enum rtx_code code = GET_CODE (x); 1146690075Sobrien const char *fmt = GET_RTX_FORMAT (code); 1146790075Sobrien int i; 1146818334Speter 1146918334Speter if (code == REG) 1147018334Speter { 1147190075Sobrien unsigned int regno = REGNO (x); 1147290075Sobrien unsigned int endregno 1147390075Sobrien = regno + (regno < FIRST_PSEUDO_REGISTER 1147490075Sobrien ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1); 1147590075Sobrien unsigned int r; 1147618334Speter 1147790075Sobrien for (r = regno; r < endregno; r++) 1147890075Sobrien reg_last_set_table_tick[r] = label_tick; 1147918334Speter 1148018334Speter return; 1148118334Speter } 1148290075Sobrien 1148318334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 1148418334Speter /* Note that we can't have an "E" in values stored; see 1148518334Speter get_last_value_validate. */ 1148618334Speter if (fmt[i] == 'e') 11487117395Skan { 11488117395Skan /* Check for identical subexpressions. If x contains 11489117395Skan identical subexpression we only have to traverse one of 11490117395Skan them. */ 11491117395Skan if (i == 0 11492117395Skan && (GET_RTX_CLASS (code) == '2' 11493117395Skan || GET_RTX_CLASS (code) == 'c')) 11494117395Skan { 11495117395Skan /* Note that at this point x1 has already been 11496117395Skan processed. */ 11497117395Skan rtx x0 = XEXP (x, 0); 11498117395Skan rtx x1 = XEXP (x, 1); 11499117395Skan 11500117395Skan /* If x0 and x1 are identical then there is no need to 11501117395Skan process x0. */ 11502117395Skan if (x0 == x1) 11503117395Skan break; 11504117395Skan 11505117395Skan /* If x0 is identical to a subexpression of x1 then while 11506117395Skan processing x1, x0 has already been processed. Thus we 11507117395Skan are done with x. */ 11508117395Skan if ((GET_RTX_CLASS (GET_CODE (x1)) == '2' 11509117395Skan || GET_RTX_CLASS (GET_CODE (x1)) == 'c') 11510117395Skan && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1))) 11511117395Skan break; 11512117395Skan 11513117395Skan /* If x1 is identical to a subexpression of x0 then we 11514117395Skan still have to process the rest of x0. */ 11515117395Skan if ((GET_RTX_CLASS (GET_CODE (x0)) == '2' 11516117395Skan || GET_RTX_CLASS (GET_CODE (x0)) == 'c') 11517117395Skan && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1))) 11518117395Skan { 11519117395Skan update_table_tick (XEXP (x0, x1 == XEXP (x0, 0) ? 1 : 0)); 11520117395Skan break; 11521117395Skan } 11522117395Skan } 11523117395Skan 11524117395Skan update_table_tick (XEXP (x, i)); 11525117395Skan } 1152618334Speter} 1152718334Speter 1152818334Speter/* Record that REG is set to VALUE in insn INSN. If VALUE is zero, we 1152918334Speter are saying that the register is clobbered and we no longer know its 1153018334Speter value. If INSN is zero, don't update reg_last_set; this is only permitted 1153118334Speter with VALUE also zero and is used to invalidate the register. */ 1153218334Speter 1153318334Speterstatic void 1153418334Speterrecord_value_for_reg (reg, insn, value) 1153518334Speter rtx reg; 1153618334Speter rtx insn; 1153718334Speter rtx value; 1153818334Speter{ 1153990075Sobrien unsigned int regno = REGNO (reg); 1154090075Sobrien unsigned int endregno 1154190075Sobrien = regno + (regno < FIRST_PSEUDO_REGISTER 1154290075Sobrien ? HARD_REGNO_NREGS (regno, GET_MODE (reg)) : 1); 1154390075Sobrien unsigned int i; 1154418334Speter 1154518334Speter /* If VALUE contains REG and we have a previous value for REG, substitute 1154618334Speter the previous value. */ 1154718334Speter if (value && insn && reg_overlap_mentioned_p (reg, value)) 1154818334Speter { 1154918334Speter rtx tem; 1155018334Speter 1155118334Speter /* Set things up so get_last_value is allowed to see anything set up to 1155218334Speter our insn. */ 1155318334Speter subst_low_cuid = INSN_CUID (insn); 1155490075Sobrien tem = get_last_value (reg); 1155518334Speter 1155690075Sobrien /* If TEM is simply a binary operation with two CLOBBERs as operands, 1155790075Sobrien it isn't going to be useful and will take a lot of time to process, 1155890075Sobrien so just use the CLOBBER. */ 1155990075Sobrien 1156018334Speter if (tem) 1156190075Sobrien { 1156290075Sobrien if ((GET_RTX_CLASS (GET_CODE (tem)) == '2' 1156390075Sobrien || GET_RTX_CLASS (GET_CODE (tem)) == 'c') 1156490075Sobrien && GET_CODE (XEXP (tem, 0)) == CLOBBER 1156590075Sobrien && GET_CODE (XEXP (tem, 1)) == CLOBBER) 1156690075Sobrien tem = XEXP (tem, 0); 1156790075Sobrien 1156890075Sobrien value = replace_rtx (copy_rtx (value), reg, tem); 1156990075Sobrien } 1157018334Speter } 1157118334Speter 1157218334Speter /* For each register modified, show we don't know its value, that 1157318334Speter we don't know about its bitwise content, that its value has been 1157418334Speter updated, and that we don't know the location of the death of the 1157518334Speter register. */ 1157690075Sobrien for (i = regno; i < endregno; i++) 1157718334Speter { 1157818334Speter if (insn) 1157918334Speter reg_last_set[i] = insn; 1158090075Sobrien 1158118334Speter reg_last_set_value[i] = 0; 1158218334Speter reg_last_set_mode[i] = 0; 1158318334Speter reg_last_set_nonzero_bits[i] = 0; 1158418334Speter reg_last_set_sign_bit_copies[i] = 0; 1158518334Speter reg_last_death[i] = 0; 1158618334Speter } 1158718334Speter 1158818334Speter /* Mark registers that are being referenced in this value. */ 1158918334Speter if (value) 1159018334Speter update_table_tick (value); 1159118334Speter 1159218334Speter /* Now update the status of each register being set. 1159318334Speter If someone is using this register in this block, set this register 1159418334Speter to invalid since we will get confused between the two lives in this 1159518334Speter basic block. This makes using this register always invalid. In cse, we 1159618334Speter scan the table to invalidate all entries using this register, but this 1159718334Speter is too much work for us. */ 1159818334Speter 1159918334Speter for (i = regno; i < endregno; i++) 1160018334Speter { 1160118334Speter reg_last_set_label[i] = label_tick; 1160218334Speter if (value && reg_last_set_table_tick[i] == label_tick) 1160318334Speter reg_last_set_invalid[i] = 1; 1160418334Speter else 1160518334Speter reg_last_set_invalid[i] = 0; 1160618334Speter } 1160718334Speter 1160818334Speter /* The value being assigned might refer to X (like in "x++;"). In that 1160918334Speter case, we must replace it with (clobber (const_int 0)) to prevent 1161018334Speter infinite loops. */ 1161150397Sobrien if (value && ! get_last_value_validate (&value, insn, 1161218334Speter reg_last_set_label[regno], 0)) 1161318334Speter { 1161418334Speter value = copy_rtx (value); 1161550397Sobrien if (! get_last_value_validate (&value, insn, 1161650397Sobrien reg_last_set_label[regno], 1)) 1161718334Speter value = 0; 1161818334Speter } 1161918334Speter 1162018334Speter /* For the main register being modified, update the value, the mode, the 1162118334Speter nonzero bits, and the number of sign bit copies. */ 1162218334Speter 1162318334Speter reg_last_set_value[regno] = value; 1162418334Speter 1162518334Speter if (value) 1162618334Speter { 1162796263Sobrien enum machine_mode mode = GET_MODE (reg); 1162818334Speter subst_low_cuid = INSN_CUID (insn); 1162996263Sobrien reg_last_set_mode[regno] = mode; 1163096263Sobrien if (GET_MODE_CLASS (mode) == MODE_INT 1163196263Sobrien && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) 1163296263Sobrien mode = nonzero_bits_mode; 1163396263Sobrien reg_last_set_nonzero_bits[regno] = nonzero_bits (value, mode); 1163418334Speter reg_last_set_sign_bit_copies[regno] 1163518334Speter = num_sign_bit_copies (value, GET_MODE (reg)); 1163618334Speter } 1163718334Speter} 1163818334Speter 1163918334Speter/* Called via note_stores from record_dead_and_set_regs to handle one 1164090075Sobrien SET or CLOBBER in an insn. DATA is the instruction in which the 1164190075Sobrien set is occurring. */ 1164218334Speter 1164318334Speterstatic void 1164490075Sobrienrecord_dead_and_set_regs_1 (dest, setter, data) 1164518334Speter rtx dest, setter; 1164690075Sobrien void *data; 1164718334Speter{ 1164890075Sobrien rtx record_dead_insn = (rtx) data; 1164990075Sobrien 1165018334Speter if (GET_CODE (dest) == SUBREG) 1165118334Speter dest = SUBREG_REG (dest); 1165218334Speter 1165318334Speter if (GET_CODE (dest) == REG) 1165418334Speter { 1165518334Speter /* If we are setting the whole register, we know its value. Otherwise 1165618334Speter show that we don't know the value. We can handle SUBREG in 1165718334Speter some cases. */ 1165818334Speter if (GET_CODE (setter) == SET && dest == SET_DEST (setter)) 1165918334Speter record_value_for_reg (dest, record_dead_insn, SET_SRC (setter)); 1166018334Speter else if (GET_CODE (setter) == SET 1166118334Speter && GET_CODE (SET_DEST (setter)) == SUBREG 1166218334Speter && SUBREG_REG (SET_DEST (setter)) == dest 1166318334Speter && GET_MODE_BITSIZE (GET_MODE (dest)) <= BITS_PER_WORD 1166418334Speter && subreg_lowpart_p (SET_DEST (setter))) 1166518334Speter record_value_for_reg (dest, record_dead_insn, 1166618334Speter gen_lowpart_for_combine (GET_MODE (dest), 1166718334Speter SET_SRC (setter))); 1166818334Speter else 1166918334Speter record_value_for_reg (dest, record_dead_insn, NULL_RTX); 1167018334Speter } 1167118334Speter else if (GET_CODE (dest) == MEM 1167218334Speter /* Ignore pushes, they clobber nothing. */ 1167318334Speter && ! push_operand (dest, GET_MODE (dest))) 1167418334Speter mem_last_set = INSN_CUID (record_dead_insn); 1167518334Speter} 1167618334Speter 1167718334Speter/* Update the records of when each REG was most recently set or killed 1167818334Speter for the things done by INSN. This is the last thing done in processing 1167918334Speter INSN in the combiner loop. 1168018334Speter 1168118334Speter We update reg_last_set, reg_last_set_value, reg_last_set_mode, 1168218334Speter reg_last_set_nonzero_bits, reg_last_set_sign_bit_copies, reg_last_death, 1168318334Speter and also the similar information mem_last_set (which insn most recently 1168418334Speter modified memory) and last_call_cuid (which insn was the most recent 1168518334Speter subroutine call). */ 1168618334Speter 1168718334Speterstatic void 1168818334Speterrecord_dead_and_set_regs (insn) 1168918334Speter rtx insn; 1169018334Speter{ 1169190075Sobrien rtx link; 1169290075Sobrien unsigned int i; 1169318334Speter 1169418334Speter for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) 1169518334Speter { 1169618334Speter if (REG_NOTE_KIND (link) == REG_DEAD 1169718334Speter && GET_CODE (XEXP (link, 0)) == REG) 1169818334Speter { 1169990075Sobrien unsigned int regno = REGNO (XEXP (link, 0)); 1170090075Sobrien unsigned int endregno 1170118334Speter = regno + (regno < FIRST_PSEUDO_REGISTER 1170218334Speter ? HARD_REGNO_NREGS (regno, GET_MODE (XEXP (link, 0))) 1170318334Speter : 1); 1170418334Speter 1170518334Speter for (i = regno; i < endregno; i++) 1170618334Speter reg_last_death[i] = insn; 1170718334Speter } 1170818334Speter else if (REG_NOTE_KIND (link) == REG_INC) 1170918334Speter record_value_for_reg (XEXP (link, 0), insn, NULL_RTX); 1171018334Speter } 1171118334Speter 1171218334Speter if (GET_CODE (insn) == CALL_INSN) 1171318334Speter { 1171418334Speter for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 1171590075Sobrien if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i)) 1171618334Speter { 1171718334Speter reg_last_set_value[i] = 0; 1171818334Speter reg_last_set_mode[i] = 0; 1171918334Speter reg_last_set_nonzero_bits[i] = 0; 1172018334Speter reg_last_set_sign_bit_copies[i] = 0; 1172118334Speter reg_last_death[i] = 0; 1172218334Speter } 1172318334Speter 1172418334Speter last_call_cuid = mem_last_set = INSN_CUID (insn); 1172590075Sobrien 1172690075Sobrien /* Don't bother recording what this insn does. It might set the 1172790075Sobrien return value register, but we can't combine into a call 1172890075Sobrien pattern anyway, so there's no point trying (and it may cause 1172990075Sobrien a crash, if e.g. we wind up asking for last_set_value of a 1173090075Sobrien SUBREG of the return value register). */ 1173190075Sobrien return; 1173218334Speter } 1173318334Speter 1173490075Sobrien note_stores (PATTERN (insn), record_dead_and_set_regs_1, insn); 1173518334Speter} 1173690075Sobrien 1173790075Sobrien/* If a SUBREG has the promoted bit set, it is in fact a property of the 1173890075Sobrien register present in the SUBREG, so for each such SUBREG go back and 1173990075Sobrien adjust nonzero and sign bit information of the registers that are 1174090075Sobrien known to have some zero/sign bits set. 1174190075Sobrien 1174290075Sobrien This is needed because when combine blows the SUBREGs away, the 1174390075Sobrien information on zero/sign bits is lost and further combines can be 1174490075Sobrien missed because of that. */ 1174590075Sobrien 1174690075Sobrienstatic void 1174790075Sobrienrecord_promoted_value (insn, subreg) 1174890075Sobrien rtx insn; 1174990075Sobrien rtx subreg; 1175090075Sobrien{ 1175190075Sobrien rtx links, set; 1175290075Sobrien unsigned int regno = REGNO (SUBREG_REG (subreg)); 1175390075Sobrien enum machine_mode mode = GET_MODE (subreg); 1175490075Sobrien 1175590075Sobrien if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT) 1175690075Sobrien return; 1175790075Sobrien 1175890075Sobrien for (links = LOG_LINKS (insn); links;) 1175990075Sobrien { 1176090075Sobrien insn = XEXP (links, 0); 1176190075Sobrien set = single_set (insn); 1176290075Sobrien 1176390075Sobrien if (! set || GET_CODE (SET_DEST (set)) != REG 1176490075Sobrien || REGNO (SET_DEST (set)) != regno 1176590075Sobrien || GET_MODE (SET_DEST (set)) != GET_MODE (SUBREG_REG (subreg))) 1176690075Sobrien { 1176790075Sobrien links = XEXP (links, 1); 1176890075Sobrien continue; 1176990075Sobrien } 1177090075Sobrien 1177190075Sobrien if (reg_last_set[regno] == insn) 1177290075Sobrien { 11773117395Skan if (SUBREG_PROMOTED_UNSIGNED_P (subreg) > 0) 1177490075Sobrien reg_last_set_nonzero_bits[regno] &= GET_MODE_MASK (mode); 1177590075Sobrien } 1177690075Sobrien 1177790075Sobrien if (GET_CODE (SET_SRC (set)) == REG) 1177890075Sobrien { 1177990075Sobrien regno = REGNO (SET_SRC (set)); 1178090075Sobrien links = LOG_LINKS (insn); 1178190075Sobrien } 1178290075Sobrien else 1178390075Sobrien break; 1178490075Sobrien } 1178590075Sobrien} 1178690075Sobrien 1178790075Sobrien/* Scan X for promoted SUBREGs. For each one found, 1178890075Sobrien note what it implies to the registers used in it. */ 1178990075Sobrien 1179090075Sobrienstatic void 1179190075Sobriencheck_promoted_subreg (insn, x) 1179290075Sobrien rtx insn; 1179390075Sobrien rtx x; 1179490075Sobrien{ 1179590075Sobrien if (GET_CODE (x) == SUBREG && SUBREG_PROMOTED_VAR_P (x) 1179690075Sobrien && GET_CODE (SUBREG_REG (x)) == REG) 1179790075Sobrien record_promoted_value (insn, x); 1179890075Sobrien else 1179990075Sobrien { 1180090075Sobrien const char *format = GET_RTX_FORMAT (GET_CODE (x)); 1180190075Sobrien int i, j; 1180290075Sobrien 1180390075Sobrien for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++) 1180490075Sobrien switch (format[i]) 1180590075Sobrien { 1180690075Sobrien case 'e': 1180790075Sobrien check_promoted_subreg (insn, XEXP (x, i)); 1180890075Sobrien break; 1180990075Sobrien case 'V': 1181090075Sobrien case 'E': 1181190075Sobrien if (XVEC (x, i) != 0) 1181290075Sobrien for (j = 0; j < XVECLEN (x, i); j++) 1181390075Sobrien check_promoted_subreg (insn, XVECEXP (x, i, j)); 1181490075Sobrien break; 1181590075Sobrien } 1181690075Sobrien } 1181790075Sobrien} 1181818334Speter 1181918334Speter/* Utility routine for the following function. Verify that all the registers 1182018334Speter mentioned in *LOC are valid when *LOC was part of a value set when 1182118334Speter label_tick == TICK. Return 0 if some are not. 1182218334Speter 11823117395Skan If REPLACE is nonzero, replace the invalid reference with 1182418334Speter (clobber (const_int 0)) and return 1. This replacement is useful because 1182518334Speter we often can get useful information about the form of a value (e.g., if 1182618334Speter it was produced by a shift that always produces -1 or 0) even though 1182718334Speter we don't know exactly what registers it was produced from. */ 1182818334Speter 1182918334Speterstatic int 1183050397Sobrienget_last_value_validate (loc, insn, tick, replace) 1183118334Speter rtx *loc; 1183250397Sobrien rtx insn; 1183318334Speter int tick; 1183418334Speter int replace; 1183518334Speter{ 1183618334Speter rtx x = *loc; 1183790075Sobrien const char *fmt = GET_RTX_FORMAT (GET_CODE (x)); 1183818334Speter int len = GET_RTX_LENGTH (GET_CODE (x)); 1183918334Speter int i; 1184018334Speter 1184118334Speter if (GET_CODE (x) == REG) 1184218334Speter { 1184390075Sobrien unsigned int regno = REGNO (x); 1184490075Sobrien unsigned int endregno 1184590075Sobrien = regno + (regno < FIRST_PSEUDO_REGISTER 1184690075Sobrien ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1); 1184790075Sobrien unsigned int j; 1184818334Speter 1184918334Speter for (j = regno; j < endregno; j++) 1185018334Speter if (reg_last_set_invalid[j] 1185190075Sobrien /* If this is a pseudo-register that was only set once and not 1185290075Sobrien live at the beginning of the function, it is always valid. */ 1185390075Sobrien || (! (regno >= FIRST_PSEUDO_REGISTER 1185490075Sobrien && REG_N_SETS (regno) == 1 1185590075Sobrien && (! REGNO_REG_SET_P 11856117395Skan (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, regno))) 1185718334Speter && reg_last_set_label[j] > tick)) 1185818334Speter { 1185918334Speter if (replace) 1186050397Sobrien *loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx); 1186118334Speter return replace; 1186218334Speter } 1186318334Speter 1186418334Speter return 1; 1186518334Speter } 1186650397Sobrien /* If this is a memory reference, make sure that there were 1186750397Sobrien no stores after it that might have clobbered the value. We don't 1186850397Sobrien have alias info, so we assume any store invalidates it. */ 1186950397Sobrien else if (GET_CODE (x) == MEM && ! RTX_UNCHANGING_P (x) 1187050397Sobrien && INSN_CUID (insn) <= mem_last_set) 1187150397Sobrien { 1187250397Sobrien if (replace) 1187350397Sobrien *loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx); 1187450397Sobrien return replace; 1187550397Sobrien } 1187618334Speter 1187718334Speter for (i = 0; i < len; i++) 11878117395Skan { 11879117395Skan if (fmt[i] == 'e') 11880117395Skan { 11881117395Skan /* Check for identical subexpressions. If x contains 11882117395Skan identical subexpression we only have to traverse one of 11883117395Skan them. */ 11884117395Skan if (i == 1 11885117395Skan && (GET_RTX_CLASS (GET_CODE (x)) == '2' 11886117395Skan || GET_RTX_CLASS (GET_CODE (x)) == 'c')) 11887117395Skan { 11888117395Skan /* Note that at this point x0 has already been checked 11889117395Skan and found valid. */ 11890117395Skan rtx x0 = XEXP (x, 0); 11891117395Skan rtx x1 = XEXP (x, 1); 1189218334Speter 11893117395Skan /* If x0 and x1 are identical then x is also valid. */ 11894117395Skan if (x0 == x1) 11895117395Skan return 1; 11896117395Skan 11897117395Skan /* If x1 is identical to a subexpression of x0 then 11898117395Skan while checking x0, x1 has already been checked. Thus 11899117395Skan it is valid and so as x. */ 11900117395Skan if ((GET_RTX_CLASS (GET_CODE (x0)) == '2' 11901117395Skan || GET_RTX_CLASS (GET_CODE (x0)) == 'c') 11902117395Skan && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1))) 11903117395Skan return 1; 11904117395Skan 11905117395Skan /* If x0 is identical to a subexpression of x1 then x is 11906117395Skan valid iff the rest of x1 is valid. */ 11907117395Skan if ((GET_RTX_CLASS (GET_CODE (x1)) == '2' 11908117395Skan || GET_RTX_CLASS (GET_CODE (x1)) == 'c') 11909117395Skan && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1))) 11910117395Skan return 11911117395Skan get_last_value_validate (&XEXP (x1, 11912117395Skan x0 == XEXP (x1, 0) ? 1 : 0), 11913117395Skan insn, tick, replace); 11914117395Skan } 11915117395Skan 11916117395Skan if (get_last_value_validate (&XEXP (x, i), insn, tick, 11917117395Skan replace) == 0) 11918117395Skan return 0; 11919117395Skan } 11920117395Skan /* Don't bother with these. They shouldn't occur anyway. */ 11921117395Skan else if (fmt[i] == 'E') 11922117395Skan return 0; 11923117395Skan } 11924117395Skan 1192518334Speter /* If we haven't found a reason for it to be invalid, it is valid. */ 1192618334Speter return 1; 1192718334Speter} 1192818334Speter 1192918334Speter/* Get the last value assigned to X, if known. Some registers 1193018334Speter in the value may be replaced with (clobber (const_int 0)) if their value 1193118334Speter is known longer known reliably. */ 1193218334Speter 1193318334Speterstatic rtx 1193418334Speterget_last_value (x) 1193518334Speter rtx x; 1193618334Speter{ 1193790075Sobrien unsigned int regno; 1193818334Speter rtx value; 1193918334Speter 1194018334Speter /* If this is a non-paradoxical SUBREG, get the value of its operand and 1194118334Speter then convert it to the desired mode. If this is a paradoxical SUBREG, 1194250397Sobrien we cannot predict what values the "extra" bits might have. */ 1194318334Speter if (GET_CODE (x) == SUBREG 1194418334Speter && subreg_lowpart_p (x) 1194518334Speter && (GET_MODE_SIZE (GET_MODE (x)) 1194618334Speter <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) 1194718334Speter && (value = get_last_value (SUBREG_REG (x))) != 0) 1194818334Speter return gen_lowpart_for_combine (GET_MODE (x), value); 1194918334Speter 1195018334Speter if (GET_CODE (x) != REG) 1195118334Speter return 0; 1195218334Speter 1195318334Speter regno = REGNO (x); 1195418334Speter value = reg_last_set_value[regno]; 1195518334Speter 1195690075Sobrien /* If we don't have a value, or if it isn't for this basic block and 1195790075Sobrien it's either a hard register, set more than once, or it's a live 1195890075Sobrien at the beginning of the function, return 0. 1195918334Speter 1196090075Sobrien Because if it's not live at the beginning of the function then the reg 1196190075Sobrien is always set before being used (is never used without being set). 1196290075Sobrien And, if it's set only once, and it's always set before use, then all 1196390075Sobrien uses must have the same last value, even if it's not from this basic 1196490075Sobrien block. */ 1196590075Sobrien 1196618334Speter if (value == 0 1196790075Sobrien || (reg_last_set_label[regno] != label_tick 1196890075Sobrien && (regno < FIRST_PSEUDO_REGISTER 1196990075Sobrien || REG_N_SETS (regno) != 1 1197090075Sobrien || (REGNO_REG_SET_P 11971117395Skan (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, regno))))) 1197218334Speter return 0; 1197318334Speter 1197418334Speter /* If the value was set in a later insn than the ones we are processing, 1197552750Sobrien we can't use it even if the register was only set once. */ 1197618334Speter if (INSN_CUID (reg_last_set[regno]) >= subst_low_cuid) 1197752750Sobrien return 0; 1197818334Speter 1197918334Speter /* If the value has all its registers valid, return it. */ 1198050397Sobrien if (get_last_value_validate (&value, reg_last_set[regno], 1198150397Sobrien reg_last_set_label[regno], 0)) 1198218334Speter return value; 1198318334Speter 1198418334Speter /* Otherwise, make a copy and replace any invalid register with 1198518334Speter (clobber (const_int 0)). If that fails for some reason, return 0. */ 1198618334Speter 1198718334Speter value = copy_rtx (value); 1198850397Sobrien if (get_last_value_validate (&value, reg_last_set[regno], 1198950397Sobrien reg_last_set_label[regno], 1)) 1199018334Speter return value; 1199118334Speter 1199218334Speter return 0; 1199318334Speter} 1199418334Speter 1199518334Speter/* Return nonzero if expression X refers to a REG or to memory 1199618334Speter that is set in an instruction more recent than FROM_CUID. */ 1199718334Speter 1199818334Speterstatic int 1199918334Speteruse_crosses_set_p (x, from_cuid) 1200090075Sobrien rtx x; 1200118334Speter int from_cuid; 1200218334Speter{ 1200390075Sobrien const char *fmt; 1200490075Sobrien int i; 1200590075Sobrien enum rtx_code code = GET_CODE (x); 1200618334Speter 1200718334Speter if (code == REG) 1200818334Speter { 1200990075Sobrien unsigned int regno = REGNO (x); 1201090075Sobrien unsigned endreg = regno + (regno < FIRST_PSEUDO_REGISTER 1201190075Sobrien ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1); 1201290075Sobrien 1201318334Speter#ifdef PUSH_ROUNDING 1201418334Speter /* Don't allow uses of the stack pointer to be moved, 1201518334Speter because we don't know whether the move crosses a push insn. */ 1201690075Sobrien if (regno == STACK_POINTER_REGNUM && PUSH_ARGS) 1201718334Speter return 1; 1201818334Speter#endif 1201990075Sobrien for (; regno < endreg; regno++) 1202018334Speter if (reg_last_set[regno] 1202118334Speter && INSN_CUID (reg_last_set[regno]) > from_cuid) 1202218334Speter return 1; 1202318334Speter return 0; 1202418334Speter } 1202518334Speter 1202618334Speter if (code == MEM && mem_last_set > from_cuid) 1202718334Speter return 1; 1202818334Speter 1202918334Speter fmt = GET_RTX_FORMAT (code); 1203018334Speter 1203118334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 1203218334Speter { 1203318334Speter if (fmt[i] == 'E') 1203418334Speter { 1203590075Sobrien int j; 1203618334Speter for (j = XVECLEN (x, i) - 1; j >= 0; j--) 1203718334Speter if (use_crosses_set_p (XVECEXP (x, i, j), from_cuid)) 1203818334Speter return 1; 1203918334Speter } 1204018334Speter else if (fmt[i] == 'e' 1204118334Speter && use_crosses_set_p (XEXP (x, i), from_cuid)) 1204218334Speter return 1; 1204318334Speter } 1204418334Speter return 0; 1204518334Speter} 1204618334Speter 1204718334Speter/* Define three variables used for communication between the following 1204818334Speter routines. */ 1204918334Speter 1205090075Sobrienstatic unsigned int reg_dead_regno, reg_dead_endregno; 1205118334Speterstatic int reg_dead_flag; 1205218334Speter 1205318334Speter/* Function called via note_stores from reg_dead_at_p. 1205418334Speter 1205590075Sobrien If DEST is within [reg_dead_regno, reg_dead_endregno), set 1205618334Speter reg_dead_flag to 1 if X is a CLOBBER and to -1 it is a SET. */ 1205718334Speter 1205818334Speterstatic void 1205990075Sobrienreg_dead_at_p_1 (dest, x, data) 1206018334Speter rtx dest; 1206118334Speter rtx x; 1206290075Sobrien void *data ATTRIBUTE_UNUSED; 1206318334Speter{ 1206490075Sobrien unsigned int regno, endregno; 1206518334Speter 1206618334Speter if (GET_CODE (dest) != REG) 1206718334Speter return; 1206818334Speter 1206918334Speter regno = REGNO (dest); 1207090075Sobrien endregno = regno + (regno < FIRST_PSEUDO_REGISTER 1207118334Speter ? HARD_REGNO_NREGS (regno, GET_MODE (dest)) : 1); 1207218334Speter 1207318334Speter if (reg_dead_endregno > regno && reg_dead_regno < endregno) 1207418334Speter reg_dead_flag = (GET_CODE (x) == CLOBBER) ? 1 : -1; 1207518334Speter} 1207618334Speter 12077117395Skan/* Return nonzero if REG is known to be dead at INSN. 1207818334Speter 1207918334Speter We scan backwards from INSN. If we hit a REG_DEAD note or a CLOBBER 1208018334Speter referencing REG, it is dead. If we hit a SET referencing REG, it is 1208118334Speter live. Otherwise, see if it is live or dead at the start of the basic 1208218334Speter block we are in. Hard regs marked as being live in NEWPAT_USED_REGS 1208318334Speter must be assumed to be always live. */ 1208418334Speter 1208518334Speterstatic int 1208618334Speterreg_dead_at_p (reg, insn) 1208718334Speter rtx reg; 1208818334Speter rtx insn; 1208918334Speter{ 12090117395Skan basic_block block; 1209190075Sobrien unsigned int i; 1209218334Speter 1209318334Speter /* Set variables for reg_dead_at_p_1. */ 1209418334Speter reg_dead_regno = REGNO (reg); 1209518334Speter reg_dead_endregno = reg_dead_regno + (reg_dead_regno < FIRST_PSEUDO_REGISTER 1209618334Speter ? HARD_REGNO_NREGS (reg_dead_regno, 1209718334Speter GET_MODE (reg)) 1209818334Speter : 1); 1209918334Speter 1210018334Speter reg_dead_flag = 0; 1210118334Speter 1210218334Speter /* Check that reg isn't mentioned in NEWPAT_USED_REGS. */ 1210318334Speter if (reg_dead_regno < FIRST_PSEUDO_REGISTER) 1210418334Speter { 1210518334Speter for (i = reg_dead_regno; i < reg_dead_endregno; i++) 1210618334Speter if (TEST_HARD_REG_BIT (newpat_used_regs, i)) 1210718334Speter return 0; 1210818334Speter } 1210918334Speter 1211018334Speter /* Scan backwards until we find a REG_DEAD note, SET, CLOBBER, label, or 1211118334Speter beginning of function. */ 1211218334Speter for (; insn && GET_CODE (insn) != CODE_LABEL && GET_CODE (insn) != BARRIER; 1211318334Speter insn = prev_nonnote_insn (insn)) 1211418334Speter { 1211590075Sobrien note_stores (PATTERN (insn), reg_dead_at_p_1, NULL); 1211618334Speter if (reg_dead_flag) 1211718334Speter return reg_dead_flag == 1 ? 1 : 0; 1211818334Speter 1211918334Speter if (find_regno_note (insn, REG_DEAD, reg_dead_regno)) 1212018334Speter return 1; 1212118334Speter } 1212218334Speter 12123117395Skan /* Get the basic block that we were in. */ 1212418334Speter if (insn == 0) 12125117395Skan block = ENTRY_BLOCK_PTR->next_bb; 1212618334Speter else 1212718334Speter { 12128117395Skan FOR_EACH_BB (block) 12129117395Skan if (insn == block->head) 1213018334Speter break; 1213118334Speter 12132117395Skan if (block == EXIT_BLOCK_PTR) 1213318334Speter return 0; 1213418334Speter } 1213518334Speter 1213618334Speter for (i = reg_dead_regno; i < reg_dead_endregno; i++) 12137117395Skan if (REGNO_REG_SET_P (block->global_live_at_start, i)) 1213818334Speter return 0; 1213918334Speter 1214018334Speter return 1; 1214118334Speter} 1214218334Speter 1214318334Speter/* Note hard registers in X that are used. This code is similar to 1214418334Speter that in flow.c, but much simpler since we don't care about pseudos. */ 1214518334Speter 1214618334Speterstatic void 1214718334Spetermark_used_regs_combine (x) 1214818334Speter rtx x; 1214918334Speter{ 1215090075Sobrien RTX_CODE code = GET_CODE (x); 1215190075Sobrien unsigned int regno; 1215218334Speter int i; 1215318334Speter 1215418334Speter switch (code) 1215518334Speter { 1215618334Speter case LABEL_REF: 1215718334Speter case SYMBOL_REF: 1215818334Speter case CONST_INT: 1215918334Speter case CONST: 1216018334Speter case CONST_DOUBLE: 1216196263Sobrien case CONST_VECTOR: 1216218334Speter case PC: 1216318334Speter case ADDR_VEC: 1216418334Speter case ADDR_DIFF_VEC: 1216518334Speter case ASM_INPUT: 1216618334Speter#ifdef HAVE_cc0 1216718334Speter /* CC0 must die in the insn after it is set, so we don't need to take 1216818334Speter special note of it here. */ 1216918334Speter case CC0: 1217018334Speter#endif 1217118334Speter return; 1217218334Speter 1217318334Speter case CLOBBER: 1217418334Speter /* If we are clobbering a MEM, mark any hard registers inside the 1217518334Speter address as used. */ 1217618334Speter if (GET_CODE (XEXP (x, 0)) == MEM) 1217718334Speter mark_used_regs_combine (XEXP (XEXP (x, 0), 0)); 1217818334Speter return; 1217918334Speter 1218018334Speter case REG: 1218118334Speter regno = REGNO (x); 1218218334Speter /* A hard reg in a wide mode may really be multiple registers. 1218318334Speter If so, mark all of them just like the first. */ 1218418334Speter if (regno < FIRST_PSEUDO_REGISTER) 1218518334Speter { 1218690075Sobrien unsigned int endregno, r; 1218790075Sobrien 12188117395Skan /* None of this applies to the stack, frame or arg pointers. */ 1218918334Speter if (regno == STACK_POINTER_REGNUM 1219018334Speter#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM 1219118334Speter || regno == HARD_FRAME_POINTER_REGNUM 1219218334Speter#endif 1219318334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM 1219418334Speter || (regno == ARG_POINTER_REGNUM && fixed_regs[regno]) 1219518334Speter#endif 1219618334Speter || regno == FRAME_POINTER_REGNUM) 1219718334Speter return; 1219818334Speter 1219990075Sobrien endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x)); 1220090075Sobrien for (r = regno; r < endregno; r++) 1220190075Sobrien SET_HARD_REG_BIT (newpat_used_regs, r); 1220218334Speter } 1220318334Speter return; 1220418334Speter 1220518334Speter case SET: 1220618334Speter { 1220718334Speter /* If setting a MEM, or a SUBREG of a MEM, then note any hard regs in 1220818334Speter the address. */ 1220990075Sobrien rtx testreg = SET_DEST (x); 1221018334Speter 1221118334Speter while (GET_CODE (testreg) == SUBREG 1221218334Speter || GET_CODE (testreg) == ZERO_EXTRACT 1221318334Speter || GET_CODE (testreg) == SIGN_EXTRACT 1221418334Speter || GET_CODE (testreg) == STRICT_LOW_PART) 1221518334Speter testreg = XEXP (testreg, 0); 1221618334Speter 1221718334Speter if (GET_CODE (testreg) == MEM) 1221818334Speter mark_used_regs_combine (XEXP (testreg, 0)); 1221918334Speter 1222018334Speter mark_used_regs_combine (SET_SRC (x)); 1222118334Speter } 1222250397Sobrien return; 1222350397Sobrien 1222450397Sobrien default: 1222550397Sobrien break; 1222618334Speter } 1222718334Speter 1222818334Speter /* Recursively scan the operands of this expression. */ 1222918334Speter 1223018334Speter { 1223190075Sobrien const char *fmt = GET_RTX_FORMAT (code); 1223218334Speter 1223318334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 1223418334Speter { 1223590075Sobrien if (fmt[i] == 'e') 1223618334Speter mark_used_regs_combine (XEXP (x, i)); 1223790075Sobrien else if (fmt[i] == 'E') 1223890075Sobrien { 1223990075Sobrien int j; 1224018334Speter 1224190075Sobrien for (j = 0; j < XVECLEN (x, i); j++) 1224290075Sobrien mark_used_regs_combine (XVECEXP (x, i, j)); 1224390075Sobrien } 1224418334Speter } 1224518334Speter } 1224618334Speter} 1224718334Speter 1224818334Speter/* Remove register number REGNO from the dead registers list of INSN. 1224918334Speter 1225018334Speter Return the note used to record the death, if there was one. */ 1225118334Speter 1225218334Speterrtx 1225318334Speterremove_death (regno, insn) 1225490075Sobrien unsigned int regno; 1225518334Speter rtx insn; 1225618334Speter{ 1225790075Sobrien rtx note = find_regno_note (insn, REG_DEAD, regno); 1225818334Speter 1225918334Speter if (note) 1226018334Speter { 1226150397Sobrien REG_N_DEATHS (regno)--; 1226218334Speter remove_note (insn, note); 1226318334Speter } 1226418334Speter 1226518334Speter return note; 1226618334Speter} 1226718334Speter 1226818334Speter/* For each register (hardware or pseudo) used within expression X, if its 1226918334Speter death is in an instruction with cuid between FROM_CUID (inclusive) and 1227018334Speter TO_INSN (exclusive), put a REG_DEAD note for that register in the 1227190075Sobrien list headed by PNOTES. 1227218334Speter 1227350397Sobrien That said, don't move registers killed by maybe_kill_insn. 1227450397Sobrien 1227518334Speter This is done when X is being merged by combination into TO_INSN. These 1227618334Speter notes will then be distributed as needed. */ 1227718334Speter 1227818334Speterstatic void 1227950397Sobrienmove_deaths (x, maybe_kill_insn, from_cuid, to_insn, pnotes) 1228018334Speter rtx x; 1228150397Sobrien rtx maybe_kill_insn; 1228218334Speter int from_cuid; 1228318334Speter rtx to_insn; 1228418334Speter rtx *pnotes; 1228518334Speter{ 1228690075Sobrien const char *fmt; 1228790075Sobrien int len, i; 1228890075Sobrien enum rtx_code code = GET_CODE (x); 1228918334Speter 1229018334Speter if (code == REG) 1229118334Speter { 1229290075Sobrien unsigned int regno = REGNO (x); 1229390075Sobrien rtx where_dead = reg_last_death[regno]; 1229490075Sobrien rtx before_dead, after_dead; 1229518334Speter 12296117395Skan /* Don't move the register if it gets killed in between from and to. */ 1229750397Sobrien if (maybe_kill_insn && reg_set_p (x, maybe_kill_insn) 1229890075Sobrien && ! reg_referenced_p (x, maybe_kill_insn)) 1229950397Sobrien return; 1230050397Sobrien 1230118334Speter /* WHERE_DEAD could be a USE insn made by combine, so first we 1230218334Speter make sure that we have insns with valid INSN_CUID values. */ 1230318334Speter before_dead = where_dead; 1230418334Speter while (before_dead && INSN_UID (before_dead) > max_uid_cuid) 1230518334Speter before_dead = PREV_INSN (before_dead); 1230690075Sobrien 1230718334Speter after_dead = where_dead; 1230818334Speter while (after_dead && INSN_UID (after_dead) > max_uid_cuid) 1230918334Speter after_dead = NEXT_INSN (after_dead); 1231018334Speter 1231118334Speter if (before_dead && after_dead 1231218334Speter && INSN_CUID (before_dead) >= from_cuid 1231318334Speter && (INSN_CUID (after_dead) < INSN_CUID (to_insn) 1231418334Speter || (where_dead != after_dead 1231518334Speter && INSN_CUID (after_dead) == INSN_CUID (to_insn)))) 1231618334Speter { 1231718334Speter rtx note = remove_death (regno, where_dead); 1231818334Speter 1231918334Speter /* It is possible for the call above to return 0. This can occur 1232018334Speter when reg_last_death points to I2 or I1 that we combined with. 1232118334Speter In that case make a new note. 1232218334Speter 1232318334Speter We must also check for the case where X is a hard register 1232418334Speter and NOTE is a death note for a range of hard registers 1232518334Speter including X. In that case, we must put REG_DEAD notes for 1232618334Speter the remaining registers in place of NOTE. */ 1232718334Speter 1232818334Speter if (note != 0 && regno < FIRST_PSEUDO_REGISTER 1232918334Speter && (GET_MODE_SIZE (GET_MODE (XEXP (note, 0))) 1233050397Sobrien > GET_MODE_SIZE (GET_MODE (x)))) 1233118334Speter { 1233290075Sobrien unsigned int deadregno = REGNO (XEXP (note, 0)); 1233390075Sobrien unsigned int deadend 1233418334Speter = (deadregno + HARD_REGNO_NREGS (deadregno, 1233518334Speter GET_MODE (XEXP (note, 0)))); 1233690075Sobrien unsigned int ourend 1233790075Sobrien = regno + HARD_REGNO_NREGS (regno, GET_MODE (x)); 1233890075Sobrien unsigned int i; 1233918334Speter 1234018334Speter for (i = deadregno; i < deadend; i++) 1234118334Speter if (i < regno || i >= ourend) 1234218334Speter REG_NOTES (where_dead) 1234350397Sobrien = gen_rtx_EXPR_LIST (REG_DEAD, 12344117395Skan regno_reg_rtx[i], 1234550397Sobrien REG_NOTES (where_dead)); 1234618334Speter } 1234790075Sobrien 1234850397Sobrien /* If we didn't find any note, or if we found a REG_DEAD note that 1234950397Sobrien covers only part of the given reg, and we have a multi-reg hard 1235018334Speter register, then to be safe we must check for REG_DEAD notes 1235118334Speter for each register other than the first. They could have 1235218334Speter their own REG_DEAD notes lying around. */ 1235350397Sobrien else if ((note == 0 1235450397Sobrien || (note != 0 1235550397Sobrien && (GET_MODE_SIZE (GET_MODE (XEXP (note, 0))) 1235650397Sobrien < GET_MODE_SIZE (GET_MODE (x))))) 1235750397Sobrien && regno < FIRST_PSEUDO_REGISTER 1235818334Speter && HARD_REGNO_NREGS (regno, GET_MODE (x)) > 1) 1235918334Speter { 1236090075Sobrien unsigned int ourend 1236190075Sobrien = regno + HARD_REGNO_NREGS (regno, GET_MODE (x)); 1236290075Sobrien unsigned int i, offset; 1236318334Speter rtx oldnotes = 0; 1236418334Speter 1236550397Sobrien if (note) 1236650397Sobrien offset = HARD_REGNO_NREGS (regno, GET_MODE (XEXP (note, 0))); 1236750397Sobrien else 1236850397Sobrien offset = 1; 1236950397Sobrien 1237050397Sobrien for (i = regno + offset; i < ourend; i++) 12371117395Skan move_deaths (regno_reg_rtx[i], 1237250397Sobrien maybe_kill_insn, from_cuid, to_insn, &oldnotes); 1237318334Speter } 1237418334Speter 1237518334Speter if (note != 0 && GET_MODE (XEXP (note, 0)) == GET_MODE (x)) 1237618334Speter { 1237718334Speter XEXP (note, 1) = *pnotes; 1237818334Speter *pnotes = note; 1237918334Speter } 1238018334Speter else 1238150397Sobrien *pnotes = gen_rtx_EXPR_LIST (REG_DEAD, x, *pnotes); 1238218334Speter 1238350397Sobrien REG_N_DEATHS (regno)++; 1238418334Speter } 1238518334Speter 1238618334Speter return; 1238718334Speter } 1238818334Speter 1238918334Speter else if (GET_CODE (x) == SET) 1239018334Speter { 1239118334Speter rtx dest = SET_DEST (x); 1239218334Speter 1239350397Sobrien move_deaths (SET_SRC (x), maybe_kill_insn, from_cuid, to_insn, pnotes); 1239418334Speter 1239518334Speter /* In the case of a ZERO_EXTRACT, a STRICT_LOW_PART, or a SUBREG 1239618334Speter that accesses one word of a multi-word item, some 1239718334Speter piece of everything register in the expression is used by 1239818334Speter this insn, so remove any old death. */ 1239990075Sobrien /* ??? So why do we test for equality of the sizes? */ 1240018334Speter 1240118334Speter if (GET_CODE (dest) == ZERO_EXTRACT 1240218334Speter || GET_CODE (dest) == STRICT_LOW_PART 1240318334Speter || (GET_CODE (dest) == SUBREG 1240418334Speter && (((GET_MODE_SIZE (GET_MODE (dest)) 1240518334Speter + UNITS_PER_WORD - 1) / UNITS_PER_WORD) 1240618334Speter == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) 1240718334Speter + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))) 1240818334Speter { 1240950397Sobrien move_deaths (dest, maybe_kill_insn, from_cuid, to_insn, pnotes); 1241018334Speter return; 1241118334Speter } 1241218334Speter 1241318334Speter /* If this is some other SUBREG, we know it replaces the entire 1241418334Speter value, so use that as the destination. */ 1241518334Speter if (GET_CODE (dest) == SUBREG) 1241618334Speter dest = SUBREG_REG (dest); 1241718334Speter 1241818334Speter /* If this is a MEM, adjust deaths of anything used in the address. 1241918334Speter For a REG (the only other possibility), the entire value is 1242018334Speter being replaced so the old value is not used in this insn. */ 1242118334Speter 1242218334Speter if (GET_CODE (dest) == MEM) 1242350397Sobrien move_deaths (XEXP (dest, 0), maybe_kill_insn, from_cuid, 1242450397Sobrien to_insn, pnotes); 1242518334Speter return; 1242618334Speter } 1242718334Speter 1242818334Speter else if (GET_CODE (x) == CLOBBER) 1242918334Speter return; 1243018334Speter 1243118334Speter len = GET_RTX_LENGTH (code); 1243218334Speter fmt = GET_RTX_FORMAT (code); 1243318334Speter 1243418334Speter for (i = 0; i < len; i++) 1243518334Speter { 1243618334Speter if (fmt[i] == 'E') 1243718334Speter { 1243890075Sobrien int j; 1243918334Speter for (j = XVECLEN (x, i) - 1; j >= 0; j--) 1244050397Sobrien move_deaths (XVECEXP (x, i, j), maybe_kill_insn, from_cuid, 1244150397Sobrien to_insn, pnotes); 1244218334Speter } 1244318334Speter else if (fmt[i] == 'e') 1244450397Sobrien move_deaths (XEXP (x, i), maybe_kill_insn, from_cuid, to_insn, pnotes); 1244518334Speter } 1244618334Speter} 1244718334Speter 1244818334Speter/* Return 1 if X is the target of a bit-field assignment in BODY, the 1244918334Speter pattern of an insn. X must be a REG. */ 1245018334Speter 1245118334Speterstatic int 1245218334Speterreg_bitfield_target_p (x, body) 1245318334Speter rtx x; 1245418334Speter rtx body; 1245518334Speter{ 1245618334Speter int i; 1245718334Speter 1245818334Speter if (GET_CODE (body) == SET) 1245918334Speter { 1246018334Speter rtx dest = SET_DEST (body); 1246118334Speter rtx target; 1246290075Sobrien unsigned int regno, tregno, endregno, endtregno; 1246318334Speter 1246418334Speter if (GET_CODE (dest) == ZERO_EXTRACT) 1246518334Speter target = XEXP (dest, 0); 1246618334Speter else if (GET_CODE (dest) == STRICT_LOW_PART) 1246718334Speter target = SUBREG_REG (XEXP (dest, 0)); 1246818334Speter else 1246918334Speter return 0; 1247018334Speter 1247118334Speter if (GET_CODE (target) == SUBREG) 1247218334Speter target = SUBREG_REG (target); 1247318334Speter 1247418334Speter if (GET_CODE (target) != REG) 1247518334Speter return 0; 1247618334Speter 1247718334Speter tregno = REGNO (target), regno = REGNO (x); 1247818334Speter if (tregno >= FIRST_PSEUDO_REGISTER || regno >= FIRST_PSEUDO_REGISTER) 1247918334Speter return target == x; 1248018334Speter 1248118334Speter endtregno = tregno + HARD_REGNO_NREGS (tregno, GET_MODE (target)); 1248218334Speter endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x)); 1248318334Speter 1248418334Speter return endregno > tregno && regno < endtregno; 1248518334Speter } 1248618334Speter 1248718334Speter else if (GET_CODE (body) == PARALLEL) 1248818334Speter for (i = XVECLEN (body, 0) - 1; i >= 0; i--) 1248918334Speter if (reg_bitfield_target_p (x, XVECEXP (body, 0, i))) 1249018334Speter return 1; 1249118334Speter 1249218334Speter return 0; 1249390075Sobrien} 1249418334Speter 1249518334Speter/* Given a chain of REG_NOTES originally from FROM_INSN, try to place them 1249618334Speter as appropriate. I3 and I2 are the insns resulting from the combination 1249718334Speter insns including FROM (I2 may be zero). 1249818334Speter 1249918334Speter ELIM_I2 and ELIM_I1 are either zero or registers that we know will 1250018334Speter not need REG_DEAD notes because they are being substituted for. This 1250118334Speter saves searching in the most common cases. 1250218334Speter 1250318334Speter Each note in the list is either ignored or placed on some insns, depending 1250418334Speter on the type of note. */ 1250518334Speter 1250618334Speterstatic void 1250718334Speterdistribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) 1250818334Speter rtx notes; 1250918334Speter rtx from_insn; 1251018334Speter rtx i3, i2; 1251118334Speter rtx elim_i2, elim_i1; 1251218334Speter{ 1251318334Speter rtx note, next_note; 1251418334Speter rtx tem; 1251518334Speter 1251618334Speter for (note = notes; note; note = next_note) 1251718334Speter { 1251818334Speter rtx place = 0, place2 = 0; 1251918334Speter 1252018334Speter /* If this NOTE references a pseudo register, ensure it references 1252118334Speter the latest copy of that register. */ 1252218334Speter if (XEXP (note, 0) && GET_CODE (XEXP (note, 0)) == REG 1252318334Speter && REGNO (XEXP (note, 0)) >= FIRST_PSEUDO_REGISTER) 1252418334Speter XEXP (note, 0) = regno_reg_rtx[REGNO (XEXP (note, 0))]; 1252518334Speter 1252618334Speter next_note = XEXP (note, 1); 1252718334Speter switch (REG_NOTE_KIND (note)) 1252818334Speter { 1252950397Sobrien case REG_BR_PROB: 1253090075Sobrien case REG_BR_PRED: 1253150397Sobrien /* Doesn't matter much where we put this, as long as it's somewhere. 1253250397Sobrien It is preferable to keep these notes on branches, which is most 1253350397Sobrien likely to be i3. */ 1253450397Sobrien place = i3; 1253550397Sobrien break; 1253650397Sobrien 1253790075Sobrien case REG_VTABLE_REF: 1253890075Sobrien /* ??? Should remain with *a particular* memory load. Given the 1253990075Sobrien nature of vtable data, the last insn seems relatively safe. */ 1254090075Sobrien place = i3; 1254190075Sobrien break; 1254290075Sobrien 1254390075Sobrien case REG_NON_LOCAL_GOTO: 1254490075Sobrien if (GET_CODE (i3) == JUMP_INSN) 1254590075Sobrien place = i3; 1254690075Sobrien else if (i2 && GET_CODE (i2) == JUMP_INSN) 1254790075Sobrien place = i2; 1254890075Sobrien else 1254990075Sobrien abort (); 1255090075Sobrien break; 1255190075Sobrien 1255252284Sobrien case REG_EH_REGION: 1255390075Sobrien /* These notes must remain with the call or trapping instruction. */ 1255490075Sobrien if (GET_CODE (i3) == CALL_INSN) 1255552284Sobrien place = i3; 1255652284Sobrien else if (i2 && GET_CODE (i2) == CALL_INSN) 1255752284Sobrien place = i2; 1255890075Sobrien else if (flag_non_call_exceptions) 1255990075Sobrien { 1256090075Sobrien if (may_trap_p (i3)) 1256190075Sobrien place = i3; 1256290075Sobrien else if (i2 && may_trap_p (i2)) 1256390075Sobrien place = i2; 1256490075Sobrien /* ??? Otherwise assume we've combined things such that we 1256590075Sobrien can now prove that the instructions can't trap. Drop the 1256690075Sobrien note in this case. */ 1256790075Sobrien } 1256852284Sobrien else 1256952284Sobrien abort (); 1257052284Sobrien break; 1257152284Sobrien 1257290075Sobrien case REG_NORETURN: 1257390075Sobrien case REG_SETJMP: 1257490075Sobrien /* These notes must remain with the call. It should not be 1257590075Sobrien possible for both I2 and I3 to be a call. */ 1257690075Sobrien if (GET_CODE (i3) == CALL_INSN) 1257790075Sobrien place = i3; 1257890075Sobrien else if (i2 && GET_CODE (i2) == CALL_INSN) 1257990075Sobrien place = i2; 1258090075Sobrien else 1258190075Sobrien abort (); 1258290075Sobrien break; 1258390075Sobrien 1258418334Speter case REG_UNUSED: 1258518334Speter /* Any clobbers for i3 may still exist, and so we must process 1258618334Speter REG_UNUSED notes from that insn. 1258718334Speter 1258818334Speter Any clobbers from i2 or i1 can only exist if they were added by 1258918334Speter recog_for_combine. In that case, recog_for_combine created the 1259018334Speter necessary REG_UNUSED notes. Trying to keep any original 1259118334Speter REG_UNUSED notes from these insns can cause incorrect output 1259218334Speter if it is for the same register as the original i3 dest. 1259318334Speter In that case, we will notice that the register is set in i3, 1259418334Speter and then add a REG_UNUSED note for the destination of i3, which 1259518334Speter is wrong. However, it is possible to have REG_UNUSED notes from 1259618334Speter i2 or i1 for register which were both used and clobbered, so 1259718334Speter we keep notes from i2 or i1 if they will turn into REG_DEAD 1259818334Speter notes. */ 1259918334Speter 1260018334Speter /* If this register is set or clobbered in I3, put the note there 1260118334Speter unless there is one already. */ 1260218334Speter if (reg_set_p (XEXP (note, 0), PATTERN (i3))) 1260318334Speter { 1260418334Speter if (from_insn != i3) 1260518334Speter break; 1260618334Speter 1260718334Speter if (! (GET_CODE (XEXP (note, 0)) == REG 1260818334Speter ? find_regno_note (i3, REG_UNUSED, REGNO (XEXP (note, 0))) 1260918334Speter : find_reg_note (i3, REG_UNUSED, XEXP (note, 0)))) 1261018334Speter place = i3; 1261118334Speter } 1261218334Speter /* Otherwise, if this register is used by I3, then this register 1261318334Speter now dies here, so we must put a REG_DEAD note here unless there 1261418334Speter is one already. */ 1261518334Speter else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)) 1261618334Speter && ! (GET_CODE (XEXP (note, 0)) == REG 1261790075Sobrien ? find_regno_note (i3, REG_DEAD, 1261890075Sobrien REGNO (XEXP (note, 0))) 1261918334Speter : find_reg_note (i3, REG_DEAD, XEXP (note, 0)))) 1262018334Speter { 1262118334Speter PUT_REG_NOTE_KIND (note, REG_DEAD); 1262218334Speter place = i3; 1262318334Speter } 1262418334Speter break; 1262518334Speter 1262618334Speter case REG_EQUAL: 1262718334Speter case REG_EQUIV: 1262850397Sobrien case REG_NOALIAS: 1262918334Speter /* These notes say something about results of an insn. We can 1263018334Speter only support them if they used to be on I3 in which case they 1263118334Speter remain on I3. Otherwise they are ignored. 1263218334Speter 1263318334Speter If the note refers to an expression that is not a constant, we 1263418334Speter must also ignore the note since we cannot tell whether the 1263518334Speter equivalence is still true. It might be possible to do 1263618334Speter slightly better than this (we only have a problem if I2DEST 1263718334Speter or I1DEST is present in the expression), but it doesn't 1263818334Speter seem worth the trouble. */ 1263918334Speter 1264018334Speter if (from_insn == i3 1264118334Speter && (XEXP (note, 0) == 0 || CONSTANT_P (XEXP (note, 0)))) 1264218334Speter place = i3; 1264318334Speter break; 1264418334Speter 1264518334Speter case REG_INC: 1264618334Speter case REG_NO_CONFLICT: 1264718334Speter /* These notes say something about how a register is used. They must 1264818334Speter be present on any use of the register in I2 or I3. */ 1264918334Speter if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3))) 1265018334Speter place = i3; 1265118334Speter 1265218334Speter if (i2 && reg_mentioned_p (XEXP (note, 0), PATTERN (i2))) 1265318334Speter { 1265418334Speter if (place) 1265518334Speter place2 = i2; 1265618334Speter else 1265718334Speter place = i2; 1265818334Speter } 1265918334Speter break; 1266018334Speter 1266152284Sobrien case REG_LABEL: 1266252284Sobrien /* This can show up in several ways -- either directly in the 1266352284Sobrien pattern, or hidden off in the constant pool with (or without?) 1266452284Sobrien a REG_EQUAL note. */ 1266552284Sobrien /* ??? Ignore the without-reg_equal-note problem for now. */ 1266652284Sobrien if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3)) 1266752284Sobrien || ((tem = find_reg_note (i3, REG_EQUAL, NULL_RTX)) 1266852284Sobrien && GET_CODE (XEXP (tem, 0)) == LABEL_REF 1266952284Sobrien && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0))) 1267052284Sobrien place = i3; 1267152284Sobrien 1267252284Sobrien if (i2 1267352284Sobrien && (reg_mentioned_p (XEXP (note, 0), PATTERN (i2)) 1267490075Sobrien || ((tem = find_reg_note (i2, REG_EQUAL, NULL_RTX)) 1267552284Sobrien && GET_CODE (XEXP (tem, 0)) == LABEL_REF 1267652284Sobrien && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0)))) 1267752284Sobrien { 1267852284Sobrien if (place) 1267952284Sobrien place2 = i2; 1268052284Sobrien else 1268152284Sobrien place = i2; 1268252284Sobrien } 1268390075Sobrien 1268490075Sobrien /* Don't attach REG_LABEL note to a JUMP_INSN which has 1268590075Sobrien JUMP_LABEL already. Instead, decrement LABEL_NUSES. */ 1268690075Sobrien if (place && GET_CODE (place) == JUMP_INSN && JUMP_LABEL (place)) 1268790075Sobrien { 1268890075Sobrien if (JUMP_LABEL (place) != XEXP (note, 0)) 1268990075Sobrien abort (); 1269090075Sobrien if (GET_CODE (JUMP_LABEL (place)) == CODE_LABEL) 1269190075Sobrien LABEL_NUSES (JUMP_LABEL (place))--; 1269290075Sobrien place = 0; 1269390075Sobrien } 1269490075Sobrien if (place2 && GET_CODE (place2) == JUMP_INSN && JUMP_LABEL (place2)) 1269590075Sobrien { 1269690075Sobrien if (JUMP_LABEL (place2) != XEXP (note, 0)) 1269790075Sobrien abort (); 1269890075Sobrien if (GET_CODE (JUMP_LABEL (place2)) == CODE_LABEL) 1269990075Sobrien LABEL_NUSES (JUMP_LABEL (place2))--; 1270090075Sobrien place2 = 0; 1270190075Sobrien } 1270252284Sobrien break; 1270352284Sobrien 1270490075Sobrien case REG_NONNEG: 1270518334Speter case REG_WAS_0: 1270690075Sobrien /* These notes say something about the value of a register prior 1270790075Sobrien to the execution of an insn. It is too much trouble to see 1270890075Sobrien if the note is still correct in all situations. It is better 1270990075Sobrien to simply delete it. */ 1271018334Speter break; 1271118334Speter 1271218334Speter case REG_RETVAL: 1271318334Speter /* If the insn previously containing this note still exists, 1271418334Speter put it back where it was. Otherwise move it to the previous 1271518334Speter insn. Adjust the corresponding REG_LIBCALL note. */ 1271618334Speter if (GET_CODE (from_insn) != NOTE) 1271718334Speter place = from_insn; 1271818334Speter else 1271918334Speter { 1272018334Speter tem = find_reg_note (XEXP (note, 0), REG_LIBCALL, NULL_RTX); 1272118334Speter place = prev_real_insn (from_insn); 1272218334Speter if (tem && place) 1272318334Speter XEXP (tem, 0) = place; 1272490075Sobrien /* If we're deleting the last remaining instruction of a 1272590075Sobrien libcall sequence, don't add the notes. */ 1272690075Sobrien else if (XEXP (note, 0) == from_insn) 1272790075Sobrien tem = place = 0; 1272818334Speter } 1272918334Speter break; 1273018334Speter 1273118334Speter case REG_LIBCALL: 1273218334Speter /* This is handled similarly to REG_RETVAL. */ 1273318334Speter if (GET_CODE (from_insn) != NOTE) 1273418334Speter place = from_insn; 1273518334Speter else 1273618334Speter { 1273718334Speter tem = find_reg_note (XEXP (note, 0), REG_RETVAL, NULL_RTX); 1273818334Speter place = next_real_insn (from_insn); 1273918334Speter if (tem && place) 1274018334Speter XEXP (tem, 0) = place; 1274190075Sobrien /* If we're deleting the last remaining instruction of a 1274290075Sobrien libcall sequence, don't add the notes. */ 1274390075Sobrien else if (XEXP (note, 0) == from_insn) 1274490075Sobrien tem = place = 0; 1274518334Speter } 1274618334Speter break; 1274718334Speter 1274818334Speter case REG_DEAD: 1274918334Speter /* If the register is used as an input in I3, it dies there. 12750117395Skan Similarly for I2, if it is nonzero and adjacent to I3. 1275118334Speter 1275218334Speter If the register is not used as an input in either I3 or I2 1275318334Speter and it is not one of the registers we were supposed to eliminate, 1275418334Speter there are two possibilities. We might have a non-adjacent I2 1275518334Speter or we might have somehow eliminated an additional register 1275618334Speter from a computation. For example, we might have had A & B where 1275718334Speter we discover that B will always be zero. In this case we will 1275818334Speter eliminate the reference to A. 1275918334Speter 1276018334Speter In both cases, we must search to see if we can find a previous 1276118334Speter use of A and put the death note there. */ 1276218334Speter 1276318334Speter if (from_insn 1276418334Speter && GET_CODE (from_insn) == CALL_INSN 1276590075Sobrien && find_reg_fusage (from_insn, USE, XEXP (note, 0))) 1276618334Speter place = from_insn; 1276718334Speter else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3))) 1276818334Speter place = i3; 1276918334Speter else if (i2 != 0 && next_nonnote_insn (i2) == i3 1277018334Speter && reg_referenced_p (XEXP (note, 0), PATTERN (i2))) 1277118334Speter place = i2; 1277218334Speter 1277390075Sobrien if (rtx_equal_p (XEXP (note, 0), elim_i2) 1277490075Sobrien || rtx_equal_p (XEXP (note, 0), elim_i1)) 1277518334Speter break; 1277618334Speter 1277718334Speter if (place == 0) 1277818334Speter { 12779117395Skan basic_block bb = this_basic_block; 1278090075Sobrien 1278190075Sobrien for (tem = PREV_INSN (i3); place == 0; tem = PREV_INSN (tem)) 1278218334Speter { 1278390075Sobrien if (! INSN_P (tem)) 1278490075Sobrien { 1278590075Sobrien if (tem == bb->head) 1278690075Sobrien break; 1278790075Sobrien continue; 1278890075Sobrien } 1278990075Sobrien 1279018334Speter /* If the register is being set at TEM, see if that is all 1279118334Speter TEM is doing. If so, delete TEM. Otherwise, make this 1279218334Speter into a REG_UNUSED note instead. */ 1279318334Speter if (reg_set_p (XEXP (note, 0), PATTERN (tem))) 1279418334Speter { 1279518334Speter rtx set = single_set (tem); 1279650397Sobrien rtx inner_dest = 0; 1279752284Sobrien#ifdef HAVE_cc0 1279852284Sobrien rtx cc0_setter = NULL_RTX; 1279952284Sobrien#endif 1280018334Speter 1280150397Sobrien if (set != 0) 1280250397Sobrien for (inner_dest = SET_DEST (set); 1280390075Sobrien (GET_CODE (inner_dest) == STRICT_LOW_PART 1280490075Sobrien || GET_CODE (inner_dest) == SUBREG 1280590075Sobrien || GET_CODE (inner_dest) == ZERO_EXTRACT); 1280650397Sobrien inner_dest = XEXP (inner_dest, 0)) 1280750397Sobrien ; 1280850397Sobrien 1280918334Speter /* Verify that it was the set, and not a clobber that 1281090075Sobrien modified the register. 1281118334Speter 1281252284Sobrien CC0 targets must be careful to maintain setter/user 1281352284Sobrien pairs. If we cannot delete the setter due to side 1281452284Sobrien effects, mark the user with an UNUSED note instead 1281552284Sobrien of deleting it. */ 1281652284Sobrien 1281718334Speter if (set != 0 && ! side_effects_p (SET_SRC (set)) 1281852284Sobrien && rtx_equal_p (XEXP (note, 0), inner_dest) 1281952284Sobrien#ifdef HAVE_cc0 1282052284Sobrien && (! reg_mentioned_p (cc0_rtx, SET_SRC (set)) 1282152284Sobrien || ((cc0_setter = prev_cc0_setter (tem)) != NULL 1282252284Sobrien && sets_cc0_p (PATTERN (cc0_setter)) > 0)) 1282352284Sobrien#endif 1282452284Sobrien ) 1282518334Speter { 1282618334Speter /* Move the notes and links of TEM elsewhere. 1282790075Sobrien This might delete other dead insns recursively. 1282818334Speter First set the pattern to something that won't use 1282918334Speter any register. */ 1283018334Speter 1283118334Speter PATTERN (tem) = pc_rtx; 1283218334Speter 1283318334Speter distribute_notes (REG_NOTES (tem), tem, tem, 1283418334Speter NULL_RTX, NULL_RTX, NULL_RTX); 1283518334Speter distribute_links (LOG_LINKS (tem)); 1283618334Speter 1283718334Speter PUT_CODE (tem, NOTE); 1283818334Speter NOTE_LINE_NUMBER (tem) = NOTE_INSN_DELETED; 1283918334Speter NOTE_SOURCE_FILE (tem) = 0; 1284052284Sobrien 1284152284Sobrien#ifdef HAVE_cc0 1284252284Sobrien /* Delete the setter too. */ 1284352284Sobrien if (cc0_setter) 1284452284Sobrien { 1284552284Sobrien PATTERN (cc0_setter) = pc_rtx; 1284652284Sobrien 1284752284Sobrien distribute_notes (REG_NOTES (cc0_setter), 1284852284Sobrien cc0_setter, cc0_setter, 1284952284Sobrien NULL_RTX, NULL_RTX, NULL_RTX); 1285052284Sobrien distribute_links (LOG_LINKS (cc0_setter)); 1285152284Sobrien 1285252284Sobrien PUT_CODE (cc0_setter, NOTE); 1285390075Sobrien NOTE_LINE_NUMBER (cc0_setter) 1285490075Sobrien = NOTE_INSN_DELETED; 1285552284Sobrien NOTE_SOURCE_FILE (cc0_setter) = 0; 1285652284Sobrien } 1285752284Sobrien#endif 1285818334Speter } 1285950397Sobrien /* If the register is both set and used here, put the 1286050397Sobrien REG_DEAD note here, but place a REG_UNUSED note 1286150397Sobrien here too unless there already is one. */ 1286250397Sobrien else if (reg_referenced_p (XEXP (note, 0), 1286350397Sobrien PATTERN (tem))) 1286450397Sobrien { 1286550397Sobrien place = tem; 1286650397Sobrien 1286750397Sobrien if (! find_regno_note (tem, REG_UNUSED, 1286850397Sobrien REGNO (XEXP (note, 0)))) 1286950397Sobrien REG_NOTES (tem) 1287090075Sobrien = gen_rtx_EXPR_LIST (REG_UNUSED, XEXP (note, 0), 1287150397Sobrien REG_NOTES (tem)); 1287250397Sobrien } 1287318334Speter else 1287418334Speter { 1287518334Speter PUT_REG_NOTE_KIND (note, REG_UNUSED); 1287690075Sobrien 1287718334Speter /* If there isn't already a REG_UNUSED note, put one 1287818334Speter here. */ 1287918334Speter if (! find_regno_note (tem, REG_UNUSED, 1288018334Speter REGNO (XEXP (note, 0)))) 1288118334Speter place = tem; 1288218334Speter break; 1288390075Sobrien } 1288490075Sobrien } 1288590075Sobrien else if (reg_referenced_p (XEXP (note, 0), PATTERN (tem)) 1288690075Sobrien || (GET_CODE (tem) == CALL_INSN 1288790075Sobrien && find_reg_fusage (tem, USE, XEXP (note, 0)))) 1288890075Sobrien { 1288990075Sobrien place = tem; 1289018334Speter 1289190075Sobrien /* If we are doing a 3->2 combination, and we have a 1289290075Sobrien register which formerly died in i3 and was not used 1289390075Sobrien by i2, which now no longer dies in i3 and is used in 1289490075Sobrien i2 but does not die in i2, and place is between i2 1289590075Sobrien and i3, then we may need to move a link from place to 1289690075Sobrien i2. */ 1289790075Sobrien if (i2 && INSN_UID (place) <= max_uid_cuid 1289890075Sobrien && INSN_CUID (place) > INSN_CUID (i2) 1289990075Sobrien && from_insn 1290090075Sobrien && INSN_CUID (from_insn) > INSN_CUID (i2) 1290190075Sobrien && reg_referenced_p (XEXP (note, 0), PATTERN (i2))) 1290290075Sobrien { 1290390075Sobrien rtx links = LOG_LINKS (place); 1290490075Sobrien LOG_LINKS (place) = 0; 1290590075Sobrien distribute_links (links); 1290690075Sobrien } 1290790075Sobrien break; 1290890075Sobrien } 1290990075Sobrien 1291090075Sobrien if (tem == bb->head) 1291118334Speter break; 1291218334Speter } 1291390075Sobrien 1291490075Sobrien /* We haven't found an insn for the death note and it 1291590075Sobrien is still a REG_DEAD note, but we have hit the beginning 1291690075Sobrien of the block. If the existing life info says the reg 1291790075Sobrien was dead, there's nothing left to do. Otherwise, we'll 1291890075Sobrien need to do a global life update after combine. */ 1291990075Sobrien if (REG_NOTE_KIND (note) == REG_DEAD && place == 0 1292090075Sobrien && REGNO_REG_SET_P (bb->global_live_at_start, 1292190075Sobrien REGNO (XEXP (note, 0)))) 1292218334Speter { 12923117395Skan SET_BIT (refresh_blocks, this_basic_block->index); 1292490075Sobrien need_refresh = 1; 1292518334Speter } 1292618334Speter } 1292718334Speter 1292818334Speter /* If the register is set or already dead at PLACE, we needn't do 1292950397Sobrien anything with this note if it is still a REG_DEAD note. 1293050397Sobrien We can here if it is set at all, not if is it totally replace, 1293150397Sobrien which is what `dead_or_set_p' checks, so also check for it being 1293250397Sobrien set partially. */ 1293318334Speter 1293418334Speter if (place && REG_NOTE_KIND (note) == REG_DEAD) 1293518334Speter { 1293690075Sobrien unsigned int regno = REGNO (XEXP (note, 0)); 1293718334Speter 1293890075Sobrien /* Similarly, if the instruction on which we want to place 1293990075Sobrien the note is a noop, we'll need do a global live update 1294090075Sobrien after we remove them in delete_noop_moves. */ 1294190075Sobrien if (noop_move_p (place)) 1294290075Sobrien { 12943117395Skan SET_BIT (refresh_blocks, this_basic_block->index); 1294490075Sobrien need_refresh = 1; 1294590075Sobrien } 1294690075Sobrien 1294718334Speter if (dead_or_set_p (place, XEXP (note, 0)) 1294818334Speter || reg_bitfield_target_p (XEXP (note, 0), PATTERN (place))) 1294918334Speter { 1295018334Speter /* Unless the register previously died in PLACE, clear 1295118334Speter reg_last_death. [I no longer understand why this is 1295218334Speter being done.] */ 1295318334Speter if (reg_last_death[regno] != place) 1295418334Speter reg_last_death[regno] = 0; 1295518334Speter place = 0; 1295618334Speter } 1295718334Speter else 1295818334Speter reg_last_death[regno] = place; 1295918334Speter 1296018334Speter /* If this is a death note for a hard reg that is occupying 1296118334Speter multiple registers, ensure that we are still using all 1296218334Speter parts of the object. If we find a piece of the object 1296390075Sobrien that is unused, we must arrange for an appropriate REG_DEAD 1296490075Sobrien note to be added for it. However, we can't just emit a USE 1296590075Sobrien and tag the note to it, since the register might actually 1296690075Sobrien be dead; so we recourse, and the recursive call then finds 1296790075Sobrien the previous insn that used this register. */ 1296818334Speter 1296918334Speter if (place && regno < FIRST_PSEUDO_REGISTER 1297018334Speter && HARD_REGNO_NREGS (regno, GET_MODE (XEXP (note, 0))) > 1) 1297118334Speter { 1297290075Sobrien unsigned int endregno 1297318334Speter = regno + HARD_REGNO_NREGS (regno, 1297418334Speter GET_MODE (XEXP (note, 0))); 1297518334Speter int all_used = 1; 1297690075Sobrien unsigned int i; 1297718334Speter 1297818334Speter for (i = regno; i < endregno; i++) 1297990075Sobrien if ((! refers_to_regno_p (i, i + 1, PATTERN (place), 0) 1298090075Sobrien && ! find_regno_fusage (place, USE, i)) 1298190075Sobrien || dead_or_set_regno_p (place, i)) 1298290075Sobrien all_used = 0; 1298318334Speter 1298418334Speter if (! all_used) 1298518334Speter { 1298618334Speter /* Put only REG_DEAD notes for pieces that are 1298790075Sobrien not already dead or set. */ 1298818334Speter 1298990075Sobrien for (i = regno; i < endregno; 1299090075Sobrien i += HARD_REGNO_NREGS (i, reg_raw_mode[i])) 1299118334Speter { 12992117395Skan rtx piece = regno_reg_rtx[i]; 12993117395Skan basic_block bb = this_basic_block; 1299418334Speter 1299590075Sobrien if (! dead_or_set_p (place, piece) 1299618334Speter && ! reg_bitfield_target_p (piece, 1299718334Speter PATTERN (place))) 1299890075Sobrien { 1299990075Sobrien rtx new_note 1300090075Sobrien = gen_rtx_EXPR_LIST (REG_DEAD, piece, NULL_RTX); 1300190075Sobrien 1300290075Sobrien distribute_notes (new_note, place, place, 1300390075Sobrien NULL_RTX, NULL_RTX, NULL_RTX); 1300490075Sobrien } 1300590075Sobrien else if (! refers_to_regno_p (i, i + 1, 1300690075Sobrien PATTERN (place), 0) 1300790075Sobrien && ! find_regno_fusage (place, USE, i)) 1300890075Sobrien for (tem = PREV_INSN (place); ; 1300990075Sobrien tem = PREV_INSN (tem)) 1301090075Sobrien { 1301190075Sobrien if (! INSN_P (tem)) 1301290075Sobrien { 1301390075Sobrien if (tem == bb->head) 1301490075Sobrien { 1301590075Sobrien SET_BIT (refresh_blocks, 13016117395Skan this_basic_block->index); 1301790075Sobrien need_refresh = 1; 1301890075Sobrien break; 1301990075Sobrien } 1302090075Sobrien continue; 1302190075Sobrien } 1302290075Sobrien if (dead_or_set_p (tem, piece) 1302390075Sobrien || reg_bitfield_target_p (piece, 1302490075Sobrien PATTERN (tem))) 1302590075Sobrien { 1302690075Sobrien REG_NOTES (tem) 1302790075Sobrien = gen_rtx_EXPR_LIST (REG_UNUSED, piece, 1302890075Sobrien REG_NOTES (tem)); 1302990075Sobrien break; 1303090075Sobrien } 1303190075Sobrien } 1303290075Sobrien 1303318334Speter } 1303418334Speter 1303518334Speter place = 0; 1303618334Speter } 1303718334Speter } 1303818334Speter } 1303918334Speter break; 1304018334Speter 1304118334Speter default: 1304218334Speter /* Any other notes should not be present at this point in the 1304318334Speter compilation. */ 1304418334Speter abort (); 1304518334Speter } 1304618334Speter 1304718334Speter if (place) 1304818334Speter { 1304918334Speter XEXP (note, 1) = REG_NOTES (place); 1305018334Speter REG_NOTES (place) = note; 1305118334Speter } 1305218334Speter else if ((REG_NOTE_KIND (note) == REG_DEAD 1305318334Speter || REG_NOTE_KIND (note) == REG_UNUSED) 1305418334Speter && GET_CODE (XEXP (note, 0)) == REG) 1305550397Sobrien REG_N_DEATHS (REGNO (XEXP (note, 0)))--; 1305618334Speter 1305718334Speter if (place2) 1305818334Speter { 1305918334Speter if ((REG_NOTE_KIND (note) == REG_DEAD 1306018334Speter || REG_NOTE_KIND (note) == REG_UNUSED) 1306118334Speter && GET_CODE (XEXP (note, 0)) == REG) 1306250397Sobrien REG_N_DEATHS (REGNO (XEXP (note, 0)))++; 1306318334Speter 1306450397Sobrien REG_NOTES (place2) = gen_rtx_fmt_ee (GET_CODE (note), 1306550397Sobrien REG_NOTE_KIND (note), 1306650397Sobrien XEXP (note, 0), 1306750397Sobrien REG_NOTES (place2)); 1306818334Speter } 1306918334Speter } 1307018334Speter} 1307118334Speter 1307218334Speter/* Similarly to above, distribute the LOG_LINKS that used to be present on 1307318334Speter I3, I2, and I1 to new locations. This is also called in one case to 1307418334Speter add a link pointing at I3 when I3's destination is changed. */ 1307518334Speter 1307618334Speterstatic void 1307718334Speterdistribute_links (links) 1307818334Speter rtx links; 1307918334Speter{ 1308018334Speter rtx link, next_link; 1308118334Speter 1308218334Speter for (link = links; link; link = next_link) 1308318334Speter { 1308418334Speter rtx place = 0; 1308518334Speter rtx insn; 1308618334Speter rtx set, reg; 1308718334Speter 1308818334Speter next_link = XEXP (link, 1); 1308918334Speter 1309018334Speter /* If the insn that this link points to is a NOTE or isn't a single 1309118334Speter set, ignore it. In the latter case, it isn't clear what we 1309290075Sobrien can do other than ignore the link, since we can't tell which 1309318334Speter register it was for. Such links wouldn't be used by combine 1309418334Speter anyway. 1309518334Speter 1309618334Speter It is not possible for the destination of the target of the link to 1309718334Speter have been changed by combine. The only potential of this is if we 1309818334Speter replace I3, I2, and I1 by I3 and I2. But in that case the 1309918334Speter destination of I2 also remains unchanged. */ 1310018334Speter 1310118334Speter if (GET_CODE (XEXP (link, 0)) == NOTE 1310218334Speter || (set = single_set (XEXP (link, 0))) == 0) 1310318334Speter continue; 1310418334Speter 1310518334Speter reg = SET_DEST (set); 1310618334Speter while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT 1310718334Speter || GET_CODE (reg) == SIGN_EXTRACT 1310818334Speter || GET_CODE (reg) == STRICT_LOW_PART) 1310918334Speter reg = XEXP (reg, 0); 1311018334Speter 1311118334Speter /* A LOG_LINK is defined as being placed on the first insn that uses 1311218334Speter a register and points to the insn that sets the register. Start 1311318334Speter searching at the next insn after the target of the link and stop 1311418334Speter when we reach a set of the register or the end of the basic block. 1311518334Speter 1311618334Speter Note that this correctly handles the link that used to point from 1311718334Speter I3 to I2. Also note that not much searching is typically done here 1311818334Speter since most links don't point very far away. */ 1311918334Speter 1312018334Speter for (insn = NEXT_INSN (XEXP (link, 0)); 13121117395Skan (insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR 13122117395Skan || this_basic_block->next_bb->head != insn)); 1312318334Speter insn = NEXT_INSN (insn)) 1312490075Sobrien if (INSN_P (insn) && reg_overlap_mentioned_p (reg, PATTERN (insn))) 1312518334Speter { 1312618334Speter if (reg_referenced_p (reg, PATTERN (insn))) 1312718334Speter place = insn; 1312818334Speter break; 1312918334Speter } 1313018334Speter else if (GET_CODE (insn) == CALL_INSN 1313190075Sobrien && find_reg_fusage (insn, USE, reg)) 1313218334Speter { 1313318334Speter place = insn; 1313418334Speter break; 1313518334Speter } 1313618334Speter 1313718334Speter /* If we found a place to put the link, place it there unless there 1313818334Speter is already a link to the same insn as LINK at that point. */ 1313918334Speter 1314018334Speter if (place) 1314118334Speter { 1314218334Speter rtx link2; 1314318334Speter 1314418334Speter for (link2 = LOG_LINKS (place); link2; link2 = XEXP (link2, 1)) 1314518334Speter if (XEXP (link2, 0) == XEXP (link, 0)) 1314618334Speter break; 1314718334Speter 1314818334Speter if (link2 == 0) 1314918334Speter { 1315018334Speter XEXP (link, 1) = LOG_LINKS (place); 1315118334Speter LOG_LINKS (place) = link; 1315218334Speter 1315318334Speter /* Set added_links_insn to the earliest insn we added a 1315418334Speter link to. */ 1315590075Sobrien if (added_links_insn == 0 1315618334Speter || INSN_CUID (added_links_insn) > INSN_CUID (place)) 1315718334Speter added_links_insn = place; 1315818334Speter } 1315918334Speter } 1316018334Speter } 1316118334Speter} 1316218334Speter 1316350397Sobrien/* Compute INSN_CUID for INSN, which is an insn made by combine. */ 1316450397Sobrien 1316550397Sobrienstatic int 1316650397Sobrieninsn_cuid (insn) 1316750397Sobrien rtx insn; 1316850397Sobrien{ 1316950397Sobrien while (insn != 0 && INSN_UID (insn) > max_uid_cuid 1317050397Sobrien && GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == USE) 1317150397Sobrien insn = NEXT_INSN (insn); 1317250397Sobrien 1317350397Sobrien if (INSN_UID (insn) > max_uid_cuid) 1317450397Sobrien abort (); 1317550397Sobrien 1317650397Sobrien return INSN_CUID (insn); 1317750397Sobrien} 1317850397Sobrien 1317918334Spetervoid 1318018334Speterdump_combine_stats (file) 1318118334Speter FILE *file; 1318218334Speter{ 1318352284Sobrien fnotice 1318418334Speter (file, 1318518334Speter ";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n", 1318618334Speter combine_attempts, combine_merges, combine_extras, combine_successes); 1318718334Speter} 1318818334Speter 1318918334Spetervoid 1319018334Speterdump_combine_total_stats (file) 1319118334Speter FILE *file; 1319218334Speter{ 1319352284Sobrien fnotice 1319418334Speter (file, 1319518334Speter "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n", 1319618334Speter total_attempts, total_merges, total_extras, total_successes); 1319718334Speter} 13198