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

📄 mt.c

📁 linux下编程用 编译软件
💻 C
📖 第 1 页 / 共 4 页
字号:
      if (fntype)	{	  tree ret_type = TREE_TYPE (fntype);	  fprintf (stderr, " return = %s,",		   tree_code_name[ (int)TREE_CODE (ret_type) ]);	}      if (libname && GET_CODE (libname) == SYMBOL_REF)	fprintf (stderr, " libname = %s", XSTR (libname, 0));      if (cfun->returns_struct)	fprintf (stderr, " return-struct");      putc ('\n', stderr);    }}/* Compute the slot number to pass an argument in.   Returns the slot number or -1 if passing on the stack.   CUM is a variable of type CUMULATIVE_ARGS which gives info about    the preceding args and about the function being called.   MODE is the argument's machine mode.   TYPE is the data type of the argument (as a tree).    This is null for libcalls where that information may    not be available.   NAMED is nonzero if this argument is a named parameter    (otherwise it is an extra parameter matching an ellipsis).   INCOMING_P is zero for FUNCTION_ARG, nonzero for FUNCTION_INCOMING_ARG.   *PREGNO records the register number to use if scalar type.  */static intmt_function_arg_slotno (const CUMULATIVE_ARGS * cum,			enum machine_mode mode,			tree type,			int named ATTRIBUTE_UNUSED,			int incoming_p ATTRIBUTE_UNUSED,			int * pregno){  int regbase = FIRST_ARG_REGNUM;  int slotno  = * cum;  if (mode == VOIDmode || targetm.calls.must_pass_in_stack (mode, type))    return -1;  if (slotno >= MT_NUM_ARG_REGS)    return -1;  * pregno = regbase + slotno;  return slotno;}/* Implement FUNCTION_ARG.  */rtxmt_function_arg (const CUMULATIVE_ARGS * cum,		 enum machine_mode mode,		 tree type,		 int named,		 int incoming_p){  int slotno, regno;  rtx reg;  slotno = mt_function_arg_slotno (cum, mode, type, named, incoming_p, &regno);  if (slotno == -1)    reg = NULL_RTX;  else    reg = gen_rtx_REG (mode, regno);  return reg;}/* Implement FUNCTION_ARG_ADVANCE.  */voidmt_function_arg_advance (CUMULATIVE_ARGS * cum,			 enum machine_mode mode,			 tree type ATTRIBUTE_UNUSED,			 int named){  int slotno, regno;  /* We pass 0 for incoming_p here, it doesn't matter.  */  slotno = mt_function_arg_slotno (cum, mode, type, named, 0, &regno);  * cum += (mode != BLKmode	    ? ROUND_ADVANCE (GET_MODE_SIZE (mode))	    : ROUND_ADVANCE (int_size_in_bytes (type)));  if (TARGET_DEBUG_ARG)    fprintf (stderr,	     "mt_function_arg_advance: words = %2d, mode = %4s, named = %d, size = %3d\n",	     *cum, GET_MODE_NAME (mode), named, 	     (*cum) * UNITS_PER_WORD);}/* Implement hook TARGET_ARG_PARTIAL_BYTES.   Returns the number of bytes at the beginning of an argument that   must be put in registers.  The value must be zero for arguments   that are passed entirely in registers or that are entirely pushed   on the stack.  */static intmt_arg_partial_bytes (CUMULATIVE_ARGS * pcum,		       enum machine_mode mode,		       tree type,		       bool named ATTRIBUTE_UNUSED){  int cum = * pcum;  int words;  if (mode == BLKmode)    words = ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)	     / UNITS_PER_WORD);  else    words = (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;  if (! targetm.calls.pass_by_reference (&cum, mode, type, named)      && cum < MT_NUM_ARG_REGS      && (cum + words) > MT_NUM_ARG_REGS)    {      int bytes = (MT_NUM_ARG_REGS - cum) * UNITS_PER_WORD;       if (TARGET_DEBUG)	fprintf (stderr, "function_arg_partial_nregs = %d\n", bytes);      return bytes;    }  return 0;}/* Implement TARGET_PASS_BY_REFERENCE hook.  */static boolmt_pass_by_reference (CUMULATIVE_ARGS * cum ATTRIBUTE_UNUSED,		       enum machine_mode mode ATTRIBUTE_UNUSED,		       tree type,		       bool named ATTRIBUTE_UNUSED){  return (type && int_size_in_bytes (type) > 4 * UNITS_PER_WORD);}/* Implement FUNCTION_ARG_BOUNDARY.  */intmt_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED,			   tree type ATTRIBUTE_UNUSED){  return BITS_PER_WORD;}/* Implement REG_OK_FOR_BASE_P.  */intmt_reg_ok_for_base_p (rtx x, int strict){  if (strict)    return  (((unsigned) REGNO (x)) < FIRST_PSEUDO_REGISTER);  return 1;}/* Helper function of mt_legitimate_address_p.  Return true if XINSN   is a simple address, otherwise false.  */static boolmt_legitimate_simple_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,				rtx xinsn, int strict){  if (TARGET_DEBUG)						    {									      fprintf (stderr, "\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n",	       strict ? "" : "not ");      debug_rtx (xinsn);    }  if (GET_CODE (xinsn) == REG && mt_reg_ok_for_base_p (xinsn, strict))    return true;  if (GET_CODE (xinsn) == PLUS      && GET_CODE (XEXP (xinsn, 0)) == REG      && mt_reg_ok_for_base_p (XEXP (xinsn, 0), strict)      && GET_CODE (XEXP (xinsn, 1)) == CONST_INT      && SMALL_INT (XEXP (xinsn, 1)))    return true;  return false;}/* Helper function of GO_IF_LEGITIMATE_ADDRESS.  Return non-zero if   XINSN is a legitimate address on MT.  */intmt_legitimate_address_p (enum machine_mode mode, rtx xinsn, int strict){  if (mt_legitimate_simple_address_p (mode, xinsn, strict))    return 1;  if ((mode) == SImode      && GET_CODE (xinsn) == AND      && GET_CODE (XEXP (xinsn, 1)) == CONST_INT      && INTVAL (XEXP (xinsn, 1)) == -3)    return mt_legitimate_simple_address_p (mode, XEXP (xinsn, 0), strict);  else    return 0;}/* Return truth value of whether OP can be used as an operands where a   register or 16 bit unsigned integer is needed.  */intuns_arith_operand (rtx op, enum machine_mode mode){  if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (op))    return 1;  return register_operand (op, mode);}/* Return truth value of whether OP can be used as an operands where a   16 bit integer is needed.  */intarith_operand (rtx op, enum machine_mode mode){  if (GET_CODE (op) == CONST_INT && SMALL_INT (op))    return 1;  return register_operand (op, mode);}/* Return truth value of whether OP is a register or the constant 0.  */intreg_or_0_operand (rtx op, enum machine_mode mode){  switch (GET_CODE (op))    {    case CONST_INT:      return INTVAL (op) == 0;    case REG:    case SUBREG:      return register_operand (op, mode);    default:      break;    }  return 0;}/* Return truth value of whether OP is a constant that requires two   loads to put in a register.  */intbig_const_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){  if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_LETTER_P (INTVAL (op), 'M'))    return 1;  return 0;}/* Return truth value of whether OP is a constant that require only   one load to put in a register.  */intsingle_const_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){  if (big_const_operand (op, mode)      || GET_CODE (op) == CONST      || GET_CODE (op) == LABEL_REF      || GET_CODE (op) == SYMBOL_REF)    return 0;  return 1;}/* True if the current function is an interrupt handler   (either via #pragma or an attribute specification).  */int interrupt_handler;enum processor_type mt_cpu;static struct machine_function *mt_init_machine_status (void){  struct machine_function *f;  f = ggc_alloc_cleared (sizeof (struct machine_function));  return f;}/* Implement OVERRIDE_OPTIONS.  */voidmt_override_options (void){  if (mt_cpu_string != NULL)    {      if (!strcmp (mt_cpu_string, "ms1-64-001"))	mt_cpu = PROCESSOR_MS1_64_001;      else if (!strcmp (mt_cpu_string, "ms1-16-002"))	mt_cpu = PROCESSOR_MS1_16_002;      else if  (!strcmp (mt_cpu_string, "ms1-16-003"))	mt_cpu = PROCESSOR_MS1_16_003;      else if (!strcmp (mt_cpu_string, "ms2"))	mt_cpu = PROCESSOR_MS2;      else	error ("bad value (%s) for -march= switch", mt_cpu_string);    }  else    mt_cpu = PROCESSOR_MS1_64_001;  if (flag_exceptions)    {      flag_omit_frame_pointer = 0;      flag_gcse = 0;    }  /* We do delayed branch filling in machine dependent reorg */  mt_flag_delayed_branch = flag_delayed_branch;  flag_delayed_branch = 0;  init_machine_status = mt_init_machine_status;}/* Do what is necessary for `va_start'.  We look at the current function   to determine if stdarg or varargs is used and return the address of the   first unnamed parameter.  */static voidmt_setup_incoming_varargs (CUMULATIVE_ARGS *cum,			   enum machine_mode mode ATTRIBUTE_UNUSED,			   tree type ATTRIBUTE_UNUSED,			   int *pretend_size, int no_rtl){  int regno;  int regs = MT_NUM_ARG_REGS - *cum;    *pretend_size = regs < 0 ? 0 : GET_MODE_SIZE (SImode) * regs;    if (no_rtl)    return;    for (regno = *cum; regno < MT_NUM_ARG_REGS; regno++)    {      rtx reg = gen_rtx_REG (SImode, FIRST_ARG_REGNUM + regno);      rtx slot = gen_rtx_PLUS (Pmode,			       gen_rtx_REG (SImode, ARG_POINTER_REGNUM),			       GEN_INT (UNITS_PER_WORD * regno));            emit_move_insn (gen_rtx_MEM (SImode, slot), reg);    }}/* Returns the number of bytes offset between the frame pointer and the stack   pointer for the current function.  SIZE is the number of bytes of space   needed for local variables.  */unsigned intmt_compute_frame_size (int size){  int           regno;  unsigned int  total_size;  unsigned int  var_size;  unsigned int  args_size;  unsigned int  pretend_size;  unsigned int  extra_size;  unsigned int  reg_size;  unsigned int  frame_size;  unsigned int  reg_mask;  var_size      = size;  args_size     = current_function_outgoing_args_size;  pretend_size  = current_function_pretend_args_size;  extra_size    = FIRST_PARM_OFFSET (0);  total_size    = extra_size + pretend_size + args_size + var_size;  reg_size      = 0;  reg_mask	= 0;  /* Calculate space needed for registers.  */  for (regno = GPR_R0; regno <= GPR_LAST; regno++)    {      if (MUST_SAVE_REGISTER (regno))        {          reg_size += UNITS_PER_WORD;          reg_mask |= 1 << regno;        }    }  current_frame_info.save_fp = (regs_ever_live [GPR_FP]				|| frame_pointer_needed				|| interrupt_handler);  current_frame_info.save_lr = (regs_ever_live [GPR_LINK]				|| profile_flag				|| interrupt_handler);   reg_size += (current_frame_info.save_fp + current_frame_info.save_lr)               * UNITS_PER_WORD;  total_size += reg_size;  total_size = ((total_size + 3) & ~3);  frame_size = total_size;  /* Save computed information.  */  current_frame_info.pretend_size = pretend_size;  current_frame_info.var_size     = var_size;  current_frame_info.args_size    = args_size;  current_frame_info.reg_size     = reg_size;  current_frame_info.frame_size   = args_size + var_size;  current_frame_info.total_size   = total_size;  current_frame_info.extra_size   = extra_size;  current_frame_info.reg_mask     = reg_mask;  current_frame_info.initialized  = reload_completed;   return total_size;}/* Emit code to save REG in stack offset pointed to by MEM.   STACK_OFFSET is the offset from the SP where the save will happen.   This function sets the REG_FRAME_RELATED_EXPR note accordingly.  */static voidmt_emit_save_restore (enum save_direction direction,		      rtx reg, rtx mem, int stack_offset){  if (direction == FROM_PROCESSOR_TO_MEM)    {      rtx insn;        insn = emit_move_insn (mem, reg);      RTX_FRAME_RELATED_P (insn) = 1;      REG_NOTES (insn)	= gen_rtx_EXPR_LIST	(REG_FRAME_RELATED_EXPR,	 gen_rtx_SET (VOIDmode,		      gen_rtx_MEM (SImode,				   gen_rtx_PLUS (SImode,						 stack_pointer_rtx,						 GEN_INT (stack_offset))),		      reg),	 REG_NOTES (insn));    }  else    emit_move_insn (reg, mem);}/* Emit code to save the frame pointer in the prologue and restore   frame pointer in epilogue.  */static voidmt_emit_save_fp (enum save_direction direction,		  struct mt_frame_info info){  rtx base_reg;  int reg_mask = info.reg_mask  & ~(FP_MASK | LINK_MASK);  int offset = info.total_size;  int stack_offset = info.total_size;  /* If there is nothing to save, get out now.  */  if (! info.save_fp && ! info.save_lr && ! reg_mask)    return;  /* If offset doesn't fit in a 15-bit signed integer,     uses a scratch registers to get a smaller offset.  */  if (CONST_OK_FOR_LETTER_P(offset, 'O'))    base_reg = stack_pointer_rtx;  else    {      /* Use the scratch register R9 that holds old stack pointer.  */      base_reg = gen_rtx_REG (SImode, GPR_R9);      offset = 0;    }  if (info.save_fp)    {      offset -= UNITS_PER_WORD;      stack_offset -= UNITS_PER_WORD;      mt_emit_save_restore	(direction, gen_rtx_REG (SImode, GPR_FP),	 gen_rtx_MEM (SImode,		      gen_rtx_PLUS (SImode, base_reg, GEN_INT (offset))),	 stack_offset);    }}/* Emit code to save registers in the prologue and restore register   in epilogue.  */static voidmt_emit_save_regs (enum save_direction direction,		    struct mt_frame_info info){  rtx base_reg;  int regno;  int reg_mask = info.reg_mask  & ~(FP_MASK | LINK_MASK);  int offset = info.total_size;  int stack_offset = info.total_size;

⌨️ 快捷键说明

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