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

📄 tc-mcore.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 4 页
字号:
    case OPTION_JSRI2BSR_OFF: do_jsri2bsr = 0;   break;    case OPTION_SIFILTER_ON:  sifilter_mode = 1; break;    case OPTION_SIFILTER_OFF: sifilter_mode = 0; break;    default:                  return 0;    }  return 1;}voidmd_show_usage (stream)     FILE * stream;{  fprintf (stream, _("\MCORE specific options:\n\  -{no-}jsri2bsr	  {dis}able jsri to bsr transformation (def: dis)\n\  -{no-}sifilter	  {dis}able silicon filter behavior (def: dis)\n\  -cpu=[210|340]          select CPU type\n\  -EB                     assemble for a big endian system (default)\n\  -EL                     assemble for a little endian system\n"));}int md_short_jump_size;voidmd_create_short_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol)     char * ptr;     addressT from_Nddr;     addressT to_Nddr;     fragS * frag;     symbolS * to_symbol;{  as_fatal (_("failed sanity check: short_jump"));}voidmd_create_long_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol)     char * ptr;     addressT from_Nddr;     addressT to_Nddr;     fragS * frag;     symbolS * to_symbol;{  as_fatal (_("failed sanity check: long_jump"));}/* Called after relaxing, change the frags so they know how big they are.  */voidmd_convert_frag (abfd, sec, fragP)     bfd * abfd;     segT sec;     register fragS * fragP;{  unsigned char * buffer;  int targ_addr = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;  buffer = (unsigned char *) (fragP->fr_fix + fragP->fr_literal);  targ_addr += symbol_get_frag (fragP->fr_symbol)->fr_address;  switch (fragP->fr_subtype)    {    case C (COND_JUMP, DISP12):    case C (UNCD_JUMP, DISP12):      {	/* Get the address of the end of the instruction.  */	int next_inst = fragP->fr_fix + fragP->fr_address + 2;	unsigned char t0;	int disp = targ_addr - next_inst;	if (disp & 1)	  as_bad (_("odd displacement at %x"), next_inst - 2);	disp >>= 1;	if (! target_big_endian)	  {	    t0 = buffer[1] & 0xF8;	    md_number_to_chars (buffer, disp, 2);	    buffer[1] = (buffer[1] & 0x07) | t0;	  }	else	  {	    t0 = buffer[0] & 0xF8;	    md_number_to_chars (buffer, disp, 2);	    buffer[0] = (buffer[0] & 0x07) | t0;	  }	fragP->fr_fix += 2;      }      break;    case C (COND_JUMP, DISP32):    case C (COND_JUMP, UNDEF_WORD_DISP):      {	/* A conditional branch wont fit into 12 bits so:	 *	b!cond	1f	 *	jmpi	0f	 *	.align 2	 * 0:	.long disp	 * 1:	 *	 * if the b!cond is 4 byte aligned, the literal which would	 * go at x+4 will also be aligned.	 */	int first_inst = fragP->fr_fix + fragP->fr_address;	int needpad = (first_inst & 3);	if (! target_big_endian)	  buffer[1] ^= 0x08;	else	  buffer[0] ^= 0x08;	/* Toggle T/F bit */	buffer[2] = INST_BYTE0 (MCORE_INST_JMPI);	/* Build jmpi */	buffer[3] = INST_BYTE1 (MCORE_INST_JMPI);	if (needpad)	  {	    if (! target_big_endian)	      {		buffer[0] = 4;	/* branch over jmpi, pad, and ptr */		buffer[2] = 1;	/* jmpi offset of 1 gets the pointer */	      }	    else	      {		buffer[1] = 4;	/* branch over jmpi, pad, and ptr */		buffer[3] = 1;	/* jmpi offset of 1 gets the pointer */	      }	    buffer[4] = 0;	/* alignment/pad */	    buffer[5] = 0;	    buffer[6] = 0;	/* space for 32 bit address */	    buffer[7] = 0;	    buffer[8] = 0;	    buffer[9] = 0;	    /* Make reloc for the long disp */	    fix_new (fragP, fragP->fr_fix + 6, 4,		     fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);	    fragP->fr_fix += C32_LEN;	  }	else	  {	    /* See comment below about this given gas' limitations for	       shrinking the fragment. '3' is the amount of code that	       we inserted here, but '4' is right for the space we reserved	       for this fragment.  */	    if (! target_big_endian)	      {		buffer[0] = 3;	/* branch over jmpi, and ptr */		buffer[2] = 0;	/* jmpi offset of 0 gets the pointer */	      }	    else	      {		buffer[1] = 3;	/* branch over jmpi, and ptr */		buffer[3] = 0;	/* jmpi offset of 0 gets the pointer */	      }	    buffer[4] = 0;	/* space for 32 bit address */	    buffer[5] = 0;	    buffer[6] = 0;	    buffer[7] = 0;	    /* Make reloc for the long disp.  */	    fix_new (fragP, fragP->fr_fix + 4, 4,		     fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);	    fragP->fr_fix += C32_LEN;	    /* Frag is actually shorter (see the other side of this ifdef)	       but gas isn't prepared for that.  We have to re-adjust	       the branch displacement so that it goes beyond the	       full length of the fragment, not just what we actually	       filled in.  */	    if (! target_big_endian)	      buffer[0] = 4;	/* jmpi, ptr, and the 'tail pad' */	    else	      buffer[1] = 4;	/* jmpi, ptr, and the 'tail pad' */	  }      }      break;    case C (UNCD_JUMP, DISP32):    case C (UNCD_JUMP, UNDEF_WORD_DISP):      {	/* An unconditional branch will not fit in 12 bits, make code which	   looks like:	  	jmpi	0f	  	.align 2	     0:	.long disp	   we need a pad if "first_inst" is 4 byte aligned.	   [because the natural literal place is x + 2]  */	int first_inst = fragP->fr_fix + fragP->fr_address;	int needpad = !(first_inst & 3);	buffer[0] = INST_BYTE0 (MCORE_INST_JMPI);	/* Build jmpi */	buffer[1] = INST_BYTE1 (MCORE_INST_JMPI);	if (needpad)	  {	    if (! target_big_endian)	      buffer[0] = 1;	/* jmpi offset of 1 since padded */	    else	      buffer[1] = 1;	/* jmpi offset of 1 since padded */	    buffer[2] = 0;	/* alignment */	    buffer[3] = 0;	    buffer[4] = 0;	/* space for 32 bit address */	    buffer[5] = 0;	    buffer[6] = 0;	    buffer[7] = 0;	    /* Make reloc for the long disp.  */	    fix_new (fragP, fragP->fr_fix + 4, 4,		     fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);	    fragP->fr_fix += U32_LEN;	  }	else	  {	    if (! target_big_endian)	      buffer[0] = 0;	/* jmpi offset of 0 if no pad */	    else	      buffer[1] = 0;	/* jmpi offset of 0 if no pad */	    buffer[2] = 0;	/* space for 32 bit address */	    buffer[3] = 0;	    buffer[4] = 0;	    buffer[5] = 0;	    /* Make reloc for the long disp.  */	    fix_new (fragP, fragP->fr_fix + 2, 4,		     fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);	    fragP->fr_fix += U32_LEN;	  }      }      break;    default:      abort ();    }}/* Applies the desired value to the specified location.   Also sets up addends for 'rela' type relocations.  */intmd_apply_fix3 (fixP, valp, segment)     fixS *   fixP;     valueT * valp;     segT     segment;{  char *       buf  = fixP->fx_where + fixP->fx_frag->fr_literal;  char *       file = fixP->fx_file ? fixP->fx_file : _("unknown");  const char * symname;  /* Note: use offsetT because it is signed, valueT is unsigned.  */  offsetT      val  = (offsetT) * valp;  symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");  /* Save this for the addend in the relocation record.  */  fixP->fx_addnumber = val;  /* If the fix is relative to a symbol which is not defined, or not     in the same segment as the fix, we cannot resolve it here.  */  if (fixP->fx_addsy != NULL      && (   ! S_IS_DEFINED (fixP->fx_addsy)	  || (S_GET_SEGMENT (fixP->fx_addsy) != segment)))    {      fixP->fx_done = 0;#ifdef OBJ_ELF      /* For ELF we can just return and let the reloc that will be generated	 take care of everything.  For COFF we still have to insert 'val'	 into the insn since the addend field will be ignored.  */      return 0;#endif    }  else    fixP->fx_done = 1;  switch (fixP->fx_r_type)    {    case BFD_RELOC_MCORE_PCREL_IMM11BY2:     /* second byte of 2 byte opcode */      if ((val & 1) != 0)	as_bad_where (file, fixP->fx_line,		      _("odd distance branch (0x%x bytes)"), val);      val /= 2;      if (((val & ~0x3ff) != 0) && ((val | 0x3ff) != -1))	as_bad_where (file, fixP->fx_line,		      _("pcrel for branch to %s too far (0x%x)"),		      symname, val);      if (target_big_endian)	{	  buf[0] |= ((val >> 8) & 0x7);	  buf[1] |= (val & 0xff);	}      else	{	  buf[1] |= ((val >> 8) & 0x7);	  buf[0] |= (val & 0xff);	}      break;    case BFD_RELOC_MCORE_PCREL_IMM8BY4:	/* lower 8 bits of 2 byte opcode */      val += 3;      val /= 4;      if (val & ~0xff)	as_bad_where (file, fixP->fx_line,		      _("pcrel for lrw/jmpi/jsri to %s too far (0x%x)"),		      symname, val);      else if (! target_big_endian)	buf[0] |= (val & 0xff);      else	buf[1] |= (val & 0xff);      break;    case BFD_RELOC_MCORE_PCREL_IMM4BY2:	/* loopt instruction */      if ((val < -32) || (val > -2))	as_bad_where (file, fixP->fx_line,		      _("pcrel for loopt too far (0x%x)"), val);      val /= 2;      if (! target_big_endian)	buf[0] |= (val & 0xf);      else	buf[1] |= (val & 0xf);      break;    case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2:      /* Conditional linker map jsri to bsr.  */      /* If its a local target and close enough, fix it.         NB: >= -2k for backwards bsr; < 2k for forwards...  */      if (fixP->fx_addsy == 0 && val >= -2048  && val < 2048)	{	  long nval = (val / 2) & 0x7ff;	  nval |= MCORE_INST_BSR;	  /* REPLACE the instruction, don't just modify it.  */	  buf[0] = INST_BYTE0 (nval);	  buf[1] = INST_BYTE1 (nval);	}      else	fixP->fx_done = 0;      break;    case BFD_RELOC_MCORE_PCREL_32:    case BFD_RELOC_VTABLE_INHERIT:    case BFD_RELOC_VTABLE_ENTRY:      fixP->fx_done = 0;      break;    default:      if (fixP->fx_addsy != NULL)	{	  /* If the fix is an absolute reloc based on a symbol's	     address, then it cannot be resolved until the final link.  */	  fixP->fx_done = 0;	}#ifdef OBJ_ELF      else#endif	{	  if (fixP->fx_size == 4)	    ;	  else if (fixP->fx_size == 2 && val >= -32768 && val <= 32767)	    ;	  else if (fixP->fx_size == 1 && val >= -256 && val <= 255)	    ;	  else	    abort ();	  md_number_to_chars (buf, val, fixP->fx_size);	}      break;    }  return 0; /* Return value is ignored.  */}voidmd_operand (expressionP)     expressionS * expressionP;{  /* Ignore leading hash symbol, if poresent.  */  if (* input_line_pointer == '#')    {      input_line_pointer ++;      expression (expressionP);    }}int md_long_jump_size;/* 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;{  switch (fragP->fr_subtype)    {    default:      abort ();    case C (UNCD_JUMP, UNDEF_DISP):      /* Used to be a branch to somewhere which was unknown.  */      if (!fragP->fr_symbol)	{	  fragP->fr_subtype = C (UNCD_JUMP, DISP12);	}      else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)	{	  fragP->fr_subtype = C (UNCD_JUMP, DISP12);	}      else	{	  fragP->fr_subtype = C (UNCD_JUMP, UNDEF_WORD_DISP);	}      break;    case C (COND_JUMP, UNDEF_DISP):      /* Used to be a branch to somewhere which was unknown.  */      if (fragP->fr_symbol	  && 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 (COND_JUMP, DISP12);	}      else if (fragP->fr_symbol)	{	  /* Its got a segment, but its not ours, so it will always be long.  */	  fragP->fr_subtype = C (COND_JUMP, UNDEF_WORD_DISP);	}      else	{	  /* We know the abs value.  */	  fragP->fr_subtype = C (COND_JUMP, DISP12);	}      break;    case C (UNCD_JUMP, DISP12):    case C (UNCD_JUMP, DISP32):    case C (UNCD_JUMP, UNDEF_WORD_DISP):    case C (COND_JUMP, DISP12):    case C (COND_JUMP, DISP32):    case C (COND_JUMP, UNDEF_WORD_DISP):      /* When relaxing a section for the second time, we don't need to	 do anything besides return the current size.  */      break;    }  return md_relax_table[fragP->fr_subtype].rlx_length;}/* Put number into target byte order.  */voidmd_number_to_chars (ptr, use, nbytes)     char * ptr;     valueT use;     int nbytes;{  if (! target_big_endian)    switch (nbytes)      {      case 4: ptr[3] = (use >> 24) & 0xff; /* fall through */      case 3: ptr[2] = (use >> 16) & 0xff; /* fall through */      case 2: ptr[1] = (use >>  8) & 0xff; /* fall through */      case 1: ptr[0] = (use >>  0) & 0xff;    break;      default: abort ();      }  else    switch (nbytes)      {      case 4: *ptr++ = (use >> 24) & 0xff; /* fall through */      case 3: *ptr++ = (use >> 16) & 0xff; /* fall through */      case 2: *ptr++ = (use >>  8) & 0xff; /* fall through */      case 1: *ptr++ = (use >>  0) & 0xff;    break;      default: abort ();      }}/* Round up a section size to the appropriate boundary.  */valueTmd_section_align (segment, size)     segT segment;     valueT size;{  return size;			/* Byte alignment is fine */}/* The location from which a PC relative jump should be calculated,   given a PC relative reloc.  */longmd_pcrel_from_section (fixp, sec)     fixS * fixp;     segT sec;{#ifdef OBJ_ELF  /* If the symbol is undefined or defined in another section     we leave the add number alone for the linker to fix it later.     Only account for the PC pre-bump (which is 2 bytes on the MCore).  */  if (fixp->fx_addsy != (symbolS *) NULL      && (! S_IS_DEFINED (fixp->fx_addsy)	  || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))  {    assert (fixp->fx_size == 2);	/* must be an insn */    return fixp->fx_size;  }#endif  /* The case where we are going to resolve things...  */  return  fixp->fx_size + fixp->fx_where + fixp->fx_frag->fr_address;}#define F(SZ,PCREL)		(((SZ) << 1) + (PCREL))#define MAP(SZ,PCREL,TYPE)	case F (SZ, PCREL): code = (TYPE); breakarelent *tc_gen_reloc (section, fixp)     asection * section;     fixS * fixp;{  arelent * rel;  bfd_reloc_code_real_type code;  int handled = 0;  switch (fixp->fx_r_type)    {      /* These confuse the size/pcrel macro approach.  */    case BFD_RELOC_VTABLE_INHERIT:    case BFD_RELOC_VTABLE_ENTRY:    case BFD_RELOC_MCORE_PCREL_IMM4BY2:    case BFD_RELOC_MCORE_PCREL_IMM8BY4:    case BFD_RELOC_MCORE_PCREL_IMM11BY2:    case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2:    case BFD_RELOC_RVA:      code = fixp->fx_r_type;      break;    default:      switch (F (fixp->fx_size, fixp->fx_pcrel))        {          MAP (1, 0, BFD_RELOC_8);          MAP (2, 0, BFD_RELOC_16);          MAP (4, 0, BFD_RELOC_32);          MAP (1, 1, BFD_RELOC_8_PCREL);          MAP (2, 1, BFD_RELOC_16_PCREL);          MAP (4, 1, BFD_RELOC_32_PCREL);        default:	  code = fixp->fx_r_type;          as_bad (_("Can not do %d byte %srelocation"),		  fixp->fx_size,	          fixp->fx_pcrel ? _("pc-relative") : "");        }      break;  }  rel = (arelent *) xmalloc (sizeof (arelent));  rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));  *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);  rel->address = fixp->fx_frag->fr_address + fixp->fx_where;  /* Always pass the addend along!  */  rel->addend = fixp->fx_addnumber;  rel->howto = bfd_reloc_type_lookup (stdoutput, code);  if (rel->howto == NULL)    {      as_bad_where (fixp->fx_file, fixp->fx_line,                    _("Cannot represent relocation type %s"),                    bfd_get_reloc_code_name (code));      /* Set howto to a garbage value so that we can keep going.  */      rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);      assert (rel->howto != NULL);    }  return rel;}#ifdef OBJ_ELF/* See whether we need to force a relocation into the output file.   This is used to force out switch and PC relative relocations when   relaxing.  */intmcore_force_relocation (fix)     fixS * fix;{  if (   fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT      || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY      || fix->fx_r_type == BFD_RELOC_RVA)    return 1;  return 0;}/* Return true if the fix can be handled by GAS, false if it must   be passed through to the linker.  */booleanmcore_fix_adjustable (fixP)   fixS * fixP;{  if (fixP->fx_addsy == NULL)    return 1;  /* We need the symbol name for the VTABLE entries.  */  if (   fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT      || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)    return 0;  return 1;}#endif /* OBJ_ELF */

⌨️ 快捷键说明

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