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

📄 cris.c

📁 gcc-you can use this code to learn something about gcc, and inquire further into linux,
💻 C
📖 第 1 页 / 共 5 页
字号:
cris_cfun_uses_pic_table (){  return current_function_uses_pic_offset_table;}/* Given an rtx, return the text string corresponding to the CODE of X.   Intended for use in the assembly language output section of a   define_insn.  */const char *cris_op_str (x)     rtx x;{  cris_output_insn_is_bound = 0;  switch (GET_CODE (x))    {    case PLUS:      return "add";      break;    case MINUS:      return "sub";      break;    case MULT:      return "mul";      break;    case DIV:      return "div";      break;    case AND:      return "and";      break;    case IOR:      return "or";      break;    case XOR:      return "xor";      break;    case NOT:      return "not";      break;    case ASHIFT:      return "lsl";      break;    case LSHIFTRT:      return "lsr";      break;    case ASHIFTRT:      return "asr";      break;    case UMIN:      /* Used to control the sign/zero-extend character for the 'e' modifier.	 BOUND has none.  */      cris_output_insn_is_bound = 1;      return "bound";      break;    default:      return "Unknown operator";      break;  }}/* Emit an error message when we're in an asm, and a fatal error for   "normal" insns.  Formatted output isn't easily implemented, since we   use output_operand_lossage to output the actual message and handle the   categorization of the error.  */static voidcris_operand_lossage (msgid, op)     const char *msgid;     rtx op;{  debug_rtx (op);  output_operand_lossage ("%s", msgid);}/* Print an index part of an address to file.  */static voidcris_print_index (index, file)     rtx index;     FILE * file;{  rtx inner = XEXP (index, 0);  /* Make the index "additive" unless we'll output a negative number, in     which case the sign character is free (as in free beer).  */  if (GET_CODE (index) != CONST_INT || INTVAL (index) >= 0)    putc ('+', file);  if (REG_P (index))    fprintf (file, "$%s.b", reg_names[REGNO (index)]);  else if (CONSTANT_P (index))    cris_output_addr_const (file, index);  else if (GET_CODE (index) == MULT)    {      fprintf (file, "$%s.",	       reg_names[REGNO (XEXP (index, 0))]);      putc (INTVAL (XEXP (index, 1)) == 2 ? 'w' : 'd', file);    }  else if (GET_CODE (index) == SIGN_EXTEND &&	   GET_CODE (inner) == MEM)    {      rtx inner_inner = XEXP (inner, 0);      if (GET_CODE (inner_inner) == POST_INC)	{	  fprintf (file, "[$%s+].",		   reg_names[REGNO (XEXP (inner_inner, 0))]);	  putc (GET_MODE (inner) == HImode ? 'w' : 'b', file);	}      else	{	  fprintf (file, "[$%s].", reg_names[REGNO (inner_inner)]);	  putc (GET_MODE (inner) == HImode ? 'w' : 'b', file);	}    }  else if (GET_CODE (index) == MEM)    {      if (GET_CODE (inner) == POST_INC)	fprintf (file, "[$%s+].d", reg_names[REGNO (XEXP (inner, 0))]);      else	fprintf (file, "[$%s].d", reg_names[REGNO (inner)]);    }  else    cris_operand_lossage ("unexpected index-type in cris_print_index",			  index);}/* Print a base rtx of an address to file.  */static voidcris_print_base (base, file)     rtx base;     FILE *file;{  if (REG_P (base))    fprintf (file, "$%s", reg_names[REGNO (base)]);  else if (GET_CODE (base) == POST_INC)    fprintf (file, "$%s+", reg_names[REGNO (XEXP (base, 0))]);  else    cris_operand_lossage ("unexpected base-type in cris_print_base",			  base);}/* Usable as a guard in expressions.  */intcris_fatal (arg)     char *arg;{  internal_error (arg);  /* We'll never get here; this is just to appease compilers.  */  return 0;}/* Textual function prologue.  */static voidcris_target_asm_function_prologue (file, size)     FILE *file;     HOST_WIDE_INT size;{  int regno;  /* Shorten the used name for readability.  */  int cfoa_size = current_function_outgoing_args_size;  int last_movem_reg = -1;  int doing_dwarf = dwarf2out_do_frame ();  int framesize;  int faked_args_size = 0;  int cfa_write_offset = 0;  char *cfa_label = NULL;  int return_address_on_stack    = regs_ever_live[CRIS_SRP_REGNUM]    || cfun->machine->needs_return_address_on_stack != 0;  /* Don't do anything if no prologues or epilogues are wanted.  */  if (!TARGET_PROLOGUE_EPILOGUE)    return;  if (size < 0)    abort ();  /* Align the size to what's best for the CPU model.  */  if (TARGET_STACK_ALIGN)    size = TARGET_ALIGN_BY_32 ? (size + 3) & ~3 : (size + 1) & ~1;  if (current_function_pretend_args_size)    {      int pretend = current_function_pretend_args_size;      for (regno = CRIS_FIRST_ARG_REG + CRIS_MAX_ARGS_IN_REGS - 1;	   pretend > 0;	   regno--, pretend -= 4)	{	  fprintf (file, "\tpush $%s\n", reg_names[regno]);	  faked_args_size += 4;	}    }  framesize = faked_args_size;  if (doing_dwarf)    {      /* FIXME: Slightly redundant calculation, as we do the same in	 pieces below.  This offset must be the total adjustment of the	 stack-pointer.  We can then def_cfa call at the end of this	 function with the current implementation of execute_cfa_insn, but	 that wouldn't really be clean.  */      int cfa_offset	= faked_args_size	+ (return_address_on_stack ? 4 : 0)	+ (frame_pointer_needed ? 4 : 0);      int cfa_reg;      if (frame_pointer_needed)	cfa_reg = FRAME_POINTER_REGNUM;      else	{	  cfa_reg = STACK_POINTER_REGNUM;	  cfa_offset += cris_initial_frame_pointer_offset ();	}      cfa_label = dwarf2out_cfi_label ();      dwarf2out_def_cfa (cfa_label, cfa_reg, cfa_offset);      cfa_write_offset = - faked_args_size - 4;    }  /* Save SRP if not a leaf function.  */  if (return_address_on_stack)    {      fprintf (file, "\tPush $srp\n");      framesize += 4;      if (doing_dwarf)	{	  dwarf2out_return_save (cfa_label, cfa_write_offset);	  cfa_write_offset -= 4;	}    }  /* Set up frame pointer if needed.  */  if (frame_pointer_needed)    {      fprintf (file, "\tpush $%s\n\tmove.d $sp,$%s\n",	       reg_names[FRAME_POINTER_REGNUM],	       reg_names[FRAME_POINTER_REGNUM]);      framesize += 4;      if (doing_dwarf)	{	  dwarf2out_reg_save (cfa_label, FRAME_POINTER_REGNUM,			      cfa_write_offset);	  cfa_write_offset -= 4;	}    }  /* Local vars are located above saved regs.  */  cfa_write_offset -= size;  /* Get a contiguous sequence of registers, starting with r0, that need     to be saved.  */  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)    {      if ((((regs_ever_live[regno]	     && !call_used_regs[regno])	    || (regno == (int) PIC_OFFSET_TABLE_REGNUM		&& (current_function_uses_pic_offset_table		    /* It is saved anyway, if there would be a gap.  */		    || (flag_pic			&& regs_ever_live[regno + 1]			&& !call_used_regs[regno + 1]))))	   && (regno != FRAME_POINTER_REGNUM || !frame_pointer_needed)	   && regno != CRIS_SRP_REGNUM)	  || (current_function_calls_eh_return	      && (regno == EH_RETURN_DATA_REGNO (0)		  || regno == EH_RETURN_DATA_REGNO (1)		  || regno == EH_RETURN_DATA_REGNO (2)		  || regno == EH_RETURN_DATA_REGNO (3))))	{	  /* Check if movem may be used for registers so far.  */	  if (regno == last_movem_reg + 1)	    /* Yes, update next expected register.  */	    last_movem_reg++;	  else	    {	      /* We cannot use movem for all registers.  We have to flush		 any movem:ed registers we got so far.  */	      if (last_movem_reg != -1)		{		  /* It is a win to use a side-effect assignment for		     64 <= size <= 128.  But side-effect on movem was		     not usable for CRIS v0..3.  Also only do it if		     side-effects insns are allowed.  */		  if ((last_movem_reg + 1) * 4 + size >= 64		      && (last_movem_reg + 1) * 4 + size <= 128		      && cris_cpu_version >= CRIS_CPU_SVINTO		      && TARGET_SIDE_EFFECT_PREFIXES)		    fprintf (file, "\tmovem $%s,[$sp=$sp-%d]\n",			     reg_names[last_movem_reg],			     (last_movem_reg + 1) * 4 + size);		  else		    {		      /* Avoid printing multiple subsequent sub:s for sp.  */		      fprintf (file, "\tsub%s %d,$sp\n",			       ADDITIVE_SIZE_MODIFIER ((last_movem_reg + 1)						       * 4 + size),			       (last_movem_reg + 1) * 4 + size);		      fprintf (file, "\tmovem $%s,[$sp]\n",			       reg_names[last_movem_reg]);		    }		  framesize += (last_movem_reg + 1) * 4 + size;		  if (TARGET_PDEBUG)		    fprintf (file, "; frame %d, #regs %d, bytes %d args %d\n",			     size,			     last_movem_reg + 1,			     (last_movem_reg + 1) * 4,			     current_function_args_size);		  last_movem_reg = -1;		  size = 0;		}	      else if (size > 0)		{		  /* Local vars on stack, but there are no movem:s.		     Just allocate space.  */		  fprintf (file, "\tSub%s %d,$sp\n",			   ADDITIVE_SIZE_MODIFIER (size),			   size);		  framesize += size;		  size = 0;		}	      fprintf (file, "\tPush $%s\n", reg_names[regno]);	      framesize += 4;	    }	  if (doing_dwarf)	    {	      /* Registers are stored lowest numbered at highest address,		 which matches the loop order; we just need to update the		 write-offset.  */	      dwarf2out_reg_save (cfa_label, regno, cfa_write_offset);	      cfa_write_offset -= 4;	    }	}    }  /* Check after, if we can movem all registers.  This is the normal     case.  */  if (last_movem_reg != -1)    {      /* Side-effect assignment on movem was not supported for CRIS v0..3,	 and don't do it if we're asked not to.	 The movem is already accounted for, for unwind.  */      if ((last_movem_reg + 1) * 4 + size >= 64	  && (last_movem_reg + 1) * 4 + size <= 128	  && cris_cpu_version >= CRIS_CPU_SVINTO	  && TARGET_SIDE_EFFECT_PREFIXES)	fprintf (file, "\tmovem $%s,[$sp=$sp-%d]\n",		 reg_names[last_movem_reg],		 (last_movem_reg+1) * 4 + size);      else	{	  /* Avoid printing multiple subsequent sub:s for sp.  FIXME:	     Clean up the conditional expression.  */	  fprintf (file, "\tsub%s %d,$sp\n",		   ADDITIVE_SIZE_MODIFIER ((last_movem_reg + 1) * 4 + size),		   (last_movem_reg + 1) * 4 + size);	  /* To be compatible with v0..v3 means we do not use an assignment	     addressing mode with movem.  We normally don't need that	     anyway.  It would only be slightly more efficient for 64..128	     bytes frame size.  */	  fprintf (file, "\tmovem $%s,[$sp]\n", reg_names[last_movem_reg]);	}      framesize += (last_movem_reg + 1) * 4 + size;      if (TARGET_PDEBUG)	fprintf (file, "; frame %d, #regs %d, bytes %d args %d\n",		 size,		 last_movem_reg + 1,		 (last_movem_reg + 1) * 4,		 current_function_args_size);      /* We have to put outgoing argument space after regs.  */      if (cfoa_size)	{	  /* This does not need to be accounted for, for unwind.  */	  fprintf (file, "\tSub%s %d,$sp\n",		   ADDITIVE_SIZE_MODIFIER (cfoa_size),		   cfoa_size);	  framesize += cfoa_size;	}    }  else if ((size + cfoa_size) > 0)    {      /* This does not need to be accounted for, for unwind.  */      /* Local vars on stack, and we could not use movem.  Add a sub here.  */      fprintf (file, "\tSub%s %d,$sp\n",	       ADDITIVE_SIZE_MODIFIER (size + cfoa_size),	       cfoa_size + size);      framesize += size + cfoa_size;    }  /* Set up the PIC register.  */  if (current_function_uses_pic_offset_table)    fprintf (file, "\tmove.d $pc,$%s\n\tsub.d .:GOTOFF,$%s\n",	     reg_names[PIC_OFFSET_TABLE_REGNUM],	     reg_names[PIC_OFFSET_TABLE_REGNUM]);  if (TARGET_PDEBUG)    fprintf (file,	     "; parm #%d @ %d; frame %d, FP-SP is %d; leaf: %s%s; fp %s, outg: %d arg %d\n",	     CRIS_MAX_ARGS_IN_REGS + 1, FIRST_PARM_OFFSET (0),	     get_frame_size (),	     cris_initial_frame_pointer_offset (),	     leaf_function_p () ? "yes" : "no",	     return_address_on_stack ? "no" :"yes",	     frame_pointer_needed ? "yes" : "no",	     cfoa_size, current_function_args_size);  if (cris_max_stackframe && framesize > cris_max_stackframe)    warning ("stackframe too big: %d bytes", framesize);}/* Return nonzero if there are regs mentioned in the insn that are not all   in the call_used regs.  This is part of the decision whether an insn   can be put in the epilogue.  */static intsaved_regs_mentioned (x)     rtx x;{  int i;  const char *fmt;

⌨️ 快捷键说明

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