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

📄 tc-a29k.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 3 页
字号:
     and do a "continue".  If an operand fails to match, we "break".  */  if (insn->args[0] != '\0')    {      /* Prime the pump.  */      s = parse_operand (s, operand, insn->args[0] == 'I');    }  for (args = insn->args;; ++args)    {      switch (*args)	{	case '\0':		/* end of args */	  if (*s == '\0')	    {	      /* We are truly done.  */	      the_insn.opcode = opcode;	      return;	    }	  as_bad (_("Too many operands: %s"), s);	  break;	case ',':		/* Must match a comma */	  if (*s++ == ',')	    {	      /* Parse next operand.  */	      s = parse_operand (s, operand, args[1] == 'I');	      continue;	    }	  break;	case 'v':		/* Trap numbers (immediate field) */	  if (operand->X_op == O_constant)	    {	      if (operand->X_add_number < 256)		{		  opcode |= (operand->X_add_number << 16);		  continue;		}	      else		{		  as_bad (_("Immediate value of %ld is too large"),			  (long) operand->X_add_number);		  continue;		}	    }	  the_insn.reloc = RELOC_8;	  the_insn.reloc_offset = 1;	/* BIG-ENDIAN Byte 1 of insn */	  the_insn.exp = *operand;	  continue;	case 'b':		/* A general register or 8-bit immediate */	case 'i':	  /* We treat the two cases identically since we mashed	     them together in the opcode table.  */	  if (operand->X_op == O_register)	    goto general_reg;	  /* Make sure the 'i' case really exists.  */	  if ((insn->opcode | IMMEDIATE_BIT) != (insn + 1)->opcode)	    break;	  opcode |= IMMEDIATE_BIT;	  if (operand->X_op == O_constant)	    {	      if (operand->X_add_number < 256)		{		  opcode |= operand->X_add_number;		  continue;		}	      else		{		  as_bad (_("Immediate value of %ld is too large"),			  (long) operand->X_add_number);		  continue;		}	    }	  the_insn.reloc = RELOC_8;	  the_insn.reloc_offset = 3;	/* BIG-ENDIAN Byte 3 of insn */	  the_insn.exp = *operand;	  continue;	case 'a':		/* next operand must be a register */	case 'c':	general_reg:	  /* lrNNN or grNNN or %%expr or a user-def register name */	  if (operand->X_op != O_register)	    break;		/* Only registers */	  know (operand->X_add_symbol == 0);	  know (operand->X_op_symbol == 0);	  reg = operand->X_add_number;	  if (reg >= SREG)	    break;		/* No special registers */	  /* Got the register, now figure out where it goes in the	     opcode.  */	  switch (*args)	    {	    case 'a':	      opcode |= reg << 8;	      continue;	    case 'b':	    case 'i':	      opcode |= reg;	      continue;	    case 'c':	      opcode |= reg << 16;	      continue;	    }	  as_fatal (_("failed sanity check."));	  break;	case 'x':		/* 16 bit constant, zero-extended */	case 'X':		/* 16 bit constant, one-extended */	  if (operand->X_op == O_constant)	    {	      opcode |= (operand->X_add_number & 0xFF) << 0 |		((operand->X_add_number & 0xFF00) << 8);	      continue;	    }	  the_insn.reloc = RELOC_CONST;	  the_insn.exp = *operand;	  continue;	case 'h':	  if (operand->X_op == O_constant)	    {	      opcode |= (operand->X_add_number & 0x00FF0000) >> 16 |		(((unsigned long) operand->X_add_number		  /* avoid sign ext */  & 0xFF000000) >> 8);	      continue;	    }	  the_insn.reloc = RELOC_CONSTH;	  the_insn.exp = *operand;	  continue;	case 'P':		/* PC-relative jump address */	case 'A':		/* Absolute jump address */	  /* These two are treated together since we folded the	     opcode table entries together.  */	  if (operand->X_op == O_constant)	    {	      /* Make sure the 'A' case really exists.  */	      if ((insn->opcode | ABSOLUTE_BIT) != (insn + 1)->opcode)		break;	      {		bfd_vma v, mask;		mask = 0x1ffff;		v = operand->X_add_number & ~ mask;		if (v)		  as_bad ("call/jmp target out of range");	      }	      opcode |= ABSOLUTE_BIT |		(operand->X_add_number & 0x0003FC00) << 6 |		((operand->X_add_number & 0x000003FC) >> 2);	      continue;	    }	  the_insn.reloc = RELOC_JUMPTARG;	  the_insn.exp = *operand;	  the_insn.pcrel = 1;	/* Assume PC-relative jump */	  /* FIXME-SOON, Do we figure out whether abs later, after             know sym val? */	  continue;	case 'e':		/* Coprocessor enable bit for LOAD/STORE insn */	  if (operand->X_op == O_constant)	    {	      if (operand->X_add_number == 0)		continue;	      if (operand->X_add_number == 1)		{		  opcode |= CE_BIT;		  continue;		}	    }	  break;	case 'n':		/* Control bits for LOAD/STORE instructions */	  if (operand->X_op == O_constant &&	      operand->X_add_number < 128)	    {	      opcode |= (operand->X_add_number << 16);	      continue;	    }	  break;	case 's':		/* Special register number */	  if (operand->X_op != O_register)	    break;		/* Only registers */	  if (operand->X_add_number < SREG)	    break;		/* Not a special register */	  opcode |= (operand->X_add_number & 0xFF) << 8;	  continue;	case 'u':		/* UI bit of CONVERT */	  if (operand->X_op == O_constant)	    {	      if (operand->X_add_number == 0)		continue;	      if (operand->X_add_number == 1)		{		  opcode |= UI_BIT;		  continue;		}	    }	  break;	case 'r':		/* RND bits of CONVERT */	  if (operand->X_op == O_constant &&	      operand->X_add_number < 8)	    {	      opcode |= operand->X_add_number << 4;	      continue;	    }	  break;	case 'I':		/* ID bits of INV and IRETINV.  */	  /* This operand is optional.  */	  if (operand->X_op == O_absent)	    continue;	  else if (operand->X_op == O_constant		   && operand->X_add_number < 4)	    {	      opcode |= operand->X_add_number << 16;	      continue;	    }	  break;	case 'd':		/* FD bits of CONVERT */	  if (operand->X_op == O_constant &&	      operand->X_add_number < 4)	    {	      opcode |= operand->X_add_number << 2;	      continue;	    }	  break;	case 'f':		/* FS bits of CONVERT */	  if (operand->X_op == O_constant &&	      operand->X_add_number < 4)	    {	      opcode |= operand->X_add_number << 0;	      continue;	    }	  break;	case 'C':	  if (operand->X_op == O_constant &&	      operand->X_add_number < 4)	    {	      opcode |= operand->X_add_number << 16;	      continue;	    }	  break;	case 'F':	  if (operand->X_op == O_constant &&	      operand->X_add_number < 16)	    {	      opcode |= operand->X_add_number << 18;	      continue;	    }	  break;	default:	  BAD_CASE (*args);	}      /* Types or values of args don't match.  */      as_bad ("Invalid operands");      return;    }}/* This is identical to the md_atof in m68k.c.  I think this is right,   but I'm not sure.   Turn a string in input_line_pointer into a floating point constant   of type TYPE, and store the appropriate bytes in *LITP.  The number   of LITTLENUMS emitted is stored in *SIZEP.  An error message is   returned, or NULL on OK.  *//* Equal to MAX_PRECISION in atof-ieee.c */#define MAX_LITTLENUMS 6char *md_atof (type, litP, sizeP)     char type;     char *litP;     int *sizeP;{  int prec;  LITTLENUM_TYPE words[MAX_LITTLENUMS];  LITTLENUM_TYPE *wordP;  char *t;  switch (type)    {    case 'f':    case 'F':    case 's':    case 'S':      prec = 2;      break;    case 'd':    case 'D':    case 'r':    case 'R':      prec = 4;      break;    case 'x':    case 'X':      prec = 6;      break;    case 'p':    case 'P':      prec = 6;      break;    default:      *sizeP = 0;      return "Bad call to MD_ATOF()";    }  t = atof_ieee (input_line_pointer, type, words);  if (t)    input_line_pointer = t;  *sizeP = prec * sizeof (LITTLENUM_TYPE);  for (wordP = words; prec--;)    {      md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));      litP += sizeof (LITTLENUM_TYPE);    }  return 0;}/* * Write out big-endian. */voidmd_number_to_chars (buf, val, n)     char *buf;     valueT val;     int n;{  number_to_chars_bigendian (buf, val, n);}voidmd_apply_fix (fixP, val)     fixS *fixP;     long val;{  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;  fixP->fx_addnumber = val;	/* Remember value for emit_reloc */  know (fixP->fx_size == 4);  know (fixP->fx_r_type < NO_RELOC);  /* This is a hack.  There should be a better way to handle this.  */  if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy)    {      val += fixP->fx_where + fixP->fx_frag->fr_address;    }  switch (fixP->fx_r_type)    {    case RELOC_32:      buf[0] = val >> 24;      buf[1] = val >> 16;      buf[2] = val >> 8;      buf[3] = val;      break;    case RELOC_8:      buf[0] = val;      break;    case RELOC_WDISP30:      val = (val >>= 2) + 1;      buf[0] |= (val >> 24) & 0x3f;      buf[1] = (val >> 16);      buf[2] = val >> 8;      buf[3] = val;      break;    case RELOC_HI22:      buf[1] |= (val >> 26) & 0x3f;      buf[2] = val >> 18;      buf[3] = val >> 10;      break;    case RELOC_LO10:      buf[2] |= (val >> 8) & 0x03;      buf[3] = val;      break;    case RELOC_BASE13:      buf[2] |= (val >> 8) & 0x1f;      buf[3] = val;      break;    case RELOC_WDISP22:      val = (val >>= 2) + 1;      /* FALLTHROUGH */    case RELOC_BASE22:      buf[1] |= (val >> 16) & 0x3f;      buf[2] = val >> 8;      buf[3] = val;      break;    case RELOC_JUMPTARG:	/* 00XX00XX pattern in a word */      if (!fixP->fx_done)	{	  /* The linker tries to support both AMD and old GNU style             R_IREL relocs.  That means that if the addend is exactly             the negative of the address within the section, the             linker will not handle it correctly.  */	  if (fixP->fx_pcrel	      && val != 0	      && val == - (fixP->fx_frag->fr_address + fixP->fx_where))	    as_bad_where	      (fixP->fx_file, fixP->fx_line,	       "the linker will not handle this relocation correctly");

⌨️ 快捷键说明

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