⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mn10300.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
  for (i = 0; i < FIRST_EXTENDED_REGNUM; i++)    if ((mask & (1 << i)) != 0)      {	if (need_comma)	  fputc (',', file);	fputs (reg_names [i], file);	need_comma = 1;      }  if ((mask & 0x3c000) != 0)    {      if ((mask & 0x3c000) != 0x3c000)	abort();      if (need_comma)	fputc (',', file);      fputs ("exreg1", file);      need_comma = 1;    }  fputc (']', file);}intcan_use_return_insn (void){  /* size includes the fixed stack space needed for function calls.  */  int size = get_frame_size () + current_function_outgoing_args_size;  /* And space for the return pointer.  */  size += current_function_outgoing_args_size ? 4 : 0;  return (reload_completed	  && size == 0	  && !regs_ever_live[2]	  && !regs_ever_live[3]	  && !regs_ever_live[6]	  && !regs_ever_live[7]	  && !regs_ever_live[14]	  && !regs_ever_live[15]	  && !regs_ever_live[16]	  && !regs_ever_live[17]	  && fp_regs_to_save () == 0	  && !frame_pointer_needed);}/* Returns the set of live, callee-saved registers as a bitmask.  The   callee-saved extended registers cannot be stored individually, so   all of them will be included in the mask if any one of them is used.  */intmn10300_get_live_callee_saved_regs (void){  int mask;  int i;  mask = 0;  for (i = 0; i <= LAST_EXTENDED_REGNUM; i++)    if (regs_ever_live[i] && ! call_used_regs[i])      mask |= (1 << i);  if ((mask & 0x3c000) != 0)    mask |= 0x3c000;  return mask;}/* Generate an instruction that pushes several registers onto the stack.   Register K will be saved if bit K in MASK is set.  The function does   nothing if MASK is zero.   To be compatible with the "movm" instruction, the lowest-numbered   register must be stored in the lowest slot.  If MASK is the set   { R1,...,RN }, where R1...RN are ordered least first, the generated   instruction will have the form:       (parallel         (set (reg:SI 9) (plus:SI (reg:SI 9) (const_int -N*4)))	 (set (mem:SI (plus:SI (reg:SI 9)	                       (const_int -1*4)))	      (reg:SI RN))	 ...	 (set (mem:SI (plus:SI (reg:SI 9)	                       (const_int -N*4)))	      (reg:SI R1))) */voidmn10300_gen_multiple_store (int mask){  if (mask != 0)    {      int i;      int count;      rtx par;      int pari;      /* Count how many registers need to be saved.  */      count = 0;      for (i = 0; i <= LAST_EXTENDED_REGNUM; i++)	if ((mask & (1 << i)) != 0)	  count += 1;      /* We need one PARALLEL element to update the stack pointer and	 an additional element for each register that is stored.  */      par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));      /* Create the instruction that updates the stack pointer.  */      XVECEXP (par, 0, 0)	= gen_rtx_SET (SImode,		       stack_pointer_rtx,		       gen_rtx_PLUS (SImode,				     stack_pointer_rtx,				     GEN_INT (-count * 4)));      /* Create each store.  */      pari = 1;      for (i = LAST_EXTENDED_REGNUM; i >= 0; i--)	if ((mask & (1 << i)) != 0)	  {	    rtx address = gen_rtx_PLUS (SImode,					stack_pointer_rtx,					GEN_INT (-pari * 4));	    XVECEXP(par, 0, pari)	      = gen_rtx_SET (VOIDmode,			     gen_rtx_MEM (SImode, address),			     gen_rtx_REG (SImode, i));	    pari += 1;	  }      par = emit_insn (par);      RTX_FRAME_RELATED_P (par) = 1;    }}voidexpand_prologue (void){  HOST_WIDE_INT size;  /* SIZE includes the fixed stack space needed for function calls.  */  size = get_frame_size () + current_function_outgoing_args_size;  size += (current_function_outgoing_args_size ? 4 : 0);  /* If we use any of the callee-saved registers, save them now.  */  mn10300_gen_multiple_store (mn10300_get_live_callee_saved_regs ());  if (TARGET_AM33_2 && fp_regs_to_save ())    {      int num_regs_to_save = fp_regs_to_save (), i;      HOST_WIDE_INT xsize;      enum { save_sp_merge,	     save_sp_no_merge,	     save_sp_partial_merge,	     save_a0_merge,	     save_a0_no_merge } strategy;      unsigned int strategy_size = (unsigned)-1, this_strategy_size;      rtx reg;      rtx insn;      /* We have several different strategies to save FP registers.	 We can store them using SP offsets, which is beneficial if	 there are just a few registers to save, or we can use `a0' in	 post-increment mode (`a0' is the only call-clobbered address	 register that is never used to pass information to a	 function).  Furthermore, if we don't need a frame pointer, we	 can merge the two SP adds into a single one, but this isn't	 always beneficial; sometimes we can just split the two adds	 so that we don't exceed a 16-bit constant size.  The code	 below will select which strategy to use, so as to generate	 smallest code.  Ties are broken in favor or shorter sequences	 (in terms of number of instructions).  */#define SIZE_ADD_AX(S) ((((S) >= (1 << 15)) || ((S) < -(1 << 15))) ? 6 \			: (((S) >= (1 << 7)) || ((S) < -(1 << 7))) ? 4 : 2)#define SIZE_ADD_SP(S) ((((S) >= (1 << 15)) || ((S) < -(1 << 15))) ? 6 \			: (((S) >= (1 << 7)) || ((S) < -(1 << 7))) ? 4 : 3)#define SIZE_FMOV_LIMIT(S,N,L,SIZE1,SIZE2,ELSE) \  (((S) >= (L)) ? (SIZE1) * (N) \   : ((S) + 4 * (N) >= (L)) ? (((L) - (S)) / 4 * (SIZE2) \			       + ((S) + 4 * (N) - (L)) / 4 * (SIZE1)) \   : (ELSE))#define SIZE_FMOV_SP_(S,N) \  (SIZE_FMOV_LIMIT ((S), (N), (1 << 24), 7, 6, \                   SIZE_FMOV_LIMIT ((S), (N), (1 << 8), 6, 4, \				    (S) ? 4 * (N) : 3 + 4 * ((N) - 1))))#define SIZE_FMOV_SP(S,N) (SIZE_FMOV_SP_ ((unsigned HOST_WIDE_INT)(S), (N)))      /* Consider alternative save_sp_merge only if we don't need the	 frame pointer and size is nonzero.  */      if (! frame_pointer_needed && size)	{	  /* Insn: add -(size + 4 * num_regs_to_save), sp.  */	  this_strategy_size = SIZE_ADD_SP (-(size + 4 * num_regs_to_save));	  /* Insn: fmov fs#, (##, sp), for each fs# to be saved.  */	  this_strategy_size += SIZE_FMOV_SP (size, num_regs_to_save);	  if (this_strategy_size < strategy_size)	    {	      strategy = save_sp_merge;	      strategy_size = this_strategy_size;	    }	}      /* Consider alternative save_sp_no_merge unconditionally.  */      /* Insn: add -4 * num_regs_to_save, sp.  */      this_strategy_size = SIZE_ADD_SP (-4 * num_regs_to_save);      /* Insn: fmov fs#, (##, sp), for each fs# to be saved.  */      this_strategy_size += SIZE_FMOV_SP (0, num_regs_to_save);      if (size)	{	  /* Insn: add -size, sp.  */	  this_strategy_size += SIZE_ADD_SP (-size);	}      if (this_strategy_size < strategy_size)	{	  strategy = save_sp_no_merge;	  strategy_size = this_strategy_size;	}      /* Consider alternative save_sp_partial_merge only if we don't	 need a frame pointer and size is reasonably large.  */      if (! frame_pointer_needed && size + 4 * num_regs_to_save > 128)	{	  /* Insn: add -128, sp.  */	  this_strategy_size = SIZE_ADD_SP (-128);	  /* Insn: fmov fs#, (##, sp), for each fs# to be saved.  */	  this_strategy_size += SIZE_FMOV_SP (128 - 4 * num_regs_to_save,					      num_regs_to_save);	  if (size)	    {	      /* Insn: add 128-size, sp.  */	      this_strategy_size += SIZE_ADD_SP (128 - size);	    }	  if (this_strategy_size < strategy_size)	    {	      strategy = save_sp_partial_merge;	      strategy_size = this_strategy_size;	    }	}      /* Consider alternative save_a0_merge only if we don't need a	 frame pointer, size is nonzero and the user hasn't	 changed the calling conventions of a0.  */      if (! frame_pointer_needed && size	  && call_used_regs[FIRST_ADDRESS_REGNUM]	  && ! fixed_regs[FIRST_ADDRESS_REGNUM])	{	  /* Insn: add -(size + 4 * num_regs_to_save), sp.  */	  this_strategy_size = SIZE_ADD_SP (-(size + 4 * num_regs_to_save));	  /* Insn: mov sp, a0.  */	  this_strategy_size++;	  if (size)	    {	      /* Insn: add size, a0.  */	      this_strategy_size += SIZE_ADD_AX (size);	    }	  /* Insn: fmov fs#, (a0+), for each fs# to be saved.  */	  this_strategy_size += 3 * num_regs_to_save;	  if (this_strategy_size < strategy_size)	    {	      strategy = save_a0_merge;	      strategy_size = this_strategy_size;	    }	}      /* Consider alternative save_a0_no_merge if the user hasn't	 changed the calling conventions of a0.  */      if (call_used_regs[FIRST_ADDRESS_REGNUM]	  && ! fixed_regs[FIRST_ADDRESS_REGNUM])	{	  /* Insn: add -4 * num_regs_to_save, sp.  */	  this_strategy_size = SIZE_ADD_SP (-4 * num_regs_to_save);	  /* Insn: mov sp, a0.  */	  this_strategy_size++;	  /* Insn: fmov fs#, (a0+), for each fs# to be saved.  */	  this_strategy_size += 3 * num_regs_to_save;	  if (size)	    {	      /* Insn: add -size, sp.  */	      this_strategy_size += SIZE_ADD_SP (-size);	    }	  if (this_strategy_size < strategy_size)	    {	      strategy = save_a0_no_merge;	      strategy_size = this_strategy_size;	    }	}      /* Emit the initial SP add, common to all strategies.  */      switch (strategy)	{	case save_sp_no_merge:	case save_a0_no_merge:	  emit_insn (gen_addsi3 (stack_pointer_rtx,				 stack_pointer_rtx,				 GEN_INT (-4 * num_regs_to_save)));	  xsize = 0;	  break;	case save_sp_partial_merge:	  emit_insn (gen_addsi3 (stack_pointer_rtx,				 stack_pointer_rtx,				 GEN_INT (-128)));	  xsize = 128 - 4 * num_regs_to_save;	  size -= xsize;	  break;	case save_sp_merge:	case save_a0_merge:	  emit_insn (gen_addsi3 (stack_pointer_rtx,				 stack_pointer_rtx,				 GEN_INT (-(size + 4 * num_regs_to_save))));	  /* We'll have to adjust FP register saves according to the	     frame size.  */	  xsize = size;	  /* Since we've already created the stack frame, don't do it	     again at the end of the function.  */	  size = 0;	  break;	default:	  abort ();	}	        /* Now prepare register a0, if we have decided to use it.  */      switch (strategy)	{	case save_sp_merge:	case save_sp_no_merge:	case save_sp_partial_merge:	  reg = 0;	  break;	case save_a0_merge:	case save_a0_no_merge:	  reg = gen_rtx_REG (SImode, FIRST_ADDRESS_REGNUM);	  emit_insn (gen_movsi (reg, stack_pointer_rtx));	  if (xsize)	    emit_insn (gen_addsi3 (reg, reg, GEN_INT (xsize)));	  reg = gen_rtx_POST_INC (SImode, reg);	  break;	  	default:	  abort ();	}            /* Now actually save the FP registers.  */      for (i = FIRST_FP_REGNUM; i <= LAST_FP_REGNUM; ++i)	if (regs_ever_live[i] && ! call_used_regs[i])	  {	    rtx addr;	    if (reg)	      addr = reg;	    else	      {		/* If we aren't using `a0', use an SP offset.  */		if (xsize)		  {		    addr = gen_rtx_PLUS (SImode,					 stack_pointer_rtx,					 GEN_INT (xsize));		  }		else		  addr = stack_pointer_rtx;				xsize += 4;	      }	    insn = emit_insn (gen_movsi (gen_rtx_MEM (SImode, addr),					 gen_rtx_REG (SImode, i)));	    RTX_FRAME_RELATED_P (insn) = 1;	  }    }  /* Now put the frame pointer into the frame pointer register.  */  if (frame_pointer_needed)    emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);  /* Allocate stack for this frame.  */  if (size)    emit_insn (gen_addsi3 (stack_pointer_rtx,			   stack_pointer_rtx,			   GEN_INT (-size)));  if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])    {      rtx insn = get_last_insn ();      rtx last = emit_insn (gen_GOTaddr2picreg ());      /* Mark these insns as possibly dead.  Sometimes, flow2 may	 delete all uses of the PIC register.  In this case, let it	 delete the initialization too.  */      do	{	  insn = NEXT_INSN (insn);	  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,						const0_rtx,						REG_NOTES (insn));	}      while (insn != last);    }}voidexpand_epilogue (void){  HOST_WIDE_INT size;  /* SIZE includes the fixed stack space needed for function calls.  */  size = get_frame_size () + current_function_outgoing_args_size;  size += (current_function_outgoing_args_size ? 4 : 0);  if (TARGET_AM33_2 && fp_regs_to_save ())    {      int num_regs_to_save = fp_regs_to_save (), i;      rtx reg = 0;      /* We have several options to restore FP registers.  We could	 load them from SP offsets, but, if there are enough FP	 registers to restore, we win if we use a post-increment	 addressing mode.  */      /* If we have a frame pointer, it's the best option, because we	 already know it has the value we want.  */      if (frame_pointer_needed)	reg = gen_rtx_REG (SImode, FRAME_POINTER_REGNUM);      /* Otherwise, we may use `a1', since it's call-clobbered and	 it's never used for return values.  But only do so if it's	 smaller than using SP offsets.  */      else	{	  enum { restore_sp_post_adjust,		 restore_sp_pre_adjust,		 restore_sp_partial_adjust,		 restore_a1 } strategy;	  unsigned int this_strategy_size, strategy_size = (unsigned)-1;	  /* Consider using sp offsets before adjusting sp.  */	  /* Insn: fmov (##,sp),fs#, for each fs# to be restored.  */	  this_strategy_size = SIZE_FMOV_SP (size, num_regs_to_save);	  /* If size is too large, we'll have to adjust SP with an		 add.  */	  if (size + 4 * num_regs_to_save + REG_SAVE_BYTES > 255)	    {	      /* Insn: add size + 4 * num_regs_to_save, sp.  */	      this_strategy_size += SIZE_ADD_SP (size + 4 * num_regs_to_save);	    }	  /* If we don't have to restore any non-FP registers,		 we'll be able to save one byte by using rets.  */	  if (! REG_SAVE_BYTES)	    this_strategy_size--;	  if (this_strategy_size < strategy_size)	    {	      strategy = restore_sp_post_adjust;	      strategy_size = this_strategy_size;	    }	  /* Consider using sp offsets after adjusting sp.  */	  /* Insn: add size, sp.  */	  this_strategy_size = SIZE_ADD_SP (size);	  /* Insn: fmov (##,sp),fs#, for each fs# to be restored.  */	  this_strategy_size += SIZE_FMOV_SP (0, num_regs_to_save);	  /* We're going to use ret to release the FP registers		 save area, so, no savings.  */	  if (this_strategy_size < strategy_size)	    {	      strategy = restore_sp_pre_adjust;	      strategy_size = this_strategy_size;	    }	  /* Consider using sp offsets after partially adjusting sp.	     When size is close to 32Kb, we may be able to adjust SP	     with an imm16 add instruction while still using fmov	     (d8,sp).  */	  if (size + 4 * num_regs_to_save + REG_SAVE_BYTES > 255)	    {	      /* Insn: add size + 4 * num_regs_to_save				+ REG_SAVE_BYTES - 252,sp.  */	      this_strategy_size = SIZE_ADD_SP (size + 4 * num_regs_to_save						+ REG_SAVE_BYTES - 252);	      /* Insn: fmov (##,sp),fs#, fo each fs# to be restored.  */	      this_strategy_size += SIZE_FMOV_SP (252 - REG_SAVE_BYTES						  - 4 * num_regs_to_save,						  num_regs_to_save);	      /* We're going to use ret to release the FP registers		 save area, so, no savings.  */	      if (this_strategy_size < strategy_size)		{		  strategy = restore_sp_partial_adjust;		  strategy_size = this_strategy_size;		}	    }	  /* Consider using a1 in post-increment mode, as long as the	     user hasn't changed the calling conventions of a1.  */	  if (call_used_regs[FIRST_ADDRESS_REGNUM+1]	      && ! fixed_regs[FIRST_ADDRESS_REGNUM+1])	    {	      /* Insn: mov sp,a1.  */	      this_strategy_size = 1;	      if (size)		{		  /* Insn: add size,a1.  */		  this_strategy_size += SIZE_ADD_AX (size);		}	      /* Insn: fmov (a1+),fs#, for each fs# to be restored.  */	      this_strategy_size += 3 * num_regs_to_save;	      /* If size is large enough, we may be able to save a		 couple of bytes.  */	      if (size + 4 * num_regs_to_save + REG_SAVE_BYTES > 255)		{		  /* Insn: mov a1,sp.  */		  this_strategy_size += 2;		}	      /* If we don't have to restore any non-FP registers,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -