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

📄 varasm.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Likewise for global constructors.  */voidassemble_constructor (name)     char *name;{#ifdef ASM_OUTPUT_CONSTRUCTOR  ASM_OUTPUT_CONSTRUCTOR (asm_out_file, name);#else  if (flag_gnu_linker)    {      /* Now tell GNU LD that this is part of the static constructor set.  */      /* This code works for any machine provided you use GNU as/ld.  */      fprintf (asm_out_file, "%s \"___CTOR_LIST__\",22,0,0,", ASM_STABS_OP);      assemble_name (asm_out_file, name);      fputc ('\n', asm_out_file);    }#endif}/* Likewise for entries we want to record for garbage collection.   Garbage collection is still under development.  */voidassemble_gc_entry (name)     char *name;{#ifdef ASM_OUTPUT_GC_ENTRY  ASM_OUTPUT_GC_ENTRY (asm_out_file, name);#else  if (flag_gnu_linker)    {      /* Now tell GNU LD that this is part of the static constructor set.  */      fprintf (asm_out_file, "%s \"___PTR_LIST__\",22,0,0,", ASM_STABS_OP);      assemble_name (asm_out_file, name);      fputc ('\n', asm_out_file);    }#endif}/* Output assembler code for the constant pool of a function and associated   with defining the name of the function.  DECL describes the function.   NAME is the function's name.  For the constant pool, we use the current   constant pool data.  */voidassemble_start_function (decl, fnname)     tree decl;     char *fnname;{  int align;  /* The following code does not need preprocessing in the assembler.  */  app_disable ();  output_constant_pool (fnname, decl);  text_section ();  /* Tell assembler to move to target machine's alignment for functions.  */  align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);  if (align > 0)    ASM_OUTPUT_ALIGN (asm_out_file, align);#ifdef ASM_OUTPUT_FUNCTION_PREFIX  ASM_OUTPUT_FUNCTION_PREFIX (asm_out_file, fnname);#endif#ifdef SDB_DEBUGGING_INFO  /* Output SDB definition of the function.  */  if (write_symbols == SDB_DEBUG)    sdbout_mark_begin_function ();#endif#ifdef DBX_DEBUGGING_INFO  /* Output DBX definition of the function.  */  if (write_symbols == DBX_DEBUG)    dbxout_begin_function (decl);#endif  /* Make function name accessible from other files, if appropriate.  */  if (TREE_PUBLIC (decl))    {      if (!first_global_object_name)	STRIP_NAME_ENCODING (first_global_object_name, fnname);      ASM_GLOBALIZE_LABEL (asm_out_file, fnname);    }  /* Do any machine/system dependent processing of the function name */#ifdef ASM_DECLARE_FUNCTION_NAME  ASM_DECLARE_FUNCTION_NAME (asm_out_file, fnname, current_function_decl);#else  /* Standard thing is just output label for the function.  */  ASM_OUTPUT_LABEL (asm_out_file, fnname);#endif /* ASM_DECLARE_FUNCTION_NAME */}/* Output assembler code associated with defining the size of the   function.  DECL describes the function.  NAME is the function's name.  */voidassemble_end_function (decl, fnname)     tree decl;     char *fnname;{#ifdef ASM_DECLARE_FUNCTION_SIZE  ASM_DECLARE_FUNCTION_SIZE (asm_out_file, fnname, decl);#endif}/* Assemble code to leave SIZE bytes of zeros.  */voidassemble_zeros (size)     int size;{#ifdef ASM_NO_SKIP_IN_TEXT  /* The `space' pseudo in the text section outputs nop insns rather than 0s,     so we must output 0s explicitly in the text section.  */  if (ASM_NO_SKIP_IN_TEXT && in_text_section ())    {      int i;      for (i = 0; i < size - 20; i += 20)	{#ifdef ASM_BYTE_OP	  fprintf (asm_out_file,		   "%s 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n", ASM_BYTE_OP);#else	  fprintf (asm_out_file,		   "\tbyte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n");#endif	}      if (i < size)        {#ifdef ASM_BYTE_OP	  fprintf (asm_out_file, "%s 0", ASM_BYTE_OP);#else	  fprintf (asm_out_file, "\tbyte 0");#endif	  i++;	  for (; i < size; i++)	    fprintf (asm_out_file, ",0");	  fprintf (asm_out_file, "\n");	}    }  else#endif    ASM_OUTPUT_SKIP (asm_out_file, size);}/* Assemble a string constant with the specified C string as contents.  */voidassemble_string (p, size)     unsigned char *p;     int size;{  register int i;  int pos = 0;  int maximum = 2000;  /* If the string is very long, split it up.  */  while (pos < size)    {      int thissize = size - pos;      if (thissize > maximum)	thissize = maximum;      ASM_OUTPUT_ASCII (asm_out_file, p, thissize);      pos += thissize;      p += thissize;    }}/* Assemble everything that is needed for a variable or function declaration.   Not used for automatic variables, and not used for function definitions.   Should not be called for variables of incomplete structure type.   TOP_LEVEL is nonzero if this variable has file scope.   AT_END is nonzero if this is the special handling, at end of compilation,   to define things that have had only tentative definitions.  */voidassemble_variable (decl, top_level, at_end)     tree decl;     int top_level;     int at_end;{  register char *name;  int align;  tree size_tree;  int reloc = 0;  if (GET_CODE (DECL_RTL (decl)) == REG)    {      /* Do output symbol info for global register variables, but do nothing	 else for them.  */      if (TREE_ASM_WRITTEN (decl))	return;      TREE_ASM_WRITTEN (decl) = 1;#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)      /* File-scope global variables are output here.  */      if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)	  && top_level)	dbxout_symbol (decl, 0);#endif#ifdef SDB_DEBUGGING_INFO      if (write_symbols == SDB_DEBUG && top_level	  /* Leave initialized global vars for end of compilation;	     see comment in compile_file.  */	  && (TREE_PUBLIC (decl) == 0 || DECL_INITIAL (decl) == 0))	sdbout_symbol (decl, 0);#endif      /* Don't output any DWARF debugging information for variables here.	 In the case of local variables, the information for them is output	 when we do our recursive traversal of the tree representation for	 the entire containing function.  In the case of file-scope variables,	 we output information for all of them at the very end of compilation	 while we are doing our final traversal of the chain of file-scope	 declarations.  */      return;    }  /* Normally no need to say anything for external references,     since assembler considers all undefined symbols external.  */  if (DECL_EXTERNAL (decl))    return;  /* Output no assembler code for a function declaration.     Only definitions of functions output anything.  */  if (TREE_CODE (decl) == FUNCTION_DECL)    return;  /* If type was incomplete when the variable was declared,     see if it is complete now.  */  if (DECL_SIZE (decl) == 0)    layout_decl (decl, 0);  /* Still incomplete => don't allocate it; treat the tentative defn     (which is what it must have been) as an `extern' reference.  */  if (DECL_SIZE (decl) == 0)    {      error_with_file_and_line (DECL_SOURCE_FILE (decl),				DECL_SOURCE_LINE (decl),				"storage size of `%s' isn't known",				IDENTIFIER_POINTER (DECL_NAME (decl)));      return;    }  /* The first declaration of a variable that comes through this function     decides whether it is global (in C, has external linkage)     or local (in C, has internal linkage).  So do nothing more     if this function has already run.  */  if (TREE_ASM_WRITTEN (decl))    return;  TREE_ASM_WRITTEN (decl) = 1;#ifdef DBX_DEBUGGING_INFO  /* File-scope global variables are output here.  */  if (write_symbols == DBX_DEBUG && top_level)    dbxout_symbol (decl, 0);#endif#ifdef SDB_DEBUGGING_INFO  if (write_symbols == SDB_DEBUG && top_level      /* Leave initialized global vars for end of compilation;	 see comment in compile_file.  */      && (TREE_PUBLIC (decl) == 0 || DECL_INITIAL (decl) == 0))    sdbout_symbol (decl, 0);#endif  /* Don't output any DWARF debugging information for variables here.     In the case of local variables, the information for them is output     when we do our recursive traversal of the tree representation for     the entire containing function.  In the case of file-scope variables,     we output information for all of them at the very end of compilation     while we are doing our final traversal of the chain of file-scope     declarations.  */  /* If storage size is erroneously variable, just continue.     Error message was already made.  */  if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)    goto finish;  app_disable ();  /* This is better than explicit arithmetic, since it avoids overflow.  */  size_tree = size_binop (CEIL_DIV_EXPR,			  DECL_SIZE (decl), size_int (BITS_PER_UNIT));  if (TREE_INT_CST_HIGH (size_tree) != 0)    {      error_with_decl (decl, "size of variable `%s' is too large");      goto finish;    }  name = XSTR (XEXP (DECL_RTL (decl), 0), 0);  /* Handle uninitialized definitions.  */  /* ANSI specifies that a tentative definition which is not merged with     a non-tentative definition behaves exactly like a definition with an     initializer equal to zero.  (Section 3.7.2)     -fno-common gives strict ANSI behavior.  Usually you don't want it.  */  if (! flag_no_common      && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))    {      int size = TREE_INT_CST_LOW (size_tree);      int rounded = size;      if (TREE_INT_CST_HIGH (size_tree) != 0)	error_with_decl (decl, "size of variable `%s' is too large");      /* Don't allocate zero bytes of common,	 since that means "undefined external" in the linker.  */      if (size == 0) rounded = 1;      /* Round size up to multiple of BIGGEST_ALIGNMENT bits	 so that each uninitialized object starts on such a boundary.  */      rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;      rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)		 * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));#if 0      if (flag_shared_data)	data_section ();#endif      if (TREE_PUBLIC (decl))	{#ifdef ASM_OUTPUT_SHARED_COMMON	  if (flag_shared_data)	    ASM_OUTPUT_SHARED_COMMON (asm_out_file, name, size, rounded);	  else#endif#ifdef ASM_OUTPUT_ALIGNED_COMMON	    ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size,				       DECL_ALIGN (decl));#else	    ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);#endif	}      else	{#ifdef ASM_OUTPUT_SHARED_LOCAL	  if (flag_shared_data)	    ASM_OUTPUT_SHARED_LOCAL (asm_out_file, name, size, rounded);	  else#endif#ifdef ASM_OUTPUT_ALIGNED_LOCAL	    ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size,				      DECL_ALIGN (decl));#else	    ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);#endif	}      goto finish;    }  /* Handle initialized definitions.  */  /* First make the assembler name(s) global if appropriate.  */  if (TREE_PUBLIC (decl) && DECL_NAME (decl))    {      if (!first_global_object_name)	STRIP_NAME_ENCODING(first_global_object_name, name);      ASM_GLOBALIZE_LABEL (asm_out_file, name);    }#if 0  for (d = equivalents; d; d = TREE_CHAIN (d))    {      tree e = TREE_VALUE (d);      if (TREE_PUBLIC (e) && DECL_NAME (e))	ASM_GLOBALIZE_LABEL (asm_out_file,			     XSTR (XEXP (DECL_RTL (e), 0), 0));    }#endif  /* Output any data that we will need to use the address of.  */  if (DECL_INITIAL (decl))    reloc = output_addressed_constants (DECL_INITIAL (decl));  /* Switch to the proper section for this data.  */#ifdef SELECT_SECTION  SELECT_SECTION (decl, reloc);#else  if (TREE_READONLY (decl)      && ! TREE_THIS_VOLATILE (decl)      && ! (flag_pic && reloc))    readonly_data_section ();  else    data_section ();#endif  /* Compute and output the alignment of this data.  */  align = DECL_ALIGN (decl);  /* Some object file formats have a maximum alignment which they support.     In particular, a.out format supports a maximum alignment of 4.  */#ifndef MAX_OFILE_ALIGNMENT#define MAX_OFILE_ALIGNMENT BIGGEST_ALIGNMENT#endif  if (align > MAX_OFILE_ALIGNMENT)    {      warning_with_decl (decl,	  "alignment of `%s' is greater than maximum object file alignment");      align = MAX_OFILE_ALIGNMENT;    }#ifdef DATA_ALIGNMENT  /* On some machines, it is good to increase alignment sometimes.  */  align = DATA_ALIGNMENT (TREE_TYPE (decl), align);#endif#ifdef CONSTANT_ALIGNMENT  if (DECL_INITIAL (decl))    align = CONSTANT_ALIGNMENT (DECL_INITIAL (decl), align);#endif  /* Reset the alignment in case we have made it tighter, so we can benefit     from it in get_pointer_alignment.  */  DECL_ALIGN (decl) = align;  if (align > BITS_PER_UNIT)    ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));  /* Do any machine/system dependent processing of the object.  */#ifdef ASM_DECLARE_OBJECT_NAME  ASM_DECLARE_OBJECT_NAME (asm_out_file, name, decl);#else  /* Standard thing is just output label for the object.  */  ASM_OUTPUT_LABEL (asm_out_file, name);#endif /* ASM_DECLARE_OBJECT_NAME */#if 0  for (d = equivalents; d; d = TREE_CHAIN (d))    {      tree e = TREE_VALUE (d);      ASM_OUTPUT_LABEL (asm_out_file, XSTR (XEXP (DECL_RTL (e), 0), 0));    }#endif  if (DECL_INITIAL (decl))    /* Output the actual data.  */    output_constant (DECL_INITIAL (decl),		     int_size_in_bytes (TREE_TYPE (decl)));  else    /* Leave space for it.  */    assemble_zeros (int_size_in_bytes (TREE_TYPE (decl))); finish:#ifdef XCOFF_DEBUGGING_INFO  /* Unfortunately, the IBM assembler cannot handle stabx before the actual     declaration.  When something like ".stabx  "aa:S-2",aa,133,0" is emitted      and `aa' hasn't been output yet, the assembler generates a stab entry with     a value of zero, in addition to creating an unnecessary external entry     for `aa'.  Hence, we must postpone dbxout_symbol to here at the end.  */  /* File-scope global variables are output here.  */  if (write_symbols == XCOFF_DEBUG && top_level)

⌨️ 快捷键说明

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