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

📄 tc-hppa.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* Output the opcode.  */  md_number_to_chars (to, the_insn.opcode, 4);  /* If necessary output more stuff.  */  if (the_insn.reloc != R_HPPA_NONE)    fix_new_hppa (frag_now, (to - frag_now->fr_literal), 4, NULL,		  (offsetT) 0, &the_insn.exp, the_insn.pcrel,		  the_insn.reloc, the_insn.field_selector,		  the_insn.format, the_insn.arg_reloc, 0);#ifdef OBJ_ELF  dwarf2_emit_insn (4);#endif}/* Do the real work for assembling a single instruction.  Store results   into the global "the_insn" variable.  */static voidpa_ip (str)     char *str;{  char *error_message = "";  char *s, c, *argstart, *name, *save_s;  const char *args;  int match = FALSE;  int comma = 0;  int cmpltr, nullif, flag, cond, num;  unsigned long opcode;  struct pa_opcode *insn;#ifdef OBJ_SOM  /* We must have a valid space and subspace.  */  pa_check_current_space_and_subspace ();#endif  /* Convert everything up to the first whitespace character into lower     case.  */  for (s = str; *s != ' ' && *s != '\t' && *s != '\n' && *s != '\0'; s++)    if (isupper (*s))      *s = tolower (*s);  /* Skip to something interesting.  */  for (s = str; isupper (*s) || islower (*s) || (*s >= '0' && *s <= '3'); ++s)    ;  switch (*s)    {    case '\0':      break;    case ',':      comma = 1;      /*FALLTHROUGH */    case ' ':      *s++ = '\0';      break;    default:      as_fatal (_("Unknown opcode: `%s'"), str);    }  save_s = str;  /* Look up the opcode in the has table.  */  if ((insn = (struct pa_opcode *) hash_find (op_hash, str)) == NULL)    {      as_bad ("Unknown opcode: `%s'", str);      return;    }  if (comma)    {      *--s = ',';    }  /* Mark the location where arguments for the instruction start, then     start processing them.  */  argstart = s;  for (;;)    {      /* Do some initialization.  */      opcode = insn->match;      strict = (insn->flags & FLAG_STRICT);      memset (&the_insn, 0, sizeof (the_insn));      the_insn.reloc = R_HPPA_NONE;      /* If this instruction is specific to a particular architecture,	 then set a new architecture.  */      /* But do not automatically promote to pa2.0.  The automatic promotion	 crud is for compatability with HP's old assemblers only.  */      if (insn->arch < 20	  && bfd_get_mach (stdoutput) < insn->arch)	{	  if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, insn->arch))	    as_warn (_("could not update architecture and machine"));	}      else if (bfd_get_mach (stdoutput) < insn->arch)	{	  match = FALSE;	  goto failed;	}      /* Build the opcode, checking as we go to make         sure that the operands match.  */      for (args = insn->args;; ++args)	{	  /* Absorb white space in instruction.  */	  while (*s == ' ' || *s == '\t')	    s++;	  switch (*args)	    {	    /* End of arguments.  */	    case '\0':	      if (*s == '\0')		match = TRUE;	      break;	    case '+':	      if (*s == '+')		{		  ++s;		  continue;		}	      if (*s == '-')		continue;	      break;	    /* These must match exactly.  */	    case '(':	    case ')':	    case ',':	    case ' ':	      if (*s++ == *args)		continue;	      break;	    /* Handle a 5 bit register or control register field at 10.  */	    case 'b':	    case '^':	      if (!pa_parse_number (&s, 0))		break;	      num = pa_number;	      CHECK_FIELD (num, 31, 0, 0);	      INSERT_FIELD_AND_CONTINUE (opcode, num, 21);	    /* Handle %sar or %cr11.  No bits get set, we just verify that it	       is there.  */	    case '!':	      /* Skip whitespace before register.  */	      while (*s == ' ' || *s == '\t')		s = s + 1;	      if (!strncasecmp(s, "%sar", 4))	        {		  s += 4;		  continue;		}	      else if (!strncasecmp(s, "%cr11", 5))	        {		  s += 5;		  continue;		}	      break;	    /* Handle a 5 bit register field at 15.  */	    case 'x':	      if (!pa_parse_number (&s, 0))		break;	      num = pa_number;	      CHECK_FIELD (num, 31, 0, 0);	      INSERT_FIELD_AND_CONTINUE (opcode, num, 16);	    /* Handle a 5 bit register field at 31.  */	    case 't':	      if (!pa_parse_number (&s, 0))		break;	      num = pa_number;	      CHECK_FIELD (num, 31, 0, 0);	      INSERT_FIELD_AND_CONTINUE (opcode, num, 0);	    /* Handle a 5 bit register field at 10 and 15.  */	    case 'a':	      if (!pa_parse_number (&s, 0))		break;	      num = pa_number;	      CHECK_FIELD (num, 31, 0, 0);	      opcode |= num << 16;	      INSERT_FIELD_AND_CONTINUE (opcode, num, 21);	    /* Handle a 5 bit field length at 31.  */	    case 'T':	      num = pa_get_absolute_expression (&the_insn, &s);	      if (strict && the_insn.exp.X_op != O_constant)		break;	      s = expr_end;	      CHECK_FIELD (num, 32, 1, 0);	      INSERT_FIELD_AND_CONTINUE (opcode, 32 - num, 0);	    /* Handle a 5 bit immediate at 15.  */	    case '5':	      num = pa_get_absolute_expression (&the_insn, &s);	      if (strict && the_insn.exp.X_op != O_constant)		break;	      s = expr_end;	      /* When in strict mode, we want to just reject this		 match instead of giving an out of range error.  */	      CHECK_FIELD (num, 15, -16, strict);	      num = low_sign_unext (num, 5);	      INSERT_FIELD_AND_CONTINUE (opcode, num, 16);	    /* Handle a 5 bit immediate at 31.  */	    case 'V':	      num = pa_get_absolute_expression (&the_insn, &s);	      if (strict && the_insn.exp.X_op != O_constant)		break;	      s = expr_end;	      /* When in strict mode, we want to just reject this		 match instead of giving an out of range error.  */	      CHECK_FIELD (num, 15, -16, strict);	      num = low_sign_unext (num, 5);	      INSERT_FIELD_AND_CONTINUE (opcode, num, 0);	    /* Handle an unsigned 5 bit immediate at 31.  */	    case 'r':	      num = pa_get_absolute_expression (&the_insn, &s);	      if (strict && the_insn.exp.X_op != O_constant)		break;	      s = expr_end;	      CHECK_FIELD (num, 31, 0, strict);	      INSERT_FIELD_AND_CONTINUE (opcode, num, 0);	    /* Handle an unsigned 5 bit immediate at 15.  */	    case 'R':	      num = pa_get_absolute_expression (&the_insn, &s);	      if (strict && the_insn.exp.X_op != O_constant)		break;	      s = expr_end;	      CHECK_FIELD (num, 31, 0, strict);	      INSERT_FIELD_AND_CONTINUE (opcode, num, 16);	    /* Handle an unsigned 10 bit immediate at 15.  */	    case 'U':	      num = pa_get_absolute_expression (&the_insn, &s);	      if (strict && the_insn.exp.X_op != O_constant)		break;	      s = expr_end;	      CHECK_FIELD (num, 1023, 0, strict);	      INSERT_FIELD_AND_CONTINUE (opcode, num, 16);	    /* Handle a 2 bit space identifier at 17.  */	    case 's':	      if (!pa_parse_number (&s, 0))		break;	      num = pa_number;	      CHECK_FIELD (num, 3, 0, 1);	      INSERT_FIELD_AND_CONTINUE (opcode, num, 14);	    /* Handle a 3 bit space identifier at 18.  */	    case 'S':	      if (!pa_parse_number (&s, 0))		break;	      num = pa_number;	      CHECK_FIELD (num, 7, 0, 1);	      opcode |= re_assemble_3 (num);	      continue;	    /* Handle all completers.  */	    case 'c':	      switch (*++args)		{		/* Handle a completer for an indexing load or store.  */		case 'x':		  {		    int uu = 0;		    int m = 0;		    int i = 0;		    while (*s == ',' && i < 2)		      {			s++;			if (strncasecmp (s, "sm", 2) == 0)			  {			    uu = 1;			    m = 1;			    s++;			    i++;			  }			else if (strncasecmp (s, "m", 1) == 0)			  m = 1;			else if ((strncasecmp (s, "s ", 2) == 0)				 || (strncasecmp (s, "s,", 2) == 0))			  uu = 1;			/* When in strict mode this is a match failure.  */			else if (strict)			  {			    s--;			    break;			  }			else			  as_bad (_("Invalid Indexed Load Completer."));			s++;			i++;		      }		    if (i > 2)		      as_bad (_("Invalid Indexed Load Completer Syntax."));		    opcode |= m << 5;		    INSERT_FIELD_AND_CONTINUE (opcode, uu, 13);		  }		/* Handle a short load/store completer.  */		case 'm':		case 'q':		case 'J':		case 'e':		  {		    int a = 0;		    int m = 0;		    if (*s == ',')		      {			int found = 0;			s++;			if (strncasecmp (s, "ma", 2) == 0)			  {			    a = 0;			    m = 1;			    found = 1;			  }			else if (strncasecmp (s, "mb", 2) == 0)			  {			    a = 1;			    m = 1;			    found = 1;			  }			/* When in strict mode, pass through for cache op.  */			if (!found && strict)			  s--;			else			  {			    if (!found)			      as_bad (_("Invalid Short Load/Store Completer."));			    s += 2;			  }		      }		    /* If we did not get a ma/mb completer, then we do not		       consider this a positive match for 'ce'.  */		    else if (*args == 'e')		      break;		   /* 'J', 'm' and 'q' are the same, except for where they		       encode the before/after field.  */		   if (*args == 'm')		      {			opcode |= m << 5;			INSERT_FIELD_AND_CONTINUE (opcode, a, 13);		      }		    else if (*args == 'q')		      {			opcode |= m << 3;			INSERT_FIELD_AND_CONTINUE (opcode, a, 2);		      }		    else if (*args == 'J')		      {		        /* M bit is explicit in the major opcode.  */			INSERT_FIELD_AND_CONTINUE (opcode, a, 2);		      }		    else if (*args == 'e')		      {			/* Stash the ma/mb flag temporarily in the			   instruction.  We will use (and remove it)			   later when handling 'J', 'K', '<' & '>'.  */			opcode |= a;			continue;		      }		  }		/* Handle a stbys completer.  */		case 's':		  {		    int a = 0;		    int m = 0;		    int i = 0;		    while (*s == ',' && i < 2)		      {			s++;			if (strncasecmp (s, "m", 1) == 0)			  m = 1;			else if ((strncasecmp (s, "b ", 2) == 0)				 || (strncasecmp (s, "b,", 2) == 0))			  a = 0;			else if (strncasecmp (s, "e", 1) == 0)			  a = 1;			/* When in strict mode this is a match failure.  */			else if (strict)			  {			    s--;			    break;			  }			else			  as_bad (_("Invalid Store Bytes Short Completer"));			s++;			i++;		      }		    if (i > 2)		      as_bad (_("Invalid Store Bytes Short Completer"));		    opcode |= m << 5;		    INSERT_FIELD_AND_CONTINUE (opcode, a, 13);		  }		/* Handle load cache hint completer.  */		case 'c':		  cmpltr = 0;		  if (!strncmp(s, ",sl", 3))		    {		      s += 3;		      cmpltr = 2;		    }		  INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 10);		/* Handle store cache hint completer.  */		case 'C':		  cmpltr = 0;		  if (!strncmp(s, ",sl", 3))		    {		      s += 3;		      cmpltr = 2;		    }		  else if (!strncmp(s, ",bc", 3))		    {		      s += 3;		      cmpltr = 1;		    }		  INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 10);		/* Handle load and clear cache hint completer.  */		case 'd':		  cmpltr = 0;		  if (!strncmp(s, ",co", 3))		    {		      s += 3;		      cmpltr = 1;		    }		  INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 10);		/* Handle load ordering completer.  */		case 'o':		  if (strncmp(s, ",o", 2) != 0)		    break;		  s += 2;		  continue;		/* Handle a branch gate completer.  */		case 'g':		  if (strncasecmp (s, ",gate", 5) != 0)		    break;		  s += 5;		  continue;		/* Handle a branch link and push completer.  */		case 'p':		  if (strncasecmp (s, ",l,push", 7) != 0)		    break;		  s += 7;		  continue;		/* Handle a branch link completer.  */		case 'l':		  if (strncasecmp (s, ",l", 2) != 0)		    break;		  s += 2;		  continue;		/* Handle a branch pop completer.  */		case 'P':		  if (strncasecmp (s, ",pop", 4) != 0)		    break;		  s += 4;		  continue;		/* Handle a local processor completer.  */		case 'L':		  if (strncasecmp (s, ",l", 2) != 0)		    break;		  s += 2;		  continue;		/* Handle a PROBE read/write completer.  */		case 'w':		  flag = 0;		  if (!strncasecmp (s, ",w", 2))		    {		      flag = 1;		      s += 2;		    }		  else if (!strncasecmp (s, ",r", 2))		    {		      flag = 0;		      s += 2;

⌨️ 快捷键说明

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