-}
-#endif /* ! (DPX2 && MOTOROLA) */
-#endif /* ! (NEWS && MOTOROLA) */
-#endif /* !CRDS */
-\f
-/* Return true if this function's epilogue can be output as RTL. */
-
-int
-use_return_insn ()
-{
- int regno;
-
- if (!reload_completed || frame_pointer_needed || get_frame_size () != 0)
- return 0;
-
- /* Copied from output_function_epilogue (). We should probably create a
- separate layout routine to perform the common work. */
-
- for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++)
- if (regs_ever_live[regno] && ! call_used_regs[regno])
- return 0;
-
- if (flag_pic && current_function_uses_pic_offset_table)
- return 0;
-
- return 1;
-}
-
-/* This function generates the assembly code for function exit,
- on machines that need it.
-
- The function epilogue should not depend on the current stack pointer!
- It should use the frame pointer only, if there is a frame pointer.
- This is mandatory because of alloca; we also take advantage of it to
- omit stack adjustments before returning. */
-
-#ifdef CRDS
-
-static void
-m68k_output_function_epilogue (stream, size)
- FILE *stream;
- HOST_WIDE_INT size;
-{
- register int regno;
- register int mask, fmask;
- register int nregs;
- HOST_WIDE_INT offset, foffset, fpoffset;
- extern char call_used_regs[];
- HOST_WIDE_INT fsize = ((size) + 3) & -4;
- int big = 0;
-
- nregs = 0; fmask = 0; fpoffset = 0;
- for (regno = 16; regno < 24; regno++)
- if (regs_ever_live[regno] && ! call_used_regs[regno])
- {
- nregs++;
- fmask |= 1 << (23 - regno);
- }
-
- foffset = fpoffset + nregs * 12;
- nregs = 0; mask = 0;
- if (frame_pointer_needed)
- regs_ever_live[FRAME_POINTER_REGNUM] = 0;
-
- for (regno = 0; regno < 16; regno++)
- if (regs_ever_live[regno] && ! call_used_regs[regno])
- {
- nregs++;
- mask |= 1 << regno;
- }
-
- offset = foffset + nregs * 4;
- if (offset + fsize >= 0x8000
- && frame_pointer_needed
- && (mask || fmask || fpoffset))
- {
- fprintf (stream, "\tmovel $%d,a0\n", -fsize);
- fsize = 0, big = 1;
- }
-
- if (exact_log2 (mask) >= 0)
- {
- if (big)
- fprintf (stream, "\tmovel -%d(a6,a0.l),%s\n",
- offset + fsize, reg_names[exact_log2 (mask)]);
- else if (! frame_pointer_needed)
- fprintf (stream, "\tmovel (sp)+,%s\n",
- reg_names[exact_log2 (mask)]);
- else
- fprintf (stream, "\tmovel -%d(a6),%s\n",
- offset + fsize, reg_names[exact_log2 (mask)]);
- }
- else if (mask)
- {
- if (big)
- fprintf (stream, "\tmovem -%d(a6,a0.l),$0x%x\n",
- offset + fsize, mask);
- else if (! frame_pointer_needed)
- fprintf (stream, "\tmovem (sp)+,$0x%x\n", mask);
- else
- fprintf (stream, "\tmovem -%d(a6),$0x%x\n",
- offset + fsize, mask);
- }
-
- if (fmask)
- {
- if (big)
- fprintf (stream, "\tfmovem -%d(a6,a0.l),$0x%x\n",
- foffset + fsize, fmask);
- else if (! frame_pointer_needed)
- fprintf (stream, "\tfmovem (sp)+,$0x%x\n", fmask);
- else
- fprintf (stream, "\tfmovem -%d(a6),$0x%x\n",
- foffset + fsize, fmask);
- }
-
- if (fpoffset != 0)
- for (regno = 55; regno >= 24; regno--)
- if (regs_ever_live[regno] && ! call_used_regs[regno])
- {
- if (big)
- fprintf(stream, "\tfpmoved -%d(a6,a0.l), %s\n",
- fpoffset + fsize, reg_names[regno]);
- else if (! frame_pointer_needed)
- fprintf(stream, "\tfpmoved (sp)+, %s\n",
- reg_names[regno]);
- else
- fprintf(stream, "\tfpmoved -%d(a6), %s\n",
- fpoffset + fsize, reg_names[regno]);
- fpoffset -= 8;
- }
-
- if (frame_pointer_needed)
- fprintf (stream, "\tunlk a6\n");
- else if (fsize)
- {
- if (fsize + 4 < 0x8000)
- fprintf (stream, "\tadd.w #%d,sp\n", fsize + 4);
- else
- fprintf (stream, "\tadd.l #%d,sp\n", fsize + 4);
- }
-
- if (current_function_pops_args)
- fprintf (stream, "\trtd $%d\n", current_function_pops_args);
- else
- fprintf (stream, "\trts\n");
-}
-
-#else
-#if defined (DPX2) && defined (MOTOROLA)
-
-static void
-m68k_output_function_epilogue (stream, size)
- FILE *stream;
- HOST_WIDE_INT size;
-{
- register int regno;
- register int mask, fmask;
- register int nregs;
- HOST_WIDE_INT offset, foffset, fpoffset, first = 1;
- extern char call_used_regs[];
- HOST_WIDE_INT fsize = ((size) + 3) & -4;
- int big = 0;
- rtx insn = get_last_insn ();
-
- /* If the last insn was a BARRIER, we don't have to write any code. */
- if (GET_CODE (insn) == NOTE)
- insn = prev_nonnote_insn (insn);
- if (insn && GET_CODE (insn) == BARRIER)
- {
- /* Output just a no-op so that debuggers don't get confused
- about which function the pc is in at this address. */
- fprintf (stream, "\tnop\n");
- return;
- }
-
- nregs = 0; fmask = 0; fpoffset = 0;
- for (regno = 16; regno < 24; regno++)
- if (regs_ever_live[regno] && ! call_used_regs[regno])
- {
- nregs++;
- fmask |= 1 << (23 - regno);
- }
-
- foffset = fpoffset + nregs * 12;
- nregs = 0; mask = 0;
- if (frame_pointer_needed)
- regs_ever_live[FRAME_POINTER_REGNUM] = 0;
-
- for (regno = 0; regno < 16; regno++)
- if (regs_ever_live[regno] && ! call_used_regs[regno])
- {
- nregs++;
- mask |= 1 << regno;
- }
-
- offset = foffset + nregs * 4;
- if (offset + fsize >= 0x8000
- && frame_pointer_needed
- && (mask || fmask || fpoffset))
- {
- fprintf (stream, "\tmove.l #%d,a0\n", -fsize);
- fsize = 0, big = 1;
- }
-
- if (nregs <= 2)
- {
- /* Restore each separately in the same order moveml does.
- Using two movel instructions instead of a single moveml
- is about 15% faster for the 68020 and 68030 at no expense
- in code size. */
-
- int i;
-
- /* Undo the work from above. */
- for (i = 0; i< 16; i++)
- if (mask & (1 << i))
- {
- if (big)
- fprintf (stream, "\tmove.l -%d(%s,a0.l),%s\n",
- offset + fsize,
- reg_names[FRAME_POINTER_REGNUM],
- reg_names[i]);
- else if (! frame_pointer_needed)
- fprintf (stream, "\tmove.l (sp)+,%s\n",
- reg_names[i]);
- else
- fprintf (stream, "\tmove.l -%d(%s),%s\n",
- offset + fsize,
- reg_names[FRAME_POINTER_REGNUM],
- reg_names[i]);
- offset = offset - 4;
- }
- }
- else if (mask)
- {
- first = 1;
- for (regno = 0; regno < 16; regno++)
- if (mask & (1 << regno))
- {
- if (first && big)
- {
- fprintf (stream, "\tmovem.l -%d(%s,a0.l),%s",
- offset + fsize,
- reg_names[FRAME_POINTER_REGNUM],
- reg_names[regno]);
- first = 0;
- }
- else if (first && ! frame_pointer_needed)
- {
- fprintf (stream, "\tmovem.l (sp)+,%s",
- reg_names[regno]);
- first = 0;
- }
- else if (first)
- {
- fprintf (stream, "\tmovem.l -%d(%s),%s",
- offset + fsize,
- reg_names[FRAME_POINTER_REGNUM],
- reg_names[regno]);
- first = 0;
- }
- else
- fprintf (stream, "/%s", reg_names[regno]);
- }
- fprintf (stream, "\n");
- }
-
- if (fmask)
- {
- first = 1;
- for (regno = 16; regno < 24; regno++)
- if (fmask & (1 << (23 - regno)))
- {
- if (first && big)
- {
- fprintf (stream, "\tfmovem.x -%d(%s,a0.l),%s",
- foffset + fsize,
- reg_names[FRAME_POINTER_REGNUM],
- reg_names[regno]);
- first = 0;
- }
- else if (first && ! frame_pointer_needed)
- {
- fprintf (stream, "\tfmovem.x (sp)+,%s",
- reg_names[regno]);
- first = 0;
- }
- else if (first)
- {
- fprintf (stream, "\tfmovem.x -%d(%s),%s",
- foffset + fsize,
- reg_names[FRAME_POINTER_REGNUM],
- reg_names[regno]);
- first = 0;
- }
- else
- fprintf (stream, "/%s", reg_names[regno]);
- }
- fprintf (stream, "\n");
- }
-
- if (frame_pointer_needed)
- fprintf (stream, "\tunlk %s\n",
- reg_names[FRAME_POINTER_REGNUM]);
- else if (fsize)
- {
- if (fsize + 4 < 0x8000)
- fprintf (stream, "\tadd.w #%d,sp\n", fsize + 4);
- else
- fprintf (stream, "\tadd.l #%d,sp\n", fsize + 4);
- }
-
- if (current_function_pops_args)
- fprintf (stream, "\trtd #%d\n", current_function_pops_args);
- else
- fprintf (stream, "\trts\n");
-}
-
-#else
-#if defined (NEWS) && defined (MOTOROLA)
-
-static void
-m68k_output_function_epilogue (stream, size)
- FILE *stream;
- HOST_WIDE_INT size;
-{
- register int regno;
- register int mask, fmask;
- register int nregs;
- HOST_WIDE_INT offset, foffset;
- extern char call_used_regs[];
- HOST_WIDE_INT fsize = ((size) + 3) & -4;
- int big = 0;
-
- nregs = 0; fmask = 0;
- for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (regs_ever_live[regno] && ! call_used_regs[regno])
- {
- nregs++;
- fmask |= 1 << (23 - regno);
- }
-
- foffset = nregs * 12;
- nregs = 0; mask = 0;
- if (frame_pointer_needed)
- regs_ever_live[FRAME_POINTER_REGNUM] = 0;
-
- for (regno = 0; regno < 16; regno++)
- if (regs_ever_live[regno] && ! call_used_regs[regno])
- {
- nregs++;
- mask |= 1 << regno;
- }
-
- offset = foffset + nregs * 4;
- if (offset + fsize >= 0x8000
- && frame_pointer_needed
- && (mask || fmask))
- {
- fprintf (stream, "\tmove.l #%d,a0\n", -fsize);
- fsize = 0, big = 1;
- }
-
- if (exact_log2 (mask) >= 0)
- {
- if (big)
- fprintf (stream, "\tmove.l (-%d,fp,a0.l),%s\n",
- offset + fsize, reg_names[exact_log2 (mask)]);
- else if (! frame_pointer_needed)
- fprintf (stream, "\tmove.l (sp)+,%s\n",
- reg_names[exact_log2 (mask)]);
- else
- fprintf (stream, "\tmove.l (-%d,fp),%s\n",
- offset + fsize, reg_names[exact_log2 (mask)]);
- }
- else if (mask)
- {
- if (big)
- fprintf (stream, "\tmovem.l (-%d,fp,a0.l),#0x%x\n",
- offset + fsize, mask);
- else if (! frame_pointer_needed)
- fprintf (stream, "\tmovem.l (sp)+,#0x%x\n", mask);
- else
- fprintf (stream, "\tmovem.l (-%d,fp),#0x%x\n",
- offset + fsize, mask);
- }
-
- if (fmask)
- {
- if (big)
- fprintf (stream, "\tfmovem.x (-%d,fp,a0.l),#0x%x\n",
- foffset + fsize, fmask);
- else if (! frame_pointer_needed)
- fprintf (stream, "\tfmovem.x (sp)+,#0x%x\n", fmask);
- else
- fprintf (stream, "\tfmovem.x (-%d,fp),#0x%x\n",
- foffset + fsize, fmask);
- }
-
- if (frame_pointer_needed)
- fprintf (stream, "\tunlk fp\n");
- else if (fsize)
- {
- if (fsize + 4 < 0x8000)
- fprintf (stream, "\tadd.w #%d,sp\n", fsize + 4);
- else
- fprintf (stream, "\tadd.l #%d,sp\n", fsize + 4);
- }