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

📄 tc-mn10300.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 4 页
字号:
	      if (strcasecmp (start, "usp") != 0)		{		  *input_line_pointer = c;		  input_line_pointer = hold;		  str = hold;		  goto error;		}	      *input_line_pointer = c;	      goto keep_going;	    }	  else if (operand->flags & MN10300_OPERAND_SSP)	    {	      char *start = input_line_pointer;	      char c = get_symbol_end ();	      if (strcasecmp (start, "ssp") != 0)		{		  *input_line_pointer = c;		  input_line_pointer = hold;		  str = hold;		  goto error;		}	      *input_line_pointer = c;	      goto keep_going;	    }	  else if (operand->flags & MN10300_OPERAND_MSP)	    {	      char *start = input_line_pointer;	      char c = get_symbol_end ();	      if (strcasecmp (start, "msp") != 0)		{		  *input_line_pointer = c;		  input_line_pointer = hold;		  str = hold;		  goto error;		}	      *input_line_pointer = c;	      goto keep_going;	    }	  else if (operand->flags & MN10300_OPERAND_PC)	    {	      char *start = input_line_pointer;	      char c = get_symbol_end ();	      if (strcasecmp (start, "pc") != 0)		{		  *input_line_pointer = c;		  input_line_pointer = hold;		  str = hold;		  goto error;		}	      *input_line_pointer = c;	      goto keep_going;	    }	  else if (operand->flags & MN10300_OPERAND_EPSW)	    {	      char *start = input_line_pointer;	      char c = get_symbol_end ();	      if (strcasecmp (start, "epsw") != 0)		{		  *input_line_pointer = c;		  input_line_pointer = hold;		  str = hold;		  goto error;		}	      *input_line_pointer = c;	      goto keep_going;	    }	  else if (operand->flags & MN10300_OPERAND_PLUS)	    {	      if (*input_line_pointer != '+')		{		  input_line_pointer = hold;		  str = hold;		  goto error;		}	      input_line_pointer++;	      goto keep_going;	    }	  else if (operand->flags & MN10300_OPERAND_PSW)	    {	      char *start = input_line_pointer;	      char c = get_symbol_end ();	      if (strcasecmp (start, "psw") != 0)		{		  *input_line_pointer = c;		  input_line_pointer = hold;		  str = hold;		  goto error;		}	      *input_line_pointer = c;	      goto keep_going;	    }	  else if (operand->flags & MN10300_OPERAND_MDR)	    {	      char *start = input_line_pointer;	      char c = get_symbol_end ();	      if (strcasecmp (start, "mdr") != 0)		{		  *input_line_pointer = c;		  input_line_pointer = hold;		  str = hold;		  goto error;		}	      *input_line_pointer = c;	      goto keep_going;	    }	  else if (operand->flags & MN10300_OPERAND_REG_LIST)	    {	      unsigned int value = 0;	      if (*input_line_pointer != '[')		{		  input_line_pointer = hold;		  str = hold;		  goto error;		}	      /* Eat the '['.  */	      input_line_pointer++;	      /* We used to reject a null register list here; however,		 we accept it now so the compiler can emit "call"		 instructions for all calls to named functions.		 The linker can then fill in the appropriate bits for the		 register list and stack size or change the instruction		 into a "calls" if using "call" is not profitable.  */	      while (*input_line_pointer != ']')		{		  char *start;		  char c;		  if (*input_line_pointer == ',')		    input_line_pointer++;		  start = input_line_pointer;		  c = get_symbol_end ();		  if (strcasecmp (start, "d2") == 0)		    {		      value |= 0x80;		      *input_line_pointer = c;		    }		  else if (strcasecmp (start, "d3") == 0)		    {		      value |= 0x40;		      *input_line_pointer = c;		    }		  else if (strcasecmp (start, "a2") == 0)		    {		      value |= 0x20;		      *input_line_pointer = c;		    }		  else if (strcasecmp (start, "a3") == 0)		    {		      value |= 0x10;		      *input_line_pointer = c;		    }		  else if (strcasecmp (start, "other") == 0)		    {		      value |= 0x08;		      *input_line_pointer = c;		    }		  else if (HAVE_AM33			   && strcasecmp (start, "exreg0") == 0)		    {		      value |= 0x04;		      *input_line_pointer = c;		    }		  else if (HAVE_AM33			   && strcasecmp (start, "exreg1") == 0)		    {		      value |= 0x02;		      *input_line_pointer = c;		    }		  else if (HAVE_AM33			   && strcasecmp (start, "exother") == 0)		    {		      value |= 0x01;		      *input_line_pointer = c;		    }		  else if (HAVE_AM33			   && strcasecmp (start, "all") == 0)		    {		      value |= 0xff;		      *input_line_pointer = c;		    }		  else		    {		      input_line_pointer = hold;		      str = hold;		      goto error;		    }		}	      input_line_pointer++;              mn10300_insert_operand (&insn, &extension, operand,                                      value, (char *) NULL, 0, 0);	      goto keep_going;	    }	  else if (data_register_name (&ex))	    {	      input_line_pointer = hold;	      str = hold;	      goto error;	    }	  else if (address_register_name (&ex))	    {	      input_line_pointer = hold;	      str = hold;	      goto error;	    }	  else if (other_register_name (&ex))	    {	      input_line_pointer = hold;	      str = hold;	      goto error;	    }	  else if (HAVE_AM33 && r_register_name (&ex))	    {	      input_line_pointer = hold;	      str = hold;	      goto error;	    }	  else if (HAVE_AM33 && xr_register_name (&ex))	    {	      input_line_pointer = hold;	      str = hold;	      goto error;	    }	  else if (*str == ')' || *str == '(')	    {	      input_line_pointer = hold;	      str = hold;	      goto error;	    }	  else	    {	      expression (&ex);	    }	  switch (ex.X_op)	    {	    case O_illegal:	      errmsg = _("illegal operand");	      goto error;	    case O_absent:	      errmsg = _("missing operand");	      goto error;	    case O_register:	      {		int mask;		mask = MN10300_OPERAND_DREG | MN10300_OPERAND_AREG;		if (HAVE_AM33)		  mask |= MN10300_OPERAND_RREG | MN10300_OPERAND_XRREG;		if ((operand->flags & mask) == 0)		  {		    input_line_pointer = hold;		    str = hold;		    goto error;		  }		if (opcode->format == FMT_D1 || opcode->format == FMT_S1)		  extra_shift = 8;		else if (opcode->format == FMT_D2			 || opcode->format == FMT_D4			 || opcode->format == FMT_S2			 || opcode->format == FMT_S4			 || opcode->format == FMT_S6			 || opcode->format == FMT_D5)		  extra_shift = 16;		else if (opcode->format == FMT_D7)		  extra_shift = 8;		else if (opcode->format == FMT_D8 || opcode->format == FMT_D9)		  extra_shift = 8;		else		  extra_shift = 0;		mn10300_insert_operand (&insn, &extension, operand,					ex.X_add_number, (char *) NULL,					0, extra_shift);		/* And note the register number in the register array.  */		mn10300_reg_operands[op_idx - 1] = ex.X_add_number;		break;	      }	    case O_constant:	      /* If this operand can be promoted, and it doesn't		 fit into the allocated bitfield for this insn,		 then promote it (ie this opcode does not match).  */	      if (operand->flags		  & (MN10300_OPERAND_PROMOTE | MN10300_OPERAND_RELAX)		  && !check_operand (insn, operand, ex.X_add_number))		{		  input_line_pointer = hold;		  str = hold;		  goto error;		}	      mn10300_insert_operand (&insn, &extension, operand,				      ex.X_add_number, (char *) NULL,				      0, 0);	      break;	    default:	      /* If this operand can be promoted, then this opcode didn't		 match since we can't know if it needed promotion!  */	      if (operand->flags & MN10300_OPERAND_PROMOTE)		{		  input_line_pointer = hold;		  str = hold;		  goto error;		}	      /* We need to generate a fixup for this expression.  */	      if (fc >= MAX_INSN_FIXUPS)		as_fatal (_("too many fixups"));	      fixups[fc].exp = ex;	      fixups[fc].opindex = *opindex_ptr;	      fixups[fc].reloc = BFD_RELOC_UNUSED;	      ++fc;	      break;	    }keep_going:	  str = input_line_pointer;	  input_line_pointer = hold;	  while (*str == ' ' || *str == ',')	    ++str;	}      /* Make sure we used all the operands!  */      if (*str != ',')	match = 1;      /* If this instruction has registers that must not match, verify	 that they do indeed not match.  */      if (opcode->no_match_operands)	{	  int i;	  /* Look at each operand to see if it's marked.  */	  for (i = 0; i < MN10300_MAX_OPERANDS; i++)	    {	      if ((1 << i) & opcode->no_match_operands)		{		  int j;		  /* operand I is marked.  Check that it does not match any		     operands > I which are marked.  */		  for (j = i + 1; j < MN10300_MAX_OPERANDS; j++)		    {		      if (((1 << j) & opcode->no_match_operands)			  && mn10300_reg_operands[i] == mn10300_reg_operands[j])			{			  errmsg = _("Invalid register specification.");			  match = 0;			  goto error;			}		    }		}	    }	}    error:      if (match == 0)	{	  next_opcode = opcode + 1;	  if (!strcmp (next_opcode->name, opcode->name))	    {	      opcode = next_opcode;	      continue;	    }	  as_bad ("%s", errmsg);	  return;	}      break;    }  while (isspace (*str))    ++str;  if (*str != '\0')    as_bad (_("junk at end of line: `%s'"), str);  input_line_pointer = str;  /* Determine the size of the instruction.  */  if (opcode->format == FMT_S0)    size = 1;  if (opcode->format == FMT_S1 || opcode->format == FMT_D0)    size = 2;  if (opcode->format == FMT_S2 || opcode->format == FMT_D1)    size = 3;  if (opcode->format == FMT_D6)    size = 3;  if (opcode->format == FMT_D7 || opcode->format == FMT_D10)    size = 4;  if (opcode->format == FMT_D8)    size = 6;  if (opcode->format == FMT_D9)    size = 7;  if (opcode->format == FMT_S4)    size = 5;  if (opcode->format == FMT_S6 || opcode->format == FMT_D5)    size = 7;  if (opcode->format == FMT_D2)    size = 4;  if (opcode->format == FMT_D4)    size = 6;  if (relaxable && fc > 0)    {      int type;      /* We want to anchor the line info to the previous frag (if	 there isn't one, create it), so that, when the insn is	 resized, we still get the right address for the beginning of	 the region.  */      f = frag_more (0);      dwarf2_emit_insn (0);      /* bCC  */      if (size == 2)	{	  /* Handle bra specially.  Basically treat it like jmp so	     that we automatically handle 8, 16 and 32 bit offsets	     correctly as well as jumps to an undefined address.	     It is also important to not treat it like other bCC	     instructions since the long forms of bra is different	     from other bCC instructions.  */	  if (opcode->opcode == 0xca00)	    type = 10;	  else	    type = 0;	}      /* call  */      else if (size == 5)	type = 6;      /* calls  */      else if (size == 4)	type = 8;      /* jmp  */      else if (size == 3 && opcode->opcode == 0xcc0000)	type = 10;      /* bCC (uncommon cases)  */      else	type = 3;      f = frag_var (rs_machine_dependent, 8, 8 - size, type,		    fixups[0].exp.X_add_symbol,		    fixups[0].exp.X_add_number,		    (char *)fixups[0].opindex);      /* This is pretty hokey.  We basically just care about the	 opcode, so we have to write out the first word big endian.	 The exception is "call", which has two operands that we	 care about.	 The first operand (the register list) happens to be in the	 first instruction word, and will be in the right place if	 we output the first word in big endian mode.	 The second operand (stack size) is in the extension word,	 and we want it to appear as the first character in the extension	 word (as it appears in memory).  Luckily, writing the extension	 word in big endian format will do what we want.  */      number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);      if (size > 8)	{	  number_to_chars_bigendian (f + 4, extension, 4);	  number_to_chars_bigendian (f + 8, 0, size - 8);	}      else if (size > 4)	number_to_chars_bigendian (f + 4, extension, size - 4);    }  else    {      /* Allocate space for the instruction.  */      f = frag_more (size);      /* Fill in bytes for the instruction.  Note that opcode fields	 are written big-endian, 16 & 32bit immediates are written	 little endian.  Egad.  */      if (opcode->format == FMT_S0	  || opcode->format == FMT_S1	  || opcode->format == FMT_D0	  || opcode->format == FMT_D6	  || opcode->format == FMT_D7	  || opcode->format == FMT_D10	  || opcode->format == FMT_D1)	{	  number_to_chars_bigendian (f, insn, size);	}      else if (opcode->format == FMT_S2	       && opcode->opcode != 0xdf0000	       && opcode->opcode != 0xde0000)	{	  /* A format S2 instruction that is _not_ "ret" and "retf".  */	  number_to_chars_bigendian (f, (insn >> 16) & 0xff, 1);	  number_to_chars_littleendian (f + 1, insn & 0xffff, 2);	}      else if (opcode->format == FMT_S2)	{	  /* This must be a ret or retf, which is written entirely in	     big-endian format.  */	  number_to_chars_bigendian (f, insn, 3);	}      else if (opcode->format == FMT_S4	       && opcode->opcode != 0xdc000000)	{	  /* This must be a format S4 "call" instruction.  What a pain.  */	  unsigned long temp = (insn >> 8) & 0xffff;	  number_to_chars_bigendian (f, (insn >> 24) & 0xff, 1);	  number_to_chars_littleendian (f + 1, temp, 2);	  number_to_chars_bigendian (f + 3, insn & 0xff, 1);	  number_to_chars_bigendian (f + 4, extension & 0xff, 1);	}      else if (opcode->format == FMT_S4)	{

⌨️ 快捷键说明

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