00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 #include "config.h"
00078 #include "system.h"
00079 #include "rtl.h"
00080 #include "tm_p.h"
00081 #include "flags.h"
00082 #include "regs.h"
00083 #include "hard-reg-set.h"
00084 #include "basic-block.h"
00085 #include "insn-config.h"
00086 #include "function.h"
00087
00088 #include "expr.h"
00089 #include "insn-attr.h"
00090 #include "recog.h"
00091 #include "real.h"
00092 #include "toplev.h"
00093
00094
00095
00096 #define gen_lowpart dont_use_gen_lowpart_you_dummy
00097
00098
00099
00100 static int combine_attempts;
00101
00102
00103
00104 static int combine_merges;
00105
00106
00107
00108 static int combine_extras;
00109
00110
00111
00112 static int combine_successes;
00113
00114
00115
00116 static int total_attempts, total_merges, total_extras, total_successes;
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 static int *uid_cuid;
00127 static int max_uid_cuid;
00128
00129
00130
00131 #define INSN_CUID(INSN) \
00132 (INSN_UID (INSN) > max_uid_cuid ? insn_cuid (INSN) : uid_cuid[INSN_UID (INSN)])
00133
00134
00135
00136
00137 #define UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD(val) \
00138 (((unsigned HOST_WIDE_INT) (val) << (BITS_PER_WORD - 1)) << 1)
00139
00140 #define nonzero_bits(X, M) \
00141 cached_nonzero_bits (X, M, NULL_RTX, VOIDmode, 0)
00142
00143 #define num_sign_bit_copies(X, M) \
00144 cached_num_sign_bit_copies (X, M, NULL_RTX, VOIDmode, 0)
00145
00146
00147
00148 static unsigned int combine_max_regno;
00149
00150
00151
00152 static rtx *reg_last_death;
00153
00154
00155
00156 static rtx *reg_last_set;
00157
00158
00159
00160
00161 static int mem_last_set;
00162
00163
00164
00165
00166 static int last_call_cuid;
00167
00168
00169
00170
00171
00172
00173
00174 static rtx subst_insn;
00175
00176
00177
00178
00179 static rtx subst_prev_insn;
00180
00181
00182
00183
00184
00185
00186
00187
00188 static int subst_low_cuid;
00189
00190
00191
00192
00193 static HARD_REG_SET newpat_used_regs;
00194
00195
00196
00197
00198
00199 static rtx added_links_insn;
00200
00201
00202 static basic_block this_basic_block;
00203
00204
00205
00206
00207 static sbitmap refresh_blocks;
00208 static int need_refresh;
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 static rtx *reg_last_set_value;
00257
00258
00259
00260
00261 static int *reg_last_set_label;
00262
00263
00264
00265
00266 static int *reg_last_set_table_tick;
00267
00268
00269
00270
00271 static char *reg_last_set_invalid;
00272
00273
00274
00275 static int label_tick;
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 static unsigned HOST_WIDE_INT *reg_nonzero_bits;
00288
00289
00290
00291
00292 static enum machine_mode nonzero_bits_mode;
00293
00294
00295
00296
00297 static unsigned char *reg_sign_bit_copies;
00298
00299
00300
00301
00302
00303
00304 static int nonzero_sign_valid;
00305
00306
00307
00308
00309
00310
00311 static enum machine_mode *reg_last_set_mode;
00312 static unsigned HOST_WIDE_INT *reg_last_set_nonzero_bits;
00313 static char *reg_last_set_sign_bit_copies;
00314
00315
00316
00317
00318
00319 struct undo
00320 {
00321 struct undo *next;
00322 int is_int;
00323 union {rtx r; int i;} old_contents;
00324 union {rtx *r; int *i;} where;
00325 };
00326
00327
00328
00329
00330
00331
00332
00333 struct undobuf
00334 {
00335 struct undo *undos;
00336 struct undo *frees;
00337 rtx other_insn;
00338 };
00339
00340 static struct undobuf undobuf;
00341
00342
00343
00344
00345 static int n_occurrences;
00346
00347 static void do_SUBST PARAMS ((rtx *, rtx));
00348 static void do_SUBST_INT PARAMS ((int *, int));
00349 static void init_reg_last_arrays PARAMS ((void));
00350 static void setup_incoming_promotions PARAMS ((void));
00351 static void set_nonzero_bits_and_sign_copies PARAMS ((rtx, rtx, void *));
00352 static int cant_combine_insn_p PARAMS ((rtx));
00353 static int can_combine_p PARAMS ((rtx, rtx, rtx, rtx, rtx *, rtx *));
00354 static int sets_function_arg_p PARAMS ((rtx));
00355 static int combinable_i3pat PARAMS ((rtx, rtx *, rtx, rtx, int, rtx *));
00356 static int contains_muldiv PARAMS ((rtx));
00357 static rtx try_combine PARAMS ((rtx, rtx, rtx, int *));
00358 static void undo_all PARAMS ((void));
00359 static void undo_commit PARAMS ((void));
00360 static rtx *find_split_point PARAMS ((rtx *, rtx));
00361 static rtx subst PARAMS ((rtx, rtx, rtx, int, int));
00362 static rtx combine_simplify_rtx PARAMS ((rtx, enum machine_mode, int, int));
00363 static rtx simplify_if_then_else PARAMS ((rtx));
00364 static rtx simplify_set PARAMS ((rtx));
00365 static rtx simplify_logical PARAMS ((rtx, int));
00366 static rtx expand_compound_operation PARAMS ((rtx));
00367 static rtx expand_field_assignment PARAMS ((rtx));
00368 static rtx make_extraction PARAMS ((enum machine_mode, rtx, HOST_WIDE_INT,
00369 rtx, unsigned HOST_WIDE_INT, int,
00370 int, int));
00371 static rtx extract_left_shift PARAMS ((rtx, int));
00372 static rtx make_compound_operation PARAMS ((rtx, enum rtx_code));
00373 static int get_pos_from_mask PARAMS ((unsigned HOST_WIDE_INT,
00374 unsigned HOST_WIDE_INT *));
00375 static rtx force_to_mode PARAMS ((rtx, enum machine_mode,
00376 unsigned HOST_WIDE_INT, rtx, int));
00377 static rtx if_then_else_cond PARAMS ((rtx, rtx *, rtx *));
00378 static rtx known_cond PARAMS ((rtx, enum rtx_code, rtx, rtx));
00379 static int rtx_equal_for_field_assignment_p PARAMS ((rtx, rtx));
00380 static rtx make_field_assignment PARAMS ((rtx));
00381 static rtx apply_distributive_law PARAMS ((rtx));
00382 static rtx simplify_and_const_int PARAMS ((rtx, enum machine_mode, rtx,
00383 unsigned HOST_WIDE_INT));
00384 static unsigned HOST_WIDE_INT cached_nonzero_bits
00385 PARAMS ((rtx, enum machine_mode, rtx,
00386 enum machine_mode,
00387 unsigned HOST_WIDE_INT));
00388 static unsigned HOST_WIDE_INT nonzero_bits1
00389 PARAMS ((rtx, enum machine_mode, rtx,
00390 enum machine_mode,
00391 unsigned HOST_WIDE_INT));
00392 static unsigned int cached_num_sign_bit_copies
00393 PARAMS ((rtx, enum machine_mode, rtx,
00394 enum machine_mode, unsigned int));
00395 static unsigned int num_sign_bit_copies1
00396 PARAMS ((rtx, enum machine_mode, rtx,
00397 enum machine_mode, unsigned int));
00398 static int merge_outer_ops PARAMS ((enum rtx_code *, HOST_WIDE_INT *,
00399 enum rtx_code, HOST_WIDE_INT,
00400 enum machine_mode, int *));
00401 static rtx simplify_shift_const PARAMS ((rtx, enum rtx_code, enum machine_mode,
00402 rtx, int));
00403 static int recog_for_combine PARAMS ((rtx *, rtx, rtx *));
00404 static rtx gen_lowpart_for_combine PARAMS ((enum machine_mode, rtx));
00405 static rtx gen_binary PARAMS ((enum rtx_code, enum machine_mode,
00406 rtx, rtx));
00407 static enum rtx_code simplify_comparison PARAMS ((enum rtx_code, rtx *, rtx *));
00408 static void update_table_tick PARAMS ((rtx));
00409 static void record_value_for_reg PARAMS ((rtx, rtx, rtx));
00410 static void check_promoted_subreg PARAMS ((rtx, rtx));
00411 static void record_dead_and_set_regs_1 PARAMS ((rtx, rtx, void *));
00412 static void record_dead_and_set_regs PARAMS ((rtx));
00413 static int get_last_value_validate PARAMS ((rtx *, rtx, int, int));
00414 static rtx get_last_value PARAMS ((rtx));
00415 static int use_crosses_set_p PARAMS ((rtx, int));
00416 static void reg_dead_at_p_1 PARAMS ((rtx, rtx, void *));
00417 static int reg_dead_at_p PARAMS ((rtx, rtx));
00418 static void move_deaths PARAMS ((rtx, rtx, int, rtx, rtx *));
00419 static int reg_bitfield_target_p PARAMS ((rtx, rtx));
00420 static void distribute_notes PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
00421 static void distribute_links PARAMS ((rtx));
00422 static void mark_used_regs_combine PARAMS ((rtx));
00423 static int insn_cuid PARAMS ((rtx));
00424 static void record_promoted_value PARAMS ((rtx, rtx));
00425 static rtx reversed_comparison PARAMS ((rtx, enum machine_mode, rtx, rtx));
00426 static enum rtx_code combine_reversed_comparison_code PARAMS ((rtx));
00427
00428
00429
00430
00431
00432
00433
00434 static void
00435 do_SUBST (into, newval)
00436 rtx *into, newval;
00437 {
00438 struct undo *buf;
00439 rtx oldval = *into;
00440
00441 if (oldval == newval)
00442 return;
00443
00444
00445
00446
00447
00448
00449 if (GET_MODE_CLASS (GET_MODE (oldval)) == MODE_INT
00450 && GET_CODE (newval) == CONST_INT)
00451 {
00452
00453
00454 if (INTVAL (newval) != trunc_int_for_mode (INTVAL (newval),
00455 GET_MODE (oldval)))
00456 abort ();
00457
00458
00459
00460
00461
00462
00463
00464 if ((GET_CODE (oldval) == SUBREG
00465 && GET_CODE (SUBREG_REG (oldval)) == CONST_INT)
00466 || (GET_CODE (oldval) == ZERO_EXTEND
00467 && GET_CODE (XEXP (oldval, 0)) == CONST_INT))
00468 abort ();
00469 }
00470
00471 if (undobuf.frees)
00472 buf = undobuf.frees, undobuf.frees = buf->next;
00473 else
00474 buf = (struct undo *) xmalloc (sizeof (struct undo));
00475
00476 buf->is_int = 0;
00477 buf->where.r = into;
00478 buf->old_contents.r = oldval;
00479 *into = newval;
00480
00481 buf->next = undobuf.undos, undobuf.undos = buf;
00482 }
00483
00484 #define SUBST(INTO, NEWVAL) do_SUBST(&(INTO), (NEWVAL))
00485
00486
00487
00488
00489
00490 static void
00491 do_SUBST_INT (into, newval)
00492 int *into, newval;
00493 {
00494 struct undo *buf;
00495 int oldval = *into;
00496
00497 if (oldval == newval)
00498 return;
00499
00500 if (undobuf.frees)
00501 buf = undobuf.frees, undobuf.frees = buf->next;
00502 else
00503 buf = (struct undo *) xmalloc (sizeof (struct undo));
00504
00505 buf->is_int = 1;
00506 buf->where.i = into;
00507 buf->old_contents.i = oldval;
00508 *into = newval;
00509
00510 buf->next = undobuf.undos, undobuf.undos = buf;
00511 }
00512
00513 #define SUBST_INT(INTO, NEWVAL) do_SUBST_INT(&(INTO), (NEWVAL))
00514
00515
00516
00517
00518
00519
00520 int
00521 combine_instructions (f, nregs)
00522 rtx f;
00523 unsigned int nregs;
00524 {
00525 rtx insn, next;
00526 #ifdef HAVE_cc0
00527 rtx prev;
00528 #endif
00529 int i;
00530 rtx links, nextlinks;
00531
00532 int new_direct_jump_p = 0;
00533
00534 combine_attempts = 0;
00535 combine_merges = 0;
00536 combine_extras = 0;
00537 combine_successes = 0;
00538
00539 combine_max_regno = nregs;
00540
00541 reg_nonzero_bits = ((unsigned HOST_WIDE_INT *)
00542 xcalloc (nregs, sizeof (unsigned HOST_WIDE_INT)));
00543 reg_sign_bit_copies
00544 = (unsigned char *) xcalloc (nregs, sizeof (unsigned char));
00545
00546 reg_last_death = (rtx *) xmalloc (nregs * sizeof (rtx));
00547 reg_last_set = (rtx *) xmalloc (nregs * sizeof (rtx));
00548 reg_last_set_value = (rtx *) xmalloc (nregs * sizeof (rtx));
00549 reg_last_set_table_tick = (int *) xmalloc (nregs * sizeof (int));
00550 reg_last_set_label = (int *) xmalloc (nregs * sizeof (int));
00551 reg_last_set_invalid = (char *) xmalloc (nregs * sizeof (char));
00552 reg_last_set_mode
00553 = (enum machine_mode *) xmalloc (nregs * sizeof (enum machine_mode));
00554 reg_last_set_nonzero_bits
00555 = (unsigned HOST_WIDE_INT *) xmalloc (nregs * sizeof (HOST_WIDE_INT));
00556 reg_last_set_sign_bit_copies
00557 = (char *) xmalloc (nregs * sizeof (char));
00558
00559 init_reg_last_arrays ();
00560
00561 init_recog_no_volatile ();
00562
00563
00564
00565 for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
00566 if (INSN_UID (insn) > i)
00567 i = INSN_UID (insn);
00568
00569 uid_cuid = (int *) xmalloc ((i + 1) * sizeof (int));
00570 max_uid_cuid = i;
00571
00572 nonzero_bits_mode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
00573
00574
00575
00576
00577 nonzero_sign_valid = 0;
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 label_tick = 1;
00591
00592
00593
00594 subst_prev_insn = NULL_RTX;
00595
00596 setup_incoming_promotions ();
00597
00598 refresh_blocks = sbitmap_alloc (last_basic_block);
00599 sbitmap_zero (refresh_blocks);
00600 need_refresh = 0;
00601
00602 for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
00603 {
00604 uid_cuid[INSN_UID (insn)] = ++i;
00605 subst_low_cuid = i;
00606 subst_insn = insn;
00607
00608 if (INSN_P (insn))
00609 {
00610 note_stores (PATTERN (insn), set_nonzero_bits_and_sign_copies,
00611 NULL);
00612 record_dead_and_set_regs (insn);
00613
00614 #ifdef AUTO_INC_DEC
00615 for (links = REG_NOTES (insn); links; links = XEXP (links, 1))
00616 if (REG_NOTE_KIND (links) == REG_INC)
00617 set_nonzero_bits_and_sign_copies (XEXP (links, 0), NULL_RTX,
00618 NULL);
00619 #endif
00620 }
00621
00622 if (GET_CODE (insn) == CODE_LABEL)
00623 label_tick++;
00624 }
00625
00626 nonzero_sign_valid = 1;
00627
00628
00629
00630 label_tick = 1;
00631 last_call_cuid = 0;
00632 mem_last_set = 0;
00633 init_reg_last_arrays ();
00634 setup_incoming_promotions ();
00635
00636 FOR_EACH_BB (this_basic_block)
00637 {
00638 for (insn = this_basic_block->head;
00639 insn != NEXT_INSN (this_basic_block->end);
00640 insn = next ? next : NEXT_INSN (insn))
00641 {
00642 next = 0;
00643
00644 if (GET_CODE (insn) == CODE_LABEL)
00645 label_tick++;
00646
00647 else if (INSN_P (insn))
00648 {
00649
00650
00651 check_promoted_subreg (insn, PATTERN (insn));
00652
00653
00654
00655 for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
00656 if ((next = try_combine (insn, XEXP (links, 0),
00657 NULL_RTX, &new_direct_jump_p)) != 0)
00658 goto retry;
00659
00660
00661
00662 for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
00663 {
00664 rtx link = XEXP (links, 0);
00665
00666
00667
00668 if (GET_CODE (link) == NOTE)
00669 continue;
00670
00671 for (nextlinks = LOG_LINKS (link);
00672 nextlinks;
00673 nextlinks = XEXP (nextlinks, 1))
00674 if ((next = try_combine (insn, link,
00675 XEXP (nextlinks, 0),
00676 &new_direct_jump_p)) != 0)
00677 goto retry;
00678 }
00679
00680 #ifdef HAVE_cc0
00681
00682
00683
00684
00685
00686
00687
00688 if (GET_CODE (insn) == JUMP_INSN
00689 && (prev = prev_nonnote_insn (insn)) != 0
00690 && GET_CODE (prev) == INSN
00691 && sets_cc0_p (PATTERN (prev)))
00692 {
00693 if ((next = try_combine (insn, prev,
00694 NULL_RTX, &new_direct_jump_p)) != 0)
00695 goto retry;
00696
00697 for (nextlinks = LOG_LINKS (prev); nextlinks;
00698 nextlinks = XEXP (nextlinks, 1))
00699 if ((next = try_combine (insn, prev,
00700 XEXP (nextlinks, 0),
00701 &new_direct_jump_p)) != 0)
00702 goto retry;
00703 }
00704
00705
00706 if (GET_CODE (insn) == INSN
00707 && (prev = prev_nonnote_insn (insn)) != 0
00708 && GET_CODE (prev) == INSN
00709 && sets_cc0_p (PATTERN (prev))
00710 && GET_CODE (PATTERN (insn)) == SET
00711 && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (insn))))
00712 {
00713 if ((next = try_combine (insn, prev,
00714 NULL_RTX, &new_direct_jump_p)) != 0)
00715 goto retry;
00716
00717 for (nextlinks = LOG_LINKS (prev); nextlinks;
00718 nextlinks = XEXP (nextlinks, 1))
00719 if ((next = try_combine (insn, prev,
00720 XEXP (nextlinks, 0),
00721 &new_direct_jump_p)) != 0)
00722 goto retry;
00723 }
00724
00725
00726
00727
00728 for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
00729 if (GET_CODE (XEXP (links, 0)) == INSN
00730 && GET_CODE (PATTERN (XEXP (links, 0))) == SET
00731 && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (XEXP (links, 0))))
00732 && (prev = prev_nonnote_insn (XEXP (links, 0))) != 0
00733 && GET_CODE (prev) == INSN
00734 && sets_cc0_p (PATTERN (prev))
00735 && (next = try_combine (insn, XEXP (links, 0),
00736 prev, &new_direct_jump_p)) != 0)
00737 goto retry;
00738 #endif
00739
00740
00741
00742 for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
00743 for (nextlinks = XEXP (links, 1); nextlinks;
00744 nextlinks = XEXP (nextlinks, 1))
00745 if ((next = try_combine (insn, XEXP (links, 0),
00746 XEXP (nextlinks, 0),
00747 &new_direct_jump_p)) != 0)
00748 goto retry;
00749
00750 if (GET_CODE (insn) != NOTE)
00751 record_dead_and_set_regs (insn);
00752
00753 retry:
00754 ;
00755 }
00756 }
00757 }
00758 clear_bb_flags ();
00759
00760 EXECUTE_IF_SET_IN_SBITMAP (refresh_blocks, 0, i,
00761 BASIC_BLOCK (i)->flags |= BB_DIRTY);
00762 new_direct_jump_p |= purge_all_dead_edges (0);
00763 delete_noop_moves (f);
00764
00765 update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
00766 PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
00767 | PROP_KILL_DEAD_CODE);
00768
00769
00770 sbitmap_free (refresh_blocks);
00771 free (reg_nonzero_bits);
00772 free (reg_sign_bit_copies);
00773 free (reg_last_death);
00774 free (reg_last_set);
00775 free (reg_last_set_value);
00776 free (reg_last_set_table_tick);
00777 free (reg_last_set_label);
00778 free (reg_last_set_invalid);
00779 free (reg_last_set_mode);
00780 free (reg_last_set_nonzero_bits);
00781 free (reg_last_set_sign_bit_copies);
00782 free (uid_cuid);
00783
00784 {
00785 struct undo *undo, *next;
00786 for (undo = undobuf.frees; undo; undo = next)
00787 {
00788 next = undo->next;
00789 free (undo);
00790 }
00791 undobuf.frees = 0;
00792 }
00793
00794 total_attempts += combine_attempts;
00795 total_merges += combine_merges;
00796 total_extras += combine_extras;
00797 total_successes += combine_successes;
00798
00799 nonzero_sign_valid = 0;
00800
00801
00802 init_recog ();
00803
00804 return new_direct_jump_p;
00805 }
00806
00807
00808
00809 static void
00810 init_reg_last_arrays ()
00811 {
00812 unsigned int nregs = combine_max_regno;
00813
00814 memset ((char *) reg_last_death, 0, nregs * sizeof (rtx));
00815 memset ((char *) reg_last_set, 0, nregs * sizeof (rtx));
00816 memset ((char *) reg_last_set_value, 0, nregs * sizeof (rtx));
00817 memset ((char *) reg_last_set_table_tick, 0, nregs * sizeof (int));
00818 memset ((char *) reg_last_set_label, 0, nregs * sizeof (int));
00819 memset (reg_last_set_invalid, 0, nregs * sizeof (char));
00820 memset ((char *) reg_last_set_mode, 0, nregs * sizeof (enum machine_mode));
00821 memset ((char *) reg_last_set_nonzero_bits, 0, nregs * sizeof (HOST_WIDE_INT));
00822 memset (reg_last_set_sign_bit_copies, 0, nregs * sizeof (char));
00823 }
00824
00825
00826
00827 static void
00828 setup_incoming_promotions ()
00829 {
00830 #ifdef PROMOTE_FUNCTION_ARGS
00831 unsigned int regno;
00832 rtx reg;
00833 enum machine_mode mode;
00834 int unsignedp;
00835 rtx first = get_insns ();
00836
00837 #ifndef OUTGOING_REGNO
00838 #define OUTGOING_REGNO(N) N
00839 #endif
00840 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
00841
00842
00843
00844 if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (regno))
00845 && (reg = promoted_input_arg (regno, &mode, &unsignedp)) != 0)
00846 {
00847 record_value_for_reg
00848 (reg, first, gen_rtx_fmt_e ((unsignedp ? ZERO_EXTEND
00849 : SIGN_EXTEND),
00850 GET_MODE (reg),
00851 gen_rtx_CLOBBER (mode, const0_rtx)));
00852 }
00853 #endif
00854 }
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 static void
00868 set_nonzero_bits_and_sign_copies (x, set, data)
00869 rtx x;
00870 rtx set;
00871 void *data ATTRIBUTE_UNUSED;
00872 {
00873 unsigned int num;
00874
00875 if (GET_CODE (x) == REG
00876 && REGNO (x) >= FIRST_PSEUDO_REGISTER
00877
00878
00879 && ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, REGNO (x))
00880 && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
00881 {
00882 if (set == 0 || GET_CODE (set) == CLOBBER)
00883 {
00884 reg_nonzero_bits[REGNO (x)] = GET_MODE_MASK (GET_MODE (x));
00885 reg_sign_bit_copies[REGNO (x)] = 1;
00886 return;
00887 }
00888
00889
00890
00891 set = expand_field_assignment (set);
00892
00893
00894
00895
00896 if (SET_DEST (set) == x
00897 || (GET_CODE (SET_DEST (set)) == SUBREG
00898 && (GET_MODE_SIZE (GET_MODE (SET_DEST (set)))
00899 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (set)))))
00900 && SUBREG_REG (SET_DEST (set)) == x))
00901 {
00902 rtx src = SET_SRC (set);
00903
00904 #ifdef SHORT_IMMEDIATES_SIGN_EXTEND
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914 if (GET_MODE_BITSIZE (GET_MODE (x)) < BITS_PER_WORD
00915 && GET_CODE (src) == CONST_INT
00916 && INTVAL (src) > 0
00917 && 0 != (INTVAL (src)
00918 & ((HOST_WIDE_INT) 1
00919 << (GET_MODE_BITSIZE (GET_MODE (x)) - 1))))
00920 src = GEN_INT (INTVAL (src)
00921 | ((HOST_WIDE_INT) (-1)
00922 << GET_MODE_BITSIZE (GET_MODE (x))));
00923 #endif
00924
00925
00926 if (reg_nonzero_bits[REGNO (x)] != ~(unsigned HOST_WIDE_INT) 0)
00927 reg_nonzero_bits[REGNO (x)]
00928 |= nonzero_bits (src, nonzero_bits_mode);
00929 num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
00930 if (reg_sign_bit_copies[REGNO (x)] == 0
00931 || reg_sign_bit_copies[REGNO (x)] > num)
00932 reg_sign_bit_copies[REGNO (x)] = num;
00933 }
00934 else
00935 {
00936 reg_nonzero_bits[REGNO (x)] = GET_MODE_MASK (GET_MODE (x));
00937 reg_sign_bit_copies[REGNO (x)] = 1;
00938 }
00939 }
00940 }
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952 static int
00953 can_combine_p (insn, i3, pred, succ, pdest, psrc)
00954 rtx insn;
00955 rtx i3;
00956 rtx pred ATTRIBUTE_UNUSED;
00957 rtx succ;
00958 rtx *pdest, *psrc;
00959 {
00960 int i;
00961 rtx set = 0, src, dest;
00962 rtx p;
00963 #ifdef AUTO_INC_DEC
00964 rtx link;
00965 #endif
00966 int all_adjacent = (succ ? (next_active_insn (insn) == succ
00967 && next_active_insn (succ) == i3)
00968 : next_active_insn (insn) == i3);
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985 if (GET_CODE (PATTERN (insn)) == SET)
00986 set = PATTERN (insn);
00987 else if (GET_CODE (PATTERN (insn)) == PARALLEL
00988 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
00989 {
00990 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
00991 {
00992 rtx elt = XVECEXP (PATTERN (insn), 0, i);
00993
00994 switch (GET_CODE (elt))
00995 {
00996
00997
00998 case USE:
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012 if (GET_CODE (XEXP (elt, 0)) == REG
01013 && GET_CODE (PATTERN (i3)) == PARALLEL)
01014 {
01015 rtx i3pat = PATTERN (i3);
01016 int i = XVECLEN (i3pat, 0) - 1;
01017 unsigned int regno = REGNO (XEXP (elt, 0));
01018
01019 do
01020 {
01021 rtx i3elt = XVECEXP (i3pat, 0, i);
01022
01023 if (GET_CODE (i3elt) == USE
01024 && GET_CODE (XEXP (i3elt, 0)) == REG
01025 && (REGNO (XEXP (i3elt, 0)) == regno
01026 ? reg_set_between_p (XEXP (elt, 0),
01027 PREV_INSN (insn), i3)
01028 : regno >= FIRST_PSEUDO_REGISTER))
01029 return 0;
01030 }
01031 while (--i >= 0);
01032 }
01033 break;
01034
01035
01036 case CLOBBER:
01037 break;
01038
01039 case SET:
01040
01041
01042 if (find_reg_note (insn, REG_UNUSED, SET_DEST (elt))
01043 && ! side_effects_p (elt))
01044 break;
01045
01046
01047
01048 if (set)
01049 return 0;
01050
01051 set = elt;
01052 break;
01053
01054 default:
01055
01056 return 0;
01057 }
01058 }
01059
01060 if (set == 0
01061
01062
01063 || GET_CODE (SET_SRC (set)) == ASM_OPERANDS)
01064 return 0;
01065 }
01066 else
01067 return 0;
01068
01069 if (set == 0)
01070 return 0;
01071
01072 set = expand_field_assignment (set);
01073 src = SET_SRC (set), dest = SET_DEST (set);
01074
01075
01076 if (dest == stack_pointer_rtx
01077
01078 || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == STRICT_LOW_PART
01079
01080
01081 || (rtx_equal_p (src, dest) && find_reg_note (insn, REG_EQUAL, NULL_RTX))
01082
01083 || GET_CODE (src) == ASM_OPERANDS
01084
01085 || GET_CODE (src) == CALL
01086
01087 || (GET_CODE (i3) == CALL_INSN
01088 && (find_reg_fusage (i3, USE, dest)
01089 || (GET_CODE (dest) == REG
01090 && REGNO (dest) < FIRST_PSEUDO_REGISTER
01091 && global_regs[REGNO (dest)])))
01092
01093 || FIND_REG_INC_NOTE (i3, dest)
01094 || (succ && FIND_REG_INC_NOTE (succ, dest))
01095 #if 0
01096
01097
01098
01099
01100
01101 || find_reg_note (insn, REG_RETVAL, NULL_RTX)
01102 #endif
01103
01104 || (succ && ! all_adjacent
01105 && reg_used_between_p (dest, succ, i3))
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115 || (! all_adjacent
01116 && (((GET_CODE (src) != MEM
01117 || ! find_reg_note (insn, REG_EQUIV, src))
01118 && use_crosses_set_p (src, INSN_CUID (insn)))
01119 || (GET_CODE (src) == ASM_OPERANDS && MEM_VOLATILE_P (src))
01120 || GET_CODE (src) == UNSPEC_VOLATILE))
01121
01122
01123 || find_reg_note (i3, REG_NO_CONFLICT, dest)
01124 || (succ && find_reg_note (succ, REG_NO_CONFLICT, dest))
01125
01126
01127
01128
01129
01130 || (INSN_CUID (insn) < last_call_cuid && ! CONSTANT_P (src)))
01131 return 0;
01132
01133
01134 if (GET_CODE (dest) == REG)
01135 {
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145 if (GET_CODE (src) == REG
01146 && ((REGNO (dest) < FIRST_PSEUDO_REGISTER
01147 && ! HARD_REGNO_MODE_OK (REGNO (dest), GET_MODE (dest)))
01148
01149
01150
01151
01152
01153
01154
01155 || (REGNO (src) < FIRST_PSEUDO_REGISTER
01156 && ! HARD_REGNO_MODE_OK (REGNO (src), GET_MODE (src)))))
01157 return 0;
01158 }
01159 else if (GET_CODE (dest) != CC0)
01160 return 0;
01161
01162
01163
01164
01165 if (GET_CODE (PATTERN (i3)) == PARALLEL)
01166 for (i = XVECLEN (PATTERN (i3), 0) - 1; i >= 0; i--)
01167 if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER
01168 && (reg_overlap_mentioned_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0),
01169 src)
01170 || rtx_equal_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0), dest)))
01171 return 0;
01172
01173
01174
01175
01176 if (GET_CODE (src) == ASM_OPERANDS || volatile_refs_p (src))
01177 {
01178
01179 if (succ != 0 && volatile_refs_p (PATTERN (succ)))
01180 return 0;
01181
01182 for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p))
01183 if (INSN_P (p) && p != succ && volatile_refs_p (PATTERN (p)))
01184 return 0;
01185 }
01186
01187
01188
01189
01190 if (GET_CODE (src) == ASM_OPERANDS
01191 && GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER)
01192 return 0;
01193
01194
01195
01196
01197 for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p))
01198 if (INSN_P (p) && p != succ && volatile_insn_p (PATTERN (p)))
01199 return 0;
01200
01201
01202
01203
01204
01205
01206
01207 #ifdef AUTO_INC_DEC
01208 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
01209 if (REG_NOTE_KIND (link) == REG_INC
01210 && (GET_CODE (i3) == JUMP_INSN
01211 || reg_used_between_p (XEXP (link, 0), insn, i3)
01212 || reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i3))))
01213 return 0;
01214 #endif
01215
01216 #ifdef HAVE_cc0
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226 p = prev_nonnote_insn (insn);
01227 if (p && p != pred && GET_CODE (p) == INSN && sets_cc0_p (PATTERN (p))
01228 && ! all_adjacent)
01229 return 0;
01230 #endif
01231
01232
01233
01234
01235 *pdest = dest;
01236 *psrc = src;
01237
01238 return 1;
01239 }
01240
01241
01242
01243
01244 static int
01245 sets_function_arg_p (pat)
01246 rtx pat;
01247 {
01248 int i;
01249 rtx inner_dest;
01250
01251 switch (GET_CODE (pat))
01252 {
01253 case INSN:
01254 return sets_function_arg_p (PATTERN (pat));
01255
01256 case PARALLEL:
01257 for (i = XVECLEN (pat, 0); --i >= 0;)
01258 if (sets_function_arg_p (XVECEXP (pat, 0, i)))
01259 return 1;
01260
01261 break;
01262
01263 case SET:
01264 inner_dest = SET_DEST (pat);
01265 while (GET_CODE (inner_dest) == STRICT_LOW_PART
01266 || GET_CODE (inner_dest) == SUBREG
01267 || GET_CODE (inner_dest) == ZERO_EXTRACT)
01268 inner_dest = XEXP (inner_dest, 0);
01269
01270 return (GET_CODE (inner_dest) == REG
01271 && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER
01272 && FUNCTION_ARG_REGNO_P (REGNO (inner_dest)));
01273
01274 default:
01275 break;
01276 }
01277
01278 return 0;
01279 }
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318 static int
01319 combinable_i3pat (i3, loc, i2dest, i1dest, i1_not_in_src, pi3dest_killed)
01320 rtx i3;
01321 rtx *loc;
01322 rtx i2dest;
01323 rtx i1dest;
01324 int i1_not_in_src;
01325 rtx *pi3dest_killed;
01326 {
01327 rtx x = *loc;
01328
01329 if (GET_CODE (x) == SET)
01330 {
01331 rtx set = expand_field_assignment (x);
01332 rtx dest = SET_DEST (set);
01333 rtx src = SET_SRC (set);
01334 rtx inner_dest = dest;
01335
01336 #if 0
01337 rtx inner_src = src;
01338 #endif
01339
01340 SUBST (*loc, set);
01341
01342 while (GET_CODE (inner_dest) == STRICT_LOW_PART
01343 || GET_CODE (inner_dest) == SUBREG
01344 || GET_CODE (inner_dest) == ZERO_EXTRACT)
01345 inner_dest = XEXP (inner_dest, 0);
01346
01347
01348
01349 #if 0
01350 while (GET_CODE (inner_src) == STRICT_LOW_PART
01351 || GET_CODE (inner_src) == SUBREG
01352 || GET_CODE (inner_src) == ZERO_EXTRACT)
01353 inner_src = XEXP (inner_src, 0);
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365 if (rtx_equal_p (inner_src, i2dest)
01366 && GET_CODE (inner_dest) == REG
01367 && ! MODES_TIEABLE_P (GET_MODE (i2dest), GET_MODE (inner_dest)))
01368 return 0;
01369 #endif
01370
01371
01372
01373 if ((inner_dest != dest
01374 && (reg_overlap_mentioned_p (i2dest, inner_dest)
01375 || (i1dest && reg_overlap_mentioned_p (i1dest, inner_dest))))
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387 || (GET_CODE (inner_dest) == REG
01388 && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER
01389 && (! HARD_REGNO_MODE_OK (REGNO (inner_dest),
01390 GET_MODE (inner_dest))))
01391 || (i1_not_in_src && reg_overlap_mentioned_p (i1dest, src)))
01392 return 0;
01393
01394
01395
01396
01397
01398
01399 if (pi3dest_killed && GET_CODE (dest) == REG
01400 && reg_referenced_p (dest, PATTERN (i3))
01401 && REGNO (dest) != FRAME_POINTER_REGNUM
01402 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
01403 && REGNO (dest) != HARD_FRAME_POINTER_REGNUM
01404 #endif
01405 #if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
01406 && (REGNO (dest) != ARG_POINTER_REGNUM
01407 || ! fixed_regs [REGNO (dest)])
01408 #endif
01409 && REGNO (dest) != STACK_POINTER_REGNUM)
01410 {
01411 if (*pi3dest_killed)
01412 return 0;
01413
01414 *pi3dest_killed = dest;
01415 }
01416 }
01417
01418 else if (GET_CODE (x) == PARALLEL)
01419 {
01420 int i;
01421
01422 for (i = 0; i < XVECLEN (x, 0); i++)
01423 if (! combinable_i3pat (i3, &XVECEXP (x, 0, i), i2dest, i1dest,
01424 i1_not_in_src, pi3dest_killed))
01425 return 0;
01426 }
01427
01428 return 1;
01429 }
01430
01431
01432
01433
01434 static int
01435 contains_muldiv (x)
01436 rtx x;
01437 {
01438 switch (GET_CODE (x))
01439 {
01440 case MOD: case DIV: case UMOD: case UDIV:
01441 return 1;
01442
01443 case MULT:
01444 return ! (GET_CODE (XEXP (x, 1)) == CONST_INT
01445 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0);
01446 default:
01447 switch (GET_RTX_CLASS (GET_CODE (x)))
01448 {
01449 case 'c': case '<': case '2':
01450 return contains_muldiv (XEXP (x, 0))
01451 || contains_muldiv (XEXP (x, 1));
01452
01453 case '1':
01454 return contains_muldiv (XEXP (x, 0));
01455
01456 default:
01457 return 0;
01458 }
01459 }
01460 }
01461
01462
01463
01464
01465
01466 static int
01467 cant_combine_insn_p (insn)
01468 rtx insn;
01469 {
01470 rtx set;
01471 rtx src, dest;
01472
01473
01474
01475
01476 if (! INSN_P (insn))
01477 return 1;
01478
01479
01480
01481
01482
01483
01484
01485
01486 set = single_set (insn);
01487 if (! set)
01488 return 0;
01489 src = SET_SRC (set);
01490 dest = SET_DEST (set);
01491 if (GET_CODE (src) == SUBREG)
01492 src = SUBREG_REG (src);
01493 if (GET_CODE (dest) == SUBREG)
01494 dest = SUBREG_REG (dest);
01495 if (REG_P (src) && REG_P (dest)
01496 && ((REGNO (src) < FIRST_PSEUDO_REGISTER
01497 && ! fixed_regs[REGNO (src)])
01498 || (REGNO (dest) < FIRST_PSEUDO_REGISTER
01499 && ! fixed_regs[REGNO (dest)])))
01500 return 1;
01501
01502 return 0;
01503 }
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521 static rtx
01522 try_combine (i3, i2, i1, new_direct_jump_p)
01523 rtx i3, i2, i1;
01524 int *new_direct_jump_p;
01525 {
01526
01527 rtx newpat, newi2pat = 0;
01528 int substed_i2 = 0, substed_i1 = 0;
01529
01530 int added_sets_1, added_sets_2;
01531
01532 int total_sets;
01533
01534 int i2_is_used;
01535
01536 int insn_code_number, i2_code_number = 0, other_code_number = 0;
01537
01538
01539
01540 rtx i3dest_killed = 0;
01541
01542 rtx i2dest, i2src, i1dest = 0, i1src = 0;
01543
01544 rtx i2pat;
01545
01546 int i2dest_in_i2src = 0, i1dest_in_i1src = 0, i2dest_in_i1src = 0;
01547 int i1_feeds_i3 = 0;
01548
01549 rtx new_i3_notes, new_i2_notes;
01550
01551 int i3_subst_into_i2 = 0;
01552
01553 int have_mult = 0;
01554
01555 int maxreg;
01556 rtx temp;
01557 rtx link;
01558 int i;
01559
01560
01561
01562 if (cant_combine_insn_p (i3)
01563 || cant_combine_insn_p (i2)
01564 || (i1 && cant_combine_insn_p (i1))
01565
01566
01567
01568 #if 0
01569
01570
01571 || find_reg_note (i3, REG_LIBCALL, NULL_RTX)
01572 #endif
01573 )
01574 return 0;
01575
01576 combine_attempts++;
01577 undobuf.other_insn = 0;
01578
01579
01580 CLEAR_HARD_REG_SET (newpat_used_regs);
01581
01582
01583
01584 if (i1 && INSN_CUID (i1) > INSN_CUID (i2))
01585 temp = i1, i1 = i2, i2 = temp;
01586
01587 added_links_insn = 0;
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605 if (i1 == 0 && GET_CODE (i3) == INSN && GET_CODE (PATTERN (i3)) == SET
01606 && GET_CODE (SET_SRC (PATTERN (i3))) == REG
01607 && REGNO (SET_SRC (PATTERN (i3))) >= FIRST_PSEUDO_REGISTER
01608 && find_reg_note (i3, REG_DEAD, SET_SRC (PATTERN (i3)))
01609 && GET_CODE (PATTERN (i2)) == PARALLEL
01610 && ! side_effects_p (SET_DEST (PATTERN (i3)))
01611
01612
01613
01614
01615 && GET_CODE (SET_DEST (PATTERN (i3))) != ZERO_EXTRACT
01616 && GET_CODE (SET_DEST (PATTERN (i3))) != STRICT_LOW_PART
01617 && ! reg_overlap_mentioned_p (SET_SRC (PATTERN (i3)),
01618 SET_DEST (PATTERN (i3)))
01619 && next_real_insn (i2) == i3)
01620 {
01621 rtx p2 = PATTERN (i2);
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633 for (i = 0; i < XVECLEN (p2, 0); i++)
01634 if ((GET_CODE (XVECEXP (p2, 0, i)) == SET
01635 || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER)
01636 && reg_overlap_mentioned_p (SET_DEST (PATTERN (i3)),
01637 SET_DEST (XVECEXP (p2, 0, i))))
01638 break;
01639
01640 if (i == XVECLEN (p2, 0))
01641 for (i = 0; i < XVECLEN (p2, 0); i++)
01642 if ((GET_CODE (XVECEXP (p2, 0, i)) == SET
01643 || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER)
01644 && SET_DEST (XVECEXP (p2, 0, i)) == SET_SRC (PATTERN (i3)))
01645 {
01646 combine_merges++;
01647
01648 subst_insn = i3;
01649 subst_low_cuid = INSN_CUID (i2);
01650
01651 added_sets_2 = added_sets_1 = 0;
01652 i2dest = SET_SRC (PATTERN (i3));
01653
01654
01655
01656
01657 SUBST (SET_DEST (XVECEXP (p2, 0, i)),
01658 SET_DEST (PATTERN (i3)));
01659
01660 newpat = p2;
01661 i3_subst_into_i2 = 1;
01662 goto validate_replacement;
01663 }
01664 }
01665
01666
01667
01668
01669 if (i1 == 0
01670 && (temp = single_set (i2)) != 0
01671 && (GET_CODE (SET_SRC (temp)) == CONST_INT
01672 || GET_CODE (SET_SRC (temp)) == CONST_DOUBLE)
01673 && GET_CODE (SET_DEST (temp)) == REG
01674 && GET_MODE_CLASS (GET_MODE (SET_DEST (temp))) == MODE_INT
01675 && GET_MODE_SIZE (GET_MODE (SET_DEST (temp))) == 2 * UNITS_PER_WORD
01676 && GET_CODE (PATTERN (i3)) == SET
01677 && GET_CODE (SET_DEST (PATTERN (i3))) == SUBREG
01678 && SUBREG_REG (SET_DEST (PATTERN (i3))) == SET_DEST (temp)
01679 && GET_MODE_CLASS (GET_MODE (SET_DEST (PATTERN (i3)))) == MODE_INT
01680 && GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (i3)))) == UNITS_PER_WORD
01681 && GET_CODE (SET_SRC (PATTERN (i3))) == CONST_INT)
01682 {
01683 HOST_WIDE_INT lo, hi;
01684
01685 if (GET_CODE (SET_SRC (temp)) == CONST_INT)
01686 lo = INTVAL (SET_SRC (temp)), hi = lo < 0 ? -1 : 0;
01687 else
01688 {
01689 lo = CONST_DOUBLE_LOW (SET_SRC (temp));
01690 hi = CONST_DOUBLE_HIGH (SET_SRC (temp));
01691 }
01692
01693 if (subreg_lowpart_p (SET_DEST (PATTERN (i3))))
01694 {
01695
01696
01697 if (HOST_BITS_PER_WIDE_INT < BITS_PER_WORD)
01698 abort ();
01699
01700 lo &= ~(UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD (1) - 1);
01701 lo |= (INTVAL (SET_SRC (PATTERN (i3)))
01702 & (UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD (1) - 1));
01703 }
01704 else if (HOST_BITS_PER_WIDE_INT == BITS_PER_WORD)
01705 hi = INTVAL (SET_SRC (PATTERN (i3)));
01706 else if (HOST_BITS_PER_WIDE_INT >= 2 * BITS_PER_WORD)
01707 {
01708 int sign = -(int) ((unsigned HOST_WIDE_INT) lo
01709 >> (HOST_BITS_PER_WIDE_INT - 1));
01710
01711 lo &= ~ (UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD
01712 (UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD (1) - 1));
01713 lo |= (UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD
01714 (INTVAL (SET_SRC (PATTERN (i3)))));
01715 if (hi == sign)
01716 hi = lo < 0 ? -1 : 0;
01717 }
01718 else
01719
01720
01721 abort ();
01722
01723 combine_merges++;
01724 subst_insn = i3;
01725 subst_low_cuid = INSN_CUID (i2);
01726 added_sets_2 = added_sets_1 = 0;
01727 i2dest = SET_DEST (temp);
01728
01729 SUBST (SET_SRC (temp),
01730 immed_double_const (lo, hi, GET_MODE (SET_DEST (temp))));
01731
01732 newpat = PATTERN (i2);
01733 goto validate_replacement;
01734 }
01735
01736 #ifndef HAVE_cc0
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750 if (i1 == 0 && GET_CODE (PATTERN (i2)) == PARALLEL
01751 && XVECLEN (PATTERN (i2), 0) >= 2
01752 && GET_CODE (XVECEXP (PATTERN (i2), 0, 0)) == SET
01753 && (GET_MODE_CLASS (GET_MODE (SET_DEST (XVECEXP (PATTERN (i2), 0, 0))))
01754 == MODE_CC)
01755 && GET_CODE (SET_SRC (XVECEXP (PATTERN (i2), 0, 0))) == COMPARE
01756 && XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 1) == const0_rtx
01757 && GET_CODE (XVECEXP (PATTERN (i2), 0, 1)) == SET
01758 && GET_CODE (SET_DEST (XVECEXP (PATTERN (i2), 0, 1))) == REG
01759 && rtx_equal_p (XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 0),
01760 SET_SRC (XVECEXP (PATTERN (i2), 0, 1))))
01761 {
01762 for (i = XVECLEN (PATTERN (i2), 0) - 1; i >= 2; i--)
01763 if (GET_CODE (XVECEXP (PATTERN (i2), 0, i)) != CLOBBER)
01764 break;
01765
01766 if (i == 1)
01767 {
01768
01769
01770
01771
01772
01773 subst_prev_insn = i1
01774 = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2,
01775 BLOCK_FOR_INSN (i2), INSN_SCOPE (i2),
01776 XVECEXP (PATTERN (i2), 0, 1), -1, NULL_RTX,
01777 NULL_RTX);
01778
01779 SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0));
01780 SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),
01781 SET_DEST (PATTERN (i1)));
01782 }
01783 }
01784 #endif
01785
01786
01787 if (! can_combine_p (i2, i3, i1, NULL_RTX, &i2dest, &i2src)
01788 || (i1 && ! can_combine_p (i1, i3, NULL_RTX, i2, &i1dest, &i1src)))
01789 {
01790 undo_all ();
01791 return 0;
01792 }
01793
01794
01795
01796 i2dest_in_i2src = reg_overlap_mentioned_p (i2dest, i2src);
01797 i1dest_in_i1src = i1 && reg_overlap_mentioned_p (i1dest, i1src);
01798 i2dest_in_i1src = i1 && reg_overlap_mentioned_p (i2dest, i1src);
01799
01800
01801
01802 i1_feeds_i3 = i1 && ! reg_overlap_mentioned_p (i1dest, i2src);
01803
01804
01805 if (! combinable_i3pat (i3, &PATTERN (i3), i2dest, i1dest,
01806 i1 && i2dest_in_i1src && i1_feeds_i3,
01807 &i3dest_killed))
01808 {
01809 undo_all ();
01810 return 0;
01811 }
01812
01813
01814
01815
01816 if (GET_CODE (i2src) == MULT
01817 || (i1 != 0 && GET_CODE (i1src) == MULT)
01818 || (GET_CODE (PATTERN (i3)) == SET
01819 && GET_CODE (SET_SRC (PATTERN (i3))) == MULT))
01820 have_mult = 1;
01821
01822
01823
01824
01825
01826
01827
01828
01829 #if 0
01830 if (!(GET_CODE (PATTERN (i3)) == SET
01831 && GET_CODE (SET_SRC (PATTERN (i3))) == REG
01832 && GET_CODE (SET_DEST (PATTERN (i3))) == MEM
01833 && (GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_INC
01834 || GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_DEC)))
01835
01836 #endif
01837 #ifdef AUTO_INC_DEC
01838 for (link = REG_NOTES (i3); link; link = XEXP (link, 1))
01839 if (REG_NOTE_KIND (link) == REG_INC
01840 && (reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i2))
01841 || (i1 != 0
01842 && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i1)))))
01843 {
01844 undo_all ();
01845 return 0;
01846 }
01847 #endif
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860 added_sets_2 = ! dead_or_set_p (i3, i2dest);
01861
01862 added_sets_1
01863 = i1 && ! (i1_feeds_i3 ? dead_or_set_p (i3, i1dest)
01864 : (dead_or_set_p (i3, i1dest) || dead_or_set_p (i2, i1dest)));
01865
01866
01867
01868
01869
01870
01871
01872
01873 i2pat = (GET_CODE (PATTERN (i2)) == PARALLEL
01874 ? gen_rtx_SET (VOIDmode, i2dest, i2src)
01875 : PATTERN (i2));
01876
01877 if (added_sets_2)
01878 i2pat = copy_rtx (i2pat);
01879
01880 combine_merges++;
01881
01882
01883
01884 maxreg = max_reg_num ();
01885
01886 subst_insn = i3;
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902 if (flag_expensive_optimizations)
01903 {
01904
01905
01906
01907 if (i1)
01908 {
01909 subst_low_cuid = INSN_CUID (i1);
01910 i1src = subst (i1src, pc_rtx, pc_rtx, 0, 0);
01911 }
01912 else
01913 {
01914 subst_low_cuid = INSN_CUID (i2);
01915 i2src = subst (i2src, pc_rtx, pc_rtx, 0, 0);
01916 }
01917 }
01918
01919 #ifndef HAVE_cc0
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931 if (i1 == 0 && added_sets_2 && GET_CODE (PATTERN (i3)) == SET
01932 && GET_CODE (SET_SRC (PATTERN (i3))) == COMPARE
01933 && XEXP (SET_SRC (PATTERN (i3)), 1) == const0_rtx
01934 && rtx_equal_p (XEXP (SET_SRC (PATTERN (i3)), 0), i2dest))
01935 {
01936 #ifdef EXTRA_CC_MODES
01937 rtx *cc_use;
01938 enum machine_mode compare_mode;
01939 #endif
01940
01941 newpat = PATTERN (i3);
01942 SUBST (XEXP (SET_SRC (newpat), 0), i2src);
01943
01944 i2_is_used = 1;
01945
01946 #ifdef EXTRA_CC_MODES
01947
01948
01949
01950
01951
01952 if (undobuf.other_insn == 0
01953 && (cc_use = find_single_use (SET_DEST (newpat), i3,
01954 &undobuf.other_insn))
01955 && ((compare_mode = SELECT_CC_MODE (GET_CODE (*cc_use),
01956 i2src, const0_rtx))
01957 != GET_MODE (SET_DEST (newpat))))
01958 {
01959 unsigned int regno = REGNO (SET_DEST (newpat));
01960 rtx new_dest = gen_rtx_REG (compare_mode, regno);
01961
01962 if (regno < FIRST_PSEUDO_REGISTER
01963 || (REG_N_SETS (regno) == 1 && ! added_sets_2
01964 && ! REG_USERVAR_P (SET_DEST (newpat))))
01965 {
01966 if (regno >= FIRST_PSEUDO_REGISTER)
01967 SUBST (regno_reg_rtx[regno], new_dest);
01968
01969 SUBST (SET_DEST (newpat), new_dest);
01970 SUBST (XEXP (*cc_use, 0), new_dest);
01971 SUBST (SET_SRC (newpat),
01972 gen_rtx_COMPARE (compare_mode, i2src, const0_rtx));
01973 }
01974 else
01975 undobuf.other_insn = 0;
01976 }
01977 #endif
01978 }
01979 else
01980 #endif
01981 {
01982 n_occurrences = 0;
01983
01984
01985
01986
01987
01988 subst_low_cuid = INSN_CUID (i2);
01989 newpat = subst (PATTERN (i3), i2dest, i2src, 0,
01990 ! i1_feeds_i3 && i1dest_in_i1src);
01991 substed_i2 = 1;
01992
01993
01994 i2_is_used = n_occurrences;
01995 }
01996
01997
01998
01999
02000 if (i1 && GET_CODE (newpat) != CLOBBER)
02001 {
02002
02003
02004
02005
02006 if (! combinable_i3pat (NULL_RTX, &newpat, i1dest, NULL_RTX,
02007 0, (rtx*) 0))
02008 {
02009 undo_all ();
02010 return 0;
02011 }
02012
02013 n_occurrences = 0;
02014 subst_low_cuid = INSN_CUID (i1);
02015 newpat = subst (newpat, i1dest, i1src, 0, 0);
02016 substed_i1 = 1;
02017 }
02018
02019
02020
02021 if ((FIND_REG_INC_NOTE (i2, NULL_RTX) != 0
02022 && i2_is_used + added_sets_2 > 1)
02023 || (i1 != 0 && FIND_REG_INC_NOTE (i1, NULL_RTX) != 0
02024 && (n_occurrences + added_sets_1 + (added_sets_2 && ! i1_feeds_i3)
02025 > 1))
02026
02027
02028 || max_reg_num () != maxreg
02029
02030 || GET_CODE (newpat) == CLOBBER
02031
02032
02033 || (GET_CODE (newpat) == SET && GET_CODE (SET_SRC (newpat)) == MULT
02034 && ! have_mult))
02035 {
02036 undo_all ();
02037 return 0;
02038 }
02039
02040
02041
02042
02043
02044
02045 if (added_sets_1 || added_sets_2)
02046 {
02047 combine_extras++;
02048
02049 if (GET_CODE (newpat) == PARALLEL)
02050 {
02051 rtvec old = XVEC (newpat, 0);
02052 total_sets = XVECLEN (newpat, 0) + added_sets_1 + added_sets_2;
02053 newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets));
02054 memcpy (XVEC (newpat, 0)->elem, &old->elem[0],
02055 sizeof (old->elem[0]) * old->num_elem);
02056 }
02057 else
02058 {
02059 rtx old = newpat;
02060 total_sets = 1 + added_sets_1 + added_sets_2;
02061 newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets));
02062 XVECEXP (newpat, 0, 0) = old;
02063 }
02064
02065 if (added_sets_1)
02066 XVECEXP (newpat, 0, --total_sets)
02067 = (GET_CODE (PATTERN (i1)) == PARALLEL
02068 ? gen_rtx_SET (VOIDmode, i1dest, i1src) : PATTERN (i1));
02069
02070 if (added_sets_2)
02071 {
02072
02073
02074
02075 if (i1 == 0)
02076 XVECEXP (newpat, 0, --total_sets) = i2pat;
02077 else
02078
02079 XVECEXP (newpat, 0, --total_sets)
02080 = subst (i2pat, i1dest, i1src, 0, 0);
02081 }
02082 }
02083
02084
02085
02086 validate_replacement:
02087
02088
02089 mark_used_regs_combine (newpat);
02090
02091
02092 insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103 if (insn_code_number < 0 && GET_CODE (newpat) == PARALLEL
02104 && XVECLEN (newpat, 0) == 2
02105 && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
02106 && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
02107 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == REG
02108 && find_reg_note (i3, REG_UNUSED, SET_DEST (XVECEXP (newpat, 0, 1)))
02109 && ! side_effects_p (SET_SRC (XVECEXP (newpat, 0, 1)))
02110 && asm_noperands (newpat) < 0)
02111 {
02112 newpat = XVECEXP (newpat, 0, 0);
02113 insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
02114 }
02115
02116 else if (insn_code_number < 0 && GET_CODE (newpat) == PARALLEL
02117 && XVECLEN (newpat, 0) == 2
02118 && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
02119 && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
02120 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) == REG
02121 && find_reg_note (i3, REG_UNUSED, SET_DEST (XVECEXP (newpat, 0, 0)))
02122 && ! side_effects_p (SET_SRC (XVECEXP (newpat, 0, 0)))
02123 && asm_noperands (newpat) < 0)
02124 {
02125 newpat = XVECEXP (newpat, 0, 1);
02126 insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
02127 }
02128
02129
02130
02131
02132
02133
02134
02135 if (i1 && insn_code_number < 0 && GET_CODE (newpat) == SET
02136 && asm_noperands (newpat) < 0)
02137 {
02138 rtx m_split, *split;
02139 rtx ni2dest = i2dest;
02140
02141
02142
02143
02144
02145 m_split = split_insns (newpat, i3);
02146
02147
02148
02149
02150
02151
02152
02153
02154 if (m_split == 0 && ! reg_overlap_mentioned_p (ni2dest, newpat))
02155 {
02156
02157
02158 if (GET_MODE (SET_DEST (newpat)) != GET_MODE (i2dest)
02159 && GET_MODE (SET_DEST (newpat)) != VOIDmode
02160 && GET_CODE (i2dest) == REG
02161 && (REGNO (i2dest) < FIRST_PSEUDO_REGISTER
02162 || (REG_N_SETS (REGNO (i2dest)) == 1 && ! added_sets_2
02163 && ! REG_USERVAR_P (i2dest))))
02164 ni2dest = gen_rtx_REG (GET_MODE (SET_DEST (newpat)),
02165 REGNO (i2dest));
02166
02167 m_split = split_insns (gen_rtx_PARALLEL
02168 (VOIDmode,
02169 gen_rtvec (2, newpat,
02170 gen_rtx_CLOBBER (VOIDmode,
02171 ni2dest))),
02172 i3);
02173
02174
02175 if (! m_split && ni2dest != i2dest)
02176 {
02177 ni2dest = i2dest;
02178 m_split = split_insns (gen_rtx_PARALLEL
02179 (VOIDmode,
02180 gen_rtvec (2, newpat,
02181 gen_rtx_CLOBBER (VOIDmode,
02182 i2dest))),
02183 i3);
02184 }
02185 }
02186
02187 if (m_split && NEXT_INSN (m_split) == NULL_RTX)
02188 {
02189 m_split = PATTERN (m_split);
02190 insn_code_number = recog_for_combine (&m_split, i3, &new_i3_notes);
02191 if (insn_code_number >= 0)
02192 newpat = m_split;
02193 }
02194 else if (m_split && NEXT_INSN (NEXT_INSN (m_split)) == NULL_RTX
02195 && (next_real_insn (i2) == i3
02196 || ! use_crosses_set_p (PATTERN (m_split), INSN_CUID (i2))))
02197 {
02198 rtx i2set, i3set;
02199 rtx newi3pat = PATTERN (NEXT_INSN (m_split));
02200 newi2pat = PATTERN (m_split);
02201
02202 i3set = single_set (NEXT_INSN (m_split));
02203 i2set = single_set (m_split);
02204
02205
02206
02207
02208
02209 if (REGNO (i2dest) >= FIRST_PSEUDO_REGISTER)
02210 SUBST (regno_reg_rtx[REGNO (i2dest)], ni2dest);
02211
02212 i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
02213
02214
02215
02216
02217
02218 if (i2_code_number >= 0 && i2set && i3set
02219 && (next_real_insn (i2) == i3
02220 || ! reg_used_between_p (SET_DEST (i2set), i2, i3)))
02221 insn_code_number = recog_for_combine (&newi3pat, i3,
02222 &new_i3_notes);
02223 if (insn_code_number >= 0)
02224 newpat = newi3pat;
02225
02226
02227
02228
02229 if (insn_code_number >= 0)
02230 {
02231 rtx new_i3_dest = SET_DEST (i3set);
02232 rtx new_i2_dest = SET_DEST (i2set);
02233
02234 while (GET_CODE (new_i3_dest) == ZERO_EXTRACT
02235 || GET_CODE (new_i3_dest) == STRICT_LOW_PART
02236 || GET_CODE (new_i3_dest) == SUBREG)
02237 new_i3_dest = XEXP (new_i3_dest, 0);
02238
02239 while (GET_CODE (new_i2_dest) == ZERO_EXTRACT
02240 || GET_CODE (new_i2_dest) == STRICT_LOW_PART
02241 || GET_CODE (new_i2_dest) == SUBREG)
02242 new_i2_dest = XEXP (new_i2_dest, 0);
02243
02244 if (GET_CODE (new_i3_dest) == REG
02245 && GET_CODE (new_i2_dest) == REG
02246 && REGNO (new_i3_dest) == REGNO (new_i2_dest))
02247 REG_N_SETS (REGNO (new_i2_dest))++;
02248 }
02249 }
02250
02251
02252
02253
02254 if (insn_code_number < 0 && (split = find_split_point (&newpat, i3)) != 0
02255 #ifdef HAVE_cc0
02256 && GET_CODE (i2dest) == REG
02257 #endif
02258
02259
02260 && (GET_MODE (*split) == GET_MODE (i2dest)
02261 || GET_MODE (*split) == VOIDmode
02262 || REGNO (i2dest) < FIRST_PSEUDO_REGISTER
02263 || (REG_N_SETS (REGNO (i2dest)) == 1 && ! added_sets_2
02264 && ! REG_USERVAR_P (i2dest)))
02265 && (next_real_insn (i2) == i3
02266 || ! use_crosses_set_p (*split, INSN_CUID (i2)))
02267
02268
02269 && ! reg_referenced_p (i2dest, newpat))
02270 {
02271 rtx newdest = i2dest;
02272 enum rtx_code split_code = GET_CODE (*split);
02273 enum machine_mode split_mode = GET_MODE (*split);
02274
02275
02276
02277 if (GET_MODE (i2dest) != split_mode && split_mode != VOIDmode)
02278 {
02279 newdest = gen_rtx_REG (split_mode, REGNO (i2dest));
02280
02281 if (REGNO (i2dest) >= FIRST_PSEUDO_REGISTER)
02282 SUBST (regno_reg_rtx[REGNO (i2dest)], newdest);
02283 }
02284
02285
02286
02287
02288 if (split_code == MULT
02289 && GET_CODE (XEXP (*split, 1)) == CONST_INT
02290 && INTVAL (XEXP (*split, 1)) > 0
02291 && (i = exact_log2 (INTVAL (XEXP (*split, 1)))) >= 0)
02292 {
02293 SUBST (*split, gen_rtx_ASHIFT (split_mode,
02294 XEXP (*split, 0), GEN_INT (i)));
02295
02296
02297 split_code = GET_CODE (*split);
02298 }
02299
02300 #ifdef INSN_SCHEDULING
02301
02302
02303 if (split_code == SUBREG && GET_CODE (SUBREG_REG (*split)) == MEM)
02304 {
02305 #ifdef LOAD_EXTEND_OP
02306
02307
02308 if (LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (*split)))
02309 == SIGN_EXTEND)
02310 SUBST (*split, gen_rtx_SIGN_EXTEND (split_mode,
02311 SUBREG_REG (*split)));
02312 else
02313 #endif
02314 SUBST (*split, gen_rtx_ZERO_EXTEND (split_mode,
02315 SUBREG_REG (*split)));
02316 }
02317 #endif
02318
02319 newi2pat = gen_rtx_SET (VOIDmode, newdest, *split);
02320 SUBST (*split, newdest);
02321 i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
02322
02323
02324
02325 if (i2_code_number >= 0 && ! (split_code == MULT && ! have_mult))
02326 insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
02327 }
02328 }
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345 else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0
02346 && GET_CODE (newpat) == PARALLEL
02347 && XVECLEN (newpat, 0) == 2
02348 && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
02349 && GET_CODE (SET_SRC (XVECEXP (newpat, 0, 0))) == SIGN_EXTEND
02350 && (GET_MODE (SET_DEST (XVECEXP (newpat, 0, 0)))
02351 == GET_MODE (SET_SRC (XVECEXP (newpat, 0, 0))))
02352 && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
02353 && rtx_equal_p (SET_SRC (XVECEXP (newpat, 0, 1)),
02354 XEXP (SET_SRC (XVECEXP (newpat, 0, 0)), 0))
02355 && ! use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)),
02356 INSN_CUID (i2))
02357 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT
02358 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
02359 && ! (temp = SET_DEST (XVECEXP (newpat, 0, 1)),
02360 (GET_CODE (temp) == REG
02361 && reg_nonzero_bits[REGNO (temp)] != 0
02362 && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
02363 && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
02364 && (reg_nonzero_bits[REGNO (temp)]
02365 != GET_MODE_MASK (word_mode))))
02366 && ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == SUBREG
02367 && (temp = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1))),
02368 (GET_CODE (temp) == REG
02369 && reg_nonzero_bits[REGNO (temp)] != 0
02370 && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
02371 && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
02372 && (reg_nonzero_bits[REGNO (temp)]
02373 != GET_MODE_MASK (word_mode)))))
02374 && ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1)),
02375 SET_SRC (XVECEXP (newpat, 0, 1)))
02376 && ! find_reg_note (i3, REG_UNUSED,
02377 SET_DEST (XVECEXP (newpat, 0, 0))))
02378 {
02379 rtx ni2dest;
02380
02381 newi2pat = XVECEXP (newpat, 0, 0);
02382 ni2dest = SET_DEST (XVECEXP (newpat, 0, 0));
02383 newpat = XVECEXP (newpat, 0, 1);
02384 SUBST (SET_SRC (newpat),
02385 gen_lowpart_for_combine (GET_MODE (SET_SRC (newpat)), ni2dest));
02386 i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
02387
02388 if (i2_code_number >= 0)
02389 insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
02390
02391 if (insn_code_number >= 0)
02392 {
02393 rtx insn;
02394 rtx link;
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405 PATTERN (i3) = newpat;
02406 distribute_links (gen_rtx_INSN_LIST (VOIDmode, i3, NULL_RTX));
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417 for (insn = NEXT_INSN (i3);
02418 insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR
02419 || insn != this_basic_block->next_bb->head);
02420 insn = NEXT_INSN (insn))
02421 {
02422 if (INSN_P (insn) && reg_referenced_p (ni2dest, PATTERN (insn)))
02423 {
02424 for (link = LOG_LINKS (insn); link;
02425 link = XEXP (link, 1))
02426 if (XEXP (link, 0) == i3)
02427 XEXP (link, 0) = i1;
02428
02429 break;
02430 }
02431 }
02432 }
02433 }
02434
02435
02436
02437
02438
02439
02440 else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0
02441 && GET_CODE (newpat) == PARALLEL
02442 && XVECLEN (newpat, 0) == 2
02443 && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
02444 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != ZERO_EXTRACT
02445 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != STRICT_LOW_PART
02446 && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
02447 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT
02448 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
02449 && ! use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)),
02450 INSN_CUID (i2))
02451
02452 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != USE
02453 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != USE
02454 && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 1)),
02455 XVECEXP (newpat, 0, 0))
02456 && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 0)),
02457 XVECEXP (newpat, 0, 1))
02458 && ! (contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 0)))
02459 && contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 1)))))
02460 {
02461
02462
02463
02464 #ifdef HAVE_cc0
02465 if (reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0)))
02466 {
02467 newi2pat = XVECEXP (newpat, 0, 0);
02468 newpat = XVECEXP (newpat, 0, 1);
02469 }
02470 else
02471 #endif
02472 {
02473 newi2pat = XVECEXP (newpat, 0, 1);
02474 newpat = XVECEXP (newpat, 0, 0);
02475 }
02476
02477 i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
02478
02479 if (i2_code_number >= 0)
02480 insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
02481 }
02482
02483
02484
02485 if ((insn_code_number < 0
02486
02487 && (! check_asm_operands (newpat) || added_sets_1 || added_sets_2)))
02488 {
02489 undo_all ();
02490 return 0;
02491 }
02492
02493
02494 if (undobuf.other_insn)
02495 {
02496 rtx other_pat = PATTERN (undobuf.other_insn);
02497 rtx new_other_notes;
02498 rtx note, next;
02499
02500 CLEAR_HARD_REG_SET (newpat_used_regs);
02501
02502 other_code_number = recog_for_combine (&other_pat, undobuf.other_insn,
02503 &new_other_notes);
02504
02505 if (other_code_number < 0 && ! check_asm_operands (other_pat))
02506 {
02507 undo_all ();
02508 return 0;
02509 }
02510
02511 PATTERN (undobuf.other_insn) = other_pat;
02512
02513
02514
02515
02516 for (note = REG_NOTES (undobuf.other_insn); note; note = next)
02517 {
02518 next = XEXP (note, 1);
02519
02520 if (REG_NOTE_KIND (note) == REG_UNUSED
02521 && ! reg_set_p (XEXP (note, 0), PATTERN (undobuf.other_insn)))
02522 {
02523 if (GET_CODE (XEXP (note, 0)) == REG)
02524 REG_N_DEATHS (REGNO (XEXP (note, 0)))--;
02525
02526 remove_note (undobuf.other_insn, note);
02527 }
02528 }
02529
02530 for (note = new_other_notes; note; note = XEXP (note, 1))
02531 if (GET_CODE (XEXP (note, 0)) == REG)
02532 REG_N_DEATHS (REGNO (XEXP (note, 0)))++;
02533
02534 distribute_notes (new_other_notes, undobuf.other_insn,
02535 undobuf.other_insn, NULL_RTX, NULL_RTX, NULL_RTX);
02536 }
02537 #ifdef HAVE_cc0
02538
02539
02540 {
02541 rtx p = prev_nonnote_insn (i3);
02542 if (p && p != i2 && GET_CODE (p) == INSN && newi2pat
02543 && sets_cc0_p (newi2pat))
02544 {
02545 undo_all ();
02546 return 0;
02547 }
02548 }
02549 #endif
02550
02551
02552
02553
02554 {
02555 rtx i3notes, i2notes, i1notes = 0;
02556 rtx i3links, i2links, i1links = 0;
02557 rtx midnotes = 0;
02558 unsigned int regno;
02559
02560
02561
02562 rtx elim_i2 = ((newi2pat && reg_set_p (i2dest, newi2pat))
02563 || i2dest_in_i2src || i2dest_in_i1src
02564 ? 0 : i2dest);
02565 rtx elim_i1 = (i1 == 0 || i1dest_in_i1src
02566 || (newi2pat && reg_set_p (i1dest, newi2pat))
02567 ? 0 : i1dest);
02568
02569
02570
02571 i3notes = REG_NOTES (i3), i3links = LOG_LINKS (i3);
02572 i2notes = REG_NOTES (i2), i2links = LOG_LINKS (i2);
02573 if (i1)
02574 i1notes = REG_NOTES (i1), i1links = LOG_LINKS (i1);
02575
02576
02577
02578
02579
02580 reset_used_flags (i3notes);
02581 reset_used_flags (i2notes);
02582 reset_used_flags (i1notes);
02583 reset_used_flags (newpat);
02584 reset_used_flags (newi2pat);
02585 if (undobuf.other_insn)
02586 reset_used_flags (PATTERN (undobuf.other_insn));
02587
02588 i3notes = copy_rtx_if_shared (i3notes);
02589 i2notes = copy_rtx_if_shared (i2notes);
02590 i1notes = copy_rtx_if_shared (i1notes);
02591 newpat = copy_rtx_if_shared (newpat);
02592 newi2pat = copy_rtx_if_shared (newi2pat);
02593 if (undobuf.other_insn)
02594 reset_used_flags (PATTERN (undobuf.other_insn));
02595
02596 INSN_CODE (i3) = insn_code_number;
02597 PATTERN (i3) = newpat;
02598
02599 if (GET_CODE (i3) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (i3))
02600 {
02601 rtx call_usage = CALL_INSN_FUNCTION_USAGE (i3);
02602
02603 reset_used_flags (call_usage);
02604 call_usage = copy_rtx (call_usage);
02605
02606 if (substed_i2)
02607 replace_rtx (call_usage, i2dest, i2src);
02608
02609 if (substed_i1)
02610 replace_rtx (call_usage, i1dest, i1src);
02611
02612 CALL_INSN_FUNCTION_USAGE (i3) = call_usage;
02613 }
02614
02615 if (undobuf.other_insn)
02616 INSN_CODE (undobuf.other_insn) = other_code_number;
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627 if (i3_subst_into_i2)
02628 {
02629 for (i = 0; i < XVECLEN (PATTERN (i2), 0); i++)
02630 if (GET_CODE (XVECEXP (PATTERN (i2), 0, i)) != USE
02631 && GET_CODE (SET_DEST (XVECEXP (PATTERN (i2), 0, i))) == REG
02632 && SET_DEST (XVECEXP (PATTERN (i2), 0, i)) != i2dest
02633 && ! find_reg_note (i2, REG_UNUSED,
02634 SET_DEST (XVECEXP (PATTERN (i2), 0, i))))
02635 for (temp = NEXT_INSN (i2);
02636 temp && (this_basic_block->next_bb == EXIT_BLOCK_PTR
02637 || this_basic_block->head != temp);
02638 temp = NEXT_INSN (temp))
02639 if (temp != i3 && INSN_P (temp))
02640 for (link = LOG_LINKS (temp); link; link = XEXP (link, 1))
02641 if (XEXP (link, 0) == i2)
02642 XEXP (link, 0) = i3;
02643
02644 if (i3notes)
02645 {
02646 rtx link = i3notes;
02647 while (XEXP (link, 1))
02648 link = XEXP (link, 1);
02649 XEXP (link, 1) = i2notes;
02650 }
02651 else
02652 i3notes = i2notes;
02653 i2notes = 0;
02654 }
02655
02656 LOG_LINKS (i3) = 0;
02657 REG_NOTES (i3) = 0;
02658 LOG_LINKS (i2) = 0;
02659 REG_NOTES (i2) = 0;
02660
02661 if (newi2pat)
02662 {
02663 INSN_CODE (i2) = i2_code_number;
02664 PATTERN (i2) = newi2pat;
02665 }
02666 else
02667 {
02668 PUT_CODE (i2, NOTE);
02669 NOTE_LINE_NUMBER (i2) = NOTE_INSN_DELETED;
02670 NOTE_SOURCE_FILE (i2) = 0;
02671 }
02672
02673 if (i1)
02674 {
02675 LOG_LINKS (i1) = 0;
02676 REG_NOTES (i1) = 0;
02677 PUT_CODE (i1, NOTE);
02678 NOTE_LINE_NUMBER (i1) = NOTE_INSN_DELETED;
02679 NOTE_SOURCE_FILE (i1) = 0;
02680 }
02681
02682
02683
02684
02685
02686
02687 if (newi2pat)
02688 {
02689 move_deaths (newi2pat, NULL_RTX, INSN_CUID (i1), i2, &midnotes);
02690 move_deaths (newpat, newi2pat, INSN_CUID (i1), i3, &midnotes);
02691 }
02692 else
02693 move_deaths (newpat, NULL_RTX, i1 ? INSN_CUID (i1) : INSN_CUID (i2),
02694 i3, &midnotes);
02695
02696
02697 if (i3notes)
02698 distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL_RTX,
02699 elim_i2, elim_i1);
02700 if (i2notes)
02701 distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL_RTX,
02702 elim_i2, elim_i1);
02703 if (i1notes)
02704 distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL_RTX,
02705 elim_i2, elim_i1);
02706 if (midnotes)
02707 distribute_notes (midnotes, NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
02708 elim_i2, elim_i1);
02709
02710
02711
02712
02713
02714
02715 if (newi2pat && new_i2_notes)
02716 {
02717 for (temp = new_i2_notes; temp; temp = XEXP (temp, 1))
02718 if (GET_CODE (XEXP (temp, 0)) == REG)
02719 REG_N_DEATHS (REGNO (XEXP (temp, 0)))++;
02720
02721 distribute_notes (new_i2_notes, i2, i2, NULL_RTX, NULL_RTX, NULL_RTX);
02722 }
02723
02724 if (new_i3_notes)
02725 {
02726 for (temp = new_i3_notes; temp; temp = XEXP (temp, 1))
02727 if (GET_CODE (XEXP (temp, 0)) == REG)
02728 REG_N_DEATHS (REGNO (XEXP (temp, 0)))++;
02729
02730 distribute_notes (new_i3_notes, i3, i3, NULL_RTX, NULL_RTX, NULL_RTX);
02731 }
02732
02733
02734
02735
02736
02737
02738
02739
02740 if (i3dest_killed)
02741 {
02742 if (GET_CODE (i3dest_killed) == REG)
02743 REG_N_DEATHS (REGNO (i3dest_killed))++;
02744
02745 if (newi2pat && reg_set_p (i3dest_killed, newi2pat))
02746 distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed,
02747 NULL_RTX),
02748 NULL_RTX, i2, NULL_RTX, elim_i2, elim_i1);
02749 else
02750 distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed,
02751 NULL_RTX),
02752 NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
02753 elim_i2, elim_i1);
02754 }
02755
02756 if (i2dest_in_i2src)
02757 {
02758 if (GET_CODE (i2dest) == REG)
02759 REG_N_DEATHS (REGNO (i2dest))++;
02760
02761 if (newi2pat && reg_set_p (i2dest, newi2pat))
02762 distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX),
02763 NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX);
02764 else
02765 distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX),
02766 NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
02767 NULL_RTX, NULL_RTX);
02768 }
02769
02770 if (i1dest_in_i1src)
02771 {
02772 if (GET_CODE (i1dest) == REG)
02773 REG_N_DEATHS (REGNO (i1dest))++;
02774
02775 if (newi2pat && reg_set_p (i1dest, newi2pat))
02776 distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX),
02777 NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX);
02778 else
02779 distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX),
02780 NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
02781 NULL_RTX, NULL_RTX);
02782 }
02783
02784 distribute_links (i3links);
02785 distribute_links (i2links);
02786 distribute_links (i1links);
02787
02788 if (GET_CODE (i2dest) == REG)
02789 {
02790 rtx link;
02791 rtx i2_insn = 0, i2_val = 0, set;
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801 for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
02802 if ((set = single_set (XEXP (link, 0))) != 0
02803 && rtx_equal_p (i2dest, SET_DEST (set)))
02804 i2_insn = XEXP (link, 0), i2_val = SET_SRC (set);
02805
02806 record_value_for_reg (i2dest, i2_insn, i2_val);
02807
02808
02809
02810 if (! added_sets_2
02811 && (newi2pat == 0 || ! reg_mentioned_p (i2dest, newi2pat))
02812 && ! i2dest_in_i2src)
02813 {
02814 regno = REGNO (i2dest);
02815 REG_N_SETS (regno)--;
02816 }
02817 }
02818
02819 if (i1 && GET_CODE (i1dest) == REG)
02820 {
02821 rtx link;
02822 rtx i1_insn = 0, i1_val = 0, set;
02823
02824 for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
02825 if ((set = single_set (XEXP (link, 0))) != 0
02826 && rtx_equal_p (i1dest, SET_DEST (set)))
02827 i1_insn = XEXP (link, 0), i1_val = SET_SRC (set);
02828
02829 record_value_for_reg (i1dest, i1_insn, i1_val);
02830
02831 regno = REGNO (i1dest);
02832 if (! added_sets_1 && ! i1dest_in_i1src)
02833 REG_N_SETS (regno)--;
02834 }
02835
02836
02837
02838
02839 if (newi2pat)
02840 note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
02841 note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
02842
02843
02844
02845
02846
02847
02848
02849
02850 if (returnjump_p (i3) || any_uncondjump_p (i3))
02851 {
02852 *new_direct_jump_p = 1;
02853
02854 if ((temp = next_nonnote_insn (i3)) == NULL_RTX
02855 || GET_CODE (temp) != BARRIER)
02856 emit_barrier_after (i3);
02857 }
02858
02859 if (undobuf.other_insn != NULL_RTX
02860 && (returnjump_p (undobuf.other_insn)
02861 || any_uncondjump_p (undobuf.other_insn)))
02862 {
02863 *new_direct_jump_p = 1;
02864
02865 if ((temp = next_nonnote_insn (undobuf.other_insn)) == NULL_RTX
02866 || GET_CODE (temp) != BARRIER)
02867 emit_barrier_after (undobuf.other_insn);
02868 }
02869
02870
02871
02872 if (GET_CODE (newpat) == SET
02873 && SET_SRC (newpat) == pc_rtx
02874 && SET_DEST (newpat) == pc_rtx)
02875 *new_direct_jump_p = 1;
02876 }
02877
02878 combine_successes++;
02879 undo_commit ();
02880
02881
02882
02883 subst_prev_insn = NULL_RTX;
02884
02885 if (added_links_insn
02886 && (newi2pat == 0 || INSN_CUID (added_links_insn) < INSN_CUID (i2))
02887 && INSN_CUID (added_links_insn) < INSN_CUID (i3))
02888 return added_links_insn;
02889 else
02890 return newi2pat ? i2 : i3;
02891 }
02892
02893
02894
02895 static void
02896 undo_all ()
02897 {
02898 struct undo *undo, *next;
02899
02900 for (undo = undobuf.undos; undo; undo = next)
02901 {
02902 next = undo->next;
02903 if (undo->is_int)
02904 *undo->where.i = undo->old_contents.i;
02905 else
02906 *undo->where.r = undo->old_contents.r;
02907
02908 undo->next = undobuf.frees;
02909 undobuf.frees = undo;
02910 }
02911
02912 undobuf.undos = 0;
02913
02914
02915
02916 subst_prev_insn = NULL_RTX;
02917 }
02918
02919
02920
02921
02922 static void
02923 undo_commit ()
02924 {
02925 struct undo *undo, *next;
02926
02927 for (undo = undobuf.undos; undo; undo = next)
02928 {
02929 next = undo->next;
02930 undo->next = undobuf.frees;
02931 undobuf.frees = undo;
02932 }
02933 undobuf.undos = 0;
02934 }
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944 static rtx *
02945 find_split_point (loc, insn)
02946 rtx *loc;
02947 rtx insn;
02948 {
02949 rtx x = *loc;
02950 enum rtx_code code = GET_CODE (x);
02951 rtx *split;
02952 unsigned HOST_WIDE_INT len = 0;
02953 HOST_WIDE_INT pos = 0;
02954 int unsignedp = 0;
02955 rtx inner = NULL_RTX;
02956
02957
02958 switch (code)
02959 {
02960 case SUBREG:
02961 #ifdef INSN_SCHEDULING
02962
02963
02964 if (GET_CODE (SUBREG_REG (x)) == MEM)
02965 return loc;
02966 #endif
02967 return find_split_point (&SUBREG_REG (x), insn);
02968
02969 case MEM:
02970 #ifdef HAVE_lo_sum
02971
02972
02973 if (GET_CODE (XEXP (x, 0)) == CONST
02974 || GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
02975 {
02976 SUBST (XEXP (x, 0),
02977 gen_rtx_LO_SUM (Pmode,
02978 gen_rtx_HIGH (Pmode, XEXP (x, 0)),
02979 XEXP (x, 0)));
02980 return &XEXP (XEXP (x, 0), 0);
02981 }
02982 #endif
02983
02984
02985
02986
02987
02988
02989 if (GET_CODE (XEXP (x, 0)) == PLUS
02990 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
02991 && ! memory_address_p (GET_MODE (x), XEXP (x, 0)))
02992 {
02993 rtx reg = regno_reg_rtx[FIRST_PSEUDO_REGISTER];
02994 rtx seq = split_insns (gen_rtx_SET (VOIDmode, reg, XEXP (x, 0)),
02995 subst_insn);
02996
02997
02998
02999
03000
03001
03002 if (seq
03003 && NEXT_INSN (seq) != NULL_RTX
03004 && NEXT_INSN (NEXT_INSN (seq)) == NULL_RTX
03005 && GET_CODE (seq) == INSN
03006 && GET_CODE (PATTERN (seq)) == SET
03007 && SET_DEST (PATTERN (seq)) == reg
03008 && ! reg_mentioned_p (reg,
03009 SET_SRC (PATTERN (seq)))
03010 && GET_CODE (NEXT_INSN (seq)) == INSN
03011 && GET_CODE (PATTERN (NEXT_INSN (seq))) == SET
03012 && SET_DEST (PATTERN (NEXT_INSN (seq))) == reg
03013 && memory_address_p (GET_MODE (x),
03014 SET_SRC (PATTERN (NEXT_INSN (seq)))))
03015 {
03016 rtx src1 = SET_SRC (PATTERN (seq));
03017 rtx src2 = SET_SRC (PATTERN (NEXT_INSN (seq)));
03018
03019
03020
03021
03022
03023
03024 src2 = replace_rtx (src2, reg, src1);
03025 split = 0;
03026 if (XEXP (src2, 0) == src1)
03027 split = &XEXP (src2, 0);
03028 else if (GET_RTX_FORMAT (GET_CODE (XEXP (src2, 0)))[0] == 'e'
03029 && XEXP (XEXP (src2, 0), 0) == src1)
03030 split = &XEXP (XEXP (src2, 0), 0);
03031
03032 if (split)
03033 {
03034 SUBST (XEXP (x, 0), src2);
03035 return split;
03036 }
03037 }
03038
03039
03040
03041
03042
03043
03044 else if (GET_RTX_CLASS (GET_CODE (XEXP (XEXP (x, 0), 0))) != 'o'
03045 && ! (GET_CODE (XEXP (XEXP (x, 0), 0)) == SUBREG
03046 && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (XEXP (x, 0), 0))))
03047 == 'o')))
03048 return &XEXP (XEXP (x, 0), 0);
03049 }
03050 break;
03051
03052 case SET:
03053 #ifdef HAVE_cc0
03054
03055
03056
03057
03058
03059 if (SET_DEST (x) == cc0_rtx
03060 && GET_CODE (SET_SRC (x)) != COMPARE
03061 && GET_CODE (SET_SRC (x)) != ZERO_EXTRACT
03062 && GET_RTX_CLASS (GET_CODE (SET_SRC (x))) != 'o'
03063 && ! (GET_CODE (SET_SRC (x)) == SUBREG
03064 && GET_RTX_CLASS (GET_CODE (SUBREG_REG (SET_SRC (x)))) == 'o'))
03065 return &SET_SRC (x);
03066 #endif
03067
03068
03069 split = find_split_point (&SET_SRC (x), insn);
03070 if (split && split != &SET_SRC (x))
03071 return split;
03072
03073
03074 split = find_split_point (&SET_DEST (x), insn);
03075 if (split && split != &SET_DEST (x))
03076 return split;
03077
03078
03079
03080 if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
03081 && (GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0)))
03082 <= HOST_BITS_PER_WIDE_INT)
03083 && GET_CODE (XEXP (SET_DEST (x), 1)) == CONST_INT
03084 && GET_CODE (XEXP (SET_DEST (x), 2)) == CONST_INT
03085 && GET_CODE (SET_SRC (x)) == CONST_INT
03086 && ((INTVAL (XEXP (SET_DEST (x), 1))
03087 + INTVAL (XEXP (SET_DEST (x), 2)))
03088 <= GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0))))
03089 && ! side_effects_p (XEXP (SET_DEST (x), 0)))
03090 {
03091 HOST_WIDE_INT pos = INTVAL (XEXP (SET_DEST (x), 2));
03092 unsigned HOST_WIDE_INT len = INTVAL (XEXP (SET_DEST (x), 1));
03093 unsigned HOST_WIDE_INT src = INTVAL (SET_SRC (x));
03094 rtx dest = XEXP (SET_DEST (x), 0);
03095 enum machine_mode mode = GET_MODE (dest);
03096 unsigned HOST_WIDE_INT mask = ((HOST_WIDE_INT) 1 << len) - 1;
03097
03098 if (BITS_BIG_ENDIAN)
03099 pos = GET_MODE_BITSIZE (mode) - len - pos;
03100
03101 if (src == mask)
03102 SUBST (SET_SRC (x),
03103 gen_binary (IOR, mode, dest, GEN_INT (src << pos)));
03104 else
03105 SUBST (SET_SRC (x),
03106 gen_binary (IOR, mode,
03107 gen_binary (AND, mode, dest,
03108 gen_int_mode (~(mask << pos),
03109 mode)),
03110 GEN_INT (src << pos)));
03111
03112 SUBST (SET_DEST (x), dest);
03113
03114 split = find_split_point (&SET_SRC (x), insn);
03115 if (split && split != &SET_SRC (x))
03116 return split;
03117 }
03118
03119
03120
03121 code = GET_CODE (SET_SRC (x));
03122
03123 switch (code)
03124 {
03125 case AND:
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135 if (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
03136 && GET_CODE (XEXP (SET_SRC (x), 0)) == REG
03137 && (pos = exact_log2 (INTVAL (XEXP (SET_SRC (x), 1)))) >= 7
03138 && GET_CODE (SET_DEST (x)) == REG
03139 && (split = find_single_use (SET_DEST (x), insn, (rtx*) 0)) != 0
03140 && (GET_CODE (*split) == EQ || GET_CODE (*split) == NE)
03141 && XEXP (*split, 0) == SET_DEST (x)
03142 && XEXP (*split, 1) == const0_rtx)
03143 {
03144 rtx extraction = make_extraction (GET_MODE (SET_DEST (x)),
03145 XEXP (SET_SRC (x), 0),
03146 pos, NULL_RTX, 1, 1, 0, 0);
03147 if (extraction != 0)
03148 {
03149 SUBST (SET_SRC (x), extraction);
03150 return find_split_point (loc, insn);
03151 }
03152 }
03153 break;
03154
03155 case NE:
03156
03157
03158 if (STORE_FLAG_VALUE == -1 && XEXP (SET_SRC (x), 1) == const0_rtx
03159 && GET_MODE (SET_SRC (x)) == GET_MODE (XEXP (SET_SRC (x), 0))
03160 && 1 <= (pos = exact_log2
03161 (nonzero_bits (XEXP (SET_SRC (x), 0),
03162 GET_MODE (XEXP (SET_SRC (x), 0))))))
03163 {
03164 enum machine_mode mode = GET_MODE (XEXP (SET_SRC (x), 0));
03165
03166 SUBST (SET_SRC (x),
03167 gen_rtx_NEG (mode,
03168 gen_rtx_LSHIFTRT (mode,
03169 XEXP (SET_SRC (x), 0),
03170 GEN_INT (pos))));
03171
03172 split = find_split_point (&SET_SRC (x), insn);
03173 if (split && split != &SET_SRC (x))
03174 return split;
03175 }
03176 break;
03177
03178 case SIGN_EXTEND:
03179 inner = XEXP (SET_SRC (x), 0);
03180
03181
03182
03183
03184 if (GET_MODE_CLASS (GET_MODE (inner)) == MODE_PARTIAL_INT
03185 || GET_MODE_CLASS (GET_MODE (SET_SRC (x))) == MODE_PARTIAL_INT)
03186 break;
03187
03188 pos = 0;
03189 len = GET_MODE_BITSIZE (GET_MODE (inner));
03190 unsignedp = 0;
03191 break;
03192
03193 case SIGN_EXTRACT:
03194 case ZERO_EXTRACT:
03195 if (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
03196 && GET_CODE (XEXP (SET_SRC (x), 2)) == CONST_INT)
03197 {
03198 inner = XEXP (SET_SRC (x), 0);
03199 len = INTVAL (XEXP (SET_SRC (x), 1));
03200 pos = INTVAL (XEXP (SET_SRC (x), 2));
03201
03202 if (BITS_BIG_ENDIAN)
03203 pos = GET_MODE_BITSIZE (GET_MODE (inner)) - len - pos;
03204 unsignedp = (code == ZERO_EXTRACT);
03205 }
03206 break;
03207
03208 default:
03209 break;
03210 }
03211
03212 if (len && pos >= 0 && pos + len <= GET_MODE_BITSIZE (GET_MODE (inner)))
03213 {
03214 enum machine_mode mode = GET_MODE (SET_SRC (x));
03215
03216
03217
03218
03219
03220
03221
03222 if (unsignedp && len <= 8)
03223 {
03224 SUBST (SET_SRC (x),
03225 gen_rtx_AND (mode,
03226 gen_rtx_LSHIFTRT
03227 (mode, gen_lowpart_for_combine (mode, inner),
03228 GEN_INT (pos)),
03229 GEN_INT (((HOST_WIDE_INT) 1 << len) - 1)));
03230
03231 split = find_split_point (&SET_SRC (x), insn);
03232 if (split && split != &SET_SRC (x))
03233 return split;
03234 }
03235 else
03236 {
03237 SUBST (SET_SRC (x),
03238 gen_rtx_fmt_ee
03239 (unsignedp ? LSHIFTRT : ASHIFTRT, mode,
03240 gen_rtx_ASHIFT (mode,
03241 gen_lowpart_for_combine (mode, inner),
03242 GEN_INT (GET_MODE_BITSIZE (mode)
03243 - len - pos)),
03244 GEN_INT (GET_MODE_BITSIZE (mode) - len)));
03245
03246 split = find_split_point (&SET_SRC (x), insn);
03247 if (split && split != &SET_SRC (x))
03248 return split;
03249 }
03250 }
03251
03252
03253
03254
03255 if ((GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '2'
03256 || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == 'c'
03257 || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '<')
03258 && CONSTANT_P (XEXP (SET_SRC (x), 1))
03259 && (GET_RTX_CLASS (GET_CODE (XEXP (SET_SRC (x), 0))) == 'o'
03260 || (GET_CODE (XEXP (SET_SRC (x), 0)) == SUBREG
03261 && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (SET_SRC (x), 0))))
03262 == 'o'))))
03263 return &XEXP (SET_SRC (x), 1);
03264
03265
03266
03267
03268
03269
03270 if ((GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '2'
03271 || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == 'c'
03272 || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '<'
03273 || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '1')
03274 && ! register_operand (XEXP (SET_SRC (x), 0), VOIDmode))
03275 return &XEXP (SET_SRC (x), 0);
03276
03277 return 0;
03278
03279 case AND:
03280 case IOR:
03281
03282
03283
03284 if (GET_CODE (XEXP (x, 0)) == NOT && GET_CODE (XEXP (x, 1)) == NOT)
03285 {
03286 SUBST (*loc,
03287 gen_rtx_NOT (GET_MODE (x),
03288 gen_rtx_fmt_ee (code == IOR ? AND : IOR,
03289 GET_MODE (x),
03290 XEXP (XEXP (x, 0), 0),
03291 XEXP (XEXP (x, 1), 0))));
03292 return find_split_point (loc, insn);
03293 }
03294
03295
03296
03297
03298 if (GET_CODE (XEXP (x, 1)) == NOT)
03299 {
03300 rtx tem = XEXP (x, 0);
03301 SUBST (XEXP (x, 0), XEXP (x, 1));
03302 SUBST (XEXP (x, 1), tem);
03303 }
03304 break;
03305
03306 default:
03307 break;
03308 }
03309
03310
03311 switch (GET_RTX_CLASS (code))
03312 {
03313 case 'b':
03314 case '3':
03315 split = find_split_point (&XEXP (x, 2), insn);
03316 if (split)
03317 return split;
03318
03319 case '2':
03320 case 'c':
03321 case '<':
03322 split = find_split_point (&XEXP (x, 1), insn);
03323 if (split)
03324 return split;
03325
03326 case '1':
03327
03328
03329 if (GET_CODE (x) != AND && GET_CODE (XEXP (x, 0)) == AND)
03330 return &XEXP (x, 0);
03331
03332 split = find_split_point (&XEXP (x, 0), insn);
03333 if (split)
03334 return split;
03335 return loc;
03336 }
03337
03338
03339 return 0;
03340 }
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361 static rtx
03362 subst (x, from, to, in_dest, unique_copy)
03363 rtx x, from, to;
03364 int in_dest;
03365 int unique_copy;
03366 {
03367 enum rtx_code code = GET_CODE (x);
03368 enum machine_mode op0_mode = VOIDmode;
03369 const char *fmt;
03370 int len, i;
03371 rtx new;
03372
03373
03374
03375
03376
03377 #define COMBINE_RTX_EQUAL_P(X,Y) \
03378 ((X) == (Y) \
03379 || (GET_CODE (X) == REG && GET_CODE (Y) == REG \
03380 && REGNO (X) == REGNO (Y) && GET_MODE (X) == GET_MODE (Y)))
03381
03382 if (! in_dest && COMBINE_RTX_EQUAL_P (x, from))
03383 {
03384 n_occurrences++;
03385 return (unique_copy && n_occurrences > 1 ? copy_rtx (to) : to);
03386 }
03387
03388
03389
03390
03391
03392
03393
03394
03395 if (! in_dest && code == REG && GET_CODE (from) == REG
03396 && REGNO (x) == REGNO (from))
03397 return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
03398
03399
03400
03401 if (code != MEM && code != LO_SUM && GET_RTX_CLASS (code) == 'o')
03402 return x;
03403
03404
03405
03406
03407
03408
03409
03410 if (COMBINE_RTX_EQUAL_P (x, to))
03411 return to;
03412
03413
03414
03415
03416
03417
03418
03419
03420
03421
03422 if (code == PARALLEL
03423 && GET_CODE (XVECEXP (x, 0, 0)) == SET
03424 && GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS)
03425 {
03426 new = subst (XVECEXP (x, 0, 0), from, to, 0, unique_copy);
03427
03428
03429 if (GET_CODE (new) == CLOBBER
03430 && XEXP (new, 0) == const0_rtx)
03431 return new;
03432
03433 SUBST (XVECEXP (x, 0, 0), new);
03434
03435 for (i = XVECLEN (x, 0) - 1; i >= 1; i--)
03436 {
03437 rtx dest = SET_DEST (XVECEXP (x, 0, i));
03438
03439 if (GET_CODE (dest) != REG
03440 && GET_CODE (dest) != CC0
03441 && GET_CODE (dest) != PC)
03442 {
03443 new = subst (dest, from, to, 0, unique_copy);
03444
03445
03446 if (GET_CODE (new) == CLOBBER
03447 && XEXP (new, 0) == const0_rtx)
03448 return new;
03449
03450 SUBST (SET_DEST (XVECEXP (x, 0, i)), new);
03451 }
03452 }
03453 }
03454 else
03455 {
03456 len = GET_RTX_LENGTH (code);
03457 fmt = GET_RTX_FORMAT (code);
03458
03459
03460
03461
03462
03463 if (code == SET
03464 && (GET_CODE (SET_DEST (x)) == REG
03465 || GET_CODE (SET_DEST (x)) == CC0
03466 || GET_CODE (SET_DEST (x)) == PC))
03467 fmt = "ie";
03468
03469
03470
03471 if (fmt[0] == 'e')
03472 op0_mode = GET_MODE (XEXP (x, 0));
03473
03474 for (i = 0; i < len; i++)
03475 {
03476 if (fmt[i] == 'E')
03477 {
03478 int j;
03479 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
03480 {
03481 if (COMBINE_RTX_EQUAL_P (XVECEXP (x, i, j), from))
03482 {
03483 new = (unique_copy && n_occurrences
03484 ? copy_rtx (to) : to);
03485 n_occurrences++;
03486 }
03487 else
03488 {
03489 new = subst (XVECEXP (x, i, j), from, to, 0,
03490 unique_copy);
03491
03492
03493
03494 if (GET_CODE (new) == CLOBBER
03495 && XEXP (new, 0) == const0_rtx)
03496 return new;
03497 }
03498
03499 SUBST (XVECEXP (x, i, j), new);
03500 }
03501 }
03502 else if (fmt[i] == 'e')
03503 {
03504
03505 new = XEXP (x, i);
03506 if (in_dest
03507 && (code == SUBREG || code == STRICT_LOW_PART
03508 || code == ZERO_EXTRACT)
03509 && i == 0
03510 && GET_CODE (new) == REG)
03511 ;
03512
03513 else if (COMBINE_RTX_EQUAL_P (XEXP (x, i), from))
03514 {
03515
03516
03517
03518
03519
03520
03521
03522
03523
03524
03525
03526
03527
03528 if (GET_CODE (to) == SUBREG
03529 && ! MODES_TIEABLE_P (GET_MODE (to),
03530 GET_MODE (SUBREG_REG (to)))
03531 && ! (code == SUBREG
03532 && MODES_TIEABLE_P (GET_MODE (x),
03533 GET_MODE (SUBREG_REG (to))))
03534 #ifdef HAVE_cc0
03535 && ! (code == SET && i == 1 && XEXP (x, 0) == cc0_rtx)
03536 #endif
03537 )
03538 return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
03539
03540 #ifdef CANNOT_CHANGE_MODE_CLASS
03541 if (code == SUBREG
03542 && GET_CODE (to) == REG
03543 && REGNO (to) < FIRST_PSEUDO_REGISTER
03544 && REG_CANNOT_CHANGE_MODE_P (REGNO (to),
03545 GET_MODE (to),
03546 GET_MODE (x)))
03547 return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
03548 #endif
03549
03550 new = (unique_copy && n_occurrences ? copy_rtx (to) : to);
03551 n_occurrences++;
03552 }
03553 else
03554
03555
03556
03557
03558
03559
03560
03561
03562 new = subst (XEXP (x, i), from, to,
03563 (((in_dest
03564 && (code == SUBREG || code == STRICT_LOW_PART
03565 || code == ZERO_EXTRACT))
03566 || code == SET)
03567 && i == 0), unique_copy);
03568
03569
03570
03571
03572
03573
03574
03575 if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx)
03576 return new;
03577
03578 if (GET_CODE (new) == CONST_INT && GET_CODE (x) == SUBREG)
03579 {
03580 enum machine_mode mode = GET_MODE (x);
03581
03582 x = simplify_subreg (GET_MODE (x), new,
03583 GET_MODE (SUBREG_REG (x)),
03584 SUBREG_BYTE (x));
03585 if (! x)
03586 x = gen_rtx_CLOBBER (mode, const0_rtx);
03587 }
03588 else if (GET_CODE (new) == CONST_INT
03589 && GET_CODE (x) == ZERO_EXTEND)
03590 {
03591 x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
03592 new, GET_MODE (XEXP (x, 0)));
03593 if (! x)
03594 abort ();
03595 }
03596 else
03597 SUBST (XEXP (x, i), new);
03598 }
03599 }
03600 }
03601
03602
03603
03604
03605
03606 for (i = 0; i < 4; i++)
03607 {
03608
03609
03610 if (code != CONST_INT && code != REG && code != CLOBBER)
03611 x = combine_simplify_rtx (x, op0_mode, i == 3, in_dest);
03612
03613 if (GET_CODE (x) == code)
03614 break;
03615
03616 code = GET_CODE (x);
03617
03618
03619
03620 op0_mode = VOIDmode;
03621 }
03622
03623 return x;
03624 }
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634 static rtx
03635 combine_simplify_rtx (x, op0_mode, last, in_dest)
03636 rtx x;
03637 enum machine_mode op0_mode;
03638 int last;
03639 int in_dest;
03640 {
03641 enum rtx_code code = GET_CODE (x);
03642 enum machine_mode mode = GET_MODE (x);
03643 rtx temp;
03644 rtx reversed;
03645 int i;
03646
03647
03648
03649 if (GET_RTX_CLASS (code) == 'c'
03650 && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
03651 {
03652 temp = XEXP (x, 0);
03653 SUBST (XEXP (x, 0), XEXP (x, 1));
03654 SUBST (XEXP (x, 1), temp);
03655 }
03656
03657
03658
03659
03660
03661
03662
03663
03664
03665
03666
03667
03668
03669
03670
03671
03672
03673
03674
03675 if ((code == PLUS || code == MINUS || code == MULT)
03676 && GET_CODE (XEXP (x, 0)) == ASHIFTRT
03677 && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS
03678 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ASHIFT
03679 && GET_CODE (XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 1)) == CONST_INT
03680 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
03681 && XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 1) == XEXP (XEXP (x, 0), 1)
03682 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
03683 && (temp = simplify_binary_operation (ASHIFTRT, mode,
03684 XEXP (XEXP (XEXP (x, 0), 0), 1),
03685 XEXP (XEXP (x, 0), 1))) != 0)
03686 {
03687 rtx new
03688 = simplify_shift_const (NULL_RTX, ASHIFT, mode,
03689 XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 0),
03690 INTVAL (XEXP (XEXP (x, 0), 1)));
03691
03692 new = simplify_shift_const (NULL_RTX, ASHIFTRT, mode, new,
03693 INTVAL (XEXP (XEXP (x, 0), 1)));
03694
03695 SUBST (XEXP (x, 0), gen_binary (PLUS, mode, new, temp));
03696 }
03697
03698
03699
03700
03701
03702
03703
03704
03705 if (((GET_RTX_CLASS (code) == '2' || GET_RTX_CLASS (code) == 'c'
03706 || GET_RTX_CLASS (code) == '<')
03707 && ((GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) != 'o'
03708 && ! (GET_CODE (XEXP (x, 0)) == SUBREG
03709 && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0))))
03710 == 'o')))
03711 || (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) != 'o'
03712 && ! (GET_CODE (XEXP (x, 1)) == SUBREG
03713 && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 1))))
03714 == 'o')))))
03715 || (GET_RTX_CLASS (code) == '1'
03716 && ((GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) != 'o'
03717 && ! (GET_CODE (XEXP (x, 0)) == SUBREG
03718 && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0))))
03719 == 'o'))))))
03720 {
03721 rtx cond, true_rtx, false_rtx;
03722
03723 cond = if_then_else_cond (x, &true_rtx, &false_rtx);
03724 if (cond != 0
03725
03726
03727 && ! (GET_RTX_CLASS (code) == '<'
03728 && (GET_RTX_CLASS (GET_CODE (true_rtx)) == '<'
03729 || GET_RTX_CLASS (GET_CODE (false_rtx)) == '<')))
03730 {
03731 rtx cop1 = const0_rtx;
03732 enum rtx_code cond_code = simplify_comparison (NE, &cond, &cop1);
03733
03734 if (cond_code == NE && GET_RTX_CLASS (GET_CODE (cond)) == '<')
03735 return x;
03736
03737
03738
03739 true_rtx = subst (true_rtx, pc_rtx, pc_rtx, 0, 0);
03740 false_rtx = subst (false_rtx, pc_rtx, pc_rtx, 0, 0);
03741
03742
03743
03744 if (general_operand (true_rtx, VOIDmode)
03745 && general_operand (false_rtx, VOIDmode))
03746 {
03747
03748
03749
03750
03751
03752 if (true_rtx == const_true_rtx && false_rtx == const0_rtx)
03753 x = gen_binary (cond_code, mode, cond, cop1);
03754 else if (true_rtx == const0_rtx && false_rtx == const_true_rtx
03755 && reverse_condition (cond_code) != UNKNOWN)
03756 x = gen_binary (reverse_condition (cond_code),
03757 mode, cond, cop1);
03758
03759
03760
03761 else if (GET_CODE (true_rtx) == CONST_INT
03762 && INTVAL (true_rtx) == - STORE_FLAG_VALUE
03763 && false_rtx == const0_rtx)
03764 x = simplify_gen_unary (NEG, mode,
03765 gen_binary (cond_code, mode, cond,
03766 cop1),
03767 mode);
03768 else if (GET_CODE (false_rtx) == CONST_INT
03769 && INTVAL (false_rtx) == - STORE_FLAG_VALUE
03770 && true_rtx == const0_rtx)
03771 x = simplify_gen_unary (NEG, mode,
03772 gen_binary (reverse_condition
03773 (cond_code),
03774 mode, cond, cop1),
03775 mode);
03776 else
03777 return gen_rtx_IF_THEN_ELSE (mode,
03778 gen_binary (cond_code, VOIDmode,
03779 cond, cop1),
03780 true_rtx, false_rtx);
03781
03782 code = GET_CODE (x);
03783 op0_mode = VOIDmode;
03784 }
03785 }
03786 }
03787
03788
03789
03790 temp = 0;
03791 switch (GET_RTX_CLASS (code))
03792 {
03793 case '1':
03794 temp = simplify_unary_operation (code, mode, XEXP (x, 0), op0_mode);
03795 break;
03796 case '<':
03797 {
03798 enum machine_mode cmp_mode = GET_MODE (XEXP (x, 0));
03799 if (cmp_mode == VOIDmode)
03800 {
03801 cmp_mode = GET_MODE (XEXP (x, 1));
03802 if (cmp_mode == VOIDmode)
03803 cmp_mode = op0_mode;
03804 }
03805 temp = simplify_relational_operation (code, cmp_mode,
03806 XEXP (x, 0), XEXP (x, 1));
03807 }
03808 #ifdef FLOAT_STORE_FLAG_VALUE
03809 if (temp != 0 && GET_MODE_CLASS (mode) == MODE_FLOAT)
03810 {
03811 if (temp == const0_rtx)
03812 temp = CONST0_RTX (mode);
03813 else
03814 temp = CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE (mode),
03815 mode);
03816 }
03817 #endif
03818 break;
03819 case 'c':
03820 case '2':
03821 temp = simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
03822 break;
03823 case 'b':
03824 case '3':
03825 temp = simplify_ternary_operation (code, mode, op0_mode, XEXP (x, 0),
03826 XEXP (x, 1), XEXP (x, 2));
03827 break;
03828 }
03829
03830 if (temp)
03831 {
03832 x = temp;
03833 code = GET_CODE (temp);
03834 op0_mode = VOIDmode;
03835 mode = GET_MODE (temp);
03836 }
03837
03838
03839 if (code == PLUS || code == MINUS
03840 || code == AND || code == IOR || code == XOR)
03841 {
03842 x = apply_distributive_law (x);
03843 code = GET_CODE (x);
03844 op0_mode = VOIDmode;
03845 }
03846
03847
03848
03849
03850 if ((code == PLUS || code == MINUS || code == MULT || code == DIV
03851 || code == AND || code == IOR || code == XOR
03852 || code == SMAX || code == SMIN || code == UMAX || code == UMIN)
03853 && ((INTEGRAL_MODE_P (mode) && code != DIV)
03854 || (flag_unsafe_math_optimizations && FLOAT_MODE_P (mode))))
03855 {
03856 if (GET_CODE (XEXP (x, 0)) == code)
03857 {
03858 rtx other = XEXP (XEXP (x, 0), 0);
03859 rtx inner_op0 = XEXP (XEXP (x, 0), 1);
03860 rtx inner_op1 = XEXP (x, 1);
03861 rtx inner;
03862
03863
03864
03865 if (CONSTANT_P (inner_op0) && GET_RTX_CLASS (code) == 'c')
03866 {
03867 rtx tem = inner_op0;
03868 inner_op0 = inner_op1;
03869 inner_op1 = tem;
03870 }
03871 inner = simplify_binary_operation (code == MINUS ? PLUS
03872 : code == DIV ? MULT
03873 : code,
03874 mode, inner_op0, inner_op1);
03875
03876
03877
03878 if (inner == 0 && GET_RTX_CLASS (code) == 'c')
03879 {
03880 other = XEXP (XEXP (x, 0), 1);
03881 inner = simplify_binary_operation (code, mode,
03882 XEXP (XEXP (x, 0), 0),
03883 XEXP (x, 1));
03884 }
03885
03886 if (inner)
03887 return gen_binary (code, mode, other, inner);
03888 }
03889 }
03890
03891
03892 switch (code)
03893 {
03894 case MEM:
03895
03896
03897 temp = make_compound_operation (XEXP (x, 0), MEM);
03898 SUBST (XEXP (x, 0), temp);
03899 break;
03900
03901 case SUBREG:
03902 if (op0_mode == VOIDmode)
03903 op0_mode = GET_MODE (SUBREG_REG (x));
03904
03905
03906 if (CONSTANT_P (SUBREG_REG (x))
03907 && subreg_lowpart_offset (mode, op0_mode) == SUBREG_BYTE (x)
03908
03909
03910
03911 && (GET_MODE (SUBREG_REG (x)) != VOIDmode
03912 || gen_lowpart_common (mode, SUBREG_REG (x))))
03913 return gen_lowpart_for_combine (mode, SUBREG_REG (x));
03914
03915 if (GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_CC)
03916 break;
03917 {
03918 rtx temp;
03919 temp = simplify_subreg (mode, SUBREG_REG (x), op0_mode,
03920 SUBREG_BYTE (x));
03921 if (temp)
03922 return temp;
03923 }
03924
03925
03926
03927 if (GET_CODE (SUBREG_REG (x)) == MEM
03928 && (MEM_VOLATILE_P (SUBREG_REG (x))
03929 || mode_dependent_address_p (XEXP (SUBREG_REG (x), 0))))
03930 return gen_rtx_CLOBBER (mode, const0_rtx);
03931
03932
03933
03934
03935
03936 break;
03937
03938 case NOT:
03939
03940 if (GET_CODE (XEXP (x, 0)) == PLUS
03941 && XEXP (XEXP (x, 0), 1) == constm1_rtx)
03942 return gen_rtx_NEG (mode, XEXP (XEXP (x, 0), 0));
03943
03944
03945 if (GET_CODE (XEXP (x, 0)) == NEG)
03946 return gen_rtx_PLUS (mode, XEXP (XEXP (x, 0), 0), constm1_rtx);
03947
03948
03949 if (GET_CODE (XEXP (x, 0)) == XOR
03950 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
03951 && (temp = simplify_unary_operation (NOT, mode,
03952 XEXP (XEXP (x, 0), 1),
03953 mode)) != 0)
03954 return gen_binary (XOR, mode, XEXP (XEXP (x, 0), 0), temp);
03955
03956
03957
03958
03959
03960 if (GET_CODE (XEXP (x, 0)) == ASHIFT
03961 && XEXP (XEXP (x, 0), 0) == const1_rtx)
03962 return gen_rtx_ROTATE (mode, simplify_gen_unary (NOT, mode,
03963 const1_rtx, mode),
03964 XEXP (XEXP (x, 0), 1));
03965
03966 if (GET_CODE (XEXP (x, 0)) == SUBREG
03967 && subreg_lowpart_p (XEXP (x, 0))
03968 && (GET_MODE_SIZE (GET_MODE (XEXP (x, 0)))
03969 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (x, 0)))))
03970 && GET_CODE (SUBREG_REG (XEXP (x, 0))) == ASHIFT
03971 && XEXP (SUBREG_REG (XEXP (x, 0)), 0) == const1_rtx)
03972 {
03973 enum machine_mode inner_mode = GET_MODE (SUBREG_REG (XEXP (x, 0)));
03974
03975 x = gen_rtx_ROTATE (inner_mode,
03976 simplify_gen_unary (NOT, inner_mode, const1_rtx,
03977 inner_mode),
03978 XEXP (SUBREG_REG (XEXP (x, 0)), 1));
03979 return gen_lowpart_for_combine (mode, x);
03980 }
03981
03982
03983
03984 if (STORE_FLAG_VALUE == -1
03985 && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
03986 && (reversed = reversed_comparison (x, mode, XEXP (XEXP (x, 0), 0),
03987 XEXP (XEXP (x, 0), 1))))
03988 return reversed;
03989
03990
03991
03992
03993
03994 if (STORE_FLAG_VALUE == -1
03995 && GET_CODE (XEXP (x, 0)) == ASHIFTRT
03996 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
03997 && INTVAL (XEXP (XEXP (x, 0), 1)) == GET_MODE_BITSIZE (mode) - 1)
03998 return gen_rtx_GE (mode, XEXP (XEXP (x, 0), 0), const0_rtx);
03999
04000
04001
04002
04003
04004
04005 if (GET_CODE (XEXP (x, 0)) == IOR || GET_CODE (XEXP (x, 0)) == AND)
04006 {
04007 rtx in1 = XEXP (XEXP (x, 0), 0), in2 = XEXP (XEXP (x, 0), 1);
04008 enum machine_mode op_mode;
04009
04010 op_mode = GET_MODE (in1);
04011 in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
04012
04013 op_mode = GET_MODE (in2);
04014 if (op_mode == VOIDmode)
04015 op_mode = mode;
04016 in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
04017
04018 if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
04019 {
04020 rtx tem = in2;
04021 in2 = in1; in1 = tem;
04022 }
04023
04024 return gen_rtx_fmt_ee (GET_CODE (XEXP (x, 0)) == IOR ? AND : IOR,
04025 mode, in1, in2);
04026 }
04027 break;
04028
04029 case NEG:
04030
04031 if (GET_CODE (XEXP (x, 0)) == PLUS
04032 && XEXP (XEXP (x, 0), 1) == const1_rtx)
04033 return gen_rtx_NOT (mode, XEXP (XEXP (x, 0), 0));
04034
04035
04036 if (GET_CODE (XEXP (x, 0)) == NOT)
04037 return plus_constant (XEXP (XEXP (x, 0), 0), 1);
04038
04039
04040
04041
04042
04043
04044 if (GET_CODE (XEXP (x, 0)) == MINUS
04045 && !HONOR_SIGNED_ZEROS (mode)
04046 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
04047 return gen_binary (MINUS, mode, XEXP (XEXP (x, 0), 1),
04048 XEXP (XEXP (x, 0), 0));
04049
04050
04051 if (GET_CODE (XEXP (x, 0)) == PLUS
04052 && !HONOR_SIGNED_ZEROS (mode)
04053 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
04054 {
04055 temp = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 0), 0), mode);
04056 temp = combine_simplify_rtx (temp, mode, last, in_dest);
04057 return gen_binary (MINUS, mode, temp, XEXP (XEXP (x, 0), 1));
04058 }
04059
04060
04061
04062 if (GET_CODE (XEXP (x, 0)) == MULT)
04063 {
04064 temp = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 0), 0), mode);
04065 return gen_binary (MULT, mode, temp, XEXP (XEXP (x, 0), 1));
04066 }
04067
04068
04069 if (GET_CODE (XEXP (x, 0)) == XOR && XEXP (XEXP (x, 0), 1) == const1_rtx
04070 && nonzero_bits (XEXP (XEXP (x, 0), 0), mode) == 1)
04071 return gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0), constm1_rtx);
04072
04073
04074
04075
04076
04077 if (GET_CODE (XEXP (x, 0)) == ASHIFT)
04078 {
04079 temp = simplify_unary_operation (NEG, mode,
04080 XEXP (XEXP (x, 0), 0), mode);
04081 if (temp)
04082 return gen_binary (ASHIFT, mode, temp, XEXP (XEXP (x, 0), 1));
04083 }
04084
04085 temp = expand_compound_operation (XEXP (x, 0));
04086
04087
04088
04089
04090
04091 if (GET_CODE (temp) == ASHIFTRT
04092 && GET_CODE (XEXP (temp, 1)) == CONST_INT
04093 && INTVAL (XEXP (temp, 1)) == GET_MODE_BITSIZE (mode) - 1)
04094 return simplify_shift_const (temp, LSHIFTRT, mode, XEXP (temp, 0),
04095 INTVAL (XEXP (temp, 1)));
04096
04097
04098
04099
04100
04101
04102
04103
04104 if (GET_CODE (temp) != REG
04105 && ! (GET_CODE (temp) == SUBREG
04106 && GET_CODE (SUBREG_REG (temp)) == REG)
04107 && (i = exact_log2 (nonzero_bits (temp, mode))) >= 0)
04108 {
04109 rtx temp1 = simplify_shift_const
04110 (NULL_RTX, ASHIFTRT, mode,
04111 simplify_shift_const (NULL_RTX, ASHIFT, mode, temp,
04112 GET_MODE_BITSIZE (mode) - 1 - i),
04113 GET_MODE_BITSIZE (mode) - 1 - i);
04114
04115
04116
04117
04118 if (GET_CODE (temp1) != ASHIFTRT
04119 || GET_CODE (XEXP (temp1, 0)) != ASHIFT
04120 || XEXP (XEXP (temp1, 0), 0) != temp)
04121 return temp1;
04122 }
04123 break;
04124
04125 case TRUNCATE:
04126
04127
04128
04129 if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
04130 break;
04131
04132 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
04133 && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
04134 GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))))
04135 SUBST (XEXP (x, 0),
04136 force_to_mode (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
04137 GET_MODE_MASK (mode), NULL_RTX, 0));
04138
04139
04140 if ((GET_CODE (XEXP (x, 0)) == SIGN_EXTEND
04141 || GET_CODE (XEXP (x, 0)) == ZERO_EXTEND)
04142 && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode)
04143 return XEXP (XEXP (x, 0), 0);
04144
04145
04146
04147 if ((GET_CODE (XEXP (x, 0)) == ABS
04148 || GET_CODE (XEXP (x, 0)) == NEG)
04149 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SIGN_EXTEND
04150 || GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND)
04151 && GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == mode)
04152 return simplify_gen_unary (GET_CODE (XEXP (x, 0)), mode,
04153 XEXP (XEXP (XEXP (x, 0), 0), 0), mode);
04154
04155
04156
04157 if (GET_CODE (XEXP (x, 0)) == SUBREG
04158 && GET_CODE (SUBREG_REG (XEXP (x, 0))) == TRUNCATE
04159 && subreg_lowpart_p (XEXP (x, 0)))
04160 return SUBREG_REG (XEXP (x, 0));
04161
04162
04163
04164
04165
04166
04167 if (TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
04168 GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))))
04169 && num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
04170 >= (unsigned int) (GET_MODE_BITSIZE (mode) + 1)
04171 && ! (GET_CODE (XEXP (x, 0)) == LSHIFTRT
04172 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT))
04173 return gen_lowpart_for_combine (mode, XEXP (x, 0));
04174
04175
04176
04177
04178
04179 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
04180 && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
04181 && ((HOST_WIDE_INT) STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0)
04182 return gen_lowpart_for_combine (mode, XEXP (x, 0));
04183
04184
04185
04186
04187 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
04188 && ((HOST_WIDE_INT) STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
04189 && (temp = get_last_value (XEXP (x, 0)))
04190 && GET_RTX_CLASS (GET_CODE (temp)) == '<')
04191 return gen_lowpart_for_combine (mode, XEXP (x, 0));
04192
04193 break;
04194
04195 case FLOAT_TRUNCATE:
04196
04197 if (GET_CODE (XEXP (x, 0)) == FLOAT_EXTEND
04198 && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode)
04199 return XEXP (XEXP (x, 0), 0);
04200
04201
04202
04203 if ((GET_CODE (XEXP (x, 0)) == ABS
04204 || GET_CODE (XEXP (x, 0)) == NEG)
04205 && GET_CODE (XEXP (XEXP (x, 0), 0)) == FLOAT_EXTEND
04206 && GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == mode)
04207 return simplify_gen_unary (GET_CODE (XEXP (x, 0)), mode,
04208 XEXP (XEXP (XEXP (x, 0), 0), 0), mode);
04209
04210
04211
04212 if (GET_CODE (XEXP (x, 0)) == SUBREG
04213 && subreg_lowpart_p (XEXP (x, 0))
04214 && GET_CODE (SUBREG_REG (XEXP (x, 0))) == FLOAT_TRUNCATE)
04215 return SUBREG_REG (XEXP (x, 0));
04216 break;
04217
04218 #ifdef HAVE_cc0
04219 case COMPARE:
04220
04221
04222
04223 if (XEXP (x, 1) == const0_rtx)
04224 return XEXP (x, 0);
04225
04226
04227
04228
04229 if (!(HONOR_SIGNED_ZEROS (GET_MODE (XEXP (x, 0)))
04230 && HONOR_SIGN_DEPENDENT_ROUNDING (GET_MODE (XEXP (x, 0))))
04231 && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 0))))
04232 return XEXP (x, 0);
04233 break;
04234 #endif
04235
04236 case CONST:
04237
04238
04239
04240 if (GET_CODE (XEXP (x, 0)) == CONST)
04241 SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
04242 break;
04243
04244 #ifdef HAVE_lo_sum
04245 case LO_SUM:
04246
04247
04248
04249 if (GET_CODE (XEXP (x, 0)) == HIGH
04250 && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
04251 return XEXP (x, 1);
04252 break;
04253 #endif
04254
04255 case PLUS:
04256
04257
04258 if (GET_CODE (XEXP (x, 0)) == MULT
04259 && GET_CODE (XEXP (XEXP (x, 0), 0)) == NEG)
04260 {
04261 rtx in1, in2;
04262
04263 in1 = XEXP (XEXP (XEXP (x, 0), 0), 0);
04264 in2 = XEXP (XEXP (x, 0), 1);
04265 return gen_binary (MINUS, mode, XEXP (x, 1),
04266 gen_binary (MULT, mode, in1, in2));
04267 }
04268
04269
04270
04271
04272
04273 if (GET_CODE (XEXP (x, 0)) == PLUS
04274 && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
04275 return gen_binary (PLUS, mode,
04276 gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0),
04277 XEXP (x, 1)),
04278 XEXP (XEXP (x, 0), 1));
04279
04280
04281
04282
04283
04284
04285 if (GET_CODE (XEXP (x, 0)) == XOR
04286 && GET_CODE (XEXP (x, 1)) == CONST_INT
04287 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
04288 && INTVAL (XEXP (x, 1)) == -INTVAL (XEXP (XEXP (x, 0), 1))
04289 && ((i = exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) >= 0
04290 || (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0)
04291 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
04292 && ((GET_CODE (XEXP (XEXP (x, 0), 0)) == AND
04293 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
04294 && (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))
04295 == ((HOST_WIDE_INT) 1 << (i + 1)) - 1))
04296 || (GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND
04297 && (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)))
04298 == (unsigned int) i + 1))))
04299 return simplify_shift_const
04300 (NULL_RTX, ASHIFTRT, mode,
04301 simplify_shift_const (NULL_RTX, ASHIFT, mode,
04302 XEXP (XEXP (XEXP (x, 0), 0), 0),
04303 GET_MODE_BITSIZE (mode) - (i + 1)),
04304 GET_MODE_BITSIZE (mode) - (i + 1));
04305
04306
04307
04308
04309
04310 if (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
04311 && ((STORE_FLAG_VALUE == -1 && XEXP (x, 1) == const1_rtx)
04312 || (STORE_FLAG_VALUE == 1 && XEXP (x, 1) == constm1_rtx))
04313 && (reversed = reversed_comparison (XEXP (x, 0), mode,
04314 XEXP (XEXP (x, 0), 0),
04315 XEXP (XEXP (x, 0), 1))))
04316 return
04317 simplify_gen_unary (NEG, mode, reversed, mode);
04318
04319
04320
04321
04322
04323 if (XEXP (x, 1) == constm1_rtx
04324 && GET_CODE (XEXP (x, 0)) != REG
04325 && ! (GET_CODE (XEXP (x,0)) == SUBREG
04326 && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG)
04327 && nonzero_bits (XEXP (x, 0), mode) == 1)
04328 return simplify_shift_const (NULL_RTX, ASHIFTRT, mode,
04329 simplify_shift_const (NULL_RTX, ASHIFT, mode,
04330 gen_rtx_XOR (mode, XEXP (x, 0), const1_rtx),
04331 GET_MODE_BITSIZE (mode) - 1),
04332 GET_MODE_BITSIZE (mode) - 1);
04333
04334
04335
04336
04337
04338
04339 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
04340 && (nonzero_bits (XEXP (x, 0), mode)
04341 & nonzero_bits (XEXP (x, 1), mode)) == 0)
04342 {
04343
04344 rtx tor = gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1));
04345 temp = combine_simplify_rtx (tor, mode, last, in_dest);
04346
04347
04348
04349
04350 if (GET_CODE (temp) != CLOBBER && temp != tor)
04351 return temp;
04352 }
04353 break;
04354
04355 case MINUS:
04356
04357
04358 if (STORE_FLAG_VALUE == 1
04359 && XEXP (x, 0) == const1_rtx
04360 && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<'
04361 && (reversed = reversed_comparison (XEXP (x, 1), mode,
04362 XEXP (XEXP (x, 1), 0),
04363 XEXP (XEXP (x, 1), 1))))
04364 return reversed;
04365
04366
04367
04368 if (GET_CODE (XEXP (x, 1)) == AND
04369 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
04370 && exact_log2 (-INTVAL (XEXP (XEXP (x, 1), 1))) >= 0
04371 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
04372 return simplify_and_const_int (NULL_RTX, mode, XEXP (x, 0),
04373 -INTVAL (XEXP (XEXP (x, 1), 1)) - 1);
04374
04375
04376
04377 if (GET_CODE (XEXP (x, 1)) == MULT
04378 && GET_CODE (XEXP (XEXP (x, 1), 0)) == NEG)
04379 {
04380 rtx in1, in2;
04381
04382 in1 = XEXP (XEXP (XEXP (x, 1), 0), 0);
04383 in2 = XEXP (XEXP (x, 1), 1);
04384 return gen_binary (PLUS, mode, gen_binary (MULT, mode, in1, in2),
04385 XEXP (x, 0));
04386 }
04387
04388
04389
04390 if (GET_CODE (XEXP (x, 1)) == MULT
04391 && GET_CODE (XEXP (x, 0)) == NEG)
04392 {
04393 rtx in1, in2;
04394
04395 in1 = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 1), 0), mode);
04396 in2 = XEXP (XEXP (x, 1), 1);
04397 return gen_binary (MINUS, mode, gen_binary (MULT, mode, in1, in2),
04398 XEXP (XEXP (x, 0), 0));
04399 }
04400
04401
04402
04403 if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode))
04404 return gen_binary (MINUS, mode,
04405 gen_binary (MINUS, mode, XEXP (x, 0),
04406 XEXP (XEXP (x, 1), 0)),
04407 XEXP (XEXP (x, 1), 1));
04408 break;
04409
04410 case MULT:
04411
04412
04413
04414
04415 if (GET_CODE (XEXP (x, 0)) == PLUS)
04416 {
04417 x = apply_distributive_law
04418 (gen_binary (PLUS, mode,
04419 gen_binary (MULT, mode,
04420 XEXP (XEXP (x, 0), 0), XEXP (x, 1)),
04421 gen_binary (MULT, mode,
04422 XEXP (XEXP (x, 0), 1),
04423 copy_rtx (XEXP (x, 1)))));
04424
04425 if (GET_CODE (x) != MULT)
04426 return x;
04427 }
04428
04429 if (FLOAT_MODE_P (mode) && flag_unsafe_math_optimizations
04430 && GET_CODE (XEXP (x, 0)) == DIV)
04431 {
04432 rtx tem = simplify_binary_operation (MULT, mode,
04433 XEXP (XEXP (x, 0), 0),
04434 XEXP (x, 1));
04435 if (tem)
04436 return gen_binary (DIV, mode, tem, XEXP (XEXP (x, 0), 1));
04437 }
04438 break;
04439
04440 case UDIV:
04441
04442
04443 if (GET_CODE (XEXP (x, 1)) == CONST_INT
04444 && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0
04445 && (GET_CODE (XEXP (x, 0)) == ASHIFT
04446 || GET_CODE (XEXP (x, 0)) == LSHIFTRT
04447 || GET_CODE (XEXP (x, 0)) == ASHIFTRT
04448 || GET_CODE (XEXP (x, 0)) == ROTATE
04449 || GET_CODE (XEXP (x, 0)) == ROTATERT))
04450 return simplify_shift_const (NULL_RTX, LSHIFTRT, mode, XEXP (x, 0), i);
04451 break;
04452
04453 case EQ: case NE:
04454 case GT: case GTU: case GE: case GEU:
04455 case LT: case LTU: case LE: case LEU:
04456 case UNEQ: case LTGT:
04457 case UNGT: case UNGE:
04458 case UNLT: case UNLE:
04459 case UNORDERED: case ORDERED:
04460
04461
04462 if (GET_CODE (XEXP (x, 0)) == COMPARE
04463 || (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_CC
04464 #ifdef HAVE_cc0
04465 && XEXP (x, 0) != cc0_rtx
04466 #endif
04467 ))
04468 {
04469 rtx op0 = XEXP (x, 0);
04470 rtx op1 = XEXP (x, 1);
04471 enum rtx_code new_code;
04472
04473 if (GET_CODE (op0) == COMPARE)
04474 op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);
04475
04476
04477 new_code = simplify_comparison (code, &op0, &op1);
04478
04479
04480
04481
04482
04483
04484
04485
04486
04487
04488
04489
04490
04491 if (STORE_FLAG_VALUE == 1
04492 && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
04493 && op1 == const0_rtx
04494 && mode == GET_MODE (op0)
04495 && nonzero_bits (op0, mode) == 1)
04496 return gen_lowpart_for_combine (mode,
04497 expand_compound_operation (op0));
04498
04499 else if (STORE_FLAG_VALUE == 1
04500 && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
04501 && op1 == const0_rtx
04502 && mode == GET_MODE (op0)
04503 && (num_sign_bit_copies (op0, mode)
04504 == GET_MODE_BITSIZE (mode)))
04505 {
04506 op0 = expand_compound_operation (op0);
04507 return simplify_gen_unary (NEG, mode,
04508 gen_lowpart_for_combine (mode, op0),
04509 mode);
04510 }
04511
04512 else if (STORE_FLAG_VALUE == 1
04513 && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
04514 && op1 == const0_rtx
04515 && mode == GET_MODE (op0)
04516 && nonzero_bits (op0, mode) == 1)
04517 {
04518 op0 = expand_compound_operation (op0);
04519 return gen_binary (XOR, mode,
04520 gen_lowpart_for_combine (mode, op0),
04521 const1_rtx);
04522 }
04523
04524 else if (STORE_FLAG_VALUE == 1
04525 && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
04526 && op1 == const0_rtx
04527 && mode == GET_MODE (op0)
04528 && (num_sign_bit_copies (op0, mode)
04529 == GET_MODE_BITSIZE (mode)))
04530 {
04531 op0 = expand_compound_operation (op0);
04532 return plus_constant (gen_lowpart_for_combine (mode, op0), 1);
04533 }
04534
04535
04536
04537 if (STORE_FLAG_VALUE == -1
04538 && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
04539 && op1 == const0_rtx
04540 && (num_sign_bit_copies (op0, mode)
04541 == GET_MODE_BITSIZE (mode)))
04542 return gen_lowpart_for_combine (mode,
04543 expand_compound_operation (op0));
04544
04545 else if (STORE_FLAG_VALUE == -1
04546 && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
04547 && op1 == const0_rtx
04548 && mode == GET_MODE (op0)
04549 && nonzero_bits (op0, mode) == 1)
04550 {
04551 op0 = expand_compound_operation (op0);
04552 return simplify_gen_unary (NEG, mode,
04553 gen_lowpart_for_combine (mode, op0),
04554 mode);
04555 }
04556
04557 else if (STORE_FLAG_VALUE == -1
04558 && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
04559 && op1 == const0_rtx
04560 && mode == GET_MODE (op0)
04561 && (num_sign_bit_copies (op0, mode)
04562 == GET_MODE_BITSIZE (mode)))
04563 {
04564 op0 = expand_compound_operation (op0);
04565 return simplify_gen_unary (NOT, mode,
04566 gen_lowpart_for_combine (mode, op0),
04567 mode);
04568 }
04569
04570
04571 else if (STORE_FLAG_VALUE == -1
04572 && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
04573 && op1 == const0_rtx
04574 && mode == GET_MODE (op0)
04575 && nonzero_bits (op0, mode) == 1)
04576 {
04577 op0 = expand_compound_operation (op0);
04578 return plus_constant (gen_lowpart_for_combine (mode, op0), -1);
04579 }
04580
04581
04582
04583
04584
04585
04586 if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
04587 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
04588 && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
04589 == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE(mode)-1))
04590 && op1 == const0_rtx
04591 && mode == GET_MODE (op0)
04592 && (i = exact_log2 (nonzero_bits (op0, mode))) >= 0)
04593 {
04594 x = simplify_shift_const (NULL_RTX, ASHIFT, mode,
04595 expand_compound_operation (op0),
04596 GET_MODE_BITSIZE (mode) - 1 - i);
04597 if (GET_CODE (x) == AND && XEXP (x, 1) == const_true_rtx)
04598 return XEXP (x, 0);
04599 else
04600 return x;
04601 }
04602
04603
04604 if (new_code != code)
04605 return gen_rtx_fmt_ee (new_code, mode, op0, op1);
04606
04607
04608
04609 SUBST (XEXP (x, 0), op0);
04610 SUBST (XEXP (x, 1), op1);
04611 }
04612 break;
04613
04614 case IF_THEN_ELSE:
04615 return simplify_if_then_else (x);
04616
04617 case ZERO_EXTRACT:
04618 case SIGN_EXTRACT:
04619 case ZERO_EXTEND:
04620 case SIGN_EXTEND:
04621
04622 if (in_dest)
04623 return x;
04624
04625 return expand_compound_operation (x);
04626
04627 case SET:
04628 return simplify_set (x);
04629
04630 case AND:
04631 case IOR:
04632 case XOR:
04633 return simplify_logical (x, last);
04634
04635 case ABS:
04636
04637 if (GET_CODE (XEXP (x, 0)) == NEG)
04638 SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
04639
04640
04641
04642 if (GET_MODE (XEXP (x, 0)) == VOIDmode)
04643 break;
04644
04645
04646 if (GET_CODE (XEXP (x, 0)) == FFS || GET_CODE (XEXP (x, 0)) == ABS
04647 || ((GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
04648 <= HOST_BITS_PER_WIDE_INT)
04649 && ((nonzero_bits (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
04650 & ((HOST_WIDE_INT) 1
04651 << (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - 1)))
04652 == 0)))
04653 return XEXP (x, 0);
04654
04655
04656 if (num_sign_bit_copies (XEXP (x, 0), mode) == GET_MODE_BITSIZE (mode))
04657 return gen_rtx_NEG (mode, XEXP (x, 0));
04658
04659 break;
04660
04661 case FFS:
04662
04663 if (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND
04664 || GET_CODE (XEXP (x, 0)) == ZERO_EXTEND)
04665 SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
04666 break;
04667
04668 case FLOAT:
04669
04670 if (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)
04671 SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
04672 break;
04673
04674 case ASHIFT:
04675 case LSHIFTRT:
04676 case ASHIFTRT:
04677 case ROTATE:
04678 case ROTATERT:
04679
04680 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
04681 return simplify_shift_const (x, code, mode, XEXP (x, 0),
04682 INTVAL (XEXP (x, 1)));
04683
04684 #ifdef SHIFT_COUNT_TRUNCATED
04685 else if (SHIFT_COUNT_TRUNCATED && GET_CODE (XEXP (x, 1)) != REG)
04686 SUBST (XEXP (x, 1),
04687 force_to_mode (XEXP (x, 1), GET_MODE (XEXP (x, 1)),
04688 ((HOST_WIDE_INT) 1
04689 << exact_log2 (GET_MODE_BITSIZE (GET_MODE (x))))
04690 - 1,
04691 NULL_RTX, 0));
04692 #endif
04693
04694 break;
04695
04696 case VEC_SELECT:
04697 {
04698 rtx op0 = XEXP (x, 0);
04699 rtx op1 = XEXP (x, 1);
04700 int len;
04701
04702 if (GET_CODE (op1) != PARALLEL)
04703 abort ();
04704 len = XVECLEN (op1, 0);
04705 if (len == 1
04706 && GET_CODE (XVECEXP (op1, 0, 0)) == CONST_INT
04707 && GET_CODE (op0) == VEC_CONCAT)
04708 {
04709 int offset = INTVAL (XVECEXP (op1, 0, 0)) * GET_MODE_SIZE (GET_MODE (x));
04710
04711
04712 for (;;)
04713 {
04714 if (GET_MODE (op0) == GET_MODE (x))
04715 return op0;
04716 if (GET_CODE (op0) == VEC_CONCAT)
04717 {
04718 HOST_WIDE_INT op0_size = GET_MODE_SIZE (GET_MODE (XEXP (op0, 0)));
04719 if (op0_size < offset)
04720 op0 = XEXP (op0, 0);
04721 else
04722 {
04723 offset -= op0_size;
04724 op0 = XEXP (op0, 1);
04725 }
04726 }
04727 else
04728 break;
04729 }
04730 }
04731 }
04732
04733 break;
04734
04735 default:
04736 break;
04737 }
04738
04739 return x;
04740 }
04741
04742
04743
04744 static rtx
04745 simplify_if_then_else (x)
04746 rtx x;
04747 {
04748 enum machine_mode mode = GET_MODE (x);
04749 rtx cond = XEXP (x, 0);
04750 rtx true_rtx = XEXP (x, 1);
04751 rtx false_rtx = XEXP (x, 2);
04752 enum rtx_code true_code = GET_CODE (cond);
04753 int comparison_p = GET_RTX_CLASS (true_code) == '<';
04754 rtx temp;
04755 int i;
04756 enum rtx_code false_code;
04757 rtx reversed;
04758
04759
04760 if (comparison_p && true_rtx == const_true_rtx && false_rtx == const0_rtx)
04761 return gen_binary (true_code, mode, XEXP (cond, 0), XEXP (cond, 1));
04762
04763
04764 if (comparison_p
04765 && true_rtx == const0_rtx && false_rtx == const_true_rtx
04766 && (reversed = reversed_comparison (cond, mode, XEXP (cond, 0),
04767 XEXP (cond, 1))))
04768 return reversed;
04769
04770
04771
04772
04773
04774 if (comparison_p
04775 && ((false_code = combine_reversed_comparison_code (cond))
04776 != UNKNOWN)
04777 && GET_CODE (XEXP (cond, 0)) == REG)
04778 {
04779 HOST_WIDE_INT nzb;
04780 rtx from = XEXP (cond, 0);
04781 rtx true_val = XEXP (cond, 1);
04782 rtx false_val = true_val;
04783 int swapped = 0;
04784
04785
04786
04787 if (false_code == EQ)
04788 {
04789 swapped = 1, true_code = EQ, false_code = NE;
04790 temp = true_rtx, true_rtx = false_rtx, false_rtx = temp;
04791 }
04792
04793
04794
04795
04796
04797 if (true_code == EQ && true_val == const0_rtx
04798 && exact_log2 (nzb = nonzero_bits (from, GET_MODE (from))) >= 0)
04799 false_code = EQ, false_val = GEN_INT (nzb);
04800 else if (true_code == EQ && true_val == const0_rtx
04801 && (num_sign_bit_copies (from, GET_MODE (from))
04802 == GET_MODE_BITSIZE (GET_MODE (from))))
04803 false_code = EQ, false_val = constm1_rtx;
04804
04805
04806
04807
04808
04809 if (reg_mentioned_p (from, true_rtx))
04810 true_rtx = subst (known_cond (copy_rtx (true_rtx), true_code,
04811 from, true_val),
04812 pc_rtx, pc_rtx, 0, 0);
04813 if (reg_mentioned_p (from, false_rtx))
04814 false_rtx = subst (known_cond (copy_rtx (false_rtx), false_code,
04815 from, false_val),
04816 pc_rtx, pc_rtx, 0, 0);
04817
04818 SUBST (XEXP (x, 1), swapped ? false_rtx : true_rtx);
04819 SUBST (XEXP (x, 2), swapped ? true_rtx : false_rtx);
04820
04821 true_rtx = XEXP (x, 1);
04822 false_rtx = XEXP (x, 2);
04823 true_code = GET_CODE (cond);
04824 }
04825
04826
04827
04828
04829
04830
04831
04832 if (comparison_p
04833 && combine_reversed_comparison_code (cond) != UNKNOWN
04834 && (true_rtx == pc_rtx
04835 || (CONSTANT_P (true_rtx)
04836 && GET_CODE (false_rtx) != CONST_INT && false_rtx != pc_rtx)
04837 || true_rtx == const0_rtx
04838 || (GET_RTX_CLASS (GET_CODE (true_rtx)) == 'o'
04839 && GET_RTX_CLASS (GET_CODE (false_rtx)) != 'o')
04840 || (GET_CODE (true_rtx) == SUBREG
04841 && GET_RTX_CLASS (GET_CODE (SUBREG_REG (true_rtx))) == 'o'
04842 && GET_RTX_CLASS (GET_CODE (false_rtx)) != 'o')
04843 || reg_mentioned_p (true_rtx, false_rtx)
04844 || rtx_equal_p (false_rtx, XEXP (cond, 0))))
04845 {
04846 true_code = reversed_comparison_code (cond, NULL);
04847 SUBST (XEXP (x, 0),
04848 reversed_comparison (cond, GET_MODE (cond), XEXP (cond, 0),
04849 XEXP (cond, 1)));
04850
04851 SUBST (XEXP (x, 1), false_rtx);
04852 SUBST (XEXP (x, 2), true_rtx);
04853
04854 temp = true_rtx, true_rtx = false_rtx, false_rtx = temp;
04855 cond = XEXP (x, 0);
04856
04857
04858 true_code = GET_CODE (cond);
04859 comparison_p = GET_RTX_CLASS (true_code) == '<';
04860 }
04861
04862
04863
04864 if (rtx_equal_p (true_rtx, false_rtx) && ! side_effects_p (cond))
04865 return true_rtx;
04866
04867
04868 if (true_code == EQ && ! side_effects_p (cond)
04869 && !HONOR_NANS (mode)
04870 && rtx_equal_p (XEXP (cond, 0), false_rtx)
04871 && rtx_equal_p (XEXP (cond, 1), true_rtx))
04872 return false_rtx;
04873 else if (true_code == NE && ! side_effects_p (cond)
04874 && !HONOR_NANS (mode)
04875 && rtx_equal_p (XEXP (cond, 0), true_rtx)
04876 && rtx_equal_p (XEXP (cond, 1), false_rtx))
04877 return true_rtx;
04878
04879
04880
04881 if (GET_MODE_CLASS (mode) == MODE_INT
04882 && GET_CODE (false_rtx) == NEG
04883 && rtx_equal_p (true_rtx, XEXP (false_rtx, 0))
04884 && comparison_p
04885 && rtx_equal_p (true_rtx, XEXP (cond, 0))
04886 && ! side_effects_p (true_rtx))
04887 switch (true_code)
04888 {
04889 case GT:
04890 case GE:
04891 return simplify_gen_unary (ABS, mode, true_rtx, mode);
04892 case LT:
04893 case LE:
04894 return
04895 simplify_gen_unary (NEG, mode,
04896 simplify_gen_unary (ABS, mode, true_rtx, mode),
04897 mode);
04898 default:
04899 break;
04900 }
04901
04902
04903
04904 if ((! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
04905 && comparison_p
04906 && rtx_equal_p (XEXP (cond, 0), true_rtx)
04907 && rtx_equal_p (XEXP (cond, 1), false_rtx)
04908 && ! side_effects_p (cond))
04909 switch (true_code)
04910 {
04911 case GE:
04912 case GT:
04913 return gen_binary (SMAX, mode, true_rtx, false_rtx);
04914 case LE:
04915 case LT:
04916 return gen_binary (SMIN, mode, true_rtx, false_rtx);
04917 case GEU:
04918 case GTU:
04919 return gen_binary (UMAX, mode, true_rtx, false_rtx);
04920 case LEU:
04921 case LTU:
04922 return gen_binary (UMIN, mode, true_rtx, false_rtx);
04923 default:
04924 break;
04925 }
04926
04927
04928
04929
04930
04931
04932
04933
04934 if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
04935 && comparison_p
04936 && GET_MODE_CLASS (mode) == MODE_INT
04937 && ! side_effects_p (x))
04938 {
04939 rtx t = make_compound_operation (true_rtx, SET);
04940 rtx f = make_compound_operation (false_rtx, SET);
04941 rtx cond_op0 = XEXP (cond, 0);
04942 rtx cond_op1 = XEXP (cond, 1);
04943 enum rtx_code op = NIL, extend_op = NIL;
04944 enum machine_mode m = mode;
04945 rtx z = 0, c1 = NULL_RTX;
04946
04947 if ((GET_CODE (t) == PLUS || GET_CODE (t) == MINUS
04948 || GET_CODE (t) == IOR || GET_CODE (t) == XOR
04949 || GET_CODE (t) == ASHIFT
04950 || GET_CODE (t) == LSHIFTRT || GET_CODE (t) == ASHIFTRT)
04951 && rtx_equal_p (XEXP (t, 0), f))
04952 c1 = XEXP (t, 1), op = GET_CODE (t), z = f;
04953
04954
04955
04956 else if ((GET_CODE (t) == PLUS || GET_CODE (t) == IOR
04957 || GET_CODE (t) == XOR)
04958 && rtx_equal_p (XEXP (t, 1), f))
04959 c1 = XEXP (t, 0), op = GET_CODE (t), z = f;
04960 else if (GET_CODE (t) == SIGN_EXTEND
04961 && (GET_CODE (XEXP (t, 0)) == PLUS
04962 || GET_CODE (XEXP (t, 0)) == MINUS
04963 || GET_CODE (XEXP (t, 0)) == IOR
04964 || GET_CODE (XEXP (t, 0)) == XOR
04965 || GET_CODE (XEXP (t, 0)) == ASHIFT
04966 || GET_CODE (XEXP (t, 0)) == LSHIFTRT
04967 || GET_CODE (XEXP (t, 0)) == ASHIFTRT)
04968 && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG
04969 && subreg_lowpart_p (XEXP (XEXP (t, 0), 0))
04970 && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f)
04971 && (num_sign_bit_copies (f, GET_MODE (f))
04972 > (unsigned int)
04973 (GET_MODE_BITSIZE (mode)
04974 - GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (t, 0), 0))))))
04975 {
04976 c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0));
04977 extend_op = SIGN_EXTEND;
04978 m = GET_MODE (XEXP (t, 0));
04979 }
04980 else if (GET_CODE (t) == SIGN_EXTEND
04981 && (GET_CODE (XEXP (t, 0)) == PLUS
04982 || GET_CODE (XEXP (t, 0)) == IOR
04983 || GET_CODE (XEXP (t, 0)) == XOR)
04984 && GET_CODE (XEXP (XEXP (t, 0), 1)) == SUBREG
04985 && subreg_lowpart_p (XEXP (XEXP (t, 0), 1))
04986 && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 1)), f)
04987 && (num_sign_bit_copies (f, GET_MODE (f))
04988 > (unsigned int)
04989 (GET_MODE_BITSIZE (mode)
04990 - GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (t, 0), 1))))))
04991 {
04992 c1 = XEXP (XEXP (t, 0), 0); z = f; op = GET_CODE (XEXP (t, 0));
04993 extend_op = SIGN_EXTEND;
04994 m = GET_MODE (XEXP (t, 0));
04995 }
04996 else if (GET_CODE (t) == ZERO_EXTEND
04997 && (GET_CODE (XEXP (t, 0)) == PLUS
04998 || GET_CODE (XEXP (t, 0)) == MINUS
04999 || GET_CODE (XEXP (t, 0)) == IOR
05000 || GET_CODE (XEXP (t, 0)) == XOR
05001 || GET_CODE (XEXP (t, 0)) == ASHIFT
05002 || GET_CODE (XEXP (t, 0)) == LSHIFTRT
05003 || GET_CODE (XEXP (t, 0)) == ASHIFTRT)
05004 && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG
05005 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
05006 && subreg_lowpart_p (XEXP (XEXP (t, 0), 0))
05007 && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f)
05008 && ((nonzero_bits (f, GET_MODE (f))
05009 & ~GET_MODE_MASK (GET_MODE (XEXP (XEXP (t, 0), 0))))
05010 == 0))
05011 {
05012 c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0));
05013 extend_op = ZERO_EXTEND;
05014 m = GET_MODE (XEXP (t, 0));
05015 }
05016 else if (GET_CODE (t) == ZERO_EXTEND
05017 && (GET_CODE (XEXP (t, 0)) == PLUS
05018 || GET_CODE (XEXP (t, 0)) == IOR
05019 || GET_CODE (XEXP (t, 0)) == XOR)
05020 && GET_CODE (XEXP (XEXP (t, 0), 1)) == SUBREG
05021 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
05022 && subreg_lowpart_p (XEXP (XEXP (t, 0), 1))
05023 && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 1)), f)
05024 && ((nonzero_bits (f, GET_MODE (f))
05025 & ~GET_MODE_MASK (GET_MODE (XEXP (XEXP (t, 0), 1))))
05026 == 0))
05027 {
05028 c1 = XEXP (XEXP (t, 0), 0); z = f; op = GET_CODE (XEXP (t, 0));
05029 extend_op = ZERO_EXTEND;
05030 m = GET_MODE (XEXP (t, 0));
05031 }
05032
05033 if (z)
05034 {
05035 temp = subst (gen_binary (true_code, m, cond_op0, cond_op1),
05036 pc_rtx, pc_rtx, 0, 0);
05037 temp = gen_binary (MULT, m, temp,
05038 gen_binary (MULT, m, c1, const_true_rtx));
05039 temp = subst (temp, pc_rtx, pc_rtx, 0, 0);
05040 temp = gen_binary (op, m, gen_lowpart_for_combine (m, z), temp);
05041
05042 if (extend_op != NIL)
05043 temp = simplify_gen_unary (extend_op, mode, temp, m);
05044
05045 return temp;
05046 }
05047 }
05048
05049
05050
05051
05052
05053
05054 if (true_code == NE && XEXP (cond, 1) == const0_rtx
05055 && false_rtx == const0_rtx && GET_CODE (true_rtx) == CONST_INT
05056 && ((1 == nonzero_bits (XEXP (cond, 0), mode)
05057 && (i = exact_log2 (INTVAL (true_rtx))) >= 0)
05058 || ((num_sign_bit_copies (XEXP (cond, 0), mode)
05059 == GET_MODE_BITSIZE (mode))
05060 && (i = exact_log2 (-INTVAL (true_rtx))) >= 0)))
05061 return
05062 simplify_shift_const (NULL_RTX, ASHIFT, mode,
05063 gen_lowpart_for_combine (mode, XEXP (cond, 0)), i);
05064
05065 return x;
05066 }
05067
05068
05069
05070 static rtx
05071 simplify_set (x)
05072 rtx x;
05073 {
05074 rtx src = SET_SRC (x);
05075 rtx dest = SET_DEST (x);
05076 enum machine_mode mode
05077 = GET_MODE (src) != VOIDmode ? GET_MODE (src) : GET_MODE (dest);
05078 rtx other_insn;
05079 rtx *cc_use;
05080
05081
05082 if (GET_CODE (dest) == PC && GET_CODE (src) == RETURN)
05083 return src;
05084
05085
05086
05087
05088
05089 if (GET_MODE_CLASS (mode) == MODE_INT
05090 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
05091 {
05092 src = force_to_mode (src, mode, ~(HOST_WIDE_INT) 0, NULL_RTX, 0);
05093 SUBST (SET_SRC (x), src);
05094 }
05095
05096
05097
05098
05099 if ((GET_MODE_CLASS (mode) == MODE_CC
05100 || GET_CODE (src) == COMPARE
05101 || CC0_P (dest))
05102 && (cc_use = find_single_use (dest, subst_insn, &other_insn)) != 0
05103 && (undobuf.other_insn == 0 || other_insn == undobuf.other_insn)
05104 && GET_RTX_CLASS (GET_CODE (*cc_use)) == '<'
05105 && rtx_equal_p (XEXP (*cc_use, 0), dest))
05106 {
05107 enum rtx_code old_code = GET_CODE (*cc_use);
05108 enum rtx_code new_code;
05109 rtx op0, op1, tmp;
05110 int other_changed = 0;
05111 enum machine_mode compare_mode = GET_MODE (dest);
05112 enum machine_mode tmp_mode;
05113
05114 if (GET_CODE (src) == COMPARE)
05115 op0 = XEXP (src, 0), op1 = XEXP (src, 1);
05116 else
05117 op0 = src, op1 = const0_rtx;
05118
05119
05120 if (GET_MODE (op0) != VOIDmode)
05121 tmp_mode = GET_MODE (op0);
05122 else if (GET_MODE (op1) != VOIDmode)
05123 tmp_mode = GET_MODE (op1);
05124 else
05125 tmp_mode = compare_mode;
05126 tmp = simplify_relational_operation (old_code, tmp_mode, op0, op1);
05127 if (tmp != NULL_RTX)
05128 {
05129 rtx pat = PATTERN (other_insn);
05130 undobuf.other_insn = other_insn;
05131 SUBST (*cc_use, tmp);
05132
05133
05134 if (GET_CODE (pat) == SET)
05135 {
05136 rtx new = simplify_rtx (SET_SRC (pat));
05137 if (new != NULL_RTX)
05138 SUBST (SET_SRC (pat), new);
05139 }
05140
05141
05142 SUBST (SET_DEST (x), pc_rtx);
05143 SUBST (SET_SRC (x), pc_rtx);
05144 return x;
05145 }
05146
05147
05148 new_code = simplify_comparison (old_code, &op0, &op1);
05149
05150 #ifdef EXTRA_CC_MODES
05151
05152
05153 compare_mode = SELECT_CC_MODE (new_code, op0, op1);
05154 #endif
05155
05156 #if !defined (HAVE_cc0) && defined (EXTRA_CC_MODES)
05157
05158
05159
05160
05161
05162 if (compare_mode != GET_MODE (dest))
05163 {
05164 unsigned int regno = REGNO (dest);
05165 rtx new_dest = gen_rtx_REG (compare_mode, regno);
05166
05167 if (regno < FIRST_PSEUDO_REGISTER
05168 || (REG_N_SETS (regno) == 1 && ! REG_USERVAR_P (dest)))
05169 {
05170 if (regno >= FIRST_PSEUDO_REGISTER)
05171 SUBST (regno_reg_rtx[regno], new_dest);
05172
05173 SUBST (SET_DEST (x), new_dest);
05174 SUBST (XEXP (*cc_use, 0), new_dest);
05175 other_changed = 1;
05176
05177 dest = new_dest;
05178 }
05179 }
05180 #endif
05181
05182
05183
05184 if (new_code != old_code)
05185 {
05186 unsigned HOST_WIDE_INT mask;
05187
05188 SUBST (*cc_use, gen_rtx_fmt_ee (new_code, GET_MODE (*cc_use),
05189 dest, const0_rtx));
05190
05191
05192
05193
05194
05195
05196
05197 if (((old_code == NE && new_code == EQ)
05198 || (old_code == EQ && new_code == NE))
05199 && ! other_changed && op1 == const0_rtx
05200 && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT
05201 && exact_log2 (mask = nonzero_bits (op0, GET_MODE (op0))) >= 0)
05202 {
05203 rtx pat = PATTERN (other_insn), note = 0;
05204
05205 if ((recog_for_combine (&pat, other_insn, ¬e) < 0
05206 && ! check_asm_operands (pat)))
05207 {
05208 PUT_CODE (*cc_use, old_code);
05209 other_insn = 0;
05210
05211 op0 = gen_binary (XOR, GET_MODE (op0), op0, GEN_INT (mask));
05212 }
05213 }
05214
05215 other_changed = 1;
05216 }
05217
05218 if (other_changed)
05219 undobuf.other_insn = other_insn;
05220
05221 #ifdef HAVE_cc0
05222
05223
05224 if (op1 == const0_rtx && dest == cc0_rtx)
05225 {
05226 SUBST (SET_SRC (x), op0);
05227 src = op0;
05228 }
05229 else
05230 #endif
05231
05232
05233
05234 if (GET_CODE (src) != COMPARE || GET_MODE (src) != compare_mode)
05235 {
05236 SUBST (SET_SRC (x), gen_rtx_COMPARE (compare_mode, op0, op1));
05237 src = SET_SRC (x);
05238 }
05239 else
05240 {
05241
05242 SUBST (XEXP (src, 0), op0);
05243 SUBST (XEXP (src, 1), op1);
05244 }
05245 }
05246 else
05247 {
05248
05249
05250 src = make_compound_operation (src, SET);
05251 SUBST (SET_SRC (x), src);
05252 }
05253
05254
05255
05256
05257
05258
05259
05260
05261
05262
05263
05264
05265
05266 if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)
05267 && GET_RTX_CLASS (GET_CODE (SUBREG_REG (src))) != 'o'
05268 && (((GET_MODE_SIZE (GET_MODE (src)) + (UNITS_PER_WORD - 1))
05269 / UNITS_PER_WORD)
05270 == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
05271 + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
05272 #ifndef WORD_REGISTER_OPERATIONS
05273 && (GET_MODE_SIZE (GET_MODE (src))
05274 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
05275 #endif
05276 #ifdef CANNOT_CHANGE_MODE_CLASS
05277 && ! (GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER
05278 && REG_CANNOT_CHANGE_MODE_P (REGNO (dest),
05279 GET_MODE (SUBREG_REG (src)),
05280 GET_MODE (src)))
05281 #endif
05282 && (GET_CODE (dest) == REG
05283 || (GET_CODE (dest) == SUBREG
05284 && GET_CODE (SUBREG_REG (dest)) == REG)))
05285 {
05286 SUBST (SET_DEST (x),
05287 gen_lowpart_for_combine (GET_MODE (SUBREG_REG (src)),
05288 dest));
05289 SUBST (SET_SRC (x), SUBREG_REG (src));
05290
05291 src = SET_SRC (x), dest = SET_DEST (x);
05292 }
05293
05294 #ifdef HAVE_cc0
05295
05296
05297 if (dest == cc0_rtx
05298 && GET_CODE (src) == SUBREG
05299 && subreg_lowpart_p (src)
05300 && (GET_MODE_BITSIZE (GET_MODE (src))
05301 < GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (src)))))
05302 {
05303 rtx inner = SUBREG_REG (src);
05304 enum machine_mode inner_mode = GET_MODE (inner);
05305
05306
05307 if (GET_MODE_BITSIZE (inner_mode) <= HOST_BITS_PER_WIDE_INT
05308 && (nonzero_bits (inner, inner_mode)
05309 < ((unsigned HOST_WIDE_INT) 1
05310 << (GET_MODE_BITSIZE (GET_MODE (src)) - 1))))
05311 {
05312 SUBST (SET_SRC (x), inner);
05313 src = SET_SRC (x);
05314 }
05315 }
05316 #endif
05317
05318 #ifdef LOAD_EXTEND_OP
05319
05320
05321
05322
05323 if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)
05324 && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (src))) != NIL
05325 && SUBREG_BYTE (src) == 0
05326 && (GET_MODE_SIZE (GET_MODE (src))
05327 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
05328 && GET_CODE (SUBREG_REG (src)) == MEM)
05329 {
05330 SUBST (SET_SRC (x),
05331 gen_rtx (LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (src))),
05332 GET_MODE (src), SUBREG_REG (src)));
05333
05334 src = SET_SRC (x);
05335 }
05336 #endif
05337
05338
05339
05340
05341
05342
05343
05344 if (GET_CODE (dest) != PC
05345 && GET_CODE (src) == IF_THEN_ELSE
05346 && GET_MODE_CLASS (GET_MODE (src)) == MODE_INT
05347 && (GET_CODE (XEXP (src, 0)) == EQ || GET_CODE (XEXP (src, 0)) == NE)
05348 && XEXP (XEXP (src, 0), 1) == const0_rtx
05349 && GET_MODE (src) == GET_MODE (XEXP (XEXP (src, 0), 0))
05350 #ifdef HAVE_conditional_move
05351 && ! can_conditionally_move_p (GET_MODE (src))
05352 #endif
05353 && (num_sign_bit_copies (XEXP (XEXP (src, 0), 0),
05354 GET_MODE (XEXP (XEXP (src, 0), 0)))
05355 == GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (src, 0), 0))))
05356 && ! side_effects_p (src))
05357 {
05358 rtx true_rtx = (GET_CODE (XEXP (src, 0)) == NE
05359 ? XEXP (src, 1) : XEXP (src, 2));
05360 rtx false_rtx = (GET_CODE (XEXP (src, 0)) == NE
05361 ? XEXP (src, 2) : XEXP (src, 1));
05362 rtx term1 = const0_rtx, term2, term3;
05363
05364 if (GET_CODE (true_rtx) == IOR
05365 && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
05366 term1 = false_rtx, true_rtx = XEXP(true_rtx, 1), false_rtx = const0_rtx;
05367 else if (GET_CODE (true_rtx) == IOR
05368 && rtx_equal_p (XEXP (true_rtx, 1), false_rtx))
05369 term1 = false_rtx, true_rtx = XEXP(true_rtx, 0), false_rtx = const0_rtx;
05370 else if (GET_CODE (false_rtx) == IOR
05371 && rtx_equal_p (XEXP (false_rtx, 0), true_rtx))
05372 term1 = true_rtx, false_rtx = XEXP(false_rtx, 1), true_rtx = const0_rtx;
05373 else if (GET_CODE (false_rtx) == IOR
05374 && rtx_equal_p (XEXP (false_rtx, 1), true_rtx))
05375 term1 = true_rtx, false_rtx = XEXP(false_rtx, 0), true_rtx = const0_rtx;
05376
05377 term2 = gen_binary (AND, GET_MODE (src),
05378 XEXP (XEXP (src, 0), 0), true_rtx);
05379 term3 = gen_binary (AND, GET_MODE (src),
05380 simplify_gen_unary (NOT, GET_MODE (src),
05381 XEXP (XEXP (src, 0), 0),
05382 GET_MODE (src)),
05383 false_rtx);
05384
05385 SUBST (SET_SRC (x),
05386 gen_binary (IOR, GET_MODE (src),
05387 gen_binary (IOR, GET_MODE (src), term1, term2),
05388 term3));
05389
05390 src = SET_SRC (x);
05391 }
05392
05393
05394
05395 if (GET_CODE (src) == CLOBBER && XEXP (src, 0) == const0_rtx)
05396 return src;
05397 else if (GET_CODE (dest) == CLOBBER && XEXP (dest, 0) == const0_rtx)
05398 return dest;
05399 else
05400
05401 return make_field_assignment (x);
05402 }
05403
05404
05405
05406
05407 static rtx
05408 simplify_logical (x, last)
05409 rtx x;
05410 int last;
05411 {
05412 enum machine_mode mode = GET_MODE (x);
05413 rtx op0 = XEXP (x, 0);
05414 rtx op1 = XEXP (x, 1);
05415 rtx reversed;
05416
05417 switch (GET_CODE (x))
05418 {
05419 case AND:
05420
05421
05422 if (GET_CODE (op0) == XOR
05423 && rtx_equal_p (XEXP (op0, 0), op1)
05424 && ! side_effects_p (op1))
05425 x = gen_binary (AND, mode,
05426 simplify_gen_unary (NOT, mode, XEXP (op0, 1), mode),
05427 op1);
05428
05429 if (GET_CODE (op0) == XOR
05430 && rtx_equal_p (XEXP (op0, 1), op1)
05431 && ! side_effects_p (op1))
05432 x = gen_binary (AND, mode,
05433 simplify_gen_unary (NOT, mode, XEXP (op0, 0), mode),
05434 op1);
05435
05436
05437 if (GET_CODE (op0) == NOT
05438 && GET_CODE (XEXP (op0, 0)) == XOR
05439 && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
05440 && ! side_effects_p (op1))
05441 x = gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
05442
05443 if (GET_CODE (op0) == NOT
05444 && GET_CODE (XEXP (op0, 0)) == XOR
05445 && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
05446 && ! side_effects_p (op1))
05447 x = gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
05448
05449
05450
05451
05452 if (GET_CODE (op1) == CONST_INT
05453 && (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
05454 || INTVAL (op1) > 0))
05455 {
05456 x = simplify_and_const_int (x, mode, op0, INTVAL (op1));
05457
05458
05459
05460
05461 if (last
05462 && GET_CODE (x) == IOR && GET_CODE (op0) == AND
05463 && GET_CODE (XEXP (op0, 1)) == CONST_INT
05464 && GET_CODE (op1) == CONST_INT)
05465 return gen_binary (IOR, mode,
05466 gen_binary (AND, mode, XEXP (op0, 0),
05467 GEN_INT (INTVAL (XEXP (op0, 1))
05468 & ~INTVAL (op1))), op1);
05469
05470 if (GET_CODE (x) != AND)
05471 return x;
05472
05473 if (GET_RTX_CLASS (GET_CODE (x)) == 'c'
05474 || GET_RTX_CLASS (GET_CODE (x)) == '2')
05475 op0 = XEXP (x, 0), op1 = XEXP (x, 1);
05476 }
05477
05478
05479 if (GET_CODE (op0) == IOR
05480 && (rtx_equal_p (XEXP (op0, 0), op1)
05481 || rtx_equal_p (XEXP (op0, 1), op1))
05482 && ! side_effects_p (XEXP (op0, 0))
05483 && ! side_effects_p (XEXP (op0, 1)))
05484 return op1;
05485
05486
05487
05488
05489
05490
05491
05492
05493
05494
05495
05496
05497
05498
05499
05500
05501 if (GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
05502 {
05503 x = apply_distributive_law
05504 (gen_binary (GET_CODE (op0), mode,
05505 gen_binary (AND, mode, XEXP (op0, 0), op1),
05506 gen_binary (AND, mode, XEXP (op0, 1),
05507 copy_rtx (op1))));
05508 if (GET_CODE (x) != AND)
05509 return x;
05510 }
05511
05512 if (GET_CODE (op1) == IOR || GET_CODE (op1) == XOR)
05513 return apply_distributive_law
05514 (gen_binary (GET_CODE (op1), mode,
05515 gen_binary (AND, mode, XEXP (op1, 0), op0),
05516 gen_binary (AND, mode, XEXP (op1, 1),
05517 copy_rtx (op0))));
05518
05519
05520
05521
05522 if (GET_CODE (op0) == NOT && GET_CODE (op1) == XOR)
05523 return apply_distributive_law
05524 (gen_binary (XOR, mode,
05525 gen_binary (IOR, mode, XEXP (op0, 0), XEXP (op1, 0)),
05526 gen_binary (IOR, mode, copy_rtx (XEXP (op0, 0)),
05527 XEXP (op1, 1))));
05528
05529 else if (GET_CODE (op1) == NOT && GET_CODE (op0) == XOR)
05530 return apply_distributive_law
05531 (gen_binary (XOR, mode,
05532 gen_binary (IOR, mode, XEXP (op1, 0), XEXP (op0, 0)),
05533 gen_binary (IOR, mode, copy_rtx (XEXP (op1, 0)), XEXP (op0, 1))));
05534 break;
05535
05536 case IOR:
05537
05538 if (GET_CODE (op1) == CONST_INT
05539 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
05540 && (nonzero_bits (op0, mode) & ~INTVAL (op1)) == 0)
05541 return op1;
05542
05543
05544 if (GET_CODE (op0) == AND
05545 && (rtx_equal_p (XEXP (op0, 0), op1)
05546 || rtx_equal_p (XEXP (op0, 1), op1))
05547 && ! side_effects_p (XEXP (op0, 0))
05548 && ! side_effects_p (XEXP (op0, 1)))
05549 return op1;
05550
05551
05552
05553
05554 if (GET_CODE (op0) == AND)
05555 {
05556 x = apply_distributive_law
05557 (gen_binary (AND, mode,
05558 gen_binary (IOR, mode, XEXP (op0, 0), op1),
05559 gen_binary (IOR, mode, XEXP (op0, 1),
05560 copy_rtx (op1))));
05561
05562 if (GET_CODE (x) != IOR)
05563 return x;
05564 }
05565
05566 if (GET_CODE (op1) == AND)
05567 {
05568 x = apply_distributive_law
05569 (gen_binary (AND, mode,
05570 gen_binary (IOR, mode, XEXP (op1, 0), op0),
05571 gen_binary (IOR, mode, XEXP (op1, 1),
05572 copy_rtx (op0))));
05573
05574 if (GET_CODE (x) != IOR)
05575 return x;
05576 }
05577
05578
05579
05580
05581 if (((GET_CODE (op0) == ASHIFT && GET_CODE (op1) == LSHIFTRT)
05582 || (GET_CODE (op1) == ASHIFT && GET_CODE (op0) == LSHIFTRT))
05583 && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
05584 && GET_CODE (XEXP (op0, 1)) == CONST_INT
05585 && GET_CODE (XEXP (op1, 1)) == CONST_INT
05586 && (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1))
05587 == GET_MODE_BITSIZE (mode)))
05588 return gen_rtx_ROTATE (mode, XEXP (op0, 0),
05589 (GET_CODE (op0) == ASHIFT
05590 ? XEXP (op0, 1) : XEXP (op1, 1)));
05591
05592
05593
05594
05595
05596
05597 if (GET_CODE (op1) == CONST_INT && GET_CODE (op0) == ASHIFTRT
05598 && GET_CODE (XEXP (op0, 0)) == PLUS
05599 && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
05600 && GET_CODE (XEXP (op0, 1)) == CONST_INT
05601 && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
05602 {
05603 int count = INTVAL (XEXP (op0, 1));
05604 HOST_WIDE_INT mask = INTVAL (op1) << count;
05605
05606 if (mask >> count == INTVAL (op1)
05607 && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
05608 {
05609 SUBST (XEXP (XEXP (op0, 0), 1),
05610 GEN_INT (INTVAL (XEXP (XEXP (op0, 0), 1)) | mask));
05611 return op0;
05612 }
05613 }
05614 break;
05615
05616 case XOR:
05617
05618
05619
05620
05621 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
05622 && (nonzero_bits (op0, mode)
05623 & nonzero_bits (op1, mode)) == 0)
05624 return (gen_binary (IOR, mode, op0, op1));
05625
05626
05627
05628
05629 {
05630 int num_negated = 0;
05631
05632 if (GET_CODE (op0) == NOT)
05633 num_negated++, op0 = XEXP (op0, 0);
05634 if (GET_CODE (op1) == NOT)
05635 num_negated++, op1 = XEXP (op1, 0);
05636
05637 if (num_negated == 2)
05638 {
05639 SUBST (XEXP (x, 0), op0);
05640 SUBST (XEXP (x, 1), op1);
05641 }
05642 else if (num_negated == 1)
05643 return
05644 simplify_gen_unary (NOT, mode, gen_binary (XOR, mode, op0, op1),
05645 mode);
05646 }
05647
05648
05649
05650
05651
05652 if (GET_CODE (op0) == AND
05653 && rtx_equal_p (XEXP (op0, 1), op1)
05654 && ! side_effects_p (op1))
05655 return gen_binary (AND, mode,
05656 simplify_gen_unary (NOT, mode, XEXP (op0, 0), mode),
05657 op1);
05658
05659 else if (GET_CODE (op0) == AND
05660 && rtx_equal_p (XEXP (op0, 0), op1)
05661 && ! side_effects_p (op1))
05662 return gen_binary (AND, mode,
05663 simplify_gen_unary (NOT, mode, XEXP (op0, 1), mode),
05664 op1);
05665
05666
05667
05668 if (STORE_FLAG_VALUE == 1
05669 && op1 == const1_rtx
05670 && GET_RTX_CLASS (GET_CODE (op0)) == '<'
05671 && (reversed = reversed_comparison (op0, mode, XEXP (op0, 0),
05672 XEXP (op0, 1))))
05673 return reversed;
05674
05675
05676
05677
05678
05679 if (STORE_FLAG_VALUE == 1
05680 && op1 == const1_rtx
05681 && GET_CODE (op0) == LSHIFTRT
05682 && GET_CODE (XEXP (op0, 1)) == CONST_INT
05683 && INTVAL (XEXP (op0, 1)) == GET_MODE_BITSIZE (mode) - 1)
05684 return gen_rtx_GE (mode, XEXP (op0, 0), const0_rtx);
05685
05686
05687
05688 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
05689 && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
05690 == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))
05691 && op1 == const_true_rtx
05692 && GET_RTX_CLASS (GET_CODE (op0)) == '<'
05693 && (reversed = reversed_comparison (op0, mode, XEXP (op0, 0),
05694 XEXP (op0, 1))))
05695 return reversed;
05696
05697 break;
05698
05699 default:
05700 abort ();
05701 }
05702
05703 return x;
05704 }
05705
05706
05707
05708
05709
05710
05711
05712
05713
05714
05715
05716
05717
05718
05719 static rtx
05720 expand_compound_operation (x)
05721 rtx x;
05722 {
05723 unsigned HOST_WIDE_INT pos = 0, len;
05724 int unsignedp = 0;
05725 unsigned int modewidth;
05726 rtx tem;
05727
05728 switch (GET_CODE (x))
05729 {
05730 case ZERO_EXTEND:
05731 unsignedp = 1;
05732 case SIGN_EXTEND:
05733
05734
05735
05736
05737
05738
05739
05740
05741 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
05742 return x;
05743
05744
05745
05746
05747
05748
05749
05750
05751
05752
05753 if (GET_MODE_SIZE (GET_MODE (XEXP (x, 0))) > UNITS_PER_WORD)
05754 return x;
05755
05756
05757
05758
05759 if (! SCALAR_INT_MODE_P (GET_MODE (XEXP (x, 0))))
05760 return x;
05761
05762 len = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)));
05763
05764
05765
05766 if (len == 0)
05767 return x;
05768
05769 break;
05770
05771 case ZERO_EXTRACT:
05772 unsignedp = 1;
05773 case SIGN_EXTRACT:
05774
05775 if (GET_CODE (XEXP (x, 0)) == CLOBBER)
05776 return XEXP (x, 0);
05777
05778 if (GET_CODE (XEXP (x, 1)) != CONST_INT
05779 || GET_CODE (XEXP (x, 2)) != CONST_INT
05780 || GET_MODE (XEXP (x, 0)) == VOIDmode)
05781 return x;
05782
05783
05784
05785
05786 if (! SCALAR_INT_MODE_P (GET_MODE (XEXP (x, 0))))
05787 return x;
05788
05789 len = INTVAL (XEXP (x, 1));
05790 pos = INTVAL (XEXP (x, 2));
05791
05792
05793
05794
05795 if (len + pos > GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))))
05796 SUBST (XEXP (x, 0), gen_rtx_USE (GET_MODE (x), XEXP (x, 0)));
05797
05798 if (BITS_BIG_ENDIAN)
05799 pos = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - len - pos;
05800
05801 break;
05802
05803 default:
05804 return x;
05805 }
05806
05807
05808
05809 if (GET_CODE (x) == SIGN_EXTEND
05810 && (GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
05811 && ((nonzero_bits (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
05812 & ~(((unsigned HOST_WIDE_INT)
05813 GET_MODE_MASK (GET_MODE (XEXP (x, 0))))
05814 >> 1))
05815 == 0)))
05816 {
05817 rtx temp = gen_rtx_ZERO_EXTEND (GET_MODE (x), XEXP (x, 0));
05818 return expand_compound_operation (temp);
05819 }
05820
05821
05822 if (GET_CODE (x) == ZERO_EXTEND)
05823 {
05824
05825
05826
05827 if (GET_CODE (XEXP (x, 0)) == TRUNCATE
05828 && GET_MODE (XEXP (XEXP (x, 0), 0)) == GET_MODE (x)
05829 && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
05830 && (nonzero_bits (XEXP (XEXP (x, 0), 0), GET_MODE (x))
05831 & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
05832 return XEXP (XEXP (x, 0), 0);
05833
05834
05835 if (GET_CODE (XEXP (x, 0)) == SUBREG
05836 && GET_MODE (SUBREG_REG (XEXP (x, 0))) == GET_MODE (x)
05837 && subreg_lowpart_p (XEXP (x, 0))
05838 && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
05839 && (nonzero_bits (SUBREG_REG (XEXP (x, 0)), GET_MODE (x))
05840 & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
05841 return SUBREG_REG (XEXP (x, 0));
05842
05843
05844
05845
05846
05847 if (GET_CODE (XEXP (x, 0)) == TRUNCATE
05848 && GET_MODE (XEXP (XEXP (x, 0), 0)) == GET_MODE (x)
05849 && GET_RTX_CLASS (GET_CODE (XEXP (XEXP (x, 0), 0))) == '<'
05850 && (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
05851 <= HOST_BITS_PER_WIDE_INT)
05852 && ((HOST_WIDE_INT) STORE_FLAG_VALUE
05853 & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
05854 return XEXP (XEXP (x, 0), 0);
05855
05856
05857 if (GET_CODE (XEXP (x, 0)) == SUBREG
05858 && GET_MODE (SUBREG_REG (XEXP (x, 0))) == GET_MODE (x)
05859 && subreg_lowpart_p (XEXP (x, 0))
05860 && GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0)))) == '<'
05861 && (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
05862 <= HOST_BITS_PER_WIDE_INT)
05863 && ((HOST_WIDE_INT) STORE_FLAG_VALUE
05864 & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
05865 return SUBREG_REG (XEXP (x, 0));
05866
05867 }
05868
05869
05870
05871
05872
05873
05874
05875
05876
05877
05878
05879
05880
05881
05882
05883
05884 modewidth = GET_MODE_BITSIZE (GET_MODE (x));
05885 if (modewidth + len >= pos)
05886 tem = simplify_shift_const (NULL_RTX, unsignedp ? LSHIFTRT : ASHIFTRT,
05887 GET_MODE (x),
05888 simplify_shift_const (NULL_RTX, ASHIFT,
05889 GET_MODE (x),
05890 XEXP (x, 0),
05891 modewidth - pos - len),
05892 modewidth - len);
05893
05894 else if (unsignedp && len < HOST_BITS_PER_WIDE_INT)
05895 tem = simplify_and_const_int (NULL_RTX, GET_MODE (x),
05896 simplify_shift_const (NULL_RTX, LSHIFTRT,
05897 GET_MODE (x),
05898 XEXP (x, 0), pos),
05899 ((HOST_WIDE_INT) 1 << len) - 1);
05900 else
05901
05902 return x;
05903
05904
05905
05906 if (GET_CODE (tem) == CLOBBER)
05907 return x;
05908
05909 return tem;
05910 }
05911
05912
05913
05914
05915
05916
05917
05918
05919
05920 static rtx
05921 expand_field_assignment (x)
05922 rtx x;
05923 {
05924 rtx inner;
05925 rtx pos;
05926 int len;
05927 rtx mask;
05928 enum machine_mode compute_mode;
05929
05930
05931 while (1)
05932 {
05933 if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART
05934 && GET_CODE (XEXP (SET_DEST (x), 0)) == SUBREG)
05935 {
05936 inner = SUBREG_REG (XEXP (SET_DEST (x), 0));
05937 len = GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0)));
05938 pos = GEN_INT (subreg_lsb (XEXP (SET_DEST (x), 0)));
05939 }
05940 else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
05941 && GET_CODE (XEXP (SET_DEST (x), 1)) == CONST_INT)
05942 {
05943 inner = XEXP (SET_DEST (x), 0);
05944 len = INTVAL (XEXP (SET_DEST (x), 1));
05945 pos = XEXP (SET_DEST (x), 2);
05946
05947
05948
05949 if (GET_CODE (pos) == CONST_INT
05950 && INTVAL (pos) + len > GET_MODE_BITSIZE (GET_MODE (inner)))
05951 inner = gen_rtx_USE (GET_MODE (SET_DEST (x)), inner);
05952
05953 if (BITS_BIG_ENDIAN)
05954 {
05955 if (GET_CODE (pos) == CONST_INT)
05956 pos = GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner)) - len
05957 - INTVAL (pos));
05958 else if (GET_CODE (pos) == MINUS
05959 && GET_CODE (XEXP (pos, 1)) == CONST_INT
05960 && (INTVAL (XEXP (pos, 1))
05961 == GET_MODE_BITSIZE (GET_MODE (inner)) - len))
05962
05963 pos = XEXP (pos, 0);
05964 else
05965 pos = gen_binary (MINUS, GET_MODE (pos),
05966 GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner))
05967 - len),
05968 pos);
05969 }
05970 }
05971
05972
05973
05974 else if (GET_CODE (SET_DEST (x)) == SUBREG
05975
05976 && nonzero_sign_valid
05977 && (((GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
05978 + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
05979 == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x))))
05980 + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
05981 {
05982 x = gen_rtx_SET (VOIDmode, SUBREG_REG (SET_DEST (x)),
05983 gen_lowpart_for_combine
05984 (GET_MODE (SUBREG_REG (SET_DEST (x))),
05985 SET_SRC (x)));
05986 continue;
05987 }
05988 else
05989 break;
05990
05991 while (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner))
05992 inner = SUBREG_REG (inner);
05993
05994 compute_mode = GET_MODE (inner);
05995
05996
05997 if (! SCALAR_INT_MODE_P (compute_mode))
05998 {
05999 enum machine_mode imode;
06000
06001
06002 if (! FLOAT_MODE_P (compute_mode))
06003 break;
06004
06005
06006 imode = mode_for_size (GET_MODE_BITSIZE (compute_mode), MODE_INT, 0);
06007 if (imode == BLKmode)
06008 break;
06009
06010 compute_mode = imode;
06011 inner = gen_lowpart_for_combine (imode, inner);
06012 }
06013
06014
06015 if (len < HOST_BITS_PER_WIDE_INT)
06016 mask = GEN_INT (((HOST_WIDE_INT) 1 << len) - 1);
06017 else
06018 break;
06019
06020
06021
06022
06023 x = gen_rtx_SET
06024 (VOIDmode, copy_rtx (inner),
06025 gen_binary (IOR, compute_mode,
06026 gen_binary (AND, compute_mode,
06027 simplify_gen_unary (NOT, compute_mode,
06028 gen_binary (ASHIFT,
06029 compute_mode,
06030 mask, pos),
06031 compute_mode),
06032 inner),
06033 gen_binary (ASHIFT, compute_mode,
06034 gen_binary (AND, compute_mode,
06035 gen_lowpart_for_combine
06036 (compute_mode, SET_SRC (x)),
06037 mask),
06038 pos)));
06039 }
06040
06041 return x;
06042 }
06043
06044
06045
06046
06047
06048
06049
06050
06051
06052
06053
06054
06055
06056
06057
06058
06059
06060
06061
06062
06063
06064
06065
06066
06067
06068
06069
06070
06071 static rtx
06072 make_extraction (mode, inner, pos, pos_rtx, len,
06073 unsignedp, in_dest, in_compare)
06074 enum machine_mode mode;
06075 rtx inner;
06076 HOST_WIDE_INT pos;
06077 rtx pos_rtx;
06078 unsigned HOST_WIDE_INT len;
06079 int unsignedp;
06080 int in_dest, in_compare;
06081 {
06082
06083
06084
06085 enum machine_mode is_mode = GET_MODE (inner);
06086 enum machine_mode inner_mode;
06087 enum machine_mode wanted_inner_mode = byte_mode;
06088 enum machine_mode wanted_inner_reg_mode = word_mode;
06089 enum machine_mode pos_mode = word_mode;
06090 enum machine_mode extraction_mode = word_mode;
06091 enum machine_mode tmode = mode_for_size (len, MODE_INT, 1);
06092 int spans_byte = 0;
06093 rtx new = 0;
06094 rtx orig_pos_rtx = pos_rtx;
06095 HOST_WIDE_INT orig_pos;
06096
06097
06098 if (GET_CODE (inner) == USE)
06099
06100
06101
06102 spans_byte = 1, inner = XEXP (inner, 0);
06103 else if (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner))
06104 {
06105
06106
06107
06108
06109
06110 if (GET_CODE (SUBREG_REG (inner)) == MEM)
06111 is_mode = GET_MODE (SUBREG_REG (inner));
06112 inner = SUBREG_REG (inner);
06113 }
06114 else if (GET_CODE (inner) == ASHIFT
06115 && GET_CODE (XEXP (inner, 1)) == CONST_INT
06116 && pos_rtx == 0 && pos == 0
06117 && len > (unsigned HOST_WIDE_INT) INTVAL (XEXP (inner, 1)))
06118 {
06119
06120
06121
06122
06123 new = make_extraction (mode, XEXP (inner, 0),
06124 0, 0, len - INTVAL (XEXP (inner, 1)),
06125 unsignedp, in_dest, in_compare);
06126 if (new != 0)
06127 return gen_rtx_ASHIFT (mode, new, XEXP (inner, 1));
06128 }
06129
06130 inner_mode = GET_MODE (inner);
06131
06132 if (pos_rtx && GET_CODE (pos_rtx) == CONST_INT)
06133 pos = INTVAL (pos_rtx), pos_rtx = 0;
06134
06135
06136
06137
06138
06139
06140
06141
06142
06143
06144
06145
06146
06147
06148 if (tmode != BLKmode
06149 && ! (spans_byte && inner_mode != tmode)
06150 && ((pos_rtx == 0 && (pos % BITS_PER_WORD) == 0
06151 && GET_CODE (inner) != MEM
06152 && (! in_dest
06153 || (GET_CODE (inner) == REG
06154 && have_insn_for (STRICT_LOW_PART, tmode))))
06155 || (GET_CODE (inner) == MEM && pos_rtx == 0
06156 && (pos
06157 % (STRICT_ALIGNMENT ? GET_MODE_ALIGNMENT (tmode)
06158 : BITS_PER_UNIT)) == 0
06159
06160
06161 && GET_MODE_BITSIZE (inner_mode) >= GET_MODE_BITSIZE (tmode)
06162 && (inner_mode == tmode
06163 || (! mode_dependent_address_p (XEXP (inner, 0))
06164 && ! MEM_VOLATILE_P (inner))))))
06165 {
06166
06167
06168
06169
06170
06171
06172
06173 if (GET_CODE (inner) == MEM)
06174 {
06175 HOST_WIDE_INT offset;
06176
06177
06178 if (BYTES_BIG_ENDIAN)
06179 offset = (GET_MODE_BITSIZE (is_mode) - len - pos) / BITS_PER_UNIT;
06180 else
06181 offset = pos / BITS_PER_UNIT;
06182
06183 new = adjust_address_nv (inner, tmode, offset);
06184 }
06185 else if (GET_CODE (inner) == REG)
06186 {
06187
06188
06189 if (tmode != inner_mode)
06190 {
06191 HOST_WIDE_INT final_word = pos / BITS_PER_WORD;
06192
06193 if (WORDS_BIG_ENDIAN
06194 && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD)
06195 final_word = ((GET_MODE_SIZE (inner_mode)
06196 - GET_MODE_SIZE (tmode))
06197 / UNITS_PER_WORD) - final_word;
06198
06199 final_word *= UNITS_PER_WORD;
06200 if (BYTES_BIG_ENDIAN &&
06201 GET_MODE_SIZE (inner_mode) > GET_MODE_SIZE (tmode))
06202 final_word += (GET_MODE_SIZE (inner_mode)
06203 - GET_MODE_SIZE (tmode)) % UNITS_PER_WORD;
06204
06205
06206
06207 if (final_word >= GET_MODE_SIZE (inner_mode))
06208 return NULL_RTX;
06209
06210 new = gen_rtx_SUBREG (tmode, inner, final_word);
06211 }
06212 else
06213 new = inner;
06214 }
06215 else
06216 new = force_to_mode (inner, tmode,
06217 len >= HOST_BITS_PER_WIDE_INT
06218 ? ~(unsigned HOST_WIDE_INT) 0
06219 : ((unsigned HOST_WIDE_INT) 1 << len) - 1,
06220 NULL_RTX, 0);
06221
06222
06223
06224
06225 if (in_dest)
06226 return (GET_CODE (new) == MEM ? new
06227 : (GET_CODE (new) != SUBREG
06228 ? gen_rtx_CLOBBER (tmode, const0_rtx)
06229 : gen_rtx_STRICT_LOW_PART (VOIDmode, new)));
06230
06231 if (mode == tmode)
06232 return new;
06233
06234 if (GET_CODE (new) == CONST_INT)
06235 return gen_int_mode (INTVAL (new), mode);
06236
06237
06238
06239
06240 if (flag_expensive_optimizations
06241 && (GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT
06242 && ((nonzero_bits (new, tmode)
06243 & ~(((unsigned HOST_WIDE_INT)
06244 GET_MODE_MASK (tmode))
06245 >> 1))
06246 == 0)))
06247 {
06248 rtx temp = gen_rtx_ZERO_EXTEND (mode, new);
06249 rtx temp1 = gen_rtx_SIGN_EXTEND (mode, new);
06250
06251
06252
06253 if (rtx_cost (temp, SET) <= rtx_cost (temp1, SET))
06254 return temp;
06255 return temp1;
06256 }
06257
06258
06259
06260
06261 return (gen_rtx_fmt_e (unsignedp ? ZERO_EXTEND : SIGN_EXTEND,
06262 mode, new));
06263 }
06264
06265
06266
06267
06268 if (pos_rtx == 0 && pos == 0 && ! in_dest
06269 && ! in_compare && ! spans_byte && unsignedp)
06270 return 0;
06271
06272
06273
06274
06275
06276
06277 if (! spans_byte && GET_CODE (inner) == MEM
06278 && ((pos_rtx == 0 && pos + len > GET_MODE_BITSIZE (is_mode))
06279 || (pos_rtx != 0 && len != 1)))
06280 return 0;
06281
06282
06283
06284 if (in_dest && mode_for_extraction (EP_insv, -1) != MAX_MACHINE_MODE)
06285 {
06286 wanted_inner_reg_mode = mode_for_extraction (EP_insv, 0);
06287 pos_mode = mode_for_extraction (EP_insv, 2);
06288 extraction_mode = mode_for_extraction (EP_insv, 3);
06289 }
06290
06291 if (! in_dest && unsignedp
06292 && mode_for_extraction (EP_extzv, -1) != MAX_MACHINE_MODE)
06293 {
06294 wanted_inner_reg_mode = mode_for_extraction (EP_extzv, 1);
06295 pos_mode = mode_for_extraction (EP_extzv, 3);
06296 extraction_mode = mode_for_extraction (EP_extzv, 0);
06297 }
06298
06299 if (! in_dest && ! unsignedp
06300 && mode_for_extraction (EP_extv, -1) != MAX_MACHINE_MODE)
06301 {
06302 wanted_inner_reg_mode = mode_for_extraction (EP_extv, 1);
06303 pos_mode = mode_for_extraction (EP_extv, 3);
06304 extraction_mode = mode_for_extraction (EP_extv, 0);
06305 }
06306
06307
06308
06309 if (mode != VOIDmode
06310 && GET_MODE_SIZE (extraction_mode) < GET_MODE_SIZE (mode))
06311 extraction_mode = mode;
06312
06313 if (pos_rtx && GET_MODE (pos_rtx) != VOIDmode
06314 && GET_MODE_SIZE (pos_mode) < GET_MODE_SIZE (GET_MODE (pos_rtx)))
06315 pos_mode = GET_MODE (pos_rtx);
06316
06317
06318
06319
06320 if (GET_CODE (inner) != MEM)
06321 wanted_inner_mode = wanted_inner_reg_mode;
06322 else if (inner_mode != wanted_inner_mode
06323 && (mode_dependent_address_p (XEXP (inner, 0))
06324 || MEM_VOLATILE_P (inner)))
06325 wanted_inner_mode = extraction_mode;
06326
06327 orig_pos = pos;
06328
06329 if (BITS_BIG_ENDIAN)
06330 {
06331
06332
06333
06334
06335
06336
06337
06338 int width = (GET_CODE (inner) == MEM
06339 ? GET_MODE_BITSIZE (is_mode)
06340 : GET_MODE_BITSIZE (wanted_inner_mode));
06341
06342 if (pos_rtx == 0)
06343 pos = width - len - pos;
06344 else
06345 pos_rtx
06346 = gen_rtx_MINUS (GET_MODE (pos_rtx), GEN_INT (width - len), pos_rtx);
06347
06348
06349 }
06350
06351
06352
06353
06354 if (wanted_inner_mode != VOIDmode
06355 && GET_MODE_SIZE (wanted_inner_mode) < GET_MODE_SIZE (is_mode)
06356 && ((GET_CODE (inner) == MEM
06357 && (inner_mode == wanted_inner_mode
06358 || (! mode_dependent_address_p (XEXP (inner, 0))
06359 && ! MEM_VOLATILE_P (inner))))))
06360 {
06361 int offset = 0;
06362
06363
06364
06365
06366
06367
06368
06369 if (BYTES_BIG_ENDIAN
06370 && ! spans_byte
06371 && GET_MODE_SIZE (inner_mode) < GET_MODE_SIZE (is_mode))
06372 offset -= GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (inner_mode);
06373
06374
06375 if (pos_rtx == 0)
06376 {
06377 offset += pos / BITS_PER_UNIT;
06378 pos %= GET_MODE_BITSIZE (wanted_inner_mode);
06379 }
06380
06381 if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN
06382 && ! spans_byte
06383 && is_mode != wanted_inner_mode)
06384 offset = (GET_MODE_SIZE (is_mode)
06385 - GET_MODE_SIZE (wanted_inner_mode) - offset);
06386
06387 if (offset != 0 || inner_mode != wanted_inner_mode)
06388 inner = adjust_address_nv (inner, wanted_inner_mode, offset);
06389 }
06390
06391
06392
06393
06394 else if (GET_CODE (inner) != MEM)
06395 {
06396 if (GET_MODE (inner) != wanted_inner_mode
06397 && (pos_rtx != 0
06398 || orig_pos + len > GET_MODE_BITSIZE (wanted_inner_mode)))
06399 return 0;
06400
06401 inner = force_to_mode (inner, wanted_inner_mode,
06402 pos_rtx
06403 || len + orig_pos >= HOST_BITS_PER_WIDE_INT
06404 ? ~(unsigned HOST_WIDE_INT) 0
06405 : ((((unsigned HOST_WIDE_INT) 1 << len) - 1)
06406 << orig_pos),
06407 NULL_RTX, 0);
06408 }
06409
06410
06411
06412 if (pos_rtx != 0
06413 && GET_MODE_SIZE (pos_mode) > GET_MODE_SIZE (GET_MODE (pos_rtx)))
06414 {
06415 rtx temp = gen_rtx_ZERO_EXTEND (pos_mode, pos_rtx);
06416
06417
06418
06419
06420
06421 if (flag_expensive_optimizations
06422 && (GET_MODE_BITSIZE (GET_MODE (pos_rtx)) <= HOST_BITS_PER_WIDE_INT
06423 && ((nonzero_bits (pos_rtx, GET_MODE (pos_rtx))
06424 & ~(((unsigned HOST_WIDE_INT)
06425 GET_MODE_MASK (GET_MODE (pos_rtx)))
06426 >> 1))
06427 == 0)))
06428 {
06429 rtx temp1 = gen_rtx_SIGN_EXTEND (pos_mode, pos_rtx);
06430
06431
06432
06433 if (rtx_cost (temp1, SET) < rtx_cost (temp, SET))
06434 temp = temp1;
06435 }
06436 pos_rtx = temp;
06437 }
06438 else if (pos_rtx != 0
06439 && GET_MODE_SIZE (pos_mode) < GET_MODE_SIZE (GET_MODE (pos_rtx)))
06440 pos_rtx = gen_lowpart_for_combine (pos_mode, pos_rtx);
06441
06442
06443
06444
06445 if (pos_rtx == 0 && orig_pos_rtx != 0 && INTVAL (orig_pos_rtx) == pos)
06446 pos_rtx = orig_pos_rtx;
06447
06448 else if (pos_rtx == 0)
06449 pos_rtx = GEN_INT (pos);
06450
06451
06452 new = gen_rtx_fmt_eee (unsignedp ? ZERO_EXTRACT : SIGN_EXTRACT,
06453 extraction_mode, inner, GEN_INT (len), pos_rtx);
06454 if (! in_dest)
06455 new = gen_lowpart_for_combine (mode, new);
06456
06457 return new;
06458 }
06459
06460
06461
06462
06463 static rtx
06464 extract_left_shift (x, count)
06465 rtx x;
06466 int count;
06467 {
06468 enum rtx_code code = GET_CODE (x);
06469 enum machine_mode mode = GET_MODE (x);
06470 rtx tem;
06471
06472 switch (code)
06473 {
06474 case ASHIFT:
06475
06476
06477
06478 if (GET_CODE (XEXP (x, 1)) == CONST_INT
06479 && INTVAL (XEXP (x, 1)) >= count)
06480 return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (x, 0),
06481 INTVAL (XEXP (x, 1)) - count);
06482 break;
06483
06484 case NEG: case NOT:
06485 if ((tem = extract_left_shift (XEXP (x, 0), count)) != 0)
06486 return simplify_gen_unary (code, mode, tem, mode);
06487
06488 break;
06489
06490 case PLUS: case IOR: case XOR: case AND:
06491
06492
06493 if (GET_CODE (XEXP (x,1)) == CONST_INT
06494 && (INTVAL (XEXP (x, 1)) & ((((HOST_WIDE_INT) 1 << count)) - 1)) == 0
06495 && (tem = extract_left_shift (XEXP (x, 0), count)) != 0)
06496 return gen_binary (code, mode, tem,
06497 GEN_INT (INTVAL (XEXP (x, 1)) >> count));
06498
06499 break;
06500
06501 default:
06502 break;
06503 }
06504
06505 return 0;
06506 }
06507
06508
06509
06510
06511
06512
06513
06514
06515
06516
06517
06518
06519
06520
06521
06522
06523
06524
06525
06526 static rtx
06527 make_compound_operation (x, in_code)
06528 rtx x;
06529 enum rtx_code in_code;
06530 {
06531 enum rtx_code code = GET_CODE (x);
06532 enum machine_mode mode = GET_MODE (x);
06533 int mode_width = GET_MODE_BITSIZE (mode);
06534 rtx rhs, lhs;
06535 enum rtx_code next_code;
06536 int i;
06537 rtx new = 0;
06538 rtx tem;
06539 const char *fmt;
06540
06541
06542
06543
06544
06545 next_code = (code == MEM || code == PLUS || code == MINUS ? MEM
06546 : ((code == COMPARE || GET_RTX_CLASS (code) == '<')
06547 && XEXP (x, 1) == const0_rtx) ? COMPARE
06548 : in_code == COMPARE ? SET : in_code);
06549
06550
06551
06552
06553 switch (code)
06554 {
06555 case ASHIFT:
06556
06557
06558 if (in_code == MEM && GET_CODE (XEXP (x, 1)) == CONST_INT
06559 && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
06560 && INTVAL (XEXP (x, 1)) >= 0)
06561 {
06562 new = make_compound_operation (XEXP (x, 0), next_code);
06563 new = gen_rtx_MULT (mode, new,
06564 GEN_INT ((HOST_WIDE_INT) 1
06565 << INTVAL (XEXP (x, 1))));
06566 }
06567 break;
06568
06569 case AND:
06570
06571
06572 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
06573 break;
06574
06575
06576
06577 if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
06578 && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
06579 {
06580 new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
06581 new = make_extraction (mode, new, 0, XEXP (XEXP (x, 0), 1), i, 1,
06582 0, in_code == COMPARE);
06583 }
06584
06585
06586 else if (GET_CODE (XEXP (x, 0)) == SUBREG
06587 && subreg_lowpart_p (XEXP (x, 0))
06588 && GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT
06589 && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
06590 {
06591 new = make_compound_operation (XEXP (SUBREG_REG (XEXP (x, 0)), 0),
06592 next_code);
06593 new = make_extraction (GET_MODE (SUBREG_REG (XEXP (x, 0))), new, 0,
06594 XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1,
06595 0, in_code == COMPARE);
06596 }
06597
06598 else if ((GET_CODE (XEXP (x, 0)) == XOR
06599 || GET_CODE (XEXP (x, 0)) == IOR)
06600 && GET_CODE (XEXP (XEXP (x, 0), 0)) == LSHIFTRT
06601 && GET_CODE (XEXP (XEXP (x, 0), 1)) == LSHIFTRT
06602 && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
06603 {
06604
06605 new = gen_rtx_fmt_ee (GET_CODE (XEXP (x, 0)), mode,
06606 gen_rtx_AND (mode, XEXP (XEXP (x, 0), 0),
06607 XEXP (x, 1)),
06608 gen_rtx_AND (mode, XEXP (XEXP (x, 0), 1),
06609 XEXP (x, 1)));
06610 new = make_compound_operation (new, in_code);
06611 }
06612
06613
06614
06615
06616 else if (GET_CODE (XEXP (x, 0)) == ROTATE
06617 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
06618 && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0
06619 && i <= INTVAL (XEXP (XEXP (x, 0), 1)))
06620 {
06621 new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
06622 new = make_extraction (mode, new,
06623 (GET_MODE_BITSIZE (mode)
06624 - INTVAL (XEXP (XEXP (x, 0), 1))),
06625 NULL_RTX, i, 1, 0, in_code == COMPARE);
06626 }
06627
06628
06629
06630
06631 else if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
06632 && !have_insn_for (LSHIFTRT, mode)
06633 && have_insn_for (ASHIFTRT, mode)
06634 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
06635 && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
06636 && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT
06637 && mode_width <= HOST_BITS_PER_WIDE_INT)
06638 {
06639 unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
06640
06641 mask >>= INTVAL (XEXP (XEXP (x, 0), 1));
06642 if ((INTVAL (XEXP (x, 1)) & ~mask) == 0)
06643 SUBST (XEXP (x, 0),
06644 gen_rtx_ASHIFTRT (mode,
06645 make_compound_operation
06646 (XEXP (XEXP (x, 0), 0), next_code),
06647 XEXP (XEXP (x, 0), 1)));
06648 }
06649
06650
06651
06652
06653
06654 else if ((i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
06655 new = make_extraction (mode,
06656 make_compound_operation (XEXP (x, 0),
06657 next_code),
06658 0, NULL_RTX, i, 1, 0, in_code == COMPARE);
06659
06660
06661
06662 else if (in_code == COMPARE
06663 && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0)
06664 new = make_extraction (mode,
06665 make_compound_operation (XEXP (x, 0),
06666 next_code),
06667 i, NULL_RTX, 1, 1, 0, 1);
06668
06669 break;
06670
06671 case LSHIFTRT:
06672
06673
06674 if (have_insn_for (ASHIFTRT, mode)
06675 && ! have_insn_for (LSHIFTRT, mode)
06676 && mode_width <= HOST_BITS_PER_WIDE_INT
06677 && (nonzero_bits (XEXP (x, 0), mode) & (1 << (mode_width - 1))) == 0)
06678 {
06679 new = gen_rtx_ASHIFTRT (mode,
06680 make_compound_operation (XEXP (x, 0),
06681 next_code),
06682 XEXP (x, 1));
06683 break;
06684 }
06685
06686
06687
06688 case ASHIFTRT:
06689 lhs = XEXP (x, 0);
06690 rhs = XEXP (x, 1);
06691
06692
06693
06694 if (GET_CODE (rhs) == CONST_INT
06695 && GET_CODE (lhs) == ASHIFT
06696 && GET_CODE (XEXP (lhs, 1)) == CONST_INT
06697 && INTVAL (rhs) >= INTVAL (XEXP (lhs, 1)))
06698 {
06699 new = make_compound_operation (XEXP (lhs, 0), next_code);
06700 new = make_extraction (mode, new,
06701 INTVAL (rhs) - INTVAL (XEXP (lhs, 1)),
06702 NULL_RTX, mode_width - INTVAL (rhs),
06703 code == LSHIFTRT, 0, in_code == COMPARE);
06704 break;
06705 }
06706
06707
06708
06709
06710
06711
06712 if (GET_RTX_CLASS (GET_CODE (lhs)) != 'o'
06713 && ! (GET_CODE (lhs) == SUBREG
06714 && (GET_RTX_CLASS (GET_CODE (SUBREG_REG (lhs))) == 'o'))
06715 && GET_CODE (rhs) == CONST_INT
06716 && INTVAL (rhs) < HOST_BITS_PER_WIDE_INT
06717 && (new = extract_left_shift (lhs, INTVAL (rhs))) != 0)
06718 new = make_extraction (mode, make_compound_operation (new, next_code),
06719 0, NULL_RTX, mode_width - INTVAL (rhs),
06720 code == LSHIFTRT, 0, in_code == COMPARE);
06721
06722 break;
06723
06724 case SUBREG:
06725
06726
06727
06728
06729 tem = make_compound_operation (SUBREG_REG (x), in_code);
06730 if (GET_CODE (tem) != GET_CODE (SUBREG_REG (x))
06731 && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (tem))
06732 && subreg_lowpart_p (x))
06733 {
06734 rtx newer = force_to_mode (tem, mode, ~(HOST_WIDE_INT) 0,
06735 NULL_RTX, 0);
06736
06737
06738
06739 if (GET_CODE (newer) != SUBREG)
06740 newer = make_compound_operation (newer, in_code);
06741
06742 return newer;
06743 }
06744
06745
06746
06747
06748
06749 if ((GET_CODE (tem) == SIGN_EXTEND
06750 || GET_CODE (tem) == ZERO_EXTEND)
06751 && subreg_lowpart_p (x))
06752 {
06753 if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (tem))
06754 || (GET_MODE_SIZE (mode) >
06755 GET_MODE_SIZE (GET_MODE (XEXP (tem, 0)))))
06756 {
06757 if (! SCALAR_INT_MODE_P (mode))
06758 break;
06759 tem = gen_rtx_fmt_e (GET_CODE (tem), mode, XEXP (tem, 0));
06760 }
06761 else
06762 tem = gen_lowpart_for_combine (mode, XEXP (tem, 0));
06763 return tem;
06764 }
06765 break;
06766
06767 default:
06768 break;
06769 }
06770
06771 if (new)
06772 {
06773 x = gen_lowpart_for_combine (mode, new);
06774 code = GET_CODE (x);
06775 }
06776
06777
06778 fmt = GET_RTX_FORMAT (code);
06779 for (i = 0; i < GET_RTX_LENGTH (code); i++)
06780 if (fmt[i] == 'e')
06781 {
06782 new = make_compound_operation (XEXP (x, i), next_code);
06783 SUBST (XEXP (x, i), new);
06784 }
06785
06786 return x;
06787 }
06788
06789
06790
06791
06792
06793
06794
06795
06796 static int
06797 get_pos_from_mask (m, plen)
06798 unsigned HOST_WIDE_INT m;
06799 unsigned HOST_WIDE_INT *plen;
06800 {
06801
06802 int pos = exact_log2 (m & -m);
06803 int len;
06804
06805 if (pos < 0)
06806 return -1;
06807
06808
06809
06810 len = exact_log2 ((m >> pos) + 1);
06811
06812 if (len <= 0)
06813 return -1;
06814
06815 *plen = len;
06816 return pos;
06817 }
06818
06819
06820
06821
06822
06823
06824
06825
06826
06827
06828
06829
06830
06831
06832
06833
06834
06835 static rtx
06836 force_to_mode (x, mode, mask, reg, just_select)
06837 rtx x;
06838 enum machine_mode mode;
06839 unsigned HOST_WIDE_INT mask;
06840 rtx reg;
06841 int just_select;
06842 {
06843 enum rtx_code code = GET_CODE (x);
06844 int next_select = just_select || code == XOR || code == NOT || code == NEG;
06845 enum machine_mode op_mode;
06846 unsigned HOST_WIDE_INT fuller_mask, nonzero;
06847 rtx op0, op1, temp;
06848
06849
06850
06851
06852
06853
06854
06855 if (code == CALL || code == ASM_OPERANDS || code == CLOBBER)
06856 return x;
06857
06858
06859
06860
06861 op_mode = ((GET_MODE_CLASS (mode) == GET_MODE_CLASS (GET_MODE (x))
06862 && have_insn_for (code, mode))
06863 ? mode : GET_MODE (x));
06864
06865
06866
06867 if ((code == LSHIFTRT || code == ASHIFTRT)
06868 && GET_MODE_BITSIZE (mode) < GET_MODE_BITSIZE (GET_MODE (x)))
06869 op_mode = GET_MODE (x);
06870
06871
06872 if (op_mode)
06873 mask &= GET_MODE_MASK (op_mode);
06874
06875
06876
06877
06878 if (op_mode)
06879 fuller_mask = (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT
06880 ? GET_MODE_MASK (op_mode)
06881 : (((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1))
06882 - 1));
06883 else
06884 fuller_mask = ~(HOST_WIDE_INT) 0;
06885
06886
06887 nonzero = nonzero_bits (x, mode);
06888
06889
06890 if (! just_select && (nonzero & mask) == 0)
06891 x = const0_rtx;
06892
06893
06894
06895 if (GET_CODE (x) == CONST_INT)
06896 {
06897 if (SCALAR_INT_MODE_P (mode))
06898 return gen_int_mode (INTVAL (x) & mask, mode);
06899 else
06900 {
06901 x = GEN_INT (INTVAL (x) & mask);
06902 return gen_lowpart_common (mode, x);
06903 }
06904 }
06905
06906
06907
06908 if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode)
06909 && (GET_MODE_MASK (GET_MODE (x)) & ~mask) == 0)
06910 return gen_lowpart_for_combine (mode, x);
06911
06912
06913
06914 if (GET_MODE (x) == mode && code != SUBREG && (~mask & nonzero) == 0)
06915 return x;
06916
06917 switch (code)
06918 {
06919 case CLOBBER:
06920
06921
06922 return x;
06923
06924 case USE:
06925
06926
06927
06928 if (! BITS_BIG_ENDIAN
06929 && (mask & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
06930 return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select);
06931 break;
06932
06933 case SIGN_EXTEND:
06934 case ZERO_EXTEND:
06935 case ZERO_EXTRACT:
06936 case SIGN_EXTRACT:
06937 x = expand_compound_operation (x);
06938 if (GET_CODE (x) != code)
06939 return force_to_mode (x, mode, mask, reg, next_select);
06940 break;
06941
06942 case REG:
06943 if (reg != 0 && (rtx_equal_p (get_last_value (reg), x)
06944 || rtx_equal_p (reg, get_last_value (x))))
06945 x = reg;
06946 break;
06947
06948 case SUBREG:
06949 if (subreg_lowpart_p (x)
06950
06951
06952
06953 && ((GET_MODE_SIZE (GET_MODE (x))
06954 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
06955 || (0 == (mask
06956 & GET_MODE_MASK (GET_MODE (x))
06957 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))))))
06958 return force_to_mode (SUBREG_REG (x), mode, mask, reg, next_select);
06959 break;
06960
06961 case AND:
06962
06963
06964
06965
06966 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
06967 {
06968 x = simplify_and_const_int (x, op_mode, XEXP (x, 0),
06969 mask & INTVAL (XEXP (x, 1)));
06970
06971
06972
06973
06974
06975 if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT
06976 && ((INTVAL (XEXP (x, 1)) & GET_MODE_MASK (GET_MODE (x)))
06977 == mask))
06978 x = XEXP (x, 0);
06979
06980
06981
06982
06983
06984
06985 if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT
06986 && GET_MODE_MASK (GET_MODE (x)) != mask
06987 && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
06988 {
06989 HOST_WIDE_INT cval = (INTVAL (XEXP (x, 1))
06990 | (GET_MODE_MASK (GET_MODE (x)) & ~mask));
06991 int width = GET_MODE_BITSIZE (GET_MODE (x));
06992 rtx y;
06993
06994
06995
06996 if (width > 0 && width < HOST_BITS_PER_WIDE_INT
06997 && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
06998 cval |= (HOST_WIDE_INT) -1 << width;
06999
07000 y = gen_binary (AND, GET_MODE (x), XEXP (x, 0), GEN_INT (cval));
07001 if (rtx_cost (y, SET) < rtx_cost (x, SET))
07002 x = y;
07003 }
07004
07005 break;
07006 }
07007
07008 goto binop;
07009
07010 case PLUS:
07011
07012
07013
07014
07015
07016 {
07017 unsigned int width = GET_MODE_BITSIZE (mode);
07018 unsigned HOST_WIDE_INT smask = mask;
07019
07020
07021
07022
07023 if (width < HOST_BITS_PER_WIDE_INT
07024 && (smask & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
07025 smask |= (HOST_WIDE_INT) -1 << width;
07026
07027 if (GET_CODE (XEXP (x, 1)) == CONST_INT
07028 && exact_log2 (- smask) >= 0
07029 && (nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0
07030 && (INTVAL (XEXP (x, 1)) & ~smask) != 0)
07031 return force_to_mode (plus_constant (XEXP (x, 0),
07032 (INTVAL (XEXP (x, 1)) & smask)),
07033 mode, smask, reg, next_select);
07034 }
07035
07036
07037
07038 case MULT:
07039
07040
07041
07042 mask = fuller_mask;
07043 goto binop;
07044
07045 case MINUS:
07046
07047
07048 if (GET_CODE (XEXP (x, 0)) == CONST_INT
07049 && (((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 0))
07050 & -INTVAL (XEXP (x, 0))))
07051 > mask))
07052 {
07053 x = simplify_gen_unary (NEG, GET_MODE (x), XEXP (x, 1),
07054 GET_MODE (x));
07055 return force_to_mode (x, mode, mask, reg, next_select);
07056 }
07057
07058
07059
07060 if (GET_CODE (XEXP (x, 0)) == CONST_INT
07061 && ((INTVAL (XEXP (x, 0)) | (HOST_WIDE_INT) fuller_mask)
07062 == INTVAL (XEXP (x, 0))))
07063 {
07064 x = simplify_gen_unary (NOT, GET_MODE (x),
07065 XEXP (x, 1), GET_MODE (x));
07066 return force_to_mode (x, mode, mask, reg, next_select);
07067 }
07068
07069 mask = fuller_mask;
07070 goto binop;
07071
07072 case IOR:
07073 case XOR:
07074
07075
07076
07077
07078
07079 if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
07080 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
07081 && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
07082 && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT
07083 && GET_CODE (XEXP (x, 1)) == CONST_INT
07084 && ((INTVAL (XEXP (XEXP (x, 0), 1))
07085 + floor_log2 (INTVAL (XEXP (x, 1))))
07086 < GET_MODE_BITSIZE (GET_MODE (x)))
07087 && (INTVAL (XEXP (x, 1))
07088 & ~nonzero_bits (XEXP (x, 0), GET_MODE (x))) == 0)
07089 {
07090 temp = GEN_INT ((INTVAL (XEXP (x, 1)) & mask)
07091 << INTVAL (XEXP (XEXP (x, 0), 1)));
07092 temp = gen_binary (GET_CODE (x), GET_MODE (x),
07093 XEXP (XEXP (x, 0), 0), temp);
07094 x = gen_binary (LSHIFTRT, GET_MODE (x), temp,
07095 XEXP (XEXP (x, 0), 1));
07096 return force_to_mode (x, mode, mask, reg, next_select);
07097 }
07098
07099 binop:
07100
07101
07102
07103 op0 = gen_lowpart_for_combine (op_mode,
07104 force_to_mode (XEXP (x, 0), mode, mask,
07105 reg, next_select));
07106 op1 = gen_lowpart_for_combine (op_mode,
07107 force_to_mode (XEXP (x, 1), mode, mask,
07108 reg, next_select));
07109
07110 if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
07111 x = gen_binary (code, op_mode, op0, op1);
07112 break;
07113
07114 case ASHIFT:
07115
07116
07117
07118
07119
07120
07121 if (! (GET_CODE (XEXP (x, 1)) == CONST_INT
07122 && INTVAL (XEXP (x, 1)) >= 0
07123 && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (mode))
07124 && ! (GET_MODE (XEXP (x, 1)) != VOIDmode
07125 && (nonzero_bits (XEXP (x, 1), GET_MODE (XEXP (x, 1)))
07126 < (unsigned HOST_WIDE_INT) GET_MODE_BITSIZE (mode))))
07127 break;
07128
07129
07130
07131
07132 if (GET_CODE (XEXP (x, 1)) == CONST_INT
07133 && INTVAL (XEXP (x, 1)) >= 0
07134 && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (op_mode)
07135 && GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT)
07136 mask >>= INTVAL (XEXP (x, 1));
07137 else
07138 mask = fuller_mask;
07139
07140 op0 = gen_lowpart_for_combine (op_mode,
07141 force_to_mode (XEXP (x, 0), op_mode,
07142 mask, reg, next_select));
07143
07144 if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0))
07145 x = gen_binary (code, op_mode, op0, XEXP (x, 1));
07146 break;
07147
07148 case LSHIFTRT:
07149
07150
07151
07152
07153 if (GET_CODE (XEXP (x, 1)) == CONST_INT
07154 && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
07155 && GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT)
07156 {
07157 rtx inner = XEXP (x, 0);
07158 unsigned HOST_WIDE_INT inner_mask;
07159
07160
07161 inner_mask = mask << INTVAL (XEXP (x, 1));
07162
07163
07164
07165
07166 if (GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT
07167 || (inner_mask & ~GET_MODE_MASK (op_mode)) != 0)
07168 op_mode = GET_MODE (x);
07169
07170 inner = force_to_mode (inner, op_mode, inner_mask, reg, next_select);
07171
07172 if (GET_MODE (x) != op_mode || inner != XEXP (x, 0))
07173 x = gen_binary (LSHIFTRT, op_mode, inner, XEXP (x, 1));
07174 }
07175
07176
07177
07178
07179
07180 if (GET_CODE (x) == LSHIFTRT
07181 && GET_CODE (XEXP (x, 1)) == CONST_INT
07182
07183
07184 && ((INTVAL (XEXP (x, 1))
07185 + num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0))))
07186 >= GET_MODE_BITSIZE (GET_MODE (x)))
07187 && exact_log2 (mask + 1) >= 0
07188
07189
07190 && ((INTVAL (XEXP (x, 1)) + exact_log2 (mask + 1))
07191 <= GET_MODE_BITSIZE (GET_MODE (x)))
07192
07193 && ((int) num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
07194 >= exact_log2 (mask + 1)))
07195 x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0),
07196 GEN_INT (GET_MODE_BITSIZE (GET_MODE (x))
07197 - exact_log2 (mask + 1)));
07198
07199 goto shiftrt;
07200
07201 case ASHIFTRT:
07202
07203
07204 if (GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
07205 && (mask == ((unsigned HOST_WIDE_INT) 1
07206 << (GET_MODE_BITSIZE (GET_MODE (x)) - 1))))
07207 return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select);
07208
07209
07210
07211
07212
07213
07214
07215
07216 if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) >= 0
07217 && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
07218 {
07219 int i = -1;
07220
07221
07222
07223
07224
07225 if (GET_MODE_BITSIZE (GET_MODE (x)) > HOST_BITS_PER_WIDE_INT)
07226 {
07227 nonzero = ~(HOST_WIDE_INT) 0;
07228
07229
07230
07231
07232
07233
07234 if (GET_MODE_BITSIZE (GET_MODE (x)) - INTVAL (XEXP (x, 1))
07235 < HOST_BITS_PER_WIDE_INT)
07236 nonzero >>= INTVAL (XEXP (x, 1))
07237 + HOST_BITS_PER_WIDE_INT
07238 - GET_MODE_BITSIZE (GET_MODE (x)) ;
07239 }
07240 else
07241 {
07242 nonzero = GET_MODE_MASK (GET_MODE (x));
07243 nonzero >>= INTVAL (XEXP (x, 1));
07244 }
07245
07246 if ((mask & ~nonzero) == 0
07247 || (i = exact_log2 (mask)) >= 0)
07248 {
07249 x = simplify_shift_const
07250 (x, LSHIFTRT, GET_MODE (x), XEXP (x, 0),
07251 i < 0 ? INTVAL (XEXP (x, 1))
07252 : GET_MODE_BITSIZE (GET_MODE (x)) - 1 - i);
07253
07254 if (GET_CODE (x) != ASHIFTRT)
07255 return force_to_mode (x, mode, mask, reg, next_select);
07256 }
07257 }
07258
07259
07260
07261 if (mask == 1)
07262 x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0), XEXP (x, 1));
07263
07264 shiftrt:
07265
07266
07267
07268
07269
07270 if ((GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ASHIFTRT)
07271 && GET_CODE (XEXP (x, 1)) == CONST_INT
07272 && INTVAL (XEXP (x, 1)) >= 0
07273 && (INTVAL (XEXP (x, 1))
07274 <= GET_MODE_BITSIZE (GET_MODE (x)) - (floor_log2 (mask) + 1))
07275 && GET_CODE (XEXP (x, 0)) == ASHIFT
07276 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
07277 && INTVAL (XEXP (XEXP (x, 0), 1)) == INTVAL (XEXP (x, 1)))
07278 return force_to_mode (XEXP (XEXP (x, 0), 0), mode, mask,
07279 reg, next_select);
07280
07281 break;
07282
07283 case ROTATE:
07284 case ROTATERT:
07285
07286
07287
07288
07289 if (GET_CODE (XEXP (x, 1)) == CONST_INT
07290 && INTVAL (XEXP (x, 1)) >= 0)
07291 {
07292 temp = simplify_binary_operation (code == ROTATE ? ROTATERT : ROTATE,
07293 GET_MODE (x), GEN_INT (mask),
07294 XEXP (x, 1));
07295 if (temp && GET_CODE(temp) == CONST_INT)
07296 SUBST (XEXP (x, 0),
07297 force_to_mode (XEXP (x, 0), GET_MODE (x),
07298 INTVAL (temp), reg, next_select));
07299 }
07300 break;
07301
07302 case NEG:
07303
07304
07305 if (mask == 1)
07306 return force_to_mode (XEXP (x, 0), mode, mask, reg, just_select);
07307
07308
07309
07310
07311 mask = fuller_mask;
07312 goto unop;
07313
07314 case NOT:
07315
07316
07317
07318
07319 if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
07320 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
07321 && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
07322 && (INTVAL (XEXP (XEXP (x, 0), 1)) + floor_log2 (mask)
07323 < GET_MODE_BITSIZE (GET_MODE (x)))
07324 && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT)
07325 {
07326 temp = gen_int_mode (mask << INTVAL (XEXP (XEXP (x, 0), 1)),
07327 GET_MODE (x));
07328 temp = gen_binary (XOR, GET_MODE (x), XEXP (XEXP (x, 0), 0), temp);
07329 x = gen_binary (LSHIFTRT, GET_MODE (x), temp, XEXP (XEXP (x, 0), 1));
07330
07331 return force_to_mode (x, mode, mask, reg, next_select);
07332 }
07333
07334
07335
07336 mask = fuller_mask;
07337
07338 unop:
07339 op0 = gen_lowpart_for_combine (op_mode,
07340 force_to_mode (XEXP (x, 0), mode, mask,
07341 reg, next_select));
07342 if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0))
07343 x = simplify_gen_unary (code, op_mode, op0, op_mode);
07344 break;
07345
07346 case NE:
07347
07348
07349
07350 if ((mask & ~STORE_FLAG_VALUE) == 0 && XEXP (x, 1) == const0_rtx
07351 && exact_log2 (nonzero_bits (XEXP (x, 0), mode)) >= 0
07352 && nonzero_bits (XEXP (x, 0), mode) == STORE_FLAG_VALUE)
07353 return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select);
07354
07355 break;
07356
07357 case IF_THEN_ELSE:
07358
07359
07360
07361 SUBST (XEXP (x, 1),
07362 gen_lowpart_for_combine (GET_MODE (x),
07363 force_to_mode (XEXP (x, 1), mode,
07364 mask, reg, next_select)));
07365 SUBST (XEXP (x, 2),
07366 gen_lowpart_for_combine (GET_MODE (x),
07367 force_to_mode (XEXP (x, 2), mode,
07368 mask, reg,next_select)));
07369 break;
07370
07371 default:
07372 break;
07373 }
07374
07375
07376 return gen_lowpart_for_combine (mode, x);
07377 }
07378
07379
07380
07381
07382
07383
07384
07385
07386 static rtx
07387 if_then_else_cond (x, ptrue, pfalse)
07388 rtx x;
07389 rtx *ptrue, *pfalse;
07390 {
07391 enum machine_mode mode = GET_MODE (x);
07392 enum rtx_code code = GET_CODE (x);
07393 rtx cond0, cond1, true0, true1, false0, false1;
07394 unsigned HOST_WIDE_INT nz;
07395
07396
07397 if ((code == NE || code == EQ)
07398 && GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 0)
07399 {
07400 *ptrue = (code == NE) ? const_true_rtx : const0_rtx;
07401 *pfalse = (code == NE) ? const0_rtx : const_true_rtx;
07402 return XEXP (x, 0);
07403 }
07404
07405
07406
07407 else if (GET_RTX_CLASS (code) == '1'
07408 && (cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0)) != 0)
07409 {
07410 *ptrue = simplify_gen_unary (code, mode, true0, GET_MODE (XEXP (x, 0)));
07411 *pfalse = simplify_gen_unary (code, mode, false0,
07412 GET_MODE (XEXP (x, 0)));
07413 return cond0;
07414 }
07415
07416
07417
07418 else if (code == COMPARE)
07419 ;
07420
07421
07422
07423
07424 else if (GET_RTX_CLASS (code) == 'c' || GET_RTX_CLASS (code) == '2'
07425 || GET_RTX_CLASS (code) == '<')
07426 {
07427 cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0);
07428 cond1 = if_then_else_cond (XEXP (x, 1), &true1, &false1);
07429
07430 if ((cond0 != 0 || cond1 != 0)
07431 && ! (cond0 != 0 && cond1 != 0 && ! rtx_equal_p (cond0, cond1)))
07432 {
07433
07434
07435
07436 if (cond0 == 0)
07437 true0 = copy_rtx (true0);
07438 else if (cond1 == 0)
07439 true1 = copy_rtx (true1);
07440
07441 *ptrue = gen_binary (code, mode, true0, true1);
07442 *pfalse = gen_binary (code, mode, false0, false1);
07443 return cond0 ? cond0 : cond1;
07444 }
07445
07446
07447
07448
07449
07450 if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
07451 && (code == PLUS || code == IOR || code == XOR || code == MINUS
07452 || code == UMAX)
07453 && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == MULT)
07454 {
07455 rtx op0 = XEXP (XEXP (x, 0), 1);
07456 rtx op1 = XEXP (XEXP (x, 1), 1);
07457
07458 cond0 = XEXP (XEXP (x, 0), 0);
07459 cond1 = XEXP (XEXP (x, 1), 0);
07460
07461 if (GET_RTX_CLASS (GET_CODE (cond0)) == '<'
07462 && GET_RTX_CLASS (GET_CODE (cond1)) == '<'
07463 && ((GET_CODE (cond0) == combine_reversed_comparison_code (cond1)
07464 && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0))
07465 && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1)))
07466 || ((swap_condition (GET_CODE (cond0))
07467 == combine_reversed_comparison_code (cond1))
07468 && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 1))
07469 && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0))))
07470 && ! side_effects_p (x))
07471 {
07472 *ptrue = gen_binary (MULT, mode, op0, const_true_rtx);
07473 *pfalse = gen_binary (MULT, mode,
07474 (code == MINUS
07475 ? simplify_gen_unary (NEG, mode, op1,
07476 mode)
07477 : op1),
07478 const_true_rtx);
07479 return cond0;
07480 }
07481 }
07482
07483
07484
07485 if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
07486 && (code == MULT || code == AND || code == UMIN)
07487 && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == MULT)
07488 {
07489 cond0 = XEXP (XEXP (x, 0), 0);
07490 cond1 = XEXP (XEXP (x, 1), 0);
07491
07492 if (GET_RTX_CLASS (GET_CODE (cond0)) == '<'
07493 && GET_RTX_CLASS (GET_CODE (cond1)) == '<'
07494 && ((GET_CODE (cond0) == combine_reversed_comparison_code (cond1)
07495 && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0))
07496 && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1)))
07497 || ((swap_condition (GET_CODE (cond0))
07498 == combine_reversed_comparison_code (cond1))
07499 && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 1))
07500 && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0))))
07501 && ! side_effects_p (x))
07502 {
07503 *ptrue = *pfalse = const0_rtx;
07504 return cond0;
07505 }
07506 }
07507 }
07508
07509 else if (code == IF_THEN_ELSE)
07510 {
07511
07512
07513 cond0 = XEXP (x, 0);
07514 *ptrue = XEXP (x, 1), *pfalse = XEXP (x, 2);
07515 if (GET_CODE (cond0) == NE && XEXP (cond0, 1) == const0_rtx)
07516 return XEXP (cond0, 0);
07517 else if (GET_CODE (cond0) == EQ && XEXP (cond0, 1) == const0_rtx)
07518 {
07519 *ptrue = XEXP (x, 2), *pfalse = XEXP (x, 1);
07520 return XEXP (cond0, 0);
07521 }
07522 else
07523 return cond0;
07524 }
07525
07526
07527
07528 else if (code == SUBREG
07529 && 0 != (cond0 = if_then_else_cond (SUBREG_REG (x),
07530 &true0, &false0)))
07531 {
07532 *ptrue = simplify_gen_subreg (mode, true0,
07533 GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
07534 *pfalse = simplify_gen_subreg (mode, false0,
07535 GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
07536
07537 return cond0;
07538 }
07539
07540
07541
07542 else if (CONSTANT_P (x)
07543 || ((cond0 = get_last_value (x)) != 0 && CONSTANT_P (cond0)))
07544 ;
07545
07546
07547
07548 else if (mode == BImode)
07549 {
07550 *ptrue = GEN_INT (STORE_FLAG_VALUE), *pfalse = const0_rtx;
07551 return x;
07552 }
07553
07554
07555
07556 else if (x == constm1_rtx || x == const0_rtx
07557 || (mode != VOIDmode
07558 && num_sign_bit_copies (x, mode) == GET_MODE_BITSIZE (mode)))
07559 {
07560 *ptrue = constm1_rtx, *pfalse = const0_rtx;
07561 return x;
07562 }
07563
07564
07565 else if (mode != VOIDmode
07566 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
07567 && exact_log2 (nz = nonzero_bits (x, mode)) >= 0)
07568 {
07569 *ptrue = gen_int_mode (nz, mode), *pfalse = const0_rtx;
07570 return x;
07571 }
07572
07573
07574 *ptrue = *pfalse = x;
07575 return 0;
07576 }
07577
07578
07579
07580
07581
07582
07583
07584
07585
07586 static rtx
07587 known_cond (x, cond, reg, val)
07588 rtx x;
07589 enum rtx_code cond;
07590 rtx reg, val;
07591 {
07592 enum rtx_code code = GET_CODE (x);
07593 rtx temp;
07594 const char *fmt;
07595 int i, j;
07596
07597 if (side_effects_p (x))
07598 return x;
07599
07600
07601
07602 if (cond == EQ
07603 && rtx_equal_p (x, reg)
07604 && ! FLOAT_MODE_P (GET_MODE (x))
07605 && ! FLOAT_MODE_P (GET_MODE (val)))
07606 return val;
07607
07608 if (cond == UNEQ && rtx_equal_p (x, reg))
07609 return val;
07610
07611
07612
07613
07614 if (code == ABS && rtx_equal_p (XEXP (x, 0), reg) && val == const0_rtx)
07615 switch (cond)
07616 {
07617 case GE: case GT: case EQ:
07618 return XEXP (x, 0);
07619 case LT: case LE:
07620 return simplify_gen_unary (NEG, GET_MODE (XEXP (x, 0)),
07621 XEXP (x, 0),
07622 GET_MODE (XEXP (x, 0)));
07623 default:
07624 break;
07625 }
07626
07627
07628
07629
07630 else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == 'c')
07631 {
07632 if (rtx_equal_p (XEXP (x, 0), val))
07633 cond = swap_condition (cond), temp = val, val = reg, reg = temp;
07634
07635 if (rtx_equal_p (XEXP (x, 0), reg) && rtx_equal_p (XEXP (x, 1), val))
07636 {
07637 if (GET_RTX_CLASS (code) == '<')
07638 {
07639 if (comparison_dominates_p (cond, code))
07640 return const_true_rtx;
07641
07642 code = combine_reversed_comparison_code (x);
07643 if (code != UNKNOWN
07644 && comparison_dominates_p (cond, code))
07645 return const0_rtx;
07646 else
07647 return x;
07648 }
07649 else if (code == SMAX || code == SMIN
07650 || code == UMIN || code == UMAX)
07651 {
07652 int unsignedp = (code == UMIN || code == UMAX);
07653
07654
07655
07656
07657
07658 if ((code == SMAX || code == UMAX)
07659 && ! (cond == EQ || cond == NE))
07660 cond = reverse_condition (cond);
07661
07662 switch (cond)
07663 {
07664 case GE: case GT:
07665 return unsignedp ? x : XEXP (x, 1);
07666 case LE: case LT:
07667 return unsignedp ? x : XEXP (x, 0);
07668 case GEU: case GTU:
07669 return unsignedp ? XEXP (x, 1) : x;
07670 case LEU: case LTU:
07671 return unsignedp ? XEXP (x, 0) : x;
07672 default:
07673 break;
07674 }
07675 }
07676 }
07677 }
07678 else if (code == SUBREG)
07679 {
07680 enum machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
07681 rtx new, r = known_cond (SUBREG_REG (x), cond, reg, val);
07682
07683 if (SUBREG_REG (x) != r)
07684 {
07685
07686
07687 new = simplify_subreg (GET_MODE (x), r,
07688 inner_mode, SUBREG_BYTE (x));
07689 if (new)
07690 return new;
07691 else
07692 SUBST (SUBREG_REG (x), r);
07693 }
07694
07695 return x;
07696 }
07697
07698
07699
07700
07701
07702
07703 else if (code == ZERO_EXTEND)
07704 {
07705 enum machine_mode inner_mode = GET_MODE (XEXP (x, 0));
07706 rtx new, r = known_cond (XEXP (x, 0), cond, reg, val);
07707
07708 if (XEXP (x, 0) != r)
07709 {
07710
07711
07712 new = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
07713 r, inner_mode);
07714 if (new)
07715 return new;
07716 else
07717 SUBST (XEXP (x, 0), r);
07718 }
07719
07720 return x;
07721 }
07722
07723 fmt = GET_RTX_FORMAT (code);
07724 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
07725 {
07726 if (fmt[i] == 'e')
07727 SUBST (XEXP (x, i), known_cond (XEXP (x, i), cond, reg, val));
07728 else if (fmt[i] == 'E')
07729 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
07730 SUBST (XVECEXP (x, i, j), known_cond (XVECEXP (x, i, j),
07731 cond, reg, val));
07732 }
07733
07734 return x;
07735 }
07736
07737
07738
07739
07740 static int
07741 rtx_equal_for_field_assignment_p (x, y)
07742 rtx x;
07743 rtx y;
07744 {
07745 if (x == y || rtx_equal_p (x, y))
07746 return 1;
07747
07748 if (x == 0 || y == 0 || GET_MODE (x) != GET_MODE (y))
07749 return 0;
07750
07751
07752
07753
07754 if (GET_CODE (x) == MEM && GET_CODE (y) == SUBREG
07755 && GET_CODE (SUBREG_REG (y)) == MEM
07756 && rtx_equal_p (SUBREG_REG (y),
07757 gen_lowpart_for_combine (GET_MODE (SUBREG_REG (y)), x)))
07758 return 1;
07759
07760 if (GET_CODE (y) == MEM && GET_CODE (x) == SUBREG
07761 && GET_CODE (SUBREG_REG (x)) == MEM
07762 && rtx_equal_p (SUBREG_REG (x),
07763 gen_lowpart_for_combine (GET_MODE (SUBREG_REG (x)), y)))
07764 return 1;
07765
07766
07767
07768
07769
07770
07771 return 0;
07772 }
07773
07774
07775
07776
07777
07778
07779 static rtx
07780 make_field_assignment (x)
07781 rtx x;
07782 {
07783 rtx dest = SET_DEST (x);
07784 rtx src = SET_SRC (x);
07785 rtx assign;
07786 rtx rhs, lhs;
07787 HOST_WIDE_INT c1;
07788 HOST_WIDE_INT pos;
07789 unsigned HOST_WIDE_INT len;
07790 rtx other;
07791 enum machine_mode mode;
07792
07793
07794
07795
07796
07797
07798 if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == ROTATE
07799 && GET_CODE (XEXP (XEXP (src, 0), 0)) == CONST_INT
07800 && INTVAL (XEXP (XEXP (src, 0), 0)) == -2
07801 && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
07802 {
07803 assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1),
07804 1, 1, 1, 0);
07805 if (assign != 0)
07806 return gen_rtx_SET (VOIDmode, assign, const0_rtx);
07807 return x;
07808 }
07809
07810 else if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == SUBREG
07811 && subreg_lowpart_p (XEXP (src, 0))
07812 && (GET_MODE_SIZE (GET_MODE (XEXP (src, 0)))
07813 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (src, 0)))))
07814 && GET_CODE (SUBREG_REG (XEXP (src, 0))) == ROTATE
07815 && INTVAL (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == -2
07816 && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
07817 {
07818 assign = make_extraction (VOIDmode, dest, 0,
07819 XEXP (SUBREG_REG (XEXP (src, 0)), 1),
07820 1, 1, 1, 0);
07821 if (assign != 0)
07822 return gen_rtx_SET (VOIDmode, assign, const0_rtx);
07823 return x;
07824 }
07825
07826
07827
07828 else if (GET_CODE (src) == IOR && GET_CODE (XEXP (src, 0)) == ASHIFT
07829 && XEXP (XEXP (src, 0), 0) == const1_rtx
07830 && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
07831 {
07832 assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1),
07833 1, 1, 1, 0);
07834 if (assign != 0)
07835 return gen_rtx_SET (VOIDmode, assign, const1_rtx);
07836 return x;
07837 }
07838
07839
07840
07841
07842
07843
07844
07845
07846
07847 if (GET_CODE (src) != IOR && GET_CODE (src) != XOR)
07848 return x;
07849
07850 rhs = expand_compound_operation (XEXP (src, 0));
07851 lhs = expand_compound_operation (XEXP (src, 1));
07852
07853 if (GET_CODE (rhs) == AND
07854 && GET_CODE (XEXP (rhs, 1)) == CONST_INT
07855 && rtx_equal_for_field_assignment_p (XEXP (rhs, 0), dest))
07856 c1 = INTVAL (XEXP (rhs, 1)), other = lhs;
07857 else if (GET_CODE (lhs) == AND
07858 && GET_CODE (XEXP (lhs, 1)) == CONST_INT
07859 && rtx_equal_for_field_assignment_p (XEXP (lhs, 0), dest))
07860 c1 = INTVAL (XEXP (lhs, 1)), other = rhs;
07861 else
07862 return x;
07863
07864 pos = get_pos_from_mask ((~c1) & GET_MODE_MASK (GET_MODE (dest)), &len);
07865 if (pos < 0 || pos + len > GET_MODE_BITSIZE (GET_MODE (dest))
07866 || GET_MODE_BITSIZE (GET_MODE (dest)) > HOST_BITS_PER_WIDE_INT
07867 || (c1 & nonzero_bits (other, GET_MODE (dest))) != 0)
07868 return x;
07869
07870 assign = make_extraction (VOIDmode, dest, pos, NULL_RTX, len, 1, 1, 0);
07871 if (assign == 0)
07872 return x;
07873
07874
07875
07876 mode = (GET_CODE (assign) == STRICT_LOW_PART
07877 ? GET_MODE (XEXP (assign, 0)) : GET_MODE (assign));
07878
07879
07880
07881
07882 src = force_to_mode (simplify_shift_const (NULL_RTX, LSHIFTRT,
07883 GET_MODE (src), other, pos),
07884 mode,
07885 GET_MODE_BITSIZE (mode) >= HOST_BITS_PER_WIDE_INT
07886 ? ~(unsigned HOST_WIDE_INT) 0
07887 : ((unsigned HOST_WIDE_INT) 1 << len) - 1,
07888 dest, 0);
07889
07890 return gen_rtx_SET (VOIDmode, assign, src);
07891 }
07892
07893
07894
07895
07896 static rtx
07897 apply_distributive_law (x)
07898 rtx x;
07899 {
07900 enum rtx_code code = GET_CODE (x);
07901 rtx lhs, rhs, other;
07902 rtx tem;
07903 enum rtx_code inner_code;
07904
07905
07906
07907
07908 if (FLOAT_MODE_P (GET_MODE (x)))
07909 return x;
07910
07911
07912 if (code != IOR && code != AND && code != XOR
07913 && code != PLUS && code != MINUS)
07914 return x;
07915
07916 lhs = XEXP (x, 0), rhs = XEXP (x, 1);
07917
07918
07919
07920 if (GET_RTX_CLASS (GET_CODE (lhs)) == 'o'
07921 || GET_RTX_CLASS (GET_CODE (rhs)) == 'o')
07922 return x;
07923
07924 lhs = expand_compound_operation (lhs);
07925 rhs = expand_compound_operation (rhs);
07926 inner_code = GET_CODE (lhs);
07927 if (inner_code != GET_CODE (rhs))
07928 return x;
07929
07930
07931 switch (inner_code)
07932 {
07933 case LSHIFTRT:
07934 case ASHIFTRT:
07935 case AND:
07936 case IOR:
07937
07938 if (code == PLUS || code == MINUS)
07939 return x;
07940 break;
07941
07942 case MULT:
07943 if (code != PLUS && code != MINUS)
07944 return x;
07945 break;
07946
07947 case ASHIFT:
07948
07949 break;
07950
07951 case SUBREG:
07952
07953
07954
07955
07956
07957
07958
07959
07960
07961
07962
07963 if (GET_MODE (SUBREG_REG (lhs)) != GET_MODE (SUBREG_REG (rhs))
07964 || SUBREG_BYTE (lhs) != SUBREG_BYTE (rhs)
07965 || ! subreg_lowpart_p (lhs)
07966 || (GET_MODE_CLASS (GET_MODE (lhs))
07967 != GET_MODE_CLASS (GET_MODE (SUBREG_REG (lhs))))
07968 || (GET_MODE_SIZE (GET_MODE (lhs))
07969 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))))
07970 || GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))) > UNITS_PER_WORD)
07971 return x;
07972
07973 tem = gen_binary (code, GET_MODE (SUBREG_REG (lhs)),
07974 SUBREG_REG (lhs), SUBREG_REG (rhs));
07975 return gen_lowpart_for_combine (GET_MODE (x), tem);
07976
07977 default:
07978 return x;
07979 }
07980
07981
07982
07983
07984
07985 if (GET_RTX_CLASS (inner_code) == 'c'
07986 && rtx_equal_p (XEXP (lhs, 0), XEXP (rhs, 0)))
07987 other = XEXP (lhs, 0), lhs = XEXP (lhs, 1), rhs = XEXP (rhs, 1);
07988 else if (GET_RTX_CLASS (inner_code) == 'c'
07989 && rtx_equal_p (XEXP (lhs, 0), XEXP (rhs, 1)))
07990 other = XEXP (lhs, 0), lhs = XEXP (lhs, 1), rhs = XEXP (rhs, 0);
07991 else if (GET_RTX_CLASS (inner_code) == 'c'
07992 && rtx_equal_p (XEXP (lhs, 1), XEXP (rhs, 0)))
07993 other = XEXP (lhs, 1), lhs = XEXP (lhs, 0), rhs = XEXP (rhs, 1);
07994 else if (rtx_equal_p (XEXP (lhs, 1), XEXP (rhs, 1)))
07995 other = XEXP (lhs, 1), lhs = XEXP (lhs, 0), rhs = XEXP (rhs, 0);
07996 else
07997 return x;
07998
07999
08000 tem = gen_binary (code, GET_MODE (x), lhs, rhs);
08001
08002
08003
08004 if (code == XOR && inner_code == IOR)
08005 {
08006 inner_code = AND;
08007 other = simplify_gen_unary (NOT, GET_MODE (x), other, GET_MODE (x));
08008 }
08009
08010
08011
08012
08013 return gen_binary (inner_code, GET_MODE (x),
08014 apply_distributive_law (tem), other);
08015 }
08016
08017
08018
08019
08020
08021
08022
08023 static rtx
08024 simplify_and_const_int (x, mode, varop, constop)
08025 rtx x;
08026 enum machine_mode mode;
08027 rtx varop;
08028 unsigned HOST_WIDE_INT constop;
08029 {
08030 unsigned HOST_WIDE_INT nonzero;
08031 int i;
08032
08033
08034
08035
08036
08037
08038
08039
08040 varop = force_to_mode (varop, mode, constop, NULL_RTX, 0);
08041
08042
08043 if (GET_CODE (varop) == CLOBBER)
08044 return varop;
08045
08046
08047
08048 if (GET_CODE (varop) == CONST_INT)
08049 return GEN_INT (trunc_int_for_mode (INTVAL (varop) & constop, mode));
08050
08051
08052
08053
08054
08055 nonzero = nonzero_bits (varop, mode) & GET_MODE_MASK (mode);
08056
08057
08058
08059
08060
08061 constop &= nonzero;
08062
08063
08064 if (constop == 0)
08065 return const0_rtx;
08066
08067
08068
08069 if (GET_CODE (varop) == NEG && nonzero_bits (XEXP (varop, 0), mode) == 1
08070 && (i = exact_log2 (constop)) >= 0)
08071 return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (varop, 0), i);
08072
08073
08074
08075
08076
08077
08078
08079 if (GET_CODE (varop) == IOR || GET_CODE (varop) == XOR)
08080 return
08081 gen_lowpart_for_combine
08082 (mode,
08083 apply_distributive_law
08084 (gen_binary (GET_CODE (varop), GET_MODE (varop),
08085 simplify_and_const_int (NULL_RTX, GET_MODE (varop),
08086 XEXP (varop, 0), constop),
08087 simplify_and_const_int (NULL_RTX, GET_MODE (varop),
08088 XEXP (varop, 1), constop))));
08089
08090
08091
08092
08093
08094 if (GET_CODE (varop) == PLUS
08095 && exact_log2 (constop + 1) >= 0)
08096 {
08097 rtx o0, o1;
08098
08099 o0 = simplify_and_const_int (NULL_RTX, mode, XEXP (varop, 0), constop);
08100 o1 = simplify_and_const_int (NULL_RTX, mode, XEXP (varop, 1), constop);
08101 if (o0 == const0_rtx)
08102 return o1;
08103 if (o1 == const0_rtx)
08104 return o0;
08105 }
08106
08107
08108
08109 if (x && GET_CODE (XEXP (x, 0)) == SUBREG
08110 && GET_MODE (XEXP (x, 0)) == mode
08111 && SUBREG_REG (XEXP (x, 0)) == varop)
08112 varop = XEXP (x, 0);
08113 else
08114 varop = gen_lowpart_for_combine (mode, varop);
08115
08116
08117 if (GET_CODE (varop) == CLOBBER)
08118 return x ? x : varop;
08119
08120
08121 if (constop == nonzero)
08122 x = varop;
08123 else
08124 {
08125
08126 constop = trunc_int_for_mode (constop, mode);
08127
08128 if (x == 0 || GET_CODE (x) != AND || GET_MODE (x) != mode)
08129 x = gen_binary (AND, mode, varop, GEN_INT (constop));
08130
08131 else
08132 {
08133 if (GET_CODE (XEXP (x, 1)) != CONST_INT
08134 || (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) != constop)
08135 SUBST (XEXP (x, 1), GEN_INT (constop));
08136
08137 SUBST (XEXP (x, 0), varop);
08138 }
08139 }
08140
08141 return x;
08142 }
08143
08144 #define nonzero_bits_with_known(X, MODE) \
08145 cached_nonzero_bits (X, MODE, known_x, known_mode, known_ret)
08146
08147
08148
08149
08150
08151 static unsigned HOST_WIDE_INT
08152 cached_nonzero_bits (x, mode, known_x, known_mode, known_ret)
08153 rtx x;
08154 enum machine_mode mode;
08155 rtx known_x;
08156 enum machine_mode known_mode;
08157 unsigned HOST_WIDE_INT known_ret;
08158 {
08159 if (x == known_x && mode == known_mode)
08160 return known_ret;
08161
08162
08163
08164
08165
08166 if (GET_RTX_CLASS (GET_CODE (x)) == '2'
08167 || GET_RTX_CLASS (GET_CODE (x)) == 'c')
08168 {
08169 rtx x0 = XEXP (x, 0);
08170 rtx x1 = XEXP (x, 1);
08171
08172
08173 if (x0 == x1)
08174 return nonzero_bits1 (x, mode, x0, mode,
08175 nonzero_bits_with_known (x0, mode));
08176
08177
08178 if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
08179 || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
08180 && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
08181 return nonzero_bits1 (x, mode, x1, mode,
08182 nonzero_bits_with_known (x1, mode));
08183
08184 if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
08185 || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
08186 && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
08187 return nonzero_bits1 (x, mode, x0, mode,
08188 nonzero_bits_with_known (x0, mode));
08189 }
08190
08191 return nonzero_bits1 (x, mode, known_x, known_mode, known_ret);
08192 }
08193
08194
08195
08196
08197
08198
08199 #define cached_num_sign_bit_copies()
08200
08201
08202
08203
08204
08205
08206
08207 static unsigned HOST_WIDE_INT
08208 nonzero_bits1 (x, mode, known_x, known_mode, known_ret)
08209 rtx x;
08210 enum machine_mode mode;
08211 rtx known_x;
08212 enum machine_mode known_mode;
08213 unsigned HOST_WIDE_INT known_ret;
08214 {
08215 unsigned HOST_WIDE_INT nonzero = GET_MODE_MASK (mode);
08216 unsigned HOST_WIDE_INT inner_nz;
08217 enum rtx_code code;
08218 unsigned int mode_width = GET_MODE_BITSIZE (mode);
08219 rtx tem;
08220
08221
08222 if (FLOAT_MODE_P (GET_MODE (x)) || FLOAT_MODE_P (mode))
08223 return nonzero;
08224
08225
08226 if (GET_MODE_BITSIZE (GET_MODE (x)) > mode_width)
08227 {
08228 mode = GET_MODE (x);
08229 nonzero = GET_MODE_MASK (mode);
08230 mode_width = GET_MODE_BITSIZE (mode);
08231 }
08232
08233 if (mode_width > HOST_BITS_PER_WIDE_INT)
08234
08235
08236 return nonzero;
08237
08238 #ifndef WORD_REGISTER_OPERATIONS
08239
08240
08241
08242
08243
08244
08245
08246 if (GET_MODE (x) != VOIDmode && GET_MODE (x) != mode
08247 && GET_MODE_BITSIZE (GET_MODE (x)) <= BITS_PER_WORD
08248 && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
08249 && GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (GET_MODE (x)))
08250 {
08251 nonzero &= nonzero_bits_with_known (x, GET_MODE (x));
08252 nonzero |= GET_MODE_MASK (mode) & ~GET_MODE_MASK (GET_MODE (x));
08253 return nonzero;
08254 }
08255 #endif
08256
08257 code = GET_CODE (x);
08258 switch (code)
08259 {
08260 case REG:
08261 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
08262
08263
08264 if (POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
08265 && REG_POINTER (x))
08266 nonzero &= GET_MODE_MASK (ptr_mode);
08267 #endif
08268
08269
08270
08271
08272
08273 if ((x == stack_pointer_rtx
08274 || x == frame_pointer_rtx
08275 || x == arg_pointer_rtx)
08276 && REGNO_POINTER_ALIGN (REGNO (x)))
08277 {
08278 unsigned HOST_WIDE_INT alignment
08279 = REGNO_POINTER_ALIGN (REGNO (x)) / BITS_PER_UNIT;
08280
08281 #ifdef PUSH_ROUNDING
08282
08283
08284
08285 if (x == stack_pointer_rtx && PUSH_ARGS)
08286 alignment = MIN (PUSH_ROUNDING (1), alignment);
08287 #endif
08288
08289 nonzero &= ~(alignment - 1);
08290 }
08291
08292
08293
08294
08295
08296
08297 if (reg_last_set_value[REGNO (x)] != 0
08298 && (reg_last_set_mode[REGNO (x)] == mode
08299 || (GET_MODE_CLASS (reg_last_set_mode[REGNO (x)]) == MODE_INT
08300 && GET_MODE_CLASS (mode) == MODE_INT))
08301 && (reg_last_set_label[REGNO (x)] == label_tick
08302 || (REGNO (x) >= FIRST_PSEUDO_REGISTER
08303 && REG_N_SETS (REGNO (x)) == 1
08304 && ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start,
08305 REGNO (x))))
08306 && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
08307 return reg_last_set_nonzero_bits[REGNO (x)] & nonzero;
08308
08309 tem = get_last_value (x);
08310
08311 if (tem)
08312 {
08313 #ifdef SHORT_IMMEDIATES_SIGN_EXTEND
08314
08315
08316
08317
08318
08319
08320
08321
08322
08323 if (GET_MODE_BITSIZE (GET_MODE (x)) < mode_width
08324 && GET_CODE (tem) == CONST_INT
08325 && INTVAL (tem) > 0
08326 && 0 != (INTVAL (tem)
08327 & ((HOST_WIDE_INT) 1
08328 << (GET_MODE_BITSIZE (GET_MODE (x)) - 1))))
08329 tem = GEN_INT (INTVAL (tem)
08330 | ((HOST_WIDE_INT) (-1)
08331 << GET_MODE_BITSIZE (GET_MODE (x))));
08332 #endif
08333 return nonzero_bits_with_known (tem, mode) & nonzero;
08334 }
08335 else if (nonzero_sign_valid && reg_nonzero_bits[REGNO (x)])
08336 {
08337 unsigned HOST_WIDE_INT mask = reg_nonzero_bits[REGNO (x)];
08338
08339 if (GET_MODE_BITSIZE (GET_MODE (x)) < mode_width)
08340
08341 mask |= GET_MODE_MASK (mode) ^ GET_MODE_MASK (GET_MODE (x));
08342 return nonzero & mask;
08343 }
08344 else
08345 return nonzero;
08346
08347 case CONST_INT:
08348 #ifdef SHORT_IMMEDIATES_SIGN_EXTEND
08349
08350 if (INTVAL (x) > 0 && mode_width < BITS_PER_WORD
08351 && 0 != (INTVAL (x) & ((HOST_WIDE_INT) 1 << (mode_width - 1))))
08352 return (INTVAL (x) | ((HOST_WIDE_INT) (-1) << mode_width));
08353 #endif
08354
08355 return INTVAL (x);
08356
08357 case MEM:
08358 #ifdef LOAD_EXTEND_OP
08359
08360
08361
08362 if (LOAD_EXTEND_OP (GET_MODE (x)) == ZERO_EXTEND)
08363 nonzero &= GET_MODE_MASK (GET_MODE (x));
08364 #endif
08365 break;
08366
08367 case EQ: case NE:
08368 case UNEQ: case LTGT:
08369 case GT: case GTU: case UNGT:
08370 case LT: case LTU: case UNLT:
08371 case GE: case GEU: case UNGE:
08372 case LE: case LEU: case UNLE:
08373 case UNORDERED: case ORDERED:
08374
08375
08376
08377
08378
08379 if (GET_MODE_CLASS (mode) == MODE_INT
08380 && mode_width <= HOST_BITS_PER_WIDE_INT)
08381 nonzero = STORE_FLAG_VALUE;
08382 break;
08383
08384 case NEG:
08385 #if 0
08386
08387
08388 if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (x))
08389 == GET_MODE_BITSIZE (GET_MODE (x)))
08390 nonzero = 1;
08391 #endif
08392
08393 if (GET_MODE_SIZE (GET_MODE (x)) < mode_width)
08394 nonzero |= (GET_MODE_MASK (mode) & ~GET_MODE_MASK (GET_MODE (x)));
08395 break;
08396
08397 case ABS:
08398 #if 0
08399
08400
08401 if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (x))
08402 == GET_MODE_BITSIZE (GET_MODE (x)))
08403 nonzero = 1;
08404 #endif
08405 break;
08406
08407 case TRUNCATE:
08408 nonzero &= (nonzero_bits_with_known (XEXP (x, 0), mode)
08409 & GET_MODE_MASK (mode));
08410 break;
08411
08412 case ZERO_EXTEND:
08413 nonzero &= nonzero_bits_with_known (XEXP (x, 0), mode);
08414 if (GET_MODE (XEXP (x, 0)) != VOIDmode)
08415 nonzero &= GET_MODE_MASK (GET_MODE (XEXP (x, 0)));
08416 break;
08417
08418 case SIGN_EXTEND:
08419
08420
08421
08422 inner_nz = nonzero_bits_with_known (XEXP (x, 0), mode);
08423 if (GET_MODE (XEXP (x, 0)) != VOIDmode)
08424 {
08425 inner_nz &= GET_MODE_MASK (GET_MODE (XEXP (x, 0)));
08426 if (inner_nz
08427 & (((HOST_WIDE_INT) 1
08428 << (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - 1))))
08429 inner_nz |= (GET_MODE_MASK (mode)
08430 & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0))));
08431 }
08432
08433 nonzero &= inner_nz;
08434 break;
08435
08436 case AND:
08437 nonzero &= (nonzero_bits_with_known (XEXP (x, 0), mode)
08438 & nonzero_bits_with_known (XEXP (x, 1), mode));
08439 break;
08440
08441 case XOR: case IOR:
08442 case UMIN: case UMAX: case SMIN: case SMAX:
08443 {
08444 unsigned HOST_WIDE_INT nonzero0 =
08445 nonzero_bits_with_known (XEXP (x, 0), mode);
08446
08447
08448
08449 if ((nonzero & nonzero0) != nonzero)
08450 nonzero &= (nonzero0
08451 | nonzero_bits_with_known (XEXP (x, 1), mode));
08452 }
08453 break;
08454
08455 case PLUS: case MINUS:
08456 case MULT:
08457 case DIV: case UDIV:
08458 case MOD: case UMOD:
08459
08460
08461
08462
08463 {
08464 unsigned HOST_WIDE_INT nz0 =
08465 nonzero_bits_with_known (XEXP (x, 0), mode);
08466 unsigned HOST_WIDE_INT nz1 =
08467 nonzero_bits_with_known (XEXP (x, 1), mode);
08468 int width0 = floor_log2 (nz0) + 1;
08469 int width1 = floor_log2 (nz1) + 1;
08470 int low0 = floor_log2 (nz0 & -nz0);
08471 int low1 = floor_log2 (nz1 & -nz1);
08472 HOST_WIDE_INT op0_maybe_minusp
08473 = (nz0 & ((HOST_WIDE_INT) 1 << (mode_width - 1)));
08474 HOST_WIDE_INT op1_maybe_minusp
08475 = (nz1 & ((HOST_WIDE_INT) 1 << (mode_width - 1)));
08476 unsigned int result_width = mode_width;
08477 int result_low = 0;
08478
08479 switch (code)
08480 {
08481 case PLUS:
08482 result_width = MAX (width0, width1) + 1;
08483 result_low = MIN (low0, low1);
08484 break;
08485 case MINUS:
08486 result_low = MIN (low0, low1);
08487 break;
08488 case MULT:
08489 result_width = width0 + width1;
08490 result_low = low0 + low1;
08491 break;
08492 case DIV:
08493 if (width1 == 0)
08494 break;
08495 if (! op0_maybe_minusp && ! op1_maybe_minusp)
08496 result_width = width0;
08497 break;
08498 case UDIV:
08499 if (width1 == 0)
08500 break;
08501 result_width = width0;
08502 break;
08503 case MOD:
08504 if (width1 == 0)
08505 break;
08506 if (! op0_maybe_minusp && ! op1_maybe_minusp)
08507 result_width = MIN (width0, width1);
08508 result_low = MIN (low0, low1);
08509 break;
08510 case UMOD:
08511 if (width1 == 0)
08512 break;
08513 result_width = MIN (width0, width1);
08514 result_low = MIN (low0, low1);
08515 break;
08516 default:
08517 abort ();
08518 }
08519
08520 if (result_width < mode_width)
08521 nonzero &= ((HOST_WIDE_INT) 1 << result_width) - 1;
08522
08523 if (result_low > 0)
08524 nonzero &= ~(((HOST_WIDE_INT) 1 << result_low) - 1);
08525
08526 #ifdef POINTERS_EXTEND_UNSIGNED
08527
08528
08529
08530 if (POINTERS_EXTEND_UNSIGNED > 0 && GET_MODE (x) == Pmode
08531 && (code == PLUS || code == MINUS)
08532 && GET_CODE (XEXP (x, 0)) == REG && REG_POINTER (XEXP (x, 0)))
08533 nonzero &= GET_MODE_MASK (ptr_mode);
08534 #endif
08535 }
08536 break;
08537
08538 case ZERO_EXTRACT:
08539 if (GET_CODE (XEXP (x, 1)) == CONST_INT
08540 && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
08541 nonzero &= ((HOST_WIDE_INT) 1 << INTVAL (XEXP (x, 1))) - 1;
08542 break;
08543
08544 case SUBREG:
08545
08546
08547
08548
08549 if (SUBREG_PROMOTED_VAR_P (x) && SUBREG_PROMOTED_UNSIGNED_P (x) > 0)
08550 nonzero = (GET_MODE_MASK (GET_MODE (x))
08551 & nonzero_bits_with_known (SUBREG_REG (x), GET_MODE (x)));
08552
08553
08554
08555
08556 if (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) <= BITS_PER_WORD
08557 && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
08558 <= HOST_BITS_PER_WIDE_INT))
08559 {
08560 nonzero &= nonzero_bits_with_known (SUBREG_REG (x), mode);
08561
08562 #if defined (WORD_REGISTER_OPERATIONS) && defined (LOAD_EXTEND_OP)
08563
08564
08565 if ((LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND
08566 ? (((nonzero
08567 & (((unsigned HOST_WIDE_INT) 1
08568 << (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) - 1))))
08569 != 0))
08570 : LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) != ZERO_EXTEND)
08571 || GET_CODE (SUBREG_REG (x)) != MEM)
08572 #endif
08573 {
08574
08575
08576
08577 if (GET_MODE_SIZE (GET_MODE (x))
08578 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
08579 nonzero |= (GET_MODE_MASK (GET_MODE (x))
08580 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x))));
08581 }
08582 }
08583 break;
08584
08585 case ASHIFTRT:
08586 case LSHIFTRT:
08587 case ASHIFT:
08588 case ROTATE:
08589
08590
08591
08592
08593
08594
08595 if (GET_CODE (XEXP (x, 1)) == CONST_INT
08596 && INTVAL (XEXP (x, 1)) >= 0
08597 && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
08598 {
08599 enum machine_mode inner_mode = GET_MODE (x);
08600 unsigned int width = GET_MODE_BITSIZE (inner_mode);
08601 int count = INTVAL (XEXP (x, 1));
08602 unsigned HOST_WIDE_INT mode_mask = GET_MODE_MASK (inner_mode);
08603 unsigned HOST_WIDE_INT op_nonzero =
08604 nonzero_bits_with_known (XEXP (x, 0), mode);
08605 unsigned HOST_WIDE_INT inner = op_nonzero & mode_mask;
08606 unsigned HOST_WIDE_INT outer = 0;
08607
08608 if (mode_width > width)
08609 outer = (op_nonzero & nonzero & ~mode_mask);
08610
08611 if (code == LSHIFTRT)
08612 inner >>= count;
08613 else if (code == ASHIFTRT)
08614 {
08615 inner >>= count;
08616
08617
08618
08619
08620 if (inner & ((HOST_WIDE_INT) 1 << (width - 1 - count)))
08621 inner |= (((HOST_WIDE_INT) 1 << count) - 1) << (width - count);
08622 }
08623 else if (code == ASHIFT)
08624 inner <<= count;
08625 else
08626 inner = ((inner << (count % width)
08627 | (inner >> (width - (count % width)))) & mode_mask);
08628
08629 nonzero &= (outer | inner);
08630 }
08631 break;
08632
08633 case FFS:
08634
08635 nonzero = ((HOST_WIDE_INT) 1 << (floor_log2 (mode_width) + 1)) - 1;
08636 break;
08637
08638 case IF_THEN_ELSE:
08639 nonzero &= (nonzero_bits_with_known (XEXP (x, 1), mode)
08640 | nonzero_bits_with_known (XEXP (x, 2), mode));
08641 break;
08642
08643 default:
08644 break;
08645 }
08646
08647 return nonzero;
08648 }
08649
08650
08651 #undef cached_num_sign_bit_copies
08652
08653 #define num_sign_bit_copies_with_known(X, M) \
08654 cached_num_sign_bit_copies (X, M, known_x, known_mode, known_ret)
08655
08656
08657
08658
08659
08660
08661 static unsigned int
08662 cached_num_sign_bit_copies (x, mode, known_x, known_mode, known_ret)
08663 rtx x;
08664 enum machine_mode mode;
08665 rtx known_x;
08666 enum machine_mode known_mode;
08667 unsigned int known_ret;
08668 {
08669 if (x == known_x && mode == known_mode)
08670 return known_ret;
08671
08672
08673
08674
08675
08676 if (GET_RTX_CLASS (GET_CODE (x)) == '2'
08677 || GET_RTX_CLASS (GET_CODE (x)) == 'c')
08678 {
08679 rtx x0 = XEXP (x, 0);
08680 rtx x1 = XEXP (x, 1);
08681
08682
08683 if (x0 == x1)
08684 return
08685 num_sign_bit_copies1 (x, mode, x0, mode,
08686 num_sign_bit_copies_with_known (x0, mode));
08687
08688
08689 if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
08690 || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
08691 && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
08692 return
08693 num_sign_bit_copies1 (x, mode, x1, mode,
08694 num_sign_bit_copies_with_known (x1, mode));
08695
08696 if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
08697 || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
08698 && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
08699 return
08700 num_sign_bit_copies1 (x, mode, x0, mode,
08701 num_sign_bit_copies_with_known (x0, mode));
08702 }
08703
08704 return num_sign_bit_copies1 (x, mode, known_x, known_mode, known_ret);
08705 }
08706
08707
08708
08709
08710
08711
08712 static unsigned int
08713 num_sign_bit_copies1 (x, mode, known_x, known_mode, known_ret)
08714 rtx x;
08715 enum machine_mode mode;
08716 rtx known_x;
08717 enum machine_mode known_mode;
08718 unsigned int known_ret;
08719 {
08720 enum rtx_code code = GET_CODE (x);
08721 unsigned int bitwidth;
08722 int num0, num1, result;
08723 unsigned HOST_WIDE_INT nonzero;
08724 rtx tem;
08725
08726
08727
08728
08729
08730 if (mode == VOIDmode)
08731 mode = GET_MODE (x);
08732
08733 if (mode == VOIDmode || FLOAT_MODE_P (mode) || FLOAT_MODE_P (GET_MODE (x)))
08734 return 1;
08735
08736 bitwidth = GET_MODE_BITSIZE (mode);
08737
08738
08739 if (bitwidth < GET_MODE_BITSIZE (GET_MODE (x)))
08740 {
08741 num0 = num_sign_bit_copies_with_known (x, GET_MODE (x));
08742 return MAX (1,
08743 num0 - (int) (GET_MODE_BITSIZE (GET_MODE (x)) - bitwidth));
08744 }
08745
08746 if (GET_MODE (x) != VOIDmode && bitwidth > GET_MODE_BITSIZE (GET_MODE (x)))
08747 {
08748 #ifndef WORD_REGISTER_OPERATIONS
08749
08750
08751
08752 return 1;
08753 #else
08754
08755
08756
08757 if (GET_MODE_BITSIZE (GET_MODE (x)) < BITS_PER_WORD
08758 #ifdef LOAD_EXTEND_OP
08759 && LOAD_EXTEND_OP (GET_MODE (x)) != SIGN_EXTEND
08760 #endif
08761 )
08762 return 1;
08763 #endif
08764 }
08765
08766 switch (code)
08767 {
08768 case REG:
08769
08770 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
08771
08772
08773 if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode && mode == Pmode
08774 && REG_POINTER (x))
08775 return GET_MODE_BITSIZE (Pmode) - GET_MODE_BITSIZE (ptr_mode) + 1;
08776 #endif
08777
08778 if (reg_last_set_value[REGNO (x)] != 0
08779 && reg_last_set_mode[REGNO (x)] == mode
08780 && (reg_last_set_label[REGNO (x)] == label_tick
08781 || (REGNO (x) >= FIRST_PSEUDO_REGISTER
08782 && REG_N_SETS (REGNO (x)) == 1
08783 && ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start,
08784 REGNO (x))))
08785 && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
08786 return reg_last_set_sign_bit_copies[REGNO (x)];
08787
08788 tem = get_last_value (x);
08789 if (tem != 0)
08790 return num_sign_bit_copies_with_known (tem, mode);
08791
08792 if (nonzero_sign_valid && reg_sign_bit_copies[REGNO (x)] != 0
08793 && GET_MODE_BITSIZE (GET_MODE (x)) == bitwidth)
08794 return reg_sign_bit_copies[REGNO (x)];
08795 break;
08796
08797 case MEM:
08798 #ifdef LOAD_EXTEND_OP
08799
08800 if (LOAD_EXTEND_OP (GET_MODE (x)) == SIGN_EXTEND)
08801 return MAX (1, ((int) bitwidth
08802 - (int) GET_MODE_BITSIZE (GET_MODE (x)) + 1));
08803 #endif
08804 break;
08805
08806 case CONST_INT:
08807
08808
08809 nonzero = INTVAL (x) & GET_MODE_MASK (mode);
08810 if (bitwidth <= HOST_BITS_PER_WIDE_INT
08811 && (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
08812 nonzero = (~nonzero) & GET_MODE_MASK (mode);
08813
08814 return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1);
08815
08816 case SUBREG:
08817
08818
08819
08820
08821 if (SUBREG_PROMOTED_VAR_P (x) && ! SUBREG_PROMOTED_UNSIGNED_P (x))
08822 {
08823 num0 = num_sign_bit_copies_with_known (SUBREG_REG (x), mode);
08824 return MAX ((int) bitwidth
08825 - (int) GET_MODE_BITSIZE (GET_MODE (x)) + 1,
08826 num0);
08827 }
08828
08829
08830 if (bitwidth <= GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))))
08831 {
08832 num0 = num_sign_bit_copies_with_known (SUBREG_REG (x), VOIDmode);
08833 return MAX (1, (num0
08834 - (int) (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
08835 - bitwidth)));
08836 }
08837
08838 #ifdef WORD_REGISTER_OPERATIONS
08839 #ifdef LOAD_EXTEND_OP
08840
08841
08842
08843
08844
08845
08846
08847
08848
08849
08850 if ((GET_MODE_SIZE (GET_MODE (x))
08851 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
08852 && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND
08853 && GET_CODE (SUBREG_REG (x)) == MEM)
08854 return num_sign_bit_copies_with_known (SUBREG_REG (x), mode);
08855 #endif
08856 #endif
08857 break;
08858
08859 case SIGN_EXTRACT:
08860 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
08861 return MAX (1, (int) bitwidth - INTVAL (XEXP (x, 1)));
08862 break;
08863
08864 case SIGN_EXTEND:
08865 return (bitwidth - GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
08866 + num_sign_bit_copies_with_known (XEXP (x, 0), VOIDmode));
08867
08868 case TRUNCATE:
08869
08870 num0 = num_sign_bit_copies_with_known (XEXP (x, 0), VOIDmode);
08871 return MAX (1, (num0 - (int) (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
08872 - bitwidth)));
08873
08874 case NOT:
08875 return num_sign_bit_copies_with_known (XEXP (x, 0), mode);
08876
08877 case ROTATE: case ROTATERT:
08878
08879
08880
08881 if (GET_CODE (XEXP (x, 1)) == CONST_INT
08882 && INTVAL (XEXP (x, 1)) >= 0
08883 && INTVAL (XEXP (x, 1)) < (int) bitwidth)
08884 {
08885 num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
08886 return MAX (1, num0 - (code == ROTATE ? INTVAL (XEXP (x, 1))
08887 : (int) bitwidth - INTVAL (XEXP (x, 1))));
08888 }
08889 break;
08890
08891 case NEG:
08892
08893
08894
08895
08896 num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
08897 if (bitwidth > HOST_BITS_PER_WIDE_INT)
08898 return num0 > 1 ? num0 - 1 : 1;
08899
08900 nonzero = nonzero_bits (XEXP (x, 0), mode);
08901 if (nonzero == 1)
08902 return bitwidth;
08903
08904 if (num0 > 1
08905 && (((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero))
08906 num0--;
08907
08908 return num0;
08909
08910 case IOR: case AND: case XOR:
08911 case SMIN: case SMAX: case UMIN: case UMAX:
08912
08913
08914 num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
08915 num1 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
08916 return MIN (num0, num1);
08917
08918 case PLUS: case MINUS:
08919
08920
08921
08922
08923
08924 if (code == PLUS && XEXP (x, 1) == constm1_rtx
08925 && bitwidth <= HOST_BITS_PER_WIDE_INT)
08926 {
08927 nonzero = nonzero_bits (XEXP (x, 0), mode);
08928 if ((((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero) == 0)
08929 return (nonzero == 1 || nonzero == 0 ? bitwidth
08930 : bitwidth - floor_log2 (nonzero) - 1);
08931 }
08932
08933 num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
08934 num1 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
08935 result = MAX (1, MIN (num0, num1) - 1);
08936
08937 #ifdef POINTERS_EXTEND_UNSIGNED
08938
08939
08940
08941 if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
08942 && (code == PLUS || code == MINUS)
08943 && GET_CODE (XEXP (x, 0)) == REG && REG_POINTER (XEXP (x, 0)))
08944 result = MAX ((int) (GET_MODE_BITSIZE (Pmode)
08945 - GET_MODE_BITSIZE (ptr_mode) + 1),
08946 result);
08947 #endif
08948 return result;
08949
08950 case MULT:
08951
08952
08953
08954
08955
08956 num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
08957 num1 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
08958
08959 result = bitwidth - (bitwidth - num0) - (bitwidth - num1);
08960 if (result > 0
08961 && (bitwidth > HOST_BITS_PER_WIDE_INT
08962 || (((nonzero_bits (XEXP (x, 0), mode)
08963 & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
08964 && ((nonzero_bits (XEXP (x, 1), mode)
08965 & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))))
08966 result--;
08967
08968 return MAX (1, result);
08969
08970 case UDIV:
08971
08972
08973
08974 if (bitwidth > HOST_BITS_PER_WIDE_INT)
08975 return 1;
08976 else if ((nonzero_bits (XEXP (x, 0), mode)
08977 & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
08978 return 1;
08979 else
08980 return num_sign_bit_copies_with_known (XEXP (x, 0), mode);
08981
08982 case UMOD:
08983
08984 return num_sign_bit_copies_with_known (XEXP (x, 1), mode);
08985
08986 case DIV:
08987
08988
08989
08990 result = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
08991 if (result > 1
08992 && (bitwidth > HOST_BITS_PER_WIDE_INT
08993 || (nonzero_bits (XEXP (x, 1), mode)
08994 & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
08995 result--;
08996
08997 return result;
08998
08999 case MOD:
09000 result = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
09001 if (result > 1
09002 && (bitwidth > HOST_BITS_PER_WIDE_INT
09003 || (nonzero_bits (XEXP (x, 1), mode)
09004 & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
09005 result--;
09006
09007 return result;
09008
09009 case ASHIFTRT:
09010
09011
09012 num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
09013 if (GET_CODE (XEXP (x, 1)) == CONST_INT
09014 && INTVAL (XEXP (x, 1)) > 0)
09015 num0 = MIN ((int) bitwidth, num0 + INTVAL (XEXP (x, 1)));
09016
09017 return num0;
09018
09019 case ASHIFT:
09020
09021 if (GET_CODE (XEXP (x, 1)) != CONST_INT
09022 || INTVAL (XEXP (x, 1)) < 0
09023 || INTVAL (XEXP (x, 1)) >= (int) bitwidth)
09024 return 1;
09025
09026 num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
09027 return MAX (1, num0 - INTVAL (XEXP (x, 1)));
09028
09029 case IF_THEN_ELSE:
09030 num0 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
09031 num1 = num_sign_bit_copies_with_known (XEXP (x, 2), mode);
09032 return MIN (num0, num1);
09033
09034 case EQ: case NE: case GE: case GT: case LE: case LT:
09035 case UNEQ: case LTGT: case UNGE: case UNGT: case UNLE: case UNLT:
09036 case GEU: case GTU: case LEU: case LTU:
09037 case UNORDERED: case ORDERED:
09038
09039
09040 nonzero = STORE_FLAG_VALUE;
09041 if (bitwidth <= HOST_BITS_PER_WIDE_INT
09042 && (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
09043 nonzero = (~nonzero) & GET_MODE_MASK (mode);
09044
09045 return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1);
09046 break;
09047
09048 default:
09049 break;
09050 }
09051
09052
09053
09054
09055
09056
09057 if (bitwidth > HOST_BITS_PER_WIDE_INT)
09058 return 1;
09059
09060 nonzero = nonzero_bits (x, mode);
09061 return (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))
09062 ? 1 : bitwidth - floor_log2 (nonzero) - 1);
09063 }
09064
09065
09066
09067
09068
09069
09070
09071
09072
09073
09074
09075
09076 unsigned int
09077 extended_count (x, mode, unsignedp)
09078 rtx x;
09079 enum machine_mode mode;
09080 int unsignedp;
09081 {
09082 if (nonzero_sign_valid == 0)
09083 return 0;
09084
09085 return (unsignedp
09086 ? (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
09087 ? (unsigned int) (GET_MODE_BITSIZE (mode) - 1
09088 - floor_log2 (nonzero_bits (x, mode)))
09089 : 0)
09090 : num_sign_bit_copies (x, mode) - 1);
09091 }
09092
09093
09094
09095
09096
09097
09098
09099
09100
09101
09102
09103
09104
09105
09106
09107
09108
09109
09110
09111
09112
09113
09114 static int
09115 merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p)
09116 enum rtx_code *pop0;
09117 HOST_WIDE_INT *pconst0;
09118 enum rtx_code op1;
09119 HOST_WIDE_INT const1;
09120 enum machine_mode mode;
09121 int *pcomp_p;
09122 {
09123 enum rtx_code op0 = *pop0;
09124 HOST_WIDE_INT const0 = *pconst0;
09125
09126 const0 &= GET_MODE_MASK (mode);
09127 const1 &= GET_MODE_MASK (mode);
09128
09129
09130 if (op0 == AND)
09131 const1 &= const0;
09132
09133
09134
09135
09136 if (op1 == NIL || op0 == SET)
09137 return 1;
09138
09139 else if (op0 == NIL)
09140 op0 = op1, const0 = const1;
09141
09142 else if (op0 == op1)
09143 {
09144 switch (op0)
09145 {
09146 case AND:
09147 const0 &= const1;
09148 break;
09149 case IOR:
09150 const0 |= const1;
09151 break;
09152 case XOR:
09153 const0 ^= const1;
09154 break;
09155 case PLUS:
09156 const0 += const1;
09157 break;
09158 case NEG:
09159 op0 = NIL;
09160 break;
09161 default:
09162 break;
09163 }
09164 }
09165
09166
09167 else if (op0 == PLUS || op1 == PLUS || op0 == NEG || op1 == NEG)
09168 return 0;
09169
09170
09171
09172 else if (const0 != const1)
09173 return 0;
09174
09175 else
09176 switch (op0)
09177 {
09178 case IOR:
09179 if (op1 == AND)
09180
09181 op0 = SET;
09182 else
09183
09184 {;}
09185 break;
09186
09187 case XOR:
09188 if (op1 == AND)
09189
09190 op0 = AND, *pcomp_p = 1;
09191 else
09192
09193 op0 = AND, *pconst0 = ~const0;
09194 break;
09195
09196 case AND:
09197 if (op1 == IOR)
09198
09199 op0 = SET;
09200 else
09201
09202 *pcomp_p = 1;
09203 break;
09204 default:
09205 break;
09206 }
09207
09208
09209 const0 &= GET_MODE_MASK (mode);
09210 if (const0 == 0
09211 && (op0 == IOR || op0 == XOR || op0 == PLUS))
09212 op0 = NIL;
09213 else if (const0 == 0 && op0 == AND)
09214 op0 = SET;
09215 else if ((unsigned HOST_WIDE_INT) const0 == GET_MODE_MASK (mode)
09216 && op0 == AND)
09217 op0 = NIL;
09218
09219
09220
09221
09222 const0 = trunc_int_for_mode (const0, mode);
09223
09224 *pop0 = op0;
09225 *pconst0 = const0;
09226
09227 return 1;
09228 }
09229
09230
09231
09232
09233
09234
09235
09236
09237
09238 static rtx
09239 simplify_shift_const (x, code, result_mode, varop, orig_count)
09240 rtx x;
09241 enum rtx_code code;
09242 enum machine_mode result_mode;
09243 rtx varop;
09244 int orig_count;
09245 {
09246 enum rtx_code orig_code = code;
09247 unsigned int count;
09248 int signed_count;
09249 enum machine_mode mode = result_mode;
09250 enum machine_mode shift_mode, tmode;
09251 unsigned int mode_words
09252 = (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
09253
09254 enum rtx_code outer_op = NIL;
09255 HOST_WIDE_INT outer_const = 0;
09256 rtx const_rtx;
09257 int complement_p = 0;
09258 rtx new;
09259
09260
09261
09262
09263 #ifdef SHIFT_COUNT_TRUNCATED
09264 if (SHIFT_COUNT_TRUNCATED)
09265 orig_count &= GET_MODE_BITSIZE (mode) - 1;
09266 #endif
09267
09268
09269
09270
09271 if (orig_count < 0 || orig_count >= (int) GET_MODE_BITSIZE (mode))
09272 {
09273 if (x)
09274 return x;
09275
09276 return gen_rtx_fmt_ee (code, mode, varop, GEN_INT (orig_count));
09277 }
09278
09279 count = orig_count;
09280
09281
09282
09283
09284 while (count != 0)
09285 {
09286
09287
09288 if (GET_CODE (varop) == CLOBBER)
09289 return varop;
09290
09291
09292
09293 if (complement_p)
09294 break;
09295
09296
09297 if (code == ROTATERT)
09298 {
09299 unsigned int bitsize = GET_MODE_BITSIZE (result_mode);;
09300 code = ROTATE;
09301 if (VECTOR_MODE_P (result_mode))
09302 count = bitsize / GET_MODE_NUNITS (result_mode) - count;
09303 else
09304 count = bitsize - count;
09305 }
09306
09307
09308
09309
09310
09311 shift_mode
09312 = (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE
09313 ? result_mode : mode);
09314
09315
09316
09317
09318
09319
09320
09321
09322
09323
09324
09325 if (count > (unsigned int) (GET_MODE_BITSIZE (shift_mode) - 1))
09326 {
09327 if (code == ASHIFTRT)
09328 count = GET_MODE_BITSIZE (shift_mode) - 1;
09329 else if (code == ROTATE || code == ROTATERT)
09330 count %= GET_MODE_BITSIZE (shift_mode);
09331 else
09332 {
09333
09334
09335 varop = const0_rtx;
09336 count = 0;
09337 break;
09338 }
09339 }
09340
09341
09342
09343 if (code == ASHIFTRT
09344 && (num_sign_bit_copies (varop, shift_mode)
09345 == GET_MODE_BITSIZE (shift_mode)))
09346 {
09347 count = 0;
09348 break;
09349 }
09350
09351
09352
09353
09354
09355
09356 if (code == ASHIFTRT
09357 && (count + num_sign_bit_copies (varop, shift_mode)
09358 >= GET_MODE_BITSIZE (shift_mode)))
09359 count = GET_MODE_BITSIZE (shift_mode) - 1;
09360
09361
09362
09363
09364
09365 if (GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT
09366 && code == ASHIFTRT
09367 && ((nonzero_bits (varop, shift_mode)
09368 & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (shift_mode) - 1)))
09369 == 0))
09370 code = LSHIFTRT;
09371
09372 switch (GET_CODE (varop))
09373 {
09374 case SIGN_EXTEND:
09375 case ZERO_EXTEND:
09376 case SIGN_EXTRACT:
09377 case ZERO_EXTRACT:
09378 new = expand_compound_operation (varop);
09379 if (new != varop)
09380 {
09381 varop = new;
09382 continue;
09383 }
09384 break;
09385
09386 case MEM:
09387
09388
09389
09390 if ((code == ASHIFTRT || code == LSHIFTRT)
09391 && ! mode_dependent_address_p (XEXP (varop, 0))
09392 && ! MEM_VOLATILE_P (varop)
09393 && (tmode = mode_for_size (GET_MODE_BITSIZE (mode) - count,
09394 MODE_INT, 1)) != BLKmode)
09395 {
09396 new = adjust_address_nv (varop, tmode,
09397 BYTES_BIG_ENDIAN ? 0
09398 : count / BITS_PER_UNIT);
09399
09400 varop = gen_rtx_fmt_e (code == ASHIFTRT ? SIGN_EXTEND
09401 : ZERO_EXTEND, mode, new);
09402 count = 0;
09403 continue;
09404 }
09405 break;
09406
09407 case USE:
09408
09409
09410
09411
09412 if ((code == ASHIFTRT || code == LSHIFTRT)
09413 && (tmode = mode_for_size (GET_MODE_BITSIZE (mode) - count,
09414 MODE_INT, 1)) != BLKmode
09415 && tmode == GET_MODE (XEXP (varop, 0)))
09416 {
09417 if (BITS_BIG_ENDIAN)
09418 new = XEXP (varop, 0);
09419 else
09420 {
09421 new = copy_rtx (XEXP (varop, 0));
09422 SUBST (XEXP (new, 0),
09423 plus_constant (XEXP (new, 0),
09424 count / BITS_PER_UNIT));
09425 }
09426
09427 varop = gen_rtx_fmt_e (code == ASHIFTRT ? SIGN_EXTEND
09428 : ZERO_EXTEND, mode, new);
09429 count = 0;
09430 continue;
09431 }
09432 break;
09433
09434 case SUBREG:
09435
09436
09437
09438 if (subreg_lowpart_p (varop)
09439 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (varop)))
09440 > GET_MODE_SIZE (GET_MODE (varop)))
09441 && (unsigned int) ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (varop)))
09442 + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
09443 == mode_words)
09444 {
09445 varop = SUBREG_REG (varop);
09446 if (GET_MODE_SIZE (GET_MODE (varop)) > GET_MODE_SIZE (mode))
09447 mode = GET_MODE (varop);
09448 continue;
09449 }
09450 break;
09451
09452 case MULT:
09453
09454
09455
09456 if (GET_CODE (XEXP (varop, 1)) == CONST_INT
09457 && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
09458 {
09459 varop
09460 = gen_binary (ASHIFT, GET_MODE (varop), XEXP (varop, 0),
09461 GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));
09462 continue;
09463 }
09464 break;
09465
09466 case UDIV:
09467
09468 if (GET_CODE (XEXP (varop, 1)) == CONST_INT
09469 && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
09470 {
09471 varop
09472 = gen_binary (LSHIFTRT, GET_MODE (varop), XEXP (varop, 0),
09473 GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));
09474 continue;
09475 }
09476 break;
09477
09478 case ASHIFTRT:
09479
09480
09481
09482
09483
09484 if (code == LSHIFTRT
09485 && count == (unsigned int) (GET_MODE_BITSIZE (result_mode) - 1)
09486 && (GET_MODE_BITSIZE (result_mode)
09487 >= GET_MODE_BITSIZE (GET_MODE (varop))))
09488 {
09489 varop = XEXP (varop, 0);
09490 continue;
09491 }
09492
09493
09494
09495 case LSHIFTRT:
09496 case ASHIFT:
09497 case ROTATE:
09498
09499
09500 if (GET_CODE (XEXP (varop, 1)) == CONST_INT
09501 && INTVAL (XEXP (varop, 1)) >= 0
09502 && INTVAL (XEXP (varop, 1)) < GET_MODE_BITSIZE (GET_MODE (varop))
09503 && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT
09504 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
09505 {
09506 enum rtx_code first_code = GET_CODE (varop);
09507 unsigned int first_count = INTVAL (XEXP (varop, 1));
09508 unsigned HOST_WIDE_INT mask;
09509 rtx mask_rtx;
09510
09511
09512
09513
09514
09515
09516
09517
09518 if (code == ASHIFT && first_code == ASHIFTRT
09519 && count == (unsigned int)
09520 (GET_MODE_BITSIZE (result_mode)
09521 - GET_MODE_BITSIZE (GET_MODE (varop))))
09522 {
09523
09524
09525 mask = (GET_MODE_MASK (mode)
09526 & ~(((HOST_WIDE_INT) 1 << first_count) - 1));
09527
09528 varop = simplify_and_const_int (NULL_RTX, result_mode,
09529 XEXP (varop, 0), mask);
09530 varop = simplify_shift_const (NULL_RTX, ASHIFT, result_mode,
09531 varop, count);
09532 count = first_count;
09533 code = ASHIFTRT;
09534 continue;
09535 }
09536
09537
09538
09539
09540
09541
09542
09543
09544 if (code == ASHIFTRT && first_code == ASHIFT
09545 && GET_MODE (varop) == shift_mode
09546 && (num_sign_bit_copies (XEXP (varop, 0), shift_mode)
09547 > first_count))
09548 {
09549 varop = XEXP (varop, 0);
09550
09551 signed_count = count - first_count;
09552 if (signed_count < 0)
09553 count = -signed_count, code = ASHIFT;
09554 else
09555 count = signed_count;
09556
09557 continue;
09558 }
09559
09560
09561
09562
09563
09564
09565
09566
09567
09568
09569
09570
09571
09572
09573
09574
09575 if (code == first_code)
09576 {
09577 if (GET_MODE (varop) != result_mode
09578 && (code == ASHIFTRT || code == LSHIFTRT
09579 || code == ROTATE))
09580 break;
09581
09582 count += first_count;
09583 varop = XEXP (varop, 0);
09584 continue;
09585 }
09586
09587 if (code == ASHIFTRT
09588 || (code == ROTATE && first_code == ASHIFTRT)
09589 || GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT
09590 || (GET_MODE (varop) != result_mode
09591 && (first_code == ASHIFTRT || first_code == LSHIFTRT
09592 || first_code == ROTATE
09593 || code == ROTATE)))
09594 break;
09595
09596
09597
09598
09599
09600 mask_rtx = GEN_INT (nonzero_bits (varop, GET_MODE (varop)));
09601
09602 mask_rtx
09603 = simplify_binary_operation (code, result_mode, mask_rtx,
09604 GEN_INT (count));
09605
09606
09607 if (mask_rtx == 0
09608 || GET_CODE (mask_rtx) != CONST_INT
09609 || ! merge_outer_ops (&outer_op, &outer_const, AND,
09610 INTVAL (mask_rtx),
09611 result_mode, &complement_p))
09612 break;
09613
09614
09615
09616 signed_count = count;
09617 if ((code == ASHIFTRT || code == LSHIFTRT)
09618 == (first_code == ASHIFTRT || first_code == LSHIFTRT))
09619 signed_count += first_count;
09620 else
09621 signed_count -= first_count;
09622
09623
09624
09625
09626
09627 if (signed_count > 0
09628 && ((first_code == ROTATE && code == ASHIFT)
09629 || (first_code == ASHIFTRT && code == LSHIFTRT)))
09630 code = first_code, count = signed_count;
09631 else if (signed_count < 0)
09632 code = first_code, count = -signed_count;
09633 else
09634 count = signed_count;
09635
09636 varop = XEXP (varop, 0);
09637 continue;
09638 }
09639
09640
09641
09642
09643
09644 else if (GET_CODE (varop) == code
09645 && GET_CODE (XEXP (varop, 1)) != CONST_INT
09646 && 0 != (new
09647 = simplify_binary_operation (code, mode,
09648 XEXP (varop, 0),
09649 GEN_INT (count))))
09650 {
09651 varop = gen_rtx_fmt_ee (code, mode, new, XEXP (varop, 1));
09652 count = 0;
09653 continue;
09654 }
09655 break;
09656
09657 case NOT:
09658
09659 varop = gen_rtx_XOR (mode, XEXP (varop, 0),
09660 GEN_INT (GET_MODE_MASK (mode)));
09661 continue;
09662
09663 case IOR:
09664 case AND:
09665 case XOR:
09666
09667
09668
09669
09670
09671
09672
09673 if (GET_CODE (varop) == IOR && GET_CODE (XEXP (varop, 0)) == PLUS
09674 && XEXP (XEXP (varop, 0), 1) == constm1_rtx
09675 && (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
09676 && (code == LSHIFTRT || code == ASHIFTRT)
09677 && count == (unsigned int)
09678 (GET_MODE_BITSIZE (GET_MODE (varop)) - 1)
09679 && rtx_equal_p (XEXP (XEXP (varop, 0), 0), XEXP (varop, 1)))
09680 {
09681 count = 0;
09682 varop = gen_rtx_LE (GET_MODE (varop), XEXP (varop, 1),
09683 const0_rtx);
09684
09685 if (STORE_FLAG_VALUE == 1 ? code == ASHIFTRT : code == LSHIFTRT)
09686 varop = gen_rtx_NEG (GET_MODE (varop), varop);
09687
09688 continue;
09689 }
09690
09691
09692
09693
09694
09695
09696
09697 if (GET_CODE (XEXP (varop, 1)) == CONST_INT
09698 && (new = simplify_binary_operation (code, result_mode,
09699 XEXP (varop, 1),
09700 GEN_INT (count))) != 0
09701 && GET_CODE (new) == CONST_INT
09702 && merge_outer_ops (&outer_op, &outer_const, GET_CODE (varop),
09703 INTVAL (new), result_mode, &complement_p))
09704 {
09705 varop = XEXP (varop, 0);
09706 continue;
09707 }
09708
09709
09710
09711
09712 {
09713 rtx lhs = simplify_shift_const (NULL_RTX, code, shift_mode,
09714 XEXP (varop, 0), count);
09715 rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode,
09716 XEXP (varop, 1), count);
09717
09718 varop = gen_binary (GET_CODE (varop), shift_mode, lhs, rhs);
09719 varop = apply_distributive_law (varop);
09720
09721 count = 0;
09722 }
09723 break;
09724
09725 case EQ:
09726
09727
09728
09729
09730 if (code == LSHIFTRT
09731 && XEXP (varop, 1) == const0_rtx
09732 && GET_MODE (XEXP (varop, 0)) == result_mode
09733 && count == (unsigned int) (GET_MODE_BITSIZE (result_mode) - 1)
09734 && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT
09735 && ((STORE_FLAG_VALUE
09736 & ((HOST_WIDE_INT) 1
09737 < (GET_MODE_BITSIZE (result_mode) - 1))))
09738 && nonzero_bits (XEXP (varop, 0), result_mode) == 1
09739 && merge_outer_ops (&outer_op, &outer_const, XOR,
09740 (HOST_WIDE_INT) 1, result_mode,
09741 &complement_p))
09742 {
09743 varop = XEXP (varop, 0);
09744 count = 0;
09745 continue;
09746 }
09747 break;
09748
09749 case NEG:
09750
09751
09752 if (code == LSHIFTRT
09753 && count == (unsigned int) (GET_MODE_BITSIZE (result_mode) - 1)
09754 && nonzero_bits (XEXP (varop, 0), result_mode) == 1)
09755 {
09756 varop = XEXP (varop, 0);
09757 count = 0;
09758 continue;
09759 }
09760
09761
09762
09763 if (code == ASHIFT
09764 && merge_outer_ops (&outer_op, &outer_const, NEG,
09765 (HOST_WIDE_INT) 0, result_mode,
09766 &complement_p))
09767 {
09768 varop = XEXP (varop, 0);
09769 continue;
09770 }
09771 break;
09772
09773 case PLUS:
09774
09775
09776
09777 if (code == LSHIFTRT
09778 && count == (unsigned int) (GET_MODE_BITSIZE (result_mode) - 1)
09779 && XEXP (varop, 1) == constm1_rtx
09780 && nonzero_bits (XEXP (varop, 0), result_mode) == 1
09781 && merge_outer_ops (&outer_op, &outer_const, XOR,
09782 (HOST_WIDE_INT) 1, result_mode,
09783 &complement_p))
09784 {
09785 count = 0;
09786 varop = XEXP (varop, 0);
09787 continue;
09788 }
09789
09790
09791
09792
09793
09794
09795
09796 if ((code == ASHIFTRT || code == LSHIFTRT)
09797 && count < HOST_BITS_PER_WIDE_INT
09798 && nonzero_bits (XEXP (varop, 1), result_mode) >> count == 0
09799 && (nonzero_bits (XEXP (varop, 1), result_mode)
09800 & nonzero_bits (XEXP (varop, 0), result_mode)) == 0)
09801 {
09802 varop = XEXP (varop, 0);
09803 continue;
09804 }
09805 else if ((code == ASHIFTRT || code == LSHIFTRT)
09806 && count < HOST_BITS_PER_WIDE_INT
09807 && GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT
09808 && 0 == (nonzero_bits (XEXP (varop, 0), result_mode)
09809 >> count)
09810 && 0 == (nonzero_bits (XEXP (varop, 0), result_mode)
09811 & nonzero_bits (XEXP (varop, 1),
09812 result_mode)))
09813 {
09814 varop = XEXP (varop, 1);
09815 continue;
09816 }
09817
09818
09819 if (code == ASHIFT
09820 && GET_CODE (XEXP (varop, 1)) == CONST_INT
09821 && (new = simplify_binary_operation (ASHIFT, result_mode,
09822 XEXP (varop, 1),
09823 GEN_INT (count))) != 0
09824 && GET_CODE (new) == CONST_INT
09825 && merge_outer_ops (&outer_op, &outer_const, PLUS,
09826 INTVAL (new), result_mode, &complement_p))
09827 {
09828 varop = XEXP (varop, 0);
09829 continue;
09830 }
09831 break;
09832
09833 case MINUS:
09834
09835
09836
09837
09838
09839
09840
09841 if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
09842 && GET_CODE (XEXP (varop, 0)) == ASHIFTRT
09843 && count == (unsigned int)
09844 (GET_MODE_BITSIZE (GET_MODE (varop)) - 1)
09845 && (code == LSHIFTRT || code == ASHIFTRT)
09846 && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT
09847 && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (varop, 0), 1))
09848 == count
09849 && rtx_equal_p (XEXP (XEXP (varop, 0), 0), XEXP (varop, 1)))
09850 {
09851 count = 0;
09852 varop = gen_rtx_GT (GET_MODE (varop), XEXP (varop, 1),
09853 const0_rtx);
09854
09855 if (STORE_FLAG_VALUE == 1 ? code == ASHIFTRT : code == LSHIFTRT)
09856 varop = gen_rtx_NEG (GET_MODE (varop), varop);
09857
09858 continue;
09859 }
09860 break;
09861
09862 case TRUNCATE:
09863
09864
09865 if (code == LSHIFTRT
09866 && GET_CODE (XEXP (varop, 0)) == LSHIFTRT
09867 && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT
09868 && (INTVAL (XEXP (XEXP (varop, 0), 1))
09869 >= (GET_MODE_BITSIZE (GET_MODE (XEXP (varop, 0)))
09870 - GET_MODE_BITSIZE (GET_MODE (varop)))))
09871 {
09872 rtx varop_inner = XEXP (varop, 0);
09873
09874 varop_inner
09875 = gen_rtx_LSHIFTRT (GET_MODE (varop_inner),
09876 XEXP (varop_inner, 0),
09877 GEN_INT
09878 (count + INTVAL (XEXP (varop_inner, 1))));
09879 varop = gen_rtx_TRUNCATE (GET_MODE (varop), varop_inner);
09880 count = 0;
09881 continue;
09882 }
09883 break;
09884
09885 default:
09886 break;
09887 }
09888
09889 break;
09890 }
09891
09892
09893
09894
09895
09896
09897 shift_mode
09898 = (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE
09899 ? result_mode : mode);
09900
09901
09902
09903
09904
09905
09906
09907
09908
09909
09910 if (x && GET_RTX_CLASS (GET_CODE (x)) == '2'
09911 && GET_CODE (XEXP (x, 1)) == CONST_INT
09912 && (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) == count)
09913 const_rtx = XEXP (x, 1);
09914 else
09915 const_rtx = GEN_INT (count);
09916
09917 if (x && GET_CODE (XEXP (x, 0)) == SUBREG
09918 && GET_MODE (XEXP (x, 0)) == shift_mode
09919 && SUBREG_REG (XEXP (x, 0)) == varop)
09920 varop = XEXP (x, 0);
09921 else if (GET_MODE (varop) != shift_mode)
09922 varop = gen_lowpart_for_combine (shift_mode, varop);
09923
09924
09925 if (GET_CODE (varop) == CLOBBER)
09926 return x ? x : varop;
09927
09928 new = simplify_binary_operation (code, shift_mode, varop, const_rtx);
09929 if (new != 0)
09930 x = new;
09931 else
09932 x = gen_rtx_fmt_ee (code, shift_mode, varop, const_rtx);
09933
09934
09935
09936
09937
09938
09939 if (outer_op != NIL && GET_CODE (x) == code
09940 && GET_CODE (XEXP (x, 1)) == CONST_INT)
09941 x = simplify_shift_const (x, code, shift_mode, XEXP (x, 0),
09942 INTVAL (XEXP (x, 1)));
09943
09944
09945
09946 if (orig_code == LSHIFTRT && result_mode != shift_mode)
09947 x = simplify_and_const_int (NULL_RTX, shift_mode, x,
09948 GET_MODE_MASK (result_mode) >> orig_count);
09949
09950
09951 x = gen_lowpart_for_combine (result_mode, x);
09952
09953
09954
09955 if (complement_p)
09956 x =simplify_gen_unary (NOT, result_mode, x, result_mode);
09957
09958 if (outer_op != NIL)
09959 {
09960 if (GET_MODE_BITSIZE (result_mode) < HOST_BITS_PER_WIDE_INT)
09961 outer_const = trunc_int_for_mode (outer_const, result_mode);
09962
09963 if (outer_op == AND)
09964 x = simplify_and_const_int (NULL_RTX, result_mode, x, outer_const);
09965 else if (outer_op == SET)
09966
09967
09968 x = GEN_INT (outer_const);
09969 else if (GET_RTX_CLASS (outer_op) == '1')
09970 x = simplify_gen_unary (outer_op, result_mode, x, result_mode);
09971 else
09972 x = gen_binary (outer_op, result_mode, x, GEN_INT (outer_const));
09973 }
09974
09975 return x;
09976 }
09977
09978
09979
09980
09981
09982
09983
09984
09985
09986
09987
09988
09989
09990
09991 static int
09992 recog_for_combine (pnewpat, insn, pnotes)
09993 rtx *pnewpat;
09994 rtx insn;
09995 rtx *pnotes;
09996 {
09997 rtx pat = *pnewpat;
09998 int insn_code_number;
09999 int num_clobbers_to_add = 0;
10000 int i;
10001 rtx notes = 0;
10002 rtx dummy_insn;
10003
10004
10005
10006
10007 if (GET_CODE (pat) == PARALLEL)
10008 for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
10009 if (GET_CODE (XVECEXP (pat, 0, i)) == CLOBBER
10010 && XEXP (XVECEXP (pat, 0, i), 0) == const0_rtx)
10011 return -1;
10012
10013
10014
10015 dummy_insn = shallow_copy_rtx (insn);
10016 PATTERN (dummy_insn) = pat;
10017 REG_NOTES (dummy_insn) = 0;
10018
10019 insn_code_number = recog (pat, dummy_insn, &num_clobbers_to_add);
10020
10021
10022
10023
10024
10025
10026 if (insn_code_number < 0 && ! check_asm_operands (pat)
10027 && GET_CODE (pat) == PARALLEL)
10028 {
10029 int pos;
10030
10031 for (pos = 0, i = 0; i < XVECLEN (pat, 0); i++)
10032 if (GET_CODE (XVECEXP (pat, 0, i)) != CLOBBER)
10033 {
10034 if (i != pos)
10035 SUBST (XVECEXP (pat, 0, pos), XVECEXP (pat, 0, i));
10036 pos++;
10037 }
10038
10039 SUBST_INT (XVECLEN (pat, 0), pos);
10040
10041 if (pos == 1)
10042 pat = XVECEXP (pat, 0, 0);
10043
10044 PATTERN (dummy_insn) = pat;
10045 insn_code_number = recog (pat, dummy_insn, &num_clobbers_to_add);
10046 }
10047
10048
10049 if (insn_code_number < 0 && GET_CODE (pat) == SET && set_noop_p (pat))
10050 insn_code_number = NOOP_MOVE_INSN_CODE, num_clobbers_to_add = 0;
10051
10052
10053
10054 if (num_clobbers_to_add)
10055 {
10056 rtx newpat = gen_rtx_PARALLEL (VOIDmode,
10057 rtvec_alloc (GET_CODE (pat) == PARALLEL
10058 ? (XVECLEN (pat, 0)
10059 + num_clobbers_to_add)
10060 : num_clobbers_to_add + 1));
10061
10062 if (GET_CODE (pat) == PARALLEL)
10063 for (i = 0; i < XVECLEN (pat, 0); i++)
10064 XVECEXP (newpat, 0, i) = XVECEXP (pat, 0, i);
10065 else
10066 XVECEXP (newpat, 0, 0) = pat;
10067
10068 add_clobbers (newpat, insn_code_number);
10069
10070 for (i = XVECLEN (newpat, 0) - num_clobbers_to_add;
10071 i < XVECLEN (newpat, 0); i++)
10072 {
10073 if (GET_CODE (XEXP (XVECEXP (newpat, 0, i), 0)) == REG
10074 && ! reg_dead_at_p (XEXP (XVECEXP (newpat, 0, i), 0), insn))
10075 return -1;
10076 notes = gen_rtx_EXPR_LIST (REG_UNUSED,
10077 XEXP (XVECEXP (newpat, 0, i), 0), notes);
10078 }
10079 pat = newpat;
10080 }
10081
10082 *pnewpat = pat;
10083 *pnotes = notes;
10084
10085 return insn_code_number;
10086 }
10087
10088
10089
10090
10091
10092
10093
10094
10095
10096
10097 #undef gen_lowpart
10098
10099 static rtx
10100 gen_lowpart_for_combine (mode, x)
10101 enum machine_mode mode;
10102 rtx x;
10103 {
10104 rtx result;
10105
10106 if (GET_MODE (x) == mode)
10107 return x;
10108
10109
10110
10111
10112 if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
10113 && ! ((GET_MODE (x) == VOIDmode
10114 && (GET_CODE (x) == CONST_INT
10115 || GET_CODE (x) == CONST_DOUBLE))
10116 || GET_MODE_SIZE (GET_MODE (x)) == GET_MODE_SIZE (mode)))
10117 return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
10118
10119
10120
10121
10122 if (GET_CODE (x) == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM)
10123 {
10124 x = SUBREG_REG (x);
10125 if (GET_MODE (x) == mode)
10126 return x;
10127 }
10128
10129 result = gen_lowpart_common (mode, x);
10130 #ifdef CANNOT_CHANGE_MODE_CLASS
10131 if (result != 0
10132 && GET_CODE (result) == SUBREG
10133 && GET_CODE (SUBREG_REG (result)) == REG
10134 && REGNO (SUBREG_REG (result)) >= FIRST_PSEUDO_REGISTER)
10135 bitmap_set_bit (&subregs_of_mode, REGNO (SUBREG_REG (result))
10136 * MAX_MACHINE_MODE
10137 + GET_MODE (result));
10138 #endif
10139
10140 if (result)
10141 return result;
10142
10143 if (GET_CODE (x) == MEM)
10144 {
10145 int offset = 0;
10146
10147
10148
10149 if (MEM_VOLATILE_P (x) || mode_dependent_address_p (XEXP (x, 0)))
10150 return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
10151
10152
10153
10154
10155 if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode))
10156 return gen_rtx_SUBREG (mode, x, 0);
10157
10158 if (WORDS_BIG_ENDIAN)
10159 offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
10160 - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
10161
10162 if (BYTES_BIG_ENDIAN)
10163 {
10164
10165
10166 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
10167 - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
10168 }
10169
10170 return adjust_address_nv (x, mode, offset);
10171 }
10172
10173
10174
10175 else if (GET_RTX_CLASS (GET_CODE (x)) == '<')
10176 return gen_rtx_fmt_ee (GET_CODE (x), mode, XEXP (x, 0), XEXP (x, 1));
10177
10178
10179
10180
10181 else
10182 {
10183 int offset = 0;
10184 rtx res;
10185 enum machine_mode sub_mode = GET_MODE (x);
10186
10187 offset = subreg_lowpart_offset (mode, sub_mode);
10188 if (sub_mode == VOIDmode)
10189 {
10190 sub_mode = int_mode_for_mode (mode);
10191 x = gen_lowpart_common (sub_mode, x);
10192 }
10193 res = simplify_gen_subreg (mode, x, sub_mode, offset);
10194 if (res)
10195 return res;
10196 return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
10197 }
10198 }
10199
10200
10201
10202
10203 static rtx
10204 gen_binary (code, mode, op0, op1)
10205 enum rtx_code code;
10206 enum machine_mode mode;
10207 rtx op0, op1;
10208 {
10209 rtx result;
10210 rtx tem;
10211
10212 if (GET_CODE (op0) == CLOBBER)
10213 return op0;
10214 else if (GET_CODE (op1) == CLOBBER)
10215 return op1;
10216
10217 if (GET_RTX_CLASS (code) == 'c'
10218 && swap_commutative_operands_p (op0, op1))
10219 tem = op0, op0 = op1, op1 = tem;
10220
10221 if (GET_RTX_CLASS (code) == '<')
10222 {
10223 enum machine_mode op_mode = GET_MODE (op0);
10224
10225
10226
10227 if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
10228 {
10229 op1 = XEXP (op0, 1);
10230 op0 = XEXP (op0, 0);
10231 op_mode = GET_MODE (op0);
10232 }
10233
10234 if (op_mode == VOIDmode)
10235 op_mode = GET_MODE (op1);
10236 result = simplify_relational_operation (code, op_mode, op0, op1);
10237 }
10238 else
10239 result = simplify_binary_operation (code, mode, op0, op1);
10240
10241 if (result)
10242 return result;
10243
10244
10245 if (GET_RTX_CLASS (code) == 'c'
10246 && swap_commutative_operands_p (op0, op1))
10247 return gen_rtx_fmt_ee (code, mode, op1, op0);
10248
10249
10250
10251 else if (code == AND && GET_CODE (op1) == CONST_INT
10252 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
10253 && (nonzero_bits (op0, mode) & ~INTVAL (op1)) == 0)
10254 return op0;
10255
10256 return gen_rtx_fmt_ee (code, mode, op0, op1);
10257 }
10258
10259
10260
10261
10262
10263
10264
10265
10266
10267
10268
10269
10270 static enum rtx_code
10271 simplify_comparison (code, pop0, pop1)
10272 enum rtx_code code;
10273 rtx *pop0;
10274 rtx *pop1;
10275 {
10276 rtx op0 = *pop0;
10277 rtx op1 = *pop1;
10278 rtx tem, tem1;
10279 int i;
10280 enum machine_mode mode, tmode;
10281
10282
10283 while (1)
10284 {
10285 #ifndef WORD_REGISTER_OPERATIONS
10286
10287
10288 if (code != GTU && code != GEU && code != LTU && code != LEU
10289 && GET_CODE (op0) == ASHIFTRT && GET_CODE (op1) == ASHIFTRT
10290 && GET_CODE (XEXP (op0, 0)) == ASHIFT
10291 && GET_CODE (XEXP (op1, 0)) == ASHIFT
10292 && GET_CODE (XEXP (XEXP (op0, 0), 0)) == SUBREG
10293 && GET_CODE (XEXP (XEXP (op1, 0), 0)) == SUBREG
10294 && (GET_MODE (SUBREG_REG (XEXP (XEXP (op0, 0), 0)))
10295 == GET_MODE (SUBREG_REG (XEXP (XEXP (op1, 0), 0))))
10296 && GET_CODE (XEXP (op0, 1)) == CONST_INT
10297 && GET_CODE (XEXP (op1, 1)) == CONST_INT
10298 && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
10299 && GET_CODE (XEXP (XEXP (op1, 0), 1)) == CONST_INT
10300 && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (op1, 1))
10301 && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (XEXP (op0, 0), 1))
10302 && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (XEXP (op1, 0), 1))
10303 && (INTVAL (XEXP (op0, 1))
10304 == (GET_MODE_BITSIZE (GET_MODE (op0))
10305 - (GET_MODE_BITSIZE
10306 (GET_MODE (SUBREG_REG (XEXP (XEXP (op0, 0), 0))))))))
10307 {
10308 op0 = SUBREG_REG (XEXP (XEXP (op0, 0), 0));
10309 op1 = SUBREG_REG (XEXP (XEXP (op1, 0), 0));
10310 }
10311 #endif
10312
10313
10314
10315
10316
10317 if (GET_CODE (op0) == GET_CODE (op1)
10318 && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT
10319 && ((GET_CODE (op0) == ROTATE && (code == NE || code == EQ))
10320 || ((GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFT)
10321 && (code != GT && code != LT && code != GE && code != LE))
10322 || (GET_CODE (op0) == ASHIFTRT
10323 && (code != GTU && code != LTU
10324 && code != GEU && code != LEU)))
10325 && GET_CODE (XEXP (op0, 1)) == CONST_INT
10326 && INTVAL (XEXP (op0, 1)) >= 0
10327 && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT
10328 && XEXP (op0, 1) == XEXP (op1, 1))
10329 {
10330 enum machine_mode mode = GET_MODE (op0);
10331 unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
10332 int shift_count = INTVAL (XEXP (op0, 1));
10333
10334 if (GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFTRT)
10335 mask &= (mask >> shift_count) << shift_count;
10336 else if (GET_CODE (op0) == ASHIFT)
10337 mask = (mask & (mask << shift_count)) >> shift_count;
10338
10339 if ((nonzero_bits (XEXP (op0, 0), mode) & ~mask) == 0
10340 && (nonzero_bits (XEXP (op1, 0), mode) & ~mask) == 0)
10341 op0 = XEXP (op0, 0), op1 = XEXP (op1, 0);
10342 else
10343 break;
10344 }
10345
10346
10347
10348
10349
10350
10351
10352
10353
10354
10355
10356
10357
10358
10359 else if (GET_CODE (op0) == AND && GET_CODE (op1) == AND
10360 && GET_CODE (XEXP (op0, 1)) == CONST_INT
10361 && GET_CODE (XEXP (op1, 1)) == CONST_INT)
10362 {
10363 rtx inner_op0 = XEXP (op0, 0);
10364 rtx inner_op1 = XEXP (op1, 0);
10365 HOST_WIDE_INT c0 = INTVAL (XEXP (op0, 1));
10366 HOST_WIDE_INT c1 = INTVAL (XEXP (op1, 1));
10367 int changed = 0;
10368
10369 if (GET_CODE (inner_op0) == SUBREG && GET_CODE (inner_op1) == SUBREG
10370 && (GET_MODE_SIZE (GET_MODE (inner_op0))
10371 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner_op0))))
10372 && (GET_MODE (SUBREG_REG (inner_op0))
10373 == GET_MODE (SUBREG_REG (inner_op1)))
10374 && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (inner_op0)))
10375 <= HOST_BITS_PER_WIDE_INT)
10376 && (0 == ((~c0) & nonzero_bits (SUBREG_REG (inner_op0),
10377 GET_MODE (SUBREG_REG (inner_op0)))))
10378 && (0 == ((~c1) & nonzero_bits (SUBREG_REG (inner_op1),
10379 GET_MODE (SUBREG_REG (inner_op1))))))
10380 {
10381 op0 = SUBREG_REG (inner_op0);
10382 op1 = SUBREG_REG (inner_op1);
10383
10384
10385
10386 code = unsigned_condition (code);
10387
10388 changed = 1;
10389 }
10390
10391 else if (c0 == c1)
10392 for (tmode = GET_CLASS_NARROWEST_MODE
10393 (GET_MODE_CLASS (GET_MODE (op0)));
10394 tmode != GET_MODE (op0); tmode = GET_MODE_WIDER_MODE (tmode))
10395 if ((unsigned HOST_WIDE_INT) c0 == GET_MODE_MASK (tmode))
10396 {
10397 op0 = gen_lowpart_for_combine (tmode, inner_op0);
10398 op1 = gen_lowpart_for_combine (tmode, inner_op1);
10399 code = unsigned_condition (code);
10400 changed = 1;
10401 break;
10402 }
10403
10404 if (! changed)
10405 break;
10406 }
10407
10408
10409
10410
10411 else if ((GET_CODE (op0) == NOT && GET_CODE (op1) == NOT)
10412 || (GET_CODE (op0) == NEG && GET_CODE (op1) == NEG
10413 && (code == EQ || code == NE)))
10414 op0 = XEXP (op0, 0), op1 = XEXP (op1, 0), code = swap_condition (code);
10415
10416 else
10417 break;
10418 }
10419
10420
10421
10422
10423 if (swap_commutative_operands_p (op0, op1))
10424 {
10425 tem = op0, op0 = op1, op1 = tem;
10426 code = swap_condition (code);
10427 }
10428
10429
10430
10431
10432
10433
10434 while (GET_CODE (op1) == CONST_INT)
10435 {
10436 enum machine_mode mode = GET_MODE (op0);
10437 unsigned int mode_width = GET_MODE_BITSIZE (mode);
10438 unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
10439 int equality_comparison_p;
10440 int sign_bit_comparison_p;
10441 int unsigned_comparison_p;
10442 HOST_WIDE_INT const_op;
10443
10444
10445
10446
10447
10448
10449 if (GET_MODE_CLASS (mode) != MODE_INT
10450 && ! (mode == VOIDmode
10451 && (GET_CODE (op0) == COMPARE
10452 || GET_RTX_CLASS (GET_CODE (op0)) == '<')))
10453 break;
10454
10455
10456
10457 const_op = INTVAL (op1);
10458 if (mode != VOIDmode)
10459 const_op = trunc_int_for_mode (const_op, mode);
10460 op1 = GEN_INT (const_op);
10461
10462
10463
10464
10465
10466 if (const_op
10467 && (code == EQ || code == NE || code == GE || code == GEU
10468 || code == LT || code == LTU)
10469 && mode_width <= HOST_BITS_PER_WIDE_INT
10470 && exact_log2 (const_op) >= 0
10471 && nonzero_bits (op0, mode) == (unsigned HOST_WIDE_INT) const_op)
10472 {
10473 code = (code == EQ || code == GE || code == GEU ? NE : EQ);
10474 op1 = const0_rtx, const_op = 0;
10475 }
10476
10477
10478
10479
10480 if (const_op == -1
10481 && (code == EQ || code == NE || code == GT || code == LE
10482 || code == GEU || code == LTU)
10483 && num_sign_bit_copies (op0, mode) == mode_width)
10484 {
10485 code = (code == EQ || code == LE || code == GEU ? NE : EQ);
10486 op1 = const0_rtx, const_op = 0;
10487 }
10488
10489
10490
10491
10492
10493 switch (code)
10494 {
10495 case LT:
10496
10497 if (const_op > 0)
10498 {
10499 const_op -= 1;
10500 op1 = GEN_INT (const_op);
10501 code = LE;
10502
10503 }
10504 else
10505 break;
10506
10507 case LE:
10508
10509 if (const_op < 0)
10510 {
10511 const_op += 1;
10512 op1 = GEN_INT (const_op);
10513 code = LT;
10514 }
10515
10516
10517
10518 else if (const_op == 0
10519 && mode_width <= HOST_BITS_PER_WIDE_INT
10520 && (nonzero_bits (op0, mode)
10521 & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0)
10522 code = EQ;
10523 break;
10524
10525 case GE:
10526
10527 if (const_op > 0)
10528 {
10529 const_op -= 1;
10530 op1 = GEN_INT (const_op);
10531 code = GT;
10532
10533 }
10534 else
10535 break;
10536
10537 case GT:
10538
10539 if (const_op < 0)
10540 {
10541 const_op += 1;
10542 op1 = GEN_INT (const_op);
10543 code = GE;
10544 }
10545
10546
10547
10548 else if (const_op == 0
10549 && mode_width <= HOST_BITS_PER_WIDE_INT
10550 && (nonzero_bits (op0, mode)
10551 & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0)
10552 code = NE;
10553 break;
10554
10555 case LTU:
10556
10557 if (const_op > 0)
10558 {
10559 const_op -= 1;
10560 op1 = GEN_INT (const_op);
10561 code = LEU;
10562
10563 }
10564
10565
10566 else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
10567 && (const_op == (HOST_WIDE_INT) 1 << (mode_width - 1)))
10568 {
10569 const_op = 0, op1 = const0_rtx;
10570 code = GE;
10571 break;
10572 }
10573 else
10574 break;
10575
10576 case LEU:
10577
10578 if (const_op == 0)
10579 code = EQ;
10580
10581
10582 else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
10583 && (const_op == ((HOST_WIDE_INT) 1 << (mode_width - 1)) - 1))
10584 {
10585 const_op = 0, op1 = const0_rtx;
10586 code = GE;
10587 }
10588 break;
10589
10590 case GEU:
10591
10592 if (const_op > 1)
10593 {
10594 const_op -= 1;
10595 op1 = GEN_INT (const_op);
10596 code = GTU;
10597
10598 }
10599
10600
10601 else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
10602 && (const_op == (HOST_WIDE_INT) 1 << (mode_width - 1)))
10603 {
10604 const_op = 0, op1 = const0_rtx;
10605 code = LT;
10606 break;
10607 }
10608 else
10609 break;
10610
10611 case GTU:
10612
10613 if (const_op == 0)
10614 code = NE;
10615
10616
10617 else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
10618 && (const_op == ((HOST_WIDE_INT) 1 << (mode_width - 1)) - 1))
10619 {
10620 const_op = 0, op1 = const0_rtx;
10621 code = LT;
10622 }
10623 break;
10624
10625 default:
10626 break;
10627 }
10628
10629
10630
10631 equality_comparison_p = (code == EQ || code == NE);
10632 sign_bit_comparison_p = ((code == LT || code == GE) && const_op == 0);
10633 unsigned_comparison_p = (code == LTU || code == LEU || code == GTU
10634 || code == GEU);
10635
10636
10637
10638 if (sign_bit_comparison_p
10639 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
10640 op0 = force_to_mode (op0, mode,
10641 ((HOST_WIDE_INT) 1
10642 << (GET_MODE_BITSIZE (mode) - 1)),
10643 NULL_RTX, 0);
10644
10645
10646
10647
10648
10649 switch (GET_CODE (op0))
10650 {
10651 case ZERO_EXTRACT:
10652
10653
10654
10655
10656
10657 if (GET_CODE (XEXP (op0, 0)) == CONST_INT
10658 && XEXP (op0, 1) == const1_rtx
10659 && equality_comparison_p && const_op == 0
10660 && (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0)
10661 {
10662 if (BITS_BIG_ENDIAN)
10663 {
10664 enum machine_mode new_mode
10665 = mode_for_extraction (EP_extzv, 1);
10666 if (new_mode == MAX_MACHINE_MODE)
10667 i = BITS_PER_WORD - 1 - i;
10668 else
10669 {
10670 mode = new_mode;
10671 i = (GET_MODE_BITSIZE (mode) - 1 - i);
10672 }
10673 }
10674
10675 op0 = XEXP (op0, 2);
10676 op1 = GEN_INT (i);
10677 const_op = i;
10678
10679
10680 code = reverse_condition (code);
10681 continue;
10682 }
10683
10684
10685
10686 case SIGN_EXTRACT:
10687 tem = expand_compound_operation (op0);
10688 if (tem != op0)
10689 {
10690 op0 = tem;
10691 continue;
10692 }
10693 break;
10694
10695 case NOT:
10696
10697 if (equality_comparison_p
10698 && (tem = simplify_unary_operation (NOT, mode, op1, mode)) != 0)
10699 {
10700 op0 = XEXP (op0, 0);
10701 op1 = tem;
10702 continue;
10703 }
10704
10705
10706
10707 if (sign_bit_comparison_p)
10708 {
10709 op0 = XEXP (op0, 0);
10710 code = (code == GE ? LT : GE);
10711 continue;
10712 }
10713 break;
10714
10715 case NEG:
10716
10717 if (equality_comparison_p
10718 && (tem = simplify_unary_operation (NEG, mode, op1, mode)) != 0)
10719 {
10720 op0 = XEXP (op0, 0);
10721 op1 = tem;
10722 continue;
10723 }
10724
10725
10726 if (const_op != 0)
10727 break;
10728
10729
10730
10731
10732 if (sign_bit_comparison_p
10733 && (GET_CODE (XEXP (op0, 0)) == ABS
10734 || (mode_width <= HOST_BITS_PER_WIDE_INT
10735 && (nonzero_bits (XEXP (op0, 0), mode)
10736 & ((HOST_WIDE_INT) 1 << (mode_width - 1))) == 0)))
10737 {
10738 op0 = XEXP (op0, 0);
10739 code = (code == LT ? NE : EQ);
10740 continue;
10741 }
10742
10743
10744
10745 if (num_sign_bit_copies (op0, mode) >= 2)
10746 {
10747 op0 = XEXP (op0, 0);
10748 code = swap_condition (code);
10749 continue;
10750 }
10751 break;
10752
10753 case ROTATE:
10754
10755
10756 if (equality_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT
10757 && (tem = simplify_binary_operation (ROTATERT, mode,
10758 op1, XEXP (op0, 1))) != 0)
10759 {
10760 op0 = XEXP (op0, 0);
10761 op1 = tem;
10762 continue;
10763 }
10764
10765
10766
10767
10768 if (const_op == 0 && sign_bit_comparison_p
10769 && GET_CODE (XEXP (op0, 1)) == CONST_INT
10770 && mode_width <= HOST_BITS_PER_WIDE_INT)
10771 {
10772 op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
10773 ((HOST_WIDE_INT) 1
10774 << (mode_width - 1
10775 - INTVAL (XEXP (op0, 1)))));
10776 code = (code == LT ? NE : EQ);
10777 continue;
10778 }
10779
10780
10781
10782 case ABS:
10783
10784 if (const_op == 0 && equality_comparison_p)
10785 {
10786 op0 = XEXP (op0, 0);
10787 continue;
10788 }
10789 break;
10790
10791 case SIGN_EXTEND:
10792
10793
10794
10795
10796 if (! unsigned_comparison_p
10797 && (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0)))
10798 <= HOST_BITS_PER_WIDE_INT)
10799 && ((unsigned HOST_WIDE_INT) const_op
10800 < (((unsigned HOST_WIDE_INT) 1
10801 << (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))) - 1)))))
10802 {
10803 op0 = XEXP (op0, 0);
10804 continue;
10805 }
10806 break;
10807
10808 case SUBREG:
10809
10810
10811
10812
10813
10814
10815
10816
10817
10818 if (mode_width <= HOST_BITS_PER_WIDE_INT
10819 && subreg_lowpart_p (op0)
10820 && GET_CODE (SUBREG_REG (op0)) == PLUS
10821 && GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT
10822 && INTVAL (XEXP (SUBREG_REG (op0), 1)) < 0
10823 && (-INTVAL (XEXP (SUBREG_REG (op0), 1))
10824 < (HOST_WIDE_INT) (GET_MODE_MASK (mode) / 2))
10825 && (unsigned HOST_WIDE_INT) const_op < GET_MODE_MASK (mode) / 2
10826 && (0 == (nonzero_bits (XEXP (SUBREG_REG (op0), 0),
10827 GET_MODE (SUBREG_REG (op0)))
10828 & ~GET_MODE_MASK (mode))
10829 || (num_sign_bit_copies (XEXP (SUBREG_REG (op0), 0),
10830 GET_MODE (SUBREG_REG (op0)))
10831 > (unsigned int)
10832 (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
10833 - GET_MODE_BITSIZE (mode)))))
10834 {
10835 op0 = SUBREG_REG (op0);
10836 continue;
10837 }
10838
10839
10840
10841 if (subreg_lowpart_p (op0)
10842 && GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) < mode_width)
10843 ;
10844 else
10845 break;
10846
10847
10848
10849 case ZERO_EXTEND:
10850 if ((unsigned_comparison_p || equality_comparison_p)
10851 && (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0)))
10852 <= HOST_BITS_PER_WIDE_INT)
10853 && ((unsigned HOST_WIDE_INT) const_op
10854 < GET_MODE_MASK (GET_MODE (XEXP (op0, 0)))))
10855 {
10856 op0 = XEXP (op0, 0);
10857 continue;
10858 }
10859 break;
10860
10861 case PLUS:
10862
10863
10864
10865 if (equality_comparison_p
10866 && 0 != (tem = simplify_binary_operation (MINUS, mode,
10867 op1, XEXP (op0, 1))))
10868 {
10869 op0 = XEXP (op0, 0);
10870 op1 = tem;
10871 continue;
10872 }
10873
10874
10875 if (const_op == 0 && XEXP (op0, 1) == constm1_rtx
10876 && GET_CODE (XEXP (op0, 0)) == ABS && sign_bit_comparison_p)
10877 {
10878 op0 = XEXP (XEXP (op0, 0), 0);
10879 code = (code == LT ? EQ : NE);
10880 continue;
10881 }
10882 break;
10883
10884 case MINUS:
10885
10886
10887
10888
10889
10890
10891
10892
10893
10894 if (equality_comparison_p
10895 && 0 != (tem = simplify_binary_operation (PLUS, mode,
10896 XEXP (op0, 1), op1)))
10897 {
10898 op0 = XEXP (op0, 0);
10899 op1 = tem;
10900 continue;
10901 }
10902
10903 if (equality_comparison_p
10904 && 0 != (tem = simplify_binary_operation (MINUS, mode,
10905 XEXP (op0, 0), op1)))
10906 {
10907 op0 = XEXP (op0, 1);
10908 op1 = tem;
10909 continue;
10910 }
10911
10912
10913
10914 if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 0)) == ASHIFTRT
10915 && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
10916 && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (op0, 0), 1))
10917 == mode_width - 1
10918 && rtx_equal_p (XEXP (XEXP (op0, 0), 0), XEXP (op0, 1)))
10919 {
10920 op0 = XEXP (op0, 1);
10921 code = (code == GE ? LE : GT);
10922 continue;
10923 }
10924 break;
10925
10926 case XOR:
10927
10928
10929 if (equality_comparison_p
10930 && 0 != (tem = simplify_binary_operation (XOR, mode,
10931 XEXP (op0, 1), op1)))
10932 {
10933 op0 = XEXP (op0, 0);
10934 op1 = tem;
10935 continue;
10936 }
10937 break;
10938
10939 case EQ: case NE:
10940 case UNEQ: case LTGT:
10941 case LT: case LTU: case UNLT: case LE: case LEU: case UNLE:
10942 case GT: case GTU: case UNGT: case GE: case GEU: case UNGE:
10943 case UNORDERED: case ORDERED:
10944
10945
10946 if (const_op != 0
10947 #ifdef HAVE_cc0
10948 || XEXP (op0, 0) == cc0_rtx
10949 #endif
10950 || GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC)
10951 break;
10952
10953
10954 if (GET_CODE (XEXP (op0, 0)) == COMPARE)
10955 tem = XEXP (XEXP (op0, 0), 0), tem1 = XEXP (XEXP (op0, 0), 1);
10956 else
10957 tem = XEXP (op0, 0), tem1 = XEXP (op0, 1);
10958
10959
10960
10961 if (code == NE || code == EQ
10962 || (GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT
10963 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
10964 && (STORE_FLAG_VALUE
10965 & (((HOST_WIDE_INT) 1
10966 << (GET_MODE_BITSIZE (GET_MODE (op0)) - 1))))
10967 && (code == LT || code == GE)))
10968 {
10969 enum rtx_code new_code;
10970 if (code == LT || code == NE)
10971 new_code = GET_CODE (op0);
10972 else
10973 new_code = combine_reversed_comparison_code (op0);
10974
10975 if (new_code != UNKNOWN)
10976 {
10977 code = new_code;
10978 op0 = tem;
10979 op1 = tem1;
10980 continue;
10981 }
10982 }
10983 break;
10984
10985 case IOR:
10986
10987
10988 if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 0)) == PLUS
10989 && XEXP (XEXP (op0, 0), 1) == constm1_rtx
10990 && rtx_equal_p (XEXP (XEXP (op0, 0), 0), XEXP (op0, 1)))
10991 {
10992 op0 = XEXP (op0, 1);
10993 code = (code == GE ? GT : LE);
10994 continue;
10995 }
10996 break;
10997
10998 case AND:
10999
11000
11001 if (const_op == 0 && equality_comparison_p
11002 && GET_CODE (XEXP (op0, 0)) == ASHIFT
11003 && XEXP (XEXP (op0, 0), 0) == const1_rtx)
11004 {
11005 op0 = simplify_and_const_int
11006 (op0, mode, gen_rtx_LSHIFTRT (mode,
11007 XEXP (op0, 1),
11008 XEXP (XEXP (op0, 0), 1)),
11009 (HOST_WIDE_INT) 1);
11010 continue;
11011 }
11012
11013
11014
11015
11016 if (const_op == 0 && equality_comparison_p
11017 && mode_width <= HOST_BITS_PER_WIDE_INT
11018 && GET_CODE (XEXP (op0, 1)) == CONST_INT
11019 && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
11020 && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
11021 && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
11022 && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT)
11023 {
11024 mask = ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode))
11025 << INTVAL (XEXP (XEXP (op0, 0), 1)));
11026 if ((~STORE_FLAG_VALUE & mask) == 0
11027 && (GET_RTX_CLASS (GET_CODE (XEXP (XEXP (op0, 0), 0))) == '<'
11028 || ((tem = get_last_value (XEXP (XEXP (op0, 0), 0))) != 0
11029 && GET_RTX_CLASS (GET_CODE (tem)) == '<')))
11030 {
11031 op0 = XEXP (XEXP (op0, 0), 0);
11032 continue;
11033 }
11034 }
11035
11036
11037
11038
11039 if (equality_comparison_p
11040 && const_op == 0
11041 && GET_CODE (XEXP (op0, 1)) == CONST_INT
11042 && mode_width <= HOST_BITS_PER_WIDE_INT
11043 && ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode))
11044 == (unsigned HOST_WIDE_INT) 1 << (mode_width - 1)))
11045 {
11046 op0 = XEXP (op0, 0);
11047 code = (code == EQ ? GE : LT);
11048 continue;
11049 }
11050
11051
11052
11053
11054
11055 if ((equality_comparison_p || unsigned_comparison_p)
11056 && GET_CODE (XEXP (op0, 1)) == CONST_INT
11057 && (i = exact_log2 ((INTVAL (XEXP (op0, 1))
11058 & GET_MODE_MASK (mode))
11059 + 1)) >= 0
11060 && const_op >> i == 0
11061 && (tmode = mode_for_size (i, MODE_INT, 1)) != BLKmode)
11062 {
11063 op0 = gen_lowpart_for_combine (tmode, XEXP (op0, 0));
11064 continue;
11065 }
11066
11067
11068
11069
11070
11071 if (GET_CODE (XEXP (op0, 0)) == SUBREG)
11072 {
11073 unsigned HOST_WIDE_INT c1;
11074 tmode = GET_MODE (SUBREG_REG (XEXP (op0, 0)));
11075
11076
11077 if (SCALAR_INT_MODE_P (tmode)
11078
11079
11080
11081
11082
11083
11084
11085 && (0
11086 #ifdef WORD_REGISTER_OPERATIONS
11087 || (mode_width > GET_MODE_BITSIZE (tmode)
11088 && mode_width <= BITS_PER_WORD)
11089 #endif
11090 || (mode_width <= GET_MODE_BITSIZE (tmode)
11091 && subreg_lowpart_p (XEXP (op0, 0))))
11092 && GET_CODE (XEXP (op0, 1)) == CONST_INT
11093 && mode_width <= HOST_BITS_PER_WIDE_INT
11094 && GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT
11095 && ((c1 = INTVAL (XEXP (op0, 1))) & ~mask) == 0
11096 && (c1 & ~GET_MODE_MASK (tmode)) == 0
11097 && c1 != mask
11098 && c1 != GET_MODE_MASK (tmode))
11099 {
11100 op0 = gen_binary (AND, tmode,
11101 SUBREG_REG (XEXP (op0, 0)),
11102 gen_int_mode (c1, tmode));
11103 op0 = gen_lowpart_for_combine (mode, op0);
11104 continue;
11105 }
11106 }
11107
11108
11109
11110 if (const_op == 0 && equality_comparison_p
11111 && XEXP (op0, 1) == const1_rtx
11112 && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
11113 && GET_CODE (XEXP (XEXP (op0, 0), 0)) == NOT)
11114 {
11115 op0 = simplify_and_const_int
11116 (op0, mode,
11117 gen_rtx_LSHIFTRT (mode, XEXP (XEXP (XEXP (op0, 0), 0), 0),
11118 XEXP (XEXP (op0, 0), 1)),
11119 (HOST_WIDE_INT) 1);
11120 code = (code == NE ? EQ : NE);
11121 continue;
11122 }
11123 break;
11124
11125 case ASHIFT:
11126
11127
11128
11129
11130
11131 if (GET_CODE (XEXP (op0, 1)) == CONST_INT
11132 && INTVAL (XEXP (op0, 1)) >= 0
11133 && ((INTVAL (XEXP (op0, 1)) + ! equality_comparison_p)
11134 < HOST_BITS_PER_WIDE_INT)
11135 && ((const_op
11136 & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0)
11137 && mode_width <= HOST_BITS_PER_WIDE_INT
11138 && (nonzero_bits (XEXP (op0, 0), mode)
11139 & ~(mask >> (INTVAL (XEXP (op0, 1))
11140 + ! equality_comparison_p))) == 0)
11141 {
11142
11143
11144 unsigned HOST_WIDE_INT temp = const_op & GET_MODE_MASK (mode);
11145
11146 temp >>= INTVAL (XEXP (op0, 1));
11147 op1 = gen_int_mode (temp, mode);
11148 op0 = XEXP (op0, 0);
11149 continue;
11150 }
11151
11152
11153
11154 if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT
11155 && mode_width <= HOST_BITS_PER_WIDE_INT)
11156 {
11157 op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
11158 ((HOST_WIDE_INT) 1
11159 << (mode_width - 1
11160 - INTVAL (XEXP (op0, 1)))));
11161 code = (code == LT ? NE : EQ);
11162 continue;
11163 }
11164
11165
11166
11167
11168 if (const_op == 0 && equality_comparison_p
11169 && GET_CODE (XEXP (op0, 1)) == CONST_INT
11170 && (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1))
11171 == mode_width - 1)
11172 {
11173 op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
11174 (HOST_WIDE_INT) 1);
11175 continue;
11176 }
11177 break;
11178
11179 case ASHIFTRT:
11180
11181
11182 if (equality_comparison_p && const_op == 0
11183 && GET_CODE (XEXP (op0, 1)) == CONST_INT)
11184 {
11185 op0 = simplify_shift_const (NULL_RTX, LSHIFTRT, mode,
11186 XEXP (op0, 0),
11187 INTVAL (XEXP (op0, 1)));
11188 continue;
11189 }
11190
11191
11192
11193 if (! unsigned_comparison_p
11194 && GET_CODE (XEXP (op0, 1)) == CONST_INT
11195 && GET_CODE (XEXP (op0, 0)) == ASHIFT
11196 && XEXP (op0, 1) == XEXP (XEXP (op0, 0), 1)
11197 && (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)),
11198 MODE_INT, 1)) != BLKmode
11199 && (((unsigned HOST_WIDE_INT) const_op
11200 + (GET_MODE_MASK (tmode) >> 1) + 1)
11201 <= GET_MODE_MASK (tmode)))
11202 {
11203 op0 = gen_lowpart_for_combine (tmode, XEXP (XEXP (op0, 0), 0));
11204 continue;
11205 }
11206
11207
11208
11209
11210 if (! unsigned_comparison_p
11211 && GET_CODE (XEXP (op0, 1)) == CONST_INT
11212 && GET_CODE (XEXP (op0, 0)) == PLUS
11213 && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
11214 && GET_CODE (XEXP (XEXP (op0, 0), 0)) == ASHIFT
11215 && XEXP (op0, 1) == XEXP (XEXP (XEXP (op0, 0), 0), 1)
11216 && (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)),
11217 MODE_INT, 1)) != BLKmode
11218 && (((unsigned HOST_WIDE_INT) const_op
11219 + (GET_MODE_MASK (tmode) >> 1) + 1)
11220 <= GET_MODE_MASK (tmode)))
11221 {
11222 rtx inner = XEXP (XEXP (XEXP (op0, 0), 0), 0);
11223 rtx add_const = XEXP (XEXP (op0, 0), 1);
11224 rtx new_const = gen_binary (ASHIFTRT, GET_MODE (op0), add_const,
11225 XEXP (op0, 1));
11226
11227 op0 = gen_binary (PLUS, tmode,
11228 gen_lowpart_for_combine (tmode, inner),
11229 new_const);
11230 continue;
11231 }
11232
11233
11234 case LSHIFTRT:
11235
11236
11237
11238
11239 if (GET_CODE (XEXP (op0, 1)) == CONST_INT
11240 && INTVAL (XEXP (op0, 1)) >= 0
11241 && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT
11242 && mode_width <= HOST_BITS_PER_WIDE_INT
11243 && (nonzero_bits (XEXP (op0, 0), mode)
11244 & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0
11245 && (((unsigned HOST_WIDE_INT) const_op
11246 + (GET_CODE (op0) != LSHIFTRT
11247 ? ((GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1)) >> 1)
11248 + 1)
11249 : 0))
11250 <= GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1))))
11251 {
11252
11253
11254 if (GET_CODE (op0) == LSHIFTRT)
11255 code = unsigned_condition (code);
11256
11257 const_op <<= INTVAL (XEXP (op0, 1));
11258 op1 = GEN_INT (const_op);
11259 op0 = XEXP (op0, 0);
11260 continue;
11261 }
11262
11263
11264
11265 if (const_op == 0
11266 && (equality_comparison_p || sign_bit_comparison_p)
11267 && GET_CODE (XEXP (op0, 1)) == CONST_INT
11268 && (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1))
11269 == mode_width - 1)
11270 {
11271 op0 = XEXP (op0, 0);
11272 code = (code == NE || code == GT ? LT : GE);
11273 continue;
11274 }
11275 break;
11276
11277 default:
11278 break;
11279 }
11280
11281 break;
11282 }
11283
11284
11285
11286
11287
11288
11289
11290
11291
11292
11293
11294
11295
11296
11297
11298
11299
11300
11301
11302
11303
11304
11305
11306 op0 = make_compound_operation (op0, op1 == const0_rtx ? COMPARE : SET);
11307 op1 = make_compound_operation (op1, SET);
11308
11309 if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0)
11310
11311
11312 && GET_CODE (SUBREG_REG (op0)) == REG
11313 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
11314 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT
11315 && (code == NE || code == EQ))
11316 {
11317 if (GET_MODE_SIZE (GET_MODE (op0))
11318 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))
11319 {
11320 op0 = SUBREG_REG (op0);
11321 op1 = gen_lowpart_for_combine (GET_MODE (op0), op1);
11322 }
11323 else if ((GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
11324 <= HOST_BITS_PER_WIDE_INT)
11325 && (nonzero_bits (SUBREG_REG (op0),
11326 GET_MODE (SUBREG_REG (op0)))
11327 & ~GET_MODE_MASK (GET_MODE (op0))) == 0)
11328 {
11329 tem = gen_lowpart_for_combine (GET_MODE (SUBREG_REG (op0)), op1);
11330
11331 if ((nonzero_bits (tem, GET_MODE (SUBREG_REG (op0)))
11332 & ~GET_MODE_MASK (GET_MODE (op0))) == 0)
11333 op0 = SUBREG_REG (op0), op1 = tem;
11334 }
11335 }
11336
11337
11338
11339
11340
11341
11342
11343 mode = GET_MODE (op0);
11344 if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT
11345 && GET_MODE_SIZE (mode) < UNITS_PER_WORD
11346 && ! have_insn_for (COMPARE, mode))
11347 for (tmode = GET_MODE_WIDER_MODE (mode);
11348 (tmode != VOIDmode
11349 && GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT);
11350 tmode = GET_MODE_WIDER_MODE (tmode))
11351 if (have_insn_for (COMPARE, tmode))
11352 {
11353 int zero_extended;
11354
11355
11356
11357
11358
11359 zero_extended = ((code == EQ || code == NE
11360 || code == GEU || code == GTU
11361 || code == LEU || code == LTU)
11362 && (nonzero_bits (op0, tmode)
11363 & ~GET_MODE_MASK (mode)) == 0
11364 && ((GET_CODE (op1) == CONST_INT
11365 || (nonzero_bits (op1, tmode)
11366 & ~GET_MODE_MASK (mode)) == 0)));
11367
11368 if (zero_extended
11369 || ((num_sign_bit_copies (op0, tmode)
11370 > (unsigned int) (GET_MODE_BITSIZE (tmode)
11371 - GET_MODE_BITSIZE (mode)))
11372 && (num_sign_bit_copies (op1, tmode)
11373 > (unsigned int) (GET_MODE_BITSIZE (tmode)
11374 - GET_MODE_BITSIZE (mode)))))
11375 {
11376
11377
11378 if (GET_CODE (op0) == AND
11379 && !have_insn_for (AND, mode))
11380 op0 = gen_binary (AND, tmode,
11381 gen_lowpart_for_combine (tmode,
11382 XEXP (op0, 0)),
11383 gen_lowpart_for_combine (tmode,
11384 XEXP (op0, 1)));
11385
11386 op0 = gen_lowpart_for_combine (tmode, op0);
11387 if (zero_extended && GET_CODE (op1) == CONST_INT)
11388 op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (mode));
11389 op1 = gen_lowpart_for_combine (tmode, op1);
11390 break;
11391 }
11392
11393
11394
11395
11396 if (op1 == const0_rtx && (code == LT || code == GE)
11397 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
11398 {
11399 op0 = gen_binary (AND, tmode,
11400 gen_lowpart_for_combine (tmode, op0),
11401 GEN_INT ((HOST_WIDE_INT) 1
11402 << (GET_MODE_BITSIZE (mode) - 1)));
11403 code = (code == LT) ? NE : EQ;
11404 break;
11405 }
11406 }
11407
11408 #ifdef CANONICALIZE_COMPARISON
11409
11410
11411 CANONICALIZE_COMPARISON (code, op0, op1);
11412 #endif
11413
11414 *pop0 = op0;
11415 *pop1 = op1;
11416
11417 return code;
11418 }
11419
11420
11421
11422 static enum rtx_code
11423 combine_reversed_comparison_code (exp)
11424 rtx exp;
11425 {
11426 enum rtx_code code1 = reversed_comparison_code (exp, NULL);
11427 rtx x;
11428
11429 if (code1 != UNKNOWN
11430 || GET_MODE_CLASS (GET_MODE (XEXP (exp, 0))) != MODE_CC)
11431 return code1;
11432
11433
11434 x = get_last_value (XEXP (exp, 0));
11435 if (!x || GET_CODE (x) != COMPARE)
11436 return UNKNOWN;
11437 return reversed_comparison_code_parts (GET_CODE (exp),
11438 XEXP (x, 0), XEXP (x, 1), NULL);
11439 }
11440
11441
11442 static rtx
11443 reversed_comparison (exp, mode, op0, op1)
11444 rtx exp, op0, op1;
11445 enum machine_mode mode;
11446 {
11447 enum rtx_code reversed_code = combine_reversed_comparison_code (exp);
11448 if (reversed_code == UNKNOWN)
11449 return NULL_RTX;
11450 else
11451 return gen_binary (reversed_code, mode, op0, op1);
11452 }
11453
11454
11455
11456
11457
11458 static void
11459 update_table_tick (x)
11460 rtx x;
11461 {
11462 enum rtx_code code = GET_CODE (x);
11463 const char *fmt = GET_RTX_FORMAT (code);
11464 int i;
11465
11466 if (code == REG)
11467 {
11468 unsigned int regno = REGNO (x);
11469 unsigned int endregno
11470 = regno + (regno < FIRST_PSEUDO_REGISTER
11471 ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
11472 unsigned int r;
11473
11474 for (r = regno; r < endregno; r++)
11475 reg_last_set_table_tick[r] = label_tick;
11476
11477 return;
11478 }
11479
11480 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
11481
11482
11483 if (fmt[i] == 'e')
11484 {
11485
11486
11487
11488 if (i == 0
11489 && (GET_RTX_CLASS (code) == '2'
11490 || GET_RTX_CLASS (code) == 'c'))
11491 {
11492
11493
11494 rtx x0 = XEXP (x, 0);
11495 rtx x1 = XEXP (x, 1);
11496
11497
11498
11499 if (x0 == x1)
11500 break;
11501
11502
11503
11504
11505 if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
11506 || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
11507 && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
11508 break;
11509
11510
11511
11512 if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
11513 || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
11514 && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
11515 {
11516 update_table_tick (XEXP (x0, x1 == XEXP (x0, 0) ? 1 : 0));
11517 break;
11518 }
11519 }
11520
11521 update_table_tick (XEXP (x, i));
11522 }
11523 }
11524
11525
11526
11527
11528
11529
11530 static void
11531 record_value_for_reg (reg, insn, value)
11532 rtx reg;
11533 rtx insn;
11534 rtx value;
11535 {
11536 unsigned int regno = REGNO (reg);
11537 unsigned int endregno
11538 = regno + (regno < FIRST_PSEUDO_REGISTER
11539 ? HARD_REGNO_NREGS (regno, GET_MODE (reg)) : 1);
11540 unsigned int i;
11541
11542
11543
11544 if (value && insn && reg_overlap_mentioned_p (reg, value))
11545 {
11546 rtx tem;
11547
11548
11549
11550 subst_low_cuid = INSN_CUID (insn);
11551 tem = get_last_value (reg);
11552
11553
11554
11555
11556
11557 if (tem)
11558 {
11559 if ((GET_RTX_CLASS (GET_CODE (tem)) == '2'
11560 || GET_RTX_CLASS (GET_CODE (tem)) == 'c')
11561 && GET_CODE (XEXP (tem, 0)) == CLOBBER
11562 && GET_CODE (XEXP (tem, 1)) == CLOBBER)
11563 tem = XEXP (tem, 0);
11564
11565 value = replace_rtx (copy_rtx (value), reg, tem);
11566 }
11567 }
11568
11569
11570
11571
11572
11573 for (i = regno; i < endregno; i++)
11574 {
11575 if (insn)
11576 reg_last_set[i] = insn;
11577
11578 reg_last_set_value[i] = 0;
11579 reg_last_set_mode[i] = 0;
11580 reg_last_set_nonzero_bits[i] = 0;
11581 reg_last_set_sign_bit_copies[i] = 0;
11582 reg_last_death[i] = 0;
11583 }
11584
11585
11586 if (value)
11587 update_table_tick (value);
11588
11589
11590
11591
11592
11593
11594
11595
11596 for (i = regno; i < endregno; i++)
11597 {
11598 reg_last_set_label[i] = label_tick;
11599 if (value && reg_last_set_table_tick[i] == label_tick)
11600 reg_last_set_invalid[i] = 1;
11601 else
11602 reg_last_set_invalid[i] = 0;
11603 }
11604
11605
11606
11607
11608 if (value && ! get_last_value_validate (&value, insn,
11609 reg_last_set_label[regno], 0))
11610 {
11611 value = copy_rtx (value);
11612 if (! get_last_value_validate (&value, insn,
11613 reg_last_set_label[regno], 1))
11614 value = 0;
11615 }
11616
11617
11618
11619
11620 reg_last_set_value[regno] = value;
11621
11622 if (value)
11623 {
11624 enum machine_mode mode = GET_MODE (reg);
11625 subst_low_cuid = INSN_CUID (insn);
11626 reg_last_set_mode[regno] = mode;
11627 if (GET_MODE_CLASS (mode) == MODE_INT
11628 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
11629 mode = nonzero_bits_mode;
11630 reg_last_set_nonzero_bits[regno] = nonzero_bits (value, mode);
11631 reg_last_set_sign_bit_copies[regno]
11632 = num_sign_bit_copies (value, GET_MODE (reg));
11633 }
11634 }
11635
11636
11637
11638
11639
11640 static void
11641 record_dead_and_set_regs_1 (dest, setter, data)
11642 rtx dest, setter;
11643 void *data;
11644 {
11645 rtx record_dead_insn = (rtx) data;
11646
11647 if (GET_CODE (dest) == SUBREG)
11648 dest = SUBREG_REG (dest);
11649
11650 if (GET_CODE (dest) == REG)
11651 {
11652
11653
11654
11655 if (GET_CODE (setter) == SET && dest == SET_DEST (setter))
11656 record_value_for_reg (dest, record_dead_insn, SET_SRC (setter));
11657 else if (GET_CODE (setter) == SET
11658 && GET_CODE (SET_DEST (setter)) == SUBREG
11659 && SUBREG_REG (SET_DEST (setter)) == dest
11660 && GET_MODE_BITSIZE (GET_MODE (dest)) <= BITS_PER_WORD
11661 && subreg_lowpart_p (SET_DEST (setter)))
11662 record_value_for_reg (dest, record_dead_insn,
11663 gen_lowpart_for_combine (GET_MODE (dest),
11664 SET_SRC (setter)));
11665 else
11666 record_value_for_reg (dest, record_dead_insn, NULL_RTX);
11667 }
11668 else if (GET_CODE (dest) == MEM
11669
11670 && ! push_operand (dest, GET_MODE (dest)))
11671 mem_last_set = INSN_CUID (record_dead_insn);
11672 }
11673
11674
11675
11676
11677
11678
11679
11680
11681
11682
11683
11684 static void
11685 record_dead_and_set_regs (insn)
11686 rtx insn;
11687 {
11688 rtx link;
11689 unsigned int i;
11690
11691 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
11692 {
11693 if (REG_NOTE_KIND (link) == REG_DEAD
11694 && GET_CODE (XEXP (link, 0)) == REG)
11695 {
11696 unsigned int regno = REGNO (XEXP (link, 0));
11697 unsigned int endregno
11698 = regno + (regno < FIRST_PSEUDO_REGISTER
11699 ? HARD_REGNO_NREGS (regno, GET_MODE (XEXP (link, 0)))
11700 : 1);
11701
11702 for (i = regno; i < endregno; i++)
11703 reg_last_death[i] = insn;
11704 }
11705 else if (REG_NOTE_KIND (link) == REG_INC)
11706 record_value_for_reg (XEXP (link, 0), insn, NULL_RTX);
11707 }
11708
11709 if (GET_CODE (insn) == CALL_INSN)
11710 {
11711 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
11712 if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
11713 {
11714 reg_last_set_value[i] = 0;
11715 reg_last_set_mode[i] = 0;
11716 reg_last_set_nonzero_bits[i] = 0;
11717 reg_last_set_sign_bit_copies[i] = 0;
11718 reg_last_death[i] = 0;
11719 }
11720
11721 last_call_cuid = mem_last_set = INSN_CUID (insn);
11722
11723
11724
11725
11726
11727
11728 return;
11729 }
11730
11731 note_stores (PATTERN (insn), record_dead_and_set_regs_1, insn);
11732 }
11733
11734
11735
11736
11737
11738
11739
11740
11741
11742
11743 static void
11744 record_promoted_value (insn, subreg)
11745 rtx insn;
11746 rtx subreg;
11747 {
11748 rtx links, set;
11749 unsigned int regno = REGNO (SUBREG_REG (subreg));
11750 enum machine_mode mode = GET_MODE (subreg);
11751
11752 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
11753 return;
11754
11755 for (links = LOG_LINKS (insn); links;)
11756 {
11757 insn = XEXP (links, 0);
11758 set = single_set (insn);
11759
11760 if (! set || GET_CODE (SET_DEST (set)) != REG
11761 || REGNO (SET_DEST (set)) != regno
11762 || GET_MODE (SET_DEST (set)) != GET_MODE (SUBREG_REG (subreg)))
11763 {
11764 links = XEXP (links, 1);
11765 continue;
11766 }
11767
11768 if (reg_last_set[regno] == insn)
11769 {
11770 if (SUBREG_PROMOTED_UNSIGNED_P (subreg) > 0)
11771 reg_last_set_nonzero_bits[regno] &= GET_MODE_MASK (mode);
11772 }
11773
11774 if (GET_CODE (SET_SRC (set)) == REG)
11775 {
11776 regno = REGNO (SET_SRC (set));
11777 links = LOG_LINKS (insn);
11778 }
11779 else
11780 break;
11781 }
11782 }
11783
11784
11785
11786
11787 static void
11788 check_promoted_subreg (insn, x)
11789 rtx insn;
11790 rtx x;
11791 {
11792 if (GET_CODE (x) == SUBREG && SUBREG_PROMOTED_VAR_P (x)
11793 && GET_CODE (SUBREG_REG (x)) == REG)
11794 record_promoted_value (insn, x);
11795 else
11796 {
11797 const char *format = GET_RTX_FORMAT (GET_CODE (x));
11798 int i, j;
11799
11800 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
11801 switch (format[i])
11802 {
11803 case 'e':
11804 check_promoted_subreg (insn, XEXP (x, i));
11805 break;
11806 case 'V':
11807 case 'E':
11808 if (XVEC (x, i) != 0)
11809 for (j = 0; j < XVECLEN (x, i); j++)
11810 check_promoted_subreg (insn, XVECEXP (x, i, j));
11811 break;
11812 }
11813 }
11814 }
11815
11816
11817
11818
11819
11820
11821
11822
11823
11824
11825
11826 static int
11827 get_last_value_validate (loc, insn, tick, replace)
11828 rtx *loc;
11829 rtx insn;
11830 int tick;
11831 int replace;
11832 {
11833 rtx x = *loc;
11834 const char *fmt = GET_RTX_FORMAT (GET_CODE (x));
11835 int len = GET_RTX_LENGTH (GET_CODE (x));
11836 int i;
11837
11838 if (GET_CODE (x) == REG)
11839 {
11840 unsigned int regno = REGNO (x);
11841 unsigned int endregno
11842 = regno + (regno < FIRST_PSEUDO_REGISTER
11843 ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
11844 unsigned int j;
11845
11846 for (j = regno; j < endregno; j++)
11847 if (reg_last_set_invalid[j]
11848
11849
11850 || (! (regno >= FIRST_PSEUDO_REGISTER
11851 && REG_N_SETS (regno) == 1
11852 && (! REGNO_REG_SET_P
11853 (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, regno)))
11854 && reg_last_set_label[j] > tick))
11855 {
11856 if (replace)
11857 *loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
11858 return replace;
11859 }
11860
11861 return 1;
11862 }
11863
11864
11865
11866 else if (GET_CODE (x) == MEM && ! RTX_UNCHANGING_P (x)
11867 && INSN_CUID (insn) <= mem_last_set)
11868 {
11869 if (replace)
11870 *loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
11871 return replace;
11872 }
11873
11874 for (i = 0; i < len; i++)
11875 {
11876 if (fmt[i] == 'e')
11877 {
11878
11879
11880
11881 if (i == 1
11882 && (GET_RTX_CLASS (GET_CODE (x)) == '2'
11883 || GET_RTX_CLASS (GET_CODE (x)) == 'c'))
11884 {
11885
11886
11887 rtx x0 = XEXP (x, 0);
11888 rtx x1 = XEXP (x, 1);
11889
11890
11891 if (x0 == x1)
11892 return 1;
11893
11894
11895
11896
11897 if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
11898 || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
11899 && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
11900 return 1;
11901
11902
11903
11904 if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
11905 || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
11906 && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
11907 return
11908 get_last_value_validate (&XEXP (x1,
11909 x0 == XEXP (x1, 0) ? 1 : 0),
11910 insn, tick, replace);
11911 }
11912
11913 if (get_last_value_validate (&XEXP (x, i), insn, tick,
11914 replace) == 0)
11915 return 0;
11916 }
11917
11918 else if (fmt[i] == 'E')
11919 return 0;
11920 }
11921
11922
11923 return 1;
11924 }
11925
11926
11927
11928
11929
11930 static rtx
11931 get_last_value (x)
11932 rtx x;
11933 {
11934 unsigned int regno;
11935 rtx value;
11936
11937
11938
11939
11940 if (GET_CODE (x) == SUBREG
11941 && subreg_lowpart_p (x)
11942 && (GET_MODE_SIZE (GET_MODE (x))
11943 <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
11944 && (value = get_last_value (SUBREG_REG (x))) != 0)
11945 return gen_lowpart_for_combine (GET_MODE (x), value);
11946
11947 if (GET_CODE (x) != REG)
11948 return 0;
11949
11950 regno = REGNO (x);
11951 value = reg_last_set_value[regno];
11952
11953
11954
11955
11956
11957
11958
11959
11960
11961
11962
11963 if (value == 0
11964 || (reg_last_set_label[regno] != label_tick
11965 && (regno < FIRST_PSEUDO_REGISTER
11966 || REG_N_SETS (regno) != 1
11967 || (REGNO_REG_SET_P
11968 (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, regno)))))
11969 return 0;
11970
11971
11972
11973 if (INSN_CUID (reg_last_set[regno]) >= subst_low_cuid)
11974 return 0;
11975
11976
11977 if (get_last_value_validate (&value, reg_last_set[regno],
11978 reg_last_set_label[regno], 0))
11979 return value;
11980
11981
11982
11983
11984 value = copy_rtx (value);
11985 if (get_last_value_validate (&value, reg_last_set[regno],
11986 reg_last_set_label[regno], 1))
11987 return value;
11988
11989 return 0;
11990 }
11991
11992
11993
11994
11995 static int
11996 use_crosses_set_p (x, from_cuid)
11997 rtx x;
11998 int from_cuid;
11999 {
12000 const char *fmt;
12001 int i;
12002 enum rtx_code code = GET_CODE (x);
12003
12004 if (code == REG)
12005 {
12006 unsigned int regno = REGNO (x);
12007 unsigned endreg = regno + (regno < FIRST_PSEUDO_REGISTER
12008 ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
12009
12010 #ifdef PUSH_ROUNDING
12011
12012
12013 if (regno == STACK_POINTER_REGNUM && PUSH_ARGS)
12014 return 1;
12015 #endif
12016 for (; regno < endreg; regno++)
12017 if (reg_last_set[regno]
12018 && INSN_CUID (reg_last_set[regno]) > from_cuid)
12019 return 1;
12020 return 0;
12021 }
12022
12023 if (code == MEM && mem_last_set > from_cuid)
12024 return 1;
12025
12026 fmt = GET_RTX_FORMAT (code);
12027
12028 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
12029 {
12030 if (fmt[i] == 'E')
12031 {
12032 int j;
12033 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
12034 if (use_crosses_set_p (XVECEXP (x, i, j), from_cuid))
12035 return 1;
12036 }
12037 else if (fmt[i] == 'e'
12038 && use_crosses_set_p (XEXP (x, i), from_cuid))
12039 return 1;
12040 }
12041 return 0;
12042 }
12043
12044
12045
12046
12047 static unsigned int reg_dead_regno, reg_dead_endregno;
12048 static int reg_dead_flag;
12049
12050
12051
12052
12053
12054
12055 static void
12056 reg_dead_at_p_1 (dest, x, data)
12057 rtx dest;
12058 rtx x;
12059 void *data ATTRIBUTE_UNUSED;
12060 {
12061 unsigned int regno, endregno;
12062
12063 if (GET_CODE (dest) != REG)
12064 return;
12065
12066 regno = REGNO (dest);
12067 endregno = regno + (regno < FIRST_PSEUDO_REGISTER
12068 ? HARD_REGNO_NREGS (regno, GET_MODE (dest)) : 1);
12069
12070 if (reg_dead_endregno > regno && reg_dead_regno < endregno)
12071 reg_dead_flag = (GET_CODE (x) == CLOBBER) ? 1 : -1;
12072 }
12073
12074
12075
12076
12077
12078
12079
12080
12081
12082 static int
12083 reg_dead_at_p (reg, insn)
12084 rtx reg;
12085 rtx insn;
12086 {
12087 basic_block block;
12088 unsigned int i;
12089
12090
12091 reg_dead_regno = REGNO (reg);
12092 reg_dead_endregno = reg_dead_regno + (reg_dead_regno < FIRST_PSEUDO_REGISTER
12093 ? HARD_REGNO_NREGS (reg_dead_regno,
12094 GET_MODE (reg))
12095 : 1);
12096
12097 reg_dead_flag = 0;
12098
12099
12100 if (reg_dead_regno < FIRST_PSEUDO_REGISTER)
12101 {
12102 for (i = reg_dead_regno; i < reg_dead_endregno; i++)
12103 if (TEST_HARD_REG_BIT (newpat_used_regs, i))
12104 return 0;
12105 }
12106
12107
12108
12109 for (; insn && GET_CODE (insn) != CODE_LABEL && GET_CODE (insn) != BARRIER;
12110 insn = prev_nonnote_insn (insn))
12111 {
12112 note_stores (PATTERN (insn), reg_dead_at_p_1, NULL);
12113 if (reg_dead_flag)
12114 return reg_dead_flag == 1 ? 1 : 0;
12115
12116 if (find_regno_note (insn, REG_DEAD, reg_dead_regno))
12117 return 1;
12118 }
12119
12120
12121 if (insn == 0)
12122 block = ENTRY_BLOCK_PTR->next_bb;
12123 else
12124 {
12125 FOR_EACH_BB (block)
12126 if (insn == block->head)
12127 break;
12128
12129 if (block == EXIT_BLOCK_PTR)
12130 return 0;
12131 }
12132
12133 for (i = reg_dead_regno; i < reg_dead_endregno; i++)
12134 if (REGNO_REG_SET_P (block->global_live_at_start, i))
12135 return 0;
12136
12137 return 1;
12138 }
12139
12140
12141
12142
12143 static void
12144 mark_used_regs_combine (x)
12145 rtx x;
12146 {
12147 RTX_CODE code = GET_CODE (x);
12148 unsigned int regno;
12149 int i;
12150
12151 switch (code)
12152 {
12153 case LABEL_REF:
12154 case SYMBOL_REF:
12155 case CONST_INT:
12156 case CONST:
12157 case CONST_DOUBLE:
12158 case CONST_VECTOR:
12159 case PC:
12160 case ADDR_VEC:
12161 case ADDR_DIFF_VEC:
12162 case ASM_INPUT:
12163 #ifdef HAVE_cc0
12164
12165
12166 case CC0:
12167 #endif
12168 return;
12169
12170 case CLOBBER:
12171
12172
12173 if (GET_CODE (XEXP (x, 0)) == MEM)
12174 mark_used_regs_combine (XEXP (XEXP (x, 0), 0));
12175 return;
12176
12177 case REG:
12178 regno = REGNO (x);
12179
12180
12181 if (regno < FIRST_PSEUDO_REGISTER)
12182 {
12183 unsigned int endregno, r;
12184
12185
12186 if (regno == STACK_POINTER_REGNUM
12187 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
12188 || regno == HARD_FRAME_POINTER_REGNUM
12189 #endif
12190 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
12191 || (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
12192 #endif
12193 || regno == FRAME_POINTER_REGNUM)
12194 return;
12195
12196 endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
12197 for (r = regno; r < endregno; r++)
12198 SET_HARD_REG_BIT (newpat_used_regs, r);
12199 }
12200 return;
12201
12202 case SET:
12203 {
12204
12205
12206 rtx testreg = SET_DEST (x);
12207
12208 while (GET_CODE (testreg) == SUBREG
12209 || GET_CODE (testreg) == ZERO_EXTRACT
12210 || GET_CODE (testreg) == SIGN_EXTRACT
12211 || GET_CODE (testreg) == STRICT_LOW_PART)
12212 testreg = XEXP (testreg, 0);
12213
12214 if (GET_CODE (testreg) == MEM)
12215 mark_used_regs_combine (XEXP (testreg, 0));
12216
12217 mark_used_regs_combine (SET_SRC (x));
12218 }
12219 return;
12220
12221 default:
12222 break;
12223 }
12224
12225
12226
12227 {
12228 const char *fmt = GET_RTX_FORMAT (code);
12229
12230 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
12231 {
12232 if (fmt[i] == 'e')
12233 mark_used_regs_combine (XEXP (x, i));
12234 else if (fmt[i] == 'E')
12235 {
12236 int j;
12237
12238 for (j = 0; j < XVECLEN (x, i); j++)
12239 mark_used_regs_combine (XVECEXP (x, i, j));
12240 }
12241 }
12242 }
12243 }
12244
12245
12246
12247
12248
12249 rtx
12250 remove_death (regno, insn)
12251 unsigned int regno;
12252 rtx insn;
12253 {
12254 rtx note = find_regno_note (insn, REG_DEAD, regno);
12255
12256 if (note)
12257 {
12258 REG_N_DEATHS (regno)--;
12259 remove_note (insn, note);
12260 }
12261
12262 return note;
12263 }
12264
12265
12266
12267
12268
12269
12270
12271
12272
12273
12274
12275 static void
12276 move_deaths (x, maybe_kill_insn, from_cuid, to_insn, pnotes)
12277 rtx x;
12278 rtx maybe_kill_insn;
12279 int from_cuid;
12280 rtx to_insn;
12281 rtx *pnotes;
12282 {
12283 const char *fmt;
12284 int len, i;
12285 enum rtx_code code = GET_CODE (x);
12286
12287 if (code == REG)
12288 {
12289 unsigned int regno = REGNO (x);
12290 rtx where_dead = reg_last_death[regno];
12291 rtx before_dead, after_dead;
12292
12293
12294 if (maybe_kill_insn && reg_set_p (x, maybe_kill_insn)
12295 && ! reg_referenced_p (x, maybe_kill_insn))
12296 return;
12297
12298
12299
12300 before_dead = where_dead;
12301 while (before_dead && INSN_UID (before_dead) > max_uid_cuid)
12302 before_dead = PREV_INSN (before_dead);
12303
12304 after_dead = where_dead;
12305 while (after_dead && INSN_UID (after_dead) > max_uid_cuid)
12306 after_dead = NEXT_INSN (after_dead);
12307
12308 if (before_dead && after_dead
12309 && INSN_CUID (before_dead) >= from_cuid
12310 && (INSN_CUID (after_dead) < INSN_CUID (to_insn)
12311 || (where_dead != after_dead
12312 && INSN_CUID (after_dead) == INSN_CUID (to_insn))))
12313 {
12314 rtx note = remove_death (regno, where_dead);
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325 if (note != 0 && regno < FIRST_PSEUDO_REGISTER
12326 && (GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
12327 > GET_MODE_SIZE (GET_MODE (x))))
12328 {
12329 unsigned int deadregno = REGNO (XEXP (note, 0));
12330 unsigned int deadend
12331 = (deadregno + HARD_REGNO_NREGS (deadregno,
12332 GET_MODE (XEXP (note, 0))));
12333 unsigned int ourend
12334 = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
12335 unsigned int i;
12336
12337 for (i = deadregno; i < deadend; i++)
12338 if (i < regno || i >= ourend)
12339 REG_NOTES (where_dead)
12340 = gen_rtx_EXPR_LIST (REG_DEAD,
12341 regno_reg_rtx[i],
12342 REG_NOTES (where_dead));
12343 }
12344
12345
12346
12347
12348
12349
12350 else if ((note == 0
12351 || (note != 0
12352 && (GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
12353 < GET_MODE_SIZE (GET_MODE (x)))))
12354 && regno < FIRST_PSEUDO_REGISTER
12355 && HARD_REGNO_NREGS (regno, GET_MODE (x)) > 1)
12356 {
12357 unsigned int ourend
12358 = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
12359 unsigned int i, offset;
12360 rtx oldnotes = 0;
12361
12362 if (note)
12363 offset = HARD_REGNO_NREGS (regno, GET_MODE (XEXP (note, 0)));
12364 else
12365 offset = 1;
12366
12367 for (i = regno + offset; i < ourend; i++)
12368 move_deaths (regno_reg_rtx[i],
12369 maybe_kill_insn, from_cuid, to_insn, &oldnotes);
12370 }
12371
12372 if (note != 0 && GET_MODE (XEXP (note, 0)) == GET_MODE (x))
12373 {
12374 XEXP (note, 1) = *pnotes;
12375 *pnotes = note;
12376 }
12377 else
12378 *pnotes = gen_rtx_EXPR_LIST (REG_DEAD, x, *pnotes);
12379
12380 REG_N_DEATHS (regno)++;
12381 }
12382
12383 return;
12384 }
12385
12386 else if (GET_CODE (x) == SET)
12387 {
12388 rtx dest = SET_DEST (x);
12389
12390 move_deaths (SET_SRC (x), maybe_kill_insn, from_cuid, to_insn, pnotes);
12391
12392
12393
12394
12395
12396
12397
12398 if (GET_CODE (dest) == ZERO_EXTRACT
12399 || GET_CODE (dest) == STRICT_LOW_PART
12400 || (GET_CODE (dest) == SUBREG
12401 && (((GET_MODE_SIZE (GET_MODE (dest))
12402 + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
12403 == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
12404 + UNITS_PER_WORD - 1) / UNITS_PER_WORD))))
12405 {
12406 move_deaths (dest, maybe_kill_insn, from_cuid, to_insn, pnotes);
12407 return;
12408 }
12409
12410
12411
12412 if (GET_CODE (dest) == SUBREG)
12413 dest = SUBREG_REG (dest);
12414
12415
12416
12417
12418
12419 if (GET_CODE (dest) == MEM)
12420 move_deaths (XEXP (dest, 0), maybe_kill_insn, from_cuid,
12421 to_insn, pnotes);
12422 return;
12423 }
12424
12425 else if (GET_CODE (x) == CLOBBER)
12426 return;
12427
12428 len = GET_RTX_LENGTH (code);
12429 fmt = GET_RTX_FORMAT (code);
12430
12431 for (i = 0; i < len; i++)
12432 {
12433 if (fmt[i] == 'E')
12434 {
12435 int j;
12436 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
12437 move_deaths (XVECEXP (x, i, j), maybe_kill_insn, from_cuid,
12438 to_insn, pnotes);
12439 }
12440 else if (fmt[i] == 'e')
12441 move_deaths (XEXP (x, i), maybe_kill_insn, from_cuid, to_insn, pnotes);
12442 }
12443 }
12444
12445
12446
12447
12448 static int
12449 reg_bitfield_target_p (x, body)
12450 rtx x;
12451 rtx body;
12452 {
12453 int i;
12454
12455 if (GET_CODE (body) == SET)
12456 {
12457 rtx dest = SET_DEST (body);
12458 rtx target;
12459 unsigned int regno, tregno, endregno, endtregno;
12460
12461 if (GET_CODE (dest) == ZERO_EXTRACT)
12462 target = XEXP (dest, 0);
12463 else if (GET_CODE (dest) == STRICT_LOW_PART)
12464 target = SUBREG_REG (XEXP (dest, 0));
12465 else
12466 return 0;
12467
12468 if (GET_CODE (target) == SUBREG)
12469 target = SUBREG_REG (target);
12470
12471 if (GET_CODE (target) != REG)
12472 return 0;
12473
12474 tregno = REGNO (target), regno = REGNO (x);
12475 if (tregno >= FIRST_PSEUDO_REGISTER || regno >= FIRST_PSEUDO_REGISTER)
12476 return target == x;
12477
12478 endtregno = tregno + HARD_REGNO_NREGS (tregno, GET_MODE (target));
12479 endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
12480
12481 return endregno > tregno && regno < endtregno;
12482 }
12483
12484 else if (GET_CODE (body) == PARALLEL)
12485 for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
12486 if (reg_bitfield_target_p (x, XVECEXP (body, 0, i)))
12487 return 1;
12488
12489 return 0;
12490 }
12491
12492
12493
12494
12495
12496
12497
12498
12499
12500
12501
12502
12503 static void
12504 distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
12505 rtx notes;
12506 rtx from_insn;
12507 rtx i3, i2;
12508 rtx elim_i2, elim_i1;
12509 {
12510 rtx note, next_note;
12511 rtx tem;
12512
12513 for (note = notes; note; note = next_note)
12514 {
12515 rtx place = 0, place2 = 0;
12516
12517
12518
12519 if (XEXP (note, 0) && GET_CODE (XEXP (note, 0)) == REG
12520 && REGNO (XEXP (note, 0)) >= FIRST_PSEUDO_REGISTER)
12521 XEXP (note, 0) = regno_reg_rtx[REGNO (XEXP (note, 0))];
12522
12523 next_note = XEXP (note, 1);
12524 switch (REG_NOTE_KIND (note))
12525 {
12526 case REG_BR_PROB:
12527 case REG_BR_PRED:
12528
12529
12530
12531 place = i3;
12532 break;
12533
12534 case REG_VTABLE_REF:
12535
12536
12537 place = i3;
12538 break;
12539
12540 case REG_NON_LOCAL_GOTO:
12541 if (GET_CODE (i3) == JUMP_INSN)
12542 place = i3;
12543 else if (i2 && GET_CODE (i2) == JUMP_INSN)
12544 place = i2;
12545 else
12546 abort ();
12547 break;
12548
12549 case REG_EH_REGION:
12550
12551 if (GET_CODE (i3) == CALL_INSN)
12552 place = i3;
12553 else if (i2 && GET_CODE (i2) == CALL_INSN)
12554 place = i2;
12555 else if (flag_non_call_exceptions)
12556 {
12557 if (may_trap_p (i3))
12558 place = i3;
12559 else if (i2 && may_trap_p (i2))
12560 place = i2;
12561
12562
12563
12564 }
12565 else
12566 abort ();
12567 break;
12568
12569 case REG_ALWAYS_RETURN:
12570 case REG_NORETURN:
12571 case REG_SETJMP:
12572
12573
12574 if (GET_CODE (i3) == CALL_INSN)
12575 place = i3;
12576 else if (i2 && GET_CODE (i2) == CALL_INSN)
12577 place = i2;
12578 else
12579 abort ();
12580 break;
12581
12582 case REG_UNUSED:
12583
12584
12585
12586
12587
12588
12589
12590
12591
12592
12593
12594
12595
12596
12597
12598
12599
12600 if (reg_set_p (XEXP (note, 0), PATTERN (i3)))
12601 {
12602 if (from_insn != i3)
12603 break;
12604
12605 if (! (GET_CODE (XEXP (note, 0)) == REG
12606 ? find_regno_note (i3, REG_UNUSED, REGNO (XEXP (note, 0)))
12607 : find_reg_note (i3, REG_UNUSED, XEXP (note, 0))))
12608 place = i3;
12609 }
12610
12611
12612
12613 else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3))
12614 && ! (GET_CODE (XEXP (note, 0)) == REG
12615 ? find_regno_note (i3, REG_DEAD,
12616 REGNO (XEXP (note, 0)))
12617 : find_reg_note (i3, REG_DEAD, XEXP (note, 0))))
12618 {
12619 PUT_REG_NOTE_KIND (note, REG_DEAD);
12620 place = i3;
12621 }
12622 break;
12623
12624 case REG_EQUAL:
12625 case REG_EQUIV:
12626 case REG_NOALIAS:
12627
12628
12629
12630
12631
12632
12633
12634
12635
12636
12637
12638 if (from_insn == i3
12639 && (XEXP (note, 0) == 0 || CONSTANT_P (XEXP (note, 0))))
12640 place = i3;
12641 break;
12642
12643 case REG_INC:
12644 case REG_NO_CONFLICT:
12645
12646
12647 if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3)))
12648 place = i3;
12649
12650 if (i2 && reg_mentioned_p (XEXP (note, 0), PATTERN (i2)))
12651 {
12652 if (place)
12653 place2 = i2;
12654 else
12655 place = i2;
12656 }
12657 break;
12658
12659 case REG_LABEL:
12660
12661
12662
12663
12664 if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3))
12665 || ((tem = find_reg_note (i3, REG_EQUAL, NULL_RTX))
12666 && GET_CODE (XEXP (tem, 0)) == LABEL_REF
12667 && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0)))
12668 place = i3;
12669
12670 if (i2
12671 && (reg_mentioned_p (XEXP (note, 0), PATTERN (i2))
12672 || ((tem = find_reg_note (i2, REG_EQUAL, NULL_RTX))
12673 && GET_CODE (XEXP (tem, 0)) == LABEL_REF
12674 && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0))))
12675 {
12676 if (place)
12677 place2 = i2;
12678 else
12679 place = i2;
12680 }
12681
12682
12683
12684 if (place && GET_CODE (place) == JUMP_INSN && JUMP_LABEL (place))
12685 {
12686 if (JUMP_LABEL (place) != XEXP (note, 0))
12687 abort ();
12688 if (GET_CODE (JUMP_LABEL (place)) == CODE_LABEL)
12689 LABEL_NUSES (JUMP_LABEL (place))--;
12690 place = 0;
12691 }
12692 if (place2 && GET_CODE (place2) == JUMP_INSN && JUMP_LABEL (place2))
12693 {
12694 if (JUMP_LABEL (place2) != XEXP (note, 0))
12695 abort ();
12696 if (GET_CODE (JUMP_LABEL (place2)) == CODE_LABEL)
12697 LABEL_NUSES (JUMP_LABEL (place2))--;
12698 place2 = 0;
12699 }
12700 break;
12701
12702 case REG_NONNEG:
12703 case REG_WAS_0:
12704
12705
12706
12707
12708 break;
12709
12710 case REG_RETVAL:
12711
12712
12713
12714 if (GET_CODE (from_insn) != NOTE)
12715 place = from_insn;
12716 else
12717 {
12718 tem = find_reg_note (XEXP (note, 0), REG_LIBCALL, NULL_RTX);
12719 place = prev_real_insn (from_insn);
12720 if (tem && place)
12721 XEXP (tem, 0) = place;
12722
12723
12724 else if (XEXP (note, 0) == from_insn)
12725 tem = place = 0;
12726 }
12727 break;
12728
12729 case REG_LIBCALL:
12730
12731 if (GET_CODE (from_insn) != NOTE)
12732 place = from_insn;
12733 else
12734 {
12735 tem = find_reg_note (XEXP (note, 0), REG_RETVAL, NULL_RTX);
12736 place = next_real_insn (from_insn);
12737 if (tem && place)
12738 XEXP (tem, 0) = place;
12739
12740
12741 else if (XEXP (note, 0) == from_insn)
12742 tem = place = 0;
12743 }
12744 break;
12745
12746 case REG_DEAD:
12747
12748
12749
12750
12751
12752
12753
12754
12755
12756
12757
12758
12759
12760
12761 if (from_insn
12762 && GET_CODE (from_insn) == CALL_INSN
12763 && find_reg_fusage (from_insn, USE, XEXP (note, 0)))
12764 place = from_insn;
12765 else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)))
12766 place = i3;
12767 else if (i2 != 0 && next_nonnote_insn (i2) == i3
12768 && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
12769 place = i2;
12770
12771 if (rtx_equal_p (XEXP (note, 0), elim_i2)
12772 || rtx_equal_p (XEXP (note, 0), elim_i1))
12773 break;
12774
12775 if (place == 0)
12776 {
12777 basic_block bb = this_basic_block;
12778
12779 for (tem = PREV_INSN (i3); place == 0; tem = PREV_INSN (tem))
12780 {
12781 if (! INSN_P (tem))
12782 {
12783 if (tem == bb->head)
12784 break;
12785 continue;
12786 }
12787
12788
12789
12790
12791 if (reg_set_p (XEXP (note, 0), PATTERN (tem)))
12792 {
12793 rtx set = single_set (tem);
12794 rtx inner_dest = 0;
12795 #ifdef HAVE_cc0
12796 rtx cc0_setter = NULL_RTX;
12797 #endif
12798
12799 if (set != 0)
12800 for (inner_dest = SET_DEST (set);
12801 (GET_CODE (inner_dest) == STRICT_LOW_PART
12802 || GET_CODE (inner_dest) == SUBREG
12803 || GET_CODE (inner_dest) == ZERO_EXTRACT);
12804 inner_dest = XEXP (inner_dest, 0))
12805 ;
12806
12807
12808
12809
12810
12811
12812
12813
12814
12815 if (set != 0 && ! side_effects_p (SET_SRC (set))
12816 && rtx_equal_p (XEXP (note, 0), inner_dest)
12817 #ifdef HAVE_cc0
12818 && (! reg_mentioned_p (cc0_rtx, SET_SRC (set))
12819 || ((cc0_setter = prev_cc0_setter (tem)) != NULL
12820 && sets_cc0_p (PATTERN (cc0_setter)) > 0))
12821 #endif
12822 )
12823 {
12824
12825
12826
12827
12828
12829 PATTERN (tem) = pc_rtx;
12830
12831 distribute_notes (REG_NOTES (tem), tem, tem,
12832 NULL_RTX, NULL_RTX, NULL_RTX);
12833 distribute_links (LOG_LINKS (tem));
12834
12835 PUT_CODE (tem, NOTE);
12836 NOTE_LINE_NUMBER (tem) = NOTE_INSN_DELETED;
12837 NOTE_SOURCE_FILE (tem) = 0;
12838
12839 #ifdef HAVE_cc0
12840
12841 if (cc0_setter)
12842 {
12843 PATTERN (cc0_setter) = pc_rtx;
12844
12845 distribute_notes (REG_NOTES (cc0_setter),
12846 cc0_setter, cc0_setter,
12847 NULL_RTX, NULL_RTX, NULL_RTX);
12848 distribute_links (LOG_LINKS (cc0_setter));
12849
12850 PUT_CODE (cc0_setter, NOTE);
12851 NOTE_LINE_NUMBER (cc0_setter)
12852 = NOTE_INSN_DELETED;
12853 NOTE_SOURCE_FILE (cc0_setter) = 0;
12854 }
12855 #endif
12856 }
12857
12858
12859
12860 else if (reg_referenced_p (XEXP (note, 0),
12861 PATTERN (tem)))
12862 {
12863 place = tem;
12864
12865 if (! find_regno_note (tem, REG_UNUSED,
12866 REGNO (XEXP (note, 0))))
12867 REG_NOTES (tem)
12868 = gen_rtx_EXPR_LIST (REG_UNUSED, XEXP (note, 0),
12869 REG_NOTES (tem));
12870 }
12871 else
12872 {
12873 PUT_REG_NOTE_KIND (note, REG_UNUSED);
12874
12875
12876
12877 if (! find_regno_note (tem, REG_UNUSED,
12878 REGNO (XEXP (note, 0))))
12879 place = tem;
12880 break;
12881 }
12882 }
12883 else if (reg_referenced_p (XEXP (note, 0), PATTERN (tem))
12884 || (GET_CODE (tem) == CALL_INSN
12885 && find_reg_fusage (tem, USE, XEXP (note, 0))))
12886 {
12887 place = tem;
12888
12889
12890
12891
12892
12893
12894
12895 if (i2 && INSN_UID (place) <= max_uid_cuid
12896 && INSN_CUID (place) > INSN_CUID (i2)
12897 && from_insn
12898 && INSN_CUID (from_insn) > INSN_CUID (i2)
12899 && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
12900 {
12901 rtx links = LOG_LINKS (place);
12902 LOG_LINKS (place) = 0;
12903 distribute_links (links);
12904 }
12905 break;
12906 }
12907
12908 if (tem == bb->head)
12909 break;
12910 }
12911
12912
12913
12914
12915
12916
12917 if (REG_NOTE_KIND (note) == REG_DEAD && place == 0
12918 && REGNO_REG_SET_P (bb->global_live_at_start,
12919 REGNO (XEXP (note, 0))))
12920 {
12921 SET_BIT (refresh_blocks, this_basic_block->index);
12922 need_refresh = 1;
12923 }
12924 }
12925
12926
12927
12928
12929
12930
12931
12932 if (place && REG_NOTE_KIND (note) == REG_DEAD)
12933 {
12934 unsigned int regno = REGNO (XEXP (note, 0));
12935
12936
12937
12938
12939 if (noop_move_p (place))
12940 {
12941 SET_BIT (refresh_blocks, this_basic_block->index);
12942 need_refresh = 1;
12943 }
12944
12945 if (dead_or_set_p (place, XEXP (note, 0))
12946 || reg_bitfield_target_p (XEXP (note, 0), PATTERN (place)))
12947 {
12948
12949
12950
12951 if (reg_last_death[regno] != place)
12952 reg_last_death[regno] = 0;
12953 place = 0;
12954 }
12955 else
12956 reg_last_death[regno] = place;
12957
12958
12959
12960
12961
12962
12963
12964
12965
12966
12967 if (place && regno < FIRST_PSEUDO_REGISTER
12968 && HARD_REGNO_NREGS (regno, GET_MODE (XEXP (note, 0))) > 1)
12969 {
12970 unsigned int endregno
12971 = regno + HARD_REGNO_NREGS (regno,
12972 GET_MODE (XEXP (note, 0)));
12973 int all_used = 1;
12974 unsigned int i;
12975
12976 for (i = regno; i < endregno; i++)
12977 if ((! refers_to_regno_p (i, i + 1, PATTERN (place), 0)
12978 && ! find_regno_fusage (place, USE, i))
12979 || dead_or_set_regno_p (place, i))
12980 all_used = 0;
12981
12982 if (! all_used)
12983 {
12984
12985
12986
12987 for (i = regno; i < endregno;
12988 i += HARD_REGNO_NREGS (i, reg_raw_mode[i]))
12989 {
12990 rtx piece = regno_reg_rtx[i];
12991 basic_block bb = this_basic_block;
12992
12993 if (! dead_or_set_p (place, piece)
12994 && ! reg_bitfield_target_p (piece,
12995 PATTERN (place)))
12996 {
12997 rtx new_note
12998 = gen_rtx_EXPR_LIST (REG_DEAD, piece, NULL_RTX);
12999
13000 distribute_notes (new_note, place, place,
13001 NULL_RTX, NULL_RTX, NULL_RTX);
13002 }
13003 else if (! refers_to_regno_p (i, i + 1,
13004 PATTERN (place), 0)
13005 && ! find_regno_fusage (place, USE, i))
13006 for (tem = PREV_INSN (place); ;
13007 tem = PREV_INSN (tem))
13008 {
13009 if (! INSN_P (tem))
13010 {
13011 if (tem == bb->head)
13012 {
13013 SET_BIT (refresh_blocks,
13014 this_basic_block->index);
13015 need_refresh = 1;
13016 break;
13017 }
13018 continue;
13019 }
13020 if (dead_or_set_p (tem, piece)
13021 || reg_bitfield_target_p (piece,
13022 PATTERN (tem)))
13023 {
13024 REG_NOTES (tem)
13025 = gen_rtx_EXPR_LIST (REG_UNUSED, piece,
13026 REG_NOTES (tem));
13027 break;
13028 }
13029 }
13030
13031 }
13032
13033 place = 0;
13034 }
13035 }
13036 }
13037 break;
13038
13039 default:
13040
13041
13042 abort ();
13043 }
13044
13045 if (place)
13046 {
13047 XEXP (note, 1) = REG_NOTES (place);
13048 REG_NOTES (place) = note;
13049 }
13050 else if ((REG_NOTE_KIND (note) == REG_DEAD
13051 || REG_NOTE_KIND (note) == REG_UNUSED)
13052 && GET_CODE (XEXP (note, 0)) == REG)
13053 REG_N_DEATHS (REGNO (XEXP (note, 0)))--;
13054
13055 if (place2)
13056 {
13057 if ((REG_NOTE_KIND (note) == REG_DEAD
13058 || REG_NOTE_KIND (note) == REG_UNUSED)
13059 && GET_CODE (XEXP (note, 0)) == REG)
13060 REG_N_DEATHS (REGNO (XEXP (note, 0)))++;
13061
13062 REG_NOTES (place2) = gen_rtx_fmt_ee (GET_CODE (note),
13063 REG_NOTE_KIND (note),
13064 XEXP (note, 0),
13065 REG_NOTES (place2));
13066 }
13067 }
13068 }
13069
13070
13071
13072
13073
13074 static void
13075 distribute_links (links)
13076 rtx links;
13077 {
13078 rtx link, next_link;
13079
13080 for (link = links; link; link = next_link)
13081 {
13082 rtx place = 0;
13083 rtx insn;
13084 rtx set, reg;
13085
13086 next_link = XEXP (link, 1);
13087
13088
13089
13090
13091
13092
13093
13094
13095
13096
13097
13098
13099 if (GET_CODE (XEXP (link, 0)) == NOTE
13100 || (set = single_set (XEXP (link, 0))) == 0)
13101 continue;
13102
13103 reg = SET_DEST (set);
13104 while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT
13105 || GET_CODE (reg) == SIGN_EXTRACT
13106 || GET_CODE (reg) == STRICT_LOW_PART)
13107 reg = XEXP (reg, 0);
13108
13109
13110
13111
13112
13113
13114
13115
13116
13117
13118 for (insn = NEXT_INSN (XEXP (link, 0));
13119 (insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR
13120 || this_basic_block->next_bb->head != insn));
13121 insn = NEXT_INSN (insn))
13122 if (INSN_P (insn) && reg_overlap_mentioned_p (reg, PATTERN (insn)))
13123 {
13124 if (reg_referenced_p (reg, PATTERN (insn)))
13125 place = insn;
13126 break;
13127 }
13128 else if (GET_CODE (insn) == CALL_INSN
13129 && find_reg_fusage (insn, USE, reg))
13130 {
13131 place = insn;
13132 break;
13133 }
13134
13135
13136
13137
13138 if (place)
13139 {
13140 rtx link2;
13141
13142 for (link2 = LOG_LINKS (place); link2; link2 = XEXP (link2, 1))
13143 if (XEXP (link2, 0) == XEXP (link, 0))
13144 break;
13145
13146 if (link2 == 0)
13147 {
13148 XEXP (link, 1) = LOG_LINKS (place);
13149 LOG_LINKS (place) = link;
13150
13151
13152
13153 if (added_links_insn == 0
13154 || INSN_CUID (added_links_insn) > INSN_CUID (place))
13155 added_links_insn = place;
13156 }
13157 }
13158 }
13159 }
13160
13161
13162
13163 static int
13164 insn_cuid (insn)
13165 rtx insn;
13166 {
13167 while (insn != 0 && INSN_UID (insn) > max_uid_cuid
13168 && GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == USE)
13169 insn = NEXT_INSN (insn);
13170
13171 if (INSN_UID (insn) > max_uid_cuid)
13172 abort ();
13173
13174 return INSN_CUID (insn);
13175 }
13176
13177 void
13178 dump_combine_stats (file)
13179 FILE *file;
13180 {
13181 fnotice
13182 (file,
13183 ";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n",
13184 combine_attempts, combine_merges, combine_extras, combine_successes);
13185 }
13186
13187 void
13188 dump_combine_total_stats (file)
13189 FILE *file;
13190 {
13191 fnotice
13192 (file,
13193 "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n",
13194 total_attempts, total_merges, total_extras, total_successes);
13195 }