📄 m68k.c
字号:
{#ifdef MOTOROLA asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n", reg_names[regno]);#else asm_fprintf (stream, "\tfpmoved %s,%Rsp@-\n", reg_names[regno]);#endif if (dwarf2out_do_frame ()) { char *l = dwarf2out_cfi_label (); cfa_store_offset += 8; if (! frame_pointer_needed) { cfa_offset = cfa_store_offset; dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset); } dwarf2out_reg_save (l, regno, -cfa_store_offset); } }#endif if (TARGET_68881) { for (regno = 16; regno < 24; regno++) if (m68k_save_reg (regno)) { mask |= 1 << (regno - 16); num_saved_regs++; } if ((mask & 0xff) != 0) {#ifdef MOTOROLA asm_fprintf (stream, "\tfmovm %0I0x%x,-(%Rsp)\n", mask & 0xff);#else asm_fprintf (stream, "\tfmovem %0I0x%x,%Rsp@-\n", mask & 0xff);#endif if (dwarf2out_do_frame ()) { char *l = (char *) dwarf2out_cfi_label (); int n_regs; cfa_store_offset += num_saved_regs * 12; if (! frame_pointer_needed) { cfa_offset = cfa_store_offset; dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset); } for (regno = 16, n_regs = 0; regno < 24; regno++) if (mask & (1 << (regno - 16))) dwarf2out_reg_save (l, regno, -cfa_store_offset + n_regs++ * 12); } } mask = 0; num_saved_regs = 0; } for (regno = 0; regno < 16; regno++) if (m68k_save_reg (regno)) { mask |= 1 << (15 - regno); num_saved_regs++; }#if NEED_PROBE#ifdef MOTOROLA asm_fprintf (stream, "\ttst.l %d(%Rsp)\n", NEED_PROBE - num_saved_regs * 4);#else asm_fprintf (stream, "\ttstl %Rsp@(%d)\n", NEED_PROBE - num_saved_regs * 4);#endif#endif /* If the stack limit is not a symbol, check it here. This has the disadvantage that it may be too late... */ if (current_function_limit_stack) { if (REG_P (stack_limit_rtx)) {#if defined (MOTOROLA) asm_fprintf (stream, "\tcmp.l %s,%Rsp\n\ttrapcs\n", reg_names[REGNO (stack_limit_rtx)]);#else asm_fprintf (stream, "\tcmpl %s,%Rsp\n\ttrapcs\n", reg_names[REGNO (stack_limit_rtx)]);#endif } else if (GET_CODE (stack_limit_rtx) != SYMBOL_REF) warning ("stack limit expression is not supported"); } if (num_saved_regs <= 2) { /* Store each separately in the same order moveml uses. 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)) { asm_fprintf (stream,#ifdef MOTOROLA "\t%Omove.l %s,-(%Rsp)\n",#else "\tmovel %s,%Rsp@-\n",#endif reg_names[15 - i]); if (dwarf2out_do_frame ()) { char *l = (char *) dwarf2out_cfi_label (); cfa_store_offset += 4; if (! frame_pointer_needed) { cfa_offset = cfa_store_offset; dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset); } dwarf2out_reg_save (l, 15 - i, -cfa_store_offset); } } } else if (mask) { if (TARGET_5200) { /* The coldfire does not support the predecrement form of the movml instruction, so we must adjust the stack pointer and then use the plain address register indirect mode. We also have to invert the register save mask to use the new mode. FIXME: if num_saved_regs was calculated earlier, we could combine the stack pointer adjustment with any adjustment done when the initial stack frame is created. This would save an instruction */ int newmask = 0; int i; for (i = 0; i < 16; i++) if (mask & (1 << i)) newmask |= (1 << (15-i));#ifdef MOTOROLA asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", -num_saved_regs*4); asm_fprintf (stream, "\tmovm.l %0I0x%x,(%Rsp)\n", newmask);#else asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", -num_saved_regs*4); asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@\n", newmask);#endif } else {#ifdef MOTOROLA asm_fprintf (stream, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask);#else asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@-\n", mask);#endif } if (dwarf2out_do_frame ()) { char *l = (char *) dwarf2out_cfi_label (); int n_regs; cfa_store_offset += num_saved_regs * 4; if (! frame_pointer_needed) { cfa_offset = cfa_store_offset; dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset); } for (regno = 0, n_regs = 0; regno < 16; regno++) if (mask & (1 << (15 - regno))) dwarf2out_reg_save (l, regno, -cfa_store_offset + n_regs++ * 4); } } if (flag_pic && current_function_uses_pic_offset_table) {#ifdef MOTOROLA asm_fprintf (stream, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n", reg_names[PIC_OFFSET_TABLE_REGNUM]);#else asm_fprintf (stream, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n", reg_names[PIC_OFFSET_TABLE_REGNUM]); asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n", reg_names[PIC_OFFSET_TABLE_REGNUM], reg_names[PIC_OFFSET_TABLE_REGNUM]);#endif }}#endif /* !CRDS *//* Return true if this function's epilogue can be output as RTL. */intuse_return_insn (){ int regno; if (!reload_completed || frame_pointer_needed || get_frame_size () != 0) return 0; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (m68k_save_reg (regno)) 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 CRDSstatic 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; nregs = 0; fmask = 0; fpoffset = 0; for (regno = 16; regno < 24; regno++) if (m68k_save_reg (regno)) { nregs++; fmask |= 1 << (23 - regno); } foffset = fpoffset + nregs * 12; nregs = 0; mask = 0; for (regno = 0; regno < 16; regno++) if (m68k_save_reg (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 (m68k_save_reg (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_calls_eh_return) fprintf (stream, "\tadd.l a0,sp\n"); if (current_function_pops_args) fprintf (stream, "\trtd $%d\n", current_function_pops_args); else fprintf (stream, "\trts\n");}#else /* !CRDS */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. */ 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 (m68k_save_reg (regno)) nregs++; fpoffset = nregs * 8;#endif nregs = 0; if (TARGET_68881) { for (regno = 16; regno < 24; regno++) if (m68k_save_reg (regno)) { nregs++; fmask |= 1 << (23 - regno); } } foffset = fpoffset + nregs * 12; nregs = 0; mask = 0; for (regno = 0; regno < 16; regno++) if (m68k_save_reg (regno)) { nregs++; mask |= 1 << regno; } 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 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -