arc-dis.c

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

C
1,222
字号
	    case 2:	      instrName = "ldw";	      state->_load_len = 2;	      break;	    default:	      instrName = "??? (1[3])"; 	      state->flow = invalid_instr;	      break;	    }	  decodingClass = 6;	}      break;          case op_ST:      if (BIT (state->words[0],25)) 	{	  instrName = "sr";	  decodingClass = 8;	}      else 	{	  switch (BITS (state->words[0],22,23)) 	    {	    case 0:	      instrName = "st";	      break;	    case 1:	      instrName = "stb";	      break;	    case 2:	      instrName = "stw";	      break;	    default:	      instrName = "??? (2[3])"; 	      state->flow = invalid_instr;	      break;	    }	  decodingClass = 7;	}      break;          case op_3:      decodingClass = 1;  /* default for opcode 3...  */      switch (FIELDC (state->words[0])) 	{	case  0:	  instrName = "flag"; 	  decodingClass = 2;	  break;	case  1:	  instrName = "asr";	  break;	case  2:	  instrName = "lsr";	  break;	case  3:	  instrName = "ror";	  break;	case  4:	  instrName = "rrc";	  break;	case  5:	  instrName = "sexb";	  break;	case  6:	  instrName = "sexw";	  break;	case  7:	  instrName = "extb";	  break;	case  8:	  instrName = "extw";	  break;	case  0x3f: 	  {	    decodingClass = 9;	    switch( FIELDD (state->words[0]) ) 	      {	      case 0:		instrName = "brk";		break;	      case 1:		instrName = "sleep";		break;	      case 2:		instrName = "swi";		break;	      default:		instrName = "???";		state->flow=invalid_instr;		break;	      }	  }	  break;	  	  /* ARC Extension Library Instructions	     NOTE: We assume that extension codes are these instrs.  */	default:	  instrName = instruction_name (state,					state->_opcode,					FIELDC (state->words[0]),					& flags);	  if (!instrName)	    {	      instrName = "???";	      state->flow = invalid_instr;	    }	  if (flags & IGNORE_FIRST_OPD)	    ignoreFirstOpd = 1;	  break;	}      break;    case op_BC:      instrName = "b";      case op_BLC:      if (!instrName)	instrName = "bl";     case op_LPC:      if (!instrName)	instrName = "lp";     case op_JC:      if (!instrName)	{	  if (BITS (state->words[0],9,9)) 	    {	      instrName = "jl";  	      is_linked = 1;	    }	  else 	    {	      instrName = "j";  	      is_linked = 0;	    }	}      condCodeIsPartOfName = 1;      decodingClass = ((state->_opcode == op_JC) ? 4 : 3);      state->isBranch = 1;      break;        case op_ADD:    case op_ADC:    case op_AND:      repeatsOp = (FIELDC (state->words[0]) == FIELDB (state->words[0]));      decodingClass = 0;      switch (state->_opcode) 	{	case op_ADD:	  instrName = (repeatsOp ? "asl" : "add");	  break;	case op_ADC:	  instrName = (repeatsOp ? "rlc" : "adc");	  break;	case op_AND:	  instrName = (repeatsOp ? "mov" : "and");	  break;	}      break;          case op_SUB: instrName = "sub";      break;    case op_SBC: instrName = "sbc";      break;    case op_OR:  instrName = "or";      break;    case op_BIC: instrName = "bic";      break;    case op_XOR:      if (state->words[0] == 0x7fffffff)	{	  /* nop encoded as xor -1, -1, -1  */	  instrName = "nop";	  decodingClass = 9;	}      else 	instrName = "xor";      break;          default:      instrName = instruction_name (state,state->_opcode,0,&flags);      /* if (instrName) printf("FLAGS=0x%x\n", flags);  */      if (!instrName)	{	  instrName = "???";	  state->flow=invalid_instr;	}      if (flags & IGNORE_FIRST_OPD)	ignoreFirstOpd = 1;      break;    }    fieldAisReg = fieldBisReg = fieldCisReg = 1; /* Assume regs for now.  */  flag = cond = is_shimm = is_limm = 0;  state->nullifyMode = BR_exec_when_no_jump;	/* 0  */  signExtend = addrWriteBack = directMem = 0;  usesAuxReg = 0;    switch (decodingClass)     {    case 0:      CHECK_FIELD_A ();      CHECK_FIELD_B ();      if (!repeatsOp)	CHECK_FIELD_C ();      CHECK_FLAG_COND_NULLIFY ();            write_instr_name ();      if (!ignoreFirstOpd) 	{	  WRITE_FORMAT_x (A);	  WRITE_FORMAT_COMMA_x (B);	  if (!repeatsOp)	    WRITE_FORMAT_COMMA_x (C);	  WRITE_NOP_COMMENT ();	  my_sprintf (state, state->operandBuffer, formatString, fieldA, fieldB, fieldC);	}      else 	{	  WRITE_FORMAT_x (B);	  if (!repeatsOp)	    WRITE_FORMAT_COMMA_x (C);	  my_sprintf (state, state->operandBuffer, formatString, fieldB, fieldC);	}      write_comments ();      break;          case 1:      CHECK_FIELD_A ();      CHECK_FIELD_B ();      CHECK_FLAG_COND_NULLIFY ();            write_instr_name ();      if (!ignoreFirstOpd) 	{	  WRITE_FORMAT_x (A);	  WRITE_FORMAT_COMMA_x (B);	  WRITE_NOP_COMMENT ();	  my_sprintf (state, state->operandBuffer, formatString, fieldA, fieldB); 	}      else 	{	  WRITE_FORMAT_x (B);	  my_sprintf (state, state->operandBuffer, formatString, fieldB); 	}      write_comments ();      break;          case 2:      CHECK_FIELD_B ();      CHECK_FLAG_COND_NULLIFY ();      flag = 0; /* this is the FLAG instruction -- it's redundant  */            write_instr_name ();      WRITE_FORMAT_x (B);      my_sprintf (state, state->operandBuffer, formatString, fieldB);      write_comments ();      break;          case 3:      fieldA = BITS (state->words[0],7,26) << 2;      fieldA = (fieldA << 10) >> 10; /* make it signed  */      fieldA += addr + 4;      CHECK_FLAG_COND_NULLIFY ();      flag = 0;            write_instr_name ();      /* This address could be a label we know. Convert it.  */      if (state->_opcode != op_LPC /* LP  */) 	{	add_target (fieldA); /* For debugger.  */	state->flow = state->_opcode == op_BLC /* BL  */	  ? direct_call	  : direct_jump;	/* indirect calls are achieved by "lr blink,[status];	   lr dest<- func addr; j [dest]"  */	}           		            strcat (formatString, "%s"); /* address/label name */      my_sprintf (state, state->operandBuffer, formatString, post_address (state, fieldA));      write_comments ();      break;          case 4:      /* For op_JC -- jump to address specified.	 Also covers jump and link--bit 9 of the instr. word	 selects whether linked, thus "is_linked" is set above.  */      fieldA = 0;      CHECK_FIELD_B ();      CHECK_FLAG_COND_NULLIFY ();            if (!fieldBisReg) 	{	  fieldAisReg = 0;	  fieldA = (fieldB >> 25) & 0x7F; /* flags */	  fieldB = (fieldB & 0xFFFFFF) << 2;	  state->flow = is_linked ? direct_call : direct_jump;	  add_target (fieldB);	  /* screwy JLcc requires .jd mode to execute correctly	   * but we pretend it is .nd (no delay slot).  */	  if (is_linked && state->nullifyMode == BR_exec_when_jump)	    state->nullifyMode = BR_exec_when_no_jump;	}      else 	{	  state->flow = is_linked ? indirect_call : indirect_jump;	  /* We should also treat this as indirect call if NOT linked	   * but the preceding instruction was a "lr blink,[status]"	   * and we have a delay slot with "add blink,blink,2".	   * For now we can't detect such.  */	  state->register_for_indirect_jump = fieldB;	}            write_instr_name ();      strcat (formatString, 	      IS_REG (B) ? "[%r]" : "%s"); /* address/label name  */      if (fieldA != 0) 	{	  fieldAisReg = 0;	  WRITE_FORMAT_COMMA_x (A);	}      if (IS_REG (B))	my_sprintf (state, state->operandBuffer, formatString, fieldB, fieldA);      else	my_sprintf (state, state->operandBuffer, formatString, 		    post_address (state, fieldB), fieldA);      write_comments ();      break;          case 5:      /* LD instruction.	 B and C can be regs, or one (both?) can be limm.  */      CHECK_FIELD_A ();      CHECK_FIELD_B ();      CHECK_FIELD_C ();      if (dbg)	printf ("5:b reg %d %d c reg %d %d  \n",		fieldBisReg,fieldB,fieldCisReg,fieldC);      state->_offset = 0;      state->_ea_present = 1;      if (fieldBisReg)	state->ea_reg1 = fieldB;      else	state->_offset += fieldB;      if (fieldCisReg)	state->ea_reg2 = fieldC;      else	state->_offset += fieldC;      state->_mem_load = 1;            directMem     = BIT (state->words[0],5);      addrWriteBack = BIT (state->words[0],3);      signExtend    = BIT (state->words[0],0);            write_instr_name ();      WRITE_FORMAT_x_COMMA_LB(A);      if (fieldBisReg || fieldB != 0)	WRITE_FORMAT_x_COMMA (B);      else	fieldB = fieldC;            WRITE_FORMAT_x_RB (C);      my_sprintf (state, state->operandBuffer, formatString, fieldA, fieldB, fieldC);      write_comments ();      break;          case 6:      /* LD instruction.  */      CHECK_FIELD_B ();      CHECK_FIELD_A ();      fieldC = FIELDD (state->words[0]);            if (dbg)	printf ("6:b reg %d %d c 0x%x  \n",		fieldBisReg, fieldB, fieldC);      state->_ea_present = 1;      state->_offset = fieldC;      state->_mem_load = 1;      if (fieldBisReg)	state->ea_reg1 = fieldB;      /* field B is either a shimm (same as fieldC) or limm (different!)	 Say ea is not present, so only one of us will do the name lookup.  */      else	state->_offset += fieldB, state->_ea_present = 0;            directMem     = BIT (state->words[0],14);      addrWriteBack = BIT (state->words[0],12);      signExtend    = BIT (state->words[0],9);            write_instr_name ();      WRITE_FORMAT_x_COMMA_LB (A);      if (!fieldBisReg) 	{	  fieldB = state->_offset;	  WRITE_FORMAT_x_RB (B);	}      else 	{	  WRITE_FORMAT_x (B);	  if (fieldC != 0 && !BIT (state->words[0],13)) 	    {	      fieldCisReg = 0;	      WRITE_FORMAT_COMMA_x_RB (C);	    }	  else	    WRITE_FORMAT_RB ();	}      my_sprintf (state, state->operandBuffer, formatString, fieldA, fieldB, fieldC);      write_comments ();      break;          case 7:      /* ST instruction.  */      CHECK_FIELD_B();      CHECK_FIELD_C();      fieldA = FIELDD(state->words[0]); /* shimm  */            /* [B,A offset]  */      if (dbg) printf("7:b reg %d %x off %x\n",				 fieldBisReg,fieldB,fieldA);      state->_ea_present = 1;      state->_offset = fieldA;      if (fieldBisReg)	state->ea_reg1 = fieldB;      /* field B is either a shimm (same as fieldA) or limm (different!) 	 Say ea is not present, so only one of us will do the name lookup.	 (for is_limm we do the name translation here).  */      else 	state->_offset += fieldB, state->_ea_present = 0;            directMem     = BIT(state->words[0],26);      addrWriteBack = BIT(state->words[0],24);            write_instr_name();      WRITE_FORMAT_x_COMMA_LB(C);	          if (!fieldBisReg) 	{	  fieldB = state->_offset;	  WRITE_FORMAT_x_RB(B);	}      else 	{	  WRITE_FORMAT_x(B);	  if (fieldBisReg && fieldA != 0) 	    {	      fieldAisReg = 0;	      WRITE_FORMAT_COMMA_x_RB(A);	    }	  else	    WRITE_FORMAT_RB();	}      my_sprintf (state, state->operandBuffer, formatString, fieldC, fieldB, fieldA);      write_comments2(fieldA);      break;    case 8:      /* SR instruction  */      CHECK_FIELD_B();      CHECK_FIELD_C();            write_instr_name();      WRITE_FORMAT_x_COMMA_LB(C);      /* Try to print B as an aux reg if it is not a core reg.  */      usesAuxReg = 1;      WRITE_FORMAT_x(B);      WRITE_FORMAT_RB();      my_sprintf (state, state->operandBuffer, formatString, fieldC, fieldB);      write_comments();      break;          case 9:      write_instr_name();      state->operandBuffer[0] = '\0';      break;          case 10:      /* LR instruction */      CHECK_FIELD_A();      CHECK_FIELD_B();            write_instr_name();      WRITE_FORMAT_x_COMMA_LB(A);      /* Try to print B as an aux reg if it is not a core reg. */      usesAuxReg = 1;      WRITE_FORMAT_x(B);      WRITE_FORMAT_RB();      my_sprintf (state, state->operandBuffer, formatString, fieldA, fieldB);      write_comments();      break;          case 11:      CHECK_COND();      write_instr_name();      state->operandBuffer[0] = '\0';      break;          default:      mwerror (state, "Bad decoding class in ARC disassembler");      break;    }    state->_cond = cond;  return state->instructionLen = offset;}/* Returns the name the user specified core extension register.  */static const char *_coreRegName(arg, regval)     void * arg ATTRIBUTE_UNUSED;     int regval;{  return arcExtMap_coreRegName (regval);}/* Returns the name the user specified AUX extension register.  */static const char *_auxRegName(void *_this ATTRIBUTE_UNUSED, int regval){    return arcExtMap_auxRegName(regval);}/* Returns the name the user specified condition code name.  */static const char *_condCodeName(void *_this ATTRIBUTE_UNUSED, int regval){    return arcExtMap_condCodeName(regval);}/* Returns the name the user specified extension instruction.  */static const char *_instName (void *_this ATTRIBUTE_UNUSED, int majop, int minop, int *flags){    return arcExtMap_instName(majop, minop, flags);}/* Decode an instruction returning the size of the instruction   in bytes or zero if unrecognized.  */static intdecodeInstr (address, info)     bfd_vma            address; /* Address of this instruction.  */     disassemble_info * info;{  int status;  bfd_byte buffer[4];  struct arcDisState s;	/* ARC Disassembler state  */  void *stream = info->stream; /* output stream  */  fprintf_ftype func = info->fprintf_func;   int bytes;    memset (&s, 0, sizeof(struct arcDisState));    /* read first instruction  */  status = (*info->read_memory_func) (address, buffer, 4, info);  if (status != 0)    {      (*info->memory_error_func) (status, address, info);      return 0;    }  if (info->endian == BFD_ENDIAN_LITTLE)    s.words[0] = bfd_getl32(buffer);  else    s.words[0] = bfd_getb32(buffer);  /* always read second word in case of limm  */  /* we ignore the result since last insn may not have a limm  */  status = (*info->read_memory_func) (address + 4, buffer, 4, info);  if (info->endian == BFD_ENDIAN_LITTLE)    s.words[1] = bfd_getl32(buffer);  else    s.words[1] = bfd_getb32(buffer);  s._this = &s;  s.coreRegName = _coreRegName;  s.auxRegName = _auxRegName;  s.condCodeName = _condCodeName;  s.instName = _instName;  /* disassemble  */  bytes = dsmOneArcInst(address, (void *)&s);  /* display the disassembly instruction  */  (*func) (stream, "%08x ", s.words[0]);  (*func) (stream, "    ");    (*func) (stream, "%-10s ", s.instrBuffer);    if (__TRANSLATION_REQUIRED(s))    {      bfd_vma addr = s.addresses[s.operandBuffer[1] - '0'];      (*info->print_address_func) ((bfd_vma) addr, info);      (*func) (stream, "\n");    }  else    (*func) (stream, "%s",s.operandBuffer);  return s.instructionLen;}/* Return the print_insn function to use.   Side effect: load (possibly empty) extension section  */disassembler_ftypearc_get_disassembler (void *ptr){  if (ptr)    build_ARC_extmap (ptr);  return decodeInstr;}

⌨️ 快捷键说明

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