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

📄 m68hc11.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	{	  emit_move_after_reload (gen_rtx_REG (HImode, regno),				  stack_pop_word, scratch);	}    }  /* de-allocate auto variables */  if (TARGET_M6812 && (size > 4 || size == 3))    {      emit_insn (gen_addhi3 (stack_pointer_rtx,			     stack_pointer_rtx, GEN_INT (size)));    }  else if ((!optimize_size && size > 8) || (optimize_size && size > 10))    {      rtx insn;      insn = gen_rtx_PARALLEL	(VOIDmode,	 gen_rtvec (2,		    gen_rtx_SET (VOIDmode,				 stack_pointer_rtx,				 gen_rtx_PLUS (HImode,					       stack_pointer_rtx,					       GEN_INT (size))),		    gen_rtx_CLOBBER (VOIDmode, scratch)));      emit_insn (insn);    }  else    {      int i;      for (i = 2; i <= size; i += 2)	emit_move_after_reload (scratch, stack_pop_word, scratch);      if (size & 1)	emit_insn (gen_addhi3 (stack_pointer_rtx,			       stack_pointer_rtx, const1_rtx));    }  /* For an interrupt handler, restore ZTMP, ZREG and XYREG.  */  if (current_function_interrupt)    {      emit_move_after_reload (gen_rtx_REG (HImode, SOFT_SAVED_XY_REGNUM),			      stack_pop_word, scratch);      emit_move_after_reload (gen_rtx_REG (HImode, SOFT_Z_REGNUM),			      stack_pop_word, scratch);      emit_move_after_reload (m68hc11_soft_tmp_reg, stack_pop_word, scratch);    }  /* Restore previous frame pointer.  */  if (frame_pointer_needed)    emit_move_after_reload (hard_frame_pointer_rtx, stack_pop_word, scratch);  /* If the trap handler returns some value, copy the value     in D, X onto the stack so that the rti will pop the return value     correctly.  */  else if (current_function_trap && return_size != 0)    {      rtx addr_reg = stack_pointer_rtx;      if (!TARGET_M6812)	{	  emit_move_after_reload (scratch, stack_pointer_rtx, 0);	  addr_reg = scratch;	}      emit_move_after_reload (gen_rtx_MEM (HImode,				       gen_rtx_PLUS (HImode, addr_reg,						const1_rtx)), d_reg, 0);      if (return_size > HARD_REG_SIZE)	emit_move_after_reload (gen_rtx_MEM (HImode,					 gen_rtx_PLUS (HImode, addr_reg,						  GEN_INT (3))), ix_reg, 0);    }  emit_jump_insn (gen_return ());}/* Low and High part extraction for 68HC11.  These routines are   similar to gen_lowpart and gen_highpart but they have been   fixed to work for constants and 68HC11 specific registers.  */rtxm68hc11_gen_lowpart (enum machine_mode mode, rtx x){  /* We assume that the low part of an auto-inc mode is the same with     the mode changed and that the caller split the larger mode in the     correct order.  */  if (GET_CODE (x) == MEM && m68hc11_auto_inc_p (XEXP (x, 0)))    {      return gen_rtx_MEM (mode, XEXP (x, 0));    }  /* Note that a CONST_DOUBLE rtx could represent either an integer or a     floating-point constant.  A CONST_DOUBLE is used whenever the     constant requires more than one word in order to be adequately     represented.  */  if (GET_CODE (x) == CONST_DOUBLE)    {      long l[2];      if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)	{	  REAL_VALUE_TYPE r;	  if (GET_MODE (x) == SFmode)	    {	      REAL_VALUE_FROM_CONST_DOUBLE (r, x);	      REAL_VALUE_TO_TARGET_SINGLE (r, l[0]);	    }	  else	    {	      rtx first, second;	      split_double (x, &first, &second);	      return second;	    }	  if (mode == SImode)	    return GEN_INT (l[0]);	  return gen_int_mode (l[0], HImode);	}      else	{	  l[0] = CONST_DOUBLE_LOW (x);	}      if (mode == SImode)	return GEN_INT (l[0]);      else if (mode == HImode && GET_MODE (x) == SFmode)	return gen_int_mode (l[0], HImode);      else	abort ();    }  if (mode == QImode && D_REG_P (x))    return gen_rtx_REG (mode, HARD_B_REGNUM);  /* gen_lowpart crashes when it is called with a SUBREG.  */  if (GET_CODE (x) == SUBREG && SUBREG_BYTE (x) != 0)    {      if (mode == SImode)	return gen_rtx_SUBREG (mode, SUBREG_REG (x), SUBREG_BYTE (x) + 4);      else if (mode == HImode)	return gen_rtx_SUBREG (mode, SUBREG_REG (x), SUBREG_BYTE (x) + 2);      else	abort ();    }  x = gen_lowpart (mode, x);  /* Return a different rtx to avoid to share it in several insns     (when used by a split pattern).  Sharing addresses within     a MEM breaks the Z register replacement (and reloading).  */  if (GET_CODE (x) == MEM)    x = copy_rtx (x);  return x;}rtxm68hc11_gen_highpart (enum machine_mode mode, rtx x){  /* We assume that the high part of an auto-inc mode is the same with     the mode changed and that the caller split the larger mode in the     correct order.  */  if (GET_CODE (x) == MEM && m68hc11_auto_inc_p (XEXP (x, 0)))    {      return gen_rtx_MEM (mode, XEXP (x, 0));    }  /* Note that a CONST_DOUBLE rtx could represent either an integer or a     floating-point constant.  A CONST_DOUBLE is used whenever the     constant requires more than one word in order to be adequately     represented.  */  if (GET_CODE (x) == CONST_DOUBLE)    {      long l[2];      if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)	{	  REAL_VALUE_TYPE r;	  if (GET_MODE (x) == SFmode)	    {	      REAL_VALUE_FROM_CONST_DOUBLE (r, x);	      REAL_VALUE_TO_TARGET_SINGLE (r, l[1]);	    }	  else	    {	      rtx first, second;	      split_double (x, &first, &second);	      return first;	    }	  if (mode == SImode)	    return GEN_INT (l[1]);	  return gen_int_mode ((l[1] >> 16), HImode);	}      else	{	  l[1] = CONST_DOUBLE_HIGH (x);	}      if (mode == SImode)	return GEN_INT (l[1]);      else if (mode == HImode && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)	return gen_int_mode ((l[0] >> 16), HImode);      else	abort ();    }  if (GET_CODE (x) == CONST_INT)    {      HOST_WIDE_INT val = INTVAL (x);      if (mode == QImode)	{	  return gen_int_mode (val >> 8, QImode);	}      else if (mode == HImode)	{	  return gen_int_mode (val >> 16, HImode);	}      else if (mode == SImode)       {         return gen_int_mode (val >> 32, SImode);       }    }  if (mode == QImode && D_REG_P (x))    return gen_rtx_REG (mode, HARD_A_REGNUM);  /* There is no way in GCC to represent the upper part of a word register.     To obtain the 8-bit upper part of a soft register, we change the     reg into a mem rtx.  This is possible because they are physically     located in memory.  There is no offset because we are big-endian.  */  if (mode == QImode && S_REG_P (x))    {      int pos;      /* Avoid the '*' for direct addressing mode when this         addressing mode is disabled.  */      pos = TARGET_NO_DIRECT_MODE ? 1 : 0;      return gen_rtx_MEM (QImode,		      gen_rtx_SYMBOL_REF (Pmode,			       &reg_names[REGNO (x)][pos]));    }  /* gen_highpart crashes when it is called with a SUBREG.  */  if (GET_CODE (x) == SUBREG)    {      return gen_rtx_SUBREG (mode, XEXP (x, 0), XEXP (x, 1));    }  if (GET_CODE (x) == REG)    {      if (REGNO (x) < FIRST_PSEUDO_REGISTER)        return gen_rtx_REG (mode, REGNO (x));      else        return gen_rtx_SUBREG (mode, x, 0);    }  if (GET_CODE (x) == MEM)    {      x = change_address (x, mode, 0);      /* Return a different rtx to avoid to share it in several insns	 (when used by a split pattern).  Sharing addresses within	 a MEM breaks the Z register replacement (and reloading).  */      if (GET_CODE (x) == MEM)	x = copy_rtx (x);      return x;    }  abort ();}/* Obscure register manipulation.  *//* Finds backward in the instructions to see if register 'reg' is   dead.  This is used when generating code to see if we can use 'reg'   as a scratch register.  This allows us to choose a better generation   of code when we know that some register dies or can be clobbered.  */intdead_register_here (rtx x, rtx reg){  rtx x_reg;  rtx p;  if (D_REG_P (reg))    x_reg = gen_rtx_REG (SImode, HARD_X_REGNUM);  else    x_reg = 0;  for (p = PREV_INSN (x); p && GET_CODE (p) != CODE_LABEL; p = PREV_INSN (p))    if (INSN_P (p))      {	rtx body;	body = PATTERN (p);	if (GET_CODE (body) == CALL_INSN)	  break;	if (GET_CODE (body) == JUMP_INSN)	  break;	if (GET_CODE (body) == SET)	  {	    rtx dst = XEXP (body, 0);	    if (GET_CODE (dst) == REG && REGNO (dst) == REGNO (reg))	      break;	    if (x_reg && rtx_equal_p (dst, x_reg))	      break;	    if (find_regno_note (p, REG_DEAD, REGNO (reg)))	      return 1;	  }	else if (reg_mentioned_p (reg, p)		 || (x_reg && reg_mentioned_p (x_reg, p)))	  break;      }  /* Scan forward to see if the register is set in some insns and never     used since then.  */  for (p = x /*NEXT_INSN (x) */ ; p; p = NEXT_INSN (p))    {      rtx body;      if (GET_CODE (p) == CODE_LABEL	  || GET_CODE (p) == JUMP_INSN	  || GET_CODE (p) == CALL_INSN || GET_CODE (p) == BARRIER)	break;      if (GET_CODE (p) != INSN)	continue;      body = PATTERN (p);      if (GET_CODE (body) == SET)	{	  rtx src = XEXP (body, 1);	  rtx dst = XEXP (body, 0);	  if (GET_CODE (dst) == REG	      && REGNO (dst) == REGNO (reg) && !reg_mentioned_p (reg, src))	    return 1;	}      /* Register is used (may be in source or in dest).  */      if (reg_mentioned_p (reg, p)	  || (x_reg != 0 && GET_MODE (p) == SImode	      && reg_mentioned_p (x_reg, p)))	break;    }  return p == 0 ? 1 : 0;}/* Code generation operations called from machine description file.  *//* Print the name of register 'regno' in the assembly file.  */static voidasm_print_register (FILE *file, int regno){  const char *name = reg_names[regno];  if (TARGET_NO_DIRECT_MODE && name[0] == '*')    name++;  fprintf (file, "%s", name);}/* A C compound statement to output to stdio stream STREAM the   assembler syntax for an instruction operand X.  X is an RTL   expression.   CODE is a value that can be used to specify one of several ways   of printing the operand.  It is used when identical operands   must be printed differently depending on the context.  CODE   comes from the `%' specification that was used to request   printing of the operand.  If the specification was just `%DIGIT'   then CODE is 0; if the specification was `%LTR DIGIT' then CODE   is the ASCII code for LTR.   If X is a register, this macro should print the register's name.   The names can be found in an array `reg_names' whose type is   `char *[]'.  `reg_names' is initialized from `REGISTER_NAMES'.   When the machine description has a specification `%PUNCT' (a `%'   followed by a punctuation character), this macro is called with   a null pointer for X and the punctuation character for CODE.   The M68HC11 specific codes are:   'b' for the low part of the operand.   'h' for the high part of the operand       The 'b' or 'h' modifiers have no effect if the operand has       the QImode and is not a S_REG_P (soft register).  If the       operand is a hard register, these two modifiers have no effect.   't' generate the temporary scratch register.  The operand is       ignored.   'T' generate the low-part temporary scratch register.  The operand is       ignored.  */voidprint_operand (FILE *file, rtx op, int letter){  if (letter == 't')    {      asm_print_register (file, SOFT_TMP_REGNUM);      return;    }  else if (letter == 'T')    {      asm_print_register (file, SOFT_TMP_REGNUM);      fprintf (file, "+1");      return;    }  else if (letter == '#')    {      asm_fprintf (file, "%I");    }  if (GET_CODE (op) == REG)    {      if (letter == 'b' && S_REG_P (op))	{	  asm_print_register (file, REGNO (op));	  fprintf (file, "+1");	}      else if (letter == 'b' && D_REG_P (op))	{	  asm_print_register (file, HARD_B_REGNUM);	}      else	{	  asm_print_register (file, REGNO (op));	}      return;    }  if (GET_CODE (op) == SYMBOL_REF && (letter == 'b' || letter == 'h'))    {      if (letter == 'b')	asm_fprintf (file, "%I%%lo(");      else	asm_fprintf (file, "%I%%hi(");      output_addr_const (file, op);      fprintf (file, ")");      return;    }  /* Get the low or high part of the operand when 'b' or 'h' modifiers     are specified.  If we already have a QImode, there is nothing to do.  */  if (GET_MODE (op) == HImode || GET_MODE (op) == VOIDmode)    {      if (letter == 'b')	{	  op = m68hc11_gen_lowpart (QImode, op);	}      else if (letter == 'h')	{	  op = m68hc11_gen_highpart (QImode, op);	}    }  if (GET_CODE (op) == MEM)    {      rtx base = XEXP (op, 0);      switch (GET_CODE (base))	{	case PRE_DEC:	  if (TARGET_M6812)	    {	      fprintf (file, "%u,-", GET_MODE_SIZE (GET_MODE (op)));	      asm_print_register (file, REGNO (XEXP (base, 0)));	    

⌨️ 快捷键说明

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