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