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

📄 v850.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
	 registers that need to be saved.  To detect this we note that the	 helper functions always push at least register r29 (provided	 that the function is not an interrupt handler).  */	       if (TARGET_PROLOG_FUNCTION          && (i == 2 || ((i >= 20) && (i < 30))))	{	  if (i == 2)	    {	      size += 4;	      reg_saved |= 1L << i;	      i = 20;	    }	  /* Helper functions save all registers between the starting	     register and the last register, regardless of whether they	     are actually used by the function or not.  */	  for (; i <= 29; i++)	    {	      size += 4;	      reg_saved |= 1L << i;	    }	  if (regs_ever_live [LINK_POINTER_REGNUM])	    {	      size += 4;	      reg_saved |= 1L << LINK_POINTER_REGNUM;	    }	}      else	{	  for (; i <= 31; i++)	    if (regs_ever_live[i] && ((! call_used_regs[i])				      || i == LINK_POINTER_REGNUM))	      {		size += 4;		reg_saved |= 1L << i;	      }	}    }    if (p_reg_saved)    *p_reg_saved = reg_saved;  return size;}intcompute_frame_size (size, p_reg_saved)     int size;     long *p_reg_saved;{  return (size	  + compute_register_save_size (p_reg_saved)	  + current_function_outgoing_args_size);}voidexpand_prologue (){  unsigned int i;  int offset;  unsigned int size = get_frame_size ();  unsigned int actual_fsize;  unsigned int init_stack_alloc = 0;  rtx save_regs[32];  rtx save_all;  unsigned int num_save;  unsigned int default_stack;  int code;  int interrupt_handler = v850_interrupt_function_p (current_function_decl);  long reg_saved = 0;  actual_fsize = compute_frame_size (size, &reg_saved);  /* Save/setup global registers for interrupt functions right now.  */  if (interrupt_handler)    {      if (TARGET_V850E && ! TARGET_DISABLE_CALLT)	emit_insn (gen_callt_save_interrupt ());      else	emit_insn (gen_save_interrupt ());      actual_fsize -= INTERRUPT_FIXED_SAVE_SIZE;            if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)	actual_fsize -= INTERRUPT_ALL_SAVE_SIZE;    }  /* Save arg registers to the stack if necessary.  */  else if (current_function_args_info.anonymous_args)    {      if (TARGET_PROLOG_FUNCTION)	{	  if (TARGET_V850E && ! TARGET_DISABLE_CALLT)	    emit_insn (gen_save_r6_r9_v850e ());	  else	    emit_insn (gen_save_r6_r9 ());	}      else	{	  offset = 0;	  for (i = 6; i < 10; i++)	    {	      emit_move_insn (gen_rtx_MEM (SImode,					   plus_constant (stack_pointer_rtx,							  offset)),			      gen_rtx_REG (SImode, i));	      offset += 4;	    }	}    }  /* Identify all of the saved registers.  */  num_save = 0;  default_stack = 0;  for (i = 1; i < 31; i++)    {      if (((1L << i) & reg_saved) != 0)	save_regs[num_save++] = gen_rtx_REG (Pmode, i);    }  /* If the return pointer is saved, the helper functions also allocate     16 bytes of stack for arguments to be saved in.  */  if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)    {      save_regs[num_save++] = gen_rtx_REG (Pmode, LINK_POINTER_REGNUM);      default_stack = 16;    }  /* See if we have an insn that allocates stack space and saves the particular     registers we want to.  */  save_all = NULL_RTX;  if (TARGET_PROLOG_FUNCTION && num_save > 0 && actual_fsize >= default_stack)    {      int alloc_stack = (4 * num_save) + default_stack;      int unalloc_stack = actual_fsize - alloc_stack;      int save_func_len = 4;      int save_normal_len;      if (unalloc_stack)	save_func_len += CONST_OK_FOR_J (unalloc_stack) ? 2 : 4;      /* see if we would have used ep to save the stack */      if (TARGET_EP && num_save > 3 && (unsigned)actual_fsize < 255)	save_normal_len = (3 * 2) + (2 * num_save);      else	save_normal_len = 4 * num_save;      save_normal_len += CONST_OK_FOR_J (actual_fsize) ? 2 : 4;      /* Don't bother checking if we don't actually save any space.	 This happens for instance if one register is saved and additional	 stack space is allocated.  */      if (save_func_len < save_normal_len)	{	  save_all = gen_rtx_PARALLEL	    (VOIDmode,	     rtvec_alloc (num_save + (TARGET_V850 ? 2 : 1)));	  XVECEXP (save_all, 0, 0)	    = gen_rtx_SET (VOIDmode,			   stack_pointer_rtx,			   plus_constant (stack_pointer_rtx, -alloc_stack));	  if (TARGET_V850)	    {	      XVECEXP (save_all, 0, num_save+1)		= gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 10));	    }	  offset = - default_stack;	  for (i = 0; i < num_save; i++)	    {	      XVECEXP (save_all, 0, i+1)		= gen_rtx_SET (VOIDmode,			       gen_rtx_MEM (Pmode,					    plus_constant (stack_pointer_rtx,							   offset)),			       save_regs[i]);	      offset -= 4;	    }	  code = recog (save_all, NULL_RTX, NULL);	  if (code >= 0)	    {	      rtx insn = emit_insn (save_all);	      INSN_CODE (insn) = code;	      actual_fsize -= alloc_stack;	      	      if (TARGET_DEBUG)		fprintf (stderr, "\Saved %d bytes via prologue function (%d vs. %d) for function %s\n",			 save_normal_len - save_func_len,			 save_normal_len, save_func_len,			 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));	    }	  else	    save_all = NULL_RTX;	}    }  /* If no prolog save function is available, store the registers the old     fashioned way (one by one). */  if (!save_all)    {      /* Special case interrupt functions that save all registers for a call.  */      if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)	{	  if (TARGET_V850E && ! TARGET_DISABLE_CALLT)	    emit_insn (gen_callt_save_all_interrupt ());	  else	    emit_insn (gen_save_all_interrupt ());	}      else	{	  /* If the stack is too big, allocate it in chunks so we can do the	     register saves.  We use the register save size so we use the ep	     register.  */	  if (actual_fsize && !CONST_OK_FOR_K (-actual_fsize))	    init_stack_alloc = compute_register_save_size (NULL);	  else	    init_stack_alloc = actual_fsize;	      	  /* Save registers at the beginning of the stack frame */	  offset = init_stack_alloc - 4;	  	  if (init_stack_alloc)	    emit_insn (gen_addsi3 (stack_pointer_rtx,				   stack_pointer_rtx,				   GEN_INT (-init_stack_alloc)));	  	  /* Save the return pointer first.  */	  if (num_save > 0 && REGNO (save_regs[num_save-1]) == LINK_POINTER_REGNUM)	    {	      emit_move_insn (gen_rtx_MEM (SImode,					   plus_constant (stack_pointer_rtx,							  offset)),			      save_regs[--num_save]);	      offset -= 4;	    }	  	  for (i = 0; i < num_save; i++)	    {	      emit_move_insn (gen_rtx_MEM (SImode,					   plus_constant (stack_pointer_rtx,							  offset)),			      save_regs[i]);	      offset -= 4;	    }	}    }  /* Allocate the rest of the stack that was not allocated above (either it is     > 32K or we just called a function to save the registers and needed more     stack.  */  if (actual_fsize > init_stack_alloc)    {      int diff = actual_fsize - init_stack_alloc;      if (CONST_OK_FOR_K (diff))	emit_insn (gen_addsi3 (stack_pointer_rtx,			       stack_pointer_rtx,			       GEN_INT (-diff)));      else	{	  rtx reg = gen_rtx_REG (Pmode, 12);	  emit_move_insn (reg, GEN_INT (-diff));	  emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, reg));	}    }  /* If we need a frame pointer, set it up now.  */  if (frame_pointer_needed)    emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);}voidexpand_epilogue (){  unsigned int i;  int offset;  unsigned int size = get_frame_size ();  long reg_saved = 0;  unsigned int actual_fsize = compute_frame_size (size, &reg_saved);  unsigned int init_stack_free = 0;  rtx restore_regs[32];  rtx restore_all;  unsigned int num_restore;  unsigned int default_stack;  int code;  int interrupt_handler = v850_interrupt_function_p (current_function_decl);  /* Eliminate the initial stack stored by interrupt functions.  */  if (interrupt_handler)    {      actual_fsize -= INTERRUPT_FIXED_SAVE_SIZE;      if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)	actual_fsize -= INTERRUPT_ALL_SAVE_SIZE;    }  /* Cut off any dynamic stack created.  */  if (frame_pointer_needed)    emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);  /* Identify all of the saved registers.  */  num_restore = 0;  default_stack = 0;  for (i = 1; i < 31; i++)    {      if (((1L << i) & reg_saved) != 0)	restore_regs[num_restore++] = gen_rtx_REG (Pmode, i);    }  /* If the return pointer is saved, the helper functions also allocate     16 bytes of stack for arguments to be saved in.  */  if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)    {      restore_regs[num_restore++] = gen_rtx_REG (Pmode, LINK_POINTER_REGNUM);      default_stack = 16;    }  /* See if we have an insn that restores the particular registers we     want to.  */  restore_all = NULL_RTX;    if (TARGET_PROLOG_FUNCTION      && num_restore > 0      && actual_fsize >= default_stack      && !interrupt_handler)    {      int alloc_stack = (4 * num_restore) + default_stack;      int unalloc_stack = actual_fsize - alloc_stack;      int restore_func_len = 4;      int restore_normal_len;      if (unalloc_stack)	restore_func_len += CONST_OK_FOR_J (unalloc_stack) ? 2 : 4;      /* See if we would have used ep to restore the registers.  */      if (TARGET_EP && num_restore > 3 && (unsigned)actual_fsize < 255)	restore_normal_len = (3 * 2) + (2 * num_restore);      else	restore_normal_len = 4 * num_restore;      restore_normal_len += (CONST_OK_FOR_J (actual_fsize) ? 2 : 4) + 2;      /* Don't bother checking if we don't actually save any space.  */      if (restore_func_len < restore_normal_len)	{	  restore_all = gen_rtx_PARALLEL (VOIDmode,					  rtvec_alloc (num_restore + 2));	  XVECEXP (restore_all, 0, 0) = gen_rtx_RETURN (VOIDmode);	  XVECEXP (restore_all, 0, 1)	    = gen_rtx_SET (VOIDmode, stack_pointer_rtx,			    gen_rtx_PLUS (Pmode,					  stack_pointer_rtx,					  GEN_INT (alloc_stack)));	  offset = alloc_stack - 4;	  for (i = 0; i < num_restore; i++)	    {	      XVECEXP (restore_all, 0, i+2)		= gen_rtx_SET (VOIDmode,			       restore_regs[i],			       gen_rtx_MEM (Pmode,					    plus_constant (stack_pointer_rtx,							   offset)));	      offset -= 4;	    }	  code = recog (restore_all, NULL_RTX, NULL);	  	  if (code >= 0)	    {	      rtx insn;	      actual_fsize -= alloc_stack;	      if (actual_fsize)		{		  if (CONST_OK_FOR_K (actual_fsize))		    emit_insn (gen_addsi3 (stack_pointer_rtx,					   stack_pointer_rtx,					   GEN_INT (actual_fsize)));		  else		    {		      rtx reg = gen_rtx_REG (Pmode, 12);		      emit_move_insn (reg, GEN_INT (actual_fsize));		      emit_insn (gen_addsi3 (stack_pointer_rtx,					     stack_pointer_rtx,					     reg));		    }		}	      insn = emit_jump_insn (restore_all);	      INSN_CODE (insn) = code;	      if (TARGET_DEBUG)		fprintf (stderr, "\Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",			 restore_normal_len - restore_func_len,			 restore_normal_len, restore_func_len,			 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));	    }	  else	    restore_all = NULL_RTX;	}    }  /* If no epilog save function is available, restore the registers the     old fashioned way (one by one).  */  if (!restore_all)    {      /* If the stack is large, we need to cut it down in 2 pieces.  */      if (actual_fsize && !CONST_OK_FOR_K (-actual_fsize))	init_stack_free = 4 * num_restore;      else	init_stack_free = actual_fsize;      /* Deallocate the rest of the stack if it is > 32K.  */      if (actual_fsize > init_stack_free)	{	  int diff;	  diff = actual_fsize - ((interrupt_handler) ? 0 : init_stack_free);	  if (CONST_OK_FOR_K (diff))	    emit_insn (gen_addsi3 (stack_pointer_rtx,				   stack_pointer_rtx,				   GEN_INT (diff)));	  else	    {	      rtx reg = gen_rtx_REG (Pmode, 12);	      emit_move_insn (reg, GEN_INT (diff));	      emit_insn (gen_addsi3 (stack_pointer_rtx,				     stack_pointer_rtx,				     reg));	    }	}      /* Special case interrupt functions that save all registers	 for a call.  */      if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)	{	  if (TARGET_V850E && ! TARGET_DISABLE_CALLT)	    emit_insn (gen_callt_restore_all_interrupt ());	  else	    emit_insn (gen_restore_all_interrupt ());	}      else	{	  /* Restore registers from the beginning of the stack frame.  */	  offset = init_stack_free - 4;	  /* Restore the return pointer first.  */	  if (num_restore > 0	      && REGNO (restore_regs [num_restore - 1]) == LINK_POINTER_REGNUM)	    {	      emit_move_insn (restore_regs[--num_restore],			      gen_rtx_MEM (SImode,					   plus_constant (stack_pointer_rtx,							  offset)));	      offset -= 4;	    }	  for (i = 0; i < num_restore; i++)	    {	      emit_move_insn (restore_regs[i],			      gen_rtx_MEM (SImode,					   plus_constant (stack_pointer_rtx,							  offset)));	      emit_insn (gen_rtx_USE (VOIDmode, restore_regs[i]));	      offset -= 4;	    }	  /* Cut back the remainder of the stack.  */	  if (init_stack_free)	    emit_insn (gen_addsi3 (stack_pointer_rtx,				   stack_pointer_rtx,				   GEN_INT (init_stack_free)));	}      /* And return or use reti for interrupt handlers.  */      if (interrupt_handler)        {          if (TARGET_V850E && ! TARGET_DISABLE_CALLT)            emit_insn (gen_callt_return_interrupt ());          else            emit_jump_insn (gen_return_interrupt ());	 }      else if (actual_fsize)	emit_jump_insn (gen_return_internal ());      else	emit_jump_insn (gen_return ());    }  v850_interrupt_cache_p = FALSE;  v850_interrupt_p = FALSE;}/* Update the condition code from the insn.  */voidnotice_update_cc (body, insn)     rtx body;     rtx insn;{  switch (get_attr_cc (insn))    {    case CC_NONE:      /* Insn does not affect CC at all.  */      break;    case CC_NONE_0HIT:      /* Insn does not change CC, but the 0'th operand has been changed.  */      if (cc_status.value1 != 0	  && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))

⌨️ 快捷键说明

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