]>
Commit | Line | Data |
---|---|---|
c5986054 | 1 | /* Save and restore call-clobbered registers which are live across a call. |
517cbe13 | 2 | Copyright (C) 1989, 1992, 1994, 1995, 1997, 1998, |
e146f815 | 3 | 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. |
c5986054 | 4 | |
1322177d | 5 | This file is part of GCC. |
c5986054 | 6 | |
1322177d LB |
7 | GCC is free software; you can redistribute it and/or modify it under |
8 | the terms of the GNU General Public License as published by the Free | |
9 | Software Foundation; either version 2, or (at your option) any later | |
10 | version. | |
c5986054 | 11 | |
1322177d LB |
12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | for more details. | |
c5986054 RS |
16 | |
17 | You should have received a copy of the GNU General Public License | |
1322177d LB |
18 | along with GCC; see the file COPYING. If not, write to the Free |
19 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |
20 | 02111-1307, USA. */ | |
c5986054 RS |
21 | |
22 | #include "config.h" | |
670ee920 | 23 | #include "system.h" |
4977bab6 ZW |
24 | #include "coretypes.h" |
25 | #include "tm.h" | |
c5986054 | 26 | #include "rtl.h" |
7932a3db | 27 | #include "regs.h" |
c5986054 RS |
28 | #include "insn-config.h" |
29 | #include "flags.h" | |
c5986054 RS |
30 | #include "hard-reg-set.h" |
31 | #include "recog.h" | |
32 | #include "basic-block.h" | |
33 | #include "reload.h" | |
49ad7cfa | 34 | #include "function.h" |
c5986054 | 35 | #include "expr.h" |
2e107e9e | 36 | #include "toplev.h" |
63290521 | 37 | #include "tm_p.h" |
c5986054 | 38 | |
dc17cfda DE |
39 | #ifndef MAX_MOVE_MAX |
40 | #define MAX_MOVE_MAX MOVE_MAX | |
41 | #endif | |
42 | ||
ef0e53ce RK |
43 | #ifndef MIN_UNITS_PER_WORD |
44 | #define MIN_UNITS_PER_WORD UNITS_PER_WORD | |
dc17cfda DE |
45 | #endif |
46 | ||
7609e720 BS |
47 | #define MOVE_MAX_WORDS (MOVE_MAX / UNITS_PER_WORD) |
48 | ||
f95361c8 JL |
49 | /* Modes for each hard register that we can save. The smallest mode is wide |
50 | enough to save the entire contents of the register. When saving the | |
51 | register because it is live we first try to save in multi-register modes. | |
52 | If that is not possible the save is done one register at a time. */ | |
c5986054 | 53 | |
d329e058 | 54 | static enum machine_mode |
ef0e53ce | 55 | regno_save_mode[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1]; |
c5986054 RS |
56 | |
57 | /* For each hard register, a place on the stack where it can be saved, | |
58 | if needed. */ | |
59 | ||
d329e058 | 60 | static rtx |
ef0e53ce | 61 | regno_save_mem[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1]; |
c5986054 RS |
62 | |
63 | /* We will only make a register eligible for caller-save if it can be | |
64 | saved in its widest mode with a simple SET insn as long as the memory | |
65 | address is valid. We record the INSN_CODE is those insns here since | |
66 | when we emit them, the addresses might not be valid, so they might not | |
67 | be recognized. */ | |
68 | ||
830a47ec | 69 | static int |
787dc842 | 70 | reg_save_code[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE]; |
d329e058 | 71 | static int |
787dc842 | 72 | reg_restore_code[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE]; |
c5986054 | 73 | |
c5986054 RS |
74 | /* Set of hard regs currently residing in save area (during insn scan). */ |
75 | ||
76 | static HARD_REG_SET hard_regs_saved; | |
77 | ||
7609e720 | 78 | /* Number of registers currently in hard_regs_saved. */ |
f95361c8 | 79 | |
7609e720 | 80 | static int n_regs_saved; |
f95361c8 | 81 | |
7609e720 BS |
82 | /* Computed by mark_referenced_regs, all regs referenced in a given |
83 | insn. */ | |
84 | static HARD_REG_SET referenced_regs; | |
c5986054 | 85 | |
7609e720 BS |
86 | /* Computed in mark_set_regs, holds all registers set by the current |
87 | instruction. */ | |
88 | static HARD_REG_SET this_insn_sets; | |
c5986054 | 89 | |
7609e720 | 90 | |
d329e058 AJ |
91 | static void mark_set_regs (rtx, rtx, void *); |
92 | static void mark_referenced_regs (rtx); | |
93 | static int insert_save (struct insn_chain *, int, int, HARD_REG_SET *, | |
94 | enum machine_mode *); | |
95 | static int insert_restore (struct insn_chain *, int, int, int, | |
96 | enum machine_mode *); | |
97 | static struct insn_chain *insert_one_insn (struct insn_chain *, int, int, | |
98 | rtx); | |
99 | static void add_stored_regs (rtx, rtx, void *); | |
c5986054 | 100 | \f |
c5986054 RS |
101 | /* Initialize for caller-save. |
102 | ||
103 | Look at all the hard registers that are used by a call and for which | |
104 | regclass.c has not already excluded from being used across a call. | |
105 | ||
d329e058 | 106 | Ensure that we can find a mode to save the register and that there is a |
c5986054 RS |
107 | simple insn to save and restore the register. This latter check avoids |
108 | problems that would occur if we tried to save the MQ register of some | |
109 | machines directly into memory. */ | |
110 | ||
111 | void | |
d329e058 | 112 | init_caller_save (void) |
c5986054 | 113 | { |
c5986054 RS |
114 | rtx addr_reg; |
115 | int offset; | |
116 | rtx address; | |
f95361c8 | 117 | int i, j; |
787dc842 | 118 | enum machine_mode mode; |
bf1660a6 JL |
119 | rtx savepat, restpat; |
120 | rtx test_reg, test_mem; | |
121 | rtx saveinsn, restinsn; | |
c5986054 RS |
122 | |
123 | /* First find all the registers that we need to deal with and all | |
124 | the modes that they can have. If we can't find a mode to use, | |
125 | we can't have the register live over calls. */ | |
126 | ||
127 | for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
128 | { | |
129 | if (call_used_regs[i] && ! call_fixed_regs[i]) | |
130 | { | |
7609e720 | 131 | for (j = 1; j <= MOVE_MAX_WORDS; j++) |
c5986054 | 132 | { |
787dc842 JH |
133 | regno_save_mode[i][j] = HARD_REGNO_CALLER_SAVE_MODE (i, j, |
134 | VOIDmode); | |
f95361c8 JL |
135 | if (regno_save_mode[i][j] == VOIDmode && j == 1) |
136 | { | |
137 | call_fixed_regs[i] = 1; | |
138 | SET_HARD_REG_BIT (call_fixed_reg_set, i); | |
139 | } | |
c5986054 RS |
140 | } |
141 | } | |
142 | else | |
f95361c8 | 143 | regno_save_mode[i][1] = VOIDmode; |
c5986054 RS |
144 | } |
145 | ||
146 | /* The following code tries to approximate the conditions under which | |
147 | we can easily save and restore a register without scratch registers or | |
148 | other complexities. It will usually work, except under conditions where | |
149 | the validity of an insn operand is dependent on the address offset. | |
150 | No such cases are currently known. | |
151 | ||
152 | We first find a typical offset from some BASE_REG_CLASS register. | |
153 | This address is chosen by finding the first register in the class | |
154 | and by finding the smallest power of two that is a valid offset from | |
155 | that register in every mode we will use to save registers. */ | |
156 | ||
157 | for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
3dcc68a4 NC |
158 | if (TEST_HARD_REG_BIT |
159 | (reg_class_contents | |
160 | [(int) MODE_BASE_REG_CLASS (regno_save_mode [i][1])], i)) | |
c5986054 RS |
161 | break; |
162 | ||
366de0ce | 163 | gcc_assert (i < FIRST_PSEUDO_REGISTER); |
c5986054 | 164 | |
38a448ca | 165 | addr_reg = gen_rtx_REG (Pmode, i); |
c5986054 RS |
166 | |
167 | for (offset = 1 << (HOST_BITS_PER_INT / 2); offset; offset >>= 1) | |
168 | { | |
38a448ca | 169 | address = gen_rtx_PLUS (Pmode, addr_reg, GEN_INT (offset)); |
c5986054 RS |
170 | |
171 | for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
f95361c8 JL |
172 | if (regno_save_mode[i][1] != VOIDmode |
173 | && ! strict_memory_address_p (regno_save_mode[i][1], address)) | |
c5986054 RS |
174 | break; |
175 | ||
176 | if (i == FIRST_PSEUDO_REGISTER) | |
177 | break; | |
178 | } | |
179 | ||
180 | /* If we didn't find a valid address, we must use register indirect. */ | |
181 | if (offset == 0) | |
182 | address = addr_reg; | |
183 | ||
184 | /* Next we try to form an insn to save and restore the register. We | |
d329e058 | 185 | see if such an insn is recognized and meets its constraints. |
bf1660a6 JL |
186 | |
187 | To avoid lots of unnecessary RTL allocation, we construct all the RTL | |
188 | once, then modify the memory and register operands in-place. */ | |
189 | ||
190 | test_reg = gen_rtx_REG (VOIDmode, 0); | |
191 | test_mem = gen_rtx_MEM (VOIDmode, address); | |
192 | savepat = gen_rtx_SET (VOIDmode, test_mem, test_reg); | |
193 | restpat = gen_rtx_SET (VOIDmode, test_reg, test_mem); | |
c5986054 | 194 | |
7f243674 JL |
195 | saveinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, 0, savepat, -1, 0, 0); |
196 | restinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, 0, restpat, -1, 0, 0); | |
0db79a6b | 197 | |
c5986054 | 198 | for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) |
787dc842 JH |
199 | for (mode = 0 ; mode < MAX_MACHINE_MODE; mode++) |
200 | if (HARD_REGNO_MODE_OK (i, mode)) | |
f95361c8 | 201 | { |
f95361c8 JL |
202 | int ok; |
203 | ||
bf1660a6 JL |
204 | /* Update the register number and modes of the register |
205 | and memory operand. */ | |
206 | REGNO (test_reg) = i; | |
207 | PUT_MODE (test_reg, mode); | |
208 | PUT_MODE (test_mem, mode); | |
209 | ||
d27bab4c RH |
210 | /* Force re-recognition of the modified insns. */ |
211 | INSN_CODE (saveinsn) = -1; | |
212 | INSN_CODE (restinsn) = -1; | |
213 | ||
787dc842 JH |
214 | reg_save_code[i][mode] = recog_memoized (saveinsn); |
215 | reg_restore_code[i][mode] = recog_memoized (restinsn); | |
f95361c8 | 216 | |
0f41302f MS |
217 | /* Now extract both insns and see if we can meet their |
218 | constraints. */ | |
830a47ec ZW |
219 | ok = (reg_save_code[i][mode] != -1 |
220 | && reg_restore_code[i][mode] != -1); | |
f95361c8 JL |
221 | if (ok) |
222 | { | |
0eadeb15 BS |
223 | extract_insn (saveinsn); |
224 | ok = constrain_operands (1); | |
225 | extract_insn (restinsn); | |
226 | ok &= constrain_operands (1); | |
f95361c8 | 227 | } |
c5986054 | 228 | |
c515799c JL |
229 | if (! ok) |
230 | { | |
830a47ec ZW |
231 | reg_save_code[i][mode] = -1; |
232 | reg_restore_code[i][mode] = -1; | |
c515799c | 233 | } |
787dc842 JH |
234 | } |
235 | else | |
236 | { | |
830a47ec ZW |
237 | reg_save_code[i][mode] = -1; |
238 | reg_restore_code[i][mode] = -1; | |
787dc842 | 239 | } |
d27bab4c | 240 | |
787dc842 JH |
241 | for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) |
242 | for (j = 1; j <= MOVE_MAX_WORDS; j++) | |
830a47ec | 243 | if (reg_save_code [i][regno_save_mode[i][j]] == -1) |
787dc842 JH |
244 | { |
245 | regno_save_mode[i][j] = VOIDmode; | |
246 | if (j == 1) | |
247 | { | |
248 | call_fixed_regs[i] = 1; | |
249 | SET_HARD_REG_BIT (call_fixed_reg_set, i); | |
250 | } | |
251 | } | |
c5986054 RS |
252 | } |
253 | \f | |
254 | /* Initialize save areas by showing that we haven't allocated any yet. */ | |
255 | ||
256 | void | |
d329e058 | 257 | init_save_areas (void) |
c5986054 | 258 | { |
f95361c8 | 259 | int i, j; |
c5986054 RS |
260 | |
261 | for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
7609e720 | 262 | for (j = 1; j <= MOVE_MAX_WORDS; j++) |
f95361c8 | 263 | regno_save_mem[i][j] = 0; |
c5986054 RS |
264 | } |
265 | ||
266 | /* Allocate save areas for any hard registers that might need saving. | |
267 | We take a conservative approach here and look for call-clobbered hard | |
268 | registers that are assigned to pseudos that cross calls. This may | |
269 | overestimate slightly (especially if some of these registers are later | |
270 | used as spill registers), but it should not be significant. | |
271 | ||
f95361c8 JL |
272 | Future work: |
273 | ||
274 | In the fallback case we should iterate backwards across all possible | |
d329e058 | 275 | modes for the save, choosing the largest available one instead of |
f95361c8 JL |
276 | falling back to the smallest mode immediately. (eg TF -> DF -> SF). |
277 | ||
278 | We do not try to use "move multiple" instructions that exist | |
d329e058 | 279 | on some machines (such as the 68k moveml). It could be a win to try |
f95361c8 | 280 | and use them when possible. The hard part is doing it in a way that is |
d329e058 | 281 | machine independent since they might be saving non-consecutive |
f95361c8 | 282 | registers. (imagine caller-saving d0,d1,a0,a1 on the 68k) */ |
c5986054 | 283 | |
437a710d | 284 | void |
d329e058 | 285 | setup_save_areas (void) |
c5986054 | 286 | { |
f95361c8 | 287 | int i, j, k; |
3bdf5ad1 | 288 | unsigned int r; |
f95361c8 | 289 | HARD_REG_SET hard_regs_used; |
f95361c8 JL |
290 | |
291 | /* Allocate space in the save area for the largest multi-register | |
292 | pseudos first, then work backwards to single register | |
293 | pseudos. */ | |
294 | ||
295 | /* Find and record all call-used hard-registers in this function. */ | |
296 | CLEAR_HARD_REG_SET (hard_regs_used); | |
c5986054 | 297 | for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) |
b1f21e0a | 298 | if (reg_renumber[i] >= 0 && REG_N_CALLS_CROSSED (i) > 0) |
c5986054 | 299 | { |
3bdf5ad1 | 300 | unsigned int regno = reg_renumber[i]; |
d329e058 | 301 | unsigned int endregno |
66fd46b6 | 302 | = regno + hard_regno_nregs[regno][GET_MODE (regno_reg_rtx[i])]; |
c5986054 | 303 | |
3bdf5ad1 RK |
304 | for (r = regno; r < endregno; r++) |
305 | if (call_used_regs[r]) | |
306 | SET_HARD_REG_BIT (hard_regs_used, r); | |
f95361c8 JL |
307 | } |
308 | ||
309 | /* Now run through all the call-used hard-registers and allocate | |
310 | space for them in the caller-save area. Try to allocate space | |
311 | in a manner which allows multi-register saves/restores to be done. */ | |
312 | ||
313 | for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
7609e720 | 314 | for (j = MOVE_MAX_WORDS; j > 0; j--) |
f95361c8 | 315 | { |
7609e720 | 316 | int do_save = 1; |
f95361c8 JL |
317 | |
318 | /* If no mode exists for this size, try another. Also break out | |
319 | if we have already saved this hard register. */ | |
320 | if (regno_save_mode[i][j] == VOIDmode || regno_save_mem[i][1] != 0) | |
321 | continue; | |
322 | ||
b5c2c9bc | 323 | /* See if any register in this group has been saved. */ |
b5c2c9bc RK |
324 | for (k = 0; k < j; k++) |
325 | if (regno_save_mem[i + k][1]) | |
326 | { | |
327 | do_save = 0; | |
328 | break; | |
329 | } | |
330 | if (! do_save) | |
331 | continue; | |
332 | ||
f95361c8 | 333 | for (k = 0; k < j; k++) |
7609e720 | 334 | if (! TEST_HARD_REG_BIT (hard_regs_used, i + k)) |
c5986054 | 335 | { |
7609e720 BS |
336 | do_save = 0; |
337 | break; | |
c5986054 | 338 | } |
7609e720 BS |
339 | if (! do_save) |
340 | continue; | |
f95361c8 | 341 | |
0f41302f | 342 | /* We have found an acceptable mode to store in. */ |
7609e720 BS |
343 | regno_save_mem[i][j] |
344 | = assign_stack_local (regno_save_mode[i][j], | |
345 | GET_MODE_SIZE (regno_save_mode[i][j]), 0); | |
346 | ||
347 | /* Setup single word save area just in case... */ | |
348 | for (k = 0; k < j; k++) | |
b72f00af RK |
349 | /* This should not depend on WORDS_BIG_ENDIAN. |
350 | The order of words in regs is the same as in memory. */ | |
351 | regno_save_mem[i + k][1] | |
f1ec5147 RK |
352 | = adjust_address_nv (regno_save_mem[i][j], |
353 | regno_save_mode[i + k][1], | |
354 | k * UNITS_PER_WORD); | |
c5986054 | 355 | } |
3bdf5ad1 RK |
356 | |
357 | /* Now loop again and set the alias set of any save areas we made to | |
358 | the alias set used to represent frame objects. */ | |
359 | for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
360 | for (j = MOVE_MAX_WORDS; j > 0; j--) | |
361 | if (regno_save_mem[i][j] != 0) | |
ba4828e0 | 362 | set_mem_alias_set (regno_save_mem[i][j], get_frame_alias_set ()); |
c5986054 RS |
363 | } |
364 | \f | |
437a710d | 365 | /* Find the places where hard regs are live across calls and save them. */ |
3bdf5ad1 | 366 | |
c5986054 | 367 | void |
d329e058 | 368 | save_call_clobbered_regs (void) |
c5986054 | 369 | { |
7609e720 | 370 | struct insn_chain *chain, *next; |
787dc842 | 371 | enum machine_mode save_mode [FIRST_PSEUDO_REGISTER]; |
7609e720 BS |
372 | |
373 | CLEAR_HARD_REG_SET (hard_regs_saved); | |
374 | n_regs_saved = 0; | |
c5986054 | 375 | |
7609e720 | 376 | for (chain = reload_insn_chain; chain != 0; chain = next) |
c5986054 | 377 | { |
7609e720 BS |
378 | rtx insn = chain->insn; |
379 | enum rtx_code code = GET_CODE (insn); | |
380 | ||
381 | next = chain->next; | |
382 | ||
366de0ce | 383 | gcc_assert (!chain->is_caller_save_insn); |
7609e720 | 384 | |
ec8e098d | 385 | if (INSN_P (insn)) |
c5986054 | 386 | { |
7609e720 BS |
387 | /* If some registers have been saved, see if INSN references |
388 | any of them. We must restore them before the insn if so. */ | |
c5986054 | 389 | |
7609e720 | 390 | if (n_regs_saved) |
c5986054 | 391 | { |
7609e720 BS |
392 | int regno; |
393 | ||
394 | if (code == JUMP_INSN) | |
395 | /* Restore all registers if this is a JUMP_INSN. */ | |
396 | COPY_HARD_REG_SET (referenced_regs, hard_regs_saved); | |
0e6362d9 | 397 | else |
0887bd4b | 398 | { |
7609e720 BS |
399 | CLEAR_HARD_REG_SET (referenced_regs); |
400 | mark_referenced_regs (PATTERN (insn)); | |
401 | AND_HARD_REG_SET (referenced_regs, hard_regs_saved); | |
0887bd4b | 402 | } |
c5986054 | 403 | |
7609e720 BS |
404 | for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) |
405 | if (TEST_HARD_REG_BIT (referenced_regs, regno)) | |
787dc842 | 406 | regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS, save_mode); |
c5986054 RS |
407 | } |
408 | ||
df5e8205 | 409 | if (code == CALL_INSN && ! find_reg_note (insn, REG_NORETURN, NULL)) |
7609e720 | 410 | { |
3cd8c58a | 411 | unsigned regno; |
7609e720 | 412 | HARD_REG_SET hard_regs_to_save; |
a2041967 | 413 | reg_set_iterator rsi; |
7609e720 BS |
414 | |
415 | /* Use the register life information in CHAIN to compute which | |
285f3cf0 R |
416 | regs are live during the call. */ |
417 | REG_SET_TO_HARD_REG_SET (hard_regs_to_save, | |
239a0f5b | 418 | &chain->live_throughout); |
f63d1bf7 | 419 | /* Save hard registers always in the widest mode available. */ |
787dc842 JH |
420 | for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) |
421 | if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) | |
422 | save_mode [regno] = regno_save_mode [regno][1]; | |
423 | else | |
424 | save_mode [regno] = VOIDmode; | |
425 | ||
f5143c46 | 426 | /* Look through all live pseudos, mark their hard registers |
787dc842 JH |
427 | and choose proper mode for saving. */ |
428 | EXECUTE_IF_SET_IN_REG_SET | |
a2041967 KH |
429 | (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi) |
430 | { | |
431 | int r = reg_renumber[regno]; | |
432 | int nregs; | |
433 | enum machine_mode mode; | |
434 | ||
435 | gcc_assert (r >= 0); | |
436 | nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)]; | |
437 | mode = HARD_REGNO_CALLER_SAVE_MODE | |
438 | (r, nregs, PSEUDO_REGNO_MODE (regno)); | |
439 | if (GET_MODE_BITSIZE (mode) | |
440 | > GET_MODE_BITSIZE (save_mode[r])) | |
441 | save_mode[r] = mode; | |
442 | while (nregs-- > 0) | |
443 | SET_HARD_REG_BIT (hard_regs_to_save, r + nregs); | |
444 | } | |
7609e720 BS |
445 | |
446 | /* Record all registers set in this call insn. These don't need | |
285f3cf0 R |
447 | to be saved. N.B. the call insn might set a subreg of a |
448 | multi-hard-reg pseudo; then the pseudo is considered live | |
449 | during the call, but the subreg that is set isn't. */ | |
7609e720 | 450 | CLEAR_HARD_REG_SET (this_insn_sets); |
84832317 | 451 | note_stores (PATTERN (insn), mark_set_regs, NULL); |
7609e720 BS |
452 | |
453 | /* Compute which hard regs must be saved before this call. */ | |
454 | AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set); | |
455 | AND_COMPL_HARD_REG_SET (hard_regs_to_save, this_insn_sets); | |
456 | AND_COMPL_HARD_REG_SET (hard_regs_to_save, hard_regs_saved); | |
457 | AND_HARD_REG_SET (hard_regs_to_save, call_used_reg_set); | |
458 | ||
7609e720 BS |
459 | for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) |
460 | if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) | |
787dc842 | 461 | regno += insert_save (chain, 1, regno, &hard_regs_to_save, save_mode); |
7609e720 BS |
462 | |
463 | /* Must recompute n_regs_saved. */ | |
464 | n_regs_saved = 0; | |
465 | for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) | |
466 | if (TEST_HARD_REG_BIT (hard_regs_saved, regno)) | |
467 | n_regs_saved++; | |
468 | } | |
469 | } | |
c5986054 | 470 | |
7609e720 BS |
471 | if (chain->next == 0 || chain->next->block > chain->block) |
472 | { | |
473 | int regno; | |
474 | /* At the end of the basic block, we must restore any registers that | |
475 | remain saved. If the last insn in the block is a JUMP_INSN, put | |
476 | the restore before the insn, otherwise, put it after the insn. */ | |
477 | ||
478 | if (n_regs_saved) | |
479 | for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) | |
480 | if (TEST_HARD_REG_BIT (hard_regs_saved, regno)) | |
4b4bf941 | 481 | regno += insert_restore (chain, JUMP_P (insn), |
787dc842 | 482 | regno, MOVE_MAX_WORDS, save_mode); |
7609e720 | 483 | } |
d329e058 | 484 | } |
c5986054 RS |
485 | } |
486 | ||
487 | /* Here from note_stores when an insn stores a value in a register. | |
7609e720 | 488 | Set the proper bit or bits in this_insn_sets. All pseudos that have |
c5986054 RS |
489 | been assigned hard regs have had their register number changed already, |
490 | so we can ignore pseudos. */ | |
c5986054 | 491 | static void |
d329e058 AJ |
492 | mark_set_regs (rtx reg, rtx setter ATTRIBUTE_UNUSED, |
493 | void *data ATTRIBUTE_UNUSED) | |
c5986054 | 494 | { |
b3694847 | 495 | int regno, endregno, i; |
e048626b | 496 | enum machine_mode mode = GET_MODE (reg); |
c5986054 RS |
497 | |
498 | if (GET_CODE (reg) == SUBREG) | |
499 | { | |
ddef6bc7 | 500 | rtx inner = SUBREG_REG (reg); |
f8cfc6aa | 501 | if (!REG_P (inner) || REGNO (inner) >= FIRST_PSEUDO_REGISTER) |
ddef6bc7 | 502 | return; |
c5986054 | 503 | |
ddef6bc7 JJ |
504 | regno = subreg_hard_regno (reg, 1); |
505 | } | |
f8cfc6aa | 506 | else if (REG_P (reg) |
ddef6bc7 JJ |
507 | && REGNO (reg) < FIRST_PSEUDO_REGISTER) |
508 | regno = REGNO (reg); | |
509 | else | |
c5986054 RS |
510 | return; |
511 | ||
66fd46b6 | 512 | endregno = regno + hard_regno_nregs[regno][mode]; |
c5986054 RS |
513 | |
514 | for (i = regno; i < endregno; i++) | |
7609e720 | 515 | SET_HARD_REG_BIT (this_insn_sets, i); |
c5986054 RS |
516 | } |
517 | ||
285f3cf0 R |
518 | /* Here from note_stores when an insn stores a value in a register. |
519 | Set the proper bit or bits in the passed regset. All pseudos that have | |
520 | been assigned hard regs have had their register number changed already, | |
521 | so we can ignore pseudos. */ | |
522 | static void | |
d329e058 | 523 | add_stored_regs (rtx reg, rtx setter, void *data) |
285f3cf0 | 524 | { |
b3694847 | 525 | int regno, endregno, i; |
285f3cf0 | 526 | enum machine_mode mode = GET_MODE (reg); |
ddef6bc7 | 527 | int offset = 0; |
285f3cf0 R |
528 | |
529 | if (GET_CODE (setter) == CLOBBER) | |
530 | return; | |
531 | ||
f8cfc6aa | 532 | if (GET_CODE (reg) == SUBREG && REG_P (SUBREG_REG (reg))) |
285f3cf0 | 533 | { |
ddef6bc7 JJ |
534 | offset = subreg_regno_offset (REGNO (SUBREG_REG (reg)), |
535 | GET_MODE (SUBREG_REG (reg)), | |
536 | SUBREG_BYTE (reg), | |
537 | GET_MODE (reg)); | |
285f3cf0 R |
538 | reg = SUBREG_REG (reg); |
539 | } | |
540 | ||
f8cfc6aa | 541 | if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER) |
285f3cf0 R |
542 | return; |
543 | ||
ddef6bc7 | 544 | regno = REGNO (reg) + offset; |
66fd46b6 | 545 | endregno = regno + hard_regno_nregs[regno][mode]; |
285f3cf0 R |
546 | |
547 | for (i = regno; i < endregno; i++) | |
548 | SET_REGNO_REG_SET ((regset) data, i); | |
549 | } | |
550 | ||
7609e720 | 551 | /* Walk X and record all referenced registers in REFERENCED_REGS. */ |
c5986054 | 552 | static void |
d329e058 | 553 | mark_referenced_regs (rtx x) |
c5986054 RS |
554 | { |
555 | enum rtx_code code = GET_CODE (x); | |
6f7d635c | 556 | const char *fmt; |
c5986054 RS |
557 | int i, j; |
558 | ||
7609e720 BS |
559 | if (code == SET) |
560 | mark_referenced_regs (SET_SRC (x)); | |
561 | if (code == SET || code == CLOBBER) | |
562 | { | |
563 | x = SET_DEST (x); | |
564 | code = GET_CODE (x); | |
4d450e9a RE |
565 | if ((code == REG && REGNO (x) < FIRST_PSEUDO_REGISTER) |
566 | || code == PC || code == CC0 | |
f8cfc6aa | 567 | || (code == SUBREG && REG_P (SUBREG_REG (x)) |
4d450e9a | 568 | && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER |
2696f6a4 AO |
569 | /* If we're setting only part of a multi-word register, |
570 | we shall mark it as referenced, because the words | |
571 | that are not being set should be restored. */ | |
572 | && ((GET_MODE_SIZE (GET_MODE (x)) | |
573 | >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) | |
574 | || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) | |
575 | <= UNITS_PER_WORD)))) | |
7609e720 BS |
576 | return; |
577 | } | |
578 | if (code == MEM || code == SUBREG) | |
579 | { | |
580 | x = XEXP (x, 0); | |
581 | code = GET_CODE (x); | |
582 | } | |
f95361c8 | 583 | |
c5986054 RS |
584 | if (code == REG) |
585 | { | |
586 | int regno = REGNO (x); | |
7609e720 BS |
587 | int hardregno = (regno < FIRST_PSEUDO_REGISTER ? regno |
588 | : reg_renumber[regno]); | |
c5986054 | 589 | |
7609e720 | 590 | if (hardregno >= 0) |
c5986054 | 591 | { |
66fd46b6 | 592 | int nregs = hard_regno_nregs[hardregno][GET_MODE (x)]; |
7609e720 BS |
593 | while (nregs-- > 0) |
594 | SET_HARD_REG_BIT (referenced_regs, hardregno + nregs); | |
c5986054 | 595 | } |
7609e720 BS |
596 | /* If this is a pseudo that did not get a hard register, scan its |
597 | memory location, since it might involve the use of another | |
598 | register, which might be saved. */ | |
599 | else if (reg_equiv_mem[regno] != 0) | |
600 | mark_referenced_regs (XEXP (reg_equiv_mem[regno], 0)); | |
601 | else if (reg_equiv_address[regno] != 0) | |
602 | mark_referenced_regs (reg_equiv_address[regno]); | |
c5986054 RS |
603 | return; |
604 | } | |
7609e720 | 605 | |
c5986054 RS |
606 | fmt = GET_RTX_FORMAT (code); |
607 | for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) | |
608 | { | |
609 | if (fmt[i] == 'e') | |
7609e720 | 610 | mark_referenced_regs (XEXP (x, i)); |
c5986054 RS |
611 | else if (fmt[i] == 'E') |
612 | for (j = XVECLEN (x, i) - 1; j >= 0; j--) | |
7609e720 | 613 | mark_referenced_regs (XVECEXP (x, i, j)); |
c5986054 RS |
614 | } |
615 | } | |
616 | \f | |
7609e720 BS |
617 | /* Insert a sequence of insns to restore. Place these insns in front of |
618 | CHAIN if BEFORE_P is nonzero, behind the insn otherwise. MAXRESTORE is | |
619 | the maximum number of registers which should be restored during this call. | |
620 | It should never be less than 1 since we only work with entire registers. | |
c5986054 RS |
621 | |
622 | Note that we have verified in init_caller_save that we can do this | |
623 | with a simple SET, so use it. Set INSN_CODE to what we save there | |
624 | since the address might not be valid so the insn might not be recognized. | |
625 | These insns will be reloaded and have register elimination done by | |
f95361c8 | 626 | find_reload, so we need not worry about that here. |
c5986054 | 627 | |
f95361c8 JL |
628 | Return the extra number of registers saved. */ |
629 | ||
630 | static int | |
d329e058 AJ |
631 | insert_restore (struct insn_chain *chain, int before_p, int regno, |
632 | int maxrestore, enum machine_mode *save_mode) | |
c5986054 | 633 | { |
285f3cf0 | 634 | int i, k; |
aefdd5ab | 635 | rtx pat = NULL_RTX; |
830a47ec | 636 | int code; |
787dc842 | 637 | unsigned int numregs = 0; |
285f3cf0 | 638 | struct insn_chain *new; |
787dc842 | 639 | rtx mem; |
c5986054 | 640 | |
09835ed2 RK |
641 | /* A common failure mode if register status is not correct in the RTL |
642 | is for this routine to be called with a REGNO we didn't expect to | |
643 | save. That will cause us to write an insn with a (nil) SET_DEST | |
644 | or SET_SRC. Instead of doing so and causing a crash later, check | |
645 | for this common case and abort here instead. This will remove one | |
646 | step in debugging such problems. */ | |
366de0ce | 647 | gcc_assert (regno_save_mem[regno][1]); |
09835ed2 | 648 | |
7609e720 | 649 | /* Get the pattern to emit and update our status. |
4554e20d | 650 | |
7609e720 | 651 | See if we can restore `maxrestore' registers at once. Work |
4554e20d JL |
652 | backwards to the single register case. */ |
653 | for (i = maxrestore; i > 0; i--) | |
c5986054 | 654 | { |
285f3cf0 | 655 | int j; |
7609e720 BS |
656 | int ok = 1; |
657 | ||
658 | if (regno_save_mem[regno][i] == 0) | |
4554e20d JL |
659 | continue; |
660 | ||
7609e720 BS |
661 | for (j = 0; j < i; j++) |
662 | if (! TEST_HARD_REG_BIT (hard_regs_saved, regno + j)) | |
663 | { | |
664 | ok = 0; | |
665 | break; | |
666 | } | |
f9da5064 | 667 | /* Must do this one restore at a time. */ |
4554e20d JL |
668 | if (! ok) |
669 | continue; | |
7609e720 | 670 | |
4554e20d JL |
671 | numregs = i; |
672 | break; | |
673 | } | |
f95361c8 | 674 | |
787dc842 JH |
675 | mem = regno_save_mem [regno][numregs]; |
676 | if (save_mode [regno] != VOIDmode | |
677 | && save_mode [regno] != GET_MODE (mem) | |
66fd46b6 | 678 | && numregs == (unsigned int) hard_regno_nregs[regno][save_mode [regno]]) |
f4ef873c | 679 | mem = adjust_address (mem, save_mode[regno], 0); |
ce7b36a4 JW |
680 | else |
681 | mem = copy_rtx (mem); | |
285f3cf0 | 682 | pat = gen_rtx_SET (VOIDmode, |
d329e058 | 683 | gen_rtx_REG (GET_MODE (mem), |
787dc842 JH |
684 | regno), mem); |
685 | code = reg_restore_code[regno][GET_MODE (mem)]; | |
285f3cf0 R |
686 | new = insert_one_insn (chain, before_p, code, pat); |
687 | ||
688 | /* Clear status for all registers we restored. */ | |
689 | for (k = 0; k < i; k++) | |
690 | { | |
691 | CLEAR_HARD_REG_BIT (hard_regs_saved, regno + k); | |
239a0f5b | 692 | SET_REGNO_REG_SET (&new->dead_or_set, regno + k); |
285f3cf0 R |
693 | n_regs_saved--; |
694 | } | |
695 | ||
6614fd40 | 696 | /* Tell our callers how many extra registers we saved/restored. */ |
4554e20d JL |
697 | return numregs - 1; |
698 | } | |
f95361c8 | 699 | |
7609e720 | 700 | /* Like insert_restore above, but save registers instead. */ |
2cc2d4bb | 701 | |
4554e20d | 702 | static int |
d329e058 AJ |
703 | insert_save (struct insn_chain *chain, int before_p, int regno, |
704 | HARD_REG_SET (*to_save), enum machine_mode *save_mode) | |
4554e20d | 705 | { |
787dc842 JH |
706 | int i; |
707 | unsigned int k; | |
4554e20d | 708 | rtx pat = NULL_RTX; |
830a47ec | 709 | int code; |
787dc842 | 710 | unsigned int numregs = 0; |
285f3cf0 | 711 | struct insn_chain *new; |
787dc842 | 712 | rtx mem; |
f95361c8 | 713 | |
4554e20d JL |
714 | /* A common failure mode if register status is not correct in the RTL |
715 | is for this routine to be called with a REGNO we didn't expect to | |
716 | save. That will cause us to write an insn with a (nil) SET_DEST | |
717 | or SET_SRC. Instead of doing so and causing a crash later, check | |
718 | for this common case and abort here instead. This will remove one | |
719 | step in debugging such problems. */ | |
366de0ce | 720 | gcc_assert (regno_save_mem[regno][1]); |
c5986054 | 721 | |
7609e720 | 722 | /* Get the pattern to emit and update our status. |
f95361c8 | 723 | |
d329e058 | 724 | See if we can save several registers with a single instruction. |
4554e20d | 725 | Work backwards to the single register case. */ |
7609e720 | 726 | for (i = MOVE_MAX_WORDS; i > 0; i--) |
4554e20d | 727 | { |
285f3cf0 | 728 | int j; |
7609e720 BS |
729 | int ok = 1; |
730 | if (regno_save_mem[regno][i] == 0) | |
4554e20d | 731 | continue; |
f95361c8 | 732 | |
7609e720 BS |
733 | for (j = 0; j < i; j++) |
734 | if (! TEST_HARD_REG_BIT (*to_save, regno + j)) | |
735 | { | |
736 | ok = 0; | |
737 | break; | |
738 | } | |
f9da5064 | 739 | /* Must do this one save at a time. */ |
4554e20d JL |
740 | if (! ok) |
741 | continue; | |
742 | ||
4554e20d JL |
743 | numregs = i; |
744 | break; | |
f95361c8 | 745 | } |
c5986054 | 746 | |
787dc842 JH |
747 | mem = regno_save_mem [regno][numregs]; |
748 | if (save_mode [regno] != VOIDmode | |
749 | && save_mode [regno] != GET_MODE (mem) | |
66fd46b6 | 750 | && numregs == (unsigned int) hard_regno_nregs[regno][save_mode [regno]]) |
f4ef873c | 751 | mem = adjust_address (mem, save_mode[regno], 0); |
ce7b36a4 JW |
752 | else |
753 | mem = copy_rtx (mem); | |
787dc842 JH |
754 | pat = gen_rtx_SET (VOIDmode, mem, |
755 | gen_rtx_REG (GET_MODE (mem), | |
285f3cf0 | 756 | regno)); |
787dc842 | 757 | code = reg_save_code[regno][GET_MODE (mem)]; |
285f3cf0 R |
758 | new = insert_one_insn (chain, before_p, code, pat); |
759 | ||
760 | /* Set hard_regs_saved and dead_or_set for all the registers we saved. */ | |
761 | for (k = 0; k < numregs; k++) | |
762 | { | |
763 | SET_HARD_REG_BIT (hard_regs_saved, regno + k); | |
239a0f5b | 764 | SET_REGNO_REG_SET (&new->dead_or_set, regno + k); |
285f3cf0 R |
765 | n_regs_saved++; |
766 | } | |
f95361c8 | 767 | |
6614fd40 | 768 | /* Tell our callers how many extra registers we saved/restored. */ |
f95361c8 | 769 | return numregs - 1; |
c5986054 | 770 | } |
4554e20d | 771 | |
7609e720 | 772 | /* Emit a new caller-save insn and set the code. */ |
285f3cf0 | 773 | static struct insn_chain * |
d329e058 | 774 | insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat) |
4554e20d | 775 | { |
7609e720 BS |
776 | rtx insn = chain->insn; |
777 | struct insn_chain *new; | |
d329e058 | 778 | |
4554e20d JL |
779 | #ifdef HAVE_cc0 |
780 | /* If INSN references CC0, put our insns in front of the insn that sets | |
781 | CC0. This is always safe, since the only way we could be passed an | |
782 | insn that references CC0 is for a restore, and doing a restore earlier | |
783 | isn't a problem. We do, however, assume here that CALL_INSNs don't | |
784 | reference CC0. Guard against non-INSN's like CODE_LABEL. */ | |
785 | ||
4b4bf941 | 786 | if ((NONJUMP_INSN_P (insn) || JUMP_P (insn)) |
4554e20d JL |
787 | && before_p |
788 | && reg_referenced_p (cc0_rtx, PATTERN (insn))) | |
7609e720 | 789 | chain = chain->prev, insn = chain->insn; |
4554e20d JL |
790 | #endif |
791 | ||
7609e720 | 792 | new = new_insn_chain (); |
4554e20d JL |
793 | if (before_p) |
794 | { | |
285f3cf0 R |
795 | rtx link; |
796 | ||
7609e720 BS |
797 | new->prev = chain->prev; |
798 | if (new->prev != 0) | |
799 | new->prev->next = new; | |
800 | else | |
801 | reload_insn_chain = new; | |
802 | ||
803 | chain->prev = new; | |
804 | new->next = chain; | |
805 | new->insn = emit_insn_before (pat, insn); | |
92691d7d JL |
806 | /* ??? It would be nice if we could exclude the already / still saved |
807 | registers from the live sets. */ | |
239a0f5b | 808 | COPY_REG_SET (&new->live_throughout, &chain->live_throughout); |
285f3cf0 R |
809 | /* Registers that die in CHAIN->INSN still live in the new insn. */ |
810 | for (link = REG_NOTES (chain->insn); link; link = XEXP (link, 1)) | |
811 | { | |
812 | if (REG_NOTE_KIND (link) == REG_DEAD) | |
813 | { | |
814 | rtx reg = XEXP (link, 0); | |
815 | int regno, i; | |
816 | ||
366de0ce | 817 | gcc_assert (REG_P (reg)); |
285f3cf0 R |
818 | regno = REGNO (reg); |
819 | if (regno >= FIRST_PSEUDO_REGISTER) | |
820 | regno = reg_renumber[regno]; | |
821 | if (regno < 0) | |
822 | continue; | |
66fd46b6 | 823 | for (i = hard_regno_nregs[regno][GET_MODE (reg)] - 1; |
285f3cf0 | 824 | i >= 0; i--) |
239a0f5b | 825 | SET_REGNO_REG_SET (&new->live_throughout, regno + i); |
285f3cf0 R |
826 | } |
827 | } | |
239a0f5b | 828 | CLEAR_REG_SET (&new->dead_or_set); |
a813c111 SB |
829 | if (chain->insn == BB_HEAD (BASIC_BLOCK (chain->block))) |
830 | BB_HEAD (BASIC_BLOCK (chain->block)) = new->insn; | |
4554e20d JL |
831 | } |
832 | else | |
833 | { | |
7609e720 BS |
834 | new->next = chain->next; |
835 | if (new->next != 0) | |
836 | new->next->prev = new; | |
837 | chain->next = new; | |
838 | new->prev = chain; | |
839 | new->insn = emit_insn_after (pat, insn); | |
92691d7d JL |
840 | /* ??? It would be nice if we could exclude the already / still saved |
841 | registers from the live sets, and observe REG_UNUSED notes. */ | |
239a0f5b | 842 | COPY_REG_SET (&new->live_throughout, &chain->live_throughout); |
285f3cf0 R |
843 | /* Registers that are set in CHAIN->INSN live in the new insn. |
844 | (Unless there is a REG_UNUSED note for them, but we don't | |
845 | look for them here.) */ | |
846 | note_stores (PATTERN (chain->insn), add_stored_regs, | |
239a0f5b BS |
847 | &new->live_throughout); |
848 | CLEAR_REG_SET (&new->dead_or_set); | |
a813c111 SB |
849 | if (chain->insn == BB_END (BASIC_BLOCK (chain->block))) |
850 | BB_END (BASIC_BLOCK (chain->block)) = new->insn; | |
4554e20d | 851 | } |
7609e720 BS |
852 | new->block = chain->block; |
853 | new->is_caller_save_insn = 1; | |
437a710d | 854 | |
7609e720 | 855 | INSN_CODE (new->insn) = code; |
285f3cf0 | 856 | return new; |
4554e20d | 857 | } |