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

📄 i860.c

📁 gcc3.2.1源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	i860_reg_prefix, i860_reg_prefix);      /* Setup the new frame pointer.  The ABI sez to do this after	 preserving registers (using adds), but that's not what the	 native C compiler on svr4 does.  */      fprintf (asm_file, "\taddu 0,%ssp,%sfp\n",	i860_reg_prefix, i860_reg_prefix);      /* Get the value of frame_lower_bytes into r31.  */      fprintf (asm_file, "\torh %d,%sr0,%sr31\n",	frame_lower_bytes >> 16, i860_reg_prefix, i860_reg_prefix);      fprintf (asm_file, "\tor %d,%sr31,%sr31\n",	frame_lower_bytes & 0xffff, i860_reg_prefix, i860_reg_prefix);      /* Now re-adjust the stack pointer using the value in r31.	 The ABI sez to do this with `subs' but SDB may prefer `subu'.  */      fprintf (asm_file, "\tsubu %ssp,%sr31,%ssp\n",	i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);      /* Preserve registers.  The ABI sez to do this before setting	 up the new frame pointer, but that's not what the native	 C compiler on svr4 does.  */      for (i = 1; i < 32; i++)        if (regs_ever_live[i] && ! call_used_regs[i])          fprintf (asm_file, "\tst.l %s%s,%d(%sfp)\n",	    i860_reg_prefix, reg_names[i],	    must_preserve_bytes  + (4 * preserved_so_far++),	    i860_reg_prefix);      for (i = 32; i < 64; i++)        if (regs_ever_live[i] && ! call_used_regs[i])          fprintf (asm_file, "\tfst.l %s%s,%d(%sfp)\n",	    i860_reg_prefix, reg_names[i],	    must_preserve_bytes + (4 * preserved_so_far++),	    i860_reg_prefix);      /* Save the return address.  */      if (must_preserve_r1)        fprintf (asm_file, "\tst.l %sr1,4(%sfp)\n",	  i860_reg_prefix, i860_reg_prefix);    }  else    {      /* Adjust the stack pointer.  The ABI sez to do this using `adds',	 but the native C compiler on svr4 uses `addu'.  */      fprintf (asm_file, "\taddu -%d,%ssp,%ssp\n",	total_fsize, i860_reg_prefix, i860_reg_prefix);      /* Save the old frame pointer.  */      fprintf (asm_file, "\tst.l %sfp,%d(%ssp)\n",	i860_reg_prefix, frame_lower_bytes, i860_reg_prefix);      /* Setup the new frame pointer.  The ABI sez to do this after	 preserving registers and after saving the return address,	(and its saz to do this using adds), but that's not what the	 native C compiler on svr4 does.  */      fprintf (asm_file, "\taddu %d,%ssp,%sfp\n",	frame_lower_bytes, i860_reg_prefix, i860_reg_prefix);      /* Preserve registers.  The ABI sez to do this before setting	 up the new frame pointer, but that's not what the native	 compiler on svr4 does.  */      for (i = 1; i < 32; i++)        if (regs_ever_live[i] && ! call_used_regs[i])          fprintf (asm_file, "\tst.l %s%s,%d(%sfp)\n",	    i860_reg_prefix, reg_names[i],	    must_preserve_bytes + (4 * preserved_so_far++),	    i860_reg_prefix);      for (i = 32; i < 64; i++)        if (regs_ever_live[i] && ! call_used_regs[i])          fprintf (asm_file, "\tfst.l %s%s,%d(%sfp)\n",	    i860_reg_prefix, reg_names[i],	    must_preserve_bytes + (4 * preserved_so_far++),	    i860_reg_prefix);      /* Save the return address.  The ABI sez to do this earlier,	 and also via an offset from %sp, but the native C compiler	 on svr4 does it later (i.e. now) and uses an offset from	 %fp.  */      if (must_preserve_r1)        fprintf (asm_file, "\tst.l %sr1,4(%sfp)\n",	  i860_reg_prefix, i860_reg_prefix);    }#else /* defined(I860_STRICT_ABI_PROLOGUES) */  /* There are two kinds of function prologues.     You use the "small" version if the total frame size is     small enough so that it can fit into an immediate 16-bit     value in one instruction.  Otherwise, you use the "large"     version of the function prologue.  */  if (total_fsize > 0x7fff)    {      /* Adjust the stack pointer (thereby allocating a new frame).  */      fprintf (asm_file, "\tadds -%d,%ssp,%ssp\n",	frame_upper_bytes, i860_reg_prefix, i860_reg_prefix);      /* Save the caller's frame pointer.  */      fprintf (asm_file, "\tst.l %sfp,0(%ssp)\n",	i860_reg_prefix, i860_reg_prefix);      /* Save return address.  */      if (must_preserve_r1)        fprintf (asm_file, "\tst.l %sr1,4(%ssp)\n",	  i860_reg_prefix, i860_reg_prefix);      /* Get the value of frame_lower_bytes into r31 for later use.  */      fprintf (asm_file, "\torh %d,%sr0,%sr31\n",	frame_lower_bytes >> 16, i860_reg_prefix, i860_reg_prefix);      fprintf (asm_file, "\tor %d,%sr31,%sr31\n",	frame_lower_bytes & 0xffff, i860_reg_prefix, i860_reg_prefix);      /* Now re-adjust the stack pointer using the value in r31.  */      fprintf (asm_file, "\tsubs %ssp,%sr31,%ssp\n",	i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);      /* Pre-compute value to be used as the new frame pointer.  */      fprintf (asm_file, "\tadds %ssp,%sr31,%sr31\n",	i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);      /* Preserve registers.  */      for (i = 1; i < 32; i++)        if (regs_ever_live[i] && ! call_used_regs[i])          fprintf (asm_file, "\tst.l %s%s,%d(%sr31)\n",	    i860_reg_prefix, reg_names[i],	    must_preserve_bytes + (4 * preserved_so_far++),	    i860_reg_prefix);      for (i = 32; i < 64; i++)        if (regs_ever_live[i] && ! call_used_regs[i])          fprintf (asm_file, "\tfst.l %s%s,%d(%sr31)\n",	    i860_reg_prefix, reg_names[i],	    must_preserve_bytes + (4 * preserved_so_far++),	    i860_reg_prefix);      /* Actually set the new value of the frame pointer.  */      fprintf (asm_file, "\tmov %sr31,%sfp\n",	i860_reg_prefix, i860_reg_prefix);    }  else    {      /* Adjust the stack pointer.  */      fprintf (asm_file, "\tadds -%d,%ssp,%ssp\n",	total_fsize, i860_reg_prefix, i860_reg_prefix);      /* Save the caller's frame pointer.  */      fprintf (asm_file, "\tst.l %sfp,%d(%ssp)\n",	i860_reg_prefix, frame_lower_bytes, i860_reg_prefix);      /* Save the return address.  */      if (must_preserve_r1)        fprintf (asm_file, "\tst.l %sr1,%d(%ssp)\n",	  i860_reg_prefix, frame_lower_bytes + 4, i860_reg_prefix);      /* Preserve registers.  */      for (i = 1; i < 32; i++)        if (regs_ever_live[i] && ! call_used_regs[i])          fprintf (asm_file, "\tst.l %s%s,%d(%ssp)\n",	    i860_reg_prefix, reg_names[i],	    frame_lower_bytes + must_preserve_bytes + (4 * preserved_so_far++),	    i860_reg_prefix);      for (i = 32; i < 64; i++)        if (regs_ever_live[i] && ! call_used_regs[i])          fprintf (asm_file, "\tfst.l %s%s,%d(%ssp)\n",	    i860_reg_prefix, reg_names[i],	    frame_lower_bytes + must_preserve_bytes + (4 * preserved_so_far++),	    i860_reg_prefix);      /* Setup the new frame pointer.  */      fprintf (asm_file, "\tadds %d,%ssp,%sfp\n",	frame_lower_bytes, i860_reg_prefix, i860_reg_prefix);    }#endif /* defined(I860_STRICT_ABI_PROLOGUES) */#ifdef ASM_OUTPUT_PROLOGUE_SUFFIX  ASM_OUTPUT_PROLOGUE_SUFFIX (asm_file);#endif /* defined(ASM_OUTPUT_PROLOGUE_SUFFIX) */}/* This function generates the assembly code for function exit.   ASM_FILE is a stdio stream to output the code to.   SIZE is an int: how many units of temporary storage to allocate.   The function epilogue should not depend on the current stack pointer!   It should use the frame pointer only.  This is mandatory because   of alloca; we also take advantage of it to omit stack adjustments   before returning.   Note that when we go to restore the preserved register values we must   not try to address their slots by using offsets from the stack pointer.   That's because the stack pointer may have been moved during the function   execution due to a call to alloca().  Rather, we must restore all   preserved registers via offsets from the frame pointer value.   Note also that when the current frame is being "popped" (by adjusting   the value of the stack pointer) on function exit, we must (for the   sake of alloca) set the new value of the stack pointer based upon   the current value of the frame pointer.  We can't just add what we   believe to be the (static) frame size to the stack pointer because   if we did that, and alloca() had been called during this function,   we would end up returning *without* having fully deallocated all of   the space grabbed by alloca.  If that happened, and a function   containing one or more alloca() calls was called over and over again,   then the stack would grow without limit!   Finally note that the epilogues generated here are completely ABI   compliant.  They go out of their way to insure that the value in   the frame pointer register is never less than the value in the stack   pointer register.  It's not clear why this relationship needs to be   maintained at all times, but maintaining it only costs one extra   instruction, so what the hell.*//* This corresponds to a version 4 TDESC structure. Lower numbered   versions successively omit the last word of the structure. We   don't try to handle version 5 here. */typedef struct TDESC_flags {	int version:4;	int reg_packing:1;	int callable_block:1;	int reserved:4;	int fregs:6;	/* fp regs 2-7 */	int iregs:16;	/* regs 0-15 */} TDESC_flags;typedef struct TDESC {	TDESC_flags flags;	int integer_reg_offset;		/* same as must_preserve_bytes */	int floating_point_reg_offset;	unsigned int positive_frame_size;	/* same as frame_upper_bytes */	unsigned int negative_frame_size;	/* same as frame_lower_bytes */} TDESC;static voidi860_output_function_epilogue (asm_file, local_bytes)     register FILE *asm_file;     register HOST_WIDE_INT local_bytes;{  register HOST_WIDE_INT frame_upper_bytes;  register HOST_WIDE_INT frame_lower_bytes;  register HOST_WIDE_INT preserved_reg_bytes = 0;  register unsigned i;  register unsigned restored_so_far = 0;  register unsigned int_restored;  register unsigned mask;  unsigned intflags=0;  register TDESC_flags *flags = (TDESC_flags *) &intflags;#ifdef	OUTPUT_TDESC	/* Output an ABI-compliant TDESC entry */  const char *long_op = integer_asm_op (4, TRUE);#endif  flags->version = 4;  flags->reg_packing = 1;  flags->iregs = 8;	/* old fp always gets saved */  /* Round-up the frame_lower_bytes so that it's a multiple of 16. */  frame_lower_bytes = (local_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT;  /* Count the number of registers that were preserved in the prologue.     Ignore r0.  It is never preserved.  */  for (i = 1; i < FIRST_PSEUDO_REGISTER; i++)    {      if (regs_ever_live[i] && ! call_used_regs[i])        preserved_reg_bytes += 4;    }  /* The upper part of each frame will contain only saved fp,     the saved r1, and stack slots for all of the other "preserved"     registers that we find we will need to save & restore. */  frame_upper_bytes = must_preserve_bytes + preserved_reg_bytes;  /* Round-up frame_upper_bytes so that t is a multiple of 16. */  frame_upper_bytes    = (frame_upper_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT;  /* Restore all of the "preserved" registers that need restoring.  */  mask = 2;  for (i = 1; i < 32; i++, mask<<=1)    if (regs_ever_live[i] && ! call_used_regs[i]) {      fprintf (asm_file, "\tld.l %d(%sfp),%s%s\n",	must_preserve_bytes + (4 * restored_so_far++),	i860_reg_prefix, i860_reg_prefix, reg_names[i]);      if (i > 3 && i < 16)	flags->iregs |= mask;    }  int_restored = restored_so_far;  mask = 1;  for (i = 32; i < 64; i++) {    if (regs_ever_live[i] && ! call_used_regs[i]) {      fprintf (asm_file, "\tfld.l %d(%sfp),%s%s\n",	must_preserve_bytes + (4 * restored_so_far++),	i860_reg_prefix, i860_reg_prefix, reg_names[i]);      if (i > 33 && i < 40)	flags->fregs |= mask;    }    if (i > 33 && i < 40)      mask<<=1;  }  /* Get the value we plan to use to restore the stack pointer into r31.  */  fprintf (asm_file, "\tadds %d,%sfp,%sr31\n",    frame_upper_bytes, i860_reg_prefix, i860_reg_prefix);  /* Restore the return address and the old frame pointer.  */  if (must_preserve_r1) {    fprintf (asm_file, "\tld.l 4(%sfp),%sr1\n",      i860_reg_prefix, i860_reg_prefix);    flags->iregs |= 2;  }  fprintf (asm_file, "\tld.l 0(%sfp),%sfp\n",    i860_reg_prefix, i860_reg_prefix);  /* Return and restore the old stack pointer value.  */  fprintf (asm_file, "\tbri %sr1\n\tmov %sr31,%ssp\n",    i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);#ifdef	OUTPUT_TDESC	/* Output an ABI-compliant TDESC entry */  if (! frame_lower_bytes) {    flags->version--;    if (! frame_upper_bytes) {      flags->version--;      if (restored_so_far == int_restored)	/* No FP saves */	flags->version--;    }  }  assemble_name(asm_file,current_function_original_name);  fputs(".TDESC:\n", asm_file);  fprintf(asm_file, "%s 0x%0x\n", long_op, intflags);  fprintf(asm_file, "%s %d\n", long_op,	int_restored ? must_preserve_bytes : 0);  if (flags->version > 1) {    fprintf(asm_file, "%s %d\n", long_op,	(restored_so_far == int_restored) ? 0 : must_preserve_bytes +	  (4 * int_restored));    if (flags->version > 2) {      fprintf(asm_file, "%s %d\n", long_op, frame_upper_bytes);      if (flags->version > 3)	fprintf(asm_file, "%s %d\n", long_op, frame_lower_bytes);    }  }  tdesc_section();  fprintf(asm_file, "%s ", long_op);  assemble_name(asm_file, current_function_original_name);  fprintf(asm_file, "\n%s ", long_op);  assemble_name(asm_file, current_function_original_name);  fputs(".TDESC\n", asm_file);  text_section();#endif}/* Expand a library call to __builtin_saveregs.  */rtxi860_saveregs (){  rtx fn = gen_rtx_SYMBOL_REF (Pmode, "__builtin_saveregs");  rtx save = gen_reg_rtx (Pmode);  rtx valreg = LIBCALL_VALUE (Pmode);  rtx ret;  /* The return value register overlaps the first argument register.     Save and restore it around the call.  */  emit_move_insn (save, valreg);  ret = emit_library_call_value (fn, NULL_RTX, 1, Pmode, 0);  if (GET_CODE (ret) != REG || REGNO (ret) < FIRST_PSEUDO_REGISTER)    ret = copy_to_reg (ret);  emit_move_insn (valreg, save);  return ret;}treei860_build_va_list (){  tree field_ireg_used, field_freg_used, field_reg_base, field_mem_ptr;  tree record;  record = make_node (RECORD_TYPE);  field_ireg_used = build_decl (FIELD_DECL, get_identifier ("__ireg_used"),				unsigned_type_node);  field_freg_used = build_decl (FIELD_DECL, get_identifier ("__freg_used"),				unsigned_type_node);  field_reg_base = build_decl (FIELD_DECL, get_identifier ("__reg_base"),			       ptr_type_node);  field_mem_ptr = build_decl (FIELD_DECL, get_identifier ("__mem_ptr"),			      ptr_type_node);  DECL_FIELD_C

⌨️ 快捷键说明

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