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

📄 varasm.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
    dbxout_symbol (decl, 0);#else  /* There must be a statement after a label.  */  ;#endif}/* Output something to declare an external symbol to the assembler.   (Most assemblers don't need this, so we normally output nothing.)   Do nothing if DECL is not external.  */voidassemble_external (decl)     tree decl;{#ifdef ASM_OUTPUT_EXTERNAL  if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd'      && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))    {      rtx rtl = DECL_RTL (decl);      if (GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF	  && ! SYMBOL_REF_USED (XEXP (rtl, 0)))	{	  /* Some systems do require some output.  */	  SYMBOL_REF_USED (XEXP (rtl, 0)) = 1;	  ASM_OUTPUT_EXTERNAL (asm_out_file, decl, XSTR (XEXP (rtl, 0), 0));	}    }#endif}/* Similar, for calling a library function FUN.  */voidassemble_external_libcall (fun)     rtx fun;{#ifdef ASM_OUTPUT_EXTERNAL_LIBCALL  /* Declare library function name external when first used, if nec.  */  if (! SYMBOL_REF_USED (fun))    {      SYMBOL_REF_USED (fun) = 1;      ASM_OUTPUT_EXTERNAL_LIBCALL (asm_out_file, fun);    }#endif}/* Declare the label NAME global.  */voidassemble_global (name)     char *name;{  ASM_GLOBALIZE_LABEL (asm_out_file, name);}/* Assemble a label named NAME.  */voidassemble_label (name)     char *name;{  ASM_OUTPUT_LABEL (asm_out_file, name);}/* Output to FILE a reference to the assembler name of a C-level name NAME.   If NAME starts with a *, the rest of NAME is output verbatim.   Otherwise NAME is transformed in an implementation-defined way   (usually by the addition of an underscore).   Many macros in the tm file are defined to call this function.  */voidassemble_name (file, name)     FILE *file;     char *name;{  if (name[0] == '*')    fputs (&name[1], file);  else    ASM_OUTPUT_LABELREF (file, name);}/* Allocate SIZE bytes writable static space with a gensym name   and return an RTX to refer to its address.  */rtxassemble_static_space (size)     int size;{  char name[12];  char *namestring;  rtx x;  /* Round size up to multiple of BIGGEST_ALIGNMENT bits     so that each uninitialized object starts on such a boundary.  */  int rounded = ((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)		 / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)		 * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));#if 0  if (flag_shared_data)    data_section ();#endif  ASM_GENERATE_INTERNAL_LABEL (name, "LF", const_labelno);  ++const_labelno;  namestring = (char *) obstack_alloc (saveable_obstack,				       strlen (name) + 2);  strcpy (namestring, name);  x = gen_rtx (SYMBOL_REF, Pmode, namestring);#ifdef ASM_OUTPUT_ALIGNED_LOCAL  ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size, BIGGEST_ALIGNMENT);#else  ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);#endif  return x;}/* Assemble the static constant template for function entry trampolines.   This is done at most once per compilation.   Returns an RTX for the address of the template.  */rtxassemble_trampoline_template (){  char label[256];  char *name;  int align;  /* By default, put trampoline templates in read-only data section.  */#ifdef TRAMPOLINE_SECTION  TRAMPOLINE_SECTION ();#else  readonly_data_section ();#endif  /* Write the assembler code to define one.  */  align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);  if (align > 0)    ASM_OUTPUT_ALIGN (asm_out_file, align);  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LTRAMP", 0);  TRAMPOLINE_TEMPLATE (asm_out_file);  /* Record the rtl to refer to it.  */  ASM_GENERATE_INTERNAL_LABEL (label, "LTRAMP", 0);  name    = (char *) obstack_copy0 (&permanent_obstack, label, strlen (label));  return gen_rtx (SYMBOL_REF, Pmode, name);}/* Assemble the integer constant X into an object of SIZE bytes.   X must be either a CONST_INT or CONST_DOUBLE.   Return 1 if we were able to output the constant, otherwise 0.  If FORCE is   non-zero, abort if we can't output the constant.  */intassemble_integer (x, size, force)     rtx x;     int size;     int force;{  /* First try to use the standard 1, 2, 4, 8, and 16 byte     ASM_OUTPUT... macros. */  switch (size)    {#ifdef ASM_OUTPUT_CHAR    case 1:      ASM_OUTPUT_CHAR (asm_out_file, x);      return 1;#endif#ifdef ASM_OUTPUT_SHORT    case 2:      ASM_OUTPUT_SHORT (asm_out_file, x);      return 1;#endif#ifdef ASM_OUTPUT_INT    case 4:      ASM_OUTPUT_INT (asm_out_file, x);      return 1;#endif#ifdef ASM_OUTPUT_DOUBLE_INT    case 8:      ASM_OUTPUT_DOUBLE_INT (asm_out_file, x);      return 1;#endif#ifdef ASM_OUTPUT_QUADRUPLE_INT    case 16:      ASM_OUTPUT_QUADRUPLE_INT (asm_out_file, x);      return 1;#endif    }  /* If we couldn't do it that way, there are two other possibilities: First,     if the machine can output an explicit byte and this is a 1 byte constant,     we can use ASM_OUTPUT_BYTE.  */#ifdef ASM_OUTPUT_BYTE  if (size == 1 && GET_CODE (x) == CONST_INT)    {      ASM_OUTPUT_BYTE (asm_out_file, INTVAL (x));      return 1;    }#endif  /* Finally, if SIZE is larger than a single word, try to output the constant     one word at a time.  */  if (size > UNITS_PER_WORD)    {      int i;      enum machine_mode mode	= mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);      rtx word;      for (i = 0; i < size / UNITS_PER_WORD; i++)	{	  word = operand_subword (x, i, 0, mode);	  if (word == 0)	    break;	  if (! assemble_integer (word, UNITS_PER_WORD, 0))	    break;	}      if (i == size / UNITS_PER_WORD)	return 1;      /* If we output at least one word and then could not finish,	 there is no valid way to continue.  */      if (i > 0)	abort ();    }  if (force)    abort ();  return 0;}/* Assemble the floating-point constant D into an object of size MODE.  */voidassemble_real (d, mode)     REAL_VALUE_TYPE d;     enum machine_mode mode;{  jmp_buf output_constant_handler;  if (setjmp (output_constant_handler))    {      error ("floating point trap outputting a constant");#ifdef REAL_IS_NOT_DOUBLE      bzero (&d, sizeof d);      d = dconst0;#else      d = 0;#endif    }  set_float_handler (output_constant_handler);  switch (mode)    {#ifdef ASM_OUTPUT_FLOAT    case SFmode:      ASM_OUTPUT_FLOAT (asm_out_file, d);      break;#endif#ifdef ASM_OUTPUT_DOUBLE    case DFmode:      ASM_OUTPUT_DOUBLE (asm_out_file, d);      break;#endif#ifdef ASM_OUTPUT_LONG_DOUBLE    case TFmode:      ASM_OUTPUT_LONG_DOUBLE (asm_out_file, d);      break;#endif    default:      abort ();    }  set_float_handler (NULL_PTR);}/* Here we combine duplicate floating constants to make   CONST_DOUBLE rtx's, and force those out to memory when necessary.  *//* Chain of all CONST_DOUBLE rtx's constructed for the current function.   They are chained through the CONST_DOUBLE_CHAIN.   A CONST_DOUBLE rtx has CONST_DOUBLE_MEM != cc0_rtx iff it is on this chain.   In that case, CONST_DOUBLE_MEM is either a MEM,   or const0_rtx if no MEM has been made for this CONST_DOUBLE yet.   (CONST_DOUBLE_MEM is used only for top-level functions.   See force_const_mem for explanation.)  */static rtx const_double_chain;/* Return a CONST_DOUBLE for a value specified as a pair of ints.   For an integer, I0 is the low-order word and I1 is the high-order word.   For a real number, I0 is the word with the low address   and I1 is the word with the high address.  */rtximmed_double_const (i0, i1, mode)     HOST_WIDE_INT i0, i1;     enum machine_mode mode;{  register rtx r;  int in_current_obstack;  if (GET_MODE_CLASS (mode) == MODE_INT)    {      /* We clear out all bits that don't belong in MODE, unless they and our	 sign bit are all one.  So we get either a reasonable negative value	 or a reasonable unsigned value for this mode.  */      int width = GET_MODE_BITSIZE (mode);      if (width < HOST_BITS_PER_WIDE_INT	  && ((i0 & ((HOST_WIDE_INT) (-1) << (width - 1)))	      != ((HOST_WIDE_INT) (-1) << (width - 1))))	i0 &= ((HOST_WIDE_INT) 1 << width) - 1, i1 = 0;      else if (width == HOST_BITS_PER_WIDE_INT	       && ! (i1 == ~0 && i0 < 0))	i1 = 0;      else if (width > 2 * HOST_BITS_PER_WIDE_INT)	/* We cannot represent this value as a constant.  */	abort ();      /* If MODE fits within HOST_BITS_PER_WIDE_INT, always use a CONST_INT.	 ??? Strictly speaking, this is wrong if we create a CONST_INT	 for a large unsigned constant with the size of MODE being	 HOST_BITS_PER_WIDE_INT and later try to interpret that constant in a	 wider mode.  In that case we will mis-interpret it as a negative	 number.	 Unfortunately, the only alternative is to make a CONST_DOUBLE	 for any constant in any mode if it is an unsigned constant larger	 than the maximum signed integer in an int on the host.  However,	 doing this will break everyone that always expects to see a CONST_INT	 for SImode and smaller.	 We have always been making CONST_INTs in this case, so nothing new	 is being broken.  */      if (width <= HOST_BITS_PER_WIDE_INT)	i1 = (i0 < 0) ? ~0 : 0;      /* If this integer fits in one word, return a CONST_INT.  */      if ((i1 == 0 && i0 >= 0)	  || (i1 == ~0 && i0 < 0))	return GEN_INT (i0);      /* We use VOIDmode for integers.  */      mode = VOIDmode;    }  /* Search the chain for an existing CONST_DOUBLE with the right value.     If one is found, return it.  */  for (r = const_double_chain; r; r = CONST_DOUBLE_CHAIN (r))    if (CONST_DOUBLE_LOW (r) == i0 && CONST_DOUBLE_HIGH (r) == i1	&& GET_MODE (r) == mode)      return r;  /* No; make a new one and add it to the chain.     We may be called by an optimizer which may be discarding any memory     allocated during its processing (such as combine and loop).  However,     we will be leaving this constant on the chain, so we cannot tolerate     freed memory.  So switch to saveable_obstack for this allocation     and then switch back if we were in current_obstack.  */  in_current_obstack = rtl_in_saveable_obstack ();  r = gen_rtx (CONST_DOUBLE, mode, 0, i0, i1);  if (in_current_obstack)    rtl_in_current_obstack ();  /* Don't touch const_double_chain in nested function;     see force_const_mem.  */  if (outer_function_chain == 0)    {      CONST_DOUBLE_CHAIN (r) = const_double_chain;      const_double_chain = r;    }  /* Store const0_rtx in mem-slot since this CONST_DOUBLE is on the chain.     Actual use of mem-slot is only through force_const_mem.  */  CONST_DOUBLE_MEM (r) = const0_rtx;  return r;}/* Return a CONST_DOUBLE for a specified `double' value   and machine mode.  */rtximmed_real_const_1 (d, mode)     REAL_VALUE_TYPE d;     enum machine_mode mode;{  union real_extract u;  register rtx r;  int in_current_obstack;  /* Get the desired `double' value as a sequence of ints     since that is how they are stored in a CONST_DOUBLE.  */  u.d = d;  /* Detect special cases.  */  /* Avoid REAL_VALUES_EQUAL here in order to distinguish minus zero.  */  if (!bcmp (&dconst0, &d, sizeof d))    return CONST0_RTX (mode);  else if (REAL_VALUES_EQUAL (dconst1, d))    return CONST1_RTX (mode);  if (sizeof u == 2 * sizeof (HOST_WIDE_INT))    return immed_double_const (u.i[0], u.i[1], mode);  /* The rest of this function handles the case where     a float value requires more than 2 ints of space.     It will be deleted as dead code on machines that don't need it.  */  /* Search the chain for an existing CONST_DOUBLE with the right value.     If one is found, return it.  */  for (r = const_double_chain; r; r = CONST_DOUBLE_CHAIN (r))    if (! bcmp (&CONST_DOUBLE_LOW (r), &u, sizeof u)	&& GET_MODE (r) == mode)      return r;  /* No; make a new one and add it to the chain.     We may be called by an optimizer which may be discarding any memory     allocated during its processing (such as combine and loop).  However,     we will be leaving this constant on the chain, so we cannot tolerate     freed memory.  So switch to saveable_obstack for this allocation     and then switch back if we were in current_obstack.  */  in_current_obstack = rtl_in_saveable_obstack ();  r = rtx_alloc (CONST_DOUBLE);  PUT_MODE (r, mode);  bcopy (&u, &CONST_DOUBLE_LOW (r), sizeof u);  if (in_current_obstack)    rtl_in_current_obstack ();  /* Don't touch const_double_chain in nested function;     see force_const_mem.  */  if (outer_function_chain == 0)    {      CONST_DOUBLE_CHAIN (r) = const_double_chain;      const_double_chain = r;    }

⌨️ 快捷键说明

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