|
|
1.1 root 1: /* Save and restore call-clobbered registers which are live across a call.
2: Copyright (C) 1989 Free Software Foundation, Inc.
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 1, 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
18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19:
20: #include "config.h"
21: #include "rtl.h"
22: #include "insn-config.h"
23: #include "flags.h"
24: #include "regs.h"
25: #include "hard-reg-set.h"
26: #include "reload.h"
27: #include "recog.h"
28: #include "basic-block.h"
29:
30: /* Set of hard regs currently live (during scan of all insns). */
31:
32: static HARD_REG_SET hard_regs_live;
33:
34: /* The block of storage on the stack where regs are saved */
35:
36: static rtx save_block_addr;
37: static int save_block_size;
38:
39: /* A REG rtx for each hard register that has been saved. */
40:
41: static rtx save_reg_rtx[FIRST_PSEUDO_REGISTER];
42:
43: static void set_reg_live ();
44: static void clear_reg_live ();
45: static void insert_call_saves ();
46: static void emit_mult_save ();
47: static void emit_mult_restore ();
48: static rtx grow_save_block ();
49: static enum machine_mode choose_hard_reg_mode ();
50:
51: /* Find the places where hard regs are live across calls and save them. */
52:
53: save_call_clobbered_regs ()
54: {
55: rtx insn;
56: int b;
57:
58: if (obey_regdecls)
59: return;
60:
61: save_block_size = 0;
62: save_block_addr = 0;
63: bzero (save_reg_rtx, sizeof save_reg_rtx);
64:
65: for (b = 0; b < n_basic_blocks; b++)
66: {
67: regset regs_live = basic_block_live_at_start[b];
68: int offset, bit, i;
69:
70: /* Compute hard regs live at start of block -- this is the
71: real hard regs marked live, plus live pseudo regs that
72: have been renumbered to hard regs. */
73:
74: #ifdef HARD_REG_SET
75: hard_regs_live = *regs_live;
76: #else
77: COPY_HARD_REG_SET (hard_regs_live, regs_live);
78: #endif
79:
80: for (offset = 0, i = 0; offset < regset_size; offset++)
81: {
82: if (regs_live[offset] == 0)
83: i += HOST_BITS_PER_INT;
84: else
85: for (bit = 1; bit && i < max_regno; bit <<= 1, i++)
86: if ((regs_live[offset] & bit) && reg_renumber[i] >= 0)
87: SET_HARD_REG_BIT (hard_regs_live, reg_renumber[i]);
88: }
89:
90: /* Now scan the insns in the block, keeping track of what hard
91: regs are live as we go. When we see a call, save the live
92: call-clobbered hard regs. */
93:
94: for (insn = basic_block_head[b]; TRUE; insn = NEXT_INSN (insn))
95: {
96: RTX_CODE code = GET_CODE (insn);
97:
98: if (code == CALL_INSN)
99: insert_call_saves (insn);
100:
101: if (code == INSN || code == CALL_INSN || code == JUMP_INSN)
102: {
103: rtx link;
104:
105: /* NB: the normal procedure is to first enliven any
106: registers set by insn, then deaden any registers that
107: had their last use at insn. This is incorrect now,
108: since multiple pseudos may have been mapped to the
109: same hard reg, and the death notes are ambiguous. So
110: it must be done in the other, safe, order. */
111:
112: for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
113: if (REG_NOTE_KIND (link) == REG_DEAD)
114: clear_reg_live (XEXP (link, 0));
115:
116: note_stores (PATTERN (insn), set_reg_live);
117: }
118:
119: if (insn == basic_block_end[b])
120: break;
121: }
122: }
123: }
124:
125: /* Here from note_stores when an insn stores a value in a register.
126: Set the proper bit or bits in hard_regs_live. */
127:
128: static void
129: set_reg_live (reg, setter)
130: rtx reg, setter;
131: {
132: register int regno;
133:
134: /* WORD is which word of a multi-register group is being stored.
135: For the case where the store is actually into a SUBREG of REG.
136: Except we don't use it; I believe the entire REG needs to be
137: live. */
138: int word = 0;
139:
140: if (GET_CODE (reg) == SUBREG)
141: {
142: word = SUBREG_WORD (reg);
143: reg = SUBREG_REG (reg);
144: }
145:
146: if (GET_CODE (reg) != REG)
147: return;
148:
149: regno = REGNO (reg);
150:
151: /* For pseudo reg, see if it has been assigned a hardware reg. */
152: if (reg_renumber[regno] >= 0)
153: regno = reg_renumber[regno] /* + word */;
154:
155: /* Handle hardware regs (and pseudos allocated to hard regs). */
156: if (regno < FIRST_PSEUDO_REGISTER && ! call_fixed_regs[regno])
157: {
158: register int last = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
159: while (regno < last)
160: {
161: SET_HARD_REG_BIT (hard_regs_live, regno);
162: regno++;
163: }
164: }
165: }
166:
167: /* Here when a REG_DEAD note records the last use of a reg. Clear
168: the appropriate bit or bits in hard_regs_live. */
169:
170: static void
171: clear_reg_live (reg)
172: rtx reg;
173: {
174: register int regno = REGNO (reg);
175:
176: /* For pseudo reg, see if it has been assigned a hardware reg. */
177: if (reg_renumber[regno] >= 0)
178: regno = reg_renumber[regno];
179:
180: /* Handle hardware regs (and pseudos allocated to hard regs). */
181: if (regno < FIRST_PSEUDO_REGISTER && ! call_fixed_regs[regno])
182: {
183: /* Pseudo regs already assigned hardware regs are treated
184: almost the same as explicit hardware regs. */
185: register int last = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
186: while (regno < last)
187: {
188: CLEAR_HARD_REG_BIT (hard_regs_live, regno);
189: regno++;
190: }
191: }
192: }
193:
194: /* Insert insns to save and restore live call-clobbered regs around
195: call insn INSN. */
196:
197: static void
198: insert_call_saves (insn)
199: rtx insn;
200: {
201: int regno;
202: int save_block_size_needed;
203: int save_block_offset[FIRST_PSEUDO_REGISTER];
204:
205: save_block_size_needed = 0;
206:
207: for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
208: {
209: save_block_offset[regno] = -1;
210: if (call_used_regs[regno] && ! call_fixed_regs[regno]
211: && TEST_HARD_REG_BIT (hard_regs_live, regno))
212: {
213: enum machine_mode mode = choose_hard_reg_mode (regno);
214: int align = GET_MODE_UNIT_SIZE (mode);
215: if (align > BIGGEST_ALIGNMENT / BITS_PER_UNIT)
216: align = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
217: save_block_size_needed =
218: ((save_block_size_needed + align - 1) / align) * align;
219: save_block_offset[regno] = save_block_size_needed;
220: save_block_size_needed += GET_MODE_SIZE (mode);
221: if (! save_reg_rtx[regno])
222: save_reg_rtx[regno] = gen_rtx (REG, mode, regno);
223: }
224: }
225:
226: if (save_block_size < save_block_size_needed)
227: save_block_addr = grow_save_block (save_block_addr,
228: save_block_size_needed);
229: emit_mult_save (insn, save_block_addr, save_block_offset);
230: emit_mult_restore (insn, save_block_addr, save_block_offset);
231: }
232:
233: /* Emit a string of stores to save the hard regs listed in
1.1.1.2 root 234: OFFSET[] at address ADDR. Emit them before INSN.
1.1 root 235: OFFSET[reg] is -1 if reg should not be saved, or a
236: suitably-aligned offset from ADDR.
237: The offsets actually used do not have to be those listed
238: in OFFSET, but should fit in a block of the same size. */
239:
240: static void
241: emit_mult_save (insn, addr, offset)
242: rtx insn, addr;
243: int offset[];
244: {
245: int regno;
1.1.1.2 root 246: /* A register to use as a temporary for address calculations. */
247: rtx tempreg;
248: /* A register that could be used as that temp if we save and restore it. */
249: rtx can_push_reg;
250: /* Nonzero means we need to save a register to use it as TEMPREG. */
251: int needpush;
252: /* The amount the stack is decremented to save that register (if we do). */
253: int decrement;
254: /* Record which regs we save, in case we branch to retry. */
255: char already_saved[FIRST_PSEUDO_REGISTER];
256:
257: bzero (already_saved, sizeof already_saved);
258:
259: /* Hair is needed because sometimes the addresses to save in are
260: not valid (offsets too big).
261: So we need a reg, TEMPREG, to compute addresses in.
262:
263: We look first for an empty reg to use.
264: Sometimes no reg is empty. Then we push a reg, use it, and pop it.
265:
266: Sometimes the only reg to push and pop this way is one we want to save.
267: We can't save it while using it as a temporary.
268: So we save all the other registers, pop it, and go back to `retry'.
269: At that point, only this reg remains to be saved;
270: all the others already saved are empty.
271: So one of them can be the temporary for this one. */
272:
273: /* Sometimes we can't save all the regs conveniently at once, just some.
274: If that happens, we branch back here to save the rest. */
275: retry:
276: needpush = 0;
277: tempreg = 0;
278: can_push_reg = 0;
279:
280: /* Set NEEDPUSH if any save-addresses are not valid memory addresses.
281: If any register is available, record it in TEMPREG.
282: If any register doesn't need saving here, record it in CAN_PUSH_REG. */
283: for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
284: {
285: if (offset[regno] >= 0 && ! already_saved[regno])
286: {
287: rtx reg = save_reg_rtx[regno];
288: rtx addr1 = plus_constant (addr, offset[regno]);
289: if (memory_address_p (GET_MODE (reg), addr1))
290: needpush = 1;
291: }
292:
293: /* A call-clobbered reg that is dead, or already saved,
294: can be used as a temporary for sure, at no extra cost. */
295: if (tempreg == 0 && call_used_regs[regno] && ! fixed_regs[regno]
296: && !(offset[regno] >= 0 && ! already_saved[regno])
297: && HARD_REGNO_MODE_OK (regno, Pmode))
298: {
299: tempreg = gen_rtx (REG, Pmode, regno);
300: /* Don't use it if not valid for addressing. */
301: if (! strict_memory_address_p (QImode, tempreg))
302: tempreg = 0;
303: }
304:
305: /* A call-saved reg can be a temporary if we push and pop it. */
306: if (can_push_reg == 0 && ! call_used_regs[regno]
307: && HARD_REGNO_MODE_OK (regno, Pmode))
308: {
309: can_push_reg = gen_rtx (REG, Pmode, regno);
310: /* Don't use it if not valid for addressing. */
311: if (! strict_memory_address_p (QImode, can_push_reg))
312: can_push_reg = 0;
313: }
314: }
315:
316: /* Clear NEEDPUSH if we already found an empty reg. */
317: if (tempreg != 0)
318: needpush = 0;
319:
320: /* If we need a temp reg and none is free, make one free. */
321: if (needpush)
322: {
323: /* Choose a reg, preferably not among those it is our job to save. */
324: if (can_push_reg != 0)
325: tempreg = can_push_reg;
326: else
327: {
328: for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
329: if (offset[regno] >= 0 && !already_saved[regno]
330: && HARD_REGNO_MODE_OK (regno, Pmode))
331: {
332: tempreg = gen_rtx (REG, Pmode, regno);
333: /* Don't use it if not valid for addressing. */
334: if (! strict_memory_address_p (QImode, tempreg))
335: tempreg = 0;
336: else
337: break;
338: }
339: }
340:
341: /* Push it on the stack. */
342: #ifdef STACK_GROWS_DOWNWARD
343: decrement = UNITS_PER_WORD;
344: #else
345: decrement = - UNITS_PER_WORD;
346: #endif
347:
348: emit_insn_before (gen_add2_insn (stack_pointer_rtx,
349: gen_rtx (CONST_INT, VOIDmode, -decrement)),
350: insn);
351: emit_insn_before (gen_move_insn (gen_rtx (MEM, Pmode, stack_pointer_rtx),
352: tempreg),
353: insn);
354: }
1.1 root 355:
1.1.1.2 root 356: /* Save the regs we are supposed to save, aside from TEMPREG.
357: Use TEMPREG for address calculations when needed. */
1.1 root 358: for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
1.1.1.2 root 359: if (offset[regno] >= 0 && ! already_saved[regno]
360: && tempreg != 0 && REGNO (tempreg) != regno)
1.1 root 361: {
362: rtx reg = save_reg_rtx[regno];
1.1.1.2 root 363: rtx addr1 = plus_constant (addr, offset[regno]);
364: rtx temp;
365: if (! memory_address_p (GET_MODE (reg), addr1))
366: {
367: if (GET_CODE (addr1) != PLUS)
368: abort ();
369: if (GET_CODE (XEXP (addr1, 1)) != CONST_INT
370: || GET_CODE (XEXP (addr1, 0)) != REG)
371: abort ();
372: emit_insn_before (gen_move_insn (tempreg, XEXP (addr1, 0)), insn);
373: emit_insn_before (gen_add2_insn (tempreg, XEXP (addr1, 1)), insn);
374: addr1 = tempreg;
375: }
376: temp = gen_rtx (MEM, GET_MODE (reg), addr1);
1.1 root 377: emit_insn_before (gen_move_insn (temp, reg), insn);
1.1.1.2 root 378: already_saved[regno] = 1;
1.1 root 379: }
1.1.1.2 root 380:
381: /* If we pushed TEMPREG to make it free, pop it. */
382: if (needpush)
383: {
384: emit_insn_before (gen_move_insn (tempreg,
385: gen_rtx (MEM, Pmode, stack_pointer_rtx)),
386: insn);
387: emit_insn_before (gen_add2_insn (stack_pointer_rtx,
388: gen_rtx (CONST_INT, VOIDmode, decrement)),
389: insn);
390: }
391:
392: /* If TEMPREG itself needs saving, go back and save it.
393: There are plenty of free regs now, those already saved. */
394: if (tempreg != 0
395: && offset[REGNO (tempreg)] >= 0 && ! already_saved[REGNO (tempreg)])
396: goto retry;
1.1 root 397: }
398:
399: /* Emit a string of loads to restore the hard regs listed in
1.1.1.2 root 400: OFFSET[] from address ADDR; insert the loads after INSN.
1.1 root 401: OFFSET[reg] is -1 if reg should not be loaded, or a
402: suitably-aligned offset from ADDR.
403: The offsets actually used do not need to be those provided in
404: OFFSET, but should agree with whatever emit_mult_save does. */
405:
406: static void
407: emit_mult_restore (insn, addr, offset)
408: rtx insn, addr;
1.1.1.2 root 409: int offset[];
1.1 root 410: {
411: int regno;
412:
1.1.1.2 root 413: /* Number of regs now needing to be restored. */
414: int restore_count;
415: /* A register to use as a temporary for address calculations. */
416: rtx tempreg;
417: /* A register available for that purpose but less desirable. */
418: rtx maybe_tempreg;
419: /* A register that could be used as that temp if we push and pop it. */
420: rtx can_push_reg;
421: /* Nonzero means we need to push and pop a register to use it as TEMPREG. */
422: int needpush;
423: /* The amount the stack is decremented to save that register (if we do). */
424: int decrement;
425: /* Record which regs we restore, in case we branch to retry. */
426: char already_restored[FIRST_PSEUDO_REGISTER];
427:
428: bzero (already_restored, sizeof already_restored);
429:
430: /* Note: INSN can't be the last insn, since if it were,
431: no regs would live across it. */
432: insn = NEXT_INSN (insn);
433: if (insn == 0)
434: abort ();
435: /* Now we can insert before INSN.
436: That is convenient because we can insert them in the order
437: that they should ultimately appear. */
438:
439: /* Hair is needed because sometimes the addresses to restore from are
440: not valid (offsets too big).
441: So we need a reg, TEMPREG, to compute addresses in.
442:
443: We look first for an empty reg to use.
444: Sometimes no reg is empty. Then we push a reg, use it, and pop it.
445:
446: If all the suitable regs need to be restored,
447: that strategy won't work. So we restore all but one, using that one
448: as a temporary. Then we jump to `retry' to restore that one,
449: pushing and popping another (already restored) as a temporary. */
450:
451: retry:
452: needpush = 0;
453: tempreg = 0;
454: can_push_reg = 0;
455: restore_count = 0;
456:
457: /* Set NEEDPUSH if any restore-addresses are not valid memory addresses.
458: If any register is available, record it in TEMPREG.
459: Otherwise, one register yet to be restored goes in MAYBE_TEMPREG,
460: and can be used as TEMPREG for any other regs to be restored.
461: If any register doesn't need restoring, record it in CAN_PUSH_REG. */
462: for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
463: {
464: if (offset[regno] >= 0 && ! already_restored[regno])
465: {
466: rtx reg = save_reg_rtx[regno];
467: rtx addr1 = plus_constant (addr, offset[regno]);
468:
469: restore_count++;
470:
471: if (memory_address_p (GET_MODE (reg), addr1))
472: needpush = 1;
473:
474: /* Find a call-clobbered reg that needs restoring.
475: We can use it as a temporary if we defer restoring it. */
476: if (maybe_tempreg == 0)
477: {
478: maybe_tempreg = gen_rtx (REG, Pmode, regno);
479: /* Don't use it if not valid for addressing. */
480: if (! strict_memory_address_p (QImode, maybe_tempreg))
481: maybe_tempreg = 0;
482: }
483: }
484:
485: /* If any call-clobbered reg is dead, put it in TEMPREG.
486: It can be used as a temporary at no extra cost. */
487: if (tempreg == 0 && call_used_regs[regno] && ! fixed_regs[regno]
1.1.1.3 ! root 488: && offset[regno] < 0
1.1.1.2 root 489: && HARD_REGNO_MODE_OK (regno, Pmode))
490: {
491: tempreg = gen_rtx (REG, Pmode, regno);
492: /* Don't use it if not valid for addressing. */
493: if (! strict_memory_address_p (QImode, tempreg))
494: tempreg = 0;
495: }
496:
497: /* Any non-call-clobbered reg, put in CAN_PUSH_REG.
498: It can be used as a temporary if we push and pop it. */
499: if (can_push_reg == 0 && ! call_used_regs[regno]
500: && HARD_REGNO_MODE_OK (regno, Pmode))
501: {
502: can_push_reg = gen_rtx (REG, Pmode, regno);
503: /* Don't use it if not valid for addressing. */
504: if (! strict_memory_address_p (QImode, can_push_reg))
505: can_push_reg = 0;
506: }
507: /* Any reg we already restored can be a temporary
508: if we push and pop it. */
509: if (can_push_reg == 0 && already_restored[regno]
510: && HARD_REGNO_MODE_OK (regno, Pmode))
511: {
512: can_push_reg = gen_rtx (REG, Pmode, regno);
513: /* Don't use it if not valid for addressing. */
514: if (! strict_memory_address_p (QImode, can_push_reg))
515: can_push_reg = 0;
516: }
517: }
518:
519: /* If 2 or more regs need to be restored, use one as a temp reg
520: for the rest (if we need a tempreg). */
521: if (tempreg == 0 && maybe_tempreg != 0 && restore_count > 1)
522: tempreg = maybe_tempreg;
523:
524: /* Clear NEEDPUSH if we already found an empty reg. */
525: if (tempreg != 0)
526: needpush = 0;
527:
528: /* If we need a temp reg and none is free, make one free. */
529: if (needpush)
530: {
531: tempreg = can_push_reg;
532:
533: /* Push it on the stack. */
534: #ifdef STACK_GROWS_DOWNWARD
535: decrement = UNITS_PER_WORD;
536: #else
537: decrement = - UNITS_PER_WORD;
538: #endif
539:
540: emit_insn_before (gen_add2_insn (stack_pointer_rtx,
541: gen_rtx (CONST_INT, VOIDmode, -decrement)),
542: insn);
543: emit_insn_before (gen_move_insn (gen_rtx (MEM, Pmode, stack_pointer_rtx),
544: tempreg),
545: insn);
546: }
547:
548: /* Restore the regs we are supposed to restore, aside from TEMPREG.
549: Use TEMPREG for address calculations when needed. */
550: for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
551: if (offset[regno] >= 0 && ! already_restored[regno]
552: && tempreg != 0 && REGNO (tempreg) != regno)
1.1 root 553: {
554: rtx reg = save_reg_rtx[regno];
1.1.1.2 root 555: rtx addr1 = plus_constant (addr, offset[regno]);
556: rtx temp;
557: if (! memory_address_p (GET_MODE (reg), addr1))
558: {
559: if (GET_CODE (addr1) != PLUS)
560: abort ();
561: if (GET_CODE (XEXP (addr1, 1)) != CONST_INT
562: || GET_CODE (XEXP (addr1, 0)) != REG)
563: abort ();
564: emit_insn_before (gen_move_insn (tempreg, XEXP (addr1, 0)), insn);
565: emit_insn_before (gen_add2_insn (tempreg, XEXP (addr1, 1)), insn);
566: addr1 = tempreg;
567: }
568: temp = gen_rtx (MEM, GET_MODE (reg), addr1);
569: emit_insn_before (gen_move_insn (reg, temp), insn);
570: already_restored[regno] = 1;
1.1 root 571: }
1.1.1.2 root 572:
573: /* If we pushed TEMPREG to make it free, pop it. */
574: if (needpush)
575: {
576: emit_insn_before (gen_move_insn (tempreg,
577: gen_rtx (MEM, Pmode, stack_pointer_rtx)),
578: insn);
579: emit_insn_before (gen_add2_insn (stack_pointer_rtx,
580: gen_rtx (CONST_INT, VOIDmode, decrement)),
581: insn);
582: }
583:
584: /* If TEMPREG itself needs restoring, go back and restore it.
585: We can find a reg already restored to push and use as a temporary. */
586: if (tempreg != 0
587: && offset[REGNO (tempreg)] >= 0 && ! already_restored[REGNO (tempreg)])
588: goto retry;
1.1 root 589: }
590:
591: /* Return the address of a new block of size SIZE on the stack.
592: The old save block is at ADDR; ADDR is 0 if no block exists yet. */
593:
594: static rtx
595: grow_save_block (addr, size)
596: rtx addr;
597: int size;
598: {
599: rtx newaddr;
600:
601: /* Keep the size a multiple of the main allocation unit. */
602: size = (((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
603: / (BIGGEST_ALIGNMENT / BITS_PER_UNIT))
604: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
605:
606: /* If no save block exists yet, create one and return it. */
607: if (! addr)
608: {
609: save_block_size = size;
610: return XEXP (assign_stack_local (BLKmode, size), 0);
611: }
612:
613: /* Get a new block and coalesce it with the old one. */
614: newaddr = XEXP (assign_stack_local (BLKmode, size - save_block_size), 0);
615: if (GET_CODE (newaddr) == PLUS
616: && XEXP (newaddr, 0) == frame_pointer_rtx
617: && GET_CODE (XEXP (newaddr, 1)) == CONST_INT
618: && GET_CODE (addr) == PLUS
619: && XEXP (addr, 0) == frame_pointer_rtx
620: && GET_CODE (XEXP (addr, 1)) == CONST_INT
621: && ((INTVAL (XEXP (newaddr, 1)) - INTVAL (XEXP (addr, 1))
622: == size - save_block_size)
623: || (INTVAL (XEXP (addr, 1)) - INTVAL (XEXP (newaddr, 1))
624: == size - save_block_size)))
625: {
626: save_block_size = size;
627: if (INTVAL (XEXP (newaddr, 1)) < INTVAL (XEXP (addr, 1)))
628: return newaddr;
629: else
630: return addr;
631: }
632:
633: /* They didn't coalesce, find out why */
634: abort ();
635:
636: save_block_size = size;
637: return XEXP (assign_stack_local (BLKmode, size), 0);
638: }
639:
640: /* Return a machine mode that is legitimate for hard reg REGNO
641: and large enough to save the whole register. */
642:
643: static enum machine_mode
644: choose_hard_reg_mode (regno)
645: int regno;
646: {
647: enum reg_class class = REGNO_REG_CLASS (regno);
648:
649: if (CLASS_MAX_NREGS (class, DImode) == 1
650: && HARD_REGNO_MODE_OK (regno, DImode))
651: return DImode;
652: else if (CLASS_MAX_NREGS (class, DFmode) == 1
653: && HARD_REGNO_MODE_OK (regno, DFmode))
654: return DFmode;
655: else if (CLASS_MAX_NREGS (class, SImode) == 1
656: && HARD_REGNO_MODE_OK (regno, SImode))
657: return SImode;
658: else if (CLASS_MAX_NREGS (class, SFmode) == 1
659: && HARD_REGNO_MODE_OK (regno, SFmode))
660: return SFmode;
661: else if (CLASS_MAX_NREGS (class, HImode) == 1
662: && HARD_REGNO_MODE_OK (regno, HImode))
663: return HImode;
664: else
665: abort ();
666: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.