tic30-dis.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 711 行 · 第 1/2 页

C
711
字号
    get_register_operand ((insn_word & 0x001F0000) >> 16, operand[2]);  info->fprintf_func (info->stream, "   %s %s,%s%c%s", insn->tm->name,		      operand[0], operand[1],		      operand[2][0] ? ',' : ' ',		      operand[2][0] ? operand[2] : "");  return 1;}intprint_par_insn (info, insn_word, insn)     disassemble_info *info;     unsigned long insn_word;     struct instruction *insn;{  size_t i, len;  char *name1, *name2;  char operand[2][3][13] =  {    {      {0},      {0},      {0}},    {      {0},      {0},      {0}}};  if (insn->ptm == NULL)    return 0;  /* Parse out the names of each of the parallel instructions from the     q_insn1_insn2 format.  */  name1 = (char *) strdup (insn->ptm->name + 2);  name2 = "";  len = strlen (name1);  for (i = 0; i < len; i++)    {      if (name1[i] == '_')	{	  name2 = &name1[i + 1];	  name1[i] = '\0';	  break;	}    }  /* Get the operands of the instruction based on the operand order.  */  switch (insn->ptm->oporder)    {    case OO_4op1:      get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][0]);      get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][1]);      get_register_operand ((insn_word >> 16) & 0x07, operand[1][0]);      get_register_operand ((insn_word >> 22) & 0x07, operand[0][1]);      break;    case OO_4op2:      get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][0]);      get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][0]);      get_register_operand ((insn_word >> 19) & 0x07, operand[1][1]);      get_register_operand ((insn_word >> 22) & 0x07, operand[0][1]);      break;    case OO_4op3:      get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][1]);      get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][1]);      get_register_operand ((insn_word >> 16) & 0x07, operand[1][0]);      get_register_operand ((insn_word >> 22) & 0x07, operand[0][0]);      break;    case OO_5op1:      get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][0]);      get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][1]);      get_register_operand ((insn_word >> 16) & 0x07, operand[1][0]);      get_register_operand ((insn_word >> 19) & 0x07, operand[0][1]);      get_register_operand ((insn_word >> 22) & 0x07, operand[0][2]);      break;    case OO_5op2:      get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][1]);      get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][1]);      get_register_operand ((insn_word >> 16) & 0x07, operand[1][0]);      get_register_operand ((insn_word >> 19) & 0x07, operand[0][0]);      get_register_operand ((insn_word >> 22) & 0x07, operand[0][2]);      break;    case OO_PField:      if (insn_word & 0x00800000)	get_register_operand (0x01, operand[0][2]);      else	get_register_operand (0x00, operand[0][2]);      if (insn_word & 0x00400000)	get_register_operand (0x03, operand[1][2]);      else	get_register_operand (0x02, operand[1][2]);      switch (insn_word & P_FIELD)	{	case 0x00000000:	  get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][1]);	  get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[0][0]);	  get_register_operand ((insn_word >> 16) & 0x07, operand[1][1]);	  get_register_operand ((insn_word >> 19) & 0x07, operand[1][0]);	  break;	case 0x01000000:	  get_indirect_operand ((insn_word & 0x000000FF), 1, operand[1][0]);	  get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[0][0]);	  get_register_operand ((insn_word >> 16) & 0x07, operand[1][1]);	  get_register_operand ((insn_word >> 19) & 0x07, operand[0][1]);	  break;	case 0x02000000:	  get_indirect_operand ((insn_word & 0x000000FF), 1, operand[1][1]);	  get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][0]);	  get_register_operand ((insn_word >> 16) & 0x07, operand[0][1]);	  get_register_operand ((insn_word >> 19) & 0x07, operand[0][0]);	  break;	case 0x03000000:	  get_indirect_operand ((insn_word & 0x000000FF), 1, operand[1][1]);	  get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[0][0]);	  get_register_operand ((insn_word >> 16) & 0x07, operand[1][0]);	  get_register_operand ((insn_word >> 19) & 0x07, operand[0][1]);	  break;	}      break;    default:      return 0;    }  info->fprintf_func (info->stream, "   %s %s,%s%c%s", name1,		      operand[0][0], operand[0][1],		      operand[0][2][0] ? ',' : ' ',		      operand[0][2][0] ? operand[0][2] : "");  info->fprintf_func (info->stream, "\n\t\t\t|| %s %s,%s%c%s", name2,		      operand[1][0], operand[1][1],		      operand[1][2][0] ? ',' : ' ',		      operand[1][2][0] ? operand[1][2] : "");  free (name1);  return 1;}intprint_branch (info, insn_word, insn)     disassemble_info *info;     unsigned long insn_word;     struct instruction *insn;{  char operand[2][13] =  {    {0},    {0}};  unsigned long address;  int print_label = 0;  if (insn->tm == NULL)    return 0;  /* Get the operands for 24-bit immediate jumps.  */  if (insn->tm->operand_types[0] & Imm24)    {      address = insn_word & 0x00FFFFFF;      sprintf (operand[0], "0x%lX", address);      print_label = 1;    }  /* Get the operand for the trap instruction.  */  else if (insn->tm->operand_types[0] & IVector)    {      address = insn_word & 0x0000001F;      sprintf (operand[0], "0x%lX", address);    }  else    {      address = insn_word & 0x0000FFFF;      /* Get the operands for the DB instructions.  */      if (insn->tm->operands == 2)	{	  get_register_operand (((insn_word & 0x01C00000) >> 22) + REG_AR0, operand[0]);	  if (insn_word & PCRel)	    {	      sprintf (operand[1], "%d", (short) address);	      print_label = 1;	    }	  else	    get_register_operand (insn_word & 0x0000001F, operand[1]);	}      /* Get the operands for the standard branches.  */      else if (insn->tm->operands == 1)	{	  if (insn_word & PCRel)	    {	      address = (short) address;	      sprintf (operand[0], "%ld", address);	      print_label = 1;	    }	  else	    get_register_operand (insn_word & 0x0000001F, operand[0]);	}    }  info->fprintf_func (info->stream, "   %s %s%c%s", insn->tm->name,		      operand[0][0] ? operand[0] : "",		      operand[1][0] ? ',' : ' ',		      operand[1][0] ? operand[1] : "");  /* Print destination of branch in relation to current symbol.  */  if (print_label && info->symbols)    {      asymbol *sym = *info->symbols;      if ((insn->tm->opcode_modifier == PCRel) && (insn_word & PCRel))	{	  address = (_pc + 1 + (short) address) - ((sym->section->vma + sym->value) / 4);	  /* Check for delayed instruction, if so adjust destination.  */	  if (insn_word & 0x00200000)	    address += 2;	}      else	{	  address -= ((sym->section->vma + sym->value) / 4);	}      if (address == 0)	info->fprintf_func (info->stream, " <%s>", sym->name);      else	info->fprintf_func (info->stream, " <%s %c %d>", sym->name,			    ((short) address < 0) ? '-' : '+',			    abs (address));    }  return 1;}intget_indirect_operand (fragment, size, buffer)     unsigned short fragment;     int size;     char *buffer;{  unsigned char mod;  unsigned arnum;  unsigned char disp;  if (buffer == NULL)    return 0;  /* Determine which bits identify the sections of the indirect     operand based on the size in bytes.  */  switch (size)    {    case 1:      mod = (fragment & 0x00F8) >> 3;      arnum = (fragment & 0x0007);      disp = 0;      break;    case 2:      mod = (fragment & 0xF800) >> 11;      arnum = (fragment & 0x0700) >> 8;      disp = (fragment & 0x00FF);      break;    default:      return 0;    }  {    const ind_addr_type *current_ind = tic30_indaddr_tab;    for (; current_ind < tic30_indaddrtab_end; current_ind++)      {	if (current_ind->modfield == mod)	  {	    if (current_ind->displacement == IMPLIED_DISP && size == 2)	      {		continue;	      }	    else	      {		size_t i, len;		int bufcnt;		len = strlen (current_ind->syntax);		for (i = 0, bufcnt = 0; i < len; i++, bufcnt++)		  {		    buffer[bufcnt] = current_ind->syntax[i];		    if (buffer[bufcnt - 1] == 'a' && buffer[bufcnt] == 'r')		      buffer[++bufcnt] = arnum + '0';		    if (buffer[bufcnt] == '('			&& current_ind->displacement == DISP_REQUIRED)		      {			sprintf (&buffer[bufcnt + 1], "%u", disp);			bufcnt += strlen (&buffer[bufcnt + 1]);		      }		  }		buffer[bufcnt + 1] = '\0';		break;	      }	  }      }  }  return 1;}intget_register_operand (fragment, buffer)     unsigned char fragment;     char *buffer;{  const reg *current_reg = tic30_regtab;  if (buffer == NULL)    return 0;  for (; current_reg < tic30_regtab_end; current_reg++)    {      if ((fragment & 0x1F) == current_reg->opcode)	{	  strcpy (buffer, current_reg->name);	  return 1;	}    }  return 0;}intcnvt_tmsfloat_ieee (tmsfloat, size, ieeefloat)     unsigned long tmsfloat;     int size;     float *ieeefloat;{  unsigned long exp, sign, mant;  if (size == 2)    {      if ((tmsfloat & 0x0000F000) == 0x00008000)	tmsfloat = 0x80000000;      else	{	  tmsfloat <<= 16;	  tmsfloat = (long) tmsfloat >> 4;	}    }  exp = tmsfloat & 0xFF000000;  if (exp == 0x80000000)    {      *ieeefloat = 0.0;      return 1;    }  exp += 0x7F000000;  sign = (tmsfloat & 0x00800000) << 8;  mant = tmsfloat & 0x007FFFFF;  if (exp == 0xFF000000)    {      if (mant == 0)	*ieeefloat = ERANGE;      if (sign == 0)	*ieeefloat = 1.0 / 0.0;      else	*ieeefloat = -1.0 / 0.0;      return 1;    }  exp >>= 1;  if (sign)    {      mant = (~mant) & 0x007FFFFF;      mant += 1;      exp += mant & 0x00800000;      exp &= 0x7F800000;      mant &= 0x007FFFFF;    }  if (tmsfloat == 0x80000000)    sign = mant = exp = 0;  tmsfloat = sign | exp | mant;  *ieeefloat = *((float *) &tmsfloat);  return 1;}

⌨️ 快捷键说明

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