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