comparison gcc/caller-save.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents a06113de4d67
children b7f97abdc517
comparison
equal deleted inserted replaced
52:c156f1bd5cd9 55:77e2b8dfacca
96 /* Computed by mark_referenced_regs, all regs referenced in a given 96 /* Computed by mark_referenced_regs, all regs referenced in a given
97 insn. */ 97 insn. */
98 static HARD_REG_SET referenced_regs; 98 static HARD_REG_SET referenced_regs;
99 99
100 100
101 typedef void refmarker_fn (rtx *loc, enum machine_mode mode, int hardregno,
102 void *mark_arg);
103
101 static int reg_save_code (int, enum machine_mode); 104 static int reg_save_code (int, enum machine_mode);
102 static int reg_restore_code (int, enum machine_mode); 105 static int reg_restore_code (int, enum machine_mode);
103 106
104 struct saved_hard_reg; 107 struct saved_hard_reg;
105 static void initiate_saved_hard_regs (void); 108 static void initiate_saved_hard_regs (void);
106 static struct saved_hard_reg *new_saved_hard_reg (int, int); 109 static struct saved_hard_reg *new_saved_hard_reg (int, int);
107 static void finish_saved_hard_regs (void); 110 static void finish_saved_hard_regs (void);
108 static int saved_hard_reg_compare_func (const void *, const void *); 111 static int saved_hard_reg_compare_func (const void *, const void *);
109 112
110 static void mark_set_regs (rtx, const_rtx, void *); 113 static void mark_set_regs (rtx, const_rtx, void *);
111 static void add_stored_regs (rtx, const_rtx, void *); 114 static void mark_referenced_regs (rtx *, refmarker_fn *mark, void *mark_arg);
112 static void mark_referenced_regs (rtx); 115 static refmarker_fn mark_reg_as_referenced;
116 static refmarker_fn replace_reg_with_saved_mem;
113 static int insert_save (struct insn_chain *, int, int, HARD_REG_SET *, 117 static int insert_save (struct insn_chain *, int, int, HARD_REG_SET *,
114 enum machine_mode *); 118 enum machine_mode *);
115 static int insert_restore (struct insn_chain *, int, int, int, 119 static int insert_restore (struct insn_chain *, int, int, int,
116 enum machine_mode *); 120 enum machine_mode *);
117 static struct insn_chain *insert_one_insn (struct insn_chain *, int, int, 121 static struct insn_chain *insert_one_insn (struct insn_chain *, int, int,
209 the modes that they can have. If we can't find a mode to use, 213 the modes that they can have. If we can't find a mode to use,
210 we can't have the register live over calls. */ 214 we can't have the register live over calls. */
211 215
212 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 216 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
213 { 217 {
214 if (call_used_regs[i] && ! call_fixed_regs[i]) 218 if (call_used_regs[i]
219 && !TEST_HARD_REG_BIT (call_fixed_reg_set, i))
215 { 220 {
216 for (j = 1; j <= MOVE_MAX_WORDS; j++) 221 for (j = 1; j <= MOVE_MAX_WORDS; j++)
217 { 222 {
218 regno_save_mode[i][j] = HARD_REGNO_CALLER_SAVE_MODE (i, j, 223 regno_save_mode[i][j] = HARD_REGNO_CALLER_SAVE_MODE (i, j,
219 VOIDmode); 224 VOIDmode);
220 if (regno_save_mode[i][j] == VOIDmode && j == 1) 225 if (regno_save_mode[i][j] == VOIDmode && j == 1)
221 { 226 {
222 call_fixed_regs[i] = 1;
223 SET_HARD_REG_BIT (call_fixed_reg_set, i); 227 SET_HARD_REG_BIT (call_fixed_reg_set, i);
224 } 228 }
225 } 229 }
226 } 230 }
227 else 231 else
285 if (reg_save_code (i,regno_save_mode[i][j]) == -1) 289 if (reg_save_code (i,regno_save_mode[i][j]) == -1)
286 { 290 {
287 regno_save_mode[i][j] = VOIDmode; 291 regno_save_mode[i][j] = VOIDmode;
288 if (j == 1) 292 if (j == 1)
289 { 293 {
290 call_fixed_regs[i] = 1;
291 SET_HARD_REG_BIT (call_fixed_reg_set, i); 294 SET_HARD_REG_BIT (call_fixed_reg_set, i);
292 if (call_used_regs[i]) 295 if (call_used_regs[i])
293 SET_HARD_REG_BIT (no_caller_save_reg_set, i); 296 SET_HARD_REG_BIT (no_caller_save_reg_set, i);
294 } 297 }
295 } 298 }
306 309
307 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 310 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
308 for (j = 1; j <= MOVE_MAX_WORDS; j++) 311 for (j = 1; j <= MOVE_MAX_WORDS; j++)
309 regno_save_mem[i][j] = 0; 312 regno_save_mem[i][j] = 0;
310 save_slots_num = 0; 313 save_slots_num = 0;
311 314
312 } 315 }
313 316
314 /* The structure represents a hard register which should be saved 317 /* The structure represents a hard register which should be saved
315 through the call. It is used when the integrated register 318 through the call. It is used when the integrated register
316 allocator (IRA) is used and sharing save slots is on. */ 319 allocator (IRA) is used and sharing save slots is on. */
389 static int 392 static int
390 saved_hard_reg_compare_func (const void *v1p, const void *v2p) 393 saved_hard_reg_compare_func (const void *v1p, const void *v2p)
391 { 394 {
392 const struct saved_hard_reg *p1 = *(struct saved_hard_reg * const *) v1p; 395 const struct saved_hard_reg *p1 = *(struct saved_hard_reg * const *) v1p;
393 const struct saved_hard_reg *p2 = *(struct saved_hard_reg * const *) v2p; 396 const struct saved_hard_reg *p2 = *(struct saved_hard_reg * const *) v2p;
394 397
395 if (flag_omit_frame_pointer) 398 if (flag_omit_frame_pointer)
396 { 399 {
397 if (p1->call_freq - p2->call_freq != 0) 400 if (p1->call_freq - p2->call_freq != 0)
398 return p1->call_freq - p2->call_freq; 401 return p1->call_freq - p2->call_freq;
399 } 402 }
462 HARD_REG_SET hard_regs_to_save, used_regs, this_insn_sets; 465 HARD_REG_SET hard_regs_to_save, used_regs, this_insn_sets;
463 reg_set_iterator rsi; 466 reg_set_iterator rsi;
464 int best_slot_num; 467 int best_slot_num;
465 int prev_save_slots_num; 468 int prev_save_slots_num;
466 rtx prev_save_slots[FIRST_PSEUDO_REGISTER]; 469 rtx prev_save_slots[FIRST_PSEUDO_REGISTER];
467 470
468 initiate_saved_hard_regs (); 471 initiate_saved_hard_regs ();
469 /* Create hard reg saved regs. */ 472 /* Create hard reg saved regs. */
470 for (chain = reload_insn_chain; chain != 0; chain = next) 473 for (chain = reload_insn_chain; chain != 0; chain = next)
471 { 474 {
472 insn = chain->insn; 475 insn = chain->insn;
473 next = chain->next; 476 next = chain->next;
474 if (GET_CODE (insn) != CALL_INSN 477 if (!CALL_P (insn)
475 || find_reg_note (insn, REG_NORETURN, NULL)) 478 || find_reg_note (insn, REG_NORETURN, NULL))
476 continue; 479 continue;
477 freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)); 480 freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
478 REG_SET_TO_HARD_REG_SET (hard_regs_to_save, 481 REG_SET_TO_HARD_REG_SET (hard_regs_to_save,
479 &chain->live_throughout); 482 &chain->live_throughout);
505 EXECUTE_IF_SET_IN_REG_SET 508 EXECUTE_IF_SET_IN_REG_SET
506 (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi) 509 (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi)
507 { 510 {
508 int r = reg_renumber[regno]; 511 int r = reg_renumber[regno];
509 int bound; 512 int bound;
510 513
511 if (r < 0) 514 if (r < 0)
512 continue; 515 continue;
513 516
514 bound = r + hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)]; 517 bound = r + hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)];
515 for (; r < bound; r++) 518 for (; r < bound; r++)
516 if (TEST_HARD_REG_BIT (used_regs, r)) 519 if (TEST_HARD_REG_BIT (used_regs, r))
517 { 520 {
518 if (hard_reg_map[r] != NULL) 521 if (hard_reg_map[r] != NULL)
529 for (chain = reload_insn_chain; chain != 0; chain = next) 532 for (chain = reload_insn_chain; chain != 0; chain = next)
530 { 533 {
531 call_saved_regs_num = 0; 534 call_saved_regs_num = 0;
532 insn = chain->insn; 535 insn = chain->insn;
533 next = chain->next; 536 next = chain->next;
534 if (GET_CODE (insn) != CALL_INSN 537 if (!CALL_P (insn)
535 || find_reg_note (insn, REG_NORETURN, NULL)) 538 || find_reg_note (insn, REG_NORETURN, NULL))
536 continue; 539 continue;
537 REG_SET_TO_HARD_REG_SET (hard_regs_to_save, 540 REG_SET_TO_HARD_REG_SET (hard_regs_to_save,
538 &chain->live_throughout); 541 &chain->live_throughout);
539 COPY_HARD_REG_SET (used_regs, call_used_reg_set); 542 COPY_HARD_REG_SET (used_regs, call_used_reg_set);
563 EXECUTE_IF_SET_IN_REG_SET 566 EXECUTE_IF_SET_IN_REG_SET
564 (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi) 567 (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi)
565 { 568 {
566 int r = reg_renumber[regno]; 569 int r = reg_renumber[regno];
567 int bound; 570 int bound;
568 571
569 if (r < 0) 572 if (r < 0)
570 continue; 573 continue;
571 574
572 bound = r + hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)]; 575 bound = r + hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)];
573 for (; r < bound; r++) 576 for (; r < bound; r++)
681 else 684 else
682 { 685 {
683 /* Now run through all the call-used hard-registers and allocate 686 /* Now run through all the call-used hard-registers and allocate
684 space for them in the caller-save area. Try to allocate space 687 space for them in the caller-save area. Try to allocate space
685 in a manner which allows multi-register saves/restores to be done. */ 688 in a manner which allows multi-register saves/restores to be done. */
686 689
687 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 690 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
688 for (j = MOVE_MAX_WORDS; j > 0; j--) 691 for (j = MOVE_MAX_WORDS; j > 0; j--)
689 { 692 {
690 int do_save = 1; 693 int do_save = 1;
691 694
692 /* If no mode exists for this size, try another. Also break out 695 /* If no mode exists for this size, try another. Also break out
693 if we have already saved this hard register. */ 696 if we have already saved this hard register. */
694 if (regno_save_mode[i][j] == VOIDmode || regno_save_mem[i][1] != 0) 697 if (regno_save_mode[i][j] == VOIDmode || regno_save_mem[i][1] != 0)
695 continue; 698 continue;
696 699
697 /* See if any register in this group has been saved. */ 700 /* See if any register in this group has been saved. */
698 for (k = 0; k < j; k++) 701 for (k = 0; k < j; k++)
699 if (regno_save_mem[i + k][1]) 702 if (regno_save_mem[i + k][1])
700 { 703 {
701 do_save = 0; 704 do_save = 0;
702 break; 705 break;
703 } 706 }
704 if (! do_save) 707 if (! do_save)
705 continue; 708 continue;
706 709
707 for (k = 0; k < j; k++) 710 for (k = 0; k < j; k++)
708 if (! TEST_HARD_REG_BIT (hard_regs_used, i + k)) 711 if (! TEST_HARD_REG_BIT (hard_regs_used, i + k))
709 { 712 {
710 do_save = 0; 713 do_save = 0;
711 break; 714 break;
712 } 715 }
713 if (! do_save) 716 if (! do_save)
714 continue; 717 continue;
715 718
716 /* We have found an acceptable mode to store in. Since 719 /* We have found an acceptable mode to store in. Since
717 hard register is always saved in the widest mode 720 hard register is always saved in the widest mode
718 available, the mode may be wider than necessary, it is 721 available, the mode may be wider than necessary, it is
719 OK to reduce the alignment of spill space. We will 722 OK to reduce the alignment of spill space. We will
720 verify that it is equal to or greater than required 723 verify that it is equal to or greater than required
722 insert_restore and insert_save. */ 725 insert_restore and insert_save. */
723 regno_save_mem[i][j] 726 regno_save_mem[i][j]
724 = assign_stack_local_1 (regno_save_mode[i][j], 727 = assign_stack_local_1 (regno_save_mode[i][j],
725 GET_MODE_SIZE (regno_save_mode[i][j]), 728 GET_MODE_SIZE (regno_save_mode[i][j]),
726 0, true); 729 0, true);
727 730
728 /* Setup single word save area just in case... */ 731 /* Setup single word save area just in case... */
729 for (k = 0; k < j; k++) 732 for (k = 0; k < j; k++)
730 /* This should not depend on WORDS_BIG_ENDIAN. 733 /* This should not depend on WORDS_BIG_ENDIAN.
731 The order of words in regs is the same as in memory. */ 734 The order of words in regs is the same as in memory. */
732 regno_save_mem[i + k][1] 735 regno_save_mem[i + k][1]
768 771
769 next = chain->next; 772 next = chain->next;
770 773
771 gcc_assert (!chain->is_caller_save_insn); 774 gcc_assert (!chain->is_caller_save_insn);
772 775
773 if (INSN_P (insn)) 776 if (NONDEBUG_INSN_P (insn))
774 { 777 {
775 /* If some registers have been saved, see if INSN references 778 /* If some registers have been saved, see if INSN references
776 any of them. We must restore them before the insn if so. */ 779 any of them. We must restore them before the insn if so. */
777 780
778 if (n_regs_saved) 781 if (n_regs_saved)
783 /* Restore all registers if this is a JUMP_INSN. */ 786 /* Restore all registers if this is a JUMP_INSN. */
784 COPY_HARD_REG_SET (referenced_regs, hard_regs_saved); 787 COPY_HARD_REG_SET (referenced_regs, hard_regs_saved);
785 else 788 else
786 { 789 {
787 CLEAR_HARD_REG_SET (referenced_regs); 790 CLEAR_HARD_REG_SET (referenced_regs);
788 mark_referenced_regs (PATTERN (insn)); 791 mark_referenced_regs (&PATTERN (insn),
792 mark_reg_as_referenced, NULL);
789 AND_HARD_REG_SET (referenced_regs, hard_regs_saved); 793 AND_HARD_REG_SET (referenced_regs, hard_regs_saved);
790 } 794 }
791 795
792 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 796 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
793 if (TEST_HARD_REG_BIT (referenced_regs, regno)) 797 if (TEST_HARD_REG_BIT (referenced_regs, regno))
856 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 860 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
857 if (TEST_HARD_REG_BIT (hard_regs_saved, regno)) 861 if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
858 n_regs_saved++; 862 n_regs_saved++;
859 } 863 }
860 } 864 }
865 else if (DEBUG_INSN_P (insn) && n_regs_saved)
866 mark_referenced_regs (&PATTERN (insn),
867 replace_reg_with_saved_mem,
868 save_mode);
861 869
862 if (chain->next == 0 || chain->next->block != chain->block) 870 if (chain->next == 0 || chain->next->block != chain->block)
863 { 871 {
864 int regno; 872 int regno;
865 /* At the end of the basic block, we must restore any registers that 873 /* At the end of the basic block, we must restore any registers that
945 SET_REGNO_REG_SET ((regset) data, i); 953 SET_REGNO_REG_SET ((regset) data, i);
946 } 954 }
947 955
948 /* Walk X and record all referenced registers in REFERENCED_REGS. */ 956 /* Walk X and record all referenced registers in REFERENCED_REGS. */
949 static void 957 static void
950 mark_referenced_regs (rtx x) 958 mark_referenced_regs (rtx *loc, refmarker_fn *mark, void *arg)
951 { 959 {
952 enum rtx_code code = GET_CODE (x); 960 enum rtx_code code = GET_CODE (*loc);
953 const char *fmt; 961 const char *fmt;
954 int i, j; 962 int i, j;
955 963
956 if (code == SET) 964 if (code == SET)
957 mark_referenced_regs (SET_SRC (x)); 965 mark_referenced_regs (&SET_SRC (*loc), mark, arg);
958 if (code == SET || code == CLOBBER) 966 if (code == SET || code == CLOBBER)
959 { 967 {
960 x = SET_DEST (x); 968 loc = &SET_DEST (*loc);
961 code = GET_CODE (x); 969 code = GET_CODE (*loc);
962 if ((code == REG && REGNO (x) < FIRST_PSEUDO_REGISTER) 970 if ((code == REG && REGNO (*loc) < FIRST_PSEUDO_REGISTER)
963 || code == PC || code == CC0 971 || code == PC || code == CC0
964 || (code == SUBREG && REG_P (SUBREG_REG (x)) 972 || (code == SUBREG && REG_P (SUBREG_REG (*loc))
965 && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER 973 && REGNO (SUBREG_REG (*loc)) < FIRST_PSEUDO_REGISTER
966 /* If we're setting only part of a multi-word register, 974 /* If we're setting only part of a multi-word register,
967 we shall mark it as referenced, because the words 975 we shall mark it as referenced, because the words
968 that are not being set should be restored. */ 976 that are not being set should be restored. */
969 && ((GET_MODE_SIZE (GET_MODE (x)) 977 && ((GET_MODE_SIZE (GET_MODE (*loc))
970 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) 978 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (*loc))))
971 || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) 979 || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (*loc)))
972 <= UNITS_PER_WORD)))) 980 <= UNITS_PER_WORD))))
973 return; 981 return;
974 } 982 }
975 if (code == MEM || code == SUBREG) 983 if (code == MEM || code == SUBREG)
976 { 984 {
977 x = XEXP (x, 0); 985 loc = &XEXP (*loc, 0);
978 code = GET_CODE (x); 986 code = GET_CODE (*loc);
979 } 987 }
980 988
981 if (code == REG) 989 if (code == REG)
982 { 990 {
983 int regno = REGNO (x); 991 int regno = REGNO (*loc);
984 int hardregno = (regno < FIRST_PSEUDO_REGISTER ? regno 992 int hardregno = (regno < FIRST_PSEUDO_REGISTER ? regno
985 : reg_renumber[regno]); 993 : reg_renumber[regno]);
986 994
987 if (hardregno >= 0) 995 if (hardregno >= 0)
988 add_to_hard_reg_set (&referenced_regs, GET_MODE (x), hardregno); 996 mark (loc, GET_MODE (*loc), hardregno, arg);
997 else if (arg)
998 /* ??? Will we ever end up with an equiv expression in a debug
999 insn, that would have required restoring a reg, or will
1000 reload take care of it for us? */
1001 return;
989 /* If this is a pseudo that did not get a hard register, scan its 1002 /* If this is a pseudo that did not get a hard register, scan its
990 memory location, since it might involve the use of another 1003 memory location, since it might involve the use of another
991 register, which might be saved. */ 1004 register, which might be saved. */
992 else if (reg_equiv_mem[regno] != 0) 1005 else if (reg_equiv_mem[regno] != 0)
993 mark_referenced_regs (XEXP (reg_equiv_mem[regno], 0)); 1006 mark_referenced_regs (&XEXP (reg_equiv_mem[regno], 0), mark, arg);
994 else if (reg_equiv_address[regno] != 0) 1007 else if (reg_equiv_address[regno] != 0)
995 mark_referenced_regs (reg_equiv_address[regno]); 1008 mark_referenced_regs (&reg_equiv_address[regno], mark, arg);
996 return; 1009 return;
997 } 1010 }
998 1011
999 fmt = GET_RTX_FORMAT (code); 1012 fmt = GET_RTX_FORMAT (code);
1000 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 1013 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1001 { 1014 {
1002 if (fmt[i] == 'e') 1015 if (fmt[i] == 'e')
1003 mark_referenced_regs (XEXP (x, i)); 1016 mark_referenced_regs (&XEXP (*loc, i), mark, arg);
1004 else if (fmt[i] == 'E') 1017 else if (fmt[i] == 'E')
1005 for (j = XVECLEN (x, i) - 1; j >= 0; j--) 1018 for (j = XVECLEN (*loc, i) - 1; j >= 0; j--)
1006 mark_referenced_regs (XVECEXP (x, i, j)); 1019 mark_referenced_regs (&XVECEXP (*loc, i, j), mark, arg);
1007 } 1020 }
1008 } 1021 }
1022
1023 /* Parameter function for mark_referenced_regs() that adds registers
1024 present in the insn and in equivalent mems and addresses to
1025 referenced_regs. */
1026
1027 static void
1028 mark_reg_as_referenced (rtx *loc ATTRIBUTE_UNUSED,
1029 enum machine_mode mode,
1030 int hardregno,
1031 void *arg ATTRIBUTE_UNUSED)
1032 {
1033 add_to_hard_reg_set (&referenced_regs, mode, hardregno);
1034 }
1035
1036 /* Parameter function for mark_referenced_regs() that replaces
1037 registers referenced in a debug_insn that would have been restored,
1038 should it be a non-debug_insn, with their save locations. */
1039
1040 static void
1041 replace_reg_with_saved_mem (rtx *loc,
1042 enum machine_mode mode,
1043 int regno,
1044 void *arg)
1045 {
1046 unsigned int i, nregs = hard_regno_nregs [regno][mode];
1047 rtx mem;
1048 enum machine_mode *save_mode = (enum machine_mode *)arg;
1049
1050 for (i = 0; i < nregs; i++)
1051 if (TEST_HARD_REG_BIT (hard_regs_saved, regno + i))
1052 break;
1053
1054 /* If none of the registers in the range would need restoring, we're
1055 all set. */
1056 if (i == nregs)
1057 return;
1058
1059 while (++i < nregs)
1060 if (!TEST_HARD_REG_BIT (hard_regs_saved, regno + i))
1061 break;
1062
1063 if (i == nregs
1064 && regno_save_mem[regno][nregs])
1065 {
1066 mem = copy_rtx (regno_save_mem[regno][nregs]);
1067
1068 if (nregs == (unsigned int) hard_regno_nregs[regno][save_mode[regno]])
1069 mem = adjust_address_nv (mem, save_mode[regno], 0);
1070
1071 if (GET_MODE (mem) != mode)
1072 {
1073 /* This is gen_lowpart_if_possible(), but without validating
1074 the newly-formed address. */
1075 int offset = 0;
1076
1077 if (WORDS_BIG_ENDIAN)
1078 offset = (MAX (GET_MODE_SIZE (GET_MODE (mem)), UNITS_PER_WORD)
1079 - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
1080 if (BYTES_BIG_ENDIAN)
1081 /* Adjust the address so that the address-after-the-data is
1082 unchanged. */
1083 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
1084 - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (mem))));
1085
1086 mem = adjust_address_nv (mem, mode, offset);
1087 }
1088 }
1089 else
1090 {
1091 mem = gen_rtx_CONCATN (mode, rtvec_alloc (nregs));
1092 for (i = 0; i < nregs; i++)
1093 if (TEST_HARD_REG_BIT (hard_regs_saved, regno + i))
1094 {
1095 gcc_assert (regno_save_mem[regno + i][1]);
1096 XVECEXP (mem, 0, i) = copy_rtx (regno_save_mem[regno + i][1]);
1097 }
1098 else
1099 {
1100 gcc_assert (save_mode[regno] != VOIDmode);
1101 XVECEXP (mem, 0, i) = gen_rtx_REG (save_mode [regno],
1102 regno + i);
1103 }
1104 }
1105
1106 gcc_assert (GET_MODE (mem) == mode);
1107 *loc = mem;
1108 }
1109
1009 1110
1010 /* Insert a sequence of insns to restore. Place these insns in front of 1111 /* Insert a sequence of insns to restore. Place these insns in front of
1011 CHAIN if BEFORE_P is nonzero, behind the insn otherwise. MAXRESTORE is 1112 CHAIN if BEFORE_P is nonzero, behind the insn otherwise. MAXRESTORE is
1012 the maximum number of registers which should be restored during this call. 1113 the maximum number of registers which should be restored during this call.
1013 It should never be less than 1 since we only work with entire registers. 1114 It should never be less than 1 since we only work with entire registers.