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

📄 out-mips.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Compute a string to use as a temporary file name.  */static FILE *make_temp_file (){  char *temp_filename;  FILE *stream;  extern char *getenv ();  char *base = getenv ("TMPDIR");  int len;  if (base == (char *)0)    {#ifdef P_tmpdir      if (access (P_tmpdir, R_OK | W_OK) == 0)	base = P_tmpdir;      else#endif	if (access ("/usr/tmp", R_OK | W_OK) == 0)	  base = "/usr/tmp/";	else	  base = "/tmp/";    }  len = strlen (base);  temp_filename = (char *) alloca (len + sizeof("/ccXXXXXX"));  strcpy (temp_filename, base);  if (len > 0 && temp_filename[len-1] != '/')    temp_filename[len++] = '/';  strcpy (temp_filename + len, "ccXXXXXX");  mktemp (temp_filename);  stream = fopen (temp_filename, "w+");  if (!stream)    pfatal_with_name (temp_filename);  unlink (temp_filename);  return stream;}/* Output at beginning of assembler file.   If we are optimizing to use the global pointer, create a temporary   file to hold all of the text stuff, and write it out to the end.   This is needed because the MIPS assembler is evidently one pass,   and if it hasn't seen the relevant .comm/.lcomm/.extern/.sdata   declaration when the code is processed, it generates a two   instruction sequence.  */voidmips_asm_file_start (stream)     FILE *stream;{  if (TARGET_NAME_REGS)    fprintf (stream, "#include <regdef.h>\n");  ASM_OUTPUT_SOURCE_FILENAME (stream, main_input_filename);  print_options (stream);  data_section ();		/* put gcc_compiled. in data, not text*/  if (TARGET_GP_OPT)    {      asm_out_data_file = stream;      asm_out_text_file = make_temp_file ();    }  else    asm_out_data_file = asm_out_text_file = stream;}/* If optimizing for the global pointer, keep track of all of   the externs, so that at the end of the file, we can emit   the appropriate .extern declaration for them, before writing   out the text section.  We assume that all names passed to   us are in the permanent obstack, so that they will be valid   at the end of the compilation.   If we have -G 0, or the extern size is unknown, don't bother   emitting the .externs.  */intmips_output_external (file, decl, name)     FILE *file;     tree decl;     char *name;{  extern char *permalloc ();  register struct extern_list *p;  int len;  if (TARGET_GP_OPT      && mips_section_threshold != 0      && ((TREE_CODE (decl)) != FUNCTION_DECL)      && ((len = int_size_in_bytes (TREE_TYPE (decl))) > 0))    {      p = (struct extern_list *)permalloc ((long) sizeof (struct extern_list));      p->next = extern_head;      p->name = name;      p->size = len;      extern_head = p;    }  return 0;}/* If we are optimizing the global pointer, emit the text section now   and any small externs which did not have .comm, etc that are   needed.  Also, give a warning if the data area is more than 32K and   -pic because 3 instructions are needed to reference the data   pointers.  */intmips_asm_file_end (file)     FILE *file;{  char buffer[8192];  tree name_tree;  struct extern_list *p;  int len;  extern tree lookup_name ();  if (TARGET_GP_OPT)    {      if (extern_head)	fputs ("\n", file);      for (p = extern_head; p != 0; p = p->next)	{	  name_tree = get_identifier (p->name);	  if (!TREE_ADDRESSABLE (name_tree))	    {	      TREE_ADDRESSABLE (name_tree) = 1;	      fprintf (file, "\t.extern\t%s, %d\n", p->name, p->size);	    }	}      fprintf (file, "\n\t.text\n");      rewind (asm_out_text_file);      if (ferror (asm_out_text_file))	fatal_io_error ("write of text assembly file in mips_asm_file_end");      while ((len = fread (buffer, 1, sizeof (buffer), asm_out_text_file)) > 0)	if (fwrite (buffer, 1, len, file) != len)	  pfatal_with_name ("write of final assembly file in mips_asm_file_end");      if (len < 0)	pfatal_with_name ("read of text assembly file in mips_asm_file_end");      if (fclose (asm_out_text_file) != 0)	pfatal_with_name ("close of tempfile in mips_asm_file_end");    }}/* Fix references to the frame pointer to be off of the stack pointer.  */struct rtx_def *mips_fix_frame_pointer (oldaddr, depth)     rtx oldaddr;     int depth;{  rtx newaddr;  rtx sp_diff_rtx;  char temp[40];  int frame_offset = 0;  extern rtx eliminate_constant_term ();  newaddr = eliminate_constant_term (oldaddr, &frame_offset);  if (newaddr != frame_pointer_rtx)    return oldaddr;  if (sp_fp_difference == (char *)0)    {      sprintf (temp, "$Ls%d", number_functions_processed);      sp_fp_difference = IDENTIFIER_POINTER (get_identifier (temp));    }  sp_diff_rtx = gen_rtx (SYMBOL_REF, SImode, sp_fp_difference);  if (frame_offset + depth == 0)    newaddr = gen_rtx (PLUS, Pmode, stack_pointer_rtx, sp_diff_rtx);  else    newaddr = gen_rtx (PLUS, Pmode,		       stack_pointer_rtx,		       gen_rtx (CONST, Pmode,				gen_rtx (PLUS, Pmode,					 sp_diff_rtx,					 gen_rtx (CONST_INT, VOIDmode,						  frame_offset + depth))));  if (TARGET_DEBUGC_MODE)    {      fprintf (stderr,	       "\n==================== FIX_FRAME, depth = %d, sp prealloc = %d, offset = %d\n",	       depth, stack_args_preallocated, frame_offset);      fprintf (stderr, "old INSN:");      debug_rtx (oldaddr);      fprintf (stderr, "\nnew INSN:");      debug_rtx (newaddr);    }  return newaddr;}/* Set up the stack and frame (if desired) for the function.  */voidfunction_prologue (file, size)     FILE *file;     int size;{  extern char call_used_regs[];  extern char *reg_numchar[];  extern tree current_function_decl;  int regno;  int mask;  int fmask;  int push_loc;  int tsize;  int num_regs;  char **reg_name_ptr = (TARGET_NAME_REGS) ? reg_names : reg_numchar;  char *base_str;  char *sp_str = reg_name_ptr[STACK_POINTER_REGNUM];  char *fp_str = (!frame_pointer_needed)			? sp_str			: reg_name_ptr[FRAME_POINTER_REGNUM];  tree fndecl = current_function_decl; /* current... is tooo long */  tree fntype = TREE_TYPE (fndecl);  tree fnargs = (TREE_CODE (fntype) != METHOD_TYPE)			? DECL_ARGUMENTS (fndecl)			: 0;  tree next_arg;  tree cur_arg;  char *arg_name = (char *)0;  CUMULATIVE_ARGS args_so_far;  inside_function = 1;  if (write_symbols != NO_DEBUG)    ASM_OUTPUT_SOURCE_LINE (file,			    DECL_SOURCE_LINE (current_function_decl));  fprintf (file, "\t.ent\t%s\n%s:\n", current_function_name,	   current_function_name);  fprintf (file, " #PROLOGUE\n");  /* Determine the last argument, and get it's name.  */  for (cur_arg = fnargs; cur_arg != (tree)0; cur_arg = next_arg)    {      next_arg = TREE_CHAIN (cur_arg);      if (next_arg == (tree)0)	{	  if (DECL_NAME (cur_arg))	    arg_name = IDENTIFIER_POINTER (DECL_NAME (cur_arg));	  break;	}    }  /* If this function is a varargs function, store any registers that     would normally hold arguments ($4 - $7) on the stack.  */  if ((TYPE_ARG_TYPES (fntype) != 0       && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) != void_type_node))      || (arg_name	  && (strcmp (arg_name, "__builtin_va_alist") == 0	      || strcmp (arg_name, "va_alist") == 0)))    {      tree parm;      regno = 4;      INIT_CUMULATIVE_ARGS (args_so_far, fntype);                for (parm = fnargs; (parm && (regno <= 7)); parm = TREE_CHAIN (parm))	{	  rtx entry_parm;	  enum machine_mode passed_mode;	  tree type;	  type = DECL_ARG_TYPE (parm);	  passed_mode = TYPE_MODE (type);	  entry_parm = FUNCTION_ARG (args_so_far, passed_mode,				     DECL_ARG_TYPE (parm), 1);	  if (entry_parm)	    {	      int words;	      /* passed in a register, so will get homed automatically */	      if (GET_MODE (entry_parm) == BLKmode)		words = (int_size_in_bytes (type) + 3) / 4;	      else		words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;	      regno = REGNO (entry_parm) + words - 1;	    }	  else	    {	      regno = 8;	      break;	    }	  FUNCTION_ARG_ADVANCE (args_so_far, passed_mode,				DECL_ARG_TYPE (parm), 1);	}      switch (regno)	{	case 4:	  fprintf(file, "\tsd\t%s,0(%s)\t#varargs: home regs 4-5\n",		  reg_name_ptr[4], sp_str);	  fprintf(file, "\tsd\t%s,8(%s)\t#varargs: home regs 6-7\n",		  reg_name_ptr[6], sp_str);	  break;	case 5:	  fprintf(file, "\tsw\t%s,4(%s)\t#varargs: home reg  5\n",		  reg_name_ptr[5], sp_str);	  fprintf(file, "\tsd\t%s,8(%s)\t#varargs: home regs 6-7\n",		  reg_name_ptr[6], sp_str);	  break;	case 6:	  fprintf(file, "\tsd\t%s,8(%s)\t#varargs: home regs 6-7\n",		  reg_name_ptr[6], sp_str);	  break;	case 7: 	  fprintf(file, "\tsw\t%s,12(%s)\t#varargs: home reg 7\n",		  reg_name_ptr[7], sp_str);	  break;	default:	  break;	}    }  mask = 0;  fmask = 0;  num_regs = 0;  push_loc = stack_args_preallocated;  tsize = AL_ADJUST_ALIGN (size) + stack_args_preallocated;  for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)    if (MUST_SAVE_REGISTER (regno))      {	tsize += 4;	num_regs += 4;	mask |= 1 << (regno - GP_REG_FIRST);      }  tsize = AL_ADJUST_ALIGN (tsize);  num_regs = AL_ADJUST_ALIGN (num_regs);  for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno += 2)    if (regs_ever_live[regno] && !call_used_regs[regno])      {	tsize += 8;	num_regs += 8;	fmask |= 1 << (regno - FP_REG_FIRST);      }  if (tsize)    tsize -= STARTING_FRAME_OFFSET;  if (!frame_pointer_needed && sp_fp_difference != (char *)0)    fprintf (file,"%s\t= %d\t\t\t#Difference between SP & FP\n\n",	     sp_fp_difference, tsize);  current_function_total_framesize = tsize;  current_function_saved_reg_size = num_regs;  if (tsize > 0)    {      if (tsize <= 32767)	fprintf (file,		 "\tsubu\t%s,%s,%d\t# temp= %d, regs= %d, args= %d, sfo= %d\n",		 sp_str, sp_str, tsize, size, num_regs,		 stack_args_preallocated, STARTING_FRAME_OFFSET);      else	fprintf (file,		 "\tli\t%s,%d\n\tsubu\t%s,%s,%s\t# temp= %d, regs= %d, args= %d, sfo= %d\n",		 reg_name_ptr[MIPS_TEMP1_REGNUM], tsize, sp_str, sp_str,		 reg_name_ptr[MIPS_TEMP1_REGNUM], size, num_regs,		 stack_args_preallocated, STARTING_FRAME_OFFSET);    }  fprintf (file, "\t.frame\t%s,%d,%s\n", fp_str,	   (frame_pointer_needed) ? 0 : tsize,	   reg_name_ptr[31]);  if (push_loc > 32767 && num_regs > 0)    {      if ((tsize - (push_loc + num_regs)) <= 32767)	{	  base_str = reg_name_ptr[MIPS_TEMP1_REGNUM];	  push_loc = tsize - push_loc;	}      else 	{	  base_str = reg_name_ptr[MIPS_TEMP2_REGNUM];	  fprintf (file, "\tli\t%s,%d\n", base_str, push_loc);	  push_loc = 0;	}    }  else    base_str = sp_str;  for  (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)    if ((mask & (1 << (regno - GP_REG_FIRST))) != 0)      {	fprintf (file, "\tsw\t%s,%d(%s)\n", reg_name_ptr[regno], push_loc,		 base_str);	push_loc += 4;      }  fprintf (file, "\t.mask\t0x%08x,%d\n", mask, push_loc - tsize - 4);  push_loc = AL_ADJUST_ALIGN (push_loc);  for  (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno += 2)    if ((fmask & (1 << (regno - FP_REG_FIRST))) != 0)      {	fprintf (file, "\ts.d\t%s,%d(%s)\n", reg_name_ptr[regno], push_loc,		 base_str);	push_loc += 8;      }  fprintf (file, "\t.fmask\t0x%08x,%d\n", fmask, push_loc - tsize - 4);  if (frame_pointer_needed)    {      if (tsize <= 32767)	fprintf (file, "\taddu\t%s,%s,%d\t# set up frame pointer\n", fp_str, sp_str, tsize);      else	fprintf (file, "\taddu\t%s,%s,%s\t# set up frame pointer\n", fp_str, sp_str,		 reg_name_ptr[MIPS_TEMP1_REGNUM]);    }  fprintf (file," #END PROLOGUE\n");}/* Do any necessary cleanup after a function to restore stack, frame, and regs. */voidfunction_epilogue (file, size)     FILE *file;     int size;{  extern FILE *asm_out_data_file, *asm_out_file;  extern char call_used_regs[];  extern char *reg_numchar[];  extern char *current_function_name;  extern int frame_pointer_needed;  int regno;  int push_loc = stack_args_preallocated;  int tsize = current_function_total_framesize;  int num_regs = current_function_saved_reg_size;  char **reg_name_ptr = (TARGET_NAME_REGS) ? reg_names : reg_numchar;  char *sp_str = reg_name_ptr[STACK_POINTER_REGNUM];  char *t1_str = reg_name_ptr[MIPS_TEMP1_REGNUM];  char *base_str;  fprintf (file," #EPILOGUE\n");  if (tsize > 32767)    fprintf (file, "\tli\t%s,%d\n", t1_str, tsize);  if (frame_pointer_needed)    {      char *fp_str = reg_name_ptr[FRAME_POINTER_REGNUM];      if (tsize > 32767)	fprintf (file,"\tsubu\t%s,%s,%s\t# sp not trusted  here\n",		 sp_str, fp_str, t1_str);      else	fprintf (file,"\tsubu\t%s,%s,%d\t# sp not trusted  here\n",		 sp_str, fp_str, tsize);    }  if (push_loc > 32767 && num_regs > 0)    {      if ((tsize - (push_loc + num_regs)) <= 32767)	{	  base_str = t1_str;	  push_loc = tsize - push_loc;	}      else 	{	  base_str = reg_name_ptr[MIPS_TEMP2_REGNUM];	  fprintf (file, "\tli\t%s,%d\n", base_str, push_loc);	  push_loc = 0;	}    }  else    base_str = sp_str;  for  (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)    if (MUST_SAVE_REGISTER (regno))      {	fprintf (file,"\tlw\t%s,%d(%s)\n", reg_name_ptr[regno], push_loc,		 base_str);	push_loc += 4;      }  push_loc = AL_ADJUST_ALIGN (push_loc);  for  (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno += 2)    if  (regs_ever_live[regno] && !call_used_regs[regno])      {	fprintf (file, "\tl.d\t%s,%d(%s)\n", reg_name_ptr[regno], push_loc,		 base_str);	push_loc += 8;      }  if (tsize > 32767)    fprintf (file, "\taddu\t%s,%s,%s\n", sp_str, sp_str, t1_str);  else if (tsize > 0)    fprintf (file, "\taddu\t%s,%s,%d\n", sp_str, sp_str, tsize);  fprintf (file,"\tj\t%s\n", reg_name_ptr[31]);  fprintf (file," #END EPILOGUE\n");  fprintf (file,"\t.end\t%s\n", current_function_name);  /* Reset state info for each function.  */  stack_args_pushed = 0;  stack_args_preallocated = 0;  inside_function = 0;  sp_fp_difference = (char *)0;  number_functions_processed++;  /* Restore the output file if optimizing the GP (optimizing the GP causes     the text to be diverted to a tempfile, so that data decls come before     references to the data).  */  if (TARGET_GP_OPT)    asm_out_file = asm_out_data_file;}

⌨️ 快捷键说明

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