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