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

📄 tc-m32r.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 4 页
字号:
      fragP->fr_opcode[0] |= 0x80;      /* Increase known (fixed) size of fragment.  */      fragP->fr_fix += 2;      /* Create a relocation for it.  */      fix_new (fragP, old_fr_fix, 4,	       fragP->fr_symbol,	       fragP->fr_offset, 1 /* pcrel  */,	       /* FIXME: Can't use a real BFD reloc here.		  gas_cgen_md_apply_fix3 can't handle it.  */	       BFD_RELOC_M32R_26_PCREL);      /* Mark this fragment as finished.  */      frag_wane (fragP);      return fragP->fr_fix - old_fr_fix;#else      {	const CGEN_INSN *insn;	int i;	/* Update the recorded insn.	   Fortunately we don't have to look very far.	   FIXME: Change this to record in the instruction the next higher	   relaxable insn to use.  */	for (i = 0, insn = fragP->fr_cgen.insn; i < 4; i++, insn++)	  {	    if ((strcmp (CGEN_INSN_MNEMONIC (insn),			 CGEN_INSN_MNEMONIC (fragP->fr_cgen.insn))		 == 0)		&& CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX))	      break;	  }	if (i == 4)	  abort ();	fragP->fr_cgen.insn = insn;	return 2;      }#endif    }  return md_relax_table[fragP->fr_subtype].rlx_length;}/* *FRAGP has been relaxed to its final size, and now needs to have   the bytes inside it modified to conform to the new size.   Called after relaxation is finished.   fragP->fr_type == rs_machine_dependent.   fragP->fr_subtype is the subtype of what the address relaxed to.  */voidmd_convert_frag (abfd, sec, fragP)     bfd *abfd;     segT sec;     fragS *fragP;{  char *opcode;  char *displacement;  int target_address;  int opcode_address;  int extension;  int addend;  opcode = fragP->fr_opcode;  /* Address opcode resides at in file space.  */  opcode_address = fragP->fr_address + fragP->fr_fix - 2;  switch (fragP->fr_subtype)    {    case 1:      extension = 0;      displacement = &opcode[1];      break;    case 2:      opcode[0] |= 0x80;      extension = 2;      displacement = &opcode[1];      break;    case 3:      opcode[2] = opcode[0] | 0x80;      md_number_to_chars (opcode, PAR_NOP_INSN, 2);      opcode_address += 2;      extension = 4;      displacement = &opcode[3];      break;    default:      abort ();    }  if (S_GET_SEGMENT (fragP->fr_symbol) != sec)    {      /* Symbol must be resolved by linker.  */      if (fragP->fr_offset & 3)	as_warn (_("Addend to unresolved symbol not on word boundary."));      addend = fragP->fr_offset >> 2;    }  else    {      /* Address we want to reach in file space.  */      target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;      target_address += symbol_get_frag (fragP->fr_symbol)->fr_address;      addend = (target_address - (opcode_address & -4)) >> 2;    }  /* Create a relocation for symbols that must be resolved by the linker.     Otherwise output the completed insn.  */  if (S_GET_SEGMENT (fragP->fr_symbol) != sec)    {      assert (fragP->fr_subtype != 1);      assert (fragP->fr_cgen.insn != 0);      gas_cgen_record_fixup (fragP,			     /* Offset of branch insn in frag.  */			     fragP->fr_fix + extension - 4,			     fragP->fr_cgen.insn,			     4 /* Length.  */,			     /* FIXME: quick hack.  */#if 0			     cgen_operand_lookup_by_num (gas_cgen_cpu_desc,							 fragP->fr_cgen.opindex),#else			     cgen_operand_lookup_by_num (gas_cgen_cpu_desc,							 M32R_OPERAND_DISP24),#endif			     fragP->fr_cgen.opinfo,			     fragP->fr_symbol, fragP->fr_offset);    }#define SIZE_FROM_RELAX_STATE(n) ((n) == 1 ? 1 : 3)  md_number_to_chars (displacement, (valueT) addend,		      SIZE_FROM_RELAX_STATE (fragP->fr_subtype));  fragP->fr_fix += extension;}/* Functions concerning relocs.  *//* 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;{  if (fixP->fx_addsy != (symbolS *) NULL      && (! S_IS_DEFINED (fixP->fx_addsy)	  || S_GET_SEGMENT (fixP->fx_addsy) != sec))    {      /* The symbol is undefined (or is defined but not in this section).	 Let the linker figure it out.  */      return 0;    }  return (fixP->fx_frag->fr_address + fixP->fx_where) & -4L;}/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.   Returns BFD_RELOC_NONE if no reloc type can be found.   *FIXP may be modified if desired.  */bfd_reloc_code_real_typemd_cgen_lookup_reloc (insn, operand, fixP)     const CGEN_INSN *insn;     const CGEN_OPERAND *operand;     fixS *fixP;{  switch (operand->type)    {    case M32R_OPERAND_DISP8:  return BFD_RELOC_M32R_10_PCREL;    case M32R_OPERAND_DISP16: return BFD_RELOC_M32R_18_PCREL;    case M32R_OPERAND_DISP24: return BFD_RELOC_M32R_26_PCREL;    case M32R_OPERAND_UIMM24: return BFD_RELOC_M32R_24;    case M32R_OPERAND_HI16:    case M32R_OPERAND_SLO16:    case M32R_OPERAND_ULO16:      /* If low/high/shigh/sda was used, it is recorded in `opinfo'.  */      if (fixP->fx_cgen.opinfo != 0)	return fixP->fx_cgen.opinfo;      break;    default:      /* Avoid -Wall warning.  */      break;    }  return BFD_RELOC_NONE;}/* Record a HI16 reloc for later matching with its LO16 cousin.  */static voidm32r_record_hi16 (reloc_type, fixP, seg)     int reloc_type;     fixS *fixP;     segT seg;{  struct m32r_hi_fixup *hi_fixup;  assert (reloc_type == BFD_RELOC_M32R_HI16_SLO	  || reloc_type == BFD_RELOC_M32R_HI16_ULO);  hi_fixup = ((struct m32r_hi_fixup *)	      xmalloc (sizeof (struct m32r_hi_fixup)));  hi_fixup->fixp = fixP;  hi_fixup->seg  = now_seg;  hi_fixup->next = m32r_hi_fixup_list;  m32r_hi_fixup_list = hi_fixup;}/* Called while parsing an instruction to create a fixup.   We need to check for HI16 relocs and queue them up for later sorting.  */fixS *m32r_cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp)     fragS *frag;     int where;     const CGEN_INSN *insn;     int length;     const CGEN_OPERAND *operand;     int opinfo;     expressionS *exp;{  fixS *fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,					  operand, opinfo, exp);  switch (operand->type)    {    case M32R_OPERAND_HI16:      /* If low/high/shigh/sda was used, it is recorded in `opinfo'.  */      if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_SLO	  || fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_ULO)	m32r_record_hi16 (fixP->fx_cgen.opinfo, fixP, now_seg);      break;    default:      /* Avoid -Wall warning */      break;    }  return fixP;}/* Return BFD reloc type from opinfo field in a fixS.   It's tricky using fx_r_type in m32r_frob_file because the values   are BFD_RELOC_UNUSED + operand number.  */#define FX_OPINFO_R_TYPE(f) ((f)->fx_cgen.opinfo)/* Sort any unmatched HI16 relocs so that they immediately precede   the corresponding LO16 reloc.  This is called before md_apply_fix and   tc_gen_reloc.  */voidm32r_frob_file (){  struct m32r_hi_fixup *l;  for (l = m32r_hi_fixup_list; l != NULL; l = l->next)    {      segment_info_type *seginfo;      int pass;      assert (FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_M32R_HI16_SLO	      || FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_M32R_HI16_ULO);      /* Check quickly whether the next fixup happens to be a matching low.  */      if (l->fixp->fx_next != NULL	  && FX_OPINFO_R_TYPE (l->fixp->fx_next) == BFD_RELOC_M32R_LO16	  && l->fixp->fx_addsy == l->fixp->fx_next->fx_addsy	  && l->fixp->fx_offset == l->fixp->fx_next->fx_offset)	continue;      /* Look through the fixups for this segment for a matching `low'.         When we find one, move the high/shigh just in front of it.  We do         this in two passes.  In the first pass, we try to find a         unique `low'.  In the second pass, we permit multiple high's         relocs for a single `low'.  */      seginfo = seg_info (l->seg);      for (pass = 0; pass < 2; pass++)	{	  fixS *f;	  fixS *prev;	  prev = NULL;	  for (f = seginfo->fix_root; f != NULL; f = f->fx_next)	    {	      /* Check whether this is a `low' fixup which matches l->fixp.  */	      if (FX_OPINFO_R_TYPE (f) == BFD_RELOC_M32R_LO16		  && f->fx_addsy == l->fixp->fx_addsy		  && f->fx_offset == l->fixp->fx_offset		  && (pass == 1		      || prev == NULL		      || (FX_OPINFO_R_TYPE (prev) != BFD_RELOC_M32R_HI16_SLO			  && FX_OPINFO_R_TYPE (prev) != BFD_RELOC_M32R_HI16_ULO)		      || prev->fx_addsy != f->fx_addsy		      || prev->fx_offset != f->fx_offset))		{		  fixS **pf;		  /* Move l->fixp before f.  */		  for (pf = &seginfo->fix_root;		       *pf != l->fixp;		       pf = & (*pf)->fx_next)		    assert (*pf != NULL);		  *pf = l->fixp->fx_next;		  l->fixp->fx_next = f;		  if (prev == NULL)		    seginfo->fix_root = l->fixp;		  else		    prev->fx_next = l->fixp;		  break;		}	      prev = f;	    }	  if (f != NULL)	    break;	  if (pass == 1	      && warn_unmatched_high)	    as_warn_where (l->fixp->fx_file, l->fixp->fx_line,			   _("Unmatched high/shigh reloc"));	}    }}/* 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.  */intm32r_force_relocation (fix)     fixS *fix;{  if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT      || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY)    return 1;  if (! m32r_relax)    return 0;  return fix->fx_pcrel;}/* Write a value out to the object file, using the appropriate endianness.  */voidmd_number_to_chars (buf, val, n)     char *buf;     valueT val;     int n;{  if (target_big_endian)    number_to_chars_bigendian (buf, val, n);  else    number_to_chars_littleendian (buf, val, n);}/* 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.  *//* Equal to MAX_PRECISION in atof-ieee.c.  */#define MAX_LITTLENUMS 6char *md_atof (type, litP, sizeP)     char type;     char *litP;     int *sizeP;{  int i;  int prec;  LITTLENUM_TYPE words[MAX_LITTLENUMS];  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;      /* FIXME: Some targets allow other format chars for bigger sizes         here.  */    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);  if (target_big_endian)    {      for (i = 0; i < prec; i++)	{	  md_number_to_chars (litP, (valueT) words[i],			      sizeof (LITTLENUM_TYPE));	  litP += sizeof (LITTLENUM_TYPE);	}    }  else    {      for (i = prec - 1; i >= 0; i--)	{	  md_number_to_chars (litP, (valueT) words[i],			      sizeof (LITTLENUM_TYPE));	  litP += sizeof (LITTLENUM_TYPE);	}    }  return 0;}voidm32r_elf_section_change_hook (){  /* If we have reached the end of a section and we have just emitted a     16 bit insn, then emit a nop to make sure that the section ends on     a 32 bit boundary.  */  if (prev_insn.insn || seen_relaxable_p)    (void) m32r_fill_insn (0);}/* Return true if can adjust the reloc to be relative to its section   (such as .data) instead of relative to some symbol.  */booleanm32r_fix_adjustable (fixP)   fixS *fixP;{  bfd_reloc_code_real_type reloc_type;  if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)    {      const CGEN_INSN *insn = NULL;      int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;      const CGEN_OPERAND *operand =	cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);      reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);    }  else    reloc_type = fixP->fx_r_type;  if (fixP->fx_addsy == NULL)    return 1;  /* Prevent all adjustments to global symbols.  */  if (S_IS_EXTERN (fixP->fx_addsy))    return 0;  if (S_IS_WEAK (fixP->fx_addsy))    return 0;  /* We need the symbol name for the VTABLE entries.  */  if (reloc_type == BFD_RELOC_VTABLE_INHERIT      || reloc_type == BFD_RELOC_VTABLE_ENTRY)    return 0;  return 1;}

⌨️ 快捷键说明

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