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

📄 s390.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  else    s390_cost = &z900_cost;  if (TARGET_BACKCHAIN && TARGET_PACKED_STACK && TARGET_HARD_FLOAT)    error ("-mbackchain -mpacked-stack -mhard-float are not supported "	   "in combination.");  if (s390_warn_framesize_string)    {      if (sscanf (s390_warn_framesize_string, HOST_WIDE_INT_PRINT_DEC,		  &s390_warn_framesize) != 1)	error ("invalid value for -mwarn-framesize");    }  if (s390_warn_dynamicstack_string)    s390_warn_dynamicstack_p = 1;    if (s390_stack_size_string)    {      if (sscanf (s390_stack_size_string, HOST_WIDE_INT_PRINT_DEC, 		  &s390_stack_size) != 1)	error ("invalid value for -mstack-size");            if (exact_log2 (s390_stack_size) == -1)	error ("stack size must be an exact power of 2");            if (s390_stack_guard_string)	{	  if (sscanf (s390_stack_guard_string, HOST_WIDE_INT_PRINT_DEC, 		      &s390_stack_guard) != 1)	    error ("invalid value for -mstack-guard");	  	  if (s390_stack_guard >= s390_stack_size)	    error ("stack size must be greater than the stack guard value"); 	  if (exact_log2 (s390_stack_guard) == -1)	    error ("stack guard value must be an exact power of 2");	}      else	error ("-mstack-size implies use of -mstack-guard");    }    if (s390_stack_guard_string && !s390_stack_size_string)    error ("-mstack-guard implies use of -mstack-size"); }/* Map for smallest class containing reg regno.  */const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] ={ GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,  ADDR_REGS,    ADDR_REGS, ADDR_REGS, ADDR_REGS,  ADDR_REGS,    ADDR_REGS, ADDR_REGS, ADDR_REGS,  ADDR_REGS,    ADDR_REGS, ADDR_REGS, ADDR_REGS,  FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,  FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,  FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,  FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,  ADDR_REGS,    CC_REGS,   ADDR_REGS, ADDR_REGS,  ACCESS_REGS,	ACCESS_REGS};/* Return attribute type of insn.  */static enum attr_types390_safe_attr_type (rtx insn){  if (recog_memoized (insn) >= 0)    return get_attr_type (insn);  else    return TYPE_NONE;}/* Return true if OP a (const_int 0) operand.   OP is the current operation.   MODE is the current operation mode.  */intconst0_operand (register rtx op, enum machine_mode mode){  return op == CONST0_RTX (mode);}/* Return true if OP is constant.   OP is the current operation.   MODE is the current operation mode.  */intconsttable_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){  return CONSTANT_P (op);}/* Return true if the mode of operand OP matches MODE.   If MODE is set to VOIDmode, set it to the mode of OP.  */static intcheck_mode (register rtx op, enum machine_mode *mode){  if (*mode == VOIDmode)      *mode = GET_MODE (op);  else  {    if (GET_MODE (op) != VOIDmode && GET_MODE (op) != *mode)       return 0;  }  return 1;}/* Return true if OP a valid operand for the LARL instruction.   OP is the current operation.   MODE is the current operation mode.  */intlarl_operand (register rtx op, enum machine_mode mode){  if (! check_mode (op, &mode))    return 0;  /* Allow labels and local symbols.  */  if (GET_CODE (op) == LABEL_REF)    return 1;  if (GET_CODE (op) == SYMBOL_REF)    return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0	    && SYMBOL_REF_TLS_MODEL (op) == 0	    && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));  /* Everything else must have a CONST, so strip it.  */  if (GET_CODE (op) != CONST)    return 0;  op = XEXP (op, 0);  /* Allow adding *even* in-range constants.  */  if (GET_CODE (op) == PLUS)    {      if (GET_CODE (XEXP (op, 1)) != CONST_INT          || (INTVAL (XEXP (op, 1)) & 1) != 0)        return 0;#if HOST_BITS_PER_WIDE_INT > 32      if (INTVAL (XEXP (op, 1)) >= (HOST_WIDE_INT)1 << 32	  || INTVAL (XEXP (op, 1)) < -((HOST_WIDE_INT)1 << 32))        return 0;#endif      op = XEXP (op, 0);    }  /* Labels and local symbols allowed here as well.  */  if (GET_CODE (op) == LABEL_REF)    return 1;  if (GET_CODE (op) == SYMBOL_REF)    return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0	    && SYMBOL_REF_TLS_MODEL (op) == 0	    && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));  /* Now we must have a @GOTENT offset or @PLT stub     or an @INDNTPOFF TLS offset.  */  if (GET_CODE (op) == UNSPEC      && XINT (op, 1) == UNSPEC_GOTENT)    return 1;  if (GET_CODE (op) == UNSPEC      && XINT (op, 1) == UNSPEC_PLT)    return 1;  if (GET_CODE (op) == UNSPEC      && XINT (op, 1) == UNSPEC_INDNTPOFF)    return 1;  return 0;}/* Return true if OP is a valid S-type operand.   OP is the current operation.   MODE is the current operation mode.  */ints_operand (rtx op, enum machine_mode mode){  struct s390_address addr;  /* Call general_operand first, so that we don't have to     check for many special cases.  */  if (!general_operand (op, mode))    return 0;  /* Just like memory_operand, allow (subreg (mem ...))     after reload.  */  if (reload_completed      && GET_CODE (op) == SUBREG      && GET_CODE (SUBREG_REG (op)) == MEM)    op = SUBREG_REG (op);  if (GET_CODE (op) != MEM)    return 0;  if (!s390_decompose_address (XEXP (op, 0), &addr))    return 0;  if (addr.indx)    return 0;  return 1;}/* Return true if OP a valid shift count operand.   OP is the current operation.   MODE is the current operation mode.  */intshift_count_operand (rtx op, enum machine_mode mode){  HOST_WIDE_INT offset = 0;  if (! check_mode (op, &mode))    return 0;  /* We can have an integer constant, an address register,     or a sum of the two.  Note that reload already checks     that any register present is an address register, so     we just check for any register here.  */  if (GET_CODE (op) == CONST_INT)    {      offset = INTVAL (op);      op = NULL_RTX;    }  if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)    {      offset = INTVAL (XEXP (op, 1));      op = XEXP (op, 0);    }  while (op && GET_CODE (op) == SUBREG)    op = SUBREG_REG (op);  if (op && GET_CODE (op) != REG)    return 0;  /* Unfortunately we have to reject constants that are invalid     for an address, or else reload will get confused.  */  if (!DISP_IN_RANGE (offset))    return 0;  return 1;}/* Return true if DISP is a valid short displacement.  */static ints390_short_displacement (rtx disp){  /* No displacement is OK.  */  if (!disp)    return 1;  /* Integer displacement in range.  */  if (GET_CODE (disp) == CONST_INT)    return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;  /* GOT offset is not OK, the GOT can be large.  */  if (GET_CODE (disp) == CONST      && GET_CODE (XEXP (disp, 0)) == UNSPEC      && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT          || XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))    return 0;  /* All other symbolic constants are literal pool references,     which are OK as the literal pool must be small.  */  if (GET_CODE (disp) == CONST)    return 1;  return 0;}/* Return true if OP is a valid operand for a C constraint.  */ints390_extra_constraint_str (rtx op, int c, const char * str){  struct s390_address addr;  if (c != str[0])    abort ();  /* Check for offsettable variants of memory constraints.  */  if (c == 'A')    {      /* Only accept non-volatile MEMs.  */      if (!MEM_P (op) || MEM_VOLATILE_P (op))	return 0;      if ((reload_completed || reload_in_progress)	  ? !offsettable_memref_p (op)	  : !offsettable_nonstrict_memref_p (op))	return 0;      c = str[1];    }  /* Check for non-literal-pool variants of memory constraints.  */  else if (c == 'B')    {      if (GET_CODE (op) != MEM)	return 0;      if (!s390_decompose_address (XEXP (op, 0), &addr))	return 0;      if (addr.base && REG_P (addr.base) && REGNO (addr.base) == BASE_REGNUM)	return 0;      if (addr.indx && REG_P (addr.indx) && REGNO (addr.indx) == BASE_REGNUM)	return 0;      c = str[1];    }  switch (c)    {    case 'Q':      if (GET_CODE (op) != MEM)	return 0;      if (!s390_decompose_address (XEXP (op, 0), &addr))	return 0;      if (addr.indx)	return 0;      if (TARGET_LONG_DISPLACEMENT)	{	  if (!s390_short_displacement (addr.disp))	    return 0;	}      break;    case 'R':      if (GET_CODE (op) != MEM)	return 0;      if (TARGET_LONG_DISPLACEMENT)	{	  if (!s390_decompose_address (XEXP (op, 0), &addr))	    return 0;	  if (!s390_short_displacement (addr.disp))	    return 0;	}      break;    case 'S':      if (!TARGET_LONG_DISPLACEMENT)	return 0;      if (GET_CODE (op) != MEM)	return 0;      if (!s390_decompose_address (XEXP (op, 0), &addr))	return 0;      if (addr.indx)	return 0;      if (s390_short_displacement (addr.disp))	return 0;      break;    case 'T':      if (!TARGET_LONG_DISPLACEMENT)	return 0;      if (GET_CODE (op) != MEM)	return 0;      /* Any invalid address here will be fixed up by reload,	 so accept it for the most generic constraint.  */      if (s390_decompose_address (XEXP (op, 0), &addr)	  && s390_short_displacement (addr.disp))	return 0;      break;    case 'U':      if (TARGET_LONG_DISPLACEMENT)	{	  if (!s390_decompose_address (op, &addr))	    return 0;	  if (!s390_short_displacement (addr.disp))	    return 0;	}      break;    case 'W':      if (!TARGET_LONG_DISPLACEMENT)	return 0;      /* Any invalid address here will be fixed up by reload,	 so accept it for the most generic constraint.  */      if (s390_decompose_address (op, &addr)	  && s390_short_displacement (addr.disp))	return 0;      break;    case 'Y':      return shift_count_operand (op, VOIDmode);    default:      return 0;    }  return 1;}/* 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;  if (c != str[0])    abort ();  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 'H': part_mode = HImode; break;	case 'Q': part_mode = QImode; 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;    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){

⌨️ 快捷键说明

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