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

📄 v850.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	      int max_regno = -1;	      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)		{		  if (max_uses < regs[i].uses)		    {		      max_uses = regs[i].uses;		      max_regno = i;		    }		}	      if (max_uses > 3)		substitute_ep_register (regs[max_regno].first_insn,					regs[max_regno].last_insn,					max_uses, max_regno, &r1, &ep);	    }	  use_ep = FALSE;	  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)	    {	      regs[i].uses = 0;	      regs[i].first_insn = NULL_RTX;	      regs[i].last_insn = NULL_RTX;	    }	  break;	case NOTE:	  break;	case INSN:	  pattern = single_set (insn);	  /* See if there are any memory references we can shorten */	  if (pattern)	    {	      rtx src = SET_SRC (pattern);	      rtx dest = SET_DEST (pattern);	      rtx mem;	      /* Memory operands are signed by default.  */	      int unsignedp = FALSE;	      if (GET_CODE (dest) == MEM && GET_CODE (src) == MEM)		mem = NULL_RTX;	      else if (GET_CODE (dest) == MEM)		mem = dest;	      else if (GET_CODE (src) == MEM)		mem = src;	      else		mem = NULL_RTX;	      if (mem && ep_memory_operand (mem, GET_MODE (mem), unsignedp))		use_ep = TRUE;	      else if (!use_ep && mem		       && GET_MODE_SIZE (GET_MODE (mem)) <= UNITS_PER_WORD)		{		  rtx addr = XEXP (mem, 0);		  int regno = -1;		  int short_p;		  if (GET_CODE (addr) == REG)		    {		      short_p = TRUE;		      regno = REGNO (addr);		    }		  else if (GET_CODE (addr) == PLUS			   && GET_CODE (XEXP (addr, 0)) == REG			   && GET_CODE (XEXP (addr, 1)) == CONST_INT			   && (((unsigned)INTVAL (XEXP (addr, 1)))			       < ep_memory_offset (GET_MODE (mem), unsignedp)))		    {		      short_p = TRUE;		      regno = REGNO (XEXP (addr, 0));		    }		  else		    short_p = FALSE;		  if (short_p)		    {		      regs[regno].uses++;		      regs[regno].last_insn = insn;		      if (!regs[regno].first_insn)			regs[regno].first_insn = insn;		    }		}	      /* Loading up a register in the basic block zaps any savings		 for the register */	      if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)		{		  enum machine_mode mode = GET_MODE (dest);		  int word = 0;		  int regno;		  int endregno;		  while (GET_CODE (dest) == SUBREG)		    {		      word = SUBREG_WORD (dest);		      dest = SUBREG_REG (dest);		    }		  regno = REGNO (dest) + word;		  endregno = regno + HARD_REGNO_NREGS (regno, mode);		  if (!use_ep)		    {		      /* See if we can use the pointer before this			 modification.  */		      int max_uses = -1;		      int max_regno = -1;		      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)			{			  if (max_uses < regs[i].uses)			    {			      max_uses = regs[i].uses;			      max_regno = i;			    }			}		      if (max_uses > 3			  && max_regno >= regno			  && max_regno < endregno)			{			  substitute_ep_register (regs[max_regno].first_insn,						  regs[max_regno].last_insn,						  max_uses, max_regno, &r1, &ep);			  /* Since we made a substitution, zap all remembered			     registers.  */			  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)			    {			      regs[i].uses = 0;			      regs[i].first_insn = NULL_RTX;			      regs[i].last_insn = NULL_RTX;			    }			}		    }		  for (i = regno; i < endregno; i++)		    {		      regs[i].uses = 0;		      regs[i].first_insn = NULL_RTX;		      regs[i].last_insn = NULL_RTX;		    }		}	    }	}    }}/* # of registers saved by the interrupt handler.  */#define INTERRUPT_FIXED_NUM 4/* # of bytes for registers saved by the interrupt handler.  */#define INTERRUPT_FIXED_SAVE_SIZE (4 * INTERRUPT_FIXED_NUM)/* # of registers saved in register parameter area.  */#define INTERRUPT_REGPARM_NUM 4/* # of words saved for other registers.  */#define INTERRUPT_ALL_SAVE_NUM \  (30 - INTERRUPT_FIXED_NUM + INTERRUPT_REGPARM_NUM)#define INTERRUPT_ALL_SAVE_SIZE (4 * INTERRUPT_ALL_SAVE_NUM)intcompute_register_save_size (p_reg_saved)     long *p_reg_saved;{  int size = 0;  int i;  int interrupt_handler = v850_interrupt_function_p (current_function_decl);  int call_p = regs_ever_live[31];  long reg_saved = 0;  /* Count the return pointer if we need to save it.  */  if (profile_flag && !call_p)    regs_ever_live[31] = call_p = 1;   /* Count space for the register saves.  */  if (interrupt_handler)    {      for (i = 0; i <= 31; i++)	switch (i)	  {	  default:	    if (regs_ever_live[i] || call_p)	      {		size += 4;		reg_saved |= 1L << i;	      }	    break;	    /* We don't save/restore r0 or the stack pointer */	  case 0:	  case STACK_POINTER_REGNUM:	    break;	    /* For registers with fixed use, we save them, set them to the	       appropriate value, and then restore them.	       These registers are handled specially, so don't list them	       on the list of registers to save in the prologue.  */	  case 1:		/* temp used to hold ep */	  case 4:		/* gp */	  case 10:		/* temp used to call interrupt save/restore */	  case EP_REGNUM:	/* ep */	    size += 4;	    break;	  }    }  else    for (i = 0; i <= 31; i++)      if (regs_ever_live[i] && ((! call_used_regs[i]) || i == 31))	{	  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;{  extern int current_function_outgoing_args_size;  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;  int num_save;  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)    {      emit_insn (gen_save_interrupt ());      actual_fsize -= INTERRUPT_FIXED_SAVE_SIZE;      if (((1L << 31) & reg_saved) != 0)	actual_fsize -= INTERRUPT_ALL_SAVE_SIZE;    }  /* Save arg registers to the stack if necessary.  */  else if (current_function_anonymous_args)    {      if (TARGET_PROLOG_FUNCTION)	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 << 31) & reg_saved) != 0)    {      save_regs[num_save++] = gen_rtx (REG, Pmode, 31);      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,					      gen_rtx (PLUS, Pmode,						       stack_pointer_rtx,						       GEN_INT (-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_PTR);	  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 << 31) & reg_saved) != 0)	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]) == 31)	    {	      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;  int num_restore;  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 << 31) & 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 << 31) & reg_saved) != 0)    {      restore_regs[num_restore++] = gen_rtx (REG, Pmode, 31);      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_PTR);	  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;	}    }

⌨️ 快捷键说明

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