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

📄 varasm.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
    {      bc_make_decl_rtl (decl, asmspec, top_level);      return;    }  reg_number = decode_reg_name (asmspec);  if (DECL_ASSEMBLER_NAME (decl) != NULL_TREE)    name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));  if (reg_number == -2)    {      /* ASMSPEC is given, and not the name of a register.  */      name = (char *) obstack_alloc (saveable_obstack,				     strlen (asmspec) + 2);      name[0] = '*';      strcpy (&name[1], asmspec);    }  /* For a duplicate declaration, we can be called twice on the     same DECL node.  Don't discard the RTL already made.  */  if (DECL_RTL (decl) == 0)    {      DECL_RTL (decl) = 0;      /* First detect errors in declaring global registers.  */      if (DECL_REGISTER (decl) && reg_number == -1)	error_with_decl (decl,			 "register name not specified for `%s'");      else if (DECL_REGISTER (decl) && reg_number < 0)	error_with_decl (decl,			 "invalid register name for `%s'");      else if ((reg_number >= 0 || reg_number == -3) && ! DECL_REGISTER (decl))	error_with_decl (decl,			 "register name given for non-register variable `%s'");      else if (DECL_REGISTER (decl) && TREE_CODE (decl) == FUNCTION_DECL)	error ("function declared `register'");      else if (DECL_REGISTER (decl) && TYPE_MODE (TREE_TYPE (decl)) == BLKmode)	error_with_decl (decl, "data type of `%s' isn't suitable for a register");      else if (DECL_REGISTER (decl)	       && ! HARD_REGNO_MODE_OK (reg_number, TYPE_MODE (TREE_TYPE (decl))))	error_with_decl (decl, "register number for `%s' isn't suitable for the data type");      /* Now handle properly declared static register variables.  */      else if (DECL_REGISTER (decl))	{	  int nregs;#if 0 /* yylex should print the warning for this */	  if (pedantic)	    pedwarn ("ANSI C forbids global register variables");#endif	  if (DECL_INITIAL (decl) != 0 && top_level)	    {	      DECL_INITIAL (decl) = 0;	      error ("global register variable has initial value");	    }	  if (fixed_regs[reg_number] == 0	      && function_defined && top_level)	    error ("global register variable follows a function definition");	  if (TREE_THIS_VOLATILE (decl))	    warning ("volatile register variables don't work as you might wish");	  /* If the user specified one of the eliminables registers here,	     e.g., FRAME_POINTER_REGNUM, we don't want to get this variable	     confused with that register and be eliminated.  Although this	     usage is somewhat suspect, we nevertheless use the following	     kludge to avoid setting DECL_RTL to frame_pointer_rtx.  */	  DECL_RTL (decl)	    = gen_rtx (REG, DECL_MODE (decl), FIRST_PSEUDO_REGISTER);	  REGNO (DECL_RTL (decl)) = reg_number;	  REG_USERVAR_P (DECL_RTL (decl)) = 1;	  if (top_level)	    {	      /* Make this register global, so not usable for anything		 else.  */	      nregs = HARD_REGNO_NREGS (reg_number, DECL_MODE (decl));	      while (nregs > 0)		globalize_reg (reg_number + --nregs);	    }	}      /* Specifying a section attribute on an uninitialized variable does not	 (and cannot) cause it to be put in the given section.  The linker	 can only put initialized objects in specific sections, everything	 else goes in bss for the linker to sort out later (otherwise the	 linker would give a duplicate definition error for each compilation	 unit that behaved thusly).  So warn the user.  */      else if (TREE_CODE (decl) == VAR_DECL	       && DECL_SECTION_NAME (decl) != NULL_TREE	       && DECL_INITIAL (decl) == NULL_TREE	       && DECL_COMMON (decl)	       && ! flag_no_common)	{	  warning_with_decl (decl,			     "section attribute ignored for uninitialized variable `%s'");	  /* Remove the section name so subsequent declarations won't see it.	     We are ignoring it, remember.  */	  DECL_SECTION_NAME (decl) = NULL_TREE;	}      /* Now handle ordinary static variables and functions (in memory).	 Also handle vars declared register invalidly.  */      if (DECL_RTL (decl) == 0)	{	  /* Can't use just the variable's own name for a variable	     whose scope is less than the whole file.	     Concatenate a distinguishing number.  */	  if (!top_level && !DECL_EXTERNAL (decl) && asmspec == 0)	    {	      char *label;	      ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);	      name = obstack_copy0 (saveable_obstack, label, strlen (label));	      var_labelno++;	    }	  if (name == 0)	    abort ();	  DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl),				     gen_rtx (SYMBOL_REF, Pmode, name));	  /* If this variable is to be treated as volatile, show its	     tree node has side effects.  If it has side effects, either	     because of this test or from TREE_THIS_VOLATILE also	     being set, show the MEM is volatile.  */	  if (flag_volatile_global && TREE_CODE (decl) == VAR_DECL	      && TREE_PUBLIC (decl))	    TREE_SIDE_EFFECTS (decl) = 1;	  if (TREE_SIDE_EFFECTS (decl))	    MEM_VOLATILE_P (DECL_RTL (decl)) = 1;	  if (TREE_READONLY (decl))	    RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;	  MEM_IN_STRUCT_P (DECL_RTL (decl))	    = AGGREGATE_TYPE_P (TREE_TYPE (decl));	  /* 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.  */#ifdef ENCODE_SECTION_INFO	  ENCODE_SECTION_INFO (decl);#endif	}    }  /* If the old RTL had the wrong mode, fix the mode.  */  else if (GET_MODE (DECL_RTL (decl)) != DECL_MODE (decl))    {      rtx rtl = DECL_RTL (decl);      PUT_MODE (rtl, DECL_MODE (decl));    }}/* Make the rtl for variable VAR be volatile.   Use this only for static variables.  */voidmake_var_volatile (var)     tree var;{  if (GET_CODE (DECL_RTL (var)) != MEM)    abort ();  MEM_VOLATILE_P (DECL_RTL (var)) = 1;}/* Output alignment directive to align for constant expression EXP.  */voidassemble_constant_align (exp)     tree exp;{  int align;  /* 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 a string of literal assembler code   for an `asm' keyword used between functions.  */voidassemble_asm (string)     tree string;{  if (output_bytecode)    {      error ("asm statements not allowed in interpreter");      return;    }  app_enable ();  if (TREE_CODE (string) == ADDR_EXPR)    string = TREE_OPERAND (string, 0);  fprintf (asm_out_file, "\t%s\n", TREE_STRING_POINTER (string));}#if 0 /* This should no longer be needed, because	 flag_gnu_linker should be 0 on these systems,	 which should prevent any output	 if ASM_OUTPUT_CONSTRUCTOR and ASM_OUTPUT_DESTRUCTOR are absent.  */#if !(defined(DBX_DEBUGGING_INFO) && !defined(FASCIST_ASSEMBLER))#ifndef ASM_OUTPUT_CONSTRUCTOR#define ASM_OUTPUT_CONSTRUCTOR(file, name)#endif#ifndef ASM_OUTPUT_DESTRUCTOR#define ASM_OUTPUT_DESTRUCTOR(file, name)#endif#endif#endif /* 0 *//* Record an element in the table of global destructors.   How this is done depends on what sort of assembler and linker   are in use.   NAME should be the name of a global function to be called   at exit time.  This name is output using assemble_name.  */voidassemble_destructor (name)     char *name;{#ifdef ASM_OUTPUT_DESTRUCTOR  ASM_OUTPUT_DESTRUCTOR (asm_out_file, name);#else  if (flag_gnu_linker)    {      /* Now tell GNU LD that this is part of the static destructor set.  */      /* This code works for any machine provided you use GNU as/ld.  */      fprintf (asm_out_file, "%s \"___DTOR_LIST__\",22,0,0,", ASM_STABS_OP);      assemble_name (asm_out_file, name);      fputc ('\n', asm_out_file);    }#endif}/* 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);  function_section (decl);  /* Tell assembler to move to target machine's alignment for functions.  */  align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);  if (align > 0)    {      if (output_bytecode)	BC_OUTPUT_ALIGN (asm_out_file, align);      else	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)	{	  char *p;	  STRIP_NAME_ENCODING (p, fnname);	  first_global_object_name = permalloc (strlen (p) + 1);	  strcpy (first_global_object_name, p);	}#ifdef ASM_WEAKEN_LABEL      if (DECL_WEAK (decl))	ASM_WEAKEN_LABEL (asm_out_file, fnname);      else#endif      if (output_bytecode)	BC_GLOBALIZE_LABEL (asm_out_file, fnname);      else	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.  */  if (output_bytecode)    BC_OUTPUT_LABEL (asm_out_file, fnname);  else    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;{  if (output_bytecode)    {      bc_emit_const_skip (size);      return;    }#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    if (size > 0)      {	if (output_bytecode)	  BC_OUTPUT_SKIP (asm_out_file, size);	else	  ASM_OUTPUT_SKIP (asm_out_file, size);      }}/* Assemble an alignment pseudo op for an ALIGN-bit boundary.  */voidassemble_align (align)     int align;{  if (align > BITS_PER_UNIT)    ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));}/* Assemble a string constant with the specified C string as contents.  */voidassemble_string (p, size)     char *p;     int size;{  register int i;  int pos = 0;  int maximum = 2000;  if (output_bytecode)    {      bc_emit (p, size);      return;    }  /* If the string is very long, split it up.  */  while (pos < size)    {      int thissize = size - pos;      if (thissize > maximum)	thissize = maximum;

⌨️ 快捷键说明

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