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