m68k.c
来自「gcc3.2.1源代码」· C语言 代码 · 共 2,431 行 · 第 1/5 页
C
2,431 行
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 voidm68k_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; 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); } if (current_function_pops_args) fprintf (stream, "\trtd #%d\n", current_function_pops_args); else fprintf (stream, "\trts\n");}#else /* !CRDS && ! (NEWS && MOTOROLA) && ! (DPX2 && MOTOROLA) */static voidm68k_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; HOST_WIDE_INT fsize = (size + 3) & -4; int big = 0; rtx insn = get_last_insn (); int restore_from_sp = 0; /* 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. */ asm_fprintf (stream, "\tnop\n"); return; }#ifdef FUNCTION_EXTRA_EPILOGUE FUNCTION_EXTRA_EPILOGUE (stream, size);#endif nregs = 0; fmask = 0; fpoffset = 0;#ifdef SUPPORT_SUN_FPA for (regno = 24 ; regno < 56 ; regno++) if (regs_ever_live[regno] && ! call_used_regs[regno]) nregs++; fpoffset = nregs * 8;#endif nregs = 0; if (TARGET_68881) { 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; } if (flag_pic && current_function_uses_pic_offset_table) { nregs++; mask |= 1 << PIC_OFFSET_TABLE_REGNUM; } offset = foffset + nregs * 4; /* FIXME : leaf_function_p below is too strong. What we really need to know there is if there could be pending stack adjustment needed at that point. */ restore_from_sp = ! frame_pointer_needed || (! current_function_calls_alloca && leaf_function_p ()); if (offset + fsize >= 0x8000 && ! restore_from_sp && (mask || fmask || fpoffset)) {#ifdef MOTOROLA asm_fprintf (stream, "\t%Omove.l %0I%d,%Ra1\n", -fsize);#else asm_fprintf (stream, "\tmovel %0I%d,%Ra1\n", -fsize);#endif fsize = 0, big = 1; } if (TARGET_5200 || 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) {#ifdef MOTOROLA asm_fprintf (stream, "\t%Omove.l -%d(%s,%Ra1.l),%s\n", offset + fsize, reg_names[FRAME_POINTER_REGNUM], reg_names[i]);#else asm_fprintf (stream, "\tmovel %s@(-%d,%Ra1:l),%s\n", reg_names[FRAME_POINTER_REGNUM], offset + fsize, reg_names[i]);#endif } else if (restore_from_sp) {#ifdef MOTOROLA asm_fprintf (stream, "\t%Omove.l (%Rsp)+,%s\n", reg_names[i]);#else asm_fprintf (stream, "\tmovel %Rsp@+,%s\n", reg_names[i]);#endif } else {#ifdef MOTOROLA asm_fprintf (stream, "\t%Omove.l -%d(%s),%s\n", offset + fsize, reg_names[FRAME_POINTER_REGNUM], reg_names[i]);#else asm_fprintf (stream, "\tmovel %s@(-%d),%s\n", reg_names[FRAME_POINTER_REGNUM], offset + fsize, reg_names[i]);#endif } offset = offset - 4; } } else if (mask) { if (big) {#ifdef MOTOROLA asm_fprintf (stream, "\tmovm.l -%d(%s,%Ra1.l),%0I0x%x\n", offset + fsize, reg_names[FRAME_POINTER_REGNUM], mask);#else asm_fprintf (stream, "\tmoveml %s@(-%d,%Ra1:l),%0I0x%x\n", reg_names[FRAME_POINTER_REGNUM], offset + fsize, mask);#endif } else if (restore_from_sp) {#ifdef MOTOROLA asm_fprintf (stream, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask);#else asm_fprintf (stream, "\tmoveml %Rsp@+,%0I0x%x\n", mask);#endif } else {#ifdef MOTOROLA asm_fprintf (stream, "\tmovm.l -%d(%s),%0I0x%x\n", offset + fsize, reg_names[FRAME_POINTER_REGNUM], mask);#else asm_fprintf (stream, "\tmoveml %s@(-%d),%0I0x%x\n", reg_names[FRAME_POINTER_REGNUM], offset + fsize, mask);#endif } } if (fmask) { if (big) {#ifdef MOTOROLA asm_fprintf (stream, "\tfmovm -%d(%s,%Ra1.l),%0I0x%x\n", foffset + fsize, reg_names[FRAME_POINTER_REGNUM], fmask);#else asm_fprintf (stream, "\tfmovem %s@(-%d,%Ra1:l),%0I0x%x\n", reg_names[FRAME_POINTER_REGNUM], foffset + fsize, fmask);#endif } else if (restore_from_sp) {#ifdef MOTOROLA asm_fprintf (stream, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask);#else asm_fprintf (stream, "\tfmovem %Rsp@+,%0I0x%x\n", fmask);#endif } else {#ifdef MOTOROLA asm_fprintf (stream, "\tfmovm -%d(%s),%0I0x%x\n", foffset + fsize, reg_names[FRAME_POINTER_REGNUM], fmask);#else asm_fprintf (stream, "\tfmovem %s@(-%d),%0I0x%x\n", reg_names[FRAME_POINTER_REGNUM], foffset + fsize, fmask);#endif } } if (fpoffset != 0) for (regno = 55; regno >= 24; regno--) if (regs_ever_live[regno] && ! call_used_regs[regno]) { if (big) {#ifdef MOTOROLA asm_fprintf (stream, "\tfpmovd -%d(%s,%Ra1.l), %s\n", fpoffset + fsize, reg_names[FRAME_POINTER_REGNUM], reg_names[regno]);#else asm_fprintf (stream, "\tfpmoved %s@(-%d,%Ra1:l), %s\n", reg_names[FRAME_POINTER_REGNUM], fpoffset + fsize, reg_names[regno]);#endif } else if (restore_from_sp) {#ifdef MOTOROLA asm_fprintf (stream, "\tfpmovd (%Rsp)+,%s\n", reg_names[regno]);#else asm_fprintf (stream, "\tfpmoved %Rsp@+, %s\n", reg_names[regno]);#endif } else {#ifdef MOTOROLA asm_fprintf (stream, "\tfpmovd -%d(%s), %s\n", fpoffset + fsize, reg_names[FRAME_POINTER_REGNUM], reg_names[regno]);#else asm_fprintf (stream, "\tfpmoved %s@(-%d), %s\n", reg_names[FRAME_POINTER_REGNUM], fpoffset + fsize, reg_names[regno]);#endif } fpoffset -= 8; } if (frame_pointer_needed) fprintf (stream, "\tunlk %s\n", reg_names[FRAME_POINTER_REGNUM]); else if (fsize) {#ifndef NO_ADDSUB_Q if (fsize + 4 <= 8) { if (!TARGET_5200) {#ifdef MOTOROLA asm_fprintf (stream, "\taddq.w %0I%d,%Rsp\n", fsize + 4);#else asm_fprintf (stream, "\taddqw %0I%d,%Rsp\n", fsize + 4);#endif } else {#ifdef MOTOROLA asm_fprintf (stream, "\taddq.l %0I%d,%Rsp\n", fsize + 4);#else asm_fprintf (stream, "\taddql %0I%d,%Rsp\n", fsize + 4);#endif } } else if (fsize + 4 <= 16 && TARGET_CPU32) { /* On the CPU32 it is faster to use two addqw instructions to add a small integer (8 < N <= 16) to a register. */ /* asm_fprintf() cannot handle %. */#ifdef MOTOROLA asm_fprintf (stream, "\taddq.w %0I8,%Rsp\n\taddq.w %0I%d,%Rsp\n", fsize + 4 - 8);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?