00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026 #include "rtl.h"
00027 #include "regs.h"
00028 #include "insn-config.h"
00029 #include "flags.h"
00030 #include "hard-reg-set.h"
00031 #include "recog.h"
00032 #include "basic-block.h"
00033 #include "reload.h"
00034 #include "function.h"
00035 #include "expr.h"
00036 #include "toplev.h"
00037 #include "tm_p.h"
00038 #include "addresses.h"
00039
00040 #ifndef MAX_MOVE_MAX
00041 #define MAX_MOVE_MAX MOVE_MAX
00042 #endif
00043
00044 #ifndef MIN_UNITS_PER_WORD
00045 #define MIN_UNITS_PER_WORD UNITS_PER_WORD
00046 #endif
00047
00048 #define MOVE_MAX_WORDS (MOVE_MAX / UNITS_PER_WORD)
00049
00050
00051
00052
00053
00054
00055 static enum machine_mode
00056 regno_save_mode[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
00057
00058
00059
00060
00061 static rtx
00062 regno_save_mem[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
00063
00064
00065
00066
00067
00068
00069
00070 static int
00071 reg_save_code[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE];
00072 static int
00073 reg_restore_code[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE];
00074
00075
00076
00077 static HARD_REG_SET hard_regs_saved;
00078
00079
00080
00081 static int n_regs_saved;
00082
00083
00084
00085 static HARD_REG_SET referenced_regs;
00086
00087
00088 static void mark_set_regs (rtx, rtx, void *);
00089 static void mark_referenced_regs (rtx);
00090 static int insert_save (struct insn_chain *, int, int, HARD_REG_SET *,
00091 enum machine_mode *);
00092 static int insert_restore (struct insn_chain *, int, int, int,
00093 enum machine_mode *);
00094 static struct insn_chain *insert_one_insn (struct insn_chain *, int, int,
00095 rtx);
00096 static void add_stored_regs (rtx, rtx, void *);
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 void
00109 init_caller_save (void)
00110 {
00111 rtx addr_reg;
00112 int offset;
00113 rtx address;
00114 int i, j;
00115 enum machine_mode mode;
00116 rtx savepat, restpat;
00117 rtx test_reg, test_mem;
00118 rtx saveinsn, restinsn;
00119
00120
00121
00122
00123
00124 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00125 {
00126 if (call_used_regs[i] && ! call_fixed_regs[i])
00127 {
00128 for (j = 1; j <= MOVE_MAX_WORDS; j++)
00129 {
00130 regno_save_mode[i][j] = HARD_REGNO_CALLER_SAVE_MODE (i, j,
00131 VOIDmode);
00132 if (regno_save_mode[i][j] == VOIDmode && j == 1)
00133 {
00134 call_fixed_regs[i] = 1;
00135 SET_HARD_REG_BIT (call_fixed_reg_set, i);
00136 }
00137 }
00138 }
00139 else
00140 regno_save_mode[i][1] = VOIDmode;
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00155 if (TEST_HARD_REG_BIT
00156 (reg_class_contents
00157 [(int) base_reg_class (regno_save_mode [i][1], PLUS, CONST_INT)], i))
00158 break;
00159
00160 gcc_assert (i < FIRST_PSEUDO_REGISTER);
00161
00162 addr_reg = gen_rtx_REG (Pmode, i);
00163
00164 for (offset = 1 << (HOST_BITS_PER_INT / 2); offset; offset >>= 1)
00165 {
00166 address = gen_rtx_PLUS (Pmode, addr_reg, GEN_INT (offset));
00167
00168 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00169 if (regno_save_mode[i][1] != VOIDmode
00170 && ! strict_memory_address_p (regno_save_mode[i][1], address))
00171 break;
00172
00173 if (i == FIRST_PSEUDO_REGISTER)
00174 break;
00175 }
00176
00177
00178 if (offset == 0)
00179 address = addr_reg;
00180
00181
00182
00183
00184
00185
00186
00187 test_reg = gen_rtx_REG (VOIDmode, 0);
00188 test_mem = gen_rtx_MEM (VOIDmode, address);
00189 savepat = gen_rtx_SET (VOIDmode, test_mem, test_reg);
00190 restpat = gen_rtx_SET (VOIDmode, test_reg, test_mem);
00191
00192 saveinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, 0, savepat, -1, 0, 0);
00193 restinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, 0, restpat, -1, 0, 0);
00194
00195 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00196 for (mode = 0 ; mode < MAX_MACHINE_MODE; mode++)
00197 if (HARD_REGNO_MODE_OK (i, mode))
00198 {
00199 int ok;
00200
00201
00202
00203 REGNO (test_reg) = i;
00204 PUT_MODE (test_reg, mode);
00205 PUT_MODE (test_mem, mode);
00206
00207
00208 INSN_CODE (saveinsn) = -1;
00209 INSN_CODE (restinsn) = -1;
00210
00211 reg_save_code[i][mode] = recog_memoized (saveinsn);
00212 reg_restore_code[i][mode] = recog_memoized (restinsn);
00213
00214
00215
00216 ok = (reg_save_code[i][mode] != -1
00217 && reg_restore_code[i][mode] != -1);
00218 if (ok)
00219 {
00220 extract_insn (saveinsn);
00221 ok = constrain_operands (1);
00222 extract_insn (restinsn);
00223 ok &= constrain_operands (1);
00224 }
00225
00226 if (! ok)
00227 {
00228 reg_save_code[i][mode] = -1;
00229 reg_restore_code[i][mode] = -1;
00230 }
00231 }
00232 else
00233 {
00234 reg_save_code[i][mode] = -1;
00235 reg_restore_code[i][mode] = -1;
00236 }
00237
00238 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00239 for (j = 1; j <= MOVE_MAX_WORDS; j++)
00240 if (reg_save_code [i][regno_save_mode[i][j]] == -1)
00241 {
00242 regno_save_mode[i][j] = VOIDmode;
00243 if (j == 1)
00244 {
00245 call_fixed_regs[i] = 1;
00246 SET_HARD_REG_BIT (call_fixed_reg_set, i);
00247 }
00248 }
00249 }
00250
00251
00252
00253 void
00254 init_save_areas (void)
00255 {
00256 int i, j;
00257
00258 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00259 for (j = 1; j <= MOVE_MAX_WORDS; j++)
00260 regno_save_mem[i][j] = 0;
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 void
00282 setup_save_areas (void)
00283 {
00284 int i, j, k;
00285 unsigned int r;
00286 HARD_REG_SET hard_regs_used;
00287
00288
00289
00290
00291
00292
00293 CLEAR_HARD_REG_SET (hard_regs_used);
00294 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
00295 if (reg_renumber[i] >= 0 && REG_N_CALLS_CROSSED (i) > 0)
00296 {
00297 unsigned int regno = reg_renumber[i];
00298 unsigned int endregno
00299 = regno + hard_regno_nregs[regno][GET_MODE (regno_reg_rtx[i])];
00300
00301 for (r = regno; r < endregno; r++)
00302 if (call_used_regs[r])
00303 SET_HARD_REG_BIT (hard_regs_used, r);
00304 }
00305
00306
00307
00308
00309
00310 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00311 for (j = MOVE_MAX_WORDS; j > 0; j--)
00312 {
00313 int do_save = 1;
00314
00315
00316
00317 if (regno_save_mode[i][j] == VOIDmode || regno_save_mem[i][1] != 0)
00318 continue;
00319
00320
00321 for (k = 0; k < j; k++)
00322 if (regno_save_mem[i + k][1])
00323 {
00324 do_save = 0;
00325 break;
00326 }
00327 if (! do_save)
00328 continue;
00329
00330 for (k = 0; k < j; k++)
00331 if (! TEST_HARD_REG_BIT (hard_regs_used, i + k))
00332 {
00333 do_save = 0;
00334 break;
00335 }
00336 if (! do_save)
00337 continue;
00338
00339
00340 regno_save_mem[i][j]
00341 = assign_stack_local (regno_save_mode[i][j],
00342 GET_MODE_SIZE (regno_save_mode[i][j]), 0);
00343
00344
00345 for (k = 0; k < j; k++)
00346
00347
00348 regno_save_mem[i + k][1]
00349 = adjust_address_nv (regno_save_mem[i][j],
00350 regno_save_mode[i + k][1],
00351 k * UNITS_PER_WORD);
00352 }
00353
00354
00355
00356 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00357 for (j = MOVE_MAX_WORDS; j > 0; j--)
00358 if (regno_save_mem[i][j] != 0)
00359 set_mem_alias_set (regno_save_mem[i][j], get_frame_alias_set ());
00360 }
00361
00362
00363
00364 void
00365 save_call_clobbered_regs (void)
00366 {
00367 struct insn_chain *chain, *next;
00368 enum machine_mode save_mode [FIRST_PSEUDO_REGISTER];
00369
00370
00371
00372 HARD_REG_SET this_insn_sets;
00373
00374 CLEAR_HARD_REG_SET (hard_regs_saved);
00375 n_regs_saved = 0;
00376
00377 for (chain = reload_insn_chain; chain != 0; chain = next)
00378 {
00379 rtx insn = chain->insn;
00380 enum rtx_code code = GET_CODE (insn);
00381
00382 next = chain->next;
00383
00384 gcc_assert (!chain->is_caller_save_insn);
00385
00386 if (INSN_P (insn))
00387 {
00388
00389
00390
00391 if (n_regs_saved)
00392 {
00393 int regno;
00394
00395 if (code == JUMP_INSN)
00396
00397 COPY_HARD_REG_SET (referenced_regs, hard_regs_saved);
00398 else
00399 {
00400 CLEAR_HARD_REG_SET (referenced_regs);
00401 mark_referenced_regs (PATTERN (insn));
00402 AND_HARD_REG_SET (referenced_regs, hard_regs_saved);
00403 }
00404
00405 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
00406 if (TEST_HARD_REG_BIT (referenced_regs, regno))
00407 regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS, save_mode);
00408 }
00409
00410 if (code == CALL_INSN && ! find_reg_note (insn, REG_NORETURN, NULL))
00411 {
00412 unsigned regno;
00413 HARD_REG_SET hard_regs_to_save;
00414 reg_set_iterator rsi;
00415
00416
00417
00418 REG_SET_TO_HARD_REG_SET (hard_regs_to_save,
00419 &chain->live_throughout);
00420
00421 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
00422 if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
00423 save_mode [regno] = regno_save_mode [regno][1];
00424 else
00425 save_mode [regno] = VOIDmode;
00426
00427
00428
00429 EXECUTE_IF_SET_IN_REG_SET
00430 (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi)
00431 {
00432 int r = reg_renumber[regno];
00433 int nregs;
00434 enum machine_mode mode;
00435
00436 gcc_assert (r >= 0);
00437 nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)];
00438 mode = HARD_REGNO_CALLER_SAVE_MODE
00439 (r, nregs, PSEUDO_REGNO_MODE (regno));
00440 if (GET_MODE_BITSIZE (mode)
00441 > GET_MODE_BITSIZE (save_mode[r]))
00442 save_mode[r] = mode;
00443 while (nregs-- > 0)
00444 SET_HARD_REG_BIT (hard_regs_to_save, r + nregs);
00445 }
00446
00447
00448
00449
00450
00451 CLEAR_HARD_REG_SET (this_insn_sets);
00452 note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets);
00453
00454
00455 if (SIBLING_CALL_P (insn) && current_function_return_rtx)
00456 mark_set_regs (current_function_return_rtx, NULL_RTX,
00457 &this_insn_sets);
00458
00459
00460 AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set);
00461 AND_COMPL_HARD_REG_SET (hard_regs_to_save, this_insn_sets);
00462 AND_COMPL_HARD_REG_SET (hard_regs_to_save, hard_regs_saved);
00463 AND_HARD_REG_SET (hard_regs_to_save, call_used_reg_set);
00464
00465 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
00466 if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
00467 regno += insert_save (chain, 1, regno, &hard_regs_to_save, save_mode);
00468
00469
00470 n_regs_saved = 0;
00471 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
00472 if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
00473 n_regs_saved++;
00474 }
00475 }
00476
00477 if (chain->next == 0 || chain->next->block > chain->block)
00478 {
00479 int regno;
00480
00481
00482
00483
00484 if (n_regs_saved)
00485 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
00486 if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
00487 regno += insert_restore (chain, JUMP_P (insn),
00488 regno, MOVE_MAX_WORDS, save_mode);
00489 }
00490 }
00491 }
00492
00493
00494
00495
00496
00497
00498 static void
00499 mark_set_regs (rtx reg, rtx setter ATTRIBUTE_UNUSED, void *data)
00500 {
00501 int regno, endregno, i;
00502 enum machine_mode mode = GET_MODE (reg);
00503 HARD_REG_SET *this_insn_sets = data;
00504
00505 if (GET_CODE (reg) == SUBREG)
00506 {
00507 rtx inner = SUBREG_REG (reg);
00508 if (!REG_P (inner) || REGNO (inner) >= FIRST_PSEUDO_REGISTER)
00509 return;
00510 regno = subreg_regno (reg);
00511 }
00512 else if (REG_P (reg)
00513 && REGNO (reg) < FIRST_PSEUDO_REGISTER)
00514 regno = REGNO (reg);
00515 else
00516 return;
00517
00518 endregno = regno + hard_regno_nregs[regno][mode];
00519
00520 for (i = regno; i < endregno; i++)
00521 SET_HARD_REG_BIT (*this_insn_sets, i);
00522 }
00523
00524
00525
00526
00527
00528 static void
00529 add_stored_regs (rtx reg, rtx setter, void *data)
00530 {
00531 int regno, endregno, i;
00532 enum machine_mode mode = GET_MODE (reg);
00533 int offset = 0;
00534
00535 if (GET_CODE (setter) == CLOBBER)
00536 return;
00537
00538 if (GET_CODE (reg) == SUBREG && REG_P (SUBREG_REG (reg)))
00539 {
00540 offset = subreg_regno_offset (REGNO (SUBREG_REG (reg)),
00541 GET_MODE (SUBREG_REG (reg)),
00542 SUBREG_BYTE (reg),
00543 GET_MODE (reg));
00544 reg = SUBREG_REG (reg);
00545 }
00546
00547 if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
00548 return;
00549
00550 regno = REGNO (reg) + offset;
00551 endregno = regno + hard_regno_nregs[regno][mode];
00552
00553 for (i = regno; i < endregno; i++)
00554 SET_REGNO_REG_SET ((regset) data, i);
00555 }
00556
00557
00558 static void
00559 mark_referenced_regs (rtx x)
00560 {
00561 enum rtx_code code = GET_CODE (x);
00562 const char *fmt;
00563 int i, j;
00564
00565 if (code == SET)
00566 mark_referenced_regs (SET_SRC (x));
00567 if (code == SET || code == CLOBBER)
00568 {
00569 x = SET_DEST (x);
00570 code = GET_CODE (x);
00571 if ((code == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
00572 || code == PC || code == CC0
00573 || (code == SUBREG && REG_P (SUBREG_REG (x))
00574 && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER
00575
00576
00577
00578 && ((GET_MODE_SIZE (GET_MODE (x))
00579 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
00580 || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))
00581 <= UNITS_PER_WORD))))
00582 return;
00583 }
00584 if (code == MEM || code == SUBREG)
00585 {
00586 x = XEXP (x, 0);
00587 code = GET_CODE (x);
00588 }
00589
00590 if (code == REG)
00591 {
00592 int regno = REGNO (x);
00593 int hardregno = (regno < FIRST_PSEUDO_REGISTER ? regno
00594 : reg_renumber[regno]);
00595
00596 if (hardregno >= 0)
00597 {
00598 int nregs = hard_regno_nregs[hardregno][GET_MODE (x)];
00599 while (nregs-- > 0)
00600 SET_HARD_REG_BIT (referenced_regs, hardregno + nregs);
00601 }
00602
00603
00604
00605 else if (reg_equiv_mem[regno] != 0)
00606 mark_referenced_regs (XEXP (reg_equiv_mem[regno], 0));
00607 else if (reg_equiv_address[regno] != 0)
00608 mark_referenced_regs (reg_equiv_address[regno]);
00609 return;
00610 }
00611
00612 fmt = GET_RTX_FORMAT (code);
00613 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
00614 {
00615 if (fmt[i] == 'e')
00616 mark_referenced_regs (XEXP (x, i));
00617 else if (fmt[i] == 'E')
00618 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
00619 mark_referenced_regs (XVECEXP (x, i, j));
00620 }
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636 static int
00637 insert_restore (struct insn_chain *chain, int before_p, int regno,
00638 int maxrestore, enum machine_mode *save_mode)
00639 {
00640 int i, k;
00641 rtx pat = NULL_RTX;
00642 int code;
00643 unsigned int numregs = 0;
00644 struct insn_chain *new;
00645 rtx mem;
00646
00647
00648
00649
00650
00651
00652
00653 gcc_assert (regno_save_mem[regno][1]);
00654
00655
00656
00657
00658
00659 for (i = maxrestore; i > 0; i--)
00660 {
00661 int j;
00662 int ok = 1;
00663
00664 if (regno_save_mem[regno][i] == 0)
00665 continue;
00666
00667 for (j = 0; j < i; j++)
00668 if (! TEST_HARD_REG_BIT (hard_regs_saved, regno + j))
00669 {
00670 ok = 0;
00671 break;
00672 }
00673
00674 if (! ok)
00675 continue;
00676
00677 numregs = i;
00678 break;
00679 }
00680
00681 mem = regno_save_mem [regno][numregs];
00682 if (save_mode [regno] != VOIDmode
00683 && save_mode [regno] != GET_MODE (mem)
00684 && numregs == (unsigned int) hard_regno_nregs[regno][save_mode [regno]])
00685 mem = adjust_address (mem, save_mode[regno], 0);
00686 else
00687 mem = copy_rtx (mem);
00688 pat = gen_rtx_SET (VOIDmode,
00689 gen_rtx_REG (GET_MODE (mem),
00690 regno), mem);
00691 code = reg_restore_code[regno][GET_MODE (mem)];
00692 new = insert_one_insn (chain, before_p, code, pat);
00693
00694
00695 for (k = 0; k < i; k++)
00696 {
00697 CLEAR_HARD_REG_BIT (hard_regs_saved, regno + k);
00698 SET_REGNO_REG_SET (&new->dead_or_set, regno + k);
00699 n_regs_saved--;
00700 }
00701
00702
00703 return numregs - 1;
00704 }
00705
00706
00707
00708 static int
00709 insert_save (struct insn_chain *chain, int before_p, int regno,
00710 HARD_REG_SET (*to_save), enum machine_mode *save_mode)
00711 {
00712 int i;
00713 unsigned int k;
00714 rtx pat = NULL_RTX;
00715 int code;
00716 unsigned int numregs = 0;
00717 struct insn_chain *new;
00718 rtx mem;
00719
00720
00721
00722
00723
00724
00725
00726 gcc_assert (regno_save_mem[regno][1]);
00727
00728
00729
00730
00731
00732 for (i = MOVE_MAX_WORDS; i > 0; i--)
00733 {
00734 int j;
00735 int ok = 1;
00736 if (regno_save_mem[regno][i] == 0)
00737 continue;
00738
00739 for (j = 0; j < i; j++)
00740 if (! TEST_HARD_REG_BIT (*to_save, regno + j))
00741 {
00742 ok = 0;
00743 break;
00744 }
00745
00746 if (! ok)
00747 continue;
00748
00749 numregs = i;
00750 break;
00751 }
00752
00753 mem = regno_save_mem [regno][numregs];
00754 if (save_mode [regno] != VOIDmode
00755 && save_mode [regno] != GET_MODE (mem)
00756 && numregs == (unsigned int) hard_regno_nregs[regno][save_mode [regno]])
00757 mem = adjust_address (mem, save_mode[regno], 0);
00758 else
00759 mem = copy_rtx (mem);
00760 pat = gen_rtx_SET (VOIDmode, mem,
00761 gen_rtx_REG (GET_MODE (mem),
00762 regno));
00763 code = reg_save_code[regno][GET_MODE (mem)];
00764 new = insert_one_insn (chain, before_p, code, pat);
00765
00766
00767 for (k = 0; k < numregs; k++)
00768 {
00769 SET_HARD_REG_BIT (hard_regs_saved, regno + k);
00770 SET_REGNO_REG_SET (&new->dead_or_set, regno + k);
00771 n_regs_saved++;
00772 }
00773
00774
00775 return numregs - 1;
00776 }
00777
00778
00779 static struct insn_chain *
00780 insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
00781 {
00782 rtx insn = chain->insn;
00783 struct insn_chain *new;
00784
00785 #ifdef HAVE_cc0
00786
00787
00788
00789
00790
00791
00792 if ((NONJUMP_INSN_P (insn) || JUMP_P (insn))
00793 && before_p
00794 && reg_referenced_p (cc0_rtx, PATTERN (insn)))
00795 chain = chain->prev, insn = chain->insn;
00796 #endif
00797
00798 new = new_insn_chain ();
00799 if (before_p)
00800 {
00801 rtx link;
00802
00803 new->prev = chain->prev;
00804 if (new->prev != 0)
00805 new->prev->next = new;
00806 else
00807 reload_insn_chain = new;
00808
00809 chain->prev = new;
00810 new->next = chain;
00811 new->insn = emit_insn_before (pat, insn);
00812
00813
00814 COPY_REG_SET (&new->live_throughout, &chain->live_throughout);
00815
00816 for (link = REG_NOTES (chain->insn); link; link = XEXP (link, 1))
00817 {
00818 if (REG_NOTE_KIND (link) == REG_DEAD)
00819 {
00820 rtx reg = XEXP (link, 0);
00821 int regno, i;
00822
00823 gcc_assert (REG_P (reg));
00824 regno = REGNO (reg);
00825 if (regno >= FIRST_PSEUDO_REGISTER)
00826 regno = reg_renumber[regno];
00827 if (regno < 0)
00828 continue;
00829 for (i = hard_regno_nregs[regno][GET_MODE (reg)] - 1;
00830 i >= 0; i--)
00831 SET_REGNO_REG_SET (&new->live_throughout, regno + i);
00832 }
00833 }
00834 CLEAR_REG_SET (&new->dead_or_set);
00835 if (chain->insn == BB_HEAD (BASIC_BLOCK (chain->block)))
00836 BB_HEAD (BASIC_BLOCK (chain->block)) = new->insn;
00837 }
00838 else
00839 {
00840 new->next = chain->next;
00841 if (new->next != 0)
00842 new->next->prev = new;
00843 chain->next = new;
00844 new->prev = chain;
00845 new->insn = emit_insn_after (pat, insn);
00846
00847
00848 COPY_REG_SET (&new->live_throughout, &chain->live_throughout);
00849
00850
00851
00852 note_stores (PATTERN (chain->insn), add_stored_regs,
00853 &new->live_throughout);
00854 CLEAR_REG_SET (&new->dead_or_set);
00855 if (chain->insn == BB_END (BASIC_BLOCK (chain->block)))
00856 BB_END (BASIC_BLOCK (chain->block)) = new->insn;
00857 }
00858 new->block = chain->block;
00859 new->is_caller_save_insn = 1;
00860
00861 INSN_CODE (new->insn) = code;
00862 return new;
00863 }