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

📄 h8300.c

📁 linux下编程用 编译软件
💻 C
📖 第 1 页 / 共 5 页
字号:
	  break;	default:	  break;	}      break;    case 'e':      switch (GET_CODE (x))	{	case REG:	  if (TARGET_H8300)	    fprintf (file, "%s", names_big[REGNO (x)]);	  else	    fprintf (file, "%s", names_upper_extended[REGNO (x)]);	  break;	case MEM:	  print_operand (file, x, 0);	  break;	case CONST_INT:	  fprintf (file, "#%ld", ((INTVAL (x) >> 16) & 0xffff));	  break;	case CONST_DOUBLE:	  {	    long val;	    REAL_VALUE_TYPE rv;	    REAL_VALUE_FROM_CONST_DOUBLE (rv, x);	    REAL_VALUE_TO_TARGET_SINGLE (rv, val);	    fprintf (file, "#%ld", ((val >> 16) & 0xffff));	    break;	  }	default:	  gcc_unreachable ();	  break;	}      break;    case 'f':      switch (GET_CODE (x))	{	case REG:	  if (TARGET_H8300)	    fprintf (file, "%s", names_big[REGNO (x) + 1]);	  else	    fprintf (file, "%s", names_big[REGNO (x)]);	  break;	case MEM:	  x = adjust_address (x, HImode, 2);	  print_operand (file, x, 0);	  break;	case CONST_INT:	  fprintf (file, "#%ld", INTVAL (x) & 0xffff);	  break;	case CONST_DOUBLE:	  {	    long val;	    REAL_VALUE_TYPE rv;	    REAL_VALUE_FROM_CONST_DOUBLE (rv, x);	    REAL_VALUE_TO_TARGET_SINGLE (rv, val);	    fprintf (file, "#%ld", (val & 0xffff));	    break;	  }	default:	  gcc_unreachable ();	}      break;    case 'j':      fputs (cond_string (GET_CODE (x)), file);      break;    case 'k':      fputs (cond_string (reverse_condition (GET_CODE (x))), file);      break;    case 'm':      gcc_assert (GET_CODE (x) == CONST_INT);      switch (INTVAL (x))	{	case 1:	  fputs (".b", file);	  break;	case 2:	  fputs (".w", file);	  break;	case 4:	  fputs (".l", file);	  break;	default:	  gcc_unreachable ();	}      break;    case 'o':      print_operand_address (file, x);      break;    case 's':      if (GET_CODE (x) == CONST_INT)	fprintf (file, "#%ld", (INTVAL (x)) & 0xff);      else	fprintf (file, "%s", byte_reg (x, 0));      break;    case 't':      if (GET_CODE (x) == CONST_INT)	fprintf (file, "#%ld", (INTVAL (x) >> 8) & 0xff);      else	fprintf (file, "%s", byte_reg (x, 1));      break;    case 'w':      if (GET_CODE (x) == CONST_INT)	fprintf (file, "#%ld", INTVAL (x) & 0xff);      else	fprintf (file, "%s",		 byte_reg (x, TARGET_H8300 ? 2 : 0));      break;    case 'x':      if (GET_CODE (x) == CONST_INT)	fprintf (file, "#%ld", (INTVAL (x) >> 8) & 0xff);      else	fprintf (file, "%s",		 byte_reg (x, TARGET_H8300 ? 3 : 1));      break;    case 'y':      if (GET_CODE (x) == CONST_INT)	fprintf (file, "#%ld", (INTVAL (x) >> 16) & 0xff);      else	fprintf (file, "%s", byte_reg (x, 0));      break;    case 'z':      if (GET_CODE (x) == CONST_INT)	fprintf (file, "#%ld", (INTVAL (x) >> 24) & 0xff);      else	fprintf (file, "%s", byte_reg (x, 1));      break;    default:    def:      switch (GET_CODE (x))	{	case REG:	  switch (GET_MODE (x))	    {	    case QImode:#if 0 /* Is it asm ("mov.b %0,r2l", ...) */	      fprintf (file, "%s", byte_reg (x, 0));#else /* ... or is it asm ("mov.b %0l,r2l", ...) */	      fprintf (file, "%s", names_big[REGNO (x)]);#endif	      break;	    case HImode:	      fprintf (file, "%s", names_big[REGNO (x)]);	      break;	    case SImode:	    case SFmode:	      fprintf (file, "%s", names_extended[REGNO (x)]);	      break;	    default:	      gcc_unreachable ();	    }	  break;	case MEM:	  {	    rtx addr = XEXP (x, 0);	    fprintf (file, "@");	    output_address (addr);	    /* Add a length suffix to constant addresses.  Although this	       is often unnecessary, it helps to avoid ambiguity in the	       syntax of mova.  If we wrote an insn like:		    mova/w.l @(1,@foo.b),er0	       then .b would be considered part of the symbol name.	       Adding a length after foo will avoid this.  */	    if (CONSTANT_P (addr))	      switch (code)		{		case 'R':		  /* Used for mov.b and bit operations.  */		  if (h8300_eightbit_constant_address_p (addr))		    {		      fprintf (file, ":8");		      break;		    }		  /* Fall through.  We should not get here if we are		     processing bit operations on H8/300 or H8/300H		     because 'U' constraint does not allow bit		     operations on the tiny area on these machines.  */		case 'X':		case 'T':		case 'S':		  if (h8300_constant_length (addr) == 2)		    fprintf (file, ":16");		  else		    fprintf (file, ":32");		  break;		default:		  break;		}	  }	  break;	case CONST_INT:	case SYMBOL_REF:	case CONST:	case LABEL_REF:	  fprintf (file, "#");	  print_operand_address (file, x);	  break;	case CONST_DOUBLE:	  {	    long val;	    REAL_VALUE_TYPE rv;	    REAL_VALUE_FROM_CONST_DOUBLE (rv, x);	    REAL_VALUE_TO_TARGET_SINGLE (rv, val);	    fprintf (file, "#%ld", val);	    break;	  }	default:	  break;	}    }}/* Output assembly language output for the address ADDR to FILE.  */voidprint_operand_address (FILE *file, rtx addr){  rtx index;  int size;  switch (GET_CODE (addr))    {    case REG:      fprintf (file, "%s", h8_reg_names[REGNO (addr)]);      break;    case PRE_DEC:      fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);      break;    case POST_INC:      fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);      break;    case PRE_INC:      fprintf (file, "+%s", h8_reg_names[REGNO (XEXP (addr, 0))]);      break;    case POST_DEC:      fprintf (file, "%s-", h8_reg_names[REGNO (XEXP (addr, 0))]);      break;    case PLUS:      fprintf (file, "(");      index = h8300_get_index (XEXP (addr, 0), VOIDmode, &size);      if (GET_CODE (index) == REG)	{	  /* reg,foo */	  print_operand_address (file, XEXP (addr, 1));	  fprintf (file, ",");	  switch (size)	    {	    case 0:	      print_operand_address (file, index);	      break;	    case 1:	      print_operand (file, index, 'X');	      fputs (".b", file);	      break;	    case 2:	      print_operand (file, index, 'T');	      fputs (".w", file);	      break;	    case 4:	      print_operand (file, index, 'S');	      fputs (".l", file);	      break;	    }	  /* print_operand_address (file, XEXP (addr, 0)); */	}      else	{	  /* foo+k */	  print_operand_address (file, XEXP (addr, 0));	  fprintf (file, "+");	  print_operand_address (file, XEXP (addr, 1));	}      fprintf (file, ")");      break;    case CONST_INT:      {	/* Since the H8/300 only has 16 bit pointers, negative values are also	   those >= 32768.  This happens for example with pointer minus a	   constant.  We don't want to turn (char *p - 2) into	   (char *p + 65534) because loop unrolling can build upon this	   (IE: char *p + 131068).  */	int n = INTVAL (addr);	if (TARGET_H8300)	  n = (int) (short) n;	fprintf (file, "%d", n);	break;      }    default:      output_addr_const (file, addr);      break;    }}/* Output all insn addresses and their sizes into the assembly language   output file.  This is helpful for debugging whether the length attributes   in the md file are correct.  This is not meant to be a user selectable   option.  */voidfinal_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,		    int num_operands ATTRIBUTE_UNUSED){  /* This holds the last insn address.  */  static int last_insn_address = 0;  const int uid = INSN_UID (insn);  if (TARGET_ADDRESSES)    {      fprintf (asm_out_file, "; 0x%x %d\n", INSN_ADDRESSES (uid),	       INSN_ADDRESSES (uid) - last_insn_address);      last_insn_address = INSN_ADDRESSES (uid);    }}/* Prepare for an SI sized move.  */inth8300_expand_movsi (rtx operands[]){  rtx src = operands[1];  rtx dst = operands[0];  if (!reload_in_progress && !reload_completed)    {      if (!register_operand (dst, GET_MODE (dst)))	{	  rtx tmp = gen_reg_rtx (GET_MODE (dst));	  emit_move_insn (tmp, src);	  operands[1] = tmp;	}    }  return 0;}/* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).   Define the offset between two registers, one to be eliminated, and   the other its replacement, at the start of a routine.  */inth8300_initial_elimination_offset (int from, int to){  /* The number of bytes that the return address takes on the stack.  */  int pc_size = POINTER_SIZE / BITS_PER_UNIT;  /* The number of bytes that the saved frame pointer takes on the stack.  */  int fp_size = frame_pointer_needed * UNITS_PER_WORD;  /* The number of bytes that the saved registers, excluding the frame     pointer, take on the stack.  */  int saved_regs_size = 0;  /* The number of bytes that the locals takes on the stack.  */  int frame_size = round_frame_size (get_frame_size ());  int regno;  for (regno = 0; regno <= HARD_FRAME_POINTER_REGNUM; regno++)    if (WORD_REG_USED (regno))      saved_regs_size += UNITS_PER_WORD;  /* Adjust saved_regs_size because the above loop took the frame     pointer int account.  */  saved_regs_size -= fp_size;  switch (to)    {    case HARD_FRAME_POINTER_REGNUM:      switch (from)	{	case ARG_POINTER_REGNUM:	  return pc_size + fp_size;	case RETURN_ADDRESS_POINTER_REGNUM:	  return fp_size;	case FRAME_POINTER_REGNUM:	  return -saved_regs_size;	default:	  gcc_unreachable ();	}      break;    case STACK_POINTER_REGNUM:      switch (from)	{	case ARG_POINTER_REGNUM:	  return pc_size + saved_regs_size + frame_size;	case RETURN_ADDRESS_POINTER_REGNUM:	  return saved_regs_size + frame_size;	case FRAME_POINTER_REGNUM:	  return frame_size;	default:	  gcc_unreachable ();	}      break;    default:      gcc_unreachable ();    }  gcc_unreachable ();}/* Worker function for RETURN_ADDR_RTX.  */rtxh8300_return_addr_rtx (int count, rtx frame){  rtx ret;  if (count == 0)    ret = gen_rtx_MEM (Pmode,		       gen_rtx_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM));  else if (flag_omit_frame_pointer)    return (rtx) 0;  else    ret = gen_rtx_MEM (Pmode,		       memory_address (Pmode,				       plus_constant (frame, UNITS_PER_WORD)));  set_mem_alias_set (ret, get_frame_alias_set ());  return ret;}/* Update the condition code from the insn.  */voidnotice_update_cc (rtx body, rtx insn){  rtx set;  switch (get_attr_cc (insn))    {    case CC_NONE:      /* Insn does not affect CC at all.  */      break;    case CC_NONE_0HIT:      /* Insn does not change CC, but the 0'th operand has been changed.  */      if (cc_status.value1 != 0	  && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))	cc_status.value1 = 0;      if (cc_status.value2 != 0	  && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value2))	cc_status.value2 = 0;      break;    case CC_SET_ZN:      /* Insn sets the Z,N flags of CC to recog_data.operand[0].	 The V flag is unusable.  The C flag may or may not be known but	 that's ok because alter_cond will change tests to use EQ/NE.  */      CC_STATUS_INIT;      cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;      set = single_set (insn);      cc_status.value1 = SET_SRC (set);      if (SET_DEST (set) != cc0_rtx)	cc_status.value2 = SET_DEST (set);      break;    case CC_SET_ZNV:      /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].	 The C flag may or may not be known but that's ok because	 alter_cond will change tests to use EQ/NE.  */      CC_STATUS_INIT;      cc_status.flags |= CC_NO_CARRY;      set = single_set (insn);      cc_status.value1 = SET_SRC (set);      if (SET_DEST (set) != cc0_rtx)	{	  /* If the destination is STRICT_LOW_PART, strip off	     STRICT_LOW_PART.  */

⌨️ 快捷键说明

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