Mercurial > hg > CbC > CbC_gcc
comparison gcc/caller-save.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Save and restore call-clobbered registers which are live across a call. | 1 /* Save and restore call-clobbered registers which are live across a call. |
2 Copyright (C) 1989, 1992, 1994, 1995, 1997, 1998, 1999, 2000, | 2 Copyright (C) 1989-2017 Free Software Foundation, Inc. |
3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 | |
4 Free Software Foundation, Inc. | |
5 | 3 |
6 This file is part of GCC. | 4 This file is part of GCC. |
7 | 5 |
8 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
9 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
20 <http://www.gnu.org/licenses/>. */ | 18 <http://www.gnu.org/licenses/>. */ |
21 | 19 |
22 #include "config.h" | 20 #include "config.h" |
23 #include "system.h" | 21 #include "system.h" |
24 #include "coretypes.h" | 22 #include "coretypes.h" |
25 #include "tm.h" | 23 #include "backend.h" |
26 #include "rtl.h" | 24 #include "rtl.h" |
25 #include "tree.h" | |
26 #include "predict.h" | |
27 #include "df.h" | |
28 #include "memmodel.h" | |
29 #include "tm_p.h" | |
30 #include "insn-config.h" | |
27 #include "regs.h" | 31 #include "regs.h" |
28 #include "insn-config.h" | 32 #include "emit-rtl.h" |
29 #include "flags.h" | |
30 #include "hard-reg-set.h" | |
31 #include "recog.h" | 33 #include "recog.h" |
32 #include "basic-block.h" | |
33 #include "df.h" | |
34 #include "reload.h" | 34 #include "reload.h" |
35 #include "function.h" | 35 #include "alias.h" |
36 #include "expr.h" | |
37 #include "diagnostic-core.h" | |
38 #include "tm_p.h" | |
39 #include "addresses.h" | 36 #include "addresses.h" |
40 #include "output.h" | 37 #include "dumpfile.h" |
41 #include "ggc.h" | 38 #include "rtl-iter.h" |
39 #include "target.h" | |
42 | 40 |
43 #define MOVE_MAX_WORDS (MOVE_MAX / UNITS_PER_WORD) | 41 #define MOVE_MAX_WORDS (MOVE_MAX / UNITS_PER_WORD) |
44 | 42 |
45 #define regno_save_mode \ | 43 #define regno_save_mode \ |
46 (this_target_reload->x_regno_save_mode) | 44 (this_target_reload->x_regno_save_mode) |
72 /* Computed by mark_referenced_regs, all regs referenced in a given | 70 /* Computed by mark_referenced_regs, all regs referenced in a given |
73 insn. */ | 71 insn. */ |
74 static HARD_REG_SET referenced_regs; | 72 static HARD_REG_SET referenced_regs; |
75 | 73 |
76 | 74 |
77 typedef void refmarker_fn (rtx *loc, enum machine_mode mode, int hardregno, | 75 typedef void refmarker_fn (rtx *loc, machine_mode mode, int hardregno, |
78 void *mark_arg); | 76 void *mark_arg); |
79 | 77 |
80 static int reg_save_code (int, enum machine_mode); | 78 static int reg_save_code (int, machine_mode); |
81 static int reg_restore_code (int, enum machine_mode); | 79 static int reg_restore_code (int, machine_mode); |
82 | 80 |
83 struct saved_hard_reg; | 81 struct saved_hard_reg; |
84 static void initiate_saved_hard_regs (void); | 82 static void initiate_saved_hard_regs (void); |
85 static struct saved_hard_reg *new_saved_hard_reg (int, int); | 83 static void new_saved_hard_reg (int, int); |
86 static void finish_saved_hard_regs (void); | 84 static void finish_saved_hard_regs (void); |
87 static int saved_hard_reg_compare_func (const void *, const void *); | 85 static int saved_hard_reg_compare_func (const void *, const void *); |
88 | 86 |
89 static void mark_set_regs (rtx, const_rtx, void *); | 87 static void mark_set_regs (rtx, const_rtx, void *); |
90 static void mark_referenced_regs (rtx *, refmarker_fn *mark, void *mark_arg); | 88 static void mark_referenced_regs (rtx *, refmarker_fn *mark, void *mark_arg); |
91 static refmarker_fn mark_reg_as_referenced; | 89 static refmarker_fn mark_reg_as_referenced; |
92 static refmarker_fn replace_reg_with_saved_mem; | 90 static refmarker_fn replace_reg_with_saved_mem; |
93 static int insert_save (struct insn_chain *, int, int, HARD_REG_SET *, | 91 static int insert_save (struct insn_chain *, int, int, HARD_REG_SET *, |
94 enum machine_mode *); | 92 machine_mode *); |
95 static int insert_restore (struct insn_chain *, int, int, int, | 93 static int insert_restore (struct insn_chain *, int, int, int, |
96 enum machine_mode *); | 94 machine_mode *); |
97 static struct insn_chain *insert_one_insn (struct insn_chain *, int, int, | 95 static struct insn_chain *insert_one_insn (struct insn_chain *, int, int, |
98 rtx); | 96 rtx); |
99 static void add_stored_regs (rtx, const_rtx, void *); | 97 static void add_stored_regs (rtx, const_rtx, void *); |
100 | 98 |
101 | 99 |
102 | 100 |
103 static GTY(()) rtx savepat; | 101 static GTY(()) rtx savepat; |
104 static GTY(()) rtx restpat; | 102 static GTY(()) rtx restpat; |
105 static GTY(()) rtx test_reg; | 103 static GTY(()) rtx test_reg; |
106 static GTY(()) rtx test_mem; | 104 static GTY(()) rtx test_mem; |
107 static GTY(()) rtx saveinsn; | 105 static GTY(()) rtx_insn *saveinsn; |
108 static GTY(()) rtx restinsn; | 106 static GTY(()) rtx_insn *restinsn; |
109 | 107 |
110 /* Return the INSN_CODE used to save register REG in mode MODE. */ | 108 /* Return the INSN_CODE used to save register REG in mode MODE. */ |
111 static int | 109 static int |
112 reg_save_code (int reg, enum machine_mode mode) | 110 reg_save_code (int reg, machine_mode mode) |
113 { | 111 { |
114 bool ok; | 112 bool ok; |
115 if (cached_reg_save_code[reg][mode]) | 113 if (cached_reg_save_code[reg][mode]) |
116 return cached_reg_save_code[reg][mode]; | 114 return cached_reg_save_code[reg][mode]; |
117 if (!HARD_REGNO_MODE_OK (reg, mode)) | 115 if (!targetm.hard_regno_mode_ok (reg, mode)) |
118 { | 116 { |
119 /* Depending on how HARD_REGNO_MODE_OK is defined, range propagation | 117 /* Depending on how targetm.hard_regno_mode_ok is defined, range |
120 might deduce here that reg >= FIRST_PSEUDO_REGISTER. So the assert | 118 propagation might deduce here that reg >= FIRST_PSEUDO_REGISTER. |
121 below silences a warning. */ | 119 So the assert below silences a warning. */ |
122 gcc_assert (reg < FIRST_PSEUDO_REGISTER); | 120 gcc_assert (reg < FIRST_PSEUDO_REGISTER); |
123 cached_reg_save_code[reg][mode] = -1; | 121 cached_reg_save_code[reg][mode] = -1; |
124 cached_reg_restore_code[reg][mode] = -1; | 122 cached_reg_restore_code[reg][mode] = -1; |
125 return -1; | 123 return -1; |
126 } | 124 } |
127 | 125 |
128 /* Update the register number and modes of the register | 126 /* Update the register number and modes of the register |
129 and memory operand. */ | 127 and memory operand. */ |
130 SET_REGNO_RAW (test_reg, reg); | 128 set_mode_and_regno (test_reg, mode, reg); |
131 PUT_MODE (test_reg, mode); | |
132 PUT_MODE (test_mem, mode); | 129 PUT_MODE (test_mem, mode); |
133 | 130 |
134 /* Force re-recognition of the modified insns. */ | 131 /* Force re-recognition of the modified insns. */ |
135 INSN_CODE (saveinsn) = -1; | 132 INSN_CODE (saveinsn) = -1; |
136 INSN_CODE (restinsn) = -1; | 133 INSN_CODE (restinsn) = -1; |
137 | 134 |
138 cached_reg_save_code[reg][mode] = recog_memoized (saveinsn); | 135 cached_reg_save_code[reg][mode] = recog_memoized (saveinsn); |
139 cached_reg_restore_code[reg][mode] = recog_memoized (restinsn); | 136 cached_reg_restore_code[reg][mode] = recog_memoized (restinsn); |
140 | 137 |
141 /* Now extract both insns and see if we can meet their | 138 /* Now extract both insns and see if we can meet their |
142 constraints. */ | 139 constraints. We don't know here whether the save and restore will |
140 be in size- or speed-tuned code, so just use the set of enabled | |
141 alternatives. */ | |
143 ok = (cached_reg_save_code[reg][mode] != -1 | 142 ok = (cached_reg_save_code[reg][mode] != -1 |
144 && cached_reg_restore_code[reg][mode] != -1); | 143 && cached_reg_restore_code[reg][mode] != -1); |
145 if (ok) | 144 if (ok) |
146 { | 145 { |
147 extract_insn (saveinsn); | 146 extract_insn (saveinsn); |
148 ok = constrain_operands (1); | 147 ok = constrain_operands (1, get_enabled_alternatives (saveinsn)); |
149 extract_insn (restinsn); | 148 extract_insn (restinsn); |
150 ok &= constrain_operands (1); | 149 ok &= constrain_operands (1, get_enabled_alternatives (restinsn)); |
151 } | 150 } |
152 | 151 |
153 if (! ok) | 152 if (! ok) |
154 { | 153 { |
155 cached_reg_save_code[reg][mode] = -1; | 154 cached_reg_save_code[reg][mode] = -1; |
159 return cached_reg_save_code[reg][mode]; | 158 return cached_reg_save_code[reg][mode]; |
160 } | 159 } |
161 | 160 |
162 /* Return the INSN_CODE used to restore register REG in mode MODE. */ | 161 /* Return the INSN_CODE used to restore register REG in mode MODE. */ |
163 static int | 162 static int |
164 reg_restore_code (int reg, enum machine_mode mode) | 163 reg_restore_code (int reg, machine_mode mode) |
165 { | 164 { |
166 if (cached_reg_restore_code[reg][mode]) | 165 if (cached_reg_restore_code[reg][mode]) |
167 return cached_reg_restore_code[reg][mode]; | 166 return cached_reg_restore_code[reg][mode]; |
168 /* Populate our cache. */ | 167 /* Populate our cache. */ |
169 reg_save_code (reg, mode); | 168 reg_save_code (reg, mode); |
229 that register in every mode we will use to save registers. */ | 228 that register in every mode we will use to save registers. */ |
230 | 229 |
231 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | 230 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) |
232 if (TEST_HARD_REG_BIT | 231 if (TEST_HARD_REG_BIT |
233 (reg_class_contents | 232 (reg_class_contents |
234 [(int) base_reg_class (regno_save_mode[i][1], PLUS, CONST_INT)], i)) | 233 [(int) base_reg_class (regno_save_mode[i][1], ADDR_SPACE_GENERIC, |
234 PLUS, CONST_INT)], i)) | |
235 break; | 235 break; |
236 | 236 |
237 gcc_assert (i < FIRST_PSEUDO_REGISTER); | 237 gcc_assert (i < FIRST_PSEUDO_REGISTER); |
238 | 238 |
239 addr_reg = gen_rtx_REG (Pmode, i); | 239 addr_reg = gen_rtx_REG (Pmode, i); |
240 | 240 |
241 for (offset = 1 << (HOST_BITS_PER_INT / 2); offset; offset >>= 1) | 241 for (offset = 1 << (HOST_BITS_PER_INT / 2); offset; offset >>= 1) |
242 { | 242 { |
243 address = gen_rtx_PLUS (Pmode, addr_reg, GEN_INT (offset)); | 243 address = gen_rtx_PLUS (Pmode, addr_reg, gen_int_mode (offset, Pmode)); |
244 | 244 |
245 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | 245 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) |
246 if (regno_save_mode[i][1] != VOIDmode | 246 if (regno_save_mode[i][1] != VOIDmode |
247 && ! strict_memory_address_p (regno_save_mode[i][1], address)) | 247 && ! strict_memory_address_p (regno_save_mode[i][1], address)) |
248 break; | 248 break; |
259 see if such an insn is recognized and meets its constraints. | 259 see if such an insn is recognized and meets its constraints. |
260 | 260 |
261 To avoid lots of unnecessary RTL allocation, we construct all the RTL | 261 To avoid lots of unnecessary RTL allocation, we construct all the RTL |
262 once, then modify the memory and register operands in-place. */ | 262 once, then modify the memory and register operands in-place. */ |
263 | 263 |
264 test_reg = gen_rtx_REG (VOIDmode, 0); | 264 test_reg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1); |
265 test_mem = gen_rtx_MEM (VOIDmode, address); | 265 test_mem = gen_rtx_MEM (word_mode, address); |
266 savepat = gen_rtx_SET (VOIDmode, test_mem, test_reg); | 266 savepat = gen_rtx_SET (test_mem, test_reg); |
267 restpat = gen_rtx_SET (VOIDmode, test_reg, test_mem); | 267 restpat = gen_rtx_SET (test_reg, test_mem); |
268 | 268 |
269 saveinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, savepat, 0, -1, 0); | 269 saveinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, savepat, 0, -1, 0); |
270 restinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, restpat, 0, -1, 0); | 270 restinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, restpat, 0, -1, 0); |
271 | 271 |
272 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | 272 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) |
273 for (j = 1; j <= MOVE_MAX_WORDS; j++) | 273 for (j = 1; j <= MOVE_MAX_WORDS; j++) |
274 if (reg_save_code (i,regno_save_mode[i][j]) == -1) | 274 if (reg_save_code (i,regno_save_mode[i][j]) == -1) |
275 { | 275 { |
344 hard_reg_map[i] = NULL; | 344 hard_reg_map[i] = NULL; |
345 } | 345 } |
346 | 346 |
347 /* Allocate and return new saved hard register with given REGNO and | 347 /* Allocate and return new saved hard register with given REGNO and |
348 CALL_FREQ. */ | 348 CALL_FREQ. */ |
349 static struct saved_hard_reg * | 349 static void |
350 new_saved_hard_reg (int regno, int call_freq) | 350 new_saved_hard_reg (int regno, int call_freq) |
351 { | 351 { |
352 struct saved_hard_reg *saved_reg; | 352 struct saved_hard_reg *saved_reg; |
353 | 353 |
354 saved_reg | 354 saved_reg |
357 saved_reg->num = saved_regs_num++; | 357 saved_reg->num = saved_regs_num++; |
358 saved_reg->hard_regno = regno; | 358 saved_reg->hard_regno = regno; |
359 saved_reg->call_freq = call_freq; | 359 saved_reg->call_freq = call_freq; |
360 saved_reg->first_p = FALSE; | 360 saved_reg->first_p = FALSE; |
361 saved_reg->next = -1; | 361 saved_reg->next = -1; |
362 return saved_reg; | |
363 } | 362 } |
364 | 363 |
365 /* Free memory allocated for the saved hard registers. */ | 364 /* Free memory allocated for the saved hard registers. */ |
366 static void | 365 static void |
367 finish_saved_hard_regs (void) | 366 finish_saved_hard_regs (void) |
417 setup_save_areas (void) | 416 setup_save_areas (void) |
418 { | 417 { |
419 int i, j, k, freq; | 418 int i, j, k, freq; |
420 HARD_REG_SET hard_regs_used; | 419 HARD_REG_SET hard_regs_used; |
421 struct saved_hard_reg *saved_reg; | 420 struct saved_hard_reg *saved_reg; |
422 rtx insn; | 421 rtx_insn *insn; |
423 struct insn_chain *chain, *next; | 422 struct insn_chain *chain, *next; |
424 unsigned int regno; | 423 unsigned int regno; |
425 HARD_REG_SET hard_regs_to_save, used_regs, this_insn_sets; | 424 HARD_REG_SET hard_regs_to_save, used_regs, this_insn_sets; |
426 reg_set_iterator rsi; | 425 reg_set_iterator rsi; |
427 | 426 |
431 call into HARD_REG_MAP and HARD_REGS_USED. */ | 430 call into HARD_REG_MAP and HARD_REGS_USED. */ |
432 initiate_saved_hard_regs (); | 431 initiate_saved_hard_regs (); |
433 /* Create hard reg saved regs. */ | 432 /* Create hard reg saved regs. */ |
434 for (chain = reload_insn_chain; chain != 0; chain = next) | 433 for (chain = reload_insn_chain; chain != 0; chain = next) |
435 { | 434 { |
435 rtx cheap; | |
436 | |
436 insn = chain->insn; | 437 insn = chain->insn; |
437 next = chain->next; | 438 next = chain->next; |
438 if (!CALL_P (insn) | 439 if (!CALL_P (insn) |
439 || find_reg_note (insn, REG_NORETURN, NULL)) | 440 || find_reg_note (insn, REG_NORETURN, NULL)) |
440 continue; | 441 continue; |
441 freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)); | 442 freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)); |
442 REG_SET_TO_HARD_REG_SET (hard_regs_to_save, | 443 REG_SET_TO_HARD_REG_SET (hard_regs_to_save, |
443 &chain->live_throughout); | 444 &chain->live_throughout); |
444 COPY_HARD_REG_SET (used_regs, call_used_reg_set); | 445 get_call_reg_set_usage (insn, &used_regs, call_used_reg_set); |
445 | 446 |
446 /* Record all registers set in this call insn. These don't | 447 /* Record all registers set in this call insn. These don't |
447 need to be saved. N.B. the call insn might set a subreg | 448 need to be saved. N.B. the call insn might set a subreg |
448 of a multi-hard-reg pseudo; then the pseudo is considered | 449 of a multi-hard-reg pseudo; then the pseudo is considered |
449 live during the call, but the subreg that is set | 450 live during the call, but the subreg that is set |
461 if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) | 462 if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) |
462 { | 463 { |
463 if (hard_reg_map[regno] != NULL) | 464 if (hard_reg_map[regno] != NULL) |
464 hard_reg_map[regno]->call_freq += freq; | 465 hard_reg_map[regno]->call_freq += freq; |
465 else | 466 else |
466 saved_reg = new_saved_hard_reg (regno, freq); | 467 new_saved_hard_reg (regno, freq); |
467 SET_HARD_REG_BIT (hard_regs_used, regno); | 468 SET_HARD_REG_BIT (hard_regs_used, regno); |
468 } | 469 } |
470 cheap = find_reg_note (insn, REG_RETURNED, NULL); | |
471 if (cheap) | |
472 cheap = XEXP (cheap, 0); | |
469 /* Look through all live pseudos, mark their hard registers. */ | 473 /* Look through all live pseudos, mark their hard registers. */ |
470 EXECUTE_IF_SET_IN_REG_SET | 474 EXECUTE_IF_SET_IN_REG_SET |
471 (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi) | 475 (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi) |
472 { | 476 { |
473 int r = reg_renumber[regno]; | 477 int r = reg_renumber[regno]; |
474 int bound; | 478 int bound; |
475 | 479 |
476 if (r < 0) | 480 if (r < 0 || regno_reg_rtx[regno] == cheap) |
477 continue; | 481 continue; |
478 | 482 |
479 bound = r + hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)]; | 483 bound = r + hard_regno_nregs (r, PSEUDO_REGNO_MODE (regno)); |
480 for (; r < bound; r++) | 484 for (; r < bound; r++) |
481 if (TEST_HARD_REG_BIT (used_regs, r)) | 485 if (TEST_HARD_REG_BIT (used_regs, r)) |
482 { | 486 { |
483 if (hard_reg_map[r] != NULL) | 487 if (hard_reg_map[r] != NULL) |
484 hard_reg_map[r]->call_freq += freq; | 488 hard_reg_map[r]->call_freq += freq; |
485 else | 489 else |
486 saved_reg = new_saved_hard_reg (r, freq); | 490 new_saved_hard_reg (r, freq); |
487 SET_HARD_REG_BIT (hard_regs_to_save, r); | 491 SET_HARD_REG_BIT (hard_regs_to_save, r); |
488 SET_HARD_REG_BIT (hard_regs_used, r); | 492 SET_HARD_REG_BIT (hard_regs_used, r); |
489 } | 493 } |
490 } | 494 } |
491 } | 495 } |
506 /* Find saved hard register conflicts. */ | 510 /* Find saved hard register conflicts. */ |
507 saved_reg_conflicts = (char *) xmalloc (saved_regs_num * saved_regs_num); | 511 saved_reg_conflicts = (char *) xmalloc (saved_regs_num * saved_regs_num); |
508 memset (saved_reg_conflicts, 0, saved_regs_num * saved_regs_num); | 512 memset (saved_reg_conflicts, 0, saved_regs_num * saved_regs_num); |
509 for (chain = reload_insn_chain; chain != 0; chain = next) | 513 for (chain = reload_insn_chain; chain != 0; chain = next) |
510 { | 514 { |
515 rtx cheap; | |
511 call_saved_regs_num = 0; | 516 call_saved_regs_num = 0; |
512 insn = chain->insn; | 517 insn = chain->insn; |
513 next = chain->next; | 518 next = chain->next; |
514 if (!CALL_P (insn) | 519 if (!CALL_P (insn) |
515 || find_reg_note (insn, REG_NORETURN, NULL)) | 520 || find_reg_note (insn, REG_NORETURN, NULL)) |
516 continue; | 521 continue; |
522 | |
523 cheap = find_reg_note (insn, REG_RETURNED, NULL); | |
524 if (cheap) | |
525 cheap = XEXP (cheap, 0); | |
526 | |
517 REG_SET_TO_HARD_REG_SET (hard_regs_to_save, | 527 REG_SET_TO_HARD_REG_SET (hard_regs_to_save, |
518 &chain->live_throughout); | 528 &chain->live_throughout); |
519 COPY_HARD_REG_SET (used_regs, call_used_reg_set); | 529 get_call_reg_set_usage (insn, &used_regs, call_used_reg_set); |
520 | 530 |
521 /* Record all registers set in this call insn. These don't | 531 /* Record all registers set in this call insn. These don't |
522 need to be saved. N.B. the call insn might set a subreg | 532 need to be saved. N.B. the call insn might set a subreg |
523 of a multi-hard-reg pseudo; then the pseudo is considered | 533 of a multi-hard-reg pseudo; then the pseudo is considered |
524 live during the call, but the subreg that is set | 534 live during the call, but the subreg that is set |
544 (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi) | 554 (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi) |
545 { | 555 { |
546 int r = reg_renumber[regno]; | 556 int r = reg_renumber[regno]; |
547 int bound; | 557 int bound; |
548 | 558 |
549 if (r < 0) | 559 if (r < 0 || regno_reg_rtx[regno] == cheap) |
550 continue; | 560 continue; |
551 | 561 |
552 bound = r + hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)]; | 562 bound = r + hard_regno_nregs (r, PSEUDO_REGNO_MODE (regno)); |
553 for (; r < bound; r++) | 563 for (; r < bound; r++) |
554 if (TEST_HARD_REG_BIT (used_regs, r)) | 564 if (TEST_HARD_REG_BIT (used_regs, r)) |
555 call_saved_regs[call_saved_regs_num++] = hard_reg_map[r]; | 565 call_saved_regs[call_saved_regs_num++] = hard_reg_map[r]; |
556 } | 566 } |
557 for (i = 0; i < call_saved_regs_num; i++) | 567 for (i = 0; i < call_saved_regs_num; i++) |
733 | 743 |
734 void | 744 void |
735 save_call_clobbered_regs (void) | 745 save_call_clobbered_regs (void) |
736 { | 746 { |
737 struct insn_chain *chain, *next, *last = NULL; | 747 struct insn_chain *chain, *next, *last = NULL; |
738 enum machine_mode save_mode [FIRST_PSEUDO_REGISTER]; | 748 machine_mode save_mode [FIRST_PSEUDO_REGISTER]; |
739 | 749 |
740 /* Computed in mark_set_regs, holds all registers set by the current | 750 /* Computed in mark_set_regs, holds all registers set by the current |
741 instruction. */ | 751 instruction. */ |
742 HARD_REG_SET this_insn_sets; | 752 HARD_REG_SET this_insn_sets; |
743 | 753 |
744 CLEAR_HARD_REG_SET (hard_regs_saved); | 754 CLEAR_HARD_REG_SET (hard_regs_saved); |
745 n_regs_saved = 0; | 755 n_regs_saved = 0; |
746 | 756 |
747 for (chain = reload_insn_chain; chain != 0; chain = next) | 757 for (chain = reload_insn_chain; chain != 0; chain = next) |
748 { | 758 { |
749 rtx insn = chain->insn; | 759 rtx_insn *insn = chain->insn; |
750 enum rtx_code code = GET_CODE (insn); | 760 enum rtx_code code = GET_CODE (insn); |
751 | 761 |
752 next = chain->next; | 762 next = chain->next; |
753 | 763 |
754 gcc_assert (!chain->is_caller_save_insn); | 764 gcc_assert (!chain->is_caller_save_insn); |
793 && ! SIBLING_CALL_P (insn) | 803 && ! SIBLING_CALL_P (insn) |
794 && ! find_reg_note (insn, REG_NORETURN, NULL)) | 804 && ! find_reg_note (insn, REG_NORETURN, NULL)) |
795 { | 805 { |
796 unsigned regno; | 806 unsigned regno; |
797 HARD_REG_SET hard_regs_to_save; | 807 HARD_REG_SET hard_regs_to_save; |
808 HARD_REG_SET call_def_reg_set; | |
798 reg_set_iterator rsi; | 809 reg_set_iterator rsi; |
810 rtx cheap; | |
811 | |
812 cheap = find_reg_note (insn, REG_RETURNED, NULL); | |
813 if (cheap) | |
814 cheap = XEXP (cheap, 0); | |
799 | 815 |
800 /* Use the register life information in CHAIN to compute which | 816 /* Use the register life information in CHAIN to compute which |
801 regs are live during the call. */ | 817 regs are live during the call. */ |
802 REG_SET_TO_HARD_REG_SET (hard_regs_to_save, | 818 REG_SET_TO_HARD_REG_SET (hard_regs_to_save, |
803 &chain->live_throughout); | 819 &chain->live_throughout); |
813 EXECUTE_IF_SET_IN_REG_SET | 829 EXECUTE_IF_SET_IN_REG_SET |
814 (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi) | 830 (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi) |
815 { | 831 { |
816 int r = reg_renumber[regno]; | 832 int r = reg_renumber[regno]; |
817 int nregs; | 833 int nregs; |
818 enum machine_mode mode; | 834 machine_mode mode; |
819 | 835 |
820 if (r < 0) | 836 if (r < 0 || regno_reg_rtx[regno] == cheap) |
821 continue; | 837 continue; |
822 nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)]; | 838 nregs = hard_regno_nregs (r, PSEUDO_REGNO_MODE (regno)); |
823 mode = HARD_REGNO_CALLER_SAVE_MODE | 839 mode = HARD_REGNO_CALLER_SAVE_MODE |
824 (r, nregs, PSEUDO_REGNO_MODE (regno)); | 840 (r, nregs, PSEUDO_REGNO_MODE (regno)); |
825 if (GET_MODE_BITSIZE (mode) | 841 if (partial_subreg_p (save_mode[r], mode)) |
826 > GET_MODE_BITSIZE (save_mode[r])) | |
827 save_mode[r] = mode; | 842 save_mode[r] = mode; |
828 while (nregs-- > 0) | 843 while (nregs-- > 0) |
829 SET_HARD_REG_BIT (hard_regs_to_save, r + nregs); | 844 SET_HARD_REG_BIT (hard_regs_to_save, r + nregs); |
830 } | 845 } |
831 | 846 |
838 | 853 |
839 /* Compute which hard regs must be saved before this call. */ | 854 /* Compute which hard regs must be saved before this call. */ |
840 AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set); | 855 AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set); |
841 AND_COMPL_HARD_REG_SET (hard_regs_to_save, this_insn_sets); | 856 AND_COMPL_HARD_REG_SET (hard_regs_to_save, this_insn_sets); |
842 AND_COMPL_HARD_REG_SET (hard_regs_to_save, hard_regs_saved); | 857 AND_COMPL_HARD_REG_SET (hard_regs_to_save, hard_regs_saved); |
843 AND_HARD_REG_SET (hard_regs_to_save, call_used_reg_set); | 858 get_call_reg_set_usage (insn, &call_def_reg_set, |
859 call_used_reg_set); | |
860 AND_HARD_REG_SET (hard_regs_to_save, call_def_reg_set); | |
844 | 861 |
845 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) | 862 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) |
846 if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) | 863 if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) |
847 regno += insert_save (chain, 1, regno, &hard_regs_to_save, save_mode); | 864 regno += insert_save (chain, 1, regno, &hard_regs_to_save, save_mode); |
848 | 865 |
849 /* Must recompute n_regs_saved. */ | 866 /* Must recompute n_regs_saved. */ |
850 n_regs_saved = 0; | 867 n_regs_saved = 0; |
851 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) | 868 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) |
852 if (TEST_HARD_REG_BIT (hard_regs_saved, regno)) | 869 if (TEST_HARD_REG_BIT (hard_regs_saved, regno)) |
853 n_regs_saved++; | 870 n_regs_saved++; |
871 | |
872 if (cheap | |
873 && HARD_REGISTER_P (cheap) | |
874 && TEST_HARD_REG_BIT (call_used_reg_set, REGNO (cheap))) | |
875 { | |
876 rtx dest, newpat; | |
877 rtx pat = PATTERN (insn); | |
878 if (GET_CODE (pat) == PARALLEL) | |
879 pat = XVECEXP (pat, 0, 0); | |
880 dest = SET_DEST (pat); | |
881 /* For multiple return values dest is PARALLEL. | |
882 Currently we handle only single return value case. */ | |
883 if (REG_P (dest)) | |
884 { | |
885 newpat = gen_rtx_SET (cheap, copy_rtx (dest)); | |
886 chain = insert_one_insn (chain, 0, -1, newpat); | |
887 } | |
888 } | |
854 } | 889 } |
855 last = chain; | 890 last = chain; |
856 } | 891 } |
857 else if (DEBUG_INSN_P (insn) && n_regs_saved) | 892 else if (DEBUG_INSN_P (insn) && n_regs_saved) |
858 mark_referenced_regs (&PATTERN (insn), | 893 mark_referenced_regs (&PATTERN (insn), |
869 if (n_regs_saved | 904 if (n_regs_saved |
870 && DEBUG_INSN_P (insn) | 905 && DEBUG_INSN_P (insn) |
871 && last | 906 && last |
872 && last->block == chain->block) | 907 && last->block == chain->block) |
873 { | 908 { |
874 rtx ins, prev; | 909 rtx_insn *ins, *prev; |
875 basic_block bb = BLOCK_FOR_INSN (insn); | 910 basic_block bb = BLOCK_FOR_INSN (insn); |
876 | 911 |
877 /* When adding hard reg restores after a DEBUG_INSN, move | 912 /* When adding hard reg restores after a DEBUG_INSN, move |
878 all notes between last real insn and this DEBUG_INSN after | 913 all notes between last real insn and this DEBUG_INSN after |
879 the DEBUG_INSN, otherwise we could get code | 914 the DEBUG_INSN, otherwise we could get code |
881 for (ins = PREV_INSN (insn); ins != last->insn; ins = prev) | 916 for (ins = PREV_INSN (insn); ins != last->insn; ins = prev) |
882 { | 917 { |
883 prev = PREV_INSN (ins); | 918 prev = PREV_INSN (ins); |
884 if (NOTE_P (ins)) | 919 if (NOTE_P (ins)) |
885 { | 920 { |
886 NEXT_INSN (prev) = NEXT_INSN (ins); | 921 SET_NEXT_INSN (prev) = NEXT_INSN (ins); |
887 PREV_INSN (NEXT_INSN (ins)) = prev; | 922 SET_PREV_INSN (NEXT_INSN (ins)) = prev; |
888 PREV_INSN (ins) = insn; | 923 SET_PREV_INSN (ins) = insn; |
889 NEXT_INSN (ins) = NEXT_INSN (insn); | 924 SET_NEXT_INSN (ins) = NEXT_INSN (insn); |
890 NEXT_INSN (insn) = ins; | 925 SET_NEXT_INSN (insn) = ins; |
891 if (NEXT_INSN (ins)) | 926 if (NEXT_INSN (ins)) |
892 PREV_INSN (NEXT_INSN (ins)) = ins; | 927 SET_PREV_INSN (NEXT_INSN (ins)) = ins; |
893 if (BB_END (bb) == insn) | 928 if (BB_END (bb) == insn) |
894 BB_END (bb) = ins; | 929 BB_END (bb) = ins; |
895 } | 930 } |
896 else | 931 else |
897 gcc_assert (DEBUG_INSN_P (ins)); | 932 gcc_assert (DEBUG_INSN_P (ins)); |
929 } | 964 } |
930 else if (REG_P (reg) | 965 else if (REG_P (reg) |
931 && REGNO (reg) < FIRST_PSEUDO_REGISTER) | 966 && REGNO (reg) < FIRST_PSEUDO_REGISTER) |
932 { | 967 { |
933 regno = REGNO (reg); | 968 regno = REGNO (reg); |
934 endregno = END_HARD_REGNO (reg); | 969 endregno = END_REGNO (reg); |
935 } | 970 } |
936 else | 971 else |
937 return; | 972 return; |
938 | 973 |
939 for (i = regno; i < endregno; i++) | 974 for (i = regno; i < endregno; i++) |
946 so we can ignore pseudos. */ | 981 so we can ignore pseudos. */ |
947 static void | 982 static void |
948 add_stored_regs (rtx reg, const_rtx setter, void *data) | 983 add_stored_regs (rtx reg, const_rtx setter, void *data) |
949 { | 984 { |
950 int regno, endregno, i; | 985 int regno, endregno, i; |
951 enum machine_mode mode = GET_MODE (reg); | 986 machine_mode mode = GET_MODE (reg); |
952 int offset = 0; | 987 int offset = 0; |
953 | 988 |
954 if (GET_CODE (setter) == CLOBBER) | 989 if (GET_CODE (setter) == CLOBBER) |
955 return; | 990 return; |
956 | 991 |
997 || (code == SUBREG && REG_P (SUBREG_REG (*loc)) | 1032 || (code == SUBREG && REG_P (SUBREG_REG (*loc)) |
998 && REGNO (SUBREG_REG (*loc)) < FIRST_PSEUDO_REGISTER | 1033 && REGNO (SUBREG_REG (*loc)) < FIRST_PSEUDO_REGISTER |
999 /* If we're setting only part of a multi-word register, | 1034 /* If we're setting only part of a multi-word register, |
1000 we shall mark it as referenced, because the words | 1035 we shall mark it as referenced, because the words |
1001 that are not being set should be restored. */ | 1036 that are not being set should be restored. */ |
1002 && ((GET_MODE_SIZE (GET_MODE (*loc)) | 1037 && !read_modify_subreg_p (*loc))) |
1003 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (*loc)))) | |
1004 || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (*loc))) | |
1005 <= UNITS_PER_WORD)))) | |
1006 return; | 1038 return; |
1007 } | 1039 } |
1008 if (code == MEM || code == SUBREG) | 1040 if (code == MEM || code == SUBREG) |
1009 { | 1041 { |
1010 loc = &XEXP (*loc, 0); | 1042 loc = &XEXP (*loc, 0); |
1025 reload take care of it for us? */ | 1057 reload take care of it for us? */ |
1026 return; | 1058 return; |
1027 /* If this is a pseudo that did not get a hard register, scan its | 1059 /* If this is a pseudo that did not get a hard register, scan its |
1028 memory location, since it might involve the use of another | 1060 memory location, since it might involve the use of another |
1029 register, which might be saved. */ | 1061 register, which might be saved. */ |
1030 else if (reg_equiv_mem[regno] != 0) | 1062 else if (reg_equiv_mem (regno) != 0) |
1031 mark_referenced_regs (&XEXP (reg_equiv_mem[regno], 0), mark, arg); | 1063 mark_referenced_regs (&XEXP (reg_equiv_mem (regno), 0), mark, arg); |
1032 else if (reg_equiv_address[regno] != 0) | 1064 else if (reg_equiv_address (regno) != 0) |
1033 mark_referenced_regs (®_equiv_address[regno], mark, arg); | 1065 mark_referenced_regs (®_equiv_address (regno), mark, arg); |
1034 return; | 1066 return; |
1035 } | 1067 } |
1036 | 1068 |
1037 fmt = GET_RTX_FORMAT (code); | 1069 fmt = GET_RTX_FORMAT (code); |
1038 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) | 1070 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) |
1049 present in the insn and in equivalent mems and addresses to | 1081 present in the insn and in equivalent mems and addresses to |
1050 referenced_regs. */ | 1082 referenced_regs. */ |
1051 | 1083 |
1052 static void | 1084 static void |
1053 mark_reg_as_referenced (rtx *loc ATTRIBUTE_UNUSED, | 1085 mark_reg_as_referenced (rtx *loc ATTRIBUTE_UNUSED, |
1054 enum machine_mode mode, | 1086 machine_mode mode, |
1055 int hardregno, | 1087 int hardregno, |
1056 void *arg ATTRIBUTE_UNUSED) | 1088 void *arg ATTRIBUTE_UNUSED) |
1057 { | 1089 { |
1058 add_to_hard_reg_set (&referenced_regs, mode, hardregno); | 1090 add_to_hard_reg_set (&referenced_regs, mode, hardregno); |
1059 } | 1091 } |
1062 registers referenced in a debug_insn that would have been restored, | 1094 registers referenced in a debug_insn that would have been restored, |
1063 should it be a non-debug_insn, with their save locations. */ | 1095 should it be a non-debug_insn, with their save locations. */ |
1064 | 1096 |
1065 static void | 1097 static void |
1066 replace_reg_with_saved_mem (rtx *loc, | 1098 replace_reg_with_saved_mem (rtx *loc, |
1067 enum machine_mode mode, | 1099 machine_mode mode, |
1068 int regno, | 1100 int regno, |
1069 void *arg) | 1101 void *arg) |
1070 { | 1102 { |
1071 unsigned int i, nregs = hard_regno_nregs [regno][mode]; | 1103 unsigned int i, nregs = hard_regno_nregs (regno, mode); |
1072 rtx mem; | 1104 rtx mem; |
1073 enum machine_mode *save_mode = (enum machine_mode *)arg; | 1105 machine_mode *save_mode = (machine_mode *)arg; |
1074 | 1106 |
1075 for (i = 0; i < nregs; i++) | 1107 for (i = 0; i < nregs; i++) |
1076 if (TEST_HARD_REG_BIT (hard_regs_saved, regno + i)) | 1108 if (TEST_HARD_REG_BIT (hard_regs_saved, regno + i)) |
1077 break; | 1109 break; |
1078 | 1110 |
1088 if (i == nregs | 1120 if (i == nregs |
1089 && regno_save_mem[regno][nregs]) | 1121 && regno_save_mem[regno][nregs]) |
1090 { | 1122 { |
1091 mem = copy_rtx (regno_save_mem[regno][nregs]); | 1123 mem = copy_rtx (regno_save_mem[regno][nregs]); |
1092 | 1124 |
1093 if (nregs == (unsigned int) hard_regno_nregs[regno][save_mode[regno]]) | 1125 if (nregs == hard_regno_nregs (regno, save_mode[regno])) |
1094 mem = adjust_address_nv (mem, save_mode[regno], 0); | 1126 mem = adjust_address_nv (mem, save_mode[regno], 0); |
1095 | 1127 |
1096 if (GET_MODE (mem) != mode) | 1128 if (GET_MODE (mem) != mode) |
1097 { | 1129 { |
1098 /* This is gen_lowpart_if_possible(), but without validating | 1130 /* This is gen_lowpart_if_possible(), but without validating |
1099 the newly-formed address. */ | 1131 the newly-formed address. */ |
1100 int offset = 0; | 1132 HOST_WIDE_INT offset = byte_lowpart_offset (mode, GET_MODE (mem)); |
1101 | |
1102 if (WORDS_BIG_ENDIAN) | |
1103 offset = (MAX (GET_MODE_SIZE (GET_MODE (mem)), UNITS_PER_WORD) | |
1104 - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)); | |
1105 if (BYTES_BIG_ENDIAN) | |
1106 /* Adjust the address so that the address-after-the-data is | |
1107 unchanged. */ | |
1108 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)) | |
1109 - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (mem)))); | |
1110 | |
1111 mem = adjust_address_nv (mem, mode, offset); | 1133 mem = adjust_address_nv (mem, mode, offset); |
1112 } | 1134 } |
1113 } | 1135 } |
1114 else | 1136 else |
1115 { | 1137 { |
1120 gcc_assert (regno_save_mem[regno + i][1]); | 1142 gcc_assert (regno_save_mem[regno + i][1]); |
1121 XVECEXP (mem, 0, i) = copy_rtx (regno_save_mem[regno + i][1]); | 1143 XVECEXP (mem, 0, i) = copy_rtx (regno_save_mem[regno + i][1]); |
1122 } | 1144 } |
1123 else | 1145 else |
1124 { | 1146 { |
1125 gcc_assert (save_mode[regno] != VOIDmode); | 1147 machine_mode smode = save_mode[regno]; |
1126 XVECEXP (mem, 0, i) = gen_rtx_REG (save_mode [regno], | 1148 gcc_assert (smode != VOIDmode); |
1127 regno + i); | 1149 if (hard_regno_nregs (regno, smode) > 1) |
1150 smode = mode_for_size (GET_MODE_SIZE (mode) / nregs, | |
1151 GET_MODE_CLASS (mode), 0).require (); | |
1152 XVECEXP (mem, 0, i) = gen_rtx_REG (smode, regno + i); | |
1128 } | 1153 } |
1129 } | 1154 } |
1130 | 1155 |
1131 gcc_assert (GET_MODE (mem) == mode); | 1156 gcc_assert (GET_MODE (mem) == mode); |
1132 *loc = mem; | 1157 *loc = mem; |
1146 | 1171 |
1147 Return the extra number of registers saved. */ | 1172 Return the extra number of registers saved. */ |
1148 | 1173 |
1149 static int | 1174 static int |
1150 insert_restore (struct insn_chain *chain, int before_p, int regno, | 1175 insert_restore (struct insn_chain *chain, int before_p, int regno, |
1151 int maxrestore, enum machine_mode *save_mode) | 1176 int maxrestore, machine_mode *save_mode) |
1152 { | 1177 { |
1153 int i, k; | 1178 int i, k; |
1154 rtx pat = NULL_RTX; | 1179 rtx pat = NULL_RTX; |
1155 int code; | 1180 int code; |
1156 unsigned int numregs = 0; | 1181 unsigned int numregs = 0; |
1192 } | 1217 } |
1193 | 1218 |
1194 mem = regno_save_mem [regno][numregs]; | 1219 mem = regno_save_mem [regno][numregs]; |
1195 if (save_mode [regno] != VOIDmode | 1220 if (save_mode [regno] != VOIDmode |
1196 && save_mode [regno] != GET_MODE (mem) | 1221 && save_mode [regno] != GET_MODE (mem) |
1197 && numregs == (unsigned int) hard_regno_nregs[regno][save_mode [regno]] | 1222 && numregs == hard_regno_nregs (regno, save_mode [regno]) |
1198 /* Check that insn to restore REGNO in save_mode[regno] is | 1223 /* Check that insn to restore REGNO in save_mode[regno] is |
1199 correct. */ | 1224 correct. */ |
1200 && reg_save_code (regno, save_mode[regno]) >= 0) | 1225 && reg_save_code (regno, save_mode[regno]) >= 0) |
1201 mem = adjust_address_nv (mem, save_mode[regno], 0); | 1226 mem = adjust_address_nv (mem, save_mode[regno], 0); |
1202 else | 1227 else |
1205 /* Verify that the alignment of spill space is equal to or greater | 1230 /* Verify that the alignment of spill space is equal to or greater |
1206 than required. */ | 1231 than required. */ |
1207 gcc_assert (MIN (MAX_SUPPORTED_STACK_ALIGNMENT, | 1232 gcc_assert (MIN (MAX_SUPPORTED_STACK_ALIGNMENT, |
1208 GET_MODE_ALIGNMENT (GET_MODE (mem))) <= MEM_ALIGN (mem)); | 1233 GET_MODE_ALIGNMENT (GET_MODE (mem))) <= MEM_ALIGN (mem)); |
1209 | 1234 |
1210 pat = gen_rtx_SET (VOIDmode, | 1235 pat = gen_rtx_SET (gen_rtx_REG (GET_MODE (mem), regno), mem); |
1211 gen_rtx_REG (GET_MODE (mem), | |
1212 regno), mem); | |
1213 code = reg_restore_code (regno, GET_MODE (mem)); | 1236 code = reg_restore_code (regno, GET_MODE (mem)); |
1214 new_chain = insert_one_insn (chain, before_p, code, pat); | 1237 new_chain = insert_one_insn (chain, before_p, code, pat); |
1215 | 1238 |
1216 /* Clear status for all registers we restored. */ | 1239 /* Clear status for all registers we restored. */ |
1217 for (k = 0; k < i; k++) | 1240 for (k = 0; k < i; k++) |
1227 | 1250 |
1228 /* Like insert_restore above, but save registers instead. */ | 1251 /* Like insert_restore above, but save registers instead. */ |
1229 | 1252 |
1230 static int | 1253 static int |
1231 insert_save (struct insn_chain *chain, int before_p, int regno, | 1254 insert_save (struct insn_chain *chain, int before_p, int regno, |
1232 HARD_REG_SET (*to_save), enum machine_mode *save_mode) | 1255 HARD_REG_SET *to_save, machine_mode *save_mode) |
1233 { | 1256 { |
1234 int i; | 1257 int i; |
1235 unsigned int k; | 1258 unsigned int k; |
1236 rtx pat = NULL_RTX; | 1259 rtx pat = NULL_RTX; |
1237 int code; | 1260 int code; |
1273 } | 1296 } |
1274 | 1297 |
1275 mem = regno_save_mem [regno][numregs]; | 1298 mem = regno_save_mem [regno][numregs]; |
1276 if (save_mode [regno] != VOIDmode | 1299 if (save_mode [regno] != VOIDmode |
1277 && save_mode [regno] != GET_MODE (mem) | 1300 && save_mode [regno] != GET_MODE (mem) |
1278 && numregs == (unsigned int) hard_regno_nregs[regno][save_mode [regno]] | 1301 && numregs == hard_regno_nregs (regno, save_mode [regno]) |
1279 /* Check that insn to save REGNO in save_mode[regno] is | 1302 /* Check that insn to save REGNO in save_mode[regno] is |
1280 correct. */ | 1303 correct. */ |
1281 && reg_save_code (regno, save_mode[regno]) >= 0) | 1304 && reg_save_code (regno, save_mode[regno]) >= 0) |
1282 mem = adjust_address_nv (mem, save_mode[regno], 0); | 1305 mem = adjust_address_nv (mem, save_mode[regno], 0); |
1283 else | 1306 else |
1286 /* Verify that the alignment of spill space is equal to or greater | 1309 /* Verify that the alignment of spill space is equal to or greater |
1287 than required. */ | 1310 than required. */ |
1288 gcc_assert (MIN (MAX_SUPPORTED_STACK_ALIGNMENT, | 1311 gcc_assert (MIN (MAX_SUPPORTED_STACK_ALIGNMENT, |
1289 GET_MODE_ALIGNMENT (GET_MODE (mem))) <= MEM_ALIGN (mem)); | 1312 GET_MODE_ALIGNMENT (GET_MODE (mem))) <= MEM_ALIGN (mem)); |
1290 | 1313 |
1291 pat = gen_rtx_SET (VOIDmode, mem, | 1314 pat = gen_rtx_SET (mem, gen_rtx_REG (GET_MODE (mem), regno)); |
1292 gen_rtx_REG (GET_MODE (mem), | |
1293 regno)); | |
1294 code = reg_save_code (regno, GET_MODE (mem)); | 1315 code = reg_save_code (regno, GET_MODE (mem)); |
1295 new_chain = insert_one_insn (chain, before_p, code, pat); | 1316 new_chain = insert_one_insn (chain, before_p, code, pat); |
1296 | 1317 |
1297 /* Set hard_regs_saved and dead_or_set for all the registers we saved. */ | 1318 /* Set hard_regs_saved and dead_or_set for all the registers we saved. */ |
1298 for (k = 0; k < numregs; k++) | 1319 for (k = 0; k < numregs; k++) |
1304 | 1325 |
1305 /* Tell our callers how many extra registers we saved/restored. */ | 1326 /* Tell our callers how many extra registers we saved/restored. */ |
1306 return numregs - 1; | 1327 return numregs - 1; |
1307 } | 1328 } |
1308 | 1329 |
1309 /* A for_each_rtx callback used by add_used_regs. Add the hard-register | |
1310 equivalent of each REG to regset DATA. */ | |
1311 | |
1312 static int | |
1313 add_used_regs_1 (rtx *loc, void *data) | |
1314 { | |
1315 int regno, i; | |
1316 regset live; | |
1317 rtx x; | |
1318 | |
1319 x = *loc; | |
1320 live = (regset) data; | |
1321 if (REG_P (x)) | |
1322 { | |
1323 regno = REGNO (x); | |
1324 if (!HARD_REGISTER_NUM_P (regno)) | |
1325 regno = reg_renumber[regno]; | |
1326 if (regno >= 0) | |
1327 for (i = hard_regno_nregs[regno][GET_MODE (x)] - 1; i >= 0; i--) | |
1328 SET_REGNO_REG_SET (live, regno + i); | |
1329 } | |
1330 return 0; | |
1331 } | |
1332 | |
1333 /* A note_uses callback used by insert_one_insn. Add the hard-register | 1330 /* A note_uses callback used by insert_one_insn. Add the hard-register |
1334 equivalent of each REG to regset DATA. */ | 1331 equivalent of each REG to regset DATA. */ |
1335 | 1332 |
1336 static void | 1333 static void |
1337 add_used_regs (rtx *loc, void *data) | 1334 add_used_regs (rtx *loc, void *data) |
1338 { | 1335 { |
1339 for_each_rtx (loc, add_used_regs_1, data); | 1336 subrtx_iterator::array_type array; |
1337 FOR_EACH_SUBRTX (iter, array, *loc, NONCONST) | |
1338 { | |
1339 const_rtx x = *iter; | |
1340 if (REG_P (x)) | |
1341 { | |
1342 unsigned int regno = REGNO (x); | |
1343 if (HARD_REGISTER_NUM_P (regno)) | |
1344 bitmap_set_range ((regset) data, regno, REG_NREGS (x)); | |
1345 else | |
1346 gcc_checking_assert (reg_renumber[regno] < 0); | |
1347 } | |
1348 } | |
1340 } | 1349 } |
1341 | 1350 |
1342 /* Emit a new caller-save insn and set the code. */ | 1351 /* Emit a new caller-save insn and set the code. */ |
1343 static struct insn_chain * | 1352 static struct insn_chain * |
1344 insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat) | 1353 insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat) |
1345 { | 1354 { |
1346 rtx insn = chain->insn; | 1355 rtx_insn *insn = chain->insn; |
1347 struct insn_chain *new_chain; | 1356 struct insn_chain *new_chain; |
1348 | 1357 |
1349 #ifdef HAVE_cc0 | |
1350 /* If INSN references CC0, put our insns in front of the insn that sets | 1358 /* If INSN references CC0, put our insns in front of the insn that sets |
1351 CC0. This is always safe, since the only way we could be passed an | 1359 CC0. This is always safe, since the only way we could be passed an |
1352 insn that references CC0 is for a restore, and doing a restore earlier | 1360 insn that references CC0 is for a restore, and doing a restore earlier |
1353 isn't a problem. We do, however, assume here that CALL_INSNs don't | 1361 isn't a problem. We do, however, assume here that CALL_INSNs don't |
1354 reference CC0. Guard against non-INSN's like CODE_LABEL. */ | 1362 reference CC0. Guard against non-INSN's like CODE_LABEL. */ |
1355 | 1363 |
1356 if ((NONJUMP_INSN_P (insn) || JUMP_P (insn)) | 1364 if (HAVE_cc0 && (NONJUMP_INSN_P (insn) || JUMP_P (insn)) |
1357 && before_p | 1365 && before_p |
1358 && reg_referenced_p (cc0_rtx, PATTERN (insn))) | 1366 && reg_referenced_p (cc0_rtx, PATTERN (insn))) |
1359 chain = chain->prev, insn = chain->insn; | 1367 chain = chain->prev, insn = chain->insn; |
1360 #endif | |
1361 | 1368 |
1362 new_chain = new_insn_chain (); | 1369 new_chain = new_insn_chain (); |
1363 if (before_p) | 1370 if (before_p) |
1364 { | 1371 { |
1365 rtx link; | 1372 rtx link; |
1386 link = XEXP (link, 1)) | 1393 link = XEXP (link, 1)) |
1387 note_uses (&XEXP (link, 0), add_used_regs, | 1394 note_uses (&XEXP (link, 0), add_used_regs, |
1388 &new_chain->live_throughout); | 1395 &new_chain->live_throughout); |
1389 | 1396 |
1390 CLEAR_REG_SET (&new_chain->dead_or_set); | 1397 CLEAR_REG_SET (&new_chain->dead_or_set); |
1391 if (chain->insn == BB_HEAD (BASIC_BLOCK (chain->block))) | 1398 if (chain->insn == BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, chain->block))) |
1392 BB_HEAD (BASIC_BLOCK (chain->block)) = new_chain->insn; | 1399 BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, chain->block)) = new_chain->insn; |
1393 } | 1400 } |
1394 else | 1401 else |
1395 { | 1402 { |
1396 new_chain->next = chain->next; | 1403 new_chain->next = chain->next; |
1397 if (new_chain->next != 0) | 1404 if (new_chain->next != 0) |
1406 (Unless there is a REG_UNUSED note for them, but we don't | 1413 (Unless there is a REG_UNUSED note for them, but we don't |
1407 look for them here.) */ | 1414 look for them here.) */ |
1408 note_stores (PATTERN (chain->insn), add_stored_regs, | 1415 note_stores (PATTERN (chain->insn), add_stored_regs, |
1409 &new_chain->live_throughout); | 1416 &new_chain->live_throughout); |
1410 CLEAR_REG_SET (&new_chain->dead_or_set); | 1417 CLEAR_REG_SET (&new_chain->dead_or_set); |
1411 if (chain->insn == BB_END (BASIC_BLOCK (chain->block))) | 1418 if (chain->insn == BB_END (BASIC_BLOCK_FOR_FN (cfun, chain->block))) |
1412 BB_END (BASIC_BLOCK (chain->block)) = new_chain->insn; | 1419 BB_END (BASIC_BLOCK_FOR_FN (cfun, chain->block)) = new_chain->insn; |
1413 } | 1420 } |
1414 new_chain->block = chain->block; | 1421 new_chain->block = chain->block; |
1415 new_chain->is_caller_save_insn = 1; | 1422 new_chain->is_caller_save_insn = 1; |
1416 | 1423 |
1417 INSN_CODE (new_chain->insn) = code; | 1424 INSN_CODE (new_chain->insn) = code; |