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

📄 tc-w65.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 2 页
字号:
  for (; opcode->code == ocode; opcode++)    {      if (opcode->amode == amode)	return opcode;    }  return 0;}intcheck (operand, low, high)     expressionS *operand;     int low;     int high;{  if (operand->X_op != O_constant      || operand->X_add_number < low      || operand->X_add_number > high)    {      as_bad ("operand must be absolute in range %d..%d", low, high);    }  return operand->X_add_number;}static int log2[] = { 0, 0, 1, 0, 2 };/* Now we know what sort of opcodes it is, let's build the bytes.  */static voidbuild_Mytes (opcode)     struct opinfo *opcode;{  int size;  int type;  int pcrel;  char *output;  if (opcode->amode == ADDR_IMPLIED)    {      output = frag_more (1);    }  else if (opcode->amode == ADDR_PC_REL)    {      int type;      /* This is a relaxable insn, so we do some special handling.  */      type = opcode->val == OP_BRA ? UNCOND_BRANCH : COND_BRANCH;      output = frag_var (rs_machine_dependent,			 md_relax_table[C (type, WORD_DISP)].rlx_length,			 md_relax_table[C (type, BYTE_DISP)].rlx_length,			 C (type, UNDEF_BYTE_DISP),			 immediate.X_add_symbol,			 immediate.X_add_number,			 0);    }  else    {      switch (opcode->amode)	{	  GETINFO (size, type, pcrel);	}      /* If something special was done in the expression modify the	 reloc type.  */      if (tc_cons_reloc)	type = tc_cons_reloc;      /* 1 byte for the opcode + the bytes for the addrmode.  */      output = frag_more (size + 1);      if (opcode->amode == ADDR_BLOCK_MOVE)	{	  /* Two relocs for this one.  */	  fix_new_exp (frag_now,		       output + 1 - frag_now->fr_literal,		       1,		       &immediate,		       0,		       R_W65_ABS8S16);	  fix_new_exp (frag_now,		       output + 2 - frag_now->fr_literal,		       1,		       &immediate1,		       0,		       R_W65_ABS8S16);	}      else if (type >= 0	       && opcode->amode != ADDR_IMPLIED	       && opcode->amode != ADDR_ACC	       && opcode->amode != ADDR_STACK)	{	  fix_new_exp (frag_now,		       output + 1 - frag_now->fr_literal,		       size,		       &immediate,		       pcrel,		       type);	}    }  output[0] = opcode->val;}/* 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 to.  */voidmd_assemble (str)     char *str;{  unsigned char *op_start;  unsigned char *op_end;  struct opinfo *opcode;  char name[20];  int nlen = 0;  char *p;  /* Drop leading whitespace */  while (*str == ' ')    str++;  /* all opcodes are three letters */  name[0] = str[0];  name[1] = str[1];  name[2] = str[2];  name[3] = 0;  tc_cons_reloc = 0;  str += 3;  opcode = (struct opinfo *) hash_find (opcode_hash_control, name);  if (opcode == NULL)    {      as_bad (_("unknown opcode"));      return;    }  if (opcode->amode != ADDR_IMPLIED      && opcode->amode != ADDR_STACK)    {      get_operands (opcode, str);      opcode = get_specific (opcode);    }  if (opcode == 0)    {      /* Couldn't find an opcode which matched the operands.  */      char *where = frag_more (1);      where[0] = 0x0;      where[1] = 0x0;      as_bad (_("invalid operands for opcode"));      return;    }  build_Mytes (opcode);}voidtc_crawl_symbol_chain (headers)     object_headers *headers;{  printf (_("call to tc_crawl_symbol_chain \n"));}symbolS *md_undefined_symbol (name)     char *name;{  return 0;}voidtc_headers_hook (headers)     object_headers *headers;{  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_NTOF()");    }  t = atof_ieee (input_line_pointer, type, words);  if (t)    input_line_pointer = t;  *sizeP = prec * sizeof (LITTLENUM_TYPE);  for (wordP = words + prec - 1; prec--;)    {      md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));      litP += sizeof (LITTLENUM_TYPE);    }  return 0;}intmd_parse_option (c, a)     int c;     char *a;{  return 1;}voidtc_Nout_fix_to_chars (){  printf (_("call to tc_Nout_fix_to_chars \n"));  abort ();}/* Called after relaxing, change the frags so they know how big they   are.  */voidmd_convert_frag (headers, seg, fragP)     object_headers *headers;     segT seg;     fragS *fragP;{  int disp_size = 0;  int inst_size = 0;  unsigned char *buffer =    (unsigned char *) (fragP->fr_fix + fragP->fr_literal);  switch (fragP->fr_subtype)    {    case C (COND_BRANCH, BYTE_DISP):    case C (UNCOND_BRANCH, BYTE_DISP):      disp_size = 1;      inst_size = 1;      break;      /* Conditional branches to a known 16 bit displacement.  */    case C (COND_BRANCH, WORD_DISP):      switch (buffer[0])	{	case OP_BCC:	case OP_BCS:	case OP_BEQ:	case OP_BMI:	case OP_BNE:	case OP_BPL:	case OP_BVS:	case OP_BVC:	  /* Invert the sense of the test */	  buffer[0] ^= 0x20;	  buffer[1] = 3;	/* Jump over following brl */	  buffer[2] = OP_BRL;	  buffer[3] = 0;	  buffer[4] = 0;	  disp_size = 2;	  inst_size = 3;	  break;	default:	  abort ();	}      break;    case C (UNCOND_BRANCH, WORD_DISP):      /* Unconditional branches to a known 16 bit displacement.  */      switch (buffer[0])	{	case OP_BRA:	  buffer[0] = OP_BRL;	  disp_size = 2;	  inst_size = 1;	  break;	default:	  abort ();	}      break;      /* Got to create a branch over a reloc here.  */    case C (COND_BRANCH, UNDEF_WORD_DISP):      buffer[0] ^= 0x20;	/* invert test */      buffer[1] = 3;      buffer[2] = OP_BRL;      buffer[3] = 0;      buffer[4] = 0;      fix_new (fragP,	       fragP->fr_fix + 3,	       4,	       fragP->fr_symbol,	       fragP->fr_offset,	       0,	       R_W65_PCR16);      fragP->fr_fix += disp_size + inst_size;      fragP->fr_var = 0;      break;    case C (UNCOND_BRANCH, UNDEF_WORD_DISP):      buffer[0] = OP_BRL;      buffer[1] = 0;      buffer[2] = 0;      fix_new (fragP,	       fragP->fr_fix + 1,	       4,	       fragP->fr_symbol,	       fragP->fr_offset,	       0,	       R_W65_PCR16);      fragP->fr_fix += disp_size + inst_size;      fragP->fr_var = 0;      break;    default:      abort ();    }  if (inst_size)    {      /* Get the address of the end of the instruction.  */      int next_inst = (fragP->fr_fix + fragP->fr_address		       + disp_size + inst_size);      int targ_addr = (S_GET_VALUE (fragP->fr_symbol) +		       fragP->fr_offset);      int disp = targ_addr - next_inst;      md_number_to_chars (buffer + inst_size, disp, disp_size);      fragP->fr_fix += disp_size + inst_size;      fragP->fr_var = 0;    }}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;  int addr = fixP->fx_frag->fr_address + fixP->fx_where;  if (fixP->fx_r_type == 0)    {      if (fixP->fx_size == 1)	fixP->fx_r_type = R_W65_ABS8;      else	fixP->fx_r_type = R_W65_ABS16;    }  switch (fixP->fx_r_type)    {    case R_W65_ABS8S16:      val >>= 8;    case R_W65_ABS8S8:      val >>= 8;    case R_W65_ABS8:      *buf++ = val;      break;    case R_W65_ABS16S16:      val >>= 8;    case R_W65_ABS16S8:      val >>= 8;    case R_W65_ABS16:      *buf++ = val >> 0;      *buf++ = val >> 8;      break;    case R_W65_ABS24:      *buf++ = val >> 0;      *buf++ = val >> 8;      *buf++ = val >> 16;      break;    case R_W65_PCR8:      *buf++ = val - addr - 1;      break;    case R_W65_PCR16:      val = val - addr - 1;      *buf++ = val;      *buf++ = val >> 8;      break;    case R_W65_DP:      *buf++ = val;      break;    default:      abort ();    }}/* Put number into target byte order */voidmd_number_to_chars (ptr, use, nbytes)     char *ptr;     valueT use;     int nbytes;{  number_to_chars_littleendian (ptr, use, nbytes);}longmd_pcrel_from (fixP)     fixS *fixP;{  int gap = fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address - 1;  return gap;}voidtc_coff_symbol_emit_hook (x)     symbolS *x;{}shorttc_coff_fix2rtype (fix_ptr)     fixS *fix_ptr;{  return fix_ptr->fx_r_type;}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 == RELOC_32)    {      /* cons likes to create reloc32's whatever the size of the reloc..       */      switch (fix_ptr->fx_size)	{	case 2:	  intr->r_type = R_IMM16;	  break;	case 1:	  intr->r_type = R_IMM8;	  break;	default:	  abort ();	}    }  else    {      if (fix_ptr->fx_size == 4)	intr->r_type = R_W65_ABS24;      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;  /* Turn the segment of the symbol into an offset.  */  if (symbol_ptr)    {      symbolS *dot;      dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;      if (dot)	{	  intr->r_offset += S_GET_VALUE (symbol_ptr);	  intr->r_symndx = dot->sy_number;	}      else	{	  intr->r_symndx = symbol_ptr->sy_number;	}    }  else    {      intr->r_symndx = -1;    }}inttc_coff_sizemachdep (frag)     fragS *frag;{  return md_relax_table[frag->fr_subtype].rlx_length;}/* Called just before address relaxation, return the length by which a   fragment must grow to reach it's destination.  */intmd_estimate_size_before_relax (fragP, segment_type)     register fragS *fragP;     register segT segment_type;{  int what;  switch (fragP->fr_subtype)    {    default:      abort ();    case C (COND_BRANCH, UNDEF_BYTE_DISP):    case C (UNCOND_BRANCH, UNDEF_BYTE_DISP):      what = GET_WHAT (fragP->fr_subtype);      /* Used to be a branch to somewhere which was unknown.  */      if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)	{	  /* Got a symbol and it's defined in this segment, become byte	     sized - maybe it will fix up.  */	  fragP->fr_subtype = C (what, BYTE_DISP);	}      else	{	  /* Its got a segment, but its not ours, so it will always be             long.  */	  fragP->fr_subtype = C (what, UNDEF_WORD_DISP);	}      break;    case C (COND_BRANCH, BYTE_DISP):    case C (COND_BRANCH, WORD_DISP):    case C (COND_BRANCH, UNDEF_WORD_DISP):    case C (UNCOND_BRANCH, BYTE_DISP):    case C (UNCOND_BRANCH, WORD_DISP):    case C (UNCOND_BRANCH, UNDEF_WORD_DISP):      /* When relaxing a section for the second time, we don't need to	 do anything besides return the current size.  */      break;    }  fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;  return fragP->fr_var;}CONST char *md_shortopts = "";struct option md_longopts[] = {#define OPTION_RELAX (OPTION_MD_BASE)  {NULL, no_argument, NULL, 0}};voidmd_show_usage (stream)     FILE *stream;{}size_t md_longopts_size = sizeof (md_longopts);

⌨️ 快捷键说明

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