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

📄 tc-v850.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 4 页
字号:
{  return 0;}char *md_atof (type, litp, sizep)     int type;     char *litp;     int *sizep;{  int prec;  LITTLENUM_TYPE words[4];  char *t;  int i;  switch (type)    {    case 'f':      prec = 2;      break;    case 'd':      prec = 4;      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 * 2;  for (i = prec - 1; i >= 0; i--)    {      md_number_to_chars (litp, (valueT) words[i], 2);      litp += 2;    }  return NULL;}/* Very gross.  */voidmd_convert_frag (abfd, sec, fragP)     bfd *abfd ATTRIBUTE_UNUSED;     asection *sec;     fragS *fragP;{  subseg_change (sec, 0);  /* In range conditional or unconditional branch.  */  if (fragP->fr_subtype == 0 || fragP->fr_subtype == 2)    {      fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,	       fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode);      fragP->fr_fix += 2;    }  /* Out of range conditional branch.  Emit a branch around a jump.  */  else if (fragP->fr_subtype == 1)    {      unsigned char *buffer =	(unsigned char *) (fragP->fr_fix + fragP->fr_literal);      /* Reverse the condition of the first branch.  */      buffer[0] ^= 0x08;      /* Mask off all the displacement bits.  */      buffer[0] &= 0x8f;      buffer[1] &= 0x07;      /* Now set the displacement bits so that we branch	 around the unconditional branch.  */      buffer[0] |= 0x30;      /* Now create the unconditional branch + fixup to the final	 target.  */      md_number_to_chars (buffer + 2, 0x00000780, 4);      fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,	       fragP->fr_offset, 1, BFD_RELOC_UNUSED +	       (int) fragP->fr_opcode + 1);      fragP->fr_fix += 6;    }  /* Out of range unconditional branch.  Emit a jump.  */  else if (fragP->fr_subtype == 3)    {      md_number_to_chars (fragP->fr_fix + fragP->fr_literal, 0x00000780, 4);      fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,	       fragP->fr_offset, 1, BFD_RELOC_UNUSED +	       (int) fragP->fr_opcode + 1);      fragP->fr_fix += 4;    }  else    abort ();}valueTmd_section_align (seg, addr)     asection *seg;     valueT addr;{  int align = bfd_get_section_alignment (stdoutput, seg);  return ((addr + (1 << align) - 1) & (-1 << align));}voidmd_begin (){  char *prev_name = "";  register const struct v850_opcode *op;  flagword applicable;  if (strncmp (TARGET_CPU, "v850ea", 6) == 0)    {      if (machine == -1)	machine = bfd_mach_v850ea;      if (processor_mask == -1)	processor_mask = PROCESSOR_V850EA;    }  else if (strncmp (TARGET_CPU, "v850e", 5) == 0)    {      if (machine == -1)	machine = bfd_mach_v850e;      if (processor_mask == -1)	processor_mask = PROCESSOR_V850E;    }  else if (strncmp (TARGET_CPU, "v850", 4) == 0)    {      if (machine == -1)	machine = 0;      if (processor_mask == -1)	processor_mask = PROCESSOR_V850;    }  else    /* xgettext:c-format  */    as_bad (_("Unable to determine default target processor from string: %s"),            TARGET_CPU);  v850_hash = hash_new ();  /* Insert unique names into hash table.  The V850 instruction set     has many identical opcode names that have different opcodes based     on the operands.  This hash table then provides a quick index to     the first opcode with a particular name in the opcode table.  */  op = v850_opcodes;  while (op->name)    {      if (strcmp (prev_name, op->name))	{	  prev_name = (char *) op->name;	  hash_insert (v850_hash, op->name, (char *) op);	}      op++;    }  bfd_set_arch_mach (stdoutput, TARGET_ARCH, machine);  applicable = bfd_applicable_section_flags (stdoutput);  call_table_data_section = subseg_new (".call_table_data", 0);  bfd_set_section_flags (stdoutput, call_table_data_section,			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC				       | SEC_DATA | SEC_HAS_CONTENTS));  call_table_text_section = subseg_new (".call_table_text", 0);  bfd_set_section_flags (stdoutput, call_table_text_section,			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_READONLY				       | SEC_CODE));  /* Restore text section as the current default.  */  subseg_set (text_section, 0);}static bfd_reloc_code_real_typehandle_ctoff (const struct v850_operand *operand){  if (operand == NULL)    return BFD_RELOC_V850_CALLT_16_16_OFFSET;  if (operand->bits != 6      || operand->shift != 0)    {      as_bad (_("ctoff() relocation used on an instruction which does not support it"));      return BFD_RELOC_64;  /* Used to indicate an error condition.  */    }  return BFD_RELOC_V850_CALLT_6_7_OFFSET;}static bfd_reloc_code_real_typehandle_sdaoff (const struct v850_operand *operand){  if (operand == NULL)    return BFD_RELOC_V850_SDA_16_16_OFFSET;  if (operand->bits == 15 && operand->shift == 17)    return BFD_RELOC_V850_SDA_15_16_OFFSET;  if (operand->bits == -1)    return BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET;  if (operand->bits != 16      || operand->shift != 16)    {      as_bad (_("sdaoff() relocation used on an instruction which does not support it"));      return BFD_RELOC_64;  /* Used to indicate an error condition.  */    }  return BFD_RELOC_V850_SDA_16_16_OFFSET;}static bfd_reloc_code_real_typehandle_zdaoff (const struct v850_operand *operand){  if (operand == NULL)    return BFD_RELOC_V850_ZDA_16_16_OFFSET;  if (operand->bits == 15 && operand->shift == 17)    return BFD_RELOC_V850_ZDA_15_16_OFFSET;  if (operand->bits == -1)    return BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET;  if (operand->bits != 16      || operand->shift != 16)    {      as_bad (_("zdaoff() relocation used on an instruction which does not support it"));      /* Used to indicate an error condition.  */      return BFD_RELOC_64;    }  return BFD_RELOC_V850_ZDA_16_16_OFFSET;}static bfd_reloc_code_real_typehandle_tdaoff (const struct v850_operand *operand){  if (operand == NULL)    /* Data item, not an instruction.  */    return BFD_RELOC_V850_TDA_7_7_OFFSET;  if (operand->bits == 6 && operand->shift == 1)    /* sld.w/sst.w, operand: D8_6  */    return BFD_RELOC_V850_TDA_6_8_OFFSET;  if (operand->bits == 4 && operand->insert != NULL)    /* sld.hu, operand: D5-4  */    return BFD_RELOC_V850_TDA_4_5_OFFSET;  if (operand->bits == 4 && operand->insert == NULL)    /* sld.bu, operand: D4   */    return BFD_RELOC_V850_TDA_4_4_OFFSET;  if (operand->bits == 16 && operand->shift == 16)    /* set1 & chums, operands: D16  */    return BFD_RELOC_V850_TDA_16_16_OFFSET;  if (operand->bits != 7)    {      as_bad (_("tdaoff() relocation used on an instruction which does not support it"));      /* Used to indicate an error condition.  */      return BFD_RELOC_64;    }  return  operand->insert != NULL    ? BFD_RELOC_V850_TDA_7_8_OFFSET     /* sld.h/sst.h, operand: D8_7  */    : BFD_RELOC_V850_TDA_7_7_OFFSET;    /* sld.b/sst.b, opreand: D7    */}/* Warning: The code in this function relies upon the definitions   in the v850_operands[] array (defined in opcodes/v850-opc.c)   matching the hard coded values contained herein.  */static bfd_reloc_code_real_typev850_reloc_prefix (const struct v850_operand *operand){  boolean paren_skipped = false;  /* Skip leading opening parenthesis.  */  if (*input_line_pointer == '(')    {      ++input_line_pointer;      paren_skipped = true;    }#define CHECK_(name, reloc) 						\  if (strncmp (input_line_pointer, name##"(", strlen (name) + 1) == 0)	\    {									\      input_line_pointer += strlen (name);				\      return reloc;							\    }  CHECK_ ("hi0",    BFD_RELOC_HI16         );  CHECK_ ("hi",     BFD_RELOC_HI16_S       );  CHECK_ ("lo",     BFD_RELOC_LO16         );  CHECK_ ("sdaoff", handle_sdaoff (operand));  CHECK_ ("zdaoff", handle_zdaoff (operand));  CHECK_ ("tdaoff", handle_tdaoff (operand));  CHECK_ ("hilo",   BFD_RELOC_32           );  CHECK_ ("ctoff",  handle_ctoff (operand) );  /* Restore skipped parenthesis.  */  if (paren_skipped)    --input_line_pointer;  return BFD_RELOC_UNUSED;}/* Insert an operand value into an instruction.  */static unsigned longv850_insert_operand (insn, operand, val, file, line, str)     unsigned long insn;     const struct v850_operand *operand;     offsetT val;     char *file;     unsigned int line;     char *str;{  if (operand->insert)    {      const char *message = NULL;      insn = operand->insert (insn, val, &message);      if (message != NULL)	{	  if ((operand->flags & V850_OPERAND_SIGNED)	      && ! warn_signed_overflows	      && strstr (message, "out of range") != NULL)	    {	      /* Skip warning...  */	    }	  else if ((operand->flags & V850_OPERAND_SIGNED) == 0		   && ! warn_unsigned_overflows		   && strstr (message, "out of range") != NULL)	    {	      /* Skip warning...  */	    }	  else if (str)	    {	      if (file == (char *) NULL)		as_warn ("%s: %s", str, message);	      else		as_warn_where (file, line, "%s: %s", str, message);	    }	  else	    {	      if (file == (char *) NULL)		as_warn (message);	      else		as_warn_where (file, line, message);	    }	}    }  else    {      if (operand->bits != 32)	{	  long min, max;	  if ((operand->flags & V850_OPERAND_SIGNED) != 0)	    {	      if (! warn_signed_overflows)		max = (1 << operand->bits) - 1;	      else		max = (1 << (operand->bits - 1)) - 1;	      min = -(1 << (operand->bits - 1));	    }	  else	    {	      max = (1 << operand->bits) - 1;	      if (! warn_unsigned_overflows)		min = -(1 << (operand->bits - 1));	      else		min = 0;	    }	  if (val < (offsetT) min || val > (offsetT) max)	    {	      /* xgettext:c-format  */	      const char *err =		_("operand out of range (%s not between %ld and %ld)");	      char buf[100];	      /* Restore min and mix to expected values for decimal ranges.  */	      if ((operand->flags & V850_OPERAND_SIGNED)		  && ! warn_signed_overflows)		max = (1 << (operand->bits - 1)) - 1;	      if (! (operand->flags & V850_OPERAND_SIGNED)		  && ! warn_unsigned_overflows)		min = 0;	      if (str)		{		  sprintf (buf, "%s: ", str);		  sprint_value (buf + strlen (buf), val);		}	      else		sprint_value (buf, val);	      if (file == (char *) NULL)		as_warn (err, buf, min, max);	      else		as_warn_where (file, line, err, buf, min, max);	    }	}      insn |= (((long) val & ((1 << operand->bits) - 1)) << operand->shift);    }  return insn;}static char copy_of_instruction[128];voidmd_assemble (str)     char *str;{  char *s;  char *start_of_operands;  struct v850_opcode *opcode;  struct v850_opcode *next_opcode;  const unsigned char *opindex_ptr;  int next_opindex;  int relaxable = 0;  unsigned long insn;  unsigned long insn_size;  char *f;  int i;  int match;  boolean extra_data_after_insn = false;  unsigned extra_data_len = 0;  unsigned long extra_data = 0;  char *saved_input_line_pointer;  strncpy (copy_of_instruction, str, sizeof (copy_of_instruction) - 1);  /* Get the opcode.  */  for (s = str; *s != '\0' && ! isspace (*s); s++)    continue;  if (*s != '\0')    *s++ = '\0';  /* Find the first opcode with the proper name.  */  opcode = (struct v850_opcode *) hash_find (v850_hash, str);  if (opcode == NULL)    {      /* xgettext:c-format  */      as_bad (_("Unrecognized opcode: `%s'"), str);      ignore_rest_of_line ();      return;    }  str = s;  while (isspace (*str))    ++str;  start_of_operands = str;  saved_input_line_pointer = input_line_pointer;  for (;;)    {      const char *errmsg = NULL;      match = 0;      if ((opcode->processors & processor_mask) == 0)	{	  errmsg = _("Target processor does not support this instruction.");	  goto error;	}      relaxable = 0;      fc = 0;      next_opindex = 0;      insn = opcode->opcode;      extra_data_after_insn = false;      input_line_pointer = str = start_of_operands;      for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)	{	  const struct v850_operand *operand;	  char *hold;	  expressionS ex;	  bfd_reloc_code_real_type reloc;	  if (next_opindex == 0)	    {	      operand = &v850_operands[*opindex_ptr];	    }	  else	    {	      operand = &v850_operands[next_opindex];	      next_opindex = 0;	    }	  errmsg = NULL;	  while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')	    ++str;	  if (operand->flags & V850_OPERAND_RELAX)	    relaxable = 1;	  /* Gather the operand.  */	  hold = input_line_pointer;	  input_line_pointer = str;	  /* lo(), hi(), hi0(), etc...  */	  if ((reloc = v850_reloc_prefix (operand)) != BFD_RELOC_UNUSED)	    {	      /* This is a fake reloc, used to indicate an error condition.  */	      if (reloc == BFD_RELOC_64)		{		  match = 1;		  goto error;		}	      expression (&ex);	      if (ex.X_op == O_constant)		{		  switch (reloc)		    {		    case BFD_RELOC_V850_ZDA_16_16_OFFSET:		      /* To cope with "not1 7, zdaoff(0xfffff006)[r0]"			 and the like.  */		      /* Fall through.  */		    case BFD_RELOC_LO16:		      {			/* Truncate, then sign extend the value.  */			ex.X_add_number = SEXT16 (ex.X_add_number);			break;		      }		    case BFD_RELOC_HI16:		      {			/* Truncate, then sign extend the value.  */			ex.X_add_number = SEXT16 (ex.X_add_number >> 16);			break;		      }		    case BFD_RELOC_HI16_S:		      {			/* Truncate, then sign extend the value.  */			int temp = (ex.X_add_number >> 16) & 0xffff;			temp += (ex.X_add_number >> 15) & 1;			ex.X_add_number = SEXT16 (temp);			break;		      }		    case BFD_RELOC_32:		      if ((operand->flags & V850E_IMMEDIATE32) == 0)			{			  errmsg = _("immediate operand is too large");			  goto error;			}		      extra_data_after_insn = true;		      extra_data_len        = 4;		      extra_data            = ex.X_add_number;		      ex.X_add_number       = 0;		      break;		    default:		      fprintf (stderr, "reloc: %d\n", reloc);		      as_bad (_("AAARG -> unhandled constant reloc"));		      break;		    }		  if (fc > MAX_INSN_FIXUPS)		    as_fatal (_("too many fixups"));		  fixups[fc].exp     = ex;		  fixups[fc].opindex = *opindex_ptr;		  fixups[fc].reloc   = reloc;		  fc++;		}	      else		{		  if (reloc == BFD_RELOC_32)		    {		      if ((operand->flags & V850E_IMMEDIATE32) == 0)			{			  errmsg = _("immediate operand is too large");			  goto error;			}		      extra_data_after_insn = true;		      extra_data_len        = 4;		      extra_data            = ex.X_add_number;		    }		  if (fc > MAX_INSN_FIXUPS)		    as_fatal (_("too many fixups"));		  fixups[fc].exp     = ex;		  fixups[fc].opindex = *opindex_ptr;		  fixups[fc].reloc   = reloc;		  fc++;		}	    }	  else	    {	      errmsg = NULL;	      if ((operand->flags & V850_OPERAND_REG) != 0)		{		  if (!register_name (&ex))		    {		      errmsg = _("invalid register name");		    }		  else if ((operand->flags & V850_NOT_R0)			   && ex.X_add_number == 0)		    {

⌨️ 快捷键说明

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