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