00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 #define REG_OK_STRICT
00092
00093 #include "config.h"
00094 #include "system.h"
00095 #include "rtl.h"
00096 #include "tm_p.h"
00097 #include "insn-config.h"
00098 #include "expr.h"
00099 #include "optabs.h"
00100 #include "recog.h"
00101 #include "reload.h"
00102 #include "regs.h"
00103 #include "hard-reg-set.h"
00104 #include "flags.h"
00105 #include "real.h"
00106 #include "output.h"
00107 #include "function.h"
00108 #include "toplev.h"
00109 #ifdef SGI_MONGOOSE
00110
00111 #include "defaults.h"
00112 #endif
00113
00114 #ifndef REGISTER_MOVE_COST
00115 #define REGISTER_MOVE_COST(m, x, y) 2
00116 #endif
00117
00118 #ifndef REGNO_MODE_OK_FOR_BASE_P
00119 #define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
00120 #endif
00121
00122 #ifndef REG_MODE_OK_FOR_BASE_P
00123 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
00124 #endif
00125
00126
00127
00128 int n_reloads;
00129 struct reload rld[MAX_RELOADS];
00130
00131
00132
00133 int n_earlyclobbers;
00134 rtx reload_earlyclobbers[MAX_RECOG_OPERANDS];
00135
00136 int reload_n_operands;
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 static int replace_reloads;
00147
00148
00149 struct replacement
00150 {
00151 rtx *where;
00152 rtx *subreg_loc;
00153
00154 int what;
00155 enum machine_mode mode;
00156 };
00157
00158 static struct replacement replacements[MAX_RECOG_OPERANDS * ((MAX_REGS_PER_ADDRESS * 2) + 1)];
00159
00160
00161 static int n_replacements;
00162
00163
00164 struct decomposition
00165 {
00166 int reg_flag;
00167 int safe;
00168 rtx base;
00169 HOST_WIDE_INT start;
00170 HOST_WIDE_INT end;
00171 };
00172
00173 #ifdef SECONDARY_MEMORY_NEEDED
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 static rtx secondary_memlocs[NUM_MACHINE_MODES];
00184 static rtx secondary_memlocs_elim[NUM_MACHINE_MODES][MAX_RECOG_OPERANDS];
00185 #endif
00186
00187
00188
00189 static rtx this_insn;
00190
00191
00192 static int this_insn_is_asm;
00193
00194
00195
00196
00197 static int hard_regs_live_known;
00198
00199
00200
00201
00202
00203 static short *static_reload_reg_p;
00204
00205
00206 static int subst_reg_equivs_changed;
00207
00208
00209
00210 static int output_reloadnum;
00211
00212
00213 #define MATCHES(x, y) \
00214 (x == y || (x != 0 && (GET_CODE (x) == REG \
00215 ? GET_CODE (y) == REG && REGNO (x) == REGNO (y) \
00216 : rtx_equal_p (x, y) && ! side_effects_p (x))))
00217
00218
00219
00220 #define MERGABLE_RELOADS(when1, when2, op1, op2) \
00221 ((when1) == RELOAD_OTHER || (when2) == RELOAD_OTHER \
00222 || ((when1) == (when2) && (op1) == (op2)) \
00223 || ((when1) == RELOAD_FOR_INPUT && (when2) == RELOAD_FOR_INPUT) \
00224 || ((when1) == RELOAD_FOR_OPERAND_ADDRESS \
00225 && (when2) == RELOAD_FOR_OPERAND_ADDRESS) \
00226 || ((when1) == RELOAD_FOR_OTHER_ADDRESS \
00227 && (when2) == RELOAD_FOR_OTHER_ADDRESS))
00228
00229
00230 #define MERGE_TO_OTHER(when1, when2, op1, op2) \
00231 ((when1) != (when2) \
00232 || ! ((op1) == (op2) \
00233 || (when1) == RELOAD_FOR_INPUT \
00234 || (when1) == RELOAD_FOR_OPERAND_ADDRESS \
00235 || (when1) == RELOAD_FOR_OTHER_ADDRESS))
00236
00237
00238
00239 #define ADDR_TYPE(type) \
00240 ((type) == RELOAD_FOR_INPUT_ADDRESS \
00241 ? RELOAD_FOR_INPADDR_ADDRESS \
00242 : ((type) == RELOAD_FOR_OUTPUT_ADDRESS \
00243 ? RELOAD_FOR_OUTADDR_ADDRESS \
00244 : (type)))
00245
00246 #ifdef HAVE_SECONDARY_RELOADS
00247 static int push_secondary_reload PARAMS ((int, rtx, int, int, enum reg_class,
00248 enum machine_mode, enum reload_type,
00249 enum insn_code *));
00250 #endif
00251 static enum reg_class find_valid_class PARAMS ((enum machine_mode, int,
00252 unsigned int));
00253 static int reload_inner_reg_of_subreg PARAMS ((rtx, enum machine_mode, int));
00254 static void push_replacement PARAMS ((rtx *, int, enum machine_mode));
00255 static void dup_replacements PARAMS ((rtx *, rtx *));
00256 static void combine_reloads PARAMS ((void));
00257 static int find_reusable_reload PARAMS ((rtx *, rtx, enum reg_class,
00258 enum reload_type, int, int));
00259 static rtx find_dummy_reload PARAMS ((rtx, rtx, rtx *, rtx *,
00260 enum machine_mode, enum machine_mode,
00261 enum reg_class, int, int));
00262 static int hard_reg_set_here_p PARAMS ((unsigned int, unsigned int, rtx));
00263 static struct decomposition decompose PARAMS ((rtx));
00264 static int immune_p PARAMS ((rtx, rtx, struct decomposition));
00265 static int alternative_allows_memconst PARAMS ((const char *, int));
00266 static rtx find_reloads_toplev PARAMS ((rtx, int, enum reload_type, int,
00267 int, rtx, int *));
00268 static rtx make_memloc PARAMS ((rtx, int));
00269 static int maybe_memory_address_p PARAMS ((enum machine_mode, rtx, rtx *));
00270 static int find_reloads_address PARAMS ((enum machine_mode, rtx *, rtx, rtx *,
00271 int, enum reload_type, int, rtx));
00272 static rtx subst_reg_equivs PARAMS ((rtx, rtx));
00273 static rtx subst_indexed_address PARAMS ((rtx));
00274 static void update_auto_inc_notes PARAMS ((rtx, int, int));
00275 static int find_reloads_address_1 PARAMS ((enum machine_mode, rtx, int, rtx *,
00276 int, enum reload_type,int, rtx));
00277 static void find_reloads_address_part PARAMS ((rtx, rtx *, enum reg_class,
00278 enum machine_mode, int,
00279 enum reload_type, int));
00280 static rtx find_reloads_subreg_address PARAMS ((rtx, int, int,
00281 enum reload_type, int, rtx));
00282 static void copy_replacements_1 PARAMS ((rtx *, rtx *, int));
00283 static int find_inc_amount PARAMS ((rtx, rtx));
00284
00285 #ifdef HAVE_SECONDARY_RELOADS
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 static int
00297 push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
00298 type, picode)
00299 int in_p;
00300 rtx x;
00301 int opnum;
00302 int optional;
00303 enum reg_class reload_class;
00304 enum machine_mode reload_mode;
00305 enum reload_type type;
00306 enum insn_code *picode;
00307 {
00308 enum reg_class class = NO_REGS;
00309 enum machine_mode mode = reload_mode;
00310 enum insn_code icode = CODE_FOR_nothing;
00311 enum reg_class t_class = NO_REGS;
00312 enum machine_mode t_mode = VOIDmode;
00313 enum insn_code t_icode = CODE_FOR_nothing;
00314 enum reload_type secondary_type;
00315 int s_reload, t_reload = -1;
00316
00317 if (type == RELOAD_FOR_INPUT_ADDRESS
00318 || type == RELOAD_FOR_OUTPUT_ADDRESS
00319 || type == RELOAD_FOR_INPADDR_ADDRESS
00320 || type == RELOAD_FOR_OUTADDR_ADDRESS)
00321 secondary_type = type;
00322 else
00323 secondary_type = in_p ? RELOAD_FOR_INPUT_ADDRESS : RELOAD_FOR_OUTPUT_ADDRESS;
00324
00325 *picode = CODE_FOR_nothing;
00326
00327
00328
00329 if (GET_CODE (x) == SUBREG
00330 && (GET_MODE_SIZE (GET_MODE (x))
00331 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
00332 {
00333 x = SUBREG_REG (x);
00334 reload_mode = GET_MODE (x);
00335 }
00336
00337
00338
00339
00340
00341
00342
00343 if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER
00344 && reg_equiv_mem[REGNO (x)] != 0)
00345 x = reg_equiv_mem[REGNO (x)];
00346
00347 #ifdef SECONDARY_INPUT_RELOAD_CLASS
00348 if (in_p)
00349 class = SECONDARY_INPUT_RELOAD_CLASS (reload_class, reload_mode, x);
00350 #endif
00351
00352 #ifdef SECONDARY_OUTPUT_RELOAD_CLASS
00353 if (! in_p)
00354 class = SECONDARY_OUTPUT_RELOAD_CLASS (reload_class, reload_mode, x);
00355 #endif
00356
00357
00358 if (class == NO_REGS)
00359 return -1;
00360
00361
00362
00363
00364 icode = (in_p ? reload_in_optab[(int) reload_mode]
00365 : reload_out_optab[(int) reload_mode]);
00366
00367 if (icode != CODE_FOR_nothing
00368 && insn_data[(int) icode].operand[in_p].predicate
00369 && (! (insn_data[(int) icode].operand[in_p].predicate) (x, reload_mode)))
00370 icode = CODE_FOR_nothing;
00371
00372
00373
00374
00375
00376
00377
00378 if (icode != CODE_FOR_nothing)
00379 {
00380
00381
00382
00383
00384
00385 enum reg_class insn_class;
00386
00387 if (insn_data[(int) icode].operand[!in_p].constraint[0] == 0)
00388 insn_class = ALL_REGS;
00389 else
00390 {
00391 char insn_letter
00392 = insn_data[(int) icode].operand[!in_p].constraint[in_p];
00393 insn_class
00394 = (insn_letter == 'r' ? GENERAL_REGS
00395 : REG_CLASS_FROM_LETTER ((unsigned char) insn_letter));
00396
00397 if (insn_class == NO_REGS)
00398 abort ();
00399 if (in_p
00400 && insn_data[(int) icode].operand[!in_p].constraint[0] != '=')
00401 abort ();
00402 }
00403
00404
00405 if (insn_data[(int) icode].operand[2].constraint[0] != '='
00406 || insn_data[(int) icode].operand[2].constraint[1] != '&')
00407 abort ();
00408
00409 if (reg_class_subset_p (reload_class, insn_class))
00410 mode = insn_data[(int) icode].operand[2].mode;
00411 else
00412 {
00413 char t_letter = insn_data[(int) icode].operand[2].constraint[2];
00414 class = insn_class;
00415 t_mode = insn_data[(int) icode].operand[2].mode;
00416 t_class = (t_letter == 'r' ? GENERAL_REGS
00417 : REG_CLASS_FROM_LETTER ((unsigned char) t_letter));
00418 t_icode = icode;
00419 icode = CODE_FOR_nothing;
00420 }
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 if (in_p && class == reload_class && icode == CODE_FOR_nothing
00438 && t_icode == CODE_FOR_nothing)
00439 abort ();
00440
00441
00442
00443
00444 if (t_class != NO_REGS)
00445 {
00446 for (t_reload = 0; t_reload < n_reloads; t_reload++)
00447 if (rld[t_reload].secondary_p
00448 && (reg_class_subset_p (t_class, rld[t_reload].class)
00449 || reg_class_subset_p (rld[t_reload].class, t_class))
00450 && ((in_p && rld[t_reload].inmode == t_mode)
00451 || (! in_p && rld[t_reload].outmode == t_mode))
00452 && ((in_p && (rld[t_reload].secondary_in_icode
00453 == CODE_FOR_nothing))
00454 || (! in_p &&(rld[t_reload].secondary_out_icode
00455 == CODE_FOR_nothing)))
00456 && (reg_class_size[(int) t_class] == 1 || SMALL_REGISTER_CLASSES)
00457 && MERGABLE_RELOADS (secondary_type,
00458 rld[t_reload].when_needed,
00459 opnum, rld[t_reload].opnum))
00460 {
00461 if (in_p)
00462 rld[t_reload].inmode = t_mode;
00463 if (! in_p)
00464 rld[t_reload].outmode = t_mode;
00465
00466 if (reg_class_subset_p (t_class, rld[t_reload].class))
00467 rld[t_reload].class = t_class;
00468
00469 rld[t_reload].opnum = MIN (rld[t_reload].opnum, opnum);
00470 rld[t_reload].optional &= optional;
00471 rld[t_reload].secondary_p = 1;
00472 if (MERGE_TO_OTHER (secondary_type, rld[t_reload].when_needed,
00473 opnum, rld[t_reload].opnum))
00474 rld[t_reload].when_needed = RELOAD_OTHER;
00475 }
00476
00477 if (t_reload == n_reloads)
00478 {
00479
00480 rld[t_reload].in = rld[t_reload].out = 0;
00481 rld[t_reload].class = t_class;
00482 rld[t_reload].inmode = in_p ? t_mode : VOIDmode;
00483 rld[t_reload].outmode = ! in_p ? t_mode : VOIDmode;
00484 rld[t_reload].reg_rtx = 0;
00485 rld[t_reload].optional = optional;
00486 rld[t_reload].inc = 0;
00487
00488 rld[t_reload].nocombine = 1;
00489 rld[t_reload].in_reg = 0;
00490 rld[t_reload].out_reg = 0;
00491 rld[t_reload].opnum = opnum;
00492 rld[t_reload].when_needed = secondary_type;
00493 rld[t_reload].secondary_in_reload = -1;
00494 rld[t_reload].secondary_out_reload = -1;
00495 rld[t_reload].secondary_in_icode = CODE_FOR_nothing;
00496 rld[t_reload].secondary_out_icode = CODE_FOR_nothing;
00497 rld[t_reload].secondary_p = 1;
00498
00499 n_reloads++;
00500 }
00501 }
00502
00503
00504 for (s_reload = 0; s_reload < n_reloads; s_reload++)
00505 if (rld[s_reload].secondary_p
00506 && (reg_class_subset_p (class, rld[s_reload].class)
00507 || reg_class_subset_p (rld[s_reload].class, class))
00508 && ((in_p && rld[s_reload].inmode == mode)
00509 || (! in_p && rld[s_reload].outmode == mode))
00510 && ((in_p && rld[s_reload].secondary_in_reload == t_reload)
00511 || (! in_p && rld[s_reload].secondary_out_reload == t_reload))
00512 && ((in_p && rld[s_reload].secondary_in_icode == t_icode)
00513 || (! in_p && rld[s_reload].secondary_out_icode == t_icode))
00514 && (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
00515 && MERGABLE_RELOADS (secondary_type, rld[s_reload].when_needed,
00516 opnum, rld[s_reload].opnum))
00517 {
00518 if (in_p)
00519 rld[s_reload].inmode = mode;
00520 if (! in_p)
00521 rld[s_reload].outmode = mode;
00522
00523 if (reg_class_subset_p (class, rld[s_reload].class))
00524 rld[s_reload].class = class;
00525
00526 rld[s_reload].opnum = MIN (rld[s_reload].opnum, opnum);
00527 rld[s_reload].optional &= optional;
00528 rld[s_reload].secondary_p = 1;
00529 if (MERGE_TO_OTHER (secondary_type, rld[s_reload].when_needed,
00530 opnum, rld[s_reload].opnum))
00531 rld[s_reload].when_needed = RELOAD_OTHER;
00532 }
00533
00534 if (s_reload == n_reloads)
00535 {
00536 #ifdef SECONDARY_MEMORY_NEEDED
00537
00538
00539
00540
00541
00542 if (in_p && icode == CODE_FOR_nothing
00543 && SECONDARY_MEMORY_NEEDED (class, reload_class, mode))
00544 {
00545 get_secondary_mem (x, reload_mode, opnum, type);
00546
00547
00548
00549 s_reload = n_reloads;
00550 }
00551 #endif
00552
00553
00554 rld[s_reload].in = rld[s_reload].out = 0;
00555 rld[s_reload].class = class;
00556
00557 rld[s_reload].inmode = in_p ? mode : VOIDmode;
00558 rld[s_reload].outmode = ! in_p ? mode : VOIDmode;
00559 rld[s_reload].reg_rtx = 0;
00560 rld[s_reload].optional = optional;
00561 rld[s_reload].inc = 0;
00562
00563 rld[s_reload].nocombine = 1;
00564 rld[s_reload].in_reg = 0;
00565 rld[s_reload].out_reg = 0;
00566 rld[s_reload].opnum = opnum;
00567 rld[s_reload].when_needed = secondary_type;
00568 rld[s_reload].secondary_in_reload = in_p ? t_reload : -1;
00569 rld[s_reload].secondary_out_reload = ! in_p ? t_reload : -1;
00570 rld[s_reload].secondary_in_icode = in_p ? t_icode : CODE_FOR_nothing;
00571 rld[s_reload].secondary_out_icode
00572 = ! in_p ? t_icode : CODE_FOR_nothing;
00573 rld[s_reload].secondary_p = 1;
00574
00575 n_reloads++;
00576
00577 #ifdef SECONDARY_MEMORY_NEEDED
00578 if (! in_p && icode == CODE_FOR_nothing
00579 && SECONDARY_MEMORY_NEEDED (reload_class, class, mode))
00580 get_secondary_mem (x, mode, opnum, type);
00581 #endif
00582 }
00583
00584 *picode = icode;
00585 return s_reload;
00586 }
00587 #endif
00588
00589 #ifdef SECONDARY_MEMORY_NEEDED
00590
00591
00592
00593
00594
00595 rtx
00596 get_secondary_mem (x, mode, opnum, type)
00597 rtx x ATTRIBUTE_UNUSED;
00598 enum machine_mode mode;
00599 int opnum;
00600 enum reload_type type;
00601 {
00602 rtx loc;
00603 int mem_valid;
00604
00605
00606
00607
00608
00609
00610 #ifdef SECONDARY_MEMORY_NEEDED_MODE
00611 mode = SECONDARY_MEMORY_NEEDED_MODE (mode);
00612 #else
00613 if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD && INTEGRAL_MODE_P (mode))
00614 mode = mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0);
00615 #endif
00616
00617
00618 if (secondary_memlocs_elim[(int) mode][opnum] != 0)
00619 return secondary_memlocs_elim[(int) mode][opnum];
00620
00621
00622
00623
00624
00625 if (secondary_memlocs[(int) mode] == 0)
00626 {
00627 #ifdef SECONDARY_MEMORY_NEEDED_RTX
00628 secondary_memlocs[(int) mode] = SECONDARY_MEMORY_NEEDED_RTX (mode);
00629 #else
00630 secondary_memlocs[(int) mode]
00631 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
00632 #endif
00633 }
00634
00635
00636
00637
00638 loc = eliminate_regs (secondary_memlocs[(int) mode], VOIDmode, NULL_RTX);
00639 mem_valid = strict_memory_address_p (mode, XEXP (loc, 0));
00640
00641 if (! mem_valid && loc == secondary_memlocs[(int) mode])
00642 loc = copy_rtx (loc);
00643
00644
00645
00646
00647
00648
00649
00650
00651 if (! mem_valid)
00652 {
00653 type = (type == RELOAD_FOR_INPUT ? RELOAD_FOR_INPUT_ADDRESS
00654 : type == RELOAD_FOR_OUTPUT ? RELOAD_FOR_OUTPUT_ADDRESS
00655 : RELOAD_OTHER);
00656
00657 find_reloads_address (mode, &loc, XEXP (loc, 0), &XEXP (loc, 0),
00658 opnum, type, 0, 0);
00659 }
00660
00661 secondary_memlocs_elim[(int) mode][opnum] = loc;
00662 return loc;
00663 }
00664
00665
00666
00667 void
00668 clear_secondary_mem ()
00669 {
00670 memset ((char *) secondary_memlocs, 0, sizeof secondary_memlocs);
00671 }
00672 #endif
00673
00674
00675
00676
00677
00678 static enum reg_class
00679 find_valid_class (m1, n, dest_regno)
00680 enum machine_mode m1 ATTRIBUTE_UNUSED;
00681 int n;
00682 unsigned int dest_regno;
00683 {
00684 int best_cost = -1;
00685 int class;
00686 int regno;
00687 enum reg_class best_class = NO_REGS;
00688 enum reg_class dest_class = REGNO_REG_CLASS (dest_regno);
00689 unsigned int best_size = 0;
00690 int cost;
00691
00692 for (class = 1; class < N_REG_CLASSES; class++)
00693 {
00694 int bad = 0;
00695 for (regno = 0; regno < FIRST_PSEUDO_REGISTER && ! bad; regno++)
00696 if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
00697 && TEST_HARD_REG_BIT (reg_class_contents[class], regno + n)
00698 && ! HARD_REGNO_MODE_OK (regno + n, m1))
00699 bad = 1;
00700
00701 if (bad)
00702 continue;
00703 cost = REGISTER_MOVE_COST (m1, class, dest_class);
00704
00705 if ((reg_class_size[class] > best_size
00706 && (best_cost < 0 || best_cost >= cost))
00707 || best_cost > cost)
00708 {
00709 best_class = class;
00710 best_size = reg_class_size[class];
00711 best_cost = REGISTER_MOVE_COST (m1, class, dest_class);
00712 }
00713 }
00714
00715 if (best_size == 0)
00716 abort ();
00717
00718 return best_class;
00719 }
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729 static int
00730 find_reusable_reload (p_in, out, class, type, opnum, dont_share)
00731 rtx *p_in, out;
00732 enum reg_class class;
00733 enum reload_type type;
00734 int opnum, dont_share;
00735 {
00736 rtx in = *p_in;
00737 int i;
00738
00739
00740
00741 if (earlyclobber_operand_p (out))
00742 return n_reloads;
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753 for (i = 0; i < n_reloads; i++)
00754 if ((reg_class_subset_p (class, rld[i].class)
00755 || reg_class_subset_p (rld[i].class, class))
00756
00757 && (rld[i].reg_rtx == 0
00758 || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
00759 true_regnum (rld[i].reg_rtx)))
00760 && ((in != 0 && MATCHES (rld[i].in, in) && ! dont_share
00761 && (out == 0 || rld[i].out == 0 || MATCHES (rld[i].out, out)))
00762 || (out != 0 && MATCHES (rld[i].out, out)
00763 && (in == 0 || rld[i].in == 0 || MATCHES (rld[i].in, in))))
00764 && (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
00765 && (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
00766 && MERGABLE_RELOADS (type, rld[i].when_needed, opnum, rld[i].opnum))
00767 return i;
00768
00769
00770
00771
00772
00773
00774 for (i = 0; i < n_reloads; i++)
00775 if ((reg_class_subset_p (class, rld[i].class)
00776 || reg_class_subset_p (rld[i].class, class))
00777
00778
00779 && (rld[i].reg_rtx == 0
00780 || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
00781 true_regnum (rld[i].reg_rtx)))
00782 && out == 0 && rld[i].out == 0 && rld[i].in != 0
00783 && ((GET_CODE (in) == REG
00784 && GET_RTX_CLASS (GET_CODE (rld[i].in)) == 'a'
00785 && MATCHES (XEXP (rld[i].in, 0), in))
00786 || (GET_CODE (rld[i].in) == REG
00787 && GET_RTX_CLASS (GET_CODE (in)) == 'a'
00788 && MATCHES (XEXP (in, 0), rld[i].in)))
00789 && (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
00790 && (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
00791 && MERGABLE_RELOADS (type, rld[i].when_needed,
00792 opnum, rld[i].opnum))
00793 {
00794
00795
00796 if (GET_CODE (in) == REG)
00797 *p_in = rld[i].in;
00798 return i;
00799 }
00800 return n_reloads;
00801 }
00802
00803
00804
00805
00806 static int
00807 reload_inner_reg_of_subreg (x, mode, output)
00808 rtx x;
00809 enum machine_mode mode;
00810 int output;
00811 {
00812 rtx inner;
00813
00814
00815 if (GET_CODE (x) != SUBREG)
00816 return 0;
00817
00818 inner = SUBREG_REG (x);
00819
00820
00821 if (CONSTANT_P (inner) || GET_CODE (inner) == PLUS)
00822 return 1;
00823
00824
00825
00826 if (GET_CODE (inner) != REG
00827 || REGNO (inner) >= FIRST_PSEUDO_REGISTER)
00828 return 0;
00829
00830 if (!subreg_offset_representable_p
00831 (REGNO (SUBREG_REG (x)),
00832 GET_MODE (SUBREG_REG (x)),
00833 SUBREG_BYTE (x),
00834 GET_MODE (x)))
00835 return 1;
00836
00837
00838 if (! HARD_REGNO_MODE_OK (subreg_regno (x), mode))
00839 return 1;
00840
00841
00842
00843
00844 return (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
00845 && output
00846 && GET_MODE_SIZE (GET_MODE (inner)) > UNITS_PER_WORD
00847 && ((GET_MODE_SIZE (GET_MODE (inner)) / UNITS_PER_WORD)
00848 != (int) HARD_REGNO_NREGS (REGNO (inner), GET_MODE (inner))));
00849 }
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884 int
00885 push_reload (in, out, inloc, outloc, class,
00886 inmode, outmode, strict_low, optional, opnum, type)
00887 rtx in, out;
00888 rtx *inloc, *outloc;
00889 enum reg_class class;
00890 enum machine_mode inmode, outmode;
00891 int strict_low;
00892 int optional;
00893 int opnum;
00894 enum reload_type type;
00895 {
00896 int i;
00897 int dont_share = 0;
00898 int dont_remove_subreg = 0;
00899 rtx *in_subreg_loc = 0, *out_subreg_loc = 0;
00900 int secondary_in_reload = -1, secondary_out_reload = -1;
00901 enum insn_code secondary_in_icode = CODE_FOR_nothing;
00902 enum insn_code secondary_out_icode = CODE_FOR_nothing;
00903
00904
00905
00906
00907 if (inmode == VOIDmode && in != 0)
00908 inmode = GET_MODE (in);
00909 if (outmode == VOIDmode && out != 0)
00910 outmode = GET_MODE (out);
00911
00912
00913
00914
00915
00916 if (in != 0 && GET_CODE (in) == REG)
00917 {
00918 int regno = REGNO (in);
00919
00920 if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
00921 && reg_equiv_constant[regno] != 0)
00922 in = reg_equiv_constant[regno];
00923 }
00924
00925
00926
00927
00928 if (out != 0 && GET_CODE (out) == REG)
00929 {
00930 int regno = REGNO (out);
00931
00932 if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
00933 && reg_equiv_constant[regno] != 0)
00934 out = reg_equiv_constant[regno];
00935 }
00936
00937
00938
00939 if (in != 0 && out != 0 && GET_CODE (in) == MEM && rtx_equal_p (in, out))
00940 switch (GET_CODE (XEXP (in, 0)))
00941 {
00942 case POST_INC: case POST_DEC: case POST_MODIFY:
00943 in = replace_equiv_address_nv (in, XEXP (XEXP (in, 0), 0));
00944 break;
00945
00946 case PRE_INC: case PRE_DEC: case PRE_MODIFY:
00947 out = replace_equiv_address_nv (out, XEXP (XEXP (out, 0), 0));
00948 break;
00949
00950 default:
00951 break;
00952 }
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984 if (in != 0 && GET_CODE (in) == SUBREG
00985 && (subreg_lowpart_p (in) || strict_low)
00986 #ifdef CANNOT_CHANGE_MODE_CLASS
00987 && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)), inmode, class)
00988 #endif
00989 && (CONSTANT_P (SUBREG_REG (in))
00990 || GET_CODE (SUBREG_REG (in)) == PLUS
00991 || strict_low
00992 || (((GET_CODE (SUBREG_REG (in)) == REG
00993 && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
00994 || GET_CODE (SUBREG_REG (in)) == MEM)
00995 && ((GET_MODE_SIZE (inmode)
00996 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
00997 #ifdef LOAD_EXTEND_OP
00998 || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
00999 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
01000 <= UNITS_PER_WORD)
01001 && (GET_MODE_SIZE (inmode)
01002 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
01003 && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
01004 && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != NIL)
01005 #endif
01006 #ifdef WORD_REGISTER_OPERATIONS
01007 || ((GET_MODE_SIZE (inmode)
01008 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
01009 && ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD ==
01010 ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1)
01011 / UNITS_PER_WORD)))
01012 #endif
01013 ))
01014 || (GET_CODE (SUBREG_REG (in)) == REG
01015 && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
01016
01017
01018 && (out == 0 || subreg_lowpart_p (in))
01019 && ((GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
01020 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
01021 > UNITS_PER_WORD)
01022 && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
01023 / UNITS_PER_WORD)
01024 != (int) HARD_REGNO_NREGS (REGNO (SUBREG_REG (in)),
01025 GET_MODE (SUBREG_REG (in)))))
01026 || ! HARD_REGNO_MODE_OK (subreg_regno (in), inmode)))
01027 #ifdef SECONDARY_INPUT_RELOAD_CLASS
01028 || (SECONDARY_INPUT_RELOAD_CLASS (class, inmode, in) != NO_REGS
01029 && (SECONDARY_INPUT_RELOAD_CLASS (class,
01030 GET_MODE (SUBREG_REG (in)),
01031 SUBREG_REG (in))
01032 == NO_REGS))
01033 #endif
01034 #ifdef CANNOT_CHANGE_MODE_CLASS
01035 || (GET_CODE (SUBREG_REG (in)) == REG
01036 && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
01037 && REG_CANNOT_CHANGE_MODE_P
01038 (REGNO (SUBREG_REG (in)), GET_MODE (SUBREG_REG (in)), inmode))
01039 #endif
01040 ))
01041 {
01042 in_subreg_loc = inloc;
01043 inloc = &SUBREG_REG (in);
01044 in = *inloc;
01045 #if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
01046 if (GET_CODE (in) == MEM)
01047
01048
01049 if (GET_MODE_SIZE (GET_MODE (in)) > GET_MODE_SIZE (inmode))
01050 abort ();
01051 #endif
01052 inmode = GET_MODE (in);
01053 }
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065 if (in != 0 && reload_inner_reg_of_subreg (in, inmode, 0))
01066 {
01067 enum reg_class in_class = class;
01068
01069 if (GET_CODE (SUBREG_REG (in)) == REG)
01070 in_class
01071 = find_valid_class (inmode,
01072 subreg_regno_offset (REGNO (SUBREG_REG (in)),
01073 GET_MODE (SUBREG_REG (in)),
01074 SUBREG_BYTE (in),
01075 GET_MODE (in)),
01076 REGNO (SUBREG_REG (in)));
01077
01078
01079
01080
01081
01082
01083 push_reload (SUBREG_REG (in), NULL_RTX, &SUBREG_REG (in), (rtx *) 0,
01084 in_class, VOIDmode, VOIDmode, 0, 0, opnum, type);
01085 dont_remove_subreg = 1;
01086 }
01087
01088
01089
01090
01091
01092
01093
01094 if (out != 0 && GET_CODE (out) == SUBREG
01095 && (subreg_lowpart_p (out) || strict_low)
01096 #ifdef CANNOT_CHANGE_MODE_CLASS
01097 && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (out)), outmode, class)
01098 #endif
01099 && (CONSTANT_P (SUBREG_REG (out))
01100 || strict_low
01101 || (((GET_CODE (SUBREG_REG (out)) == REG
01102 && REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
01103 || GET_CODE (SUBREG_REG (out)) == MEM)
01104 && ((GET_MODE_SIZE (outmode)
01105 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
01106 #ifdef WORD_REGISTER_OPERATIONS
01107 || ((GET_MODE_SIZE (outmode)
01108 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
01109 && ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD ==
01110 ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1)
01111 / UNITS_PER_WORD)))
01112 #endif
01113 ))
01114 || (GET_CODE (SUBREG_REG (out)) == REG
01115 && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
01116 && ((GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
01117 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
01118 > UNITS_PER_WORD)
01119 && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
01120 / UNITS_PER_WORD)
01121 != (int) HARD_REGNO_NREGS (REGNO (SUBREG_REG (out)),
01122 GET_MODE (SUBREG_REG (out)))))
01123 || ! HARD_REGNO_MODE_OK (subreg_regno (out), outmode)))
01124 #ifdef SECONDARY_OUTPUT_RELOAD_CLASS
01125 || (SECONDARY_OUTPUT_RELOAD_CLASS (class, outmode, out) != NO_REGS
01126 && (SECONDARY_OUTPUT_RELOAD_CLASS (class,
01127 GET_MODE (SUBREG_REG (out)),
01128 SUBREG_REG (out))
01129 == NO_REGS))
01130 #endif
01131 #ifdef CANNOT_CHANGE_MODE_CLASS
01132 || (GET_CODE (SUBREG_REG (out)) == REG
01133 && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
01134 && REG_CANNOT_CHANGE_MODE_P (REGNO (SUBREG_REG (out)),
01135 GET_MODE (SUBREG_REG (out)),
01136 outmode))
01137 #endif
01138 ))
01139 {
01140 out_subreg_loc = outloc;
01141 outloc = &SUBREG_REG (out);
01142 out = *outloc;
01143 #if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
01144 if (GET_CODE (out) == MEM
01145 && GET_MODE_SIZE (GET_MODE (out)) > GET_MODE_SIZE (outmode))
01146 abort ();
01147 #endif
01148 outmode = GET_MODE (out);
01149 }
01150
01151
01152
01153
01154
01155
01156
01157
01158 if (out != 0 && reload_inner_reg_of_subreg (out, outmode, 1))
01159 {
01160
01161
01162
01163
01164
01165 dont_remove_subreg = 1;
01166 push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
01167 &SUBREG_REG (out),
01168 find_valid_class (outmode,
01169 subreg_regno_offset (REGNO (SUBREG_REG (out)),
01170 GET_MODE (SUBREG_REG (out)),
01171 SUBREG_BYTE (out),
01172 GET_MODE (out)),
01173 REGNO (SUBREG_REG (out))),
01174 VOIDmode, VOIDmode, 0, 0,
01175 opnum, RELOAD_OTHER);
01176 }
01177
01178
01179 if (in != 0 && out != 0 && GET_CODE (out) == MEM
01180 && (GET_CODE (in) == REG || GET_CODE (in) == MEM)
01181 && reg_overlap_mentioned_for_reload_p (in, XEXP (out, 0)))
01182 dont_share = 1;
01183
01184
01185
01186
01187 if (in != 0 && GET_CODE (in) == SUBREG && GET_CODE (SUBREG_REG (in)) == REG
01188 && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
01189 && ! dont_remove_subreg)
01190 in = gen_rtx_REG (GET_MODE (in), subreg_regno (in));
01191
01192
01193 if (out != 0 && GET_CODE (out) == SUBREG
01194 && GET_CODE (SUBREG_REG (out)) == REG
01195 && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
01196 && ! dont_remove_subreg)
01197 out = gen_rtx_REG (GET_MODE (out), subreg_regno (out));
01198
01199
01200
01201 if (in != 0)
01202 class = PREFERRED_RELOAD_CLASS (in, class);
01203
01204
01205 #ifdef PREFERRED_OUTPUT_RELOAD_CLASS
01206 if (out != 0)
01207 class = PREFERRED_OUTPUT_RELOAD_CLASS (out, class);
01208 #endif
01209
01210
01211
01212
01213
01214 #ifdef LIMIT_RELOAD_CLASS
01215 if (in_subreg_loc)
01216 class = LIMIT_RELOAD_CLASS (inmode, class);
01217 else if (in != 0 && GET_CODE (in) == SUBREG)
01218 class = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (in)), class);
01219
01220 if (out_subreg_loc)
01221 class = LIMIT_RELOAD_CLASS (outmode, class);
01222 if (out != 0 && GET_CODE (out) == SUBREG)
01223 class = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (out)), class);
01224 #endif
01225
01226
01227
01228 if (this_insn_is_asm)
01229 {
01230 enum machine_mode mode;
01231 if (GET_MODE_SIZE (inmode) > GET_MODE_SIZE (outmode))
01232 mode = inmode;
01233 else
01234 mode = outmode;
01235 if (mode == VOIDmode)
01236 {
01237 error_for_asm (this_insn, "cannot reload integer constant operand in `asm'");
01238 mode = word_mode;
01239 if (in != 0)
01240 inmode = word_mode;
01241 if (out != 0)
01242 outmode = word_mode;
01243 }
01244 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01245 if (HARD_REGNO_MODE_OK (i, mode)
01246 && TEST_HARD_REG_BIT (reg_class_contents[(int) class], i))
01247 {
01248 int nregs = HARD_REGNO_NREGS (i, mode);
01249
01250 int j;
01251 for (j = 1; j < nregs; j++)
01252 if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class], i + j))
01253 break;
01254 if (j == nregs)
01255 break;
01256 }
01257 if (i == FIRST_PSEUDO_REGISTER)
01258 {
01259 error_for_asm (this_insn, "impossible register constraint in `asm'");
01260 class = ALL_REGS;
01261 }
01262 }
01263
01264
01265
01266
01267 if (class == NO_REGS
01268 && (optional == 0 || type != RELOAD_FOR_OUTPUT))
01269 abort ();
01270
01271 i = find_reusable_reload (&in, out, class, type, opnum, dont_share);
01272
01273 if (i == n_reloads)
01274 {
01275
01276
01277
01278
01279 #ifdef SECONDARY_INPUT_RELOAD_CLASS
01280 if (in != 0)
01281 secondary_in_reload
01282 = push_secondary_reload (1, in, opnum, optional, class, inmode, type,
01283 &secondary_in_icode);
01284 #endif
01285
01286 #ifdef SECONDARY_OUTPUT_RELOAD_CLASS
01287 if (out != 0 && GET_CODE (out) != SCRATCH)
01288 secondary_out_reload
01289 = push_secondary_reload (0, out, opnum, optional, class, outmode,
01290 type, &secondary_out_icode);
01291 #endif
01292
01293
01294
01295
01296 #ifdef SECONDARY_MEMORY_NEEDED
01297
01298 if (in != 0 && (GET_CODE (in) == REG || GET_CODE (in) == SUBREG)
01299 && reg_or_subregno (in) < FIRST_PSEUDO_REGISTER
01300 && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (reg_or_subregno (in)),
01301 class, inmode))
01302 get_secondary_mem (in, inmode, opnum, type);
01303 #endif
01304
01305 i = n_reloads;
01306 rld[i].in = in;
01307 rld[i].out = out;
01308 rld[i].class = class;
01309 rld[i].inmode = inmode;
01310 rld[i].outmode = outmode;
01311 rld[i].reg_rtx = 0;
01312 rld[i].optional = optional;
01313 rld[i].inc = 0;
01314 rld[i].nocombine = 0;
01315 rld[i].in_reg = inloc ? *inloc : 0;
01316 rld[i].out_reg = outloc ? *outloc : 0;
01317 rld[i].opnum = opnum;
01318 rld[i].when_needed = type;
01319 rld[i].secondary_in_reload = secondary_in_reload;
01320 rld[i].secondary_out_reload = secondary_out_reload;
01321 rld[i].secondary_in_icode = secondary_in_icode;
01322 rld[i].secondary_out_icode = secondary_out_icode;
01323 rld[i].secondary_p = 0;
01324
01325 n_reloads++;
01326
01327 #ifdef SECONDARY_MEMORY_NEEDED
01328 if (out != 0 && (GET_CODE (out) == REG || GET_CODE (out) == SUBREG)
01329 && reg_or_subregno (out) < FIRST_PSEUDO_REGISTER
01330 && SECONDARY_MEMORY_NEEDED (class,
01331 REGNO_REG_CLASS (reg_or_subregno (out)),
01332 outmode))
01333 get_secondary_mem (out, outmode, opnum, type);
01334 #endif
01335 }
01336 else
01337 {
01338
01339
01340
01341
01342
01343
01344
01345 if (inmode != VOIDmode
01346 && GET_MODE_SIZE (inmode) > GET_MODE_SIZE (rld[i].inmode))
01347 rld[i].inmode = inmode;
01348 if (outmode != VOIDmode
01349 && GET_MODE_SIZE (outmode) > GET_MODE_SIZE (rld[i].outmode))
01350 rld[i].outmode = outmode;
01351 if (in != 0)
01352 {
01353 rtx in_reg = inloc ? *inloc : 0;
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368 if (rld[i].in != in && rtx_equal_p (in, rld[i].in)
01369 && ! (rld[i].optional && optional))
01370 {
01371
01372
01373 if (opnum > rld[i].opnum)
01374 {
01375 remove_address_replacements (in);
01376 in = rld[i].in;
01377 in_reg = rld[i].in_reg;
01378 }
01379 else
01380 remove_address_replacements (rld[i].in);
01381 }
01382 rld[i].in = in;
01383 rld[i].in_reg = in_reg;
01384 }
01385 if (out != 0)
01386 {
01387 rld[i].out = out;
01388 rld[i].out_reg = outloc ? *outloc : 0;
01389 }
01390 if (reg_class_subset_p (class, rld[i].class))
01391 rld[i].class = class;
01392 rld[i].optional &= optional;
01393 if (MERGE_TO_OTHER (type, rld[i].when_needed,
01394 opnum, rld[i].opnum))
01395 rld[i].when_needed = RELOAD_OTHER;
01396 rld[i].opnum = MIN (rld[i].opnum, opnum);
01397 }
01398
01399
01400
01401
01402
01403 if (in != 0 && in != *inloc)
01404 rld[i].nocombine = 1;
01405
01406 #if 0
01407
01408
01409
01410
01411
01412
01413
01414
01415 if (out != 0 && sets_cc0_p (PATTERN (this_insn)))
01416 {
01417 out = 0;
01418 rld[i].out = 0;
01419 rld[i].inc = find_inc_amount (PATTERN (this_insn), in);
01420
01421
01422
01423 if (rld[i].inc == 0)
01424 abort ();
01425 }
01426 #endif
01427
01428
01429
01430
01431
01432 if (replace_reloads)
01433 {
01434 if (inloc != 0)
01435 {
01436 struct replacement *r = &replacements[n_replacements++];
01437 r->what = i;
01438 r->subreg_loc = in_subreg_loc;
01439 r->where = inloc;
01440 r->mode = inmode;
01441 }
01442 if (outloc != 0 && outloc != inloc)
01443 {
01444 struct replacement *r = &replacements[n_replacements++];
01445 r->what = i;
01446 r->where = outloc;
01447 r->subreg_loc = out_subreg_loc;
01448 r->mode = outmode;
01449 }
01450 }
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460 if (in != 0 && out != 0 && in != out && rld[i].reg_rtx == 0)
01461 {
01462 rld[i].reg_rtx = find_dummy_reload (in, out, inloc, outloc,
01463 inmode, outmode,
01464 rld[i].class, i,
01465 earlyclobber_operand_p (out));
01466
01467
01468
01469
01470
01471 if (rld[i].reg_rtx == out
01472 && (GET_CODE (in) == REG || CONSTANT_P (in))
01473 && 0 != find_equiv_reg (in, this_insn, 0, REGNO (out),
01474 static_reload_reg_p, i, inmode))
01475 rld[i].in = out;
01476 }
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490 if (rld[i].reg_rtx == 0 && in != 0)
01491 {
01492 rtx note;
01493 int regno;
01494 enum machine_mode rel_mode = inmode;
01495
01496 if (out && GET_MODE_SIZE (outmode) > GET_MODE_SIZE (inmode))
01497 rel_mode = outmode;
01498
01499 for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
01500 if (REG_NOTE_KIND (note) == REG_DEAD
01501 && GET_CODE (XEXP (note, 0)) == REG
01502 && (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
01503 && reg_mentioned_p (XEXP (note, 0), in)
01504 && ! refers_to_regno_for_reload_p (regno,
01505 (regno
01506 + HARD_REGNO_NREGS (regno,
01507 rel_mode)),
01508 PATTERN (this_insn), inloc)
01509
01510
01511
01512 && (out == 0 || in == out
01513 || ! hard_reg_set_here_p (regno,
01514 (regno
01515 + HARD_REGNO_NREGS (regno,
01516 rel_mode)),
01517 PATTERN (this_insn)))
01518
01519
01520
01521 && (in != out
01522 || (GET_CODE (in) == SUBREG
01523 && (((GET_MODE_SIZE (GET_MODE (in)) + (UNITS_PER_WORD - 1))
01524 / UNITS_PER_WORD)
01525 == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
01526 + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))))
01527
01528 && (GET_MODE_SIZE (rel_mode)
01529 <= GET_MODE_SIZE (GET_MODE (XEXP (note, 0))))
01530 && HARD_REGNO_MODE_OK (regno, inmode)
01531 && HARD_REGNO_MODE_OK (regno, outmode))
01532 {
01533 unsigned int offs;
01534 unsigned int nregs = MAX (HARD_REGNO_NREGS (regno, inmode),
01535 HARD_REGNO_NREGS (regno, outmode));
01536
01537 for (offs = 0; offs < nregs; offs++)
01538 if (fixed_regs[regno + offs]
01539 || ! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
01540 regno + offs))
01541 break;
01542
01543 if (offs == nregs)
01544 {
01545 rld[i].reg_rtx = gen_rtx_REG (rel_mode, regno);
01546 break;
01547 }
01548 }
01549 }
01550
01551 if (out)
01552 output_reloadnum = i;
01553
01554 return i;
01555 }
01556
01557
01558
01559
01560
01561
01562
01563 static void
01564 push_replacement (loc, reloadnum, mode)
01565 rtx *loc;
01566 int reloadnum;
01567 enum machine_mode mode;
01568 {
01569 if (replace_reloads)
01570 {
01571 struct replacement *r = &replacements[n_replacements++];
01572 r->what = reloadnum;
01573 r->where = loc;
01574 r->subreg_loc = 0;
01575 r->mode = mode;
01576 }
01577 }
01578
01579
01580
01581
01582
01583 static void
01584 dup_replacements (dup_loc, orig_loc)
01585 rtx *dup_loc;
01586 rtx *orig_loc;
01587 {
01588 int i, n = n_replacements;
01589
01590 for (i = 0; i < n; i++)
01591 {
01592 struct replacement *r = &replacements[i];
01593 if (r->where == orig_loc)
01594 push_replacement (dup_loc, r->what, r->mode);
01595 }
01596 }
01597
01598
01599
01600
01601 void
01602 transfer_replacements (to, from)
01603 int to, from;
01604 {
01605 int i;
01606
01607 for (i = 0; i < n_replacements; i++)
01608 if (replacements[i].what == from)
01609 replacements[i].what = to;
01610 }
01611
01612
01613
01614
01615
01616 int
01617 remove_address_replacements (in_rtx)
01618 rtx in_rtx;
01619 {
01620 int i, j;
01621 char reload_flags[MAX_RELOADS];
01622 int something_changed = 0;
01623
01624 memset (reload_flags, 0, sizeof reload_flags);
01625 for (i = 0, j = 0; i < n_replacements; i++)
01626 {
01627 if (loc_mentioned_in_p (replacements[i].where, in_rtx))
01628 reload_flags[replacements[i].what] |= 1;
01629 else
01630 {
01631 replacements[j++] = replacements[i];
01632 reload_flags[replacements[i].what] |= 2;
01633 }
01634 }
01635
01636 n_replacements = j;
01637
01638 for (i = n_reloads - 1; i >= 0; i--)
01639 {
01640 if (reload_flags[i] == 1)
01641 {
01642 deallocate_reload_reg (i);
01643 remove_address_replacements (rld[i].in);
01644 rld[i].in = 0;
01645 something_changed = 1;
01646 }
01647 }
01648 return something_changed;
01649 }
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663 static void
01664 combine_reloads ()
01665 {
01666 int i;
01667 int output_reload = -1;
01668 int secondary_out = -1;
01669 rtx note;
01670
01671
01672
01673
01674 for (i = 0; i < n_reloads; i++)
01675 if (rld[i].out != 0)
01676 {
01677 if (output_reload >= 0)
01678 return;
01679 output_reload = i;
01680 }
01681
01682 if (output_reload < 0 || rld[output_reload].optional)
01683 return;
01684
01685
01686
01687 if (rld[output_reload].in != 0)
01688 return;
01689
01690
01691 if (earlyclobber_operand_p (rld[output_reload].out))
01692 return;
01693
01694
01695
01696
01697
01698 for (i = 0; i < n_reloads; i++)
01699 if ((rld[i].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
01700 || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
01701 && rld[i].opnum == rld[output_reload].opnum)
01702 return;
01703
01704
01705
01706 for (i = 0; i < n_reloads; i++)
01707 if (rld[i].in && ! rld[i].optional && ! rld[i].nocombine
01708
01709 && rld[i].when_needed != RELOAD_FOR_OUTPUT_ADDRESS
01710 && rld[i].when_needed != RELOAD_FOR_OUTADDR_ADDRESS
01711 && rld[i].when_needed != RELOAD_OTHER
01712 && (CLASS_MAX_NREGS (rld[i].class, rld[i].inmode)
01713 == CLASS_MAX_NREGS (rld[output_reload].class,
01714 rld[output_reload].outmode))
01715 && rld[i].inc == 0
01716 && rld[i].reg_rtx == 0
01717 #ifdef SECONDARY_MEMORY_NEEDED
01718
01719
01720 && (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum] == 0
01721 || secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum] == 0
01722 || rtx_equal_p (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum],
01723 secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum]))
01724 #endif
01725 && (SMALL_REGISTER_CLASSES
01726 ? (rld[i].class == rld[output_reload].class)
01727 : (reg_class_subset_p (rld[i].class,
01728 rld[output_reload].class)
01729 || reg_class_subset_p (rld[output_reload].class,
01730 rld[i].class)))
01731 && (MATCHES (rld[i].in, rld[output_reload].out)
01732
01733
01734
01735 || (! reg_overlap_mentioned_for_reload_p (rld[output_reload].out,
01736 rld[i].in)
01737
01738
01739
01740
01741
01742
01743 && ! (GET_CODE (rld[i].in) == REG
01744 && reg_overlap_mentioned_for_reload_p (rld[i].in,
01745 rld[output_reload].out))))
01746 && ! reload_inner_reg_of_subreg (rld[i].in, rld[i].inmode,
01747 rld[i].when_needed != RELOAD_FOR_INPUT)
01748 && (reg_class_size[(int) rld[i].class]
01749 || SMALL_REGISTER_CLASSES)
01750
01751
01752 && (rld[i].when_needed == RELOAD_FOR_INPUT
01753 || rld[i].when_needed == RELOAD_FOR_OUTPUT))
01754 {
01755 int j;
01756
01757
01758 rld[i].out = rld[output_reload].out;
01759 rld[i].out_reg = rld[output_reload].out_reg;
01760 rld[i].outmode = rld[output_reload].outmode;
01761
01762 rld[output_reload].out = 0;
01763
01764 rld[i].when_needed = RELOAD_OTHER;
01765
01766 if (rld[output_reload].secondary_out_reload != -1)
01767 {
01768 rld[i].secondary_out_reload
01769 = rld[output_reload].secondary_out_reload;
01770 rld[i].secondary_out_icode
01771 = rld[output_reload].secondary_out_icode;
01772 }
01773
01774 #ifdef SECONDARY_MEMORY_NEEDED
01775
01776 if (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum] != 0)
01777 secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum]
01778 = secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum];
01779 #endif
01780
01781 if (reg_class_subset_p (rld[output_reload].class,
01782 rld[i].class))
01783 rld[i].class = rld[output_reload].class;
01784
01785
01786 for (j = 0; j < n_replacements; j++)
01787 if (replacements[j].what == output_reload)
01788 replacements[j].what = i;
01789
01790 return;
01791 }
01792
01793
01794
01795
01796
01797
01798
01799 if (INSN_CODE (this_insn) == -1)
01800 return;
01801
01802 for (i = 1; i < insn_data[INSN_CODE (this_insn)].n_operands; i++)
01803 if (insn_data[INSN_CODE (this_insn)].operand[i].constraint[0] == '='
01804 || insn_data[INSN_CODE (this_insn)].operand[i].constraint[0] == '+')
01805 return;
01806
01807
01808
01809
01810 for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
01811 if (REG_NOTE_KIND (note) == REG_DEAD
01812 && GET_CODE (XEXP (note, 0)) == REG
01813 && ! reg_overlap_mentioned_for_reload_p (XEXP (note, 0),
01814 rld[output_reload].out)
01815 && REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
01816 && HARD_REGNO_MODE_OK (REGNO (XEXP (note, 0)), rld[output_reload].outmode)
01817 && TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].class],
01818 REGNO (XEXP (note, 0)))
01819 && (HARD_REGNO_NREGS (REGNO (XEXP (note, 0)), rld[output_reload].outmode)
01820 <= HARD_REGNO_NREGS (REGNO (XEXP (note, 0)), GET_MODE (XEXP (note, 0))))
01821
01822
01823 && ((secondary_out = rld[output_reload].secondary_out_reload) == -1
01824 || (! (TEST_HARD_REG_BIT
01825 (reg_class_contents[(int) rld[secondary_out].class],
01826 REGNO (XEXP (note, 0))))
01827 && ((secondary_out = rld[secondary_out].secondary_out_reload) == -1
01828 || ! (TEST_HARD_REG_BIT
01829 (reg_class_contents[(int) rld[secondary_out].class],
01830 REGNO (XEXP (note, 0)))))))
01831 && ! fixed_regs[REGNO (XEXP (note, 0))])
01832 {
01833 rld[output_reload].reg_rtx
01834 = gen_rtx_REG (rld[output_reload].outmode,
01835 REGNO (XEXP (note, 0)));
01836 return;
01837 }
01838 }
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860 static rtx
01861 find_dummy_reload (real_in, real_out, inloc, outloc,
01862 inmode, outmode, class, for_real, earlyclobber)
01863 rtx real_in, real_out;
01864 rtx *inloc, *outloc;
01865 enum machine_mode inmode, outmode;
01866 enum reg_class class;
01867 int for_real;
01868 int earlyclobber;
01869 {
01870 rtx in = real_in;
01871 rtx out = real_out;
01872 int in_offset = 0;
01873 int out_offset = 0;
01874 rtx value = 0;
01875
01876
01877
01878 if (GET_MODE_SIZE (outmode) != GET_MODE_SIZE (inmode)
01879 && (GET_MODE_SIZE (outmode) > UNITS_PER_WORD
01880 || GET_MODE_SIZE (inmode) > UNITS_PER_WORD))
01881 return 0;
01882
01883
01884
01885
01886
01887 while (GET_CODE (out) == SUBREG)
01888 {
01889 if (GET_CODE (SUBREG_REG (out)) == REG
01890 && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER)
01891 out_offset += subreg_regno_offset (REGNO (SUBREG_REG (out)),
01892 GET_MODE (SUBREG_REG (out)),
01893 SUBREG_BYTE (out),
01894 GET_MODE (out));
01895 out = SUBREG_REG (out);
01896 }
01897 while (GET_CODE (in) == SUBREG)
01898 {
01899 if (GET_CODE (SUBREG_REG (in)) == REG
01900 && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER)
01901 in_offset += subreg_regno_offset (REGNO (SUBREG_REG (in)),
01902 GET_MODE (SUBREG_REG (in)),
01903 SUBREG_BYTE (in),
01904 GET_MODE (in));
01905 in = SUBREG_REG (in);
01906 }
01907
01908
01909
01910 class = PREFERRED_RELOAD_CLASS (in, class);
01911
01912
01913 if (GET_CODE (out) == REG
01914 && REGNO (out) < FIRST_PSEUDO_REGISTER)
01915 {
01916 unsigned int regno = REGNO (out) + out_offset;
01917 unsigned int nwords = HARD_REGNO_NREGS (regno, outmode);
01918 rtx saved_rtx;
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929 saved_rtx = *inloc;
01930 *inloc = const0_rtx;
01931
01932 if (regno < FIRST_PSEUDO_REGISTER
01933 && HARD_REGNO_MODE_OK (regno, outmode)
01934 && ! refers_to_regno_for_reload_p (regno, regno + nwords,
01935 PATTERN (this_insn), outloc))
01936 {
01937 unsigned int i;
01938
01939 for (i = 0; i < nwords; i++)
01940 if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
01941 regno + i))
01942 break;
01943
01944 if (i == nwords)
01945 {
01946 if (GET_CODE (real_out) == REG)
01947 value = real_out;
01948 else
01949 value = gen_rtx_REG (outmode, regno);
01950 }
01951 }
01952
01953 *inloc = saved_rtx;
01954 }
01955
01956
01957
01958
01959
01960
01961
01962 if (hard_regs_live_known
01963 && GET_CODE (in) == REG
01964 && REGNO (in) < FIRST_PSEUDO_REGISTER
01965 && (value == 0
01966 || find_reg_note (this_insn, REG_UNUSED, real_out))
01967 && find_reg_note (this_insn, REG_DEAD, real_in)
01968 && !fixed_regs[REGNO (in)]
01969 && HARD_REGNO_MODE_OK (REGNO (in),
01970
01971
01972
01973
01974 (GET_MODE (out) != VOIDmode
01975 ? GET_MODE (out) : outmode)))
01976 {
01977 unsigned int regno = REGNO (in) + in_offset;
01978 unsigned int nwords = HARD_REGNO_NREGS (regno, inmode);
01979
01980 if (! refers_to_regno_for_reload_p (regno, regno + nwords, out, (rtx*) 0)
01981 && ! hard_reg_set_here_p (regno, regno + nwords,
01982 PATTERN (this_insn))
01983 && (! earlyclobber
01984 || ! refers_to_regno_for_reload_p (regno, regno + nwords,
01985 PATTERN (this_insn), inloc)))
01986 {
01987 unsigned int i;
01988
01989 for (i = 0; i < nwords; i++)
01990 if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
01991 regno + i))
01992 break;
01993
01994 if (i == nwords)
01995 {
01996
01997
01998
01999 if (for_real >= 0 && value == real_out)
02000 rld[for_real].out = 0;
02001 if (GET_CODE (real_in) == REG)
02002 value = real_in;
02003 else
02004 value = gen_rtx_REG (inmode, regno);
02005 }
02006 }
02007 }
02008
02009 return value;
02010 }
02011
02012
02013
02014
02015
02016
02017
02018 int
02019 earlyclobber_operand_p (x)
02020 rtx x;
02021 {
02022 int i;
02023
02024 for (i = 0; i < n_earlyclobbers; i++)
02025 if (reload_earlyclobbers[i] == x)
02026 return 1;
02027
02028 return 0;
02029 }
02030
02031
02032
02033
02034
02035
02036 static int
02037 hard_reg_set_here_p (beg_regno, end_regno, x)
02038 unsigned int beg_regno, end_regno;
02039 rtx x;
02040 {
02041 if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
02042 {
02043 rtx op0 = SET_DEST (x);
02044
02045 while (GET_CODE (op0) == SUBREG)
02046 op0 = SUBREG_REG (op0);
02047 if (GET_CODE (op0) == REG)
02048 {
02049 unsigned int r = REGNO (op0);
02050
02051
02052 if (r < end_regno
02053 && r + HARD_REGNO_NREGS (r, GET_MODE (op0)) > beg_regno)
02054 return 1;
02055 }
02056 }
02057 else if (GET_CODE (x) == PARALLEL)
02058 {
02059 int i = XVECLEN (x, 0) - 1;
02060
02061 for (; i >= 0; i--)
02062 if (hard_reg_set_here_p (beg_regno, end_regno, XVECEXP (x, 0, i)))
02063 return 1;
02064 }
02065
02066 return 0;
02067 }
02068
02069
02070
02071
02072
02073 int
02074 strict_memory_address_p (mode, addr)
02075 enum machine_mode mode ATTRIBUTE_UNUSED;
02076 rtx addr;
02077 {
02078 GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
02079 return 0;
02080
02081 win:
02082 return 1;
02083 }
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100 int
02101 operands_match_p (x, y)
02102 rtx x, y;
02103 {
02104 int i;
02105 RTX_CODE code = GET_CODE (x);
02106 const char *fmt;
02107 int success_2;
02108
02109 if (x == y)
02110 return 1;
02111 if ((code == REG || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG))
02112 && (GET_CODE (y) == REG || (GET_CODE (y) == SUBREG
02113 && GET_CODE (SUBREG_REG (y)) == REG)))
02114 {
02115 int j;
02116
02117 if (code == SUBREG)
02118 {
02119 i = REGNO (SUBREG_REG (x));
02120 if (i >= FIRST_PSEUDO_REGISTER)
02121 goto slow;
02122 i += subreg_regno_offset (REGNO (SUBREG_REG (x)),
02123 GET_MODE (SUBREG_REG (x)),
02124 SUBREG_BYTE (x),
02125 GET_MODE (x));
02126 }
02127 else
02128 i = REGNO (x);
02129
02130 if (GET_CODE (y) == SUBREG)
02131 {
02132 j = REGNO (SUBREG_REG (y));
02133 if (j >= FIRST_PSEUDO_REGISTER)
02134 goto slow;
02135 j += subreg_regno_offset (REGNO (SUBREG_REG (y)),
02136 GET_MODE (SUBREG_REG (y)),
02137 SUBREG_BYTE (y),
02138 GET_MODE (y));
02139 }
02140 else
02141 j = REGNO (y);
02142
02143
02144
02145
02146 if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
02147 && i < FIRST_PSEUDO_REGISTER)
02148 i += (GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD) - 1;
02149 if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (y)) > UNITS_PER_WORD
02150 && j < FIRST_PSEUDO_REGISTER)
02151 j += (GET_MODE_SIZE (GET_MODE (y)) / UNITS_PER_WORD) - 1;
02152
02153 return i == j;
02154 }
02155
02156
02157
02158
02159
02160 if (code == POST_DEC || code == POST_INC || code == POST_MODIFY)
02161 return operands_match_p (XEXP (x, 0), y);
02162
02163
02164
02165
02166
02167
02168 if (GET_CODE (y) == PRE_DEC || GET_CODE (y) == PRE_INC
02169 || GET_CODE (y) == PRE_MODIFY)
02170 return operands_match_p (x, XEXP (y, 0)) ? 2 : 0;
02171
02172 slow:
02173
02174
02175
02176 if (code != GET_CODE (y))
02177 return 0;
02178 if (code == LABEL_REF)
02179 return XEXP (x, 0) == XEXP (y, 0);
02180 if (code == SYMBOL_REF)
02181 return XSTR (x, 0) == XSTR (y, 0);
02182
02183
02184
02185 if (GET_MODE (x) != GET_MODE (y))
02186 return 0;
02187
02188
02189
02190
02191 success_2 = 0;
02192 fmt = GET_RTX_FORMAT (code);
02193 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02194 {
02195 int val, j;
02196 switch (fmt[i])
02197 {
02198 case 'w':
02199 if (XWINT (x, i) != XWINT (y, i))
02200 return 0;
02201 break;
02202
02203 case 'i':
02204 if (XINT (x, i) != XINT (y, i))
02205 return 0;
02206 break;
02207
02208 case 'e':
02209 val = operands_match_p (XEXP (x, i), XEXP (y, i));
02210 if (val == 0)
02211 return 0;
02212
02213
02214 if (val == 2)
02215 success_2 = 1;
02216 break;
02217
02218 case '0':
02219 break;
02220
02221 case 'E':
02222 if (XVECLEN (x, i) != XVECLEN (y, i))
02223 return 0;
02224 for (j = XVECLEN (x, i) - 1; j >= 0; --j)
02225 {
02226 val = operands_match_p (XVECEXP (x, i, j), XVECEXP (y, i, j));
02227 if (val == 0)
02228 return 0;
02229 if (val == 2)
02230 success_2 = 1;
02231 }
02232 break;
02233
02234
02235
02236
02237 default:
02238 abort ();
02239 }
02240 }
02241 return 1 + success_2;
02242 }
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252 static struct decomposition
02253 decompose (x)
02254 rtx x;
02255 {
02256 struct decomposition val;
02257 int all_const = 0;
02258
02259 val.reg_flag = 0;
02260 val.safe = 0;
02261 val.base = 0;
02262 if (GET_CODE (x) == MEM)
02263 {
02264 rtx base = NULL_RTX, offset = 0;
02265 rtx addr = XEXP (x, 0);
02266
02267 if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC
02268 || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC)
02269 {
02270 val.base = XEXP (addr, 0);
02271 val.start = -GET_MODE_SIZE (GET_MODE (x));
02272 val.end = GET_MODE_SIZE (GET_MODE (x));
02273 val.safe = REGNO (val.base) == STACK_POINTER_REGNUM;
02274 return val;
02275 }
02276
02277 if (GET_CODE (addr) == PRE_MODIFY || GET_CODE (addr) == POST_MODIFY)
02278 {
02279 if (GET_CODE (XEXP (addr, 1)) == PLUS
02280 && XEXP (addr, 0) == XEXP (XEXP (addr, 1), 0)
02281 && CONSTANT_P (XEXP (XEXP (addr, 1), 1)))
02282 {
02283 val.base = XEXP (addr, 0);
02284 val.start = -INTVAL (XEXP (XEXP (addr, 1), 1));
02285 val.end = INTVAL (XEXP (XEXP (addr, 1), 1));
02286 val.safe = REGNO (val.base) == STACK_POINTER_REGNUM;
02287 return val;
02288 }
02289 }
02290
02291 if (GET_CODE (addr) == CONST)
02292 {
02293 addr = XEXP (addr, 0);
02294 all_const = 1;
02295 }
02296 if (GET_CODE (addr) == PLUS)
02297 {
02298 if (CONSTANT_P (XEXP (addr, 0)))
02299 {
02300 base = XEXP (addr, 1);
02301 offset = XEXP (addr, 0);
02302 }
02303 else if (CONSTANT_P (XEXP (addr, 1)))
02304 {
02305 base = XEXP (addr, 0);
02306 offset = XEXP (addr, 1);
02307 }
02308 }
02309
02310 if (offset == 0)
02311 {
02312 base = addr;
02313 offset = const0_rtx;
02314 }
02315 if (GET_CODE (offset) == CONST)
02316 offset = XEXP (offset, 0);
02317 if (GET_CODE (offset) == PLUS)
02318 {
02319 if (GET_CODE (XEXP (offset, 0)) == CONST_INT)
02320 {
02321 base = gen_rtx_PLUS (GET_MODE (base), base, XEXP (offset, 1));
02322 offset = XEXP (offset, 0);
02323 }
02324 else if (GET_CODE (XEXP (offset, 1)) == CONST_INT)
02325 {
02326 base = gen_rtx_PLUS (GET_MODE (base), base, XEXP (offset, 0));
02327 offset = XEXP (offset, 1);
02328 }
02329 else
02330 {
02331 base = gen_rtx_PLUS (GET_MODE (base), base, offset);
02332 offset = const0_rtx;
02333 }
02334 }
02335 else if (GET_CODE (offset) != CONST_INT)
02336 {
02337 base = gen_rtx_PLUS (GET_MODE (base), base, offset);
02338 offset = const0_rtx;
02339 }
02340
02341 if (all_const && GET_CODE (base) == PLUS)
02342 base = gen_rtx_CONST (GET_MODE (base), base);
02343
02344 if (GET_CODE (offset) != CONST_INT)
02345 abort ();
02346
02347 val.start = INTVAL (offset);
02348 val.end = val.start + GET_MODE_SIZE (GET_MODE (x));
02349 val.base = base;
02350 return val;
02351 }
02352 else if (GET_CODE (x) == REG)
02353 {
02354 val.reg_flag = 1;
02355 val.start = true_regnum (x);
02356 if (val.start < 0)
02357 {
02358
02359 val.start = REGNO (x);
02360 val.end = val.start + 1;
02361 }
02362 else
02363
02364 val.end = val.start + HARD_REGNO_NREGS (val.start, GET_MODE (x));
02365 }
02366 else if (GET_CODE (x) == SUBREG)
02367 {
02368 if (GET_CODE (SUBREG_REG (x)) != REG)
02369
02370 return decompose (SUBREG_REG (x));
02371 val.reg_flag = 1;
02372 val.start = true_regnum (x);
02373 if (val.start < 0)
02374 return decompose (SUBREG_REG (x));
02375 else
02376
02377 val.end = val.start + HARD_REGNO_NREGS (val.start, GET_MODE (x));
02378 }
02379 else if (CONSTANT_P (x)
02380
02381 || GET_CODE (x) == SCRATCH)
02382 val.safe = 1;
02383 else
02384 abort ();
02385 return val;
02386 }
02387
02388
02389
02390
02391 static int
02392 immune_p (x, y, ydata)
02393 rtx x, y;
02394 struct decomposition ydata;
02395 {
02396 struct decomposition xdata;
02397
02398 if (ydata.reg_flag)
02399 return !refers_to_regno_for_reload_p (ydata.start, ydata.end, x, (rtx*) 0);
02400 if (ydata.safe)
02401 return 1;
02402
02403 if (GET_CODE (y) != MEM)
02404 abort ();
02405
02406 if (GET_CODE (x) != MEM)
02407 return 1;
02408
02409 xdata = decompose (x);
02410
02411 if (! rtx_equal_p (xdata.base, ydata.base))
02412 {
02413
02414 if (CONSTANT_P (xdata.base) && CONSTANT_P (ydata.base))
02415 return 1;
02416
02417 if (CONSTANT_P (xdata.base)
02418 && (ydata.base == frame_pointer_rtx
02419 || ydata.base == hard_frame_pointer_rtx
02420 || ydata.base == stack_pointer_rtx))
02421 return 1;
02422 if (CONSTANT_P (ydata.base)
02423 && (xdata.base == frame_pointer_rtx
02424 || xdata.base == hard_frame_pointer_rtx
02425 || xdata.base == stack_pointer_rtx))
02426 return 1;
02427
02428 return 0;
02429 }
02430
02431 return (xdata.start >= ydata.end || ydata.start >= xdata.end);
02432 }
02433
02434
02435
02436 int
02437 safe_from_earlyclobber (op, clobber)
02438 rtx op, clobber;
02439 {
02440 struct decomposition early_data;
02441
02442 early_data = decompose (clobber);
02443 return immune_p (op, clobber, early_data);
02444 }
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468 int
02469 find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
02470 rtx insn;
02471 int replace, ind_levels;
02472 int live_known;
02473 short *reload_reg_p;
02474 {
02475 int insn_code_number;
02476 int i, j;
02477 int noperands;
02478
02479
02480 char *constraints[MAX_RECOG_OPERANDS];
02481
02482
02483 enum reg_class preferred_class[MAX_RECOG_OPERANDS];
02484 char pref_or_nothing[MAX_RECOG_OPERANDS];
02485
02486 int address_reloaded[MAX_RECOG_OPERANDS];
02487
02488 int address_operand_reloaded[MAX_RECOG_OPERANDS];
02489
02490 enum reload_type operand_type[MAX_RECOG_OPERANDS];
02491
02492 enum reload_type address_type[MAX_RECOG_OPERANDS];
02493
02494 enum reload_usage { RELOAD_READ, RELOAD_READ_WRITE, RELOAD_WRITE } modified[MAX_RECOG_OPERANDS];
02495 int no_input_reloads = 0, no_output_reloads = 0;
02496 int n_alternatives;
02497 int this_alternative[MAX_RECOG_OPERANDS];
02498 char this_alternative_match_win[MAX_RECOG_OPERANDS];
02499 char this_alternative_win[MAX_RECOG_OPERANDS];
02500 char this_alternative_offmemok[MAX_RECOG_OPERANDS];
02501 char this_alternative_earlyclobber[MAX_RECOG_OPERANDS];
02502 int this_alternative_matches[MAX_RECOG_OPERANDS];
02503 int swapped;
02504 int goal_alternative[MAX_RECOG_OPERANDS];
02505 int this_alternative_number;
02506 int goal_alternative_number = 0;
02507 int operand_reloadnum[MAX_RECOG_OPERANDS];
02508 int goal_alternative_matches[MAX_RECOG_OPERANDS];
02509 int goal_alternative_matched[MAX_RECOG_OPERANDS];
02510 char goal_alternative_match_win[MAX_RECOG_OPERANDS];
02511 char goal_alternative_win[MAX_RECOG_OPERANDS];
02512 char goal_alternative_offmemok[MAX_RECOG_OPERANDS];
02513 char goal_alternative_earlyclobber[MAX_RECOG_OPERANDS];
02514 int goal_alternative_swapped;
02515 int best;
02516 int commutative;
02517 char operands_match[MAX_RECOG_OPERANDS][MAX_RECOG_OPERANDS];
02518 rtx substed_operand[MAX_RECOG_OPERANDS];
02519 rtx body = PATTERN (insn);
02520 rtx set = single_set (insn);
02521 int goal_earlyclobber = 0, this_earlyclobber;
02522 enum machine_mode operand_mode[MAX_RECOG_OPERANDS];
02523 int retval = 0;
02524
02525 this_insn = insn;
02526 n_reloads = 0;
02527 n_replacements = 0;
02528 n_earlyclobbers = 0;
02529 replace_reloads = replace;
02530 hard_regs_live_known = live_known;
02531 static_reload_reg_p = reload_reg_p;
02532
02533
02534
02535
02536 if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN)
02537 no_output_reloads = 1;
02538
02539 #ifdef HAVE_cc0
02540 if (reg_referenced_p (cc0_rtx, PATTERN (insn)))
02541 no_input_reloads = 1;
02542 if (reg_set_p (cc0_rtx, PATTERN (insn)))
02543 no_output_reloads = 1;
02544 #endif
02545
02546 #ifdef SECONDARY_MEMORY_NEEDED
02547
02548
02549
02550 memset ((char *) secondary_memlocs_elim, 0, sizeof secondary_memlocs_elim);
02551 #endif
02552
02553
02554
02555
02556 if (GET_CODE (body) == SET
02557 && GET_CODE (SET_DEST (body)) == REG
02558 && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER
02559 && GET_CODE (SET_SRC (body)) == REG
02560 && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
02561 && REGISTER_MOVE_COST (GET_MODE (SET_SRC (body)),
02562 REGNO_REG_CLASS (REGNO (SET_SRC (body))),
02563 REGNO_REG_CLASS (REGNO (SET_DEST (body)))) == 2)
02564 return 0;
02565
02566 extract_insn (insn);
02567
02568 noperands = reload_n_operands = recog_data.n_operands;
02569 n_alternatives = recog_data.n_alternatives;
02570
02571
02572 if (noperands == 0 || n_alternatives == 0)
02573 return 0;
02574
02575 insn_code_number = INSN_CODE (insn);
02576 this_insn_is_asm = insn_code_number < 0;
02577
02578 memcpy (operand_mode, recog_data.operand_mode,
02579 noperands * sizeof (enum machine_mode));
02580 memcpy (constraints, recog_data.constraints, noperands * sizeof (char *));
02581
02582 commutative = -1;
02583
02584
02585
02586
02587
02588
02589 for (i = 0; i < noperands; i++)
02590 {
02591 char *p;
02592 int c;
02593
02594 substed_operand[i] = recog_data.operand[i];
02595 p = constraints[i];
02596
02597 modified[i] = RELOAD_READ;
02598
02599
02600
02601
02602 while ((c = *p++))
02603 {
02604 if (c == '=')
02605 modified[i] = RELOAD_WRITE;
02606 else if (c == '+')
02607 modified[i] = RELOAD_READ_WRITE;
02608 else if (c == '%')
02609 {
02610
02611 if (i == noperands - 1)
02612 abort ();
02613
02614 commutative = i;
02615 }
02616 else if (ISDIGIT (c))
02617 {
02618 c = strtoul (p - 1, &p, 10);
02619
02620 operands_match[c][i]
02621 = operands_match_p (recog_data.operand[c],
02622 recog_data.operand[i]);
02623
02624
02625 if (c == i)
02626 abort ();
02627
02628
02629
02630 if (commutative >= 0)
02631 {
02632 if (c == commutative || c == commutative + 1)
02633 {
02634 int other = c + (c == commutative ? 1 : -1);
02635 operands_match[other][i]
02636 = operands_match_p (recog_data.operand[other],
02637 recog_data.operand[i]);
02638 }
02639 if (i == commutative || i == commutative + 1)
02640 {
02641 int other = i + (i == commutative ? 1 : -1);
02642 operands_match[c][other]
02643 = operands_match_p (recog_data.operand[c],
02644 recog_data.operand[other]);
02645 }
02646
02647
02648
02649 }
02650 }
02651 }
02652 }
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662 for (i = 0; i < noperands; i++)
02663 {
02664 RTX_CODE code = GET_CODE (recog_data.operand[i]);
02665
02666 address_reloaded[i] = 0;
02667 address_operand_reloaded[i] = 0;
02668 operand_type[i] = (modified[i] == RELOAD_READ ? RELOAD_FOR_INPUT
02669 : modified[i] == RELOAD_WRITE ? RELOAD_FOR_OUTPUT
02670 : RELOAD_OTHER);
02671 address_type[i]
02672 = (modified[i] == RELOAD_READ ? RELOAD_FOR_INPUT_ADDRESS
02673 : modified[i] == RELOAD_WRITE ? RELOAD_FOR_OUTPUT_ADDRESS
02674 : RELOAD_OTHER);
02675
02676 if (*constraints[i] == 0)
02677
02678 ;
02679 else if (constraints[i][0] == 'p'
02680 || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0]))
02681 {
02682 address_operand_reloaded[i]
02683 = find_reloads_address (recog_data.operand_mode[i], (rtx*) 0,
02684 recog_data.operand[i],
02685 recog_data.operand_loc[i],
02686 i, operand_type[i], ind_levels, insn);
02687
02688
02689
02690 if ((GET_RTX_CLASS (GET_CODE (*recog_data.operand_loc[i])) == 'o'
02691 || GET_CODE (*recog_data.operand_loc[i]) == SUBREG)
02692 && (GET_CODE (recog_data.operand[i]) == MULT
02693 || GET_CODE (recog_data.operand[i]) == PLUS))
02694 {
02695 INSN_CODE (insn) = -1;
02696 retval = find_reloads (insn, replace, ind_levels, live_known,
02697 reload_reg_p);
02698 return retval;
02699 }
02700
02701 recog_data.operand[i] = *recog_data.operand_loc[i];
02702 substed_operand[i] = recog_data.operand[i];
02703
02704
02705
02706 operand_mode[i] = GET_MODE (recog_data.operand[i]);
02707 }
02708 else if (code == MEM)
02709 {
02710 address_reloaded[i]
02711 = find_reloads_address (GET_MODE (recog_data.operand[i]),
02712 recog_data.operand_loc[i],
02713 XEXP (recog_data.operand[i], 0),
02714 &XEXP (recog_data.operand[i], 0),
02715 i, address_type[i], ind_levels, insn);
02716 recog_data.operand[i] = *recog_data.operand_loc[i];
02717 substed_operand[i] = recog_data.operand[i];
02718 }
02719 else if (code == SUBREG)
02720 {
02721 rtx reg = SUBREG_REG (recog_data.operand[i]);
02722 rtx op
02723 = find_reloads_toplev (recog_data.operand[i], i, address_type[i],
02724 ind_levels,
02725 set != 0
02726 && &SET_DEST (set) == recog_data.operand_loc[i],
02727 insn,
02728 &address_reloaded[i]);
02729
02730
02731
02732
02733
02734
02735 if (replace
02736 && GET_CODE (op) == MEM
02737 && GET_CODE (reg) == REG
02738 && (GET_MODE_SIZE (GET_MODE (reg))
02739 >= GET_MODE_SIZE (GET_MODE (op))))
02740 set_unique_reg_note (emit_insn_before (gen_rtx_USE (VOIDmode, reg),
02741 insn),
02742 REG_EQUAL, reg_equiv_memory_loc[REGNO (reg)]);
02743
02744 substed_operand[i] = recog_data.operand[i] = op;
02745 }
02746 else if (code == PLUS || GET_RTX_CLASS (code) == '1')
02747
02748
02749
02750 substed_operand[i] = recog_data.operand[i]
02751 = find_reloads_toplev (recog_data.operand[i], i, address_type[i],
02752 ind_levels, 0, insn,
02753 &address_reloaded[i]);
02754 else if (code == REG)
02755 {
02756
02757
02758
02759
02760
02761
02762 int regno = REGNO (recog_data.operand[i]);
02763 if (reg_equiv_constant[regno] != 0
02764 && (set == 0 || &SET_DEST (set) != recog_data.operand_loc[i]))
02765 {
02766
02767
02768
02769 if (operand_mode[i] == VOIDmode)
02770 operand_mode[i] = GET_MODE (recog_data.operand[i]);
02771
02772 substed_operand[i] = recog_data.operand[i]
02773 = reg_equiv_constant[regno];
02774 }
02775 if (reg_equiv_memory_loc[regno] != 0
02776 && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
02777
02778
02779 substed_operand[i] = recog_data.operand[i]
02780 = find_reloads_toplev (recog_data.operand[i], i, address_type[i],
02781 ind_levels, 0, insn,
02782 &address_reloaded[i]);
02783 }
02784
02785
02786 code = GET_CODE (recog_data.operand[i]);
02787 preferred_class[i]
02788 = ((code == REG && REGNO (recog_data.operand[i])
02789 >= FIRST_PSEUDO_REGISTER)
02790 ? reg_preferred_class (REGNO (recog_data.operand[i]))
02791 : NO_REGS);
02792 pref_or_nothing[i]
02793 = (code == REG
02794 && REGNO (recog_data.operand[i]) >= FIRST_PSEUDO_REGISTER
02795 && reg_alternate_class (REGNO (recog_data.operand[i])) == NO_REGS);
02796 }
02797
02798
02799
02800 if (set != 0 && noperands >= 2 && recog_data.operand[0] == SET_DEST (set)
02801 && recog_data.operand[1] == SET_SRC (set))
02802 {
02803 preferred_class[0] = preferred_class[1]
02804 = reg_class_subunion[(int) preferred_class[0]][(int) preferred_class[1]];
02805 pref_or_nothing[0] |= pref_or_nothing[1];
02806 pref_or_nothing[1] |= pref_or_nothing[0];
02807 }
02808
02809
02810
02811
02812
02813 best = MAX_RECOG_OPERANDS * 2 + 600;
02814
02815 swapped = 0;
02816 goal_alternative_swapped = 0;
02817 try_swapped:
02818
02819
02820
02821
02822
02823
02824
02825
02826 for (this_alternative_number = 0;
02827 this_alternative_number < n_alternatives;
02828 this_alternative_number++)
02829 {
02830
02831
02832
02833 int losers = 0;
02834
02835
02836 int bad = 0;
02837
02838
02839
02840
02841
02842
02843 int reject = 0;
02844
02845 this_earlyclobber = 0;
02846
02847 for (i = 0; i < noperands; i++)
02848 {
02849 char *p = constraints[i];
02850 int win = 0;
02851 int did_match = 0;
02852
02853 int badop = 1;
02854
02855 int winreg = 0;
02856 int c;
02857 rtx operand = recog_data.operand[i];
02858 int offset = 0;
02859
02860
02861 int force_reload = 0;
02862 int offmemok = 0;
02863
02864
02865 int constmemok = 0;
02866 int earlyclobber = 0;
02867
02868
02869
02870
02871 if (GET_RTX_CLASS (GET_CODE (operand)) == '1' && *p != 0)
02872 operand = XEXP (operand, 0);
02873
02874
02875
02876
02877
02878 while (GET_CODE (operand) == SUBREG)
02879 {
02880
02881
02882
02883
02884 if (GET_CODE (SUBREG_REG (operand)) == REG
02885 && REGNO (SUBREG_REG (operand)) < FIRST_PSEUDO_REGISTER)
02886 {
02887 if (!subreg_offset_representable_p
02888 (REGNO (SUBREG_REG (operand)),
02889 GET_MODE (SUBREG_REG (operand)),
02890 SUBREG_BYTE (operand),
02891 GET_MODE (operand)))
02892 force_reload = 1;
02893 offset += subreg_regno_offset (REGNO (SUBREG_REG (operand)),
02894 GET_MODE (SUBREG_REG (operand)),
02895 SUBREG_BYTE (operand),
02896 GET_MODE (operand));
02897 }
02898 operand = SUBREG_REG (operand);
02899
02900
02901 if (CONSTANT_P (operand)
02902 || GET_CODE (operand) == PLUS
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927 || ((GET_CODE (operand) == MEM
02928 || (GET_CODE (operand)== REG
02929 && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
02930 #ifndef WORD_REGISTER_OPERATIONS
02931 && (((GET_MODE_BITSIZE (GET_MODE (operand))
02932 < BIGGEST_ALIGNMENT)
02933 && (GET_MODE_SIZE (operand_mode[i])
02934 > GET_MODE_SIZE (GET_MODE (operand))))
02935 || (GET_CODE (operand) == MEM && BYTES_BIG_ENDIAN)
02936 #ifdef LOAD_EXTEND_OP
02937 || (GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
02938 && (GET_MODE_SIZE (GET_MODE (operand))
02939 <= UNITS_PER_WORD)
02940 && (GET_MODE_SIZE (operand_mode[i])
02941 > GET_MODE_SIZE (GET_MODE (operand)))
02942 && INTEGRAL_MODE_P (GET_MODE (operand))
02943 && LOAD_EXTEND_OP (GET_MODE (operand)) != NIL)
02944 #endif
02945 )
02946 #endif
02947 )
02948 )
02949 force_reload = 1;
02950 }
02951
02952 this_alternative[i] = (int) NO_REGS;
02953 this_alternative_win[i] = 0;
02954 this_alternative_match_win[i] = 0;
02955 this_alternative_offmemok[i] = 0;
02956 this_alternative_earlyclobber[i] = 0;
02957 this_alternative_matches[i] = -1;
02958
02959
02960
02961 if (*p == 0 || *p == ',')
02962 win = 1, badop = 0;
02963
02964
02965
02966
02967
02968
02969
02970
02971 while (*p && (c = *p++) != ',')
02972 switch (c)
02973 {
02974 case '=': case '+': case '*':
02975 break;
02976
02977 case '%':
02978
02979 if (i != noperands - 1)
02980 commutative = i;
02981 break;
02982
02983 case '?':
02984 reject += 6;
02985 break;
02986
02987 case '!':
02988 reject = 600;
02989 break;
02990
02991 case '#':
02992
02993
02994 while (*p && *p != ',')
02995 p++;
02996 break;
02997
02998 case '0': case '1': case '2': case '3': case '4':
02999 case '5': case '6': case '7': case '8': case '9':
03000 c = strtoul (p - 1, &p, 10);
03001
03002 this_alternative_matches[i] = c;
03003
03004
03005
03006
03007
03008
03009
03010 if ((swapped && (c != commutative || i != commutative + 1))
03011
03012
03013
03014
03015
03016
03017 ? (operands_match
03018 [(c == commutative || c == commutative + 1)
03019 ? 2 * commutative + 1 - c : c]
03020 [(i == commutative || i == commutative + 1)
03021 ? 2 * commutative + 1 - i : i])
03022 : operands_match[c][i])
03023 {
03024
03025
03026
03027 if (this_alternative_offmemok[c]
03028 && GET_CODE (recog_data.operand[c]) == MEM
03029 && this_alternative[c] == (int) NO_REGS
03030 && ! this_alternative_win[c])
03031 bad = 1;
03032
03033 did_match = this_alternative_win[c];
03034 }
03035 else
03036 {
03037
03038 rtx value;
03039
03040
03041 if (this_alternative_win[c])
03042 losers++;
03043 this_alternative_win[c] = 0;
03044 if (this_alternative[c] == (int) NO_REGS)
03045 bad = 1;
03046
03047
03048 value
03049 = find_dummy_reload (recog_data.operand[i],
03050 recog_data.operand[c],
03051 recog_data.operand_loc[i],
03052 recog_data.operand_loc[c],
03053 operand_mode[i], operand_mode[c],
03054 this_alternative[c], -1,
03055 this_alternative_earlyclobber[c]);
03056
03057 if (value != 0)
03058 losers--;
03059 }
03060
03061
03062 badop = 0;
03063 this_alternative[i] = this_alternative[c];
03064
03065
03066
03067
03068
03069 if (! did_match || force_reload)
03070 for (j = 0; j < i; j++)
03071 if (this_alternative_matches[j]
03072 == this_alternative_matches[i])
03073 badop = 1;
03074 break;
03075
03076 case 'p':
03077
03078
03079 this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode);
03080 win = 1;
03081 badop = 0;
03082 break;
03083
03084 case 'm':
03085 if (force_reload)
03086 break;
03087 if (GET_CODE (operand) == MEM
03088 || (GET_CODE (operand) == REG
03089 && REGNO (operand) >= FIRST_PSEUDO_REGISTER
03090 && reg_renumber[REGNO (operand)] < 0))
03091 win = 1;
03092 if (CONSTANT_P (operand)
03093
03094 && GET_CODE (operand) != HIGH)
03095 badop = 0;
03096 constmemok = 1;
03097 break;
03098
03099 case '<':
03100 if (GET_CODE (operand) == MEM
03101 && ! address_reloaded[i]
03102 && (GET_CODE (XEXP (operand, 0)) == PRE_DEC
03103 || GET_CODE (XEXP (operand, 0)) == POST_DEC))
03104 win = 1;
03105 break;
03106
03107 case '>':
03108 if (GET_CODE (operand) == MEM
03109 && ! address_reloaded[i]
03110 && (GET_CODE (XEXP (operand, 0)) == PRE_INC
03111 || GET_CODE (XEXP (operand, 0)) == POST_INC))
03112 win = 1;
03113 break;
03114
03115
03116 case 'V':
03117 if (force_reload)
03118 break;
03119 if (GET_CODE (operand) == MEM
03120 && ! (ind_levels ? offsettable_memref_p (operand)
03121 : offsettable_nonstrict_memref_p (operand))
03122
03123
03124
03125
03126 && !(GET_CODE (XEXP (operand, 0)) == REG
03127 && (ind_levels == 0
03128 || reg_equiv_address[REGNO (XEXP (operand, 0))] != 0)))
03129 win = 1;
03130 break;
03131
03132
03133 case 'o':
03134 if (force_reload)
03135 break;
03136 if ((GET_CODE (operand) == MEM
03137
03138
03139
03140 && ((ind_levels ? offsettable_memref_p (operand)
03141 : offsettable_nonstrict_memref_p (operand))
03142
03143
03144 || address_reloaded[i]))
03145 || (GET_CODE (operand) == REG
03146 && REGNO (operand) >= FIRST_PSEUDO_REGISTER
03147 && reg_renumber[REGNO (operand)] < 0
03148
03149
03150
03151
03152 && ((reg_equiv_mem[REGNO (operand)] != 0
03153 && offsettable_memref_p (reg_equiv_mem[REGNO (operand)]))
03154 || (reg_equiv_address[REGNO (operand)] != 0))))
03155 win = 1;
03156
03157 if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
03158 || GET_CODE (operand) == MEM)
03159 badop = 0;
03160 constmemok = 1;
03161 offmemok = 1;
03162 break;
03163
03164 case '&':
03165
03166
03167 earlyclobber = 1, this_earlyclobber = 1;
03168 break;
03169
03170 case 'E':
03171 case 'F':
03172 if (GET_CODE (operand) == CONST_DOUBLE
03173 || (GET_CODE (operand) == CONST_VECTOR
03174 && (GET_MODE_CLASS (GET_MODE (operand))
03175 == MODE_VECTOR_FLOAT)))
03176 win = 1;
03177 break;
03178
03179 case 'G':
03180 case 'H':
03181 if (GET_CODE (operand) == CONST_DOUBLE
03182 && CONST_DOUBLE_OK_FOR_LETTER_P (operand, c))
03183 win = 1;
03184 break;
03185
03186 case 's':
03187 if (GET_CODE (operand) == CONST_INT
03188 || (GET_CODE (operand) == CONST_DOUBLE
03189 && GET_MODE (operand) == VOIDmode))
03190 break;
03191 case 'i':
03192 if (CONSTANT_P (operand)
03193 #ifdef LEGITIMATE_PIC_OPERAND_P
03194 && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (operand))
03195 #endif
03196 )
03197 win = 1;
03198 break;
03199
03200 case 'n':
03201 if (GET_CODE (operand) == CONST_INT
03202 || (GET_CODE (operand) == CONST_DOUBLE
03203 && GET_MODE (operand) == VOIDmode))
03204 win = 1;
03205 break;
03206
03207 case 'I':
03208 case 'J':
03209 case 'K':
03210 case 'L':
03211 case 'M':
03212 case 'N':
03213 case 'O':
03214 case 'P':
03215 if (GET_CODE (operand) == CONST_INT
03216 && CONST_OK_FOR_LETTER_P (INTVAL (operand), c))
03217 win = 1;
03218 break;
03219
03220 case 'X':
03221 win = 1;
03222 break;
03223
03224 case 'g':
03225 if (! force_reload
03226
03227
03228 && GET_CODE (operand) != PLUS
03229
03230 && GET_CODE (operand) != SCRATCH
03231 #ifdef LEGITIMATE_PIC_OPERAND_P
03232 && (! CONSTANT_P (operand)
03233 || ! flag_pic
03234 || LEGITIMATE_PIC_OPERAND_P (operand))
03235 #endif
03236 && (GENERAL_REGS == ALL_REGS
03237 || GET_CODE (operand) != REG
03238 || (REGNO (operand) >= FIRST_PSEUDO_REGISTER
03239 && reg_renumber[REGNO (operand)] < 0)))
03240 win = 1;
03241
03242
03243 case 'r':
03244 this_alternative[i]
03245 = (int) reg_class_subunion[this_alternative[i]][(int) GENERAL_REGS];
03246 goto reg;
03247
03248 default:
03249 if (REG_CLASS_FROM_LETTER (c) == NO_REGS)
03250 {
03251 #ifdef EXTRA_CONSTRAINT
03252 if (EXTRA_MEMORY_CONSTRAINT (c))
03253 {
03254 if (force_reload)
03255 break;
03256 if (EXTRA_CONSTRAINT (operand, c))
03257 win = 1;
03258
03259
03260 if (GET_CODE (operand) == MEM && address_reloaded[i])
03261 win = 1;
03262
03263
03264
03265 if (GET_CODE (operand) == REG
03266 && REGNO (operand) >= FIRST_PSEUDO_REGISTER
03267 && reg_renumber[REGNO (operand)] < 0
03268 && ((reg_equiv_mem[REGNO (operand)] != 0
03269 && EXTRA_CONSTRAINT (reg_equiv_mem[REGNO (operand)], c))
03270 || (reg_equiv_address[REGNO (operand)] != 0)))
03271 win = 1;
03272
03273
03274
03275
03276 if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
03277 || GET_CODE (operand) == MEM)
03278 badop = 0;
03279 constmemok = 1;
03280 offmemok = 1;
03281 break;
03282 }
03283 if (EXTRA_ADDRESS_CONSTRAINT (c))
03284 {
03285 if (EXTRA_CONSTRAINT (operand, c))
03286 win = 1;
03287
03288
03289
03290 this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode);
03291 badop = 0;
03292 break;
03293 }
03294
03295 if (EXTRA_CONSTRAINT (operand, c))
03296 win = 1;
03297 #endif
03298 break;
03299 }
03300
03301 this_alternative[i]
03302 = (int) reg_class_subunion[this_alternative[i]][(int) REG_CLASS_FROM_LETTER (c)];
03303 reg:
03304 if (GET_MODE (operand) == BLKmode)
03305 break;
03306 winreg = 1;
03307 if (GET_CODE (operand) == REG
03308 && reg_fits_class_p (operand, this_alternative[i],
03309 offset, GET_MODE (recog_data.operand[i])))
03310 win = 1;
03311 break;
03312 }
03313
03314 constraints[i] = p;
03315
03316
03317
03318 if (winreg && this_alternative[i] != (int) NO_REGS)
03319 badop = 0;
03320
03321
03322 this_alternative_earlyclobber[i] = earlyclobber;
03323 if (win && ! force_reload)
03324 this_alternative_win[i] = 1;
03325 else if (did_match && ! force_reload)
03326 this_alternative_match_win[i] = 1;
03327 else
03328 {
03329 int const_to_mem = 0;
03330
03331 this_alternative_offmemok[i] = offmemok;
03332 losers++;
03333 if (badop)
03334 bad = 1;
03335
03336 if (GET_CODE (operand) == REG
03337 && this_alternative[i] == (int) NO_REGS
03338 && this_alternative_matches[i] < 0)
03339 bad = 1;
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349 if (CONSTANT_P (operand)
03350
03351 && GET_CODE (operand) != HIGH
03352 && ((PREFERRED_RELOAD_CLASS (operand,
03353 (enum reg_class) this_alternative[i])
03354 == NO_REGS)
03355 || no_input_reloads)
03356 && operand_mode[i] != VOIDmode)
03357 {
03358 const_to_mem = 1;
03359 if (this_alternative[i] != (int) NO_REGS)
03360 losers++;
03361 }
03362
03363
03364
03365
03366
03367
03368 if (! CONSTANT_P (operand)
03369 && (enum reg_class) this_alternative[i] != NO_REGS
03370 && (PREFERRED_RELOAD_CLASS (operand,
03371 (enum reg_class) this_alternative[i])
03372 == NO_REGS))
03373 bad = 1;
03374
03375
03376
03377
03378 else if (GET_CODE (operand) != SCRATCH
03379 && modified[i] != RELOAD_READ && no_output_reloads
03380 && ! find_reg_note (insn, REG_UNUSED, operand))
03381 bad = 1;
03382 else if (modified[i] != RELOAD_WRITE && no_input_reloads
03383 && ! const_to_mem)
03384 bad = 1;
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394 if (! (GET_CODE (operand) == REG
03395 && REGNO (operand) >= FIRST_PSEUDO_REGISTER)
03396 && GET_CODE (operand) != SCRATCH
03397 && ! (const_to_mem && constmemok))
03398 reject += 2;
03399
03400
03401
03402 if (operand_type[i] != RELOAD_FOR_INPUT
03403 && GET_CODE (operand) != SCRATCH)
03404 reject++;
03405 }
03406
03407
03408
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428 if (! win && ! did_match
03429 && this_alternative[i] != (int) NO_REGS
03430 && GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
03431 && reg_class_size[(int) preferred_class[i]] > 1)
03432 {
03433 if (! reg_class_subset_p (this_alternative[i],
03434 preferred_class[i]))
03435 {
03436
03437
03438
03439
03440 if (reg_class_subset_p (preferred_class[i],
03441 this_alternative[i]))
03442 this_alternative[i] = (int) preferred_class[i];
03443 else
03444 reject += (2 + 2 * pref_or_nothing[i]);
03445 }
03446 }
03447 }
03448
03449
03450
03451
03452
03453 for (i = 0; i < noperands; i++)
03454 if (this_alternative_earlyclobber[i]
03455 && (this_alternative_win[i] || this_alternative_match_win[i]))
03456 {
03457 struct decomposition early_data;
03458
03459 early_data = decompose (recog_data.operand[i]);
03460
03461 if (modified[i] == RELOAD_READ)
03462 abort ();
03463
03464 if (this_alternative[i] == NO_REGS)
03465 {
03466 this_alternative_earlyclobber[i] = 0;
03467 if (this_insn_is_asm)
03468 error_for_asm (this_insn,
03469 "`&' constraint used with no register class");
03470 else
03471 abort ();
03472 }
03473
03474 for (j = 0; j < noperands; j++)
03475
03476 if ((GET_CODE (recog_data.operand[j]) == MEM
03477 || modified[j] != RELOAD_WRITE)
03478 && j != i
03479
03480 && *recog_data.constraints[j] != 0
03481
03482
03483 && ! (this_alternative_matches[j] == i
03484 && rtx_equal_p (recog_data.operand[i],
03485 recog_data.operand[j]))
03486
03487 && !immune_p (recog_data.operand[j], recog_data.operand[i],
03488 early_data))
03489 {
03490
03491
03492 if (reg_class_size[this_alternative[i]] == 1
03493 && (GET_CODE (recog_data.operand[j]) == REG
03494 || GET_CODE (recog_data.operand[j]) == SUBREG))
03495 {
03496 losers++;
03497 this_alternative_win[j] = 0;
03498 this_alternative_match_win[j] = 0;
03499 }
03500 else
03501 break;
03502 }
03503
03504
03505 if (j != noperands)
03506 {
03507 losers++;
03508 this_alternative_win[i] = 0;
03509 this_alternative_match_win[j] = 0;
03510 for (j = 0; j < noperands; j++)
03511 if (this_alternative_matches[j] == i
03512 && this_alternative_match_win[j])
03513 {
03514 this_alternative_win[j] = 0;
03515 this_alternative_match_win[j] = 0;
03516 losers++;
03517 }
03518 }
03519 }
03520
03521
03522
03523 if (losers == 0)
03524 {
03525
03526 if (commutative >= 0)
03527 {
03528 recog_data.operand[commutative] = substed_operand[commutative];
03529 recog_data.operand[commutative + 1]
03530 = substed_operand[commutative + 1];
03531 }
03532 for (i = 0; i < noperands; i++)
03533 {
03534 goal_alternative_win[i] = this_alternative_win[i];
03535 goal_alternative_match_win[i] = this_alternative_match_win[i];
03536 goal_alternative[i] = this_alternative[i];
03537 goal_alternative_offmemok[i] = this_alternative_offmemok[i];
03538 goal_alternative_matches[i] = this_alternative_matches[i];
03539 goal_alternative_earlyclobber[i]
03540 = this_alternative_earlyclobber[i];
03541 }
03542 goal_alternative_number = this_alternative_number;
03543 goal_alternative_swapped = swapped;
03544 goal_earlyclobber = this_earlyclobber;
03545 goto finish;
03546 }
03547
03548
03549
03550
03551
03552 losers = losers * 6 + reject;
03553
03554
03555
03556
03557 if (! bad && best > losers)
03558 {
03559 for (i = 0; i < noperands; i++)
03560 {
03561 goal_alternative[i] = this_alternative[i];
03562 goal_alternative_win[i] = this_alternative_win[i];
03563 goal_alternative_match_win[i] = this_alternative_match_win[i];
03564 goal_alternative_offmemok[i] = this_alternative_offmemok[i];
03565 goal_alternative_matches[i] = this_alternative_matches[i];
03566 goal_alternative_earlyclobber[i]
03567 = this_alternative_earlyclobber[i];
03568 }
03569 goal_alternative_swapped = swapped;
03570 best = losers;
03571 goal_alternative_number = this_alternative_number;
03572 goal_earlyclobber = this_earlyclobber;
03573 }
03574 }
03575
03576
03577
03578
03579
03580
03581
03582
03583
03584
03585 if (commutative >= 0)
03586 {
03587 swapped = !swapped;
03588 if (swapped)
03589 {
03590 enum reg_class tclass;
03591 int t;
03592
03593 recog_data.operand[commutative] = substed_operand[commutative + 1];
03594 recog_data.operand[commutative + 1] = substed_operand[commutative];
03595
03596 for (i = 0; i < recog_data.n_dups; i++)
03597 if (recog_data.dup_num[i] == commutative
03598 || recog_data.dup_num[i] == commutative + 1)
03599 *recog_data.dup_loc[i]
03600 = recog_data.operand[(int) recog_data.dup_num[i]];
03601
03602 tclass = preferred_class[commutative];
03603 preferred_class[commutative] = preferred_class[commutative + 1];
03604 preferred_class[commutative + 1] = tclass;
03605
03606 t = pref_or_nothing[commutative];
03607 pref_or_nothing[commutative] = pref_or_nothing[commutative + 1];
03608 pref_or_nothing[commutative + 1] = t;
03609
03610 memcpy (constraints, recog_data.constraints,
03611 noperands * sizeof (char *));
03612 goto try_swapped;
03613 }
03614 else
03615 {
03616 recog_data.operand[commutative] = substed_operand[commutative];
03617 recog_data.operand[commutative + 1]
03618 = substed_operand[commutative + 1];
03619
03620 for (i = 0; i < recog_data.n_dups; i++)
03621 if (recog_data.dup_num[i] == commutative
03622 || recog_data.dup_num[i] == commutative + 1)
03623 *recog_data.dup_loc[i]
03624 = recog_data.operand[(int) recog_data.dup_num[i]];
03625 }
03626 }
03627
03628
03629
03630
03631
03632
03633 if (best == MAX_RECOG_OPERANDS * 2 + 600)
03634 {
03635
03636 if (insn_code_number >= 0)
03637 fatal_insn ("unable to generate reloads for:", insn);
03638 error_for_asm (insn, "inconsistent operand constraints in an `asm'");
03639
03640 PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
03641 n_reloads = 0;
03642 return 0;
03643 }
03644
03645
03646
03647 finish:
03648
03649
03650
03651
03652
03653
03654
03655 for (i = 0; i < noperands; i++)
03656 goal_alternative_matched[i] = -1;
03657
03658 for (i = 0; i < noperands; i++)
03659 if (! goal_alternative_win[i]
03660 && goal_alternative_matches[i] >= 0)
03661 goal_alternative_matched[goal_alternative_matches[i]] = i;
03662
03663 for (i = 0; i < noperands; i++)
03664 goal_alternative_win[i] |= goal_alternative_match_win[i];
03665
03666
03667
03668
03669
03670 if (goal_alternative_swapped)
03671 {
03672 rtx tem;
03673
03674 tem = substed_operand[commutative];
03675 substed_operand[commutative] = substed_operand[commutative + 1];
03676 substed_operand[commutative + 1] = tem;
03677 tem = recog_data.operand[commutative];
03678 recog_data.operand[commutative] = recog_data.operand[commutative + 1];
03679 recog_data.operand[commutative + 1] = tem;
03680 tem = *recog_data.operand_loc[commutative];
03681 *recog_data.operand_loc[commutative]
03682 = *recog_data.operand_loc[commutative + 1];
03683 *recog_data.operand_loc[commutative + 1] = tem;
03684
03685 for (i = 0; i < n_reloads; i++)
03686 {
03687 if (rld[i].opnum == commutative)
03688 rld[i].opnum = commutative + 1;
03689 else if (rld[i].opnum == commutative + 1)
03690 rld[i].opnum = commutative;
03691 }
03692 }
03693
03694 for (i = 0; i < noperands; i++)
03695 {
03696 operand_reloadnum[i] = -1;
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706
03707
03708
03709
03710
03711
03712
03713
03714
03715 if (goal_alternative_earlyclobber[i] && operand_type[i] != RELOAD_OTHER)
03716 operand_type[i]
03717 = (find_reg_note (insn, REG_UNUSED, recog_data.operand[i])
03718 ? RELOAD_FOR_INSN : RELOAD_OTHER);
03719 }
03720
03721
03722
03723 for (i = 0; i < noperands; i++)
03724 if (! goal_alternative_win[i]
03725 && CONSTANT_P (recog_data.operand[i])
03726
03727 && GET_CODE (recog_data.operand[i]) != HIGH
03728 && ((PREFERRED_RELOAD_CLASS (recog_data.operand[i],
03729 (enum reg_class) goal_alternative[i])
03730 == NO_REGS)
03731 || no_input_reloads)
03732 && operand_mode[i] != VOIDmode)
03733 {
03734 substed_operand[i] = recog_data.operand[i]
03735 = find_reloads_toplev (force_const_mem (operand_mode[i],
03736 recog_data.operand[i]),
03737 i, address_type[i], ind_levels, 0, insn,
03738 NULL);
03739 if (alternative_allows_memconst (recog_data.constraints[i],
03740 goal_alternative_number))
03741 goal_alternative_win[i] = 1;
03742 }
03743
03744
03745 if (goal_earlyclobber)
03746 for (i = 0; i < noperands; i++)
03747 if (goal_alternative_earlyclobber[i])
03748 reload_earlyclobbers[n_earlyclobbers++] = recog_data.operand[i];
03749
03750
03751 for (i = 0; i < noperands; i++)
03752 if (! goal_alternative_win[i])
03753 {
03754
03755 if (goal_alternative_matches[i] >= 0)
03756 ;
03757
03758
03759
03760
03761
03762
03763
03764 else if (goal_alternative_matched[i] == -1
03765 && goal_alternative_offmemok[i]
03766 && GET_CODE (recog_data.operand[i]) == MEM)
03767 {
03768 operand_reloadnum[i]
03769 = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
03770 &XEXP (recog_data.operand[i], 0), (rtx*) 0,
03771 MODE_BASE_REG_CLASS (VOIDmode),
03772 GET_MODE (XEXP (recog_data.operand[i], 0)),
03773 VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
03774 rld[operand_reloadnum[i]].inc
03775 = GET_MODE_SIZE (GET_MODE (recog_data.operand[i]));
03776
03777
03778
03779
03780
03781
03782 if (modified[i] == RELOAD_WRITE)
03783 {
03784 for (j = 0; j < n_reloads; j++)
03785 {
03786 if (rld[j].opnum == i)
03787 {
03788 if (rld[j].when_needed == RELOAD_FOR_OUTPUT_ADDRESS)
03789 rld[j].when_needed = RELOAD_FOR_INPUT_ADDRESS;
03790 else if (rld[j].when_needed
03791 == RELOAD_FOR_OUTADDR_ADDRESS)
03792 rld[j].when_needed = RELOAD_FOR_INPADDR_ADDRESS;
03793 }
03794 }
03795 }
03796 }
03797 else if (goal_alternative_matched[i] == -1)
03798 {
03799 operand_reloadnum[i]
03800 = push_reload ((modified[i] != RELOAD_WRITE
03801 ? recog_data.operand[i] : 0),
03802 (modified[i] != RELOAD_READ
03803 ? recog_data.operand[i] : 0),
03804 (modified[i] != RELOAD_WRITE
03805 ? recog_data.operand_loc[i] : 0),
03806 (modified[i] != RELOAD_READ
03807 ? recog_data.operand_loc[i] : 0),
03808 (enum reg_class) goal_alternative[i],
03809 (modified[i] == RELOAD_WRITE
03810 ? VOIDmode : operand_mode[i]),
03811 (modified[i] == RELOAD_READ
03812 ? VOIDmode : operand_mode[i]),
03813 (insn_code_number < 0 ? 0
03814 : insn_data[insn_code_number].operand[i].strict_low),
03815 0, i, operand_type[i]);
03816 }
03817
03818
03819
03820 else if (modified[i] == RELOAD_READ
03821 && modified[goal_alternative_matched[i]] == RELOAD_WRITE)
03822 {
03823 operand_reloadnum[i]
03824 = push_reload (recog_data.operand[i],
03825 recog_data.operand[goal_alternative_matched[i]],
03826 recog_data.operand_loc[i],
03827 recog_data.operand_loc[goal_alternative_matched[i]],
03828 (enum reg_class) goal_alternative[i],
03829 operand_mode[i],
03830 operand_mode[goal_alternative_matched[i]],
03831 0, 0, i, RELOAD_OTHER);
03832 operand_reloadnum[goal_alternative_matched[i]] = output_reloadnum;
03833 }
03834 else if (modified[i] == RELOAD_WRITE
03835 && modified[goal_alternative_matched[i]] == RELOAD_READ)
03836 {
03837 operand_reloadnum[goal_alternative_matched[i]]
03838 = push_reload (recog_data.operand[goal_alternative_matched[i]],
03839 recog_data.operand[i],
03840 recog_data.operand_loc[goal_alternative_matched[i]],
03841 recog_data.operand_loc[i],
03842 (enum reg_class) goal_alternative[i],
03843 operand_mode[goal_alternative_matched[i]],
03844 operand_mode[i],
03845 0, 0, i, RELOAD_OTHER);
03846 operand_reloadnum[i] = output_reloadnum;
03847 }
03848 else if (insn_code_number >= 0)
03849 abort ();
03850 else
03851 {
03852 error_for_asm (insn, "inconsistent operand constraints in an `asm'");
03853
03854 PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
03855 n_reloads = 0;
03856 return 0;
03857 }
03858 }
03859 else if (goal_alternative_matched[i] < 0
03860 && goal_alternative_matches[i] < 0
03861 && !address_operand_reloaded[i]
03862 && optimize)
03863 {
03864
03865
03866
03867
03868 rtx operand = recog_data.operand[i];
03869
03870 while (GET_CODE (operand) == SUBREG)
03871 operand = SUBREG_REG (operand);
03872 if ((GET_CODE (operand) == MEM
03873 || (GET_CODE (operand) == REG
03874 && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
03875
03876
03877
03878 && ((enum reg_class) goal_alternative[i] != NO_REGS
03879 || modified[i] == RELOAD_WRITE)
03880 && ! no_input_reloads
03881
03882
03883
03884
03885
03886
03887
03888 && (modified[i] == RELOAD_READ
03889 || (! no_output_reloads && ! this_insn_is_asm)))
03890 operand_reloadnum[i]
03891 = push_reload ((modified[i] != RELOAD_WRITE
03892 ? recog_data.operand[i] : 0),
03893 (modified[i] != RELOAD_READ
03894 ? recog_data.operand[i] : 0),
03895 (modified[i] != RELOAD_WRITE
03896 ? recog_data.operand_loc[i] : 0),
03897 (modified[i] != RELOAD_READ
03898 ? recog_data.operand_loc[i] : 0),
03899 (enum reg_class) goal_alternative[i],
03900 (modified[i] == RELOAD_WRITE
03901 ? VOIDmode : operand_mode[i]),
03902 (modified[i] == RELOAD_READ
03903 ? VOIDmode : operand_mode[i]),
03904 (insn_code_number < 0 ? 0
03905 : insn_data[insn_code_number].operand[i].strict_low),
03906 1, i, operand_type[i]);
03907
03908
03909
03910
03911
03912 else if (replace
03913 && (GET_CODE (operand) == MEM
03914 || (GET_CODE (operand) == REG
03915 && REGNO (operand) >= FIRST_PSEUDO_REGISTER
03916 && reg_renumber [REGNO (operand)] < 0)))
03917 {
03918 operand = *recog_data.operand_loc[i];
03919
03920 while (GET_CODE (operand) == SUBREG)
03921 operand = SUBREG_REG (operand);
03922 if (GET_CODE (operand) == REG)
03923 {
03924 if (modified[i] != RELOAD_WRITE)
03925
03926
03927
03928 PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode, operand),
03929 insn), QImode);
03930 if (modified[i] != RELOAD_READ)
03931 emit_insn_after (gen_rtx_CLOBBER (VOIDmode, operand), insn);
03932 }
03933 }
03934 }
03935 else if (goal_alternative_matches[i] >= 0
03936 && goal_alternative_win[goal_alternative_matches[i]]
03937 && modified[i] == RELOAD_READ
03938 && modified[goal_alternative_matches[i]] == RELOAD_WRITE
03939 && ! no_input_reloads && ! no_output_reloads
03940 && optimize)
03941 {
03942
03943
03944
03945 rtx operand = recog_data.operand[i];
03946
03947 while (GET_CODE (operand) == SUBREG)
03948 operand = SUBREG_REG (operand);
03949 if ((GET_CODE (operand) == MEM
03950 || (GET_CODE (operand) == REG
03951 && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
03952 && ((enum reg_class) goal_alternative[goal_alternative_matches[i]]
03953 != NO_REGS))
03954 operand_reloadnum[i] = operand_reloadnum[goal_alternative_matches[i]]
03955 = push_reload (recog_data.operand[goal_alternative_matches[i]],
03956 recog_data.operand[i],
03957 recog_data.operand_loc[goal_alternative_matches[i]],
03958 recog_data.operand_loc[i],
03959 (enum reg_class) goal_alternative[goal_alternative_matches[i]],
03960 operand_mode[goal_alternative_matches[i]],
03961 operand_mode[i],
03962 0, 1, goal_alternative_matches[i], RELOAD_OTHER);
03963 }
03964
03965
03966
03967
03968
03969 for (i = 0; i < noperands; i++)
03970 {
03971
03972
03973
03974
03975
03976 if (replace)
03977 {
03978 rtx substitution = substed_operand[i];
03979
03980 *recog_data.operand_loc[i] = substitution;
03981
03982
03983
03984
03985 if (GET_CODE (insn) != JUMP_INSN
03986 && GET_CODE (substitution) == LABEL_REF
03987 && !find_reg_note (insn, REG_LABEL, XEXP (substitution, 0)))
03988 REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL,
03989 XEXP (substitution, 0),
03990 REG_NOTES (insn));
03991 }
03992 else
03993 retval |= (substed_operand[i] != *recog_data.operand_loc[i]);
03994 }
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004 if (insn_code_number >= 0 && replace)
04005 for (i = insn_data[insn_code_number].n_dups - 1; i >= 0; i--)
04006 {
04007 int opno = recog_data.dup_num[i];
04008 *recog_data.dup_loc[i] = *recog_data.operand_loc[opno];
04009 dup_replacements (recog_data.dup_loc[i], recog_data.operand_loc[opno]);
04010 }
04011
04012 #if 0
04013
04014
04015
04016
04017
04018
04019
04020
04021
04022 for (i = 0; i < n_reloads; i++)
04023 if (rld[i].reg_rtx == 0
04024 && rld[i].in != 0
04025 && GET_CODE (rld[i].in) == REG
04026 && rld[i].out == 0)
04027 {
04028 rld[i].reg_rtx
04029 = find_equiv_reg (rld[i].in, insn, rld[i].class, -1,
04030 static_reload_reg_p, 0, rld[i].inmode);
04031
04032
04033 if (rld[i].reg_rtx)
04034 rld[i].in = rld[i].reg_rtx;
04035 }
04036 #endif
04037
04038
04039
04040 if (!goal_earlyclobber)
04041 combine_reloads ();
04042
04043
04044
04045
04046
04047
04048 for (i = 0; i < n_reloads; i++)
04049 {
04050 int k;
04051
04052 for (j = i + 1; j < n_reloads; j++)
04053 if ((rld[i].when_needed == RELOAD_FOR_INPUT_ADDRESS
04054 || rld[i].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
04055 || rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS
04056 || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
04057 && (rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS
04058 || rld[j].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
04059 || rld[j].when_needed == RELOAD_FOR_INPADDR_ADDRESS
04060 || rld[j].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
04061 && rtx_equal_p (rld[i].in, rld[j].in)
04062 && (operand_reloadnum[rld[i].opnum] < 0
04063 || rld[operand_reloadnum[rld[i].opnum]].optional)
04064 && (operand_reloadnum[rld[j].opnum] < 0
04065 || rld[operand_reloadnum[rld[j].opnum]].optional)
04066 && (goal_alternative_matches[rld[i].opnum] == rld[j].opnum
04067 || (goal_alternative_matches[rld[j].opnum]
04068 == rld[i].opnum)))
04069 {
04070 for (k = 0; k < n_replacements; k++)
04071 if (replacements[k].what == j)
04072 replacements[k].what = i;
04073
04074 if (rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS
04075 || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
04076 rld[i].when_needed = RELOAD_FOR_OPADDR_ADDR;
04077 else
04078 rld[i].when_needed = RELOAD_FOR_OPERAND_ADDRESS;
04079 rld[j].in = 0;
04080 }
04081 }
04082
04083
04084
04085
04086
04087
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100 for (i = 0; i < n_reloads; i++)
04101 {
04102 if (rld[i].secondary_p
04103 && rld[i].when_needed == operand_type[rld[i].opnum])
04104 rld[i].when_needed = address_type[rld[i].opnum];
04105
04106 if ((rld[i].when_needed == RELOAD_FOR_INPUT_ADDRESS
04107 || rld[i].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
04108 || rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS
04109 || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
04110 && (operand_reloadnum[rld[i].opnum] < 0
04111 || rld[operand_reloadnum[rld[i].opnum]].optional))
04112 {
04113
04114
04115
04116 if ((rld[i].when_needed == RELOAD_FOR_INPUT_ADDRESS
04117 || rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS)
04118 && rld[i].secondary_in_reload != -1)
04119 {
04120 int secondary_in_reload = rld[i].secondary_in_reload;
04121
04122 rld[secondary_in_reload].when_needed = RELOAD_FOR_OPADDR_ADDR;
04123
04124
04125 if (secondary_in_reload > 0
04126 && rld[secondary_in_reload].secondary_in_reload != -1)
04127 rld[rld[secondary_in_reload].secondary_in_reload].when_needed
04128 = RELOAD_FOR_OPADDR_ADDR;
04129 }
04130
04131 if ((rld[i].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
04132 || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
04133 && rld[i].secondary_out_reload != -1)
04134 {
04135 int secondary_out_reload = rld[i].secondary_out_reload;
04136
04137 rld[secondary_out_reload].when_needed = RELOAD_FOR_OPADDR_ADDR;
04138
04139
04140 if (secondary_out_reload
04141 && rld[secondary_out_reload].secondary_out_reload != -1)
04142 rld[rld[secondary_out_reload].secondary_out_reload].when_needed
04143 = RELOAD_FOR_OPADDR_ADDR;
04144 }
04145
04146 if (rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS
04147 || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
04148 rld[i].when_needed = RELOAD_FOR_OPADDR_ADDR;
04149 else
04150 rld[i].when_needed = RELOAD_FOR_OPERAND_ADDRESS;
04151 }
04152
04153 if ((rld[i].when_needed == RELOAD_FOR_INPUT_ADDRESS
04154 || rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS)
04155 && operand_reloadnum[rld[i].opnum] >= 0
04156 && (rld[operand_reloadnum[rld[i].opnum]].when_needed
04157 == RELOAD_OTHER))
04158 rld[i].when_needed = RELOAD_FOR_OTHER_ADDRESS;
04159
04160 if (goal_alternative_matches[rld[i].opnum] >= 0)
04161 rld[i].opnum = goal_alternative_matches[rld[i].opnum];
04162 }
04163
04164
04165
04166
04167
04168
04169
04170
04171
04172
04173
04174
04175
04176
04177
04178
04179
04180
04181
04182
04183
04184
04185
04186
04187 {
04188 int first_op_addr_num = -2;
04189 int first_inpaddr_num[MAX_RECOG_OPERANDS];
04190 int first_outpaddr_num[MAX_RECOG_OPERANDS];
04191 int need_change = 0;
04192
04193
04194
04195
04196
04197
04198 for (i = 0; i < noperands; i++)
04199 first_inpaddr_num[i] = first_outpaddr_num[i] = -2;
04200 for (i = n_reloads - 1; i >= 0; i--)
04201 {
04202 switch (rld[i].when_needed)
04203 {
04204 case RELOAD_FOR_OPERAND_ADDRESS:
04205 if (++first_op_addr_num >= 0)
04206 {
04207 first_op_addr_num = i;
04208 need_change = 1;
04209 }
04210 break;
04211 case RELOAD_FOR_INPUT_ADDRESS:
04212 if (++first_inpaddr_num[rld[i].opnum] >= 0)
04213 {
04214 first_inpaddr_num[rld[i].opnum] = i;
04215 need_change = 1;
04216 }
04217 break;
04218 case RELOAD_FOR_OUTPUT_ADDRESS:
04219 if (++first_outpaddr_num[rld[i].opnum] >= 0)
04220 {
04221 first_outpaddr_num[rld[i].opnum] = i;
04222 need_change = 1;
04223 }
04224 break;
04225 default:
04226 break;
04227 }
04228 }
04229
04230 if (need_change)
04231 {
04232 for (i = 0; i < n_reloads; i++)
04233 {
04234 int first_num;
04235 enum reload_type type;
04236
04237 switch (rld[i].when_needed)
04238 {
04239 case RELOAD_FOR_OPADDR_ADDR:
04240 first_num = first_op_addr_num;
04241 type = RELOAD_FOR_OPERAND_ADDRESS;
04242 break;
04243 case RELOAD_FOR_INPADDR_ADDRESS:
04244 first_num = first_inpaddr_num[rld[i].opnum];
04245 type = RELOAD_FOR_INPUT_ADDRESS;
04246 break;
04247 case RELOAD_FOR_OUTADDR_ADDRESS:
04248 first_num = first_outpaddr_num[rld[i].opnum];
04249 type = RELOAD_FOR_OUTPUT_ADDRESS;
04250 break;
04251 default:
04252 continue;
04253 }
04254 if (first_num < 0)
04255 continue;
04256 else if (i > first_num)
04257 rld[i].when_needed = type;
04258 else
04259 {
04260
04261
04262 for (j = n_reloads - 1; j > first_num; j--)
04263 {
04264 if (rld[j].when_needed == type
04265 && (rld[i].secondary_p
04266 ? rld[j].secondary_in_reload == i
04267 : reg_mentioned_p (rld[i].in, rld[j].in)))
04268 {
04269 rld[i].when_needed = type;
04270 break;
04271 }
04272 }
04273 }
04274 }
04275 }
04276 }
04277
04278
04279
04280
04281
04282
04283 for (i = 0; i < n_reloads; i++)
04284 if (rld[i].in != 0 && rld[i].out == 0
04285 && (rld[i].when_needed == RELOAD_FOR_OPERAND_ADDRESS
04286 || rld[i].when_needed == RELOAD_FOR_OPADDR_ADDR
04287 || rld[i].when_needed == RELOAD_FOR_OTHER_ADDRESS))
04288 for (j = 0; j < n_reloads; j++)
04289 if (i != j && rld[j].in != 0 && rld[j].out == 0
04290 && rld[j].when_needed == rld[i].when_needed
04291 && MATCHES (rld[i].in, rld[j].in)
04292 && rld[i].class == rld[j].class
04293 && !rld[i].nocombine && !rld[j].nocombine
04294 && rld[i].reg_rtx == rld[j].reg_rtx)
04295 {
04296 rld[i].opnum = MIN (rld[i].opnum, rld[j].opnum);
04297 transfer_replacements (i, j);
04298 rld[j].in = 0;
04299 }
04300
04301 #ifdef HAVE_cc0
04302
04303
04304
04305 if (no_input_reloads)
04306 for (i = 0; i < n_reloads; i++)
04307 if (rld[i].in != 0
04308 && rld[i].when_needed != RELOAD_FOR_OUTADDR_ADDRESS
04309 && rld[i].when_needed != RELOAD_FOR_OUTPUT_ADDRESS)
04310 abort ();
04311 #endif
04312
04313
04314 for (i = 0; i < n_reloads; i++)
04315 {
04316 rld[i].mode
04317 = (rld[i].inmode == VOIDmode
04318 || (GET_MODE_SIZE (rld[i].outmode)
04319 > GET_MODE_SIZE (rld[i].inmode)))
04320 ? rld[i].outmode : rld[i].inmode;
04321
04322 rld[i].nregs = CLASS_MAX_NREGS (rld[i].class, rld[i].mode);
04323 }
04324
04325
04326
04327 for (i = 0; i < n_reloads; i++)
04328 if (rld[i].when_needed == RELOAD_FOR_INPUT
04329 && GET_CODE (PATTERN (insn)) == SET
04330 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
04331 && SET_SRC (PATTERN (insn)) == rld[i].in)
04332 {
04333 rtx dest = SET_DEST (PATTERN (insn));
04334 unsigned int regno = REGNO (dest);
04335
04336 if (regno < FIRST_PSEUDO_REGISTER
04337 && TEST_HARD_REG_BIT (reg_class_contents[rld[i].class], regno)
04338 && HARD_REGNO_MODE_OK (regno, rld[i].mode))
04339 rld[i].reg_rtx = dest;
04340 }
04341
04342 return retval;
04343 }
04344
04345
04346
04347
04348 static int
04349 alternative_allows_memconst (constraint, altnum)
04350 const char *constraint;
04351 int altnum;
04352 {
04353 int c;
04354
04355 while (altnum > 0)
04356 {
04357 while (*constraint++ != ',');
04358 altnum--;
04359 }
04360
04361
04362 while ((c = *constraint++) && c != ',' && c != '#')
04363 if (c == 'm' || c == 'o' || EXTRA_MEMORY_CONSTRAINT (c))
04364 return 1;
04365 return 0;
04366 }
04367
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380
04381
04382
04383
04384
04385
04386
04387
04388
04389
04390 static rtx
04391 find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest, insn,
04392 address_reloaded)
04393 rtx x;
04394 int opnum;
04395 enum reload_type type;
04396 int ind_levels;
04397 int is_set_dest;
04398 rtx insn;
04399 int *address_reloaded;
04400 {
04401 RTX_CODE code = GET_CODE (x);
04402
04403 const char *fmt = GET_RTX_FORMAT (code);
04404 int i;
04405 int copied;
04406
04407 if (code == REG)
04408 {
04409
04410 int regno = REGNO (x);
04411 if (reg_equiv_constant[regno] != 0 && !is_set_dest)
04412 x = reg_equiv_constant[regno];
04413 #if 0
04414
04415
04416 else if (reg_equiv_mem[regno] != 0)
04417 x = reg_equiv_mem[regno];
04418 #endif
04419 else if (reg_equiv_memory_loc[regno]
04420 && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
04421 {
04422 rtx mem = make_memloc (x, regno);
04423 if (reg_equiv_address[regno]
04424 || ! rtx_equal_p (mem, reg_equiv_mem[regno]))
04425 {
04426
04427
04428
04429 if (replace_reloads && recog_data.operand[opnum] != x)
04430
04431
04432
04433 PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode, x), insn),
04434 QImode);
04435 x = mem;
04436 i = find_reloads_address (GET_MODE (x), &x, XEXP (x, 0), &XEXP (x, 0),
04437 opnum, type, ind_levels, insn);
04438 if (address_reloaded)
04439 *address_reloaded = i;
04440 }
04441 }
04442 return x;
04443 }
04444 if (code == MEM)
04445 {
04446 rtx tem = x;
04447
04448 i = find_reloads_address (GET_MODE (x), &tem, XEXP (x, 0), &XEXP (x, 0),
04449 opnum, type, ind_levels, insn);
04450 if (address_reloaded)
04451 *address_reloaded = i;
04452
04453 return tem;
04454 }
04455
04456 if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG)
04457 {
04458
04459
04460
04461
04462
04463
04464
04465
04466
04467 int regno = REGNO (SUBREG_REG (x));
04468 rtx tem;
04469
04470 if (subreg_lowpart_p (x)
04471 && regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
04472 && reg_equiv_constant[regno] != 0
04473 && (tem = gen_lowpart_common (GET_MODE (x),
04474 reg_equiv_constant[regno])) != 0)
04475 return tem;
04476
04477 if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
04478 && reg_equiv_constant[regno] != 0)
04479 {
04480 tem =
04481 simplify_gen_subreg (GET_MODE (x), reg_equiv_constant[regno],
04482 GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
04483 if (!tem)
04484 abort ();
04485 return tem;
04486 }
04487
04488
04489
04490
04491
04492
04493
04494
04495
04496
04497
04498
04499
04500
04501 else if (regno >= FIRST_PSEUDO_REGISTER
04502 #ifdef LOAD_EXTEND_OP
04503 && (GET_MODE_SIZE (GET_MODE (x))
04504 <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
04505 #endif
04506 && (reg_equiv_address[regno] != 0
04507 || (reg_equiv_mem[regno] != 0
04508 && (! strict_memory_address_p (GET_MODE (x),
04509 XEXP (reg_equiv_mem[regno], 0))
04510 || ! offsettable_memref_p (reg_equiv_mem[regno])
04511 || num_not_at_initial_offset))))
04512 x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
04513 insn);
04514 }
04515
04516 for (copied = 0, i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
04517 {
04518 if (fmt[i] == 'e')
04519 {
04520 rtx new_part = find_reloads_toplev (XEXP (x, i), opnum, type,
04521 ind_levels, is_set_dest, insn,
04522 address_reloaded);
04523
04524
04525
04526
04527
04528 if (new_part != XEXP (x, i) && ! CONSTANT_P (new_part) && ! copied)
04529 {
04530 x = shallow_copy_rtx (x);
04531 copied = 1;
04532 }
04533 XEXP (x, i) = new_part;
04534 }
04535 }
04536 return x;
04537 }
04538
04539
04540
04541
04542 static rtx
04543 make_memloc (ad, regno)
04544 rtx ad;
04545 int regno;
04546 {
04547
04548
04549 rtx tem
04550 = XEXP (eliminate_regs (reg_equiv_memory_loc[regno], 0, NULL_RTX), 0);
04551
04552
04553
04554 if (rtx_varies_p (tem, 0))
04555 tem = copy_rtx (tem);
04556
04557 tem = replace_equiv_address_nv (reg_equiv_memory_loc[regno], tem);
04558 tem = adjust_address_nv (tem, GET_MODE (ad), 0);
04559
04560
04561
04562 if (tem == reg_equiv_memory_loc[regno])
04563 tem = copy_rtx (tem);
04564 return tem;
04565 }
04566
04567
04568
04569
04570
04571 static int
04572 maybe_memory_address_p (mode, ad, part)
04573 enum machine_mode mode;
04574 rtx ad;
04575 rtx *part;
04576 {
04577 int retv;
04578 rtx tem = *part;
04579 rtx reg = gen_rtx_REG (GET_MODE (tem), max_reg_num ());
04580
04581 *part = reg;
04582 retv = memory_address_p (mode, ad);
04583 *part = tem;
04584
04585 return retv;
04586 }
04587
04588
04589
04590
04591
04592
04593
04594
04595
04596
04597
04598
04599
04600
04601
04602
04603
04604
04605
04606
04607
04608
04609
04610
04611
04612 static int
04613 find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
04614 enum machine_mode mode;
04615 rtx *memrefloc;
04616 rtx ad;
04617 rtx *loc;
04618 int opnum;
04619 enum reload_type type;
04620 int ind_levels;
04621 rtx insn;
04622 {
04623 int regno;
04624 int removed_and = 0;
04625 rtx tem;
04626
04627
04628
04629
04630
04631 if (GET_CODE (ad) == REG)
04632 {
04633 regno = REGNO (ad);
04634
04635
04636
04637 tem = reg_equiv_constant[regno];
04638 if (tem != 0
04639 && (tem = eliminate_regs (tem, mode, insn))
04640 && strict_memory_address_p (mode, tem))
04641 {
04642 *loc = ad = tem;
04643 return 0;
04644 }
04645
04646 tem = reg_equiv_memory_loc[regno];
04647 if (tem != 0)
04648 {
04649 if (reg_equiv_address[regno] != 0 || num_not_at_initial_offset)
04650 {
04651 tem = make_memloc (ad, regno);
04652 if (! strict_memory_address_p (GET_MODE (tem), XEXP (tem, 0)))
04653 {
04654 find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
04655 &XEXP (tem, 0), opnum,
04656 ADDR_TYPE (type), ind_levels, insn);
04657 }
04658
04659
04660
04661
04662
04663 if (ind_levels > 0
04664 && strict_memory_address_p (mode, tem)
04665 && (GET_CODE (XEXP (tem, 0)) == REG
04666 || (GET_CODE (XEXP (tem, 0)) == PLUS
04667 && GET_CODE (XEXP (XEXP (tem, 0), 0)) == REG
04668 && CONSTANT_P (XEXP (XEXP (tem, 0), 1)))))
04669 {
04670
04671
04672
04673 if (replace_reloads
04674 && num_not_at_initial_offset
04675 && ! rtx_equal_p (tem, reg_equiv_mem[regno]))
04676 {
04677 *loc = tem;
04678
04679
04680
04681 PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode, ad),
04682 insn), QImode);
04683
04684
04685
04686 }
04687 return 0;
04688 }
04689 ad = tem;
04690 }
04691 }
04692
04693
04694
04695
04696
04697 else if (regno < FIRST_PSEUDO_REGISTER
04698 && REGNO_MODE_OK_FOR_BASE_P (regno, mode)
04699 && ! regno_clobbered_p (regno, this_insn, mode, 0))
04700 return 0;
04701
04702
04703 push_reload (ad, NULL_RTX, loc, (rtx*) 0, MODE_BASE_REG_CLASS (mode),
04704 GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
04705 return 1;
04706 }
04707
04708 if (strict_memory_address_p (mode, ad))
04709 {
04710
04711
04712
04713
04714
04715
04716
04717
04718 if (GET_CODE (ad) == PLUS
04719 && GET_CODE (XEXP (ad, 1)) == CONST_INT
04720 && GET_CODE (XEXP (ad, 0)) == REG
04721 && reg_equiv_constant[REGNO (XEXP (ad, 0))] == 0)
04722 return 0;
04723
04724 subst_reg_equivs_changed = 0;
04725 *loc = subst_reg_equivs (ad, insn);
04726
04727 if (! subst_reg_equivs_changed)
04728 return 0;
04729
04730
04731 if (strict_memory_address_p (mode, ad))
04732 return 0;
04733 }
04734
04735 #ifdef LEGITIMIZE_RELOAD_ADDRESS
04736 do
04737 {
04738 if (memrefloc)
04739 {
04740 LEGITIMIZE_RELOAD_ADDRESS (ad, GET_MODE (*memrefloc), opnum, type,
04741 ind_levels, win);
04742 }
04743 break;
04744 win:
04745 *memrefloc = copy_rtx (*memrefloc);
04746 XEXP (*memrefloc, 0) = ad;
04747 move_replacements (&ad, &XEXP (*memrefloc, 0));
04748 return 1;
04749 }
04750 while (0);
04751 #endif
04752
04753
04754
04755
04756 if (GET_CODE (ad) == AND)
04757 {
04758 removed_and = 1;
04759 loc = &XEXP (ad, 0);
04760 ad = *loc;
04761 }
04762
04763
04764
04765
04766
04767
04768
04769 if (GET_CODE (ad) == MEM)
04770 {
04771
04772
04773 tem = ad;
04774 find_reloads_address (GET_MODE (ad), &tem, XEXP (ad, 0), &XEXP (ad, 0),
04775 opnum, ADDR_TYPE (type),
04776 ind_levels == 0 ? 0 : ind_levels - 1, insn);
04777
04778
04779
04780 if (tem != ad && memrefloc)
04781 {
04782 *memrefloc = copy_rtx (*memrefloc);
04783 copy_replacements (tem, XEXP (*memrefloc, 0));
04784 loc = &XEXP (*memrefloc, 0);
04785 if (removed_and)
04786 loc = &XEXP (*loc, 0);
04787 }
04788
04789
04790
04791
04792
04793 if (ind_levels == 0
04794 || (GET_CODE (XEXP (tem, 0)) == SYMBOL_REF && ! indirect_symref_ok)
04795 || GET_CODE (XEXP (tem, 0)) == MEM
04796 || ! (GET_CODE (XEXP (tem, 0)) == REG
04797 || (GET_CODE (XEXP (tem, 0)) == PLUS
04798 && GET_CODE (XEXP (XEXP (tem, 0), 0)) == REG
04799 && GET_CODE (XEXP (XEXP (tem, 0), 1)) == CONST_INT)))
04800 {
04801
04802
04803 push_reload (tem, NULL_RTX, loc, (rtx*) 0,
04804 MODE_BASE_REG_CLASS (mode), GET_MODE (tem),
04805 VOIDmode, 0,
04806 0, opnum, type);
04807 return ! removed_and;
04808 }
04809 else
04810 return 0;
04811 }
04812
04813
04814
04815
04816
04817
04818 else if (GET_CODE (ad) == PLUS
04819 && GET_CODE (XEXP (ad, 0)) == REG
04820 && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
04821 && REG_MODE_OK_FOR_BASE_P (XEXP (ad, 0), mode)
04822 && GET_CODE (XEXP (ad, 1)) == CONST_INT)
04823 {
04824
04825 if (memrefloc)
04826 {
04827 *memrefloc = copy_rtx (*memrefloc);
04828 loc = &XEXP (*memrefloc, 0);
04829 if (removed_and)
04830 loc = &XEXP (*loc, 0);
04831 }
04832
04833 if (double_reg_address_ok)
04834 {
04835
04836 *loc = ad = copy_rtx (ad);
04837
04838
04839
04840 find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1),
04841 INDEX_REG_CLASS, GET_MODE (ad), opnum,
04842 type, ind_levels);
04843 return 0;
04844 }
04845 else
04846 {
04847
04848
04849
04850 find_reloads_address_part (ad, loc, MODE_BASE_REG_CLASS (mode),
04851 Pmode, opnum, type, ind_levels);
04852 }
04853 return ! removed_and;
04854 }
04855
04856
04857
04858
04859
04860
04861
04862
04863
04864
04865
04866
04867
04868
04869
04870
04871
04872
04873
04874
04875
04876
04877
04878
04879
04880 else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
04881 && GET_CODE (XEXP (ad, 0)) == PLUS
04882 && GET_CODE (XEXP (XEXP (ad, 0), 0)) == REG
04883 && REGNO (XEXP (XEXP (ad, 0), 0)) < FIRST_PSEUDO_REGISTER
04884 && REG_MODE_OK_FOR_BASE_P (XEXP (XEXP (ad, 0), 0), mode)
04885 && ! maybe_memory_address_p (mode, ad, &XEXP (XEXP (ad, 0), 1)))
04886 {
04887 *loc = ad = gen_rtx_PLUS (GET_MODE (ad),
04888 plus_constant (XEXP (XEXP (ad, 0), 0),
04889 INTVAL (XEXP (ad, 1))),
04890 XEXP (XEXP (ad, 0), 1));
04891 find_reloads_address_part (XEXP (ad, 0), &XEXP (ad, 0),
04892 MODE_BASE_REG_CLASS (mode),
04893 GET_MODE (ad), opnum, type, ind_levels);
04894 find_reloads_address_1 (mode, XEXP (ad, 1), 1, &XEXP (ad, 1), opnum,
04895 type, 0, insn);
04896
04897 return 0;
04898 }
04899
04900 else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
04901 && GET_CODE (XEXP (ad, 0)) == PLUS
04902 && GET_CODE (XEXP (XEXP (ad, 0), 1)) == REG
04903 && REGNO (XEXP (XEXP (ad, 0), 1)) < FIRST_PSEUDO_REGISTER
04904 && REG_MODE_OK_FOR_BASE_P (XEXP (XEXP (ad, 0), 1), mode)
04905 && ! maybe_memory_address_p (mode, ad, &XEXP (XEXP (ad, 0), 0)))
04906 {
04907 *loc = ad = gen_rtx_PLUS (GET_MODE (ad),
04908 XEXP (XEXP (ad, 0), 0),
04909 plus_constant (XEXP (XEXP (ad, 0), 1),
04910 INTVAL (XEXP (ad, 1))));
04911 find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1),
04912 MODE_BASE_REG_CLASS (mode),
04913 GET_MODE (ad), opnum, type, ind_levels);
04914 find_reloads_address_1 (mode, XEXP (ad, 0), 1, &XEXP (ad, 0), opnum,
04915 type, 0, insn);
04916
04917 return 0;
04918 }
04919
04920
04921
04922
04923 tem = ad;
04924 if (GET_CODE (ad) == PLUS)
04925 tem = subst_indexed_address (ad);
04926 if (tem != ad && strict_memory_address_p (mode, tem))
04927 {
04928
04929
04930
04931 subst_reg_equivs_changed = 0;
04932 tem = subst_reg_equivs (tem, insn);
04933
04934
04935
04936 if (! subst_reg_equivs_changed || strict_memory_address_p (mode, tem))
04937 {
04938 *loc = tem;
04939 return 0;
04940 }
04941 }
04942
04943
04944
04945 if (CONSTANT_P (ad) && ! strict_memory_address_p (mode, ad))
04946 {
04947
04948
04949 if (memrefloc && GET_CODE (ad) == SYMBOL_REF
04950 && CONSTANT_POOL_ADDRESS_P (ad))
04951 {
04952 *memrefloc = copy_rtx (*memrefloc);
04953 loc = &XEXP (*memrefloc, 0);
04954 if (removed_and)
04955 loc = &XEXP (*loc, 0);
04956 }
04957
04958 find_reloads_address_part (ad, loc, MODE_BASE_REG_CLASS (mode),
04959 Pmode, opnum, type, ind_levels);
04960 return ! removed_and;
04961 }
04962
04963 return find_reloads_address_1 (mode, ad, 0, loc, opnum, type, ind_levels,
04964 insn);
04965 }
04966
04967
04968
04969
04970
04971
04972
04973 static rtx
04974 subst_reg_equivs (ad, insn)
04975 rtx ad;
04976 rtx insn;
04977 {
04978 RTX_CODE code = GET_CODE (ad);
04979 int i;
04980 const char *fmt;
04981
04982 switch (code)
04983 {
04984 case HIGH:
04985 case CONST_INT:
04986 case CONST:
04987 case CONST_DOUBLE:
04988 case CONST_VECTOR:
04989 case SYMBOL_REF:
04990 case LABEL_REF:
04991 case PC:
04992 case CC0:
04993 return ad;
04994
04995 case REG:
04996 {
04997 int regno = REGNO (ad);
04998
04999 if (reg_equiv_constant[regno] != 0)
05000 {
05001 subst_reg_equivs_changed = 1;
05002 return reg_equiv_constant[regno];
05003 }
05004 if (reg_equiv_memory_loc[regno] && num_not_at_initial_offset)
05005 {
05006 rtx mem = make_memloc (ad, regno);
05007 if (! rtx_equal_p (mem, reg_equiv_mem[regno]))
05008 {
05009 subst_reg_equivs_changed = 1;
05010
05011
05012
05013 PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode, ad), insn),
05014 QImode);
05015 return mem;
05016 }
05017 }
05018 }
05019 return ad;
05020
05021 case PLUS:
05022
05023 if (XEXP (ad, 0) == frame_pointer_rtx
05024 && GET_CODE (XEXP (ad, 1)) == CONST_INT)
05025 return ad;
05026 break;
05027
05028 default:
05029 break;
05030 }
05031
05032 fmt = GET_RTX_FORMAT (code);
05033 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
05034 if (fmt[i] == 'e')
05035 XEXP (ad, i) = subst_reg_equivs (XEXP (ad, i), insn);
05036 return ad;
05037 }
05038
05039
05040
05041
05042
05043
05044
05045
05046 rtx
05047 form_sum (x, y)
05048 rtx x, y;
05049 {
05050 rtx tem;
05051 enum machine_mode mode = GET_MODE (x);
05052
05053 if (mode == VOIDmode)
05054 mode = GET_MODE (y);
05055
05056 if (mode == VOIDmode)
05057 mode = Pmode;
05058
05059 if (GET_CODE (x) == CONST_INT)
05060 return plus_constant (y, INTVAL (x));
05061 else if (GET_CODE (y) == CONST_INT)
05062 return plus_constant (x, INTVAL (y));
05063 else if (CONSTANT_P (x))
05064 tem = x, x = y, y = tem;
05065
05066 if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1)))
05067 return form_sum (XEXP (x, 0), form_sum (XEXP (x, 1), y));
05068
05069
05070
05071 if (GET_CODE (y) == PLUS && CONSTANT_P (XEXP (y, 1)))
05072 return form_sum (form_sum (x, XEXP (y, 0)), XEXP (y, 1));
05073
05074
05075
05076 if (CONSTANT_P (x) && CONSTANT_P (y))
05077 {
05078 if (GET_CODE (x) == CONST)
05079 x = XEXP (x, 0);
05080 if (GET_CODE (y) == CONST)
05081 y = XEXP (y, 0);
05082
05083 return gen_rtx_CONST (VOIDmode, gen_rtx_PLUS (mode, x, y));
05084 }
05085
05086 return gen_rtx_PLUS (mode, x, y);
05087 }
05088
05089
05090
05091
05092
05093
05094
05095
05096
05097
05098
05099
05100
05101 static rtx
05102 subst_indexed_address (addr)
05103 rtx addr;
05104 {
05105 rtx op0 = 0, op1 = 0, op2 = 0;
05106 rtx tem;
05107 int regno;
05108
05109 if (GET_CODE (addr) == PLUS)
05110 {
05111
05112 op0 = XEXP (addr, 0), op1 = XEXP (addr, 1), op2 = 0;
05113 if (GET_CODE (op0) == REG
05114 && (regno = REGNO (op0)) >= FIRST_PSEUDO_REGISTER
05115 && reg_renumber[regno] < 0
05116 && reg_equiv_constant[regno] != 0)
05117 op0 = reg_equiv_constant[regno];
05118 else if (GET_CODE (op1) == REG
05119 && (regno = REGNO (op1)) >= FIRST_PSEUDO_REGISTER
05120 && reg_renumber[regno] < 0
05121 && reg_equiv_constant[regno] != 0)
05122 op1 = reg_equiv_constant[regno];
05123 else if (GET_CODE (op0) == PLUS
05124 && (tem = subst_indexed_address (op0)) != op0)
05125 op0 = tem;
05126 else if (GET_CODE (op1) == PLUS
05127 && (tem = subst_indexed_address (op1)) != op1)
05128 op1 = tem;
05129 else
05130 return addr;
05131
05132
05133 if (GET_CODE (op1) == PLUS)
05134 op2 = XEXP (op1, 1), op1 = XEXP (op1, 0);
05135 else if (GET_CODE (op0) == PLUS)
05136 op2 = op1, op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);
05137
05138
05139 if (op2 != 0)
05140 op1 = form_sum (op1, op2);
05141 if (op1 != 0)
05142 op0 = form_sum (op0, op1);
05143
05144 return op0;
05145 }
05146 return addr;
05147 }
05148
05149
05150
05151
05152
05153
05154
05155
05156
05157
05158
05159 static void
05160 update_auto_inc_notes (insn, regno, reloadnum)
05161 rtx insn ATTRIBUTE_UNUSED;
05162 int regno ATTRIBUTE_UNUSED;
05163 int reloadnum ATTRIBUTE_UNUSED;
05164 {
05165 #ifdef AUTO_INC_DEC
05166 rtx link;
05167
05168 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
05169 if (REG_NOTE_KIND (link) == REG_INC
05170 && REGNO (XEXP (link, 0)) == regno)
05171 push_replacement (&XEXP (link, 0), reloadnum, VOIDmode);
05172 #endif
05173 }
05174
05175
05176
05177
05178
05179
05180
05181
05182
05183
05184
05185
05186
05187
05188
05189
05190
05191
05192
05193
05194
05195
05196
05197
05198
05199 static int
05200 find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
05201 enum machine_mode mode;
05202 rtx x;
05203 int context;
05204 rtx *loc;
05205 int opnum;
05206 enum reload_type type;
05207 int ind_levels;
05208 rtx insn;
05209 {
05210 RTX_CODE code = GET_CODE (x);
05211
05212 switch (code)
05213 {
05214 case PLUS:
05215 {
05216 rtx orig_op0 = XEXP (x, 0);
05217 rtx orig_op1 = XEXP (x, 1);
05218 RTX_CODE code0 = GET_CODE (orig_op0);
05219 RTX_CODE code1 = GET_CODE (orig_op1);
05220 rtx op0 = orig_op0;
05221 rtx op1 = orig_op1;
05222
05223 if (GET_CODE (op0) == SUBREG)
05224 {
05225 op0 = SUBREG_REG (op0);
05226 code0 = GET_CODE (op0);
05227 if (code0 == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER)
05228 op0 = gen_rtx_REG (word_mode,
05229 (REGNO (op0) +
05230 subreg_regno_offset (REGNO (SUBREG_REG (orig_op0)),
05231 GET_MODE (SUBREG_REG (orig_op0)),
05232 SUBREG_BYTE (orig_op0),
05233 GET_MODE (orig_op0))));
05234 }
05235
05236 if (GET_CODE (op1) == SUBREG)
05237 {
05238 op1 = SUBREG_REG (op1);
05239 code1 = GET_CODE (op1);
05240 if (code1 == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER)
05241
05242
05243 op1 = gen_rtx_REG (GET_MODE (op1),
05244 (REGNO (op1) +
05245 subreg_regno_offset (REGNO (SUBREG_REG (orig_op1)),
05246 GET_MODE (SUBREG_REG (orig_op1)),
05247 SUBREG_BYTE (orig_op1),
05248 GET_MODE (orig_op1))));
05249 }
05250
05251
05252
05253
05254 if (context)
05255 {
05256 find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
05257 opnum, ADDR_TYPE (type), ind_levels, insn);
05258 push_reload (*loc, NULL_RTX, loc, (rtx*) 0,
05259 (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
05260 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
05261 return 1;
05262 }
05263
05264 if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
05265 || code0 == ZERO_EXTEND || code1 == MEM)
05266 {
05267 find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
05268 type, ind_levels, insn);
05269 find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
05270 type, ind_levels, insn);
05271 }
05272
05273 else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
05274 || code1 == ZERO_EXTEND || code0 == MEM)
05275 {
05276 find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
05277 type, ind_levels, insn);
05278 find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
05279 type, ind_levels, insn);
05280 }
05281
05282 else if (code0 == CONST_INT || code0 == CONST
05283 || code0 == SYMBOL_REF || code0 == LABEL_REF)
05284 find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
05285 type, ind_levels, insn);
05286
05287 else if (code1 == CONST_INT || code1 == CONST
05288 || code1 == SYMBOL_REF || code1 == LABEL_REF)
05289 find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
05290 type, ind_levels, insn);
05291
05292 else if (code0 == REG && code1 == REG)
05293 {
05294 if (REG_OK_FOR_INDEX_P (op0)
05295 && REG_MODE_OK_FOR_BASE_P (op1, mode))
05296 return 0;
05297 else if (REG_OK_FOR_INDEX_P (op1)
05298 && REG_MODE_OK_FOR_BASE_P (op0, mode))
05299 return 0;
05300 else if (REG_MODE_OK_FOR_BASE_P (op1, mode))
05301 find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
05302 type, ind_levels, insn);
05303 else if (REG_MODE_OK_FOR_BASE_P (op0, mode))
05304 find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
05305 type, ind_levels, insn);
05306 else if (REG_OK_FOR_INDEX_P (op1))
05307 find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
05308 type, ind_levels, insn);
05309 else if (REG_OK_FOR_INDEX_P (op0))
05310 find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
05311 type, ind_levels, insn);
05312 else
05313 {
05314 find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
05315 type, ind_levels, insn);
05316 find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
05317 type, ind_levels, insn);
05318 }
05319 }
05320
05321 else if (code0 == REG)
05322 {
05323 find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
05324 type, ind_levels, insn);
05325 find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
05326 type, ind_levels, insn);
05327 }
05328
05329 else if (code1 == REG)
05330 {
05331 find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
05332 type, ind_levels, insn);
05333 find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
05334 type, ind_levels, insn);
05335 }
05336 }
05337
05338 return 0;
05339
05340 case POST_MODIFY:
05341 case PRE_MODIFY:
05342 {
05343 rtx op0 = XEXP (x, 0);
05344 rtx op1 = XEXP (x, 1);
05345
05346 if (GET_CODE (op1) != PLUS && GET_CODE (op1) != MINUS)
05347 return 0;
05348
05349
05350
05351
05352
05353 if (op0 != XEXP (op1, 0))
05354 abort ();
05355
05356
05357
05358
05359
05360 if (REG_P (XEXP (op1, 1)))
05361 if (!REGNO_OK_FOR_INDEX_P (REGNO (XEXP (op1, 1))))
05362 find_reloads_address_1 (mode, XEXP (op1, 1), 1, &XEXP (op1, 1),
05363 opnum, type, ind_levels, insn);
05364
05365 if (REG_P (XEXP (op1, 0)))
05366 {
05367 int regno = REGNO (XEXP (op1, 0));
05368 int reloadnum;
05369
05370
05371 if (regno >= FIRST_PSEUDO_REGISTER
05372 && reg_equiv_constant[regno] != 0)
05373 abort ();
05374
05375
05376
05377 if (reg_equiv_memory_loc[regno] != 0
05378 && (reg_equiv_address[regno] != 0
05379 || num_not_at_initial_offset))
05380 {
05381 rtx tem = make_memloc (XEXP (x, 0), regno);
05382
05383 if (reg_equiv_address[regno]
05384 || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
05385 {
05386
05387
05388
05389
05390 find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
05391 &XEXP (tem, 0), opnum,
05392 RELOAD_OTHER,
05393 ind_levels, insn);
05394
05395
05396
05397 reloadnum = push_reload (tem, tem, &XEXP (x, 0),
05398 &XEXP (op1, 0),
05399 MODE_BASE_REG_CLASS (mode),
05400 GET_MODE (x), GET_MODE (x), 0,
05401 0, opnum, RELOAD_OTHER);
05402
05403 update_auto_inc_notes (this_insn, regno, reloadnum);
05404 return 0;
05405 }
05406 }
05407
05408 if (reg_renumber[regno] >= 0)
05409 regno = reg_renumber[regno];
05410
05411
05412 if (!REGNO_MODE_OK_FOR_BASE_P (regno, GET_MODE (x)))
05413 {
05414 reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
05415 &XEXP (op1, 0), &XEXP (x, 0),
05416 MODE_BASE_REG_CLASS (mode),
05417 GET_MODE (x), GET_MODE (x), 0, 0,
05418 opnum, RELOAD_OTHER);
05419
05420 update_auto_inc_notes (this_insn, regno, reloadnum);
05421 return 0;
05422 }
05423 }
05424 else
05425 abort ();
05426 }
05427 return 0;
05428
05429 case POST_INC:
05430 case POST_DEC:
05431 case PRE_INC:
05432 case PRE_DEC:
05433 if (GET_CODE (XEXP (x, 0)) == REG)
05434 {
05435 int regno = REGNO (XEXP (x, 0));
05436 int value = 0;
05437 rtx x_orig = x;
05438
05439
05440 if (regno >= FIRST_PSEUDO_REGISTER
05441 && reg_equiv_constant[regno] != 0)
05442 abort ();
05443
05444
05445
05446 if (reg_equiv_memory_loc[regno] != 0
05447 && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
05448 {
05449 rtx tem = make_memloc (XEXP (x, 0), regno);
05450 if (reg_equiv_address[regno]
05451 || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
05452 {
05453
05454
05455
05456
05457 find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
05458 &XEXP (tem, 0), opnum, type,
05459 ind_levels, insn);
05460
05461 x = gen_rtx_fmt_e (GET_CODE (x), GET_MODE (x), tem);
05462
05463 }
05464 }
05465
05466
05467
05468
05469
05470
05471
05472
05473
05474
05475
05476
05477 if (reg_renumber[regno] >= 0)
05478 regno = reg_renumber[regno];
05479 if ((regno >= FIRST_PSEUDO_REGISTER
05480 || !(context ? REGNO_OK_FOR_INDEX_P (regno)
05481 : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
05482 {
05483 int reloadnum;
05484
05485
05486
05487
05488
05489
05490
05491
05492
05493 rtx equiv = (GET_CODE (XEXP (x, 0)) == MEM
05494 ? XEXP (x, 0)
05495 : reg_equiv_mem[regno]);
05496 int icode = (int) add_optab->handlers[(int) Pmode].insn_code;
05497 if (insn && GET_CODE (insn) == INSN && equiv
05498 && memory_operand (equiv, GET_MODE (equiv))
05499 #ifdef HAVE_cc0
05500 && ! sets_cc0_p (PATTERN (insn))
05501 #endif
05502 && ! (icode != CODE_FOR_nothing
05503 && ((*insn_data[icode].operand[0].predicate)
05504 (equiv, Pmode))
05505 && ((*insn_data[icode].operand[1].predicate)
05506 (equiv, Pmode))))
05507 {
05508
05509
05510
05511
05512
05513 loc = &XEXP (x_orig, 0);
05514 x = XEXP (x, 0);
05515 reloadnum
05516 = push_reload (x, x, loc, loc,
05517 (context ? INDEX_REG_CLASS :
05518 MODE_BASE_REG_CLASS (mode)),
05519 GET_MODE (x), GET_MODE (x), 0, 0,
05520 opnum, RELOAD_OTHER);
05521 }
05522 else
05523 {
05524 reloadnum
05525 = push_reload (x, NULL_RTX, loc, (rtx*) 0,
05526 (context ? INDEX_REG_CLASS :
05527 MODE_BASE_REG_CLASS (mode)),
05528 GET_MODE (x), GET_MODE (x), 0, 0,
05529 opnum, type);
05530 rld[reloadnum].inc
05531 = find_inc_amount (PATTERN (this_insn), XEXP (x_orig, 0));
05532
05533 value = 1;
05534 }
05535
05536 update_auto_inc_notes (this_insn, REGNO (XEXP (x_orig, 0)),
05537 reloadnum);
05538 }
05539 return value;
05540 }
05541
05542 else if (GET_CODE (XEXP (x, 0)) == MEM)
05543 {
05544
05545
05546
05547
05548
05549 rtx tem ATTRIBUTE_UNUSED = XEXP (x, 0);
05550 rtx link;
05551 int reloadnum;
05552
05553
05554
05555
05556
05557
05558
05559
05560
05561
05562 find_reloads_address (GET_MODE (x), &XEXP (x, 0),
05563 XEXP (XEXP (x, 0), 0), &XEXP (XEXP (x, 0), 0),
05564 opnum, type, ind_levels, insn);
05565
05566 reloadnum = push_reload (x, NULL_RTX, loc, (rtx*) 0,
05567 (context ? INDEX_REG_CLASS :
05568 MODE_BASE_REG_CLASS (mode)),
05569 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
05570 rld[reloadnum].inc
05571 = find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
05572
05573 link = FIND_REG_INC_NOTE (this_insn, tem);
05574 if (link != 0)
05575 push_replacement (&XEXP (link, 0), reloadnum, VOIDmode);
05576
05577 return 1;
05578 }
05579 return 0;
05580
05581 case MEM:
05582
05583
05584
05585
05586
05587
05588
05589
05590
05591
05592
05593
05594 find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
05595 opnum, ADDR_TYPE (type), ind_levels, insn);
05596 push_reload (*loc, NULL_RTX, loc, (rtx*) 0,
05597 (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
05598 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
05599 return 1;
05600
05601 case REG:
05602 {
05603 int regno = REGNO (x);
05604
05605 if (reg_equiv_constant[regno] != 0)
05606 {
05607 find_reloads_address_part (reg_equiv_constant[regno], loc,
05608 (context ? INDEX_REG_CLASS :
05609 MODE_BASE_REG_CLASS (mode)),
05610 GET_MODE (x), opnum, type, ind_levels);
05611 return 1;
05612 }
05613
05614 #if 0
05615
05616 if (reg_equiv_mem[regno] != 0)
05617 {
05618 push_reload (reg_equiv_mem[regno], NULL_RTX, loc, (rtx*) 0,
05619 (context ? INDEX_REG_CLASS :
05620 MODE_BASE_REG_CLASS (mode)),
05621 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
05622 return 1;
05623 }
05624 #endif
05625
05626 if (reg_equiv_memory_loc[regno]
05627 && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
05628 {
05629 rtx tem = make_memloc (x, regno);
05630 if (reg_equiv_address[regno] != 0
05631 || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
05632 {
05633 x = tem;
05634 find_reloads_address (GET_MODE (x), &x, XEXP (x, 0),
05635 &XEXP (x, 0), opnum, ADDR_TYPE (type),
05636 ind_levels, insn);
05637 }
05638 }
05639
05640 if (reg_renumber[regno] >= 0)
05641 regno = reg_renumber[regno];
05642
05643 if ((regno >= FIRST_PSEUDO_REGISTER
05644 || !(context ? REGNO_OK_FOR_INDEX_P (regno)
05645 : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
05646 {
05647 push_reload (x, NULL_RTX, loc, (rtx*) 0,
05648 (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
05649 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
05650 return 1;
05651 }
05652
05653
05654
05655
05656
05657 if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0))
05658 {
05659 push_reload (x, NULL_RTX, loc, (rtx*) 0,
05660 (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
05661 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
05662 return 1;
05663 }
05664 }
05665 return 0;
05666
05667 case SUBREG:
05668 if (GET_CODE (SUBREG_REG (x)) == REG)
05669 {
05670
05671
05672
05673 if (REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
05674 {
05675 int regno = subreg_regno (x);
05676
05677 if (! (context ? REGNO_OK_FOR_INDEX_P (regno)
05678 : REGNO_MODE_OK_FOR_BASE_P (regno, mode)))
05679 {
05680 push_reload (x, NULL_RTX, loc, (rtx*) 0,
05681 (context ? INDEX_REG_CLASS :
05682 MODE_BASE_REG_CLASS (mode)),
05683 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
05684 return 1;
05685 }
05686 }
05687
05688
05689 else
05690 {
05691 enum reg_class class = (context ? INDEX_REG_CLASS
05692 : MODE_BASE_REG_CLASS (mode));
05693 if ((unsigned) CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
05694 > reg_class_size[class])
05695 {
05696 x = find_reloads_subreg_address (x, 0, opnum, type,
05697 ind_levels, insn);
05698 push_reload (x, NULL_RTX, loc, (rtx*) 0, class,
05699 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
05700 return 1;
05701 }
05702 }
05703 }
05704 break;
05705
05706 default:
05707 break;
05708 }
05709
05710 {
05711 const char *fmt = GET_RTX_FORMAT (code);
05712 int i;
05713
05714 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
05715 {
05716 if (fmt[i] == 'e')
05717 find_reloads_address_1 (mode, XEXP (x, i), context, &XEXP (x, i),
05718 opnum, type, ind_levels, insn);
05719 }
05720 }
05721
05722 return 0;
05723 }
05724
05725
05726
05727
05728
05729
05730
05731
05732
05733
05734
05735
05736
05737
05738
05739
05740 static void
05741 find_reloads_address_part (x, loc, class, mode, opnum, type, ind_levels)
05742 rtx x;
05743 rtx *loc;
05744 enum reg_class class;
05745 enum machine_mode mode;
05746 int opnum;
05747 enum reload_type type;
05748 int ind_levels;
05749 {
05750 if (CONSTANT_P (x)
05751 && (! LEGITIMATE_CONSTANT_P (x)
05752 || PREFERRED_RELOAD_CLASS (x, class) == NO_REGS))
05753 {
05754 rtx tem;
05755
05756 tem = x = force_const_mem (mode, x);
05757 find_reloads_address (mode, &tem, XEXP (tem, 0), &XEXP (tem, 0),
05758 opnum, type, ind_levels, 0);
05759 }
05760
05761 else if (GET_CODE (x) == PLUS
05762 && CONSTANT_P (XEXP (x, 1))
05763 && (! LEGITIMATE_CONSTANT_P (XEXP (x, 1))
05764 || PREFERRED_RELOAD_CLASS (XEXP (x, 1), class) == NO_REGS))
05765 {
05766 rtx tem;
05767
05768 tem = force_const_mem (GET_MODE (x), XEXP (x, 1));
05769 x = gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), tem);
05770 find_reloads_address (mode, &tem, XEXP (tem, 0), &XEXP (tem, 0),
05771 opnum, type, ind_levels, 0);
05772 }
05773
05774 push_reload (x, NULL_RTX, loc, (rtx*) 0, class,
05775 mode, VOIDmode, 0, 0, opnum, type);
05776 }
05777
05778
05779
05780
05781
05782
05783
05784
05785
05786
05787
05788
05789
05790
05791
05792
05793
05794
05795
05796
05797
05798
05799
05800 static rtx
05801 find_reloads_subreg_address (x, force_replace, opnum, type,
05802 ind_levels, insn)
05803 rtx x;
05804 int force_replace;
05805 int opnum;
05806 enum reload_type type;
05807 int ind_levels;
05808 rtx insn;
05809 {
05810 int regno = REGNO (SUBREG_REG (x));
05811
05812 if (reg_equiv_memory_loc[regno])
05813 {
05814
05815
05816 if (! force_replace
05817 && (reg_equiv_address[regno]
05818 || ! offsettable_memref_p (reg_equiv_mem[regno])))
05819 force_replace = 1;
05820
05821 if (force_replace || num_not_at_initial_offset)
05822 {
05823 rtx tem = make_memloc (SUBREG_REG (x), regno);
05824
05825
05826
05827 if (force_replace
05828 || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
05829 {
05830 int offset = SUBREG_BYTE (x);
05831 unsigned outer_size = GET_MODE_SIZE (GET_MODE (x));
05832 unsigned inner_size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
05833
05834 XEXP (tem, 0) = plus_constant (XEXP (tem, 0), offset);
05835 PUT_MODE (tem, GET_MODE (x));
05836
05837
05838
05839
05840 if (outer_size > inner_size && STRICT_ALIGNMENT)
05841 {
05842 rtx base;
05843
05844 base = XEXP (tem, 0);
05845 if (GET_CODE (base) == PLUS)
05846 {
05847 if (GET_CODE (XEXP (base, 1)) == CONST_INT
05848 && INTVAL (XEXP (base, 1)) % outer_size != 0)
05849 return x;
05850 base = XEXP (base, 0);
05851 }
05852 if (GET_CODE (base) != REG
05853 || (REGNO_POINTER_ALIGN (REGNO (base))
05854 < outer_size * BITS_PER_UNIT))
05855 return x;
05856 }
05857
05858 find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
05859 &XEXP (tem, 0), opnum, ADDR_TYPE (type),
05860 ind_levels, insn);
05861
05862
05863
05864
05865 if (replace_reloads && recog_data.operand[opnum] != x)
05866
05867
05868
05869 PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode,
05870 SUBREG_REG (x)),
05871 insn), QImode);
05872 x = tem;
05873 }
05874 }
05875 }
05876 return x;
05877 }
05878
05879
05880
05881
05882
05883
05884
05885
05886 void
05887 subst_reloads (insn)
05888 rtx insn;
05889 {
05890 int i;
05891
05892 for (i = 0; i < n_replacements; i++)
05893 {
05894 struct replacement *r = &replacements[i];
05895 rtx reloadreg = rld[r->what].reg_rtx;
05896 if (reloadreg)
05897 {
05898 #ifdef ENABLE_CHECKING
05899
05900
05901
05902
05903
05904
05905
05906 int check_regno;
05907
05908 for (check_regno = 0; check_regno < max_regno; check_regno++)
05909 {
05910 #define CHECK_MODF(ARRAY) \
05911 if (ARRAY[check_regno] \
05912 && loc_mentioned_in_p (r->where, \
05913 ARRAY[check_regno])) \
05914 abort ()
05915
05916 CHECK_MODF (reg_equiv_constant);
05917 CHECK_MODF (reg_equiv_memory_loc);
05918 CHECK_MODF (reg_equiv_address);
05919 CHECK_MODF (reg_equiv_mem);
05920 #undef CHECK_MODF
05921 }
05922 #endif
05923
05924
05925
05926
05927 if (GET_CODE (*r->where) == LABEL_REF
05928 && GET_CODE (insn) == JUMP_INSN)
05929 REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL,
05930 XEXP (*r->where, 0),
05931 REG_NOTES (insn));
05932
05933
05934
05935
05936
05937 if (GET_MODE (reloadreg) != r->mode && r->mode != VOIDmode)
05938 reloadreg = gen_rtx_REG (r->mode, REGNO (reloadreg));
05939
05940
05941
05942
05943
05944 if (r->subreg_loc != 0 && GET_CODE (reloadreg) == SUBREG)
05945 {
05946 if (GET_MODE (*r->subreg_loc)
05947 == GET_MODE (SUBREG_REG (reloadreg)))
05948 *r->subreg_loc = SUBREG_REG (reloadreg);
05949 else
05950 {
05951 int final_offset =
05952 SUBREG_BYTE (*r->subreg_loc) + SUBREG_BYTE (reloadreg);
05953
05954
05955
05956 final_offset = (final_offset /
05957 GET_MODE_SIZE (GET_MODE (*r->subreg_loc)));
05958 final_offset = (final_offset *
05959 GET_MODE_SIZE (GET_MODE (*r->subreg_loc)));
05960
05961 *r->where = SUBREG_REG (reloadreg);
05962 SUBREG_BYTE (*r->subreg_loc) = final_offset;
05963 }
05964 }
05965 else
05966 *r->where = reloadreg;
05967 }
05968
05969 else if (! rld[r->what].optional)
05970 abort ();
05971 }
05972 }
05973
05974
05975
05976
05977 void
05978 copy_replacements (x, y)
05979 rtx x, y;
05980 {
05981
05982
05983 if (GET_CODE (x) == SUBREG)
05984 abort ();
05985
05986 copy_replacements_1 (&x, &y, n_replacements);
05987 }
05988
05989 static void
05990 copy_replacements_1 (px, py, orig_replacements)
05991 rtx *px;
05992 rtx *py;
05993 int orig_replacements;
05994 {
05995 int i, j;
05996 rtx x, y;
05997 struct replacement *r;
05998 enum rtx_code code;
05999 const char *fmt;
06000
06001 for (j = 0; j < orig_replacements; j++)
06002 {
06003 if (replacements[j].subreg_loc == px)
06004 {
06005 r = &replacements[n_replacements++];
06006 r->where = replacements[j].where;
06007 r->subreg_loc = py;
06008 r->what = replacements[j].what;
06009 r->mode = replacements[j].mode;
06010 }
06011 else if (replacements[j].where == px)
06012 {
06013 r = &replacements[n_replacements++];
06014 r->where = py;
06015 r->subreg_loc = 0;
06016 r->what = replacements[j].what;
06017 r->mode = replacements[j].mode;
06018 }
06019 }
06020
06021 x = *px;
06022 y = *py;
06023 code = GET_CODE (x);
06024 fmt = GET_RTX_FORMAT (code);
06025
06026 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
06027 {
06028 if (fmt[i] == 'e')
06029 copy_replacements_1 (&XEXP (x, i), &XEXP (y, i), orig_replacements);
06030 else if (fmt[i] == 'E')
06031 for (j = XVECLEN (x, i); --j >= 0; )
06032 copy_replacements_1 (&XVECEXP (x, i, j), &XVECEXP (y, i, j),
06033 orig_replacements);
06034 }
06035 }
06036
06037
06038
06039 void
06040 move_replacements (x, y)
06041 rtx *x;
06042 rtx *y;
06043 {
06044 int i;
06045
06046 for (i = 0; i < n_replacements; i++)
06047 if (replacements[i].subreg_loc == x)
06048 replacements[i].subreg_loc = y;
06049 else if (replacements[i].where == x)
06050 {
06051 replacements[i].where = y;
06052 replacements[i].subreg_loc = 0;
06053 }
06054 }
06055
06056
06057
06058
06059 rtx
06060 find_replacement (loc)
06061 rtx *loc;
06062 {
06063 struct replacement *r;
06064
06065 for (r = &replacements[0]; r < &replacements[n_replacements]; r++)
06066 {
06067 rtx reloadreg = rld[r->what].reg_rtx;
06068
06069 if (reloadreg && r->where == loc)
06070 {
06071 if (r->mode != VOIDmode && GET_MODE (reloadreg) != r->mode)
06072 reloadreg = gen_rtx_REG (r->mode, REGNO (reloadreg));
06073
06074 return reloadreg;
06075 }
06076 else if (reloadreg && r->subreg_loc == loc)
06077 {
06078
06079
06080
06081
06082 if (GET_CODE (reloadreg) == REG)
06083 return gen_rtx_REG (GET_MODE (*loc),
06084 (REGNO (reloadreg) +
06085 subreg_regno_offset (REGNO (SUBREG_REG (*loc)),
06086 GET_MODE (SUBREG_REG (*loc)),
06087 SUBREG_BYTE (*loc),
06088 GET_MODE (*loc))));
06089 else if (GET_MODE (reloadreg) == GET_MODE (*loc))
06090 return reloadreg;
06091 else
06092 {
06093 int final_offset = SUBREG_BYTE (reloadreg) + SUBREG_BYTE (*loc);
06094
06095
06096
06097 final_offset = (final_offset / GET_MODE_SIZE (GET_MODE (*loc)));
06098 final_offset = (final_offset * GET_MODE_SIZE (GET_MODE (*loc)));
06099 return gen_rtx_SUBREG (GET_MODE (*loc), SUBREG_REG (reloadreg),
06100 final_offset);
06101 }
06102 }
06103 }
06104
06105
06106
06107 if (GET_CODE (*loc) == PLUS || GET_CODE (*loc) == MINUS
06108 || GET_CODE (*loc) == MULT)
06109 {
06110 rtx x = find_replacement (&XEXP (*loc, 0));
06111 rtx y = find_replacement (&XEXP (*loc, 1));
06112
06113 if (x != XEXP (*loc, 0) || y != XEXP (*loc, 1))
06114 return gen_rtx_fmt_ee (GET_CODE (*loc), GET_MODE (*loc), x, y);
06115 }
06116
06117 return *loc;
06118 }
06119
06120
06121
06122
06123
06124
06125
06126
06127
06128
06129
06130 int
06131 refers_to_regno_for_reload_p (regno, endregno, x, loc)
06132 unsigned int regno, endregno;
06133 rtx x;
06134 rtx *loc;
06135 {
06136 int i;
06137 unsigned int r;
06138 RTX_CODE code;
06139 const char *fmt;
06140
06141 if (x == 0)
06142 return 0;
06143
06144 repeat:
06145 code = GET_CODE (x);
06146
06147 switch (code)
06148 {
06149 case REG:
06150 r = REGNO (x);
06151
06152
06153
06154 if (r >= FIRST_PSEUDO_REGISTER)
06155 {
06156 if (reg_equiv_memory_loc[r])
06157 return refers_to_regno_for_reload_p (regno, endregno,
06158 reg_equiv_memory_loc[r],
06159 (rtx*) 0);
06160
06161 if (reg_equiv_constant[r])
06162 return 0;
06163
06164 abort ();
06165 }
06166
06167 return (endregno > r
06168 && regno < r + (r < FIRST_PSEUDO_REGISTER
06169 ? HARD_REGNO_NREGS (r, GET_MODE (x))
06170 : 1));
06171
06172 case SUBREG:
06173
06174
06175 if (GET_CODE (SUBREG_REG (x)) == REG
06176 && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
06177 {
06178 unsigned int inner_regno = subreg_regno (x);
06179 unsigned int inner_endregno
06180 = inner_regno + (inner_regno < FIRST_PSEUDO_REGISTER
06181 ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
06182
06183 return endregno > inner_regno && regno < inner_endregno;
06184 }
06185 break;
06186
06187 case CLOBBER:
06188 case SET:
06189 if (&SET_DEST (x) != loc
06190
06191
06192
06193 && ((GET_CODE (SET_DEST (x)) == SUBREG
06194 && loc != &SUBREG_REG (SET_DEST (x))
06195 && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
06196 && REGNO (SUBREG_REG (SET_DEST (x))) >= FIRST_PSEUDO_REGISTER
06197 && refers_to_regno_for_reload_p (regno, endregno,
06198 SUBREG_REG (SET_DEST (x)),
06199 loc))
06200
06201
06202 || ((GET_CODE (SET_DEST (x)) != REG
06203 || earlyclobber_operand_p (SET_DEST (x)))
06204 && refers_to_regno_for_reload_p (regno, endregno,
06205 SET_DEST (x), loc))))
06206 return 1;
06207
06208 if (code == CLOBBER || loc == &SET_SRC (x))
06209 return 0;
06210 x = SET_SRC (x);
06211 goto repeat;
06212
06213 default:
06214 break;
06215 }
06216
06217
06218
06219 fmt = GET_RTX_FORMAT (code);
06220 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
06221 {
06222 if (fmt[i] == 'e' && loc != &XEXP (x, i))
06223 {
06224 if (i == 0)
06225 {
06226 x = XEXP (x, 0);
06227 goto repeat;
06228 }
06229 else
06230 if (refers_to_regno_for_reload_p (regno, endregno,
06231 XEXP (x, i), loc))
06232 return 1;
06233 }
06234 else if (fmt[i] == 'E')
06235 {
06236 int j;
06237 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
06238 if (loc != &XVECEXP (x, i, j)
06239 && refers_to_regno_for_reload_p (regno, endregno,
06240 XVECEXP (x, i, j), loc))
06241 return 1;
06242 }
06243 }
06244 return 0;
06245 }
06246
06247
06248
06249
06250
06251
06252
06253
06254
06255
06256 int
06257 reg_overlap_mentioned_for_reload_p (x, in)
06258 rtx x, in;
06259 {
06260 int regno, endregno;
06261
06262
06263 if (GET_CODE (x) == STRICT_LOW_PART
06264 || GET_RTX_CLASS (GET_CODE (x)) == 'a')
06265 x = XEXP (x, 0);
06266
06267
06268 if (CONSTANT_P (x) || CONSTANT_P (in))
06269 return 0;
06270 else if (GET_CODE (x) == SUBREG)
06271 {
06272 regno = REGNO (SUBREG_REG (x));
06273 if (regno < FIRST_PSEUDO_REGISTER)
06274 regno += subreg_regno_offset (REGNO (SUBREG_REG (x)),
06275 GET_MODE (SUBREG_REG (x)),
06276 SUBREG_BYTE (x),
06277 GET_MODE (x));
06278 }
06279 else if (GET_CODE (x) == REG)
06280 {
06281 regno = REGNO (x);
06282
06283
06284
06285
06286 if (regno >= FIRST_PSEUDO_REGISTER)
06287 {
06288 if (reg_equiv_memory_loc[regno])
06289 return refers_to_mem_for_reload_p (in);
06290 else if (reg_equiv_constant[regno])
06291 return 0;
06292 abort ();
06293 }
06294 }
06295 else if (GET_CODE (x) == MEM)
06296 return refers_to_mem_for_reload_p (in);
06297 else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
06298 || GET_CODE (x) == CC0)
06299 return reg_mentioned_p (x, in);
06300 else if (GET_CODE (x) == PLUS)
06301 return (reg_overlap_mentioned_for_reload_p (XEXP (x, 0), in)
06302 || reg_overlap_mentioned_for_reload_p (XEXP (x, 1), in));
06303 else
06304 abort ();
06305
06306 endregno = regno + (regno < FIRST_PSEUDO_REGISTER
06307 ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
06308
06309 return refers_to_regno_for_reload_p (regno, endregno, in, (rtx*) 0);
06310 }
06311
06312
06313
06314
06315 int
06316 refers_to_mem_for_reload_p (x)
06317 rtx x;
06318 {
06319 const char *fmt;
06320 int i;
06321
06322 if (GET_CODE (x) == MEM)
06323 return 1;
06324
06325 if (GET_CODE (x) == REG)
06326 return (REGNO (x) >= FIRST_PSEUDO_REGISTER
06327 && reg_equiv_memory_loc[REGNO (x)]);
06328
06329 fmt = GET_RTX_FORMAT (GET_CODE (x));
06330 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
06331 if (fmt[i] == 'e'
06332 && (GET_CODE (XEXP (x, i)) == MEM
06333 || refers_to_mem_for_reload_p (XEXP (x, i))))
06334 return 1;
06335
06336 return 0;
06337 }
06338
06339
06340
06341
06342
06343
06344
06345
06346
06347
06348
06349
06350
06351
06352
06353
06354
06355
06356
06357
06358
06359
06360
06361
06362
06363
06364
06365
06366 rtx
06367 find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
06368 rtx goal;
06369 rtx insn;
06370 enum reg_class class;
06371 int other;
06372 short *reload_reg_p;
06373 int goalreg;
06374 enum machine_mode mode;
06375 {
06376 rtx p = insn;
06377 rtx goaltry, valtry, value, where;
06378 rtx pat;
06379 int regno = -1;
06380 int valueno;
06381 int goal_mem = 0;
06382 int goal_const = 0;
06383 int goal_mem_addr_varies = 0;
06384 int need_stable_sp = 0;
06385 int nregs;
06386 int valuenregs;
06387
06388 if (goal == 0)
06389 regno = goalreg;
06390 else if (GET_CODE (goal) == REG)
06391 regno = REGNO (goal);
06392 else if (GET_CODE (goal) == MEM)
06393 {
06394 enum rtx_code code = GET_CODE (XEXP (goal, 0));
06395 if (MEM_VOLATILE_P (goal))
06396 return 0;
06397 if (flag_float_store && GET_MODE_CLASS (GET_MODE (goal)) == MODE_FLOAT)
06398 return 0;
06399
06400 switch (code)
06401 {
06402 case POST_INC:
06403 case PRE_INC:
06404 case POST_DEC:
06405 case PRE_DEC:
06406 case POST_MODIFY:
06407 case PRE_MODIFY:
06408 return 0;
06409 default:
06410 break;
06411 }
06412 goal_mem = 1;
06413 }
06414 else if (CONSTANT_P (goal))
06415 goal_const = 1;
06416 else if (GET_CODE (goal) == PLUS
06417 && XEXP (goal, 0) == stack_pointer_rtx
06418 && CONSTANT_P (XEXP (goal, 1)))
06419 goal_const = need_stable_sp = 1;
06420 else if (GET_CODE (goal) == PLUS
06421 && XEXP (goal, 0) == frame_pointer_rtx
06422 && CONSTANT_P (XEXP (goal, 1)))
06423 goal_const = 1;
06424 else
06425 return 0;
06426
06427
06428
06429
06430
06431 while (1)
06432 {
06433 p = PREV_INSN (p);
06434 if (p == 0 || GET_CODE (p) == CODE_LABEL)
06435 return 0;
06436
06437 if (GET_CODE (p) == INSN
06438
06439 && (! (reload_reg_p != 0
06440 && reload_reg_p != (short *) (HOST_WIDE_INT) 1)
06441
06442
06443
06444
06445
06446
06447
06448
06449 || INSN_UID (p) < reload_first_uid))
06450 {
06451 rtx tem;
06452 pat = single_set (p);
06453
06454
06455 if (pat != 0
06456 && ((regno >= 0
06457 && true_regnum (SET_SRC (pat)) == regno
06458 && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0)
06459 ||
06460 (regno >= 0
06461 && true_regnum (SET_DEST (pat)) == regno
06462 && (valueno = true_regnum (valtry = SET_SRC (pat))) >= 0)
06463 ||
06464 (goal_const && rtx_equal_p (SET_SRC (pat), goal)
06465
06466
06467 && !reg_overlap_mentioned_for_reload_p (SET_DEST (pat), goal)
06468 && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0)
06469 || (goal_mem
06470 && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0
06471 && rtx_renumbered_equal_p (goal, SET_SRC (pat)))
06472 || (goal_mem
06473 && (valueno = true_regnum (valtry = SET_SRC (pat))) >= 0
06474 && rtx_renumbered_equal_p (goal, SET_DEST (pat)))
06475
06476
06477
06478 || (goal_const && REG_NOTES (p) != 0
06479 && (tem = find_reg_note (p, REG_EQUIV, NULL_RTX))
06480 && ((rtx_equal_p (XEXP (tem, 0), goal)
06481 && (valueno
06482 = true_regnum (valtry = SET_DEST (pat))) >= 0)
06483 || (GET_CODE (SET_DEST (pat)) == REG
06484 && GET_CODE (XEXP (tem, 0)) == CONST_DOUBLE
06485 && (GET_MODE_CLASS (GET_MODE (XEXP (tem, 0)))
06486 == MODE_FLOAT)
06487 && GET_CODE (goal) == CONST_INT
06488 && 0 != (goaltry
06489 = operand_subword (XEXP (tem, 0), 0, 0,
06490 VOIDmode))
06491 && rtx_equal_p (goal, goaltry)
06492 && (valtry
06493 = operand_subword (SET_DEST (pat), 0, 0,
06494 VOIDmode))
06495 && (valueno = true_regnum (valtry)) >= 0)))
06496 || (goal_const && (tem = find_reg_note (p, REG_EQUIV,
06497 NULL_RTX))
06498 && GET_CODE (SET_DEST (pat)) == REG
06499 && GET_CODE (XEXP (tem, 0)) == CONST_DOUBLE
06500 && (GET_MODE_CLASS (GET_MODE (XEXP (tem, 0)))
06501 == MODE_FLOAT)
06502 && GET_CODE (goal) == CONST_INT
06503 && 0 != (goaltry = operand_subword (XEXP (tem, 0), 1, 0,
06504 VOIDmode))
06505 && rtx_equal_p (goal, goaltry)
06506 && (valtry
06507 = operand_subword (SET_DEST (pat), 1, 0, VOIDmode))
06508 && (valueno = true_regnum (valtry)) >= 0)))
06509 {
06510 if (other >= 0)
06511 {
06512 if (valueno != other)
06513 continue;
06514 }
06515 else if ((unsigned) valueno >= FIRST_PSEUDO_REGISTER)
06516 continue;
06517 else
06518 {
06519 int i;
06520
06521 for (i = HARD_REGNO_NREGS (valueno, mode) - 1; i >= 0; i--)
06522 if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
06523 valueno + i))
06524 break;
06525 if (i >= 0)
06526 continue;
06527 }
06528 value = valtry;
06529 where = p;
06530 break;
06531 }
06532 }
06533 }
06534
06535
06536
06537
06538
06539
06540
06541
06542
06543 if (REG_NOTES (where) != 0 && find_reg_note (where, REG_UNUSED, value))
06544 return 0;
06545
06546
06547
06548 if (valueno == STACK_POINTER_REGNUM || regno == STACK_POINTER_REGNUM
06549 || (goal_mem && reg_overlap_mentioned_for_reload_p (stack_pointer_rtx,
06550 goal)))
06551 need_stable_sp = 1;
06552
06553
06554 if (GET_MODE (value) != mode)
06555 return 0;
06556
06557
06558
06559
06560 if (goal_mem && value == SET_DEST (single_set (where))
06561 && refers_to_regno_for_reload_p (valueno,
06562 (valueno
06563 + HARD_REGNO_NREGS (valueno, mode)),
06564 goal, (rtx*) 0))
06565 return 0;
06566
06567
06568
06569 if (!goal_mem && !goal_const
06570 && regno + (int) HARD_REGNO_NREGS (regno, mode) > valueno
06571 && regno < valueno + (int) HARD_REGNO_NREGS (valueno, mode))
06572 return 0;
06573
06574 nregs = HARD_REGNO_NREGS (regno, mode);
06575 valuenregs = HARD_REGNO_NREGS (valueno, mode);
06576
06577
06578
06579
06580
06581
06582
06583 if (reload_reg_p != 0 && reload_reg_p != (short *) (HOST_WIDE_INT) 1)
06584 {
06585 int i;
06586 for (i = 0; i < valuenregs; ++i)
06587 if (reload_reg_p[valueno + i] >= 0)
06588 return 0;
06589 }
06590
06591
06592
06593
06594 if (reload_reg_p != 0)
06595 {
06596 int i;
06597 for (i = 0; i < n_reloads; i++)
06598 if (rld[i].reg_rtx != 0 && rld[i].in)
06599 {
06600 int regno1 = REGNO (rld[i].reg_rtx);
06601 int nregs1 = HARD_REGNO_NREGS (regno1,
06602 GET_MODE (rld[i].reg_rtx));
06603 if (regno1 < valueno + valuenregs
06604 && regno1 + nregs1 > valueno)
06605 return 0;
06606 }
06607 }
06608
06609 if (goal_mem)
06610
06611
06612 goal_mem_addr_varies = !CONSTANT_ADDRESS_P (XEXP (goal, 0));
06613
06614
06615
06616
06617 p = insn;
06618 while (1)
06619 {
06620 p = PREV_INSN (p);
06621 if (p == where)
06622 return value;
06623
06624
06625
06626 if (GET_CODE (p) == CALL_INSN)
06627 {
06628 int i;
06629
06630 if (goal_mem || need_stable_sp)
06631 return 0;
06632
06633 if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER)
06634 for (i = 0; i < nregs; ++i)
06635 if (call_used_regs[regno + i])
06636 return 0;
06637
06638 if (valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER)
06639 for (i = 0; i < valuenregs; ++i)
06640 if (call_used_regs[valueno + i])
06641 return 0;
06642 #ifdef NON_SAVING_SETJMP
06643 if (NON_SAVING_SETJMP && find_reg_note (p, REG_SETJMP, NULL))
06644 return 0;
06645 #endif
06646 }
06647
06648 if (INSN_P (p))
06649 {
06650 pat = PATTERN (p);
06651
06652
06653 if (volatile_insn_p (pat))
06654 return 0;
06655
06656
06657
06658
06659
06660
06661 if (GET_CODE (pat) == COND_EXEC)
06662 pat = COND_EXEC_CODE (pat);
06663 if (GET_CODE (pat) == SET || GET_CODE (pat) == CLOBBER)
06664 {
06665 rtx dest = SET_DEST (pat);
06666 while (GET_CODE (dest) == SUBREG
06667 || GET_CODE (dest) == ZERO_EXTRACT
06668 || GET_CODE (dest) == SIGN_EXTRACT
06669 || GET_CODE (dest) == STRICT_LOW_PART)
06670 dest = XEXP (dest, 0);
06671 if (GET_CODE (dest) == REG)
06672 {
06673 int xregno = REGNO (dest);
06674 int xnregs;
06675 if (REGNO (dest) < FIRST_PSEUDO_REGISTER)
06676 xnregs = HARD_REGNO_NREGS (xregno, GET_MODE (dest));
06677 else
06678 xnregs = 1;
06679 if (xregno < regno + nregs && xregno + xnregs > regno)
06680 return 0;
06681 if (xregno < valueno + valuenregs
06682 && xregno + xnregs > valueno)
06683 return 0;
06684 if (goal_mem_addr_varies
06685 && reg_overlap_mentioned_for_reload_p (dest, goal))
06686 return 0;
06687 if (xregno == STACK_POINTER_REGNUM && need_stable_sp)
06688 return 0;
06689 }
06690 else if (goal_mem && GET_CODE (dest) == MEM
06691 && ! push_operand (dest, GET_MODE (dest)))
06692 return 0;
06693 else if (GET_CODE (dest) == MEM && regno >= FIRST_PSEUDO_REGISTER
06694 && reg_equiv_memory_loc[regno] != 0)
06695 return 0;
06696 else if (need_stable_sp && push_operand (dest, GET_MODE (dest)))
06697 return 0;
06698 }
06699 else if (GET_CODE (pat) == PARALLEL)
06700 {
06701 int i;
06702 for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
06703 {
06704 rtx v1 = XVECEXP (pat, 0, i);
06705 if (GET_CODE (v1) == COND_EXEC)
06706 v1 = COND_EXEC_CODE (v1);
06707 if (GET_CODE (v1) == SET || GET_CODE (v1) == CLOBBER)
06708 {
06709 rtx dest = SET_DEST (v1);
06710 while (GET_CODE (dest) == SUBREG
06711 || GET_CODE (dest) == ZERO_EXTRACT
06712 || GET_CODE (dest) == SIGN_EXTRACT
06713 || GET_CODE (dest) == STRICT_LOW_PART)
06714 dest = XEXP (dest, 0);
06715 if (GET_CODE (dest) == REG)
06716 {
06717 int xregno = REGNO (dest);
06718 int xnregs;
06719 if (REGNO (dest) < FIRST_PSEUDO_REGISTER)
06720 xnregs = HARD_REGNO_NREGS (xregno, GET_MODE (dest));
06721 else
06722 xnregs = 1;
06723 if (xregno < regno + nregs
06724 && xregno + xnregs > regno)
06725 return 0;
06726 if (xregno < valueno + valuenregs
06727 && xregno + xnregs > valueno)
06728 return 0;
06729 if (goal_mem_addr_varies
06730 && reg_overlap_mentioned_for_reload_p (dest,
06731 goal))
06732 return 0;
06733 if (xregno == STACK_POINTER_REGNUM && need_stable_sp)
06734 return 0;
06735 }
06736 else if (goal_mem && GET_CODE (dest) == MEM
06737 && ! push_operand (dest, GET_MODE (dest)))
06738 return 0;
06739 else if (GET_CODE (dest) == MEM && regno >= FIRST_PSEUDO_REGISTER
06740 && reg_equiv_memory_loc[regno] != 0)
06741 return 0;
06742 else if (need_stable_sp
06743 && push_operand (dest, GET_MODE (dest)))
06744 return 0;
06745 }
06746 }
06747 }
06748
06749 if (GET_CODE (p) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (p))
06750 {
06751 rtx link;
06752
06753 for (link = CALL_INSN_FUNCTION_USAGE (p); XEXP (link, 1) != 0;
06754 link = XEXP (link, 1))
06755 {
06756 pat = XEXP (link, 0);
06757 if (GET_CODE (pat) == CLOBBER)
06758 {
06759 rtx dest = SET_DEST (pat);
06760
06761 if (GET_CODE (dest) == REG)
06762 {
06763 int xregno = REGNO (dest);
06764 int xnregs
06765 = HARD_REGNO_NREGS (xregno, GET_MODE (dest));
06766
06767 if (xregno < regno + nregs
06768 && xregno + xnregs > regno)
06769 return 0;
06770 else if (xregno < valueno + valuenregs
06771 && xregno + xnregs > valueno)
06772 return 0;
06773 else if (goal_mem_addr_varies
06774 && reg_overlap_mentioned_for_reload_p (dest,
06775 goal))
06776 return 0;
06777 }
06778
06779 else if (goal_mem && GET_CODE (dest) == MEM
06780 && ! push_operand (dest, GET_MODE (dest)))
06781 return 0;
06782 else if (need_stable_sp
06783 && push_operand (dest, GET_MODE (dest)))
06784 return 0;
06785 }
06786 }
06787 }
06788
06789 #ifdef AUTO_INC_DEC
06790
06791
06792
06793
06794 {
06795 rtx link;
06796
06797 for (link = REG_NOTES (p); link; link = XEXP (link, 1))
06798 if (REG_NOTE_KIND (link) == REG_INC
06799 && GET_CODE (XEXP (link, 0)) == REG)
06800 {
06801 int incno = REGNO (XEXP (link, 0));
06802 if (incno < regno + nregs && incno >= regno)
06803 return 0;
06804 if (incno < valueno + valuenregs && incno >= valueno)
06805 return 0;
06806 if (goal_mem_addr_varies
06807 && reg_overlap_mentioned_for_reload_p (XEXP (link, 0),
06808 goal))
06809 return 0;
06810 }
06811 }
06812 #endif
06813 }
06814 }
06815 }
06816
06817
06818
06819
06820
06821 static int
06822 find_inc_amount (x, inced)
06823 rtx x, inced;
06824 {
06825 enum rtx_code code = GET_CODE (x);
06826 const char *fmt;
06827 int i;
06828
06829 if (code == MEM)
06830 {
06831 rtx addr = XEXP (x, 0);
06832 if ((GET_CODE (addr) == PRE_DEC
06833 || GET_CODE (addr) == POST_DEC
06834 || GET_CODE (addr) == PRE_INC
06835 || GET_CODE (addr) == POST_INC)
06836 && XEXP (addr, 0) == inced)
06837 return GET_MODE_SIZE (GET_MODE (x));
06838 else if ((GET_CODE (addr) == PRE_MODIFY
06839 || GET_CODE (addr) == POST_MODIFY)
06840 && GET_CODE (XEXP (addr, 1)) == PLUS
06841 && XEXP (addr, 0) == XEXP (XEXP (addr, 1), 0)
06842 && XEXP (addr, 0) == inced
06843 && GET_CODE (XEXP (XEXP (addr, 1), 1)) == CONST_INT)
06844 {
06845 i = INTVAL (XEXP (XEXP (addr, 1), 1));
06846 return i < 0 ? -i : i;
06847 }
06848 }
06849
06850 fmt = GET_RTX_FORMAT (code);
06851 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
06852 {
06853 if (fmt[i] == 'e')
06854 {
06855 int tem = find_inc_amount (XEXP (x, i), inced);
06856 if (tem != 0)
06857 return tem;
06858 }
06859 if (fmt[i] == 'E')
06860 {
06861 int j;
06862 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
06863 {
06864 int tem = find_inc_amount (XVECEXP (x, i, j), inced);
06865 if (tem != 0)
06866 return tem;
06867 }
06868 }
06869 }
06870
06871 return 0;
06872 }
06873
06874
06875
06876
06877 int
06878 regno_clobbered_p (regno, insn, mode, sets)
06879 unsigned int regno;
06880 rtx insn;
06881 enum machine_mode mode;
06882 int sets;
06883 {
06884 unsigned int nregs = HARD_REGNO_NREGS (regno, mode);
06885 unsigned int endregno = regno + nregs;
06886
06887 if ((GET_CODE (PATTERN (insn)) == CLOBBER
06888 || (sets && GET_CODE (PATTERN (insn)) == SET))
06889 && GET_CODE (XEXP (PATTERN (insn), 0)) == REG)
06890 {
06891 unsigned int test = REGNO (XEXP (PATTERN (insn), 0));
06892
06893 return test >= regno && test < endregno;
06894 }
06895
06896 if (GET_CODE (PATTERN (insn)) == PARALLEL)
06897 {
06898 int i = XVECLEN (PATTERN (insn), 0) - 1;
06899
06900 for (; i >= 0; i--)
06901 {
06902 rtx elt = XVECEXP (PATTERN (insn), 0, i);
06903 if ((GET_CODE (elt) == CLOBBER
06904 || (sets && GET_CODE (PATTERN (insn)) == SET))
06905 && GET_CODE (XEXP (elt, 0)) == REG)
06906 {
06907 unsigned int test = REGNO (XEXP (elt, 0));
06908
06909 if (test >= regno && test < endregno)
06910 return 1;
06911 }
06912 }
06913 }
06914
06915 return 0;
06916 }
06917
06918 static const char *const reload_when_needed_name[] =
06919 {
06920 "RELOAD_FOR_INPUT",
06921 "RELOAD_FOR_OUTPUT",
06922 "RELOAD_FOR_INSN",
06923 "RELOAD_FOR_INPUT_ADDRESS",
06924 "RELOAD_FOR_INPADDR_ADDRESS",
06925 "RELOAD_FOR_OUTPUT_ADDRESS",
06926 "RELOAD_FOR_OUTADDR_ADDRESS",
06927 "RELOAD_FOR_OPERAND_ADDRESS",
06928 "RELOAD_FOR_OPADDR_ADDR",
06929 "RELOAD_OTHER",
06930 "RELOAD_FOR_OTHER_ADDRESS"
06931 };
06932
06933 static const char * const reg_class_names[] = REG_CLASS_NAMES;
06934
06935
06936
06937 void
06938 debug_reload_to_stream (f)
06939 FILE *f;
06940 {
06941 int r;
06942 const char *prefix;
06943
06944 if (! f)
06945 f = stderr;
06946 for (r = 0; r < n_reloads; r++)
06947 {
06948 fprintf (f, "Reload %d: ", r);
06949
06950 if (rld[r].in != 0)
06951 {
06952 fprintf (f, "reload_in (%s) = ",
06953 GET_MODE_NAME (rld[r].inmode));
06954 print_inline_rtx (f, rld[r].in, 24);
06955 fprintf (f, "\n\t");
06956 }
06957
06958 if (rld[r].out != 0)
06959 {
06960 fprintf (f, "reload_out (%s) = ",
06961 GET_MODE_NAME (rld[r].outmode));
06962 print_inline_rtx (f, rld[r].out, 24);
06963 fprintf (f, "\n\t");
06964 }
06965
06966 fprintf (f, "%s, ", reg_class_names[(int) rld[r].class]);
06967
06968 fprintf (f, "%s (opnum = %d)",
06969 reload_when_needed_name[(int) rld[r].when_needed],
06970 rld[r].opnum);
06971
06972 if (rld[r].optional)
06973 fprintf (f, ", optional");
06974
06975 if (rld[r].nongroup)
06976 fprintf (f, ", nongroup");
06977
06978 if (rld[r].inc != 0)
06979 fprintf (f, ", inc by %d", rld[r].inc);
06980
06981 if (rld[r].nocombine)
06982 fprintf (f, ", can't combine");
06983
06984 if (rld[r].secondary_p)
06985 fprintf (f, ", secondary_reload_p");
06986
06987 if (rld[r].in_reg != 0)
06988 {
06989 fprintf (f, "\n\treload_in_reg: ");
06990 print_inline_rtx (f, rld[r].in_reg, 24);
06991 }
06992
06993 if (rld[r].out_reg != 0)
06994 {
06995 fprintf (f, "\n\treload_out_reg: ");
06996 print_inline_rtx (f, rld[r].out_reg, 24);
06997 }
06998
06999 if (rld[r].reg_rtx != 0)
07000 {
07001 fprintf (f, "\n\treload_reg_rtx: ");
07002 print_inline_rtx (f, rld[r].reg_rtx, 24);
07003 }
07004
07005 prefix = "\n\t";
07006 if (rld[r].secondary_in_reload != -1)
07007 {
07008 fprintf (f, "%ssecondary_in_reload = %d",
07009 prefix, rld[r].secondary_in_reload);
07010 prefix = ", ";
07011 }
07012
07013 if (rld[r].secondary_out_reload != -1)
07014 fprintf (f, "%ssecondary_out_reload = %d\n",
07015 prefix, rld[r].secondary_out_reload);
07016
07017 prefix = "\n\t";
07018 if (rld[r].secondary_in_icode != CODE_FOR_nothing)
07019 {
07020 fprintf (f, "%ssecondary_in_icode = %s", prefix,
07021 insn_data[rld[r].secondary_in_icode].name);
07022 prefix = ", ";
07023 }
07024
07025 if (rld[r].secondary_out_icode != CODE_FOR_nothing)
07026 fprintf (f, "%ssecondary_out_icode = %s", prefix,
07027 insn_data[rld[r].secondary_out_icode].name);
07028
07029 fprintf (f, "\n");
07030 }
07031 }
07032
07033 void
07034 debug_reload ()
07035 {
07036 debug_reload_to_stream (stderr);
07037 }