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