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

📄 tc-h8300.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 3 页
字号:
      nibble_count++;      *p++ = nib;    }  /* Disgusting.  Why, oh why didn't someone ask us for advice     on the assembler format.  */  if (strcmp (this_try->name, "stm.l") == 0      || strcmp (this_try->name, "ldm.l") == 0)    {      int high, low;      high = (operand[this_try->name[0] == 'l' ? 1 : 0].reg >> 8) & 0xf;      low = operand[this_try->name[0] == 'l' ? 1 : 0].reg & 0xf;      asnibbles[2] = high - low;      asnibbles[7] = (this_try->name[0] == 'l') ? high : low;    }  for (i = 0; i < this_try->length; i++)    {      output[i] = (asnibbles[i * 2] << 4) | asnibbles[i * 2 + 1];    }  /* Note if this is a movb instruction -- there's a special relaxation     which only applies to them.  */  if (strcmp (this_try->name, "mov.b") == 0)    movb = 1;  /* Output any fixes.  */  for (i = 0; i < 2; i++)    {      int x = operand[i].mode;      if (x & (IMM | DISP))	{	  do_a_fix_imm (output - frag_now->fr_literal + immat,			operand + i, x & MEMRELAX != 0);	}      else if (x & ABS)	{	  do_a_fix_imm (output - frag_now->fr_literal + absat,			operand + i, x & MEMRELAX ? movb + 1 : 0);	}      else if (x & PCREL)	{	  int size16 = x & L_16;	  int where = size16 ? 2 : 1;	  int size = size16 ? 2 : 1;	  int type = size16 ? R_PCRWORD : R_PCRBYTE;	  check_operand (operand + i, size16 ? 0x7fff : 0x7f, "@");	  if (operand[i].exp.X_add_number & 1)	    {	      as_warn (_("branch operand has odd offset (%lx)\n"),		       (unsigned long) operand->exp.X_add_number);	    }	  operand[i].exp.X_add_number -= 1;	  operand[i].exp.X_add_number =	    ((operand[i].exp.X_add_number & 0xff) ^ 0x80) - 0x80;	  fix_new_exp (frag_now,		       output - frag_now->fr_literal + where,		       size,		       &operand[i].exp,		       1,		       type);	}      else if (x & MEMIND)	{	  check_operand (operand + i, 0xff, "@@");	  fix_new_exp (frag_now,		       output - frag_now->fr_literal + 1,		       1,		       &operand[i].exp,		       0,		       R_MEM_INDIRECT);	}      else if (x & ABSJMP)	{	  /* This jmp may be a jump or a branch.  */	  check_operand (operand + i, Hmode ? 0xffffff : 0xffff, "@");	  if (operand[i].exp.X_add_number & 1)	    {	      as_warn (_("branch operand has odd offset (%lx)\n"),		       (unsigned long) operand->exp.X_add_number);	    }	  if (!Hmode)	    operand[i].exp.X_add_number =	      ((operand[i].exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;	  fix_new_exp (frag_now,		       output - frag_now->fr_literal,		       4,		       &operand[i].exp,		       0,		       R_JMPL1);	}    }}/* Try to give an intelligent error message for common and simple to   detect errors.  */static voidclever_message (opcode, operand)     struct h8_opcode *opcode;     struct h8_op *operand;{  /* Find out if there was more than one possible opcode.  */  if ((opcode + 1)->idx != opcode->idx)    {      unsigned int argn;      /* Only one opcode of this flavour, try to guess which operand         didn't match.  */      for (argn = 0; argn < opcode->noperands; argn++)	{	  switch (opcode->args.nib[argn])	    {	    case RD16:	      if (operand[argn].mode != RD16)		{		  as_bad (_("destination operand must be 16 bit register"));		  return;		}	      break;	    case RS8:	      if (operand[argn].mode != RS8)		{		  as_bad (_("source operand must be 8 bit register"));		  return;		}	      break;	    case ABS16DST:	      if (operand[argn].mode != ABS16DST)		{		  as_bad (_("destination operand must be 16bit absolute address"));		  return;		}	      break;	    case RD8:	      if (operand[argn].mode != RD8)		{		  as_bad (_("destination operand must be 8 bit register"));		  return;		}	      break;	    case ABS16SRC:	      if (operand[argn].mode != ABS16SRC)		{		  as_bad (_("source operand must be 16bit absolute address"));		  return;		}	      break;	    }	}    }  as_bad (_("invalid operands"));}/* This is the guts of the machine-dependent assembler.  STR points to   a machine dependent instruction.  This function is supposed to emit   the frags/bytes it assembles.  */voidmd_assemble (str)     char *str;{  char *op_start;  char *op_end;  struct h8_op operand[2];  struct h8_opcode *opcode;  struct h8_opcode *prev_opcode;  char *dot = 0;  char c;  int size;  /* Drop leading whitespace.  */  while (*str == ' ')    str++;  /* Find the op code end.  */  for (op_start = op_end = str;       *op_end != 0 && *op_end != ' ';       op_end++)    {      if (*op_end == '.')	{	  dot = op_end + 1;	  *op_end = 0;	  op_end += 2;	  break;	}    }  if (op_end == op_start)    {      as_bad (_("can't find opcode "));    }  c = *op_end;  *op_end = 0;  opcode = (struct h8_opcode *) hash_find (opcode_hash_control,					   op_start);  if (opcode == NULL)    {      as_bad (_("unknown opcode"));      return;    }  /* We used to set input_line_pointer to the result of get_operands,     but that is wrong.  Our caller assumes we don't change it.  */  (void) get_operands (opcode->noperands, op_end, operand);  *op_end = c;  prev_opcode = opcode;  size = SN;  if (dot)    {      switch (*dot)	{	case 'b':	  size = SB;	  break;	case 'w':	  size = SW;	  break;	case 'l':	  size = SL;	  break;	}    }  opcode = get_specific (opcode, operand, size);  if (opcode == 0)    {      /* Couldn't find an opcode which matched the operands.  */      char *where = frag_more (2);      where[0] = 0x0;      where[1] = 0x0;      clever_message (prev_opcode, operand);      return;    }  if (opcode->size && dot)    {      if (opcode->size != *dot)	{	  as_warn (_("mismatch between opcode size and operand size"));	}    }  build_bytes (opcode, operand);}voidtc_crawl_symbol_chain (headers)     object_headers *headers ATTRIBUTE_UNUSED;{  printf (_("call to tc_crawl_symbol_chain \n"));}symbolS *md_undefined_symbol (name)     char *name ATTRIBUTE_UNUSED;{  return 0;}voidtc_headers_hook (headers)     object_headers *headers ATTRIBUTE_UNUSED;{  printf (_("call to tc_headers_hook \n"));}/* Various routines to kill one day *//* Equal to MAX_PRECISION in atof-ieee.c */#define MAX_LITTLENUMS 6/* 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.  */char *md_atof (type, litP, sizeP)     char type;     char *litP;     int *sizeP;{  int prec;  LITTLENUM_TYPE words[MAX_LITTLENUMS];  LITTLENUM_TYPE *wordP;  char *t;  char *atof_ieee ();  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, (long) (*wordP++), sizeof (LITTLENUM_TYPE));      litP += sizeof (LITTLENUM_TYPE);    }  return 0;}CONST char *md_shortopts = "";struct option md_longopts[] = {  {NULL, no_argument, NULL, 0}};size_t md_longopts_size = sizeof (md_longopts);intmd_parse_option (c, arg)     int c ATTRIBUTE_UNUSED;     char *arg ATTRIBUTE_UNUSED;{  return 0;}voidmd_show_usage (stream)     FILE *stream ATTRIBUTE_UNUSED;{}voidtc_aout_fix_to_chars (){  printf (_("call to tc_aout_fix_to_chars \n"));  abort ();}voidmd_convert_frag (headers, seg, fragP)     object_headers *headers ATTRIBUTE_UNUSED;     segT seg ATTRIBUTE_UNUSED;     fragS *fragP ATTRIBUTE_UNUSED;{  printf (_("call to md_convert_frag \n"));  abort ();}valueTmd_section_align (seg, size)     segT seg;     valueT size;{  return ((size + (1 << section_alignment[(int) seg]) - 1)	  & (-1 << section_alignment[(int) seg]));}voidmd_apply_fix (fixP, val)     fixS *fixP;     long val;{  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;  switch (fixP->fx_size)    {    case 1:      *buf++ = val;      break;    case 2:      *buf++ = (val >> 8);      *buf++ = val;      break;    case 4:      *buf++ = (val >> 24);      *buf++ = (val >> 16);      *buf++ = (val >> 8);      *buf++ = val;      break;    default:      abort ();    }}intmd_estimate_size_before_relax (fragP, segment_type)     register fragS *fragP ATTRIBUTE_UNUSED;     register segT segment_type ATTRIBUTE_UNUSED;{  printf (_("call tomd_estimate_size_before_relax \n"));  abort ();}/* Put number into target byte order.  */voidmd_number_to_chars (ptr, use, nbytes)     char *ptr;     valueT use;     int nbytes;{  number_to_chars_bigendian (ptr, use, nbytes);}longmd_pcrel_from (fixP)     fixS *fixP ATTRIBUTE_UNUSED;{  abort ();}voidtc_reloc_mangle (fix_ptr, intr, base)     fixS *fix_ptr;     struct internal_reloc *intr;     bfd_vma base;{  symbolS *symbol_ptr;  symbol_ptr = fix_ptr->fx_addsy;  /* If this relocation is attached to a symbol then it's ok     to output it.  */  if (fix_ptr->fx_r_type == TC_CONS_RELOC)    {      /* cons likes to create reloc32's whatever the size of the reloc..       */      switch (fix_ptr->fx_size)	{	case 4:	  intr->r_type = R_RELLONG;	  break;	case 2:	  intr->r_type = R_RELWORD;	  break;	case 1:	  intr->r_type = R_RELBYTE;	  break;	default:	  abort ();	}    }  else    {      intr->r_type = fix_ptr->fx_r_type;    }  intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;  intr->r_offset = fix_ptr->fx_offset;  if (symbol_ptr)    {      if (symbol_ptr->sy_number != -1)	intr->r_symndx = symbol_ptr->sy_number;      else	{	  symbolS *segsym;	  /* This case arises when a reference is made to `.'.  */	  segsym = seg_info (S_GET_SEGMENT (symbol_ptr))->dot;	  if (segsym == NULL)	    intr->r_symndx = -1;	  else	    {	      intr->r_symndx = segsym->sy_number;	      intr->r_offset += S_GET_VALUE (symbol_ptr);	    }	}    }  else    intr->r_symndx = -1;}

⌨️ 快捷键说明

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