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

📄 varasm.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
		    (char *) &value.offset, sizeof value.offset);      /* Record the symbol name.  */      obstack_grow (&permanent_obstack, XSTR (value.base, 0),		    strlen (XSTR (value.base, 0)) + 1);      return;    }  else if (code == PLUS_EXPR || code == MINUS_EXPR)    {      record_constant_1 (TREE_OPERAND (exp, 0));      record_constant_1 (TREE_OPERAND (exp, 1));      return;    }  else if (code == NOP_EXPR || code == CONVERT_EXPR)    {      record_constant_1 (TREE_OPERAND (exp, 0));      return;    }  /* Record constant contents.  */  obstack_grow (&permanent_obstack, strp, len);}/* Return an rtx representing a reference to constant data in memory   for the constant expression EXP.   If assembler code for such a constant has already been output,   return an rtx to refer to it.   Otherwise, output such a constant in memory and generate   an rtx for it.  The TREE_CST_RTL of EXP is set up to point to that rtx.   The const_hash_table records which constants already have label strings.  */rtxoutput_constant_def (exp)     tree exp;{  register int hash, align;  register struct constant_descriptor *desc;  char label[256];  char *found = 0;  int reloc;  register rtx def;  if (TREE_CODE (exp) == INTEGER_CST)    abort ();			/* No TREE_CST_RTL slot in these.  */  if (TREE_CST_RTL (exp))    return TREE_CST_RTL (exp);  /* Make sure any other constants whose addresses appear in EXP     are assigned label numbers.  */  reloc = output_addressed_constants (exp);  /* Compute hash code of EXP.  Search the descriptors for that hash code     to see if any of them describes EXP.  If yes, the descriptor records     the label number already assigned.  */  hash = const_hash (exp) % MAX_HASH_TABLE;  for (desc = const_hash_table[hash]; desc; desc = desc->next)    if (compare_constant (exp, desc))      {	found = desc->label;	break;      }  if (found == 0)    {      /* No constant equal to EXP is known to have been output.	 Make a constant descriptor to enter EXP in the hash table.	 Assign the label number and record it in the descriptor for	 future calls to this function to find.  */      /* Create a string containing the label name, in LABEL.  */      ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);      desc = record_constant (exp);      desc->next = const_hash_table[hash];      desc->label	= (char *) obstack_copy0 (&permanent_obstack, label, strlen (label));      const_hash_table[hash] = desc;    }  /* We have a symbol name; construct the SYMBOL_REF and the MEM.  */  push_obstacks_nochange ();  if (TREE_PERMANENT (exp))    end_temporary_allocation ();  def = gen_rtx (SYMBOL_REF, Pmode, desc->label);  TREE_CST_RTL (exp)    = gen_rtx (MEM, TYPE_MODE (TREE_TYPE (exp)), def);  RTX_UNCHANGING_P (TREE_CST_RTL (exp)) = 1;  if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE      || TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)    MEM_IN_STRUCT_P (TREE_CST_RTL (exp)) = 1;  pop_obstacks ();  /* Optionally set flags or add text to the name to record information     such as that it is a function name.  If the name is changed, the macro     ASM_OUTPUT_LABELREF will have to know how to strip this information.     And if it finds a * at the beginning after doing so, it must handle     that too.  */#ifdef ENCODE_SECTION_INFO  ENCODE_SECTION_INFO (exp);#endif  if (found == 0)    {      /* Now output assembler code to define that label	 and follow it with the data of EXP.  */      /* First switch to text section, except for writable strings.  */#ifdef SELECT_SECTION      SELECT_SECTION (exp, reloc);#else      if (((TREE_CODE (exp) == STRING_CST) && flag_writable_strings)	  || (flag_pic && reloc))	data_section ();      else	readonly_data_section ();#endif      /* Align the location counter as required by EXP's data type.  */      align = TYPE_ALIGN (TREE_TYPE (exp));#ifdef CONSTANT_ALIGNMENT      align = CONSTANT_ALIGNMENT (exp, align);#endif      if (align > BITS_PER_UNIT)	ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));      /* Output the label itself.  */      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LC", const_labelno);      /* Output the value of EXP.  */      output_constant (exp,		       (TREE_CODE (exp) == STRING_CST			? TREE_STRING_LENGTH (exp)			: int_size_in_bytes (TREE_TYPE (exp))));      ++const_labelno;    }  return TREE_CST_RTL (exp);}/* Similar hash facility for making memory-constants   from constant rtl-expressions.  It is used on RISC machines   where immediate integer arguments and constant addresses are restricted   so that such constants must be stored in memory.   This pool of constants is reinitialized for each function   so each function gets its own constants-pool that comes right before it.   All structures allocated here are discarded when functions are saved for   inlining, so they do not need to be allocated permanently.  */#define MAX_RTX_HASH_TABLE 61static struct constant_descriptor **const_rtx_hash_table;/* Structure to represent sufficient information about a constant so that   it can be output when the constant pool is output, so that function   integration can be done, and to simplify handling on machines that reference   constant pool as base+displacement.  */struct pool_constant{  struct constant_descriptor *desc;  struct pool_constant *next;  enum machine_mode mode;  rtx constant;  int labelno;  int align;  int offset;};/* Pointers to first and last constant in pool.  */static struct pool_constant *first_pool, *last_pool;/* Current offset in constant pool (does not include any machine-specific   header.  */static int pool_offset;/* Structure used to maintain hash table mapping symbols used to their   corresponding constants.  */struct pool_sym{  char *label;  struct pool_constant *pool;  struct pool_sym *next;};static struct pool_sym **const_rtx_sym_hash_table;/* Hash code for a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true.   The argument is XSTR (... , 0)  */#define SYMHASH(LABEL)	\  ((((HOST_WIDE_INT) (LABEL)) & ((1 << HASHBITS) - 1))  % MAX_RTX_HASH_TABLE)/* Initialize constant pool hashing for next function.  */voidinit_const_rtx_hash_table (){  const_rtx_hash_table    = ((struct constant_descriptor **)       oballoc (MAX_RTX_HASH_TABLE * sizeof (struct constant_descriptor *)));  const_rtx_sym_hash_table    = ((struct pool_sym **)       oballoc (MAX_RTX_HASH_TABLE * sizeof (struct pool_sym *)));  bzero (const_rtx_hash_table,	 MAX_RTX_HASH_TABLE * sizeof (struct constant_descriptor *));  bzero (const_rtx_sym_hash_table,	 MAX_RTX_HASH_TABLE * sizeof (struct pool_sym *));  first_pool = last_pool = 0;  pool_offset = 0;}/* Save and restore it for a nested function.  */voidsave_varasm_status (p)     struct function *p;{  p->const_rtx_hash_table = const_rtx_hash_table;  p->const_rtx_sym_hash_table = const_rtx_sym_hash_table;  p->first_pool = first_pool;  p->last_pool = last_pool;  p->pool_offset = pool_offset;}voidrestore_varasm_status (p)     struct function *p;{  const_rtx_hash_table = p->const_rtx_hash_table;  const_rtx_sym_hash_table = p->const_rtx_sym_hash_table;  first_pool = p->first_pool;  last_pool = p->last_pool;  pool_offset = p->pool_offset;}enum kind { RTX_DOUBLE, RTX_INT };struct rtx_const{#ifdef ONLY_INT_FIELDS  unsigned int kind : 16;  unsigned int mode : 16;#else  enum kind kind : 16;  enum machine_mode mode : 16;#endif  union {    union real_extract du;    struct addr_const addr;  } un;};/* Express an rtx for a constant integer (perhaps symbolic)   as the sum of a symbol or label plus an explicit integer.   They are stored into VALUE.  */static voiddecode_rtx_const (mode, x, value)     enum machine_mode mode;     rtx x;     struct rtx_const *value;{  /* Clear the whole structure, including any gaps.  */  {    int *p = (int *) value;    int *end = (int *) (value + 1);    while (p < end)      *p++ = 0;  }  value->kind = RTX_INT;	/* Most usual kind. */  value->mode = mode;  switch (GET_CODE (x))    {    case CONST_DOUBLE:      value->kind = RTX_DOUBLE;      value->mode = GET_MODE (x);      bcopy (&CONST_DOUBLE_LOW (x), &value->un.du, sizeof value->un.du);      break;    case CONST_INT:      value->un.addr.offset = INTVAL (x);      break;    case SYMBOL_REF:    case LABEL_REF:    case PC:      value->un.addr.base = x;      break;    case CONST:      x = XEXP (x, 0);      if (GET_CODE (x) == PLUS)	{	  value->un.addr.base = XEXP (x, 0);	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)	    abort ();	  value->un.addr.offset = INTVAL (XEXP (x, 1));	}      else if (GET_CODE (x) == MINUS)	{	  value->un.addr.base = XEXP (x, 0);	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)	    abort ();	  value->un.addr.offset = - INTVAL (XEXP (x, 1));	}      else	abort ();      break;    default:      abort ();    }  if (value->kind == RTX_INT && value->un.addr.base != 0)    switch (GET_CODE (value->un.addr.base))      {      case SYMBOL_REF:      case LABEL_REF:	/* Use the string's address, not the SYMBOL_REF's address,	   for the sake of addresses of library routines.	   For a LABEL_REF, compare labels.  */	value->un.addr.base = XEXP (value->un.addr.base, 0);      }}/* Given a MINUS expression, simplify it if both sides   include the same symbol.  */rtxsimplify_subtraction (x)     rtx x;{  struct rtx_const val0, val1;  decode_rtx_const (GET_MODE (x), XEXP (x, 0), &val0);  decode_rtx_const (GET_MODE (x), XEXP (x, 1), &val1);  if (val0.un.addr.base == val1.un.addr.base)    return GEN_INT (val0.un.addr.offset - val1.un.addr.offset);  return x;}/* Compute a hash code for a constant RTL expression.  */intconst_hash_rtx (mode, x)     enum machine_mode mode;     rtx x;{  register int hi, i;  struct rtx_const value;  decode_rtx_const (mode, x, &value);  /* Compute hashing function */  hi = 0;  for (i = 0; i < sizeof value / sizeof (int); i++)    hi += ((int *) &value)[i];  hi &= (1 << HASHBITS) - 1;  hi %= MAX_RTX_HASH_TABLE;  return hi;}/* Compare a constant rtl object X with a constant-descriptor DESC.   Return 1 if DESC describes a constant with the same value as X.  */static intcompare_constant_rtx (mode, x, desc)     enum machine_mode mode;     rtx x;     struct constant_descriptor *desc;{  register int *p = (int *) desc->contents;  register int *strp;  register int len;  struct rtx_const value;  decode_rtx_const (mode, x, &value);  strp = (int *) &value;  len = sizeof value / sizeof (int);  /* Compare constant contents.  */  while (--len >= 0)    if (*p++ != *strp++)      return 0;  return 1;}/* Construct a constant descriptor for the rtl-expression X.   It is up to the caller to enter the descriptor in the hash table.  */static struct constant_descriptor *record_constant_rtx (mode, x)     enum machine_mode mode;     rtx x;{  struct constant_descriptor *ptr;  char *label;  struct rtx_const value;  decode_rtx_const (mode, x, &value);  obstack_grow (current_obstack, &ptr, sizeof ptr);  obstack_grow (current_obstack, &label, sizeof label);  /* Record constant contents.  */  obstack_grow (current_obstack, &value, sizeof value);  return (struct constant_descriptor *) obstack_finish (current_obstack);}/* Given a constant rtx X, make (or find) a memory constant for its value   and return a MEM rtx to refer to it in memory.  */rtxforce_const_mem (mode, x)     enum machine_mode mode;     rtx x;{  register int hash;  register struct constant_descriptor *desc;  char label[256];  char *found = 0;  rtx def;  /* If we want this CONST_DOUBLE in the same mode as it is in memory     (this will always be true for floating CONST_DOUBLEs that have been     placed in memory, but not for VOIDmode (integer) CONST_DOUBLEs),     use the previous copy.  Otherwise, make a new one.  Note that in     the unlikely event that this same CONST_DOUBLE is used in two different     modes in an alternating fashion, we will allocate a lot of different     memory locations, but this should be extremely rare.  */  /* Don't use CONST_DOUBLE_MEM in a nested function.     Nested functions have their own constant pools,     so they can't share the same values in CONST_DOUBLE_MEM     with the containing function.  */  if (outer_function_chain == 0)    if (GET_CODE (x) == CONST_DOUBLE	&& GET_CODE (CONST_DOUBLE_MEM (x)) == MEM	&& GET_MODE (CONST_DOUBLE_MEM (x)) == mode)      return CONST_DOUBLE_MEM (x);  /* Compute hash code of X.  Search the descriptors for that hash code     to see if any of them describes X.  If yes, the descriptor records     the label number already assigned.  */  hash = const_hash_rtx (mode, x);  for (

⌨️ 快捷键说明

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