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 + -
显示快捷键?