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