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

📄 tc-v850.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 4 页
字号:
		      errmsg = _("register r0 cannot be used here");		      /* Force an error message to be generated by			 skipping over any following potential matches			 for this opcode.  */		      opcode += 3;		    }		}	      else if ((operand->flags & V850_OPERAND_SRG) != 0)		{		  if (!system_register_name (&ex, true, false))		    {		      errmsg = _("invalid system register name");		    }		}	      else if ((operand->flags & V850_OPERAND_EP) != 0)		{		  char *start = input_line_pointer;		  char c = get_symbol_end ();		  if (strcmp (start, "ep") != 0 && strcmp (start, "r30") != 0)		    {		      /* Put things back the way we found them.  */		      *input_line_pointer = c;		      input_line_pointer = start;		      errmsg = _("expected EP register");		      goto error;		    }		  *input_line_pointer = c;		  str = input_line_pointer;		  input_line_pointer = hold;		  while (*str == ' ' || *str == ','			 || *str == '[' || *str == ']')		    ++str;		  continue;		}	      else if ((operand->flags & V850_OPERAND_CC) != 0)		{		  if (!cc_name (&ex))		    {		      errmsg = _("invalid condition code name");		    }		}	      else if (operand->flags & V850E_PUSH_POP)		{		  errmsg = parse_register_list (&insn, operand);		  /* The parse_register_list() function has already done		     everything, so fake a dummy expression.  */		  ex.X_op         = O_constant;		  ex.X_add_number = 0;		}	      else if (operand->flags & V850E_IMMEDIATE16)		{		  expression (&ex);		  if (ex.X_op != O_constant)		    errmsg = _("constant expression expected");		  else if (ex.X_add_number & 0xffff0000)		    {		      if (ex.X_add_number & 0xffff)			errmsg = _("constant too big to fit into instruction");		      else if ((insn & 0x001fffc0) == 0x00130780)			ex.X_add_number >>= 16;		      else			errmsg = _("constant too big to fit into instruction");		    }		  extra_data_after_insn = true;		  extra_data_len        = 2;		  extra_data            = ex.X_add_number;		  ex.X_add_number       = 0;		}	      else if (operand->flags & V850E_IMMEDIATE32)		{		  expression (&ex);		  if (ex.X_op != O_constant)		    errmsg = _("constant expression expected");		  extra_data_after_insn = true;		  extra_data_len        = 4;		  extra_data            = ex.X_add_number;		  ex.X_add_number       = 0;		}	      else if (register_name (&ex)		       && (operand->flags & V850_OPERAND_REG) == 0)		{		  char c;		  int exists = 0;		  /* It is possible that an alias has been defined that		     matches a register name.  For example the code may		     include a ".set ZERO, 0" directive, which matches		     the register name "zero".  Attempt to reparse the		     field as an expression, and only complain if we		     cannot generate a constant.  */		  input_line_pointer = str;		  c = get_symbol_end ();		  if (symbol_find (str) != NULL)		    exists = 1;		  *input_line_pointer = c;		  input_line_pointer = str;		  expression (&ex);		  if (ex.X_op != O_constant)		    {		      /* If this register is actually occuring too early on			 the parsing of the instruction, (because another			 field is missing) then report this.  */		      if (opindex_ptr[1] != 0			  && (v850_operands[opindex_ptr[1]].flags			      & V850_OPERAND_REG))			errmsg = _("syntax error: value is missing before the register name");		      else			errmsg = _("syntax error: register not expected");		      /* If we created a symbol in the process of this			 test then delete it now, so that it will not			 be output with the real symbols...  */		      if (exists == 0			  && ex.X_op == O_symbol)			symbol_remove (ex.X_add_symbol,				       &symbol_rootP, &symbol_lastP);		    }		}	      else if (system_register_name (&ex, false, false)		       && (operand->flags & V850_OPERAND_SRG) == 0)		{		  errmsg = _("syntax error: system register not expected");		}	      else if (cc_name (&ex)		       && (operand->flags & V850_OPERAND_CC) == 0)		{		  errmsg = _("syntax error: condition code not expected");		}	      else		{		  expression (&ex);		  /* Special case:		     If we are assembling a MOV instruction (or a CALLT.... :-)		     and the immediate value does not fit into the bits		     available then create a fake error so that the next MOV		     instruction will be selected.  This one has a 32 bit		     immediate field.  */		  if (((insn & 0x07e0) == 0x0200)		      && ex.X_op == O_constant		      && (ex.X_add_number < (-(1 << (operand->bits - 1)))			  || ex.X_add_number > ((1 << operand->bits) - 1)))		    errmsg = _("immediate operand is too large");		}	      if (errmsg)		goto error;#if 0	      fprintf (stderr,		       " insn: %x, operand %d, op: %d, add_number: %d\n",		       insn, opindex_ptr - opcode->operands,		       ex.X_op, ex.X_add_number);#endif	      switch (ex.X_op)		{		case O_illegal:		  errmsg = _("illegal operand");		  goto error;		case O_absent:		  errmsg = _("missing operand");		  goto error;		case O_register:		  if ((operand->flags		       & (V850_OPERAND_REG | V850_OPERAND_SRG)) == 0)		    {		      errmsg = _("invalid operand");		      goto error;		    }		  insn = v850_insert_operand (insn, operand, ex.X_add_number,					      (char *) NULL, 0,					      copy_of_instruction);		  break;		case O_constant:		  insn = v850_insert_operand (insn, operand, ex.X_add_number,					      (char *) NULL, 0,					      copy_of_instruction);		  break;		default:		  /* 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;		}	    }	  str = input_line_pointer;	  input_line_pointer = hold;	  while (*str == ' ' || *str == ',' || *str == '[' || *str == ']'		 || *str == ')')	    ++str;	}      match = 1;    error:      if (match == 0)	{	  next_opcode = opcode + 1;	  if (next_opcode->name != NULL	      && strcmp (next_opcode->name, opcode->name) == 0)	    {	      opcode = next_opcode;	      /* Skip versions that are not supported by the target		 processor.  */	      if ((opcode->processors & processor_mask) == 0)		goto error;	      continue;	    }	  as_bad ("%s: %s", copy_of_instruction, errmsg);	  if (*input_line_pointer == ']')	    ++input_line_pointer;	  ignore_rest_of_line ();	  input_line_pointer = saved_input_line_pointer;	  return;	}      break;    }  while (isspace (*str))    ++str;  if (*str != '\0')    /* xgettext:c-format  */    as_bad (_("junk at end of line: `%s'"), str);  input_line_pointer = str;  /* Tie dwarf2 debug info to the address at the start of the insn.     We can't do this after the insn has been output as the current     frag may have been closed off.  eg. by frag_var.  */  dwarf2_emit_insn (0);  /* Write out the instruction.  */  if (relaxable && fc > 0)    {      insn_size = 2;      fc = 0;      if (!strcmp (opcode->name, "br"))	{	  f = frag_var (rs_machine_dependent, 4, 2, 2,			fixups[0].exp.X_add_symbol,			fixups[0].exp.X_add_number,			(char *) fixups[0].opindex);	  md_number_to_chars (f, insn, insn_size);	  md_number_to_chars (f + 2, 0, 2);	}      else	{	  f = frag_var (rs_machine_dependent, 6, 4, 0,			fixups[0].exp.X_add_symbol,			fixups[0].exp.X_add_number,			(char *) fixups[0].opindex);	  md_number_to_chars (f, insn, insn_size);	  md_number_to_chars (f + 2, 0, 4);	}    }  else    {      /* Four byte insns have an opcode with the two high bits on.  */      if ((insn & 0x0600) == 0x0600)	insn_size = 4;      else	insn_size = 2;      /* Special case: 32 bit MOV.  */      if ((insn & 0xffe0) == 0x0620)	insn_size = 2;      f = frag_more (insn_size);      md_number_to_chars (f, insn, insn_size);      if (extra_data_after_insn)	{	  f = frag_more (extra_data_len);	  md_number_to_chars (f, extra_data, extra_data_len);	  extra_data_after_insn = false;	}    }  /* Create any fixups.  At this point we do not use a     bfd_reloc_code_real_type, but instead just use the     BFD_RELOC_UNUSED plus the operand index.  This lets us easily     handle fixups for any operand type, although that is admittedly     not a very exciting feature.  We pick a BFD reloc type in     md_apply_fix.  */  for (i = 0; i < fc; i++)    {      const struct v850_operand *operand;      bfd_reloc_code_real_type reloc;      operand = &v850_operands[fixups[i].opindex];      reloc = fixups[i].reloc;      if (reloc != BFD_RELOC_UNUSED)	{	  reloc_howto_type *reloc_howto =	    bfd_reloc_type_lookup (stdoutput, reloc);	  int size;	  int address;	  fixS *fixP;	  if (!reloc_howto)	    abort ();	  size = bfd_get_reloc_size (reloc_howto);	  /* XXX This will abort on an R_V850_8 reloc -	     is this reloc actually used?  */	  if (size != 2 && size != 4)	    abort ();	  address = (f - frag_now->fr_literal) + insn_size - size;	  if (reloc == BFD_RELOC_32)	    address += 2;	  fixP = fix_new_exp (frag_now, address, size,			      &fixups[i].exp,			      reloc_howto->pc_relative,			      reloc);	  switch (reloc)	    {	    case BFD_RELOC_LO16:	    case BFD_RELOC_HI16:	    case BFD_RELOC_HI16_S:	      fixP->fx_no_overflow = 1;	      break;	    default:	      break;	    }	}      else	{	  fix_new_exp (frag_now,		       f - frag_now->fr_literal, 4,		       & fixups[i].exp,		       1 /* FIXME: V850_OPERAND_RELATIVE ???  */,		       (bfd_reloc_code_real_type) (fixups[i].opindex						   + (int) BFD_RELOC_UNUSED));	}    }  input_line_pointer = saved_input_line_pointer;}/* If while processing a fixup, a reloc really needs to be created   then it is done here.  */arelent *tc_gen_reloc (seg, fixp)     asection *seg ATTRIBUTE_UNUSED;     fixS *fixp;{  arelent *reloc;  reloc               = (arelent *) xmalloc (sizeof (arelent));  reloc->sym_ptr_ptr  = (asymbol **) xmalloc (sizeof (asymbol *));  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);  reloc->address      = fixp->fx_frag->fr_address + fixp->fx_where;  reloc->howto        = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);  if (reloc->howto == (reloc_howto_type *) NULL)    {      as_bad_where (fixp->fx_file, fixp->fx_line,		    /* xgettext:c-format  */		    _("reloc %d not supported by object file format"),		    (int) fixp->fx_r_type);      xfree (reloc);      return NULL;    }  if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY      || fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT)    reloc->addend = fixp->fx_offset;  else    reloc->addend = fixp->fx_addnumber;  return reloc;}/* Return current size of variable part of frag.  */intmd_estimate_size_before_relax (fragp, seg)     fragS *fragp;     asection *seg ATTRIBUTE_UNUSED;{  if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))    abort ();  return md_relax_table[fragp->fr_subtype].rlx_length;}longv850_pcrel_from_section (fixp, section)     fixS *fixp;     segT section;{  /* If the symbol is undefined, or in a section other than our own,     or it is weak (in which case it may well be in another section,     then let the linker figure it out.  */  if (fixp->fx_addsy != (symbolS *) NULL      && (! S_IS_DEFINED (fixp->fx_addsy)	  || S_IS_WEAK (fixp->fx_addsy)	  || (S_GET_SEGMENT (fixp->fx_addsy) != section)))    return 0;  return fixp->fx_frag->fr_address + fixp->fx_where;}intmd_apply_fix3 (fixp, valuep, seg)     fixS *fixp;     valueT *valuep;     segT seg ATTRIBUTE_UNUSED;{  valueT value;  char *where;  if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT      || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)    {      fixp->fx_done = 0;      return 1;    }  if (fixp->fx_addsy == (symbolS *) NULL)    {      value = *valuep;      fixp->fx_done = 1;    }  else if (fixp->fx_pcrel)    value = *valuep;  else    {      value = fixp->fx_offset;      if (fixp->fx_subsy != (symbolS *) NULL)	{	  if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)	    value -= S_GET_VALUE (fixp->fx_subsy);	  else	    {	      /* We don't actually support subtracting a symbol.  */	      as_bad_where (fixp->fx_file, fixp->fx_line,			    _("expression too complex"));	    }	}    }  if ((int) fixp->fx_r_type >= (int) BFD_RELOC_UNUSED)    {      int opindex;      const struct v850_operand *operand;      unsigned long insn;      opindex = (int) fixp->fx_r_type - (int) BFD_RELOC_UNUSED;      operand = &v850_operands[opindex];      /* Fetch the instruction, insert the fully resolved operand         value, and stuff the instruction back again.	 Note the instruction has been stored in little endian	 format!  */      where = fixp->fx_frag->fr_literal + fixp->fx_where;      insn = bfd_getl32 ((unsigned char *) where);      insn = v850_insert_operand (insn, operand, (offsetT) value,				  fixp->fx_file, fixp->fx_line, NULL);      bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);      if (fixp->fx_done)	{	  /* Nothing else to do here.  */	  return 1;	}      /* Determine a BFD reloc value based on the operand information.	 We are only prepared to turn a few of the operands into relocs.  */      if (operand->bits == 22)	fixp->fx_r_type = BFD_RELOC_V850_22_PCREL;      else if (operand->bits == 9)	fixp->fx_r_type = BFD_RELOC_V850_9_PCREL;      else	{#if 0	  fprintf (stderr, "bits: %d, insn: %x\n", operand->bits, insn);#endif	  as_bad_where (fixp->fx_file, fixp->fx_line,			_("unresolved expression that must be resolved"));	  fixp->fx_done = 1;	  return 1;	}    }  else if (fixp->fx_done)    {      /* We still have to insert the value into memory!  */      where = fixp->fx_frag->fr_literal + fixp->fx_where;      if (fixp->fx_size == 1)	*where = value & 0xff;      else if (fixp->fx_size == 2)	bfd_putl16 (value & 0xffff, (unsigned char *) where);      else if (fixp->fx_size == 4)	bfd_putl32 (value, (unsigned char *) where);    }  fixp->fx_addnumber = value;  return 1;}/* Parse a cons expression.  We have to handle hi(), lo(), etc   on the v850.  */voidparse_cons_expression_v850 (exp)     expressionS *exp;{  /* See if there's a reloc prefix like hi() we have to handle.  */  hold_cons_reloc = v850_reloc_prefix (NULL);  /* Do normal expression parsing.  */  expression (exp);}/* Create a fixup for a cons expression.  If parse_cons_expression_v850   found a reloc prefix, then we use that reloc, else we choose an   appropriate one based on the size of the expression.  */voidcons_fix_new_v850 (frag, where, size, exp)     fragS *frag;     int where;     int size;     expressionS *exp;{  if (hold_cons_reloc == BFD_RELOC_UNUSED)    {      if (size == 4)	hold_cons_reloc = BFD_RELOC_32;      if (size == 2)	hold_cons_reloc = BFD_RELOC_16;      if (size == 1)	hold_cons_reloc = BFD_RELOC_8;    }  if (exp != NULL)    fix_new_exp (frag, where, size, exp, 0, hold_cons_reloc);  else    fix_new (frag, where, size, NULL, 0, 0, hold_cons_reloc);  hold_cons_reloc = BFD_RELOC_UNUSED;}booleanv850_fix_adjustable (fixP)     fixS *fixP;{  if (fixP->fx_addsy == NULL)    return 1;  /* Prevent all adjustments to global symbols.  */  if (S_IS_EXTERN (fixP->fx_addsy))    return 0;  /* Similarly for weak symbols.  */  if (S_IS_WEAK (fixP->fx_addsy))    return 0;  /* Don't adjust function names.  */  if (S_IS_FUNCTION (fixP->fx_addsy))    return 0;  /* We need the symbol name for the VTABLE entries.  */  if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT      || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)    return 0;  return 1;}intv850_force_relocation (fixP)     struct fix *fixP;{  if (fixP->fx_addsy && S_IS_WEAK (fixP->fx_addsy))    return 1;  if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT      || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)    return 1;  return 0;}

⌨️ 快捷键说明

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