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

📄 ns32k.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
}/* Value is the number of bytes of arguments automatically   popped when returning from a subroutine call.   FUNDECL is the declaration node of the function (as a tree),   FUNTYPE is the data type of the function (as a tree),   or for a library call it is an identifier node for the subroutine name.   SIZE is the number of bytes of arguments passed on the stack.   On the ns32k, the RET insn may be used to pop them if the number     of args is fixed, but if the number is variable then the caller     must pop them all.  RET can't be used for library calls now     because the library is compiled with the Unix compiler.   Use of RET is a selectable option, since it is incompatible with   standard Unix calling sequences.  If the option is not selected,   the caller must always pop the args.   The attribute stdcall is equivalent to RET on a per module basis.  */intns32k_return_pops_args (fundecl, funtype, size)     tree fundecl ATTRIBUTE_UNUSED;     tree funtype;     int size;{  int rtd = TARGET_RTD;  if (TREE_CODE (funtype) == IDENTIFIER_NODE)    return rtd ? size : 0;  /* Cdecl functions override -mrtd, and never pop the stack */  if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype)))    return 0;  /* Stdcall functions will pop the stack if not variable args */  if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)))    rtd = 1;  if (rtd)    {      if (TYPE_ARG_TYPES (funtype) == NULL_TREE	  || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype))) == void_type_node))	return size;    }  return 0;}/* PRINT_OPERAND is defined to call this function,   which is easier to debug than putting all the code in   a macro definition in ns32k.h.  *//* XXX time 12% of cpu time is in fprintf for non optimizing */voidprint_operand (file, x, code)     FILE *file;     rtx x;     int code;{  if (code == '$')    PUT_IMMEDIATE_PREFIX (file);  else if (code == '?')    PUT_EXTERNAL_PREFIX (file);  else if (GET_CODE (x) == REG)    fprintf (file, "%s", ns32k_out_reg_names[REGNO (x)]);  else if (GET_CODE (x) == MEM)    {      output_address (XEXP (x, 0));    }  else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode)    {      REAL_VALUE_TYPE r;      REAL_VALUE_FROM_CONST_DOUBLE (r, x);      PUT_IMMEDIATE_PREFIX (file);      if (GET_MODE (x) == DFmode)	{ #ifdef SEQUENT_ASM	  /* Sequent likes its floating point constants as integers */	  long l[2];	  REAL_VALUE_TO_TARGET_DOUBLE (r, l);	  fprintf (file, "0Dx%08x%08x",		   l[!WORDS_BIG_ENDIAN], l[WORDS_BIG_ENDIAN]);#else	  char s[30];	  real_to_decimal (s, &r, sizeof (s), 0, 1);#ifdef ENCORE_ASM	  fprintf (file, "0f%s", s);#else	  fprintf (file, "0d%s", s);#endif#endif	}      else	{#ifdef SEQUENT_ASM	  long l;	  REAL_VALUE_TO_TARGET_SINGLE (r, l);	  fprintf (file, "0Fx%08lx", l);#else	  char s[30];	  real_to_decimal (s, &r, sizeof (s), 0, 1);	  fprintf (file, "0f%s", s);#endif	}    }  else    {      if (flag_pic          && GET_CODE (x) == CONST          && symbolic_reference_mentioned_p (x))        {	  fprintf (stderr, "illegal constant for pic-mode: \n");	  print_rtl (stderr, x);          fprintf (stderr, "\nGET_CODE (x) == %d, CONST == %d, symbolic_reference_mentioned_p (x) == %d\n",		  GET_CODE (x), CONST, symbolic_reference_mentioned_p (x));	  abort ();	}      else if (flag_pic               && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF))	{	  output_addr_const (file, x);	  fprintf (file, "(sb)");	}      else        {#ifdef NO_IMMEDIATE_PREFIX_IF_SYMBOLIC          if (GET_CODE (x) == CONST_INT)#endif	    PUT_IMMEDIATE_PREFIX (file);          output_addr_const (file, x);	}    }}/* PRINT_OPERAND_ADDRESS is defined to call this function,   which is easier to debug than putting all the code in   a macro definition in ns32k.h .  *//* Completely rewritten to get this to work with Gas for PC532 Mach.   This function didn't work and I just wasn't able (nor very willing) to   figure out how it worked.   90-11-25 Tatu Yl|nen <ylo@cs.hut.fi> */voidprint_operand_address (file, addr)     register FILE *file;     register rtx addr;{  static const char scales[] = { 'b', 'w', 'd', 0, 'q', };  rtx offset, base, indexexp, tmp;  int scale;  extern int flag_pic;  if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_DEC)    {      fprintf (file, "tos");      return;    }  offset = NULL;  base = NULL;  indexexp = NULL;  while (addr != NULL)    {      if (GET_CODE (addr) == PLUS)	{	  if (GET_CODE (XEXP (addr, 0)) == PLUS)	    {	      tmp = XEXP (addr, 1);	      addr = XEXP (addr, 0);	    }	  else	    {	      tmp = XEXP (addr,0);	      addr = XEXP (addr,1);	    }	}      else	{	  tmp = addr;	  addr = NULL;	}      switch (GET_CODE (tmp))	{	case PLUS:	  abort ();	case MEM:	  if (base)	    {	      indexexp = base;	      base = tmp;	    }	  else	    base = tmp;	  break;	case REG:	  if (REGNO (tmp) < F0_REGNUM)	    if (base)	      {		indexexp = tmp;	      }	    else	      base = tmp;	  else	    if (base)	      {		indexexp = base;		base = tmp;	      }	    else	      base = tmp;	  break;	case MULT:	  indexexp = tmp;	  break;	case SYMBOL_REF:	  if (flag_pic && ! CONSTANT_POOL_ADDRESS_P (tmp)	      && ! SYMBOL_REF_FLAG (tmp))	    {	      if (base)		{		  if (indexexp)		    abort ();		  indexexp = base;		}	      base = tmp;	      break;	    }	case CONST:	  if (flag_pic && GET_CODE (tmp) == CONST)	    {	      rtx sym, off, tmp1;	      tmp1 = XEXP (tmp,0);	      if (GET_CODE (tmp1)  != PLUS)		abort ();	      sym = XEXP (tmp1,0);	      if (GET_CODE (sym) != SYMBOL_REF)	        {	          off = sym;		  sym = XEXP (tmp1,1);		}	      else	        off = XEXP (tmp1,1);	      if (GET_CODE (sym) == SYMBOL_REF)		{		  if (GET_CODE (off) != CONST_INT)		    abort ();		  if (CONSTANT_POOL_ADDRESS_P (sym)		      || SYMBOL_REF_FLAG (sym))		    {		      SYMBOL_REF_FLAG (tmp) = 1;		    }		  else		    {		      if (base)			{			  if (indexexp)			    abort ();			  indexexp = base;			}		      if (offset != 0)			abort ();		      base = sym;		      offset = off;		      break;		    }		}	    }	case CONST_INT:	case LABEL_REF:	  if (offset)	    offset = gen_rtx_PLUS (SImode, tmp, offset);	  else	    offset = tmp;	  break;	default:	  abort ();	}    }  if (! offset)    offset = const0_rtx;  if (base#ifndef INDEX_RATHER_THAN_BASE      && (flag_pic || TARGET_HIMEM)      && GET_CODE (base) != SYMBOL_REF       && GET_CODE (offset) != CONST_INT#else  /* This is a re-implementation of the SEQUENT_ADDRESS_BUG fix.  */#endif      && !indexexp && GET_CODE (base) == REG      && REG_OK_FOR_INDEX_P (base))    {      indexexp = base;      base = NULL;    }  /* now, offset, base and indexexp are set */#ifndef BASE_REG_NEEDED  if (! base)    {#if defined (PC_RELATIVE) || defined (NO_ABSOLUTE_PREFIX_IF_SYMBOLIC)      if (GET_CODE (offset) == CONST_INT)#endif	PUT_ABSOLUTE_PREFIX (file);    }#endif  output_addr_const (file, offset);  if (base) /* base can be (REG ...) or (MEM ...) */    switch (GET_CODE (base))      {	/* now we must output base.  Possible alternatives are:	   (rN)       (REG ...)	   (sp)	      (REG ...)	   (fp)       (REG ...)	   (pc)       (REG ...)  used for SYMBOL_REF and LABEL_REF, output	   (disp(fp)) (MEM ...)       just before possible [rX:y]	   (disp(sp)) (MEM ...)	   (disp(sb)) (MEM ...)	   */      case REG:	fprintf (file, "(%s)", ns32k_out_reg_names[REGNO (base)]);	break;      case SYMBOL_REF:	if (! flag_pic)	  abort ();        fprintf (file, "(");	output_addr_const (file, base);	fprintf (file, "(sb))");        break;      case MEM:	addr = XEXP (base,0);	base = NULL;	offset = NULL;	while (addr != NULL)	  {	    if (GET_CODE (addr) == PLUS)	      {		if (GET_CODE (XEXP (addr, 0)) == PLUS)		  {		    tmp = XEXP (addr, 1);		    addr = XEXP (addr, 0);		  }		else		  {		    tmp = XEXP (addr, 0);		    addr = XEXP (addr, 1);		  }	      }	    else	      {		tmp = addr;		addr = NULL;	      }	    switch (GET_CODE (tmp))	      {	      case REG:		base = tmp;		break;	      case CONST:	      case CONST_INT:	      case SYMBOL_REF:	      case LABEL_REF:		if (offset)		  offset = gen_rtx_PLUS (SImode, tmp, offset);		else		  offset = tmp;		break;	      default:		abort ();	      }	  }	if (! offset)	  offset = const0_rtx;	fprintf (file, "(");	output_addr_const (file, offset);	if (base)	  fprintf (file, "(%s)", ns32k_out_reg_names[REGNO (base)]);	else if (TARGET_SB)	  fprintf (file, "(sb)");	else	  abort ();	fprintf (file, ")");	break;      default:	abort ();      }#ifdef PC_RELATIVE  else if (GET_CODE (offset) != CONST_INT)    fprintf (file, "(pc)");#ifdef BASE_REG_NEEDED  else if (TARGET_SB)    fprintf (file, "(sb)");  else    abort ();#endif#endif /* PC_RELATIVE */  /* now print index if we have one */  if (indexexp)    {      if (GET_CODE (indexexp) == MULT)	{	  scale = INTVAL (XEXP (indexexp, 1)) >> 1;	  indexexp = XEXP (indexexp, 0);	}      else	scale = 0;      if (GET_CODE (indexexp) != REG || REGNO (indexexp) >= F0_REGNUM)	abort ();#ifdef UTEK_ASM      fprintf (file, "[%c`%s]",	       scales[scale],	       ns32k_out_reg_names[REGNO (indexexp)]);#else      fprintf (file, "[%s:%c]",	       ns32k_out_reg_names[REGNO (indexexp)],	       scales[scale]);#endif    }}/* National 32032 shifting is so bad that we can get   better performance in many common cases by using other   techniques.  */const char *output_shift_insn (operands)     rtx *operands;{  if (GET_CODE (operands[2]) == CONST_INT      && INTVAL (operands[2]) > 0      && INTVAL (operands[2]) <= 3)    {      if (GET_CODE (operands[0]) == REG)	{	  if (GET_CODE (operands[1]) == REG)	    {	      if (REGNO (operands[0]) == REGNO (operands[1]))		{		  if (operands[2] == const1_rtx)		    return "addd %0,%0";		  else if (INTVAL (operands[2]) == 2)		    return "addd %0,%0\n\taddd %0,%0";		}	      if (operands[2] == const1_rtx)		return "movd %1,%0\n\taddd %0,%0";	    	      operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]);	      return "addr %a1,%0";	    }	  if (operands[2] == const1_rtx)	    return "movd %1,%0\n\taddd %0,%0";	}      else if (GET_CODE (operands[1]) == REG)	{	  operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]);	  return "addr %a1,%0";	}      else if (INTVAL (operands[2]) == 1	       && GET_CODE (operands[1]) == MEM	       && rtx_equal_p (operands [0], operands[1]))	{	  rtx temp = XEXP (operands[1], 0);		  if (GET_CODE (temp) == REG	      || (GET_CODE (temp) == PLUS		  && GET_CODE (XEXP (temp, 0)) == REG		  && GET_CODE (XEXP (temp, 1)) == CONST_INT))	    return "addd %0,%0";	}      else return "ashd %2,%0";    }  return "ashd %2,%0";}const char *output_move_dconst (n, s)	int n;	const char *s;{  static char r[32];  if (n > -9 && n < 8)    strcpy (r, "movqd ");  else if (n > 0 && n < 256)    strcpy (r, "movzbd ");  else if (n > 0 && n < 65536)    strcpy (r, "movzwd ");  else if (n < 0 && n > -129)    strcpy (r, "movxbd ");  else if (n < 0 && n > -32769)    strcpy (r, "movxwd ");  else    strcpy (r, "movd ");  strcat (r, s);  return r;}/* If using PIC, mark a SYMBOL_REF for a non-global symbol or a code   symbol. These symbols are referenced via pc and not via sb. */static voidns32k_encode_section_info (decl, first)     tree decl;     int first ATTRIBUTE_UNUSED;{  if (flag_pic)    {      rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'		 ? TREE_CST_RTL (decl) : DECL_RTL (decl));      SYMBOL_REF_FLAG (XEXP (rtl, 0))	= (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'	   || ! TREE_PUBLIC (decl));    }}

⌨️ 快捷键说明

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