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

📄 fr30.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
      insn = emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));      RTX_FRAME_RELATED_P (insn) = 1;      insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));      RTX_FRAME_RELATED_P (insn) = 1;    }  if (current_function_profile)    emit_insn (gen_blockage ());}/* Called after register allocation to add any instructions needed for the   epilogue.  Using an epilogue insn is favored compared to putting all of the   instructions in output_function_epilogue(), since it allows the scheduler   to intermix instructions with the restores of the caller saved registers.   In some cases, it might be necessary to emit a barrier instruction as the   first insn to prevent such scheduling.  */voidfr30_expand_epilogue (void){  int regno;  /* Perform the inversion operations of the prologue.  */  if (! current_frame_info.initialised)    abort ();  /* Pop local variables and arguments off the stack.     If frame_pointer_needed is TRUE then the frame pointer register     has actually been used as a frame pointer, and we can recover     the stack pointer from it, otherwise we must unwind the stack     manually.  */  if (current_frame_info.frame_size > 0)    {      if (current_frame_info.save_fp && frame_pointer_needed)	{	  emit_insn (gen_leave_func ());	  current_frame_info.save_fp = 0;	}      else if (current_frame_info.frame_size <= 508)	emit_insn (gen_add_to_stack		   (GEN_INT (current_frame_info.frame_size)));      else	{	  rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);	  emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));	  emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));	}    }    if (current_frame_info.save_fp)    emit_insn (gen_movsi_pop (frame_pointer_rtx));    /* Pop all the registers that were pushed.  */  if (current_frame_info.save_rp)    emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, RETURN_POINTER_REGNUM)));      for (regno = 0; regno < STACK_POINTER_REGNUM; regno ++)    if (current_frame_info.gmask & (1 << regno))      emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, regno)));    if (current_frame_info.pretend_size)    emit_insn (gen_add_to_stack (GEN_INT (current_frame_info.pretend_size)));  /* Reset state info for each function.  */  current_frame_info = zero_frame_info;  emit_jump_insn (gen_return_from_func ());}/* Do any needed setup for a variadic function.  We must create a register   parameter block, and then copy any anonymous arguments, plus the last   named argument, from registers into memory.  * copying actually done in   fr30_expand_prologue().   ARG_REGS_USED_SO_FAR has *not* been updated for the last named argument   which has type TYPE and mode MODE, and we rely on this fact.  */voidfr30_setup_incoming_varargs (CUMULATIVE_ARGS *arg_regs_used_so_far,			     enum machine_mode mode,			     tree type ATTRIBUTE_UNUSED,			     int *pretend_size,			     int second_time ATTRIBUTE_UNUSED){  int size;  /* All BLKmode values are passed by reference.  */  if (mode == BLKmode)    abort ();  /* ??? This run-time test as well as the code inside the if     statement is probably unnecessary.  */  if (targetm.calls.strict_argument_naming (arg_regs_used_so_far))    /* If TARGET_STRICT_ARGUMENT_NAMING returns true, then the last named       arg must not be treated as an anonymous arg.  */    arg_regs_used_so_far += fr30_num_arg_regs (mode, type);  size = FR30_NUM_ARG_REGS - (* arg_regs_used_so_far);  if (size <= 0)    return;  * pretend_size = (size * UNITS_PER_WORD);}/*}}}*//*{{{  Printing operands */ /* Print a memory address as an operand to reference that memory location.  */voidfr30_print_operand_address (FILE *stream, rtx address){  switch (GET_CODE (address))    {    case SYMBOL_REF:      output_addr_const (stream, address);      break;          default:      fprintf (stderr, "code = %x\n", GET_CODE (address));      debug_rtx (address);      output_operand_lossage ("fr30_print_operand_address: unhandled address");      break;    }}/* Print an operand.  */voidfr30_print_operand (FILE *file, rtx x, int code){  rtx x0;    switch (code)    {    case '#':      /* Output a :D if this instruction is delayed.  */      if (dbr_sequence_length () != 0)	fputs (":D", file);      return;          case 'p':      /* Compute the register name of the second register in a hi/lo	 register pair.  */      if (GET_CODE (x) != REG)	output_operand_lossage ("fr30_print_operand: unrecognized %%p code");      else	fprintf (file, "r%d", REGNO (x) + 1);      return;          case 'b':      /* Convert GCC's comparison operators into FR30 comparison codes.  */      switch (GET_CODE (x))	{	case EQ:  fprintf (file, "eq"); break;	case NE:  fprintf (file, "ne"); break;	case LT:  fprintf (file, "lt"); break;	case LE:  fprintf (file, "le"); break;	case GT:  fprintf (file, "gt"); break;	case GE:  fprintf (file, "ge"); break;	case LTU: fprintf (file, "c"); break;	case LEU: fprintf (file, "ls"); break;	case GTU: fprintf (file, "hi"); break;	case GEU: fprintf (file, "nc");  break;	default:	  output_operand_lossage ("fr30_print_operand: unrecognized %%b code");	  break;	}      return;          case 'B':      /* Convert GCC's comparison operators into the complimentary FR30	 comparison codes.  */      switch (GET_CODE (x))	{	case EQ:  fprintf (file, "ne"); break;	case NE:  fprintf (file, "eq"); break;	case LT:  fprintf (file, "ge"); break;	case LE:  fprintf (file, "gt"); break;	case GT:  fprintf (file, "le"); break;	case GE:  fprintf (file, "lt"); break;	case LTU: fprintf (file, "nc"); break;	case LEU: fprintf (file, "hi"); break;	case GTU: fprintf (file, "ls"); break;	case GEU: fprintf (file, "c"); break;	default:	  output_operand_lossage ("fr30_print_operand: unrecognized %%B code");	  break;	}      return;    case 'A':      /* Print a signed byte value as an unsigned value.  */      if (GET_CODE (x) != CONST_INT)	output_operand_lossage ("fr30_print_operand: invalid operand to %%A code");      else	{	  HOST_WIDE_INT val;	  	  val = INTVAL (x);	  val &= 0xff;	  fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);	}      return;          case 'x':      if (GET_CODE (x) != CONST_INT	  || INTVAL (x) < 16	  || INTVAL (x) > 32)	output_operand_lossage ("fr30_print_operand: invalid %%x code");      else	fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) - 16);      return;    case 'F':      if (GET_CODE (x) != CONST_DOUBLE)	output_operand_lossage ("fr30_print_operand: invalid %%F code");      else	{	  char str[30];	  real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x),			   sizeof (str), 0, 1);	  fputs (str, file);	}      return;          case 0:      /* Handled below.  */      break;          default:      fprintf (stderr, "unknown code = %x\n", code);      output_operand_lossage ("fr30_print_operand: unknown code");      return;    }  switch (GET_CODE (x))    {    case REG:      fputs (reg_names [REGNO (x)], file);      break;    case MEM:      x0 = XEXP (x,0);            switch (GET_CODE (x0))	{	case REG:	  if ((unsigned) REGNO (x0) >= ARRAY_SIZE (reg_names))	    abort ();	  fprintf (file, "@%s", reg_names [REGNO (x0)]);	  break;	case PLUS:	  if (GET_CODE (XEXP (x0, 0)) != REG	      || REGNO (XEXP (x0, 0)) < FRAME_POINTER_REGNUM	      || REGNO (XEXP (x0, 0)) > STACK_POINTER_REGNUM	      || GET_CODE (XEXP (x0, 1)) != CONST_INT)	    {	      fprintf (stderr, "bad INDEXed address:");	      debug_rtx (x);	      output_operand_lossage ("fr30_print_operand: unhandled MEM");	    }	  else if (REGNO (XEXP (x0, 0)) == FRAME_POINTER_REGNUM)	    {	      HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));	      if (val < -(1 << 9) || val > ((1 << 9) - 4))		{		  fprintf (stderr, "frame INDEX out of range:");		  debug_rtx (x);		  output_operand_lossage ("fr30_print_operand: unhandled MEM");		}	      fprintf (file, "@(r14, #" HOST_WIDE_INT_PRINT_DEC ")", val);	    }	  else	    {	      HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));	      if (val < 0 || val > ((1 << 6) - 4))		{		  fprintf (stderr, "stack INDEX out of range:");		  debug_rtx (x);		  output_operand_lossage ("fr30_print_operand: unhandled MEM");		}	      fprintf (file, "@(r15, #" HOST_WIDE_INT_PRINT_DEC ")", val);	    }	  break;	  	case SYMBOL_REF:	  output_address (x0);	  break;	  	default:	  fprintf (stderr, "bad MEM code = %x\n", GET_CODE (x0));	  debug_rtx (x);	  output_operand_lossage ("fr30_print_operand: unhandled MEM");	  break;	}      break;          case CONST_DOUBLE :      /* We handle SFmode constants here as output_addr_const doesn't.  */      if (GET_MODE (x) == SFmode)	{	  REAL_VALUE_TYPE d;	  long l;	  REAL_VALUE_FROM_CONST_DOUBLE (d, x);	  REAL_VALUE_TO_TARGET_SINGLE (d, l);	  fprintf (file, "0x%08lx", l);	  break;	}      /* Fall through.  Let output_addr_const deal with it.  */    default:      output_addr_const (file, x);      break;    }  return;}/*}}}*//*{{{  Function arguments */ /* Return true if we should pass an argument on the stack rather than   in registers.  */static boolfr30_must_pass_in_stack (enum machine_mode mode, tree type){  if (mode == BLKmode)    return true;  if (type == NULL)    return false;  return AGGREGATE_TYPE_P (type);}/* Compute the number of word sized registers needed to hold a   function argument of mode INT_MODE and tree type TYPE.  */intfr30_num_arg_regs (enum machine_mode mode, tree type){  int size;  if (targetm.calls.must_pass_in_stack (mode, type))

⌨️ 快捷键说明

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