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

📄 s390.c

📁 linux下编程用 编译软件
💻 C
📖 第 1 页 / 共 5 页
字号:
s390_const_double_ok_for_constraint_p (rtx value,				       int c,				       const char * str){  gcc_assert (c == str[0]);  switch (str[0])    {    case 'G':      /* The floating point zero constant.  */      return (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT              && value == CONST0_RTX (GET_MODE (value)));          default:      return 0;    }}/* Return true if VALUE matches the constraint STR.  */ints390_const_ok_for_constraint_p (HOST_WIDE_INT value,				int c,				const char * str){  enum machine_mode mode, part_mode;  int def;  int part, part_goal;  gcc_assert (c == str[0]);  switch (str[0])    {    case 'I':      return (unsigned int)value < 256;    case 'J':      return (unsigned int)value < 4096;    case 'K':      return value >= -32768 && value < 32768;    case 'L':      return (TARGET_LONG_DISPLACEMENT ?	      (value >= -524288 && value <= 524287)	      : (value >= 0 && value <= 4095));    case 'M':      return value == 2147483647;    case 'N':      if (str[1] == 'x')	part_goal = -1;      else	part_goal = str[1] - '0';      switch (str[2])	{  	case 'Q': part_mode = QImode; break; 	case 'H': part_mode = HImode; break; 	case 'S': part_mode = SImode; break;	default:  return 0;	}      switch (str[3])	{	case 'H': mode = HImode; break;	case 'S': mode = SImode; break;	case 'D': mode = DImode; break;	default: return 0;	}      switch (str[4])	{	case '0': def = 0;  break;	case 'F': def = -1; break;	default: return 0;	}      if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))	return 0;      part = s390_single_part (GEN_INT (value), mode, part_mode, def);      if (part < 0)	return 0;      if (part_goal != -1 && part_goal != part)	return 0;      break;    case 'O':      if (!TARGET_EXTIMM)	return 0;            switch (str[1])	{	case 's':	  return trunc_int_for_mode (value, SImode) == value;	  	case 'p':	  return value == 0	    || s390_single_part (GEN_INT (value), DImode, SImode, 0) == 1;	  	case 'n':	  return value == -1	    || s390_single_part (GEN_INT (value), DImode, SImode, -1) == 1;	  	default:	  gcc_unreachable ();	}      break;    case 'P':      return legitimate_reload_constant_p (GEN_INT (value));    default:      return 0;    }  return 1;}/* Compute a (partial) cost for rtx X.  Return true if the complete   cost has been computed, and false if subexpressions should be   scanned.  In either case, *TOTAL contains the cost result.     CODE contains GET_CODE (x), OUTER_CODE contains the code    of the superexpression of x.  */static bools390_rtx_costs (rtx x, int code, int outer_code, int *total){  switch (code)    {    case CONST:    case CONST_INT:    case LABEL_REF:    case SYMBOL_REF:    case CONST_DOUBLE:    case MEM:      *total = 0;      return true;    case ASHIFT:    case ASHIFTRT:    case LSHIFTRT:    case ROTATE:    case ROTATERT:    case AND:    case IOR:    case XOR:    case NEG:    case NOT:      *total = COSTS_N_INSNS (1);      return false;    case PLUS:    case MINUS:      /* Check for multiply and add.  */      if ((GET_MODE (x) == DFmode || GET_MODE (x) == SFmode)	  && GET_CODE (XEXP (x, 0)) == MULT	  && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD)	{	  /* This is the multiply and add case.  */	  if (GET_MODE (x) == DFmode)	    *total = s390_cost->madbr;	  else	    *total = s390_cost->maebr;	  *total += rtx_cost (XEXP (XEXP (x, 0), 0), MULT) 	    + rtx_cost (XEXP (XEXP (x, 0), 1), MULT) 	    + rtx_cost (XEXP (x, 1), code);	  return true;  /* Do not do an additional recursive descent.  */	}      *total = COSTS_N_INSNS (1);      return false;    case MULT:            switch (GET_MODE (x))	{	case SImode:	  {	    rtx left = XEXP (x, 0);	    rtx right = XEXP (x, 1);	    if (GET_CODE (right) == CONST_INT		&& CONST_OK_FOR_K (INTVAL (right)))	      *total = s390_cost->mhi;	    else if (GET_CODE (left) == SIGN_EXTEND)	      *total = s390_cost->mh;	    else	      *total = s390_cost->ms;  /* msr, ms, msy */	    break;	  }	case DImode:	  {	    rtx left = XEXP (x, 0);	    rtx right = XEXP (x, 1);	    if (TARGET_64BIT)	      {		if (GET_CODE (right) == CONST_INT		    && CONST_OK_FOR_K (INTVAL (right)))		  *total = s390_cost->mghi;		else if (GET_CODE (left) == SIGN_EXTEND)		  *total = s390_cost->msgf;		else		  *total = s390_cost->msg;  /* msgr, msg */	      }	    else /* TARGET_31BIT */	      {		if (GET_CODE (left) == SIGN_EXTEND		    && GET_CODE (right) == SIGN_EXTEND)		  /* mulsidi case: mr, m */		  *total = s390_cost->m;		else if (GET_CODE (left) == ZERO_EXTEND			 && GET_CODE (right) == ZERO_EXTEND			 && TARGET_CPU_ZARCH)		  /* umulsidi case: ml, mlr */		  *total = s390_cost->ml;		else		  /* Complex calculation is required.  */		  *total = COSTS_N_INSNS (40);	      }	    break;	  }	case SFmode:	case DFmode:	  *total = s390_cost->mult_df;	  break;	case TFmode:	  *total = s390_cost->mxbr;	  break;	default:	  return false;	}      return false;    case UDIV:    case UMOD:      if (GET_MODE (x) == TImode) 	       /* 128 bit division */	*total = s390_cost->dlgr;      else if (GET_MODE (x) == DImode)	{	  rtx right = XEXP (x, 1);	  if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */	    *total = s390_cost->dlr;	  else 	                               /* 64 by 64 bit division */	    *total = s390_cost->dlgr;	}      else if (GET_MODE (x) == SImode)         /* 32 bit division */	*total = s390_cost->dlr;      return false;    case DIV:    case MOD:      if (GET_MODE (x) == DImode)	{	  rtx right = XEXP (x, 1);	  if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */	    if (TARGET_64BIT)	      *total = s390_cost->dsgfr;	    else	      *total = s390_cost->dr;	  else 	                               /* 64 by 64 bit division */	    *total = s390_cost->dsgr;	}      else if (GET_MODE (x) == SImode)         /* 32 bit division */	*total = s390_cost->dlr;      else if (GET_MODE (x) == SFmode)	{	  if (TARGET_IEEE_FLOAT)	    *total = s390_cost->debr;	  else /* TARGET_IBM_FLOAT */	    *total = s390_cost->der;	}      else if (GET_MODE (x) == DFmode)	{	  if (TARGET_IEEE_FLOAT)	    *total = s390_cost->ddbr;	  else /* TARGET_IBM_FLOAT */	    *total = s390_cost->ddr;	}      else if (GET_MODE (x) == TFmode)	{	  if (TARGET_IEEE_FLOAT)	    *total = s390_cost->dxbr;	  else /* TARGET_IBM_FLOAT */	    *total = s390_cost->dxr;	}      return false;    case SQRT:      if (GET_MODE (x) == SFmode)	*total = s390_cost->sqebr;      else if (GET_MODE (x) == DFmode)	*total = s390_cost->sqdbr;      else /* TFmode */	*total = s390_cost->sqxbr;      return false;    case SIGN_EXTEND:    case ZERO_EXTEND:      if (outer_code == MULT || outer_code == DIV || outer_code == MOD	  || outer_code == PLUS || outer_code == MINUS	  || outer_code == COMPARE)	*total = 0;      return false;    case COMPARE:      *total = COSTS_N_INSNS (1);      if (GET_CODE (XEXP (x, 0)) == AND	  && GET_CODE (XEXP (x, 1)) == CONST_INT	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)	{	  rtx op0 = XEXP (XEXP (x, 0), 0);	  rtx op1 = XEXP (XEXP (x, 0), 1);	  rtx op2 = XEXP (x, 1);	  if (memory_operand (op0, GET_MODE (op0))	      && s390_tm_ccmode (op1, op2, 0) != VOIDmode)	    return true;	  if (register_operand (op0, GET_MODE (op0))	      && s390_tm_ccmode (op1, op2, 1) != VOIDmode)	    return true;	}      return false;    default:      return false;    }}/* Return the cost of an address rtx ADDR.  */static ints390_address_cost (rtx addr){  struct s390_address ad;  if (!s390_decompose_address (addr, &ad))    return 1000;  return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);}/* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,   otherwise return 0.  */inttls_symbolic_operand (rtx op){  if (GET_CODE (op) != SYMBOL_REF)    return 0;  return SYMBOL_REF_TLS_MODEL (op);}/* Split DImode access register reference REG (on 64-bit) into its constituent   low and high parts, and store them into LO and HI.  Note that gen_lowpart/   gen_highpart cannot be used as they assume all registers are word-sized,   while our access registers have only half that size.  */voids390_split_access_reg (rtx reg, rtx *lo, rtx *hi){  gcc_assert (TARGET_64BIT);  gcc_assert (ACCESS_REG_P (reg));  gcc_assert (GET_MODE (reg) == DImode);  gcc_assert (!(REGNO (reg) & 1));  *lo = gen_rtx_REG (SImode, REGNO (reg) + 1);  *hi = gen_rtx_REG (SImode, REGNO (reg));}/* Return true if OP contains a symbol reference */boolsymbolic_reference_mentioned_p (rtx op){  const char *fmt;  int i;  if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)    return 1;  fmt = GET_RTX_FORMAT (GET_CODE (op));  for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)    {      if (fmt[i] == 'E')	{	  int j;	  for (j = XVECLEN (op, i) - 1; j >= 0; j--)	    if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))	      return 1;	}      else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))	return 1;    }  return 0;}/* Return true if OP contains a reference to a thread-local symbol.  */booltls_symbolic_reference_mentioned_p (rtx op){  const char *fmt;  int i;  if (GET_CODE (op) == SYMBOL_REF)    return tls_symbolic_operand (op);  fmt = GET_RTX_FORMAT (GET_CODE (op));  for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)    {      if (fmt[i] == 'E')	{	  int j;	  for (j = XVECLEN (op, i) - 1; j >= 0; j--)	    if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))	      return true;	}      else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))	return true;    }  return false;}/* Return true if OP is a legitimate general operand when   generating PIC code.  It is given that flag_pic is on   and that OP satisfies CONSTANT_P or is a CONST_DOUBLE.  */intlegitimate_pic_operand_p (rtx op){  /* Accept all non-symbolic constants.  */  if (!SYMBOLIC_CONST (op))    return 1;  /* Reject everything else; must be handled     via emit_symbolic_move.  */  return 0;}/* Returns true if the constant value OP is a legitimate general operand.   It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE.  */intlegitimate_constant_p (rtx op){  /* Accept all non-symbolic constants.  */  if (!SYMBOLIC_CONST (op))    return 1;  /* Accept immediate LARL operands.  */  if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))    return 1;  /* Thread-local symbols are never legal constants.  This is     so that emit_call knows that computing such addresses     might require a function call.  */  if (TLS_SYMBOLIC_CONST (op))    return 0;  /* In the PIC case, symbolic constants must *not* be     forced into the literal pool.  We accept them here,     so that they will be handled by emit_symbolic_move.  */  if (flag_pic)    return 1;  /* All remaining non-PIC symbolic constants are     forced into the literal pool.  */  return 0;}/* Determine if it's legal to put X into the constant pool.  This   is not possible if X contains the address of a symbol that is   not constant (TLS) or not known at final link time (PIC).  */static bools390_cannot_force_const_mem (rtx x){  switch (GET_CODE (x))    {    case CONST_INT:    case CONST_DOUBLE:      /* Acce

⌨️ 快捷键说明

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