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

📄 ip2k.c

📁 gcc-you can use this code to learn something about gcc, and inquire further into linux,
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)    return get_frame_size () + 1;  if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)    return (CHAIN_FRAMES ? 2 : 0) + (no_saved_pc ? 0 : 2);        /* Count all the registers we had to preserve.  */  reglimit = CHAIN_FRAMES ? REG_FP : (REG_FP + 2);  for (offset = 0,reg = 0; reg < reglimit; ++reg)    {      if ((regs_ever_live[reg] && ! call_used_regs[reg]))	{	  ++offset;	}    }  if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)    return -offset;  if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)    /* Add in the stack-local variables.  */    return offset + get_frame_size () + 1;  if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)    /* Add stack-locals plus saved FP and PC.  */    return offset + get_frame_size () + 1	   + (CHAIN_FRAMES ? 2 : 0) + (no_saved_pc ? 0 : 2);  abort ();			/* Unanticipated elimination.  */}/* Return nonzero if X (an RTX) is a legitimate memory address on the target   machine for a memory operand of mode MODE.  */intlegitimate_address_p (mode, x, strict)     enum machine_mode mode;     rtx x;     int strict;{  int off;  if (GET_CODE (x) == SUBREG)     x = SUBREG_REG (x);  switch (GET_CODE (x))    {    case REG:      /* IP allows indirection without offset - only okay if         we don't require access to multiple bytes.  */      if (REGNO (x) == REG_IP)	return (GET_MODE_SIZE (mode) == 1) ? 'R' : 0;      /* We can indirect thru DP or SP register.  */      if (strict ? REG_OK_FOR_BASE_STRICT_P (x)	         : REG_OK_FOR_BASE_NOSTRICT_P (x))	return 'S';      break;    case PLUS:      /* Offsets from DP or SP are legal in the range 0..127  */      {	rtx op1, op2;	op1 = XEXP (x, 0);	op2 = XEXP (x, 1);	if (REG_P (op2) && ! REG_P (op1))	  {	    rtx tmp = op1;	    op1 = op2;	    op2 = tmp;	  }	/* Don't let anything but R+I thru..  */	if (! REG_P (op1)	    || REG_P (op2)	    || GET_CODE (op2) != CONST_INT)	  return 0;	      	switch (REGNO (op1))	  {	  case REG_DP:		/* only 0..127 displacement  */	  case REG_SP:	    off = 2 * GET_MODE_SIZE (mode);	    if (! off)	      off = 1;	    if (INTVAL (op2) < 0 || INTVAL (op2) > (128 - off))	      return 0;		/* Positive must be small enough that after				   splitting all pieces are addressed.  */	    return 'S';		/* Safe displacement.  */	  case REG_IP:	    if (GET_MODE_SIZE (mode) <= 1 && INTVAL (op2) == 0)	      return (GET_MODE_SIZE (mode) == 1) ? 'R' : 0;	    return 0;	  case REG_AP:	  case REG_FP:	  case REG_VFP:	  default:	    if (strict || ! REG_OK_FOR_BASE_NOSTRICT_P (op1))	      return 0;		/* Allow until reload.  */	    return 'S';	  }      }      break;    case CONST:    case SYMBOL_REF:	 /* We always allow references to things in code space.  */      return is_regfile_address (x) ? 0 : 'C';    case LABEL_REF:      return 'L';    default:      return 0;    }  return 0;}/* Is ADDR mode dependent?  */intip2k_mode_dependent_address (addr)     rtx addr;{  switch (GET_CODE (addr))    {    case POST_INC:    case POST_DEC:    case PRE_INC:    case PRE_DEC:      return 1;    case REG:      return (REGNO (addr) == REG_IP); /* Can't do IP displaced addresses.  */    default:      return 0;			/* Assume no dependency.  */    }}/* Attempts to replace X with a valid   memory address for an operand of mode MODE.  */rtxlegitimize_address (x, oldx, mode, scratch)     rtx x;     rtx oldx ATTRIBUTE_UNUSED;     rtx scratch;     enum machine_mode mode ATTRIBUTE_UNUSED;{  rtx reg;  /* You might think that we could split up a symbolic address by     adding the HIGH 8 bits and doing a displacement off the dp.  But     because we only have 7 bits of offset, that doesn't actually     help.  So only constant displacements are likely to obtain an     advantage.  */        if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 0))      && GET_CODE (XEXP (x, 1)) == CONST_INT      && ! CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x, 1)), 'K'))    {      int offset = INTVAL (XEXP (x, 1));      reg = scratch ? scratch : gen_reg_rtx (Pmode);      emit_insn (gen_rtx_SET (VOIDmode, reg,			      gen_rtx_PLUS (Pmode, XEXP (x, 0),					    GEN_INT (offset & 0xffc0))));      x = gen_rtx_PLUS (Pmode, reg, GEN_INT (offset & 0x3f));    }  return x;			/* We don't have any other tricks.  */}/* Determine if X is a 'data' address or a code address.  All static   data and stack variables reside in data memory.  Only code is believed   to be in PRAM or FLASH.  */intis_regfile_address (x)     rtx x;{  while (1)    switch (GET_CODE (x))      {      case SYMBOL_REF:	return ! SYMBOL_REF_FLAG (x); /* Declared as function.  */      case CONST:      case PLUS:	x = XEXP (x, 0);	break;      case CONST_INT:      case REG:      case SUBREG:	return 1;      case LABEL_REF:	return 0;      default:	return 0;    }  return 0;}/* Output ADDR to FILE as address.  */voidprint_operand_address (file, addr)     FILE *file;     rtx addr;{  switch (GET_CODE (addr))    {    case SUBREG:      addr = alter_subreg (&addr);      /* fall-thru  */    case REG:      fprintf (file, "(%s)",	       REGNO (addr) == REG_DP ? "DP"	       : REGNO (addr) == REG_SP ? "SP"	       : REGNO (addr) == REG_IP ? "IP"	       : REGNO (addr) == REG_VFP ? "VFP" /* Should never see this  */	       : REGNO (addr) == REG_AP ? "AP" 	 /*  or this, either.  */	       : reg_names[REGNO (addr)]);      break;    case PRE_DEC:    case POST_INC:      abort ();      break;    case CONST:      addr = XEXP (addr, 0);      print_operand_address (file, XEXP (addr, 0));      fprintf (file, "+");      print_operand_address (file, XEXP (addr, 1));      return;    case LO_SUM:      if (is_regfile_address (XEXP (addr, 1)))	fprintf (file, "%%lo8data(");      else	fprintf (file, "%%lo8insn(");      print_operand_address (file, XEXP (addr, 1));      fprintf (file, ")");      print_operand_address (file, XEXP (addr, 0));      break;	           case PLUS:			/* Ought to be stack or dp references.  */      if (XEXP (addr, 1) == const0_rtx	  && GET_CODE (XEXP (addr, 0)) == PLUS)	{	  print_operand_address (file, XEXP (addr, 0));	  return;	}      if (! REG_P (XEXP (addr, 0)) || REGNO (XEXP (addr, 0)) != REG_IP)	print_operand_address (file, XEXP (addr, 1)); /* const  */      print_operand_address (file, XEXP (addr, 0));   /* (reg)  */      break;    case HIGH:      if (is_regfile_address (XEXP (addr, 0)))	fprintf (file, "%%hi8data(");      else	fprintf (file, "%%hi8insn(");      output_addr_const (file, XEXP (addr, 0));      fprintf (file, ")");      break;    default:      output_addr_const (file, addr);    }}/* Output X as assembler operand to file FILE.  */     voidprint_operand (file, x, code)     FILE *file;     rtx x;     int code;{  int abcd = 0;  unsigned long value;  switch (code)    {    case '<':			/* Push */      ip2k_stack_delta++;      return;    case '>':			/* Pop */      ip2k_stack_delta--;      return;    case 'A':    case 'B':    case 'C':    case 'D':      abcd = code - 'A';      break;    case 'H':      abcd = 0;      break;    case 'L':      abcd = 1;      break;    case 'S':    case 'T':    case 'U':    case 'V':    case 'W':    case 'X':    case 'Y':    case 'Z':      abcd = code - 'S';    default:      break;    }  if (ip2k_short_operand (x, GET_MODE (x))      && ip2k_address_uses_reg_p (x, REG_SP))    /* An SP-relative address needs to account for interior stack       pushes that reload didn't know about when it calculated the       stack offset.  */    abcd += ip2k_stack_delta;  switch (GET_CODE (x))    {    case SUBREG:      x = alter_subreg (&x);      /* fall-thru  */    case REG:      fprintf (file, reg_names[true_regnum (x) + abcd]);      break;    case CONST_INT:      switch (code)	{        case 'x':	  fprintf (file, "$%x", INTVAL (x) & 0xffff);	  break;	case 'b':	  fprintf (file, "%d", INTVAL (x)); /* bit selector  */	  break;	case 'e':		/* "1 << n" - e.g. "exp"  */	  fprintf (file, "#%d", 1 << INTVAL (x));	  break;	case 'A':	case 'B':	case 'C':	case 'D':	  value = INTVAL (x);	  value >>= 8 * (3 - abcd);	  value &= 0xff;	  fprintf (file, "#%ld", value);	  break;	case 'H':	  fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);	  break;	case 'L':	  fprintf (file, "#%d", INTVAL (x) & 0xff);	  break;	case 'S':	case 'T':	case 'U':	case 'V':	case 'W':	case 'X':	case 'Y':	case 'Z':	  value = ((unsigned long long)INTVAL (x)) >> (8 * (7 - abcd)) & 0xff;	  fprintf (file, "#%ld", value);	  break;	default:	  fprintf (file, "#%d", INTVAL (x));	}      break;    case SYMBOL_REF:    case LABEL_REF:    case CODE_LABEL:    case CONST:      switch (code)	{	case 'A':	case 'B':	case 'C':	case 'D':	case 'S':	case 'T':	case 'U':	case 'V':	case 'W':	case 'X':	case 'Y':	case 'Z':	  abort ();		/* Probably an error.  */	  break;	case 'H':	  fprintf (file, "#%s(",		   is_regfile_address (x) ? "%hi8data"		   			  : "%hi8insn");	  print_operand_address (file, x);	  fputc (')', file);	  break;	case 'L':	  fprintf (file, "#%s(",		   is_regfile_address (x) ? "%lo8data"		   			  : "%lo8insn");	  print_operand_address (file, x);	  fputc (')', file);	  break;	default:	  print_operand_address (file, x);	}      break;    case MEM:      {	rtx addr = XEXP (x, 0);	if (GET_CODE (addr) == SUBREG)	  addr = alter_subreg (&x);	if (CONSTANT_P (addr) && abcd)		  {	    fputc ('(', file);	    print_operand_address (file, addr);	    fprintf (file, ")+%d", abcd);	  }	else if (abcd)	  {	    switch (GET_CODE (addr))	      {	      case PLUS:		abcd += INTVAL (XEXP (addr, 1));		/* Worry about (plus (plus (reg DP) (const_int 10))					   (const_int 0))  */		if (GET_CODE (XEXP (addr, 0)) == PLUS)		  {		    addr = XEXP (addr, 0);		    abcd += INTVAL (XEXP (addr, 1));		  }		       		fprintf (file, "%d", abcd);		print_operand_address (file, XEXP (addr, 0));		break;	      case REG:	      default:		fprintf (file, "%d", abcd);		print_operand_address (file, addr);	      }	  }	else if (GET_CODE (addr) == REG		 && (REGNO (addr) == REG_DP || REGNO (addr) == REG_SP))	  {	    fprintf (file, "0");	    print_operand_address (file, addr);	  }	else	  print_operand_address (file, addr);      }      break;    case CONST_DOUBLE:      /* Is this an integer or a floating point value?  */      if (GET_MODE (x) == VOIDmode)        {          switch (code)	    {	    case 'S':	    case 'T':	    case 'U':	    case 'V':	      value = CONST_DOUBLE_HIGH (x);	      value >>= 8 * (3 - abcd);	      value &= 0xff;	      fprintf (file, "#%ld", value);	      break;	    case 'W':	    case 'X':	    case 'Y':	    case 'Z':	      value = CONST_DOUBLE_LOW (x);	      value >>= 8 * (7 - abcd);	      value &= 0xff;	      fprintf (file, "#%ld", value);	      break;	    }	}      else        {	  REAL_VALUE_TYPE rv;	  REAL_VALUE_FROM_CONST_DOUBLE (rv, x);	  REAL_VALUE_TO_TARGET_SINGLE (rv, value);	  fprintf (file, "0x%lx", value);        }      break;    default:      fatal_insn ("bad operand", x);    }}/* Remember the operands for the compare.  */const char *ip2k_set_compare (x, y)     rtx x;     rtx y;{  ip2k_compare_operands[0] = x;  ip2k_compare_operands[1] = y;  return "";}/* Emit the code for sCOND instructions.  */const char *ip2k_gen_sCOND (insn, code, dest)     rtx insn ATTRIBUTE_UNUSED;

⌨️ 快捷键说明

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