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

📄 tc-ppc.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
	 whitespace.  */      if (*str != endc	  && (endc != ',' || *str != '\0'))	{	  as_bad (_("syntax error; found `%c' but expected `%c'"), *str, endc);	  break;	}      if (*str != '\0')	++str;    }  while (isspace (*str))    ++str;  if (*str != '\0')    as_bad (_("junk at end of line: `%s'"), str);  /* Write out the instruction.  */  f = frag_more (4);  md_number_to_chars (f, insn, 4);#ifdef OBJ_ELF  dwarf2_emit_insn (4);#endif  /* Create any fixups.  At this point we do not use a     bfd_reloc_code_real_type, but instead just use the     BFD_RELOC_UNUSED plus the operand index.  This lets us easily     handle fixups for any operand type, although that is admittedly     not a very exciting feature.  We pick a BFD reloc type in     md_apply_fix.  */  for (i = 0; i < fc; i++)    {      const struct powerpc_operand *operand;      operand = &powerpc_operands[fixups[i].opindex];      if (fixups[i].reloc != BFD_RELOC_UNUSED)	{	  reloc_howto_type *reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);	  int size;	  int offset;	  fixS *fixP;	  if (!reloc_howto)	    abort ();	  size = bfd_get_reloc_size (reloc_howto);	  offset = target_big_endian ? (4 - size) : 0;	  if (size < 1 || size > 4)	    abort ();	  fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset, size,			      &fixups[i].exp, reloc_howto->pc_relative,			      fixups[i].reloc);	  /* Turn off complaints that the addend is too large for things like	     foo+100000@ha.  */	  switch (fixups[i].reloc)	    {	    case BFD_RELOC_16_GOTOFF:	    case BFD_RELOC_PPC_TOC16:	    case BFD_RELOC_LO16:	    case BFD_RELOC_HI16:	    case BFD_RELOC_HI16_S:	      fixP->fx_no_overflow = 1;	      break;	    default:	      break;	    }	}      else	fix_new_exp (frag_now, f - frag_now->fr_literal, 4,		     &fixups[i].exp,		     (operand->flags & PPC_OPERAND_RELATIVE) != 0,		     ((bfd_reloc_code_real_type)		       (fixups[i].opindex + (int) BFD_RELOC_UNUSED)));    }}/* Handle a macro.  Gather all the operands, transform them as   described by the macro, and call md_assemble recursively.  All the   operands are separated by commas; we don't accept parentheses   around operands here.  */static voidppc_macro (str, macro)     char *str;     const struct powerpc_macro *macro;{  char *operands[10];  unsigned int count;  char *s;  unsigned int len;  const char *format;  int arg;  char *send;  char *complete;  /* Gather the users operands into the operands array.  */  count = 0;  s = str;  while (1)    {      if (count >= sizeof operands / sizeof operands[0])	break;      operands[count++] = s;      s = strchr (s, ',');      if (s == (char *) NULL)	break;      *s++ = '\0';    }  if (count != macro->operands)    {      as_bad (_("wrong number of operands"));      return;    }  /* Work out how large the string must be (the size is unbounded     because it includes user input).  */  len = 0;  format = macro->format;  while (*format != '\0')    {      if (*format != '%')	{	  ++len;	  ++format;	}      else	{	  arg = strtol (format + 1, &send, 10);	  know (send != format && arg >= 0 && arg < count);	  len += strlen (operands[arg]);	  format = send;	}    }  /* Put the string together.  */  complete = s = (char *) alloca (len + 1);  format = macro->format;  while (*format != '\0')    {      if (*format != '%')	*s++ = *format++;      else	{	  arg = strtol (format + 1, &send, 10);	  strcpy (s, operands[arg]);	  s += strlen (s);	  format = send;	}    }  *s = '\0';  /* Assemble the constructed instruction.  */  md_assemble (complete);}#ifdef OBJ_ELF/* For ELF, add support for SHF_EXCLUDE and SHT_ORDERED */intppc_section_letter (letter, ptr_msg)     int letter;     char **ptr_msg;{  if (letter == 'e')    return SHF_EXCLUDE;  *ptr_msg = _("Bad .section directive: want a,w,x,e in string");  return 0;}intppc_section_word (str, len)     char *str;     size_t len;{  if (len == 7 && strncmp (str, "exclude", 7) == 0)    return SHF_EXCLUDE;  return -1;}intppc_section_type (str, len)     char *str;     size_t len;{  if (len == 7 && strncmp (str, "ordered", 7) == 0)    return SHT_ORDERED;  return -1;}intppc_section_flags (flags, attr, type)     int flags;     int attr;     int type;{  if (type == SHT_ORDERED)    flags |= SEC_ALLOC | SEC_LOAD | SEC_SORT_ENTRIES;  if (attr & SHF_EXCLUDE)    flags |= SEC_EXCLUDE;  return flags;}#endif /* OBJ_ELF *//* Pseudo-op handling.  *//* The .byte pseudo-op.  This is similar to the normal .byte   pseudo-op, but it can also take a single ASCII string.  */static voidppc_byte (ignore)     int ignore ATTRIBUTE_UNUSED;{  if (*input_line_pointer != '\"')    {      cons (1);      return;    }  /* Gather characters.  A real double quote is doubled.  Unusual     characters are not permitted.  */  ++input_line_pointer;  while (1)    {      char c;      c = *input_line_pointer++;      if (c == '\"')	{	  if (*input_line_pointer != '\"')	    break;	  ++input_line_pointer;	}      FRAG_APPEND_1_CHAR (c);    }  demand_empty_rest_of_line ();}#ifdef OBJ_XCOFF/* XCOFF specific pseudo-op handling.  *//* This is set if we are creating a .stabx symbol, since we don't want   to handle symbol suffixes for such symbols.  */static boolean ppc_stab_symbol;/* The .comm and .lcomm pseudo-ops for XCOFF.  XCOFF puts common   symbols in the .bss segment as though they were local common   symbols, and uses a different smclas.  */static voidppc_comm (lcomm)     int lcomm;{  asection *current_seg = now_seg;  subsegT current_subseg = now_subseg;  char *name;  char endc;  char *end_name;  offsetT size;  offsetT align;  symbolS *lcomm_sym = NULL;  symbolS *sym;  char *pfrag;  name = input_line_pointer;  endc = get_symbol_end ();  end_name = input_line_pointer;  *end_name = endc;  if (*input_line_pointer != ',')    {      as_bad (_("missing size"));      ignore_rest_of_line ();      return;    }  ++input_line_pointer;  size = get_absolute_expression ();  if (size < 0)    {      as_bad (_("negative size"));      ignore_rest_of_line ();      return;    }  if (! lcomm)    {      /* The third argument to .comm is the alignment.  */      if (*input_line_pointer != ',')	align = 3;      else	{	  ++input_line_pointer;	  align = get_absolute_expression ();	  if (align <= 0)	    {	      as_warn (_("ignoring bad alignment"));	      align = 3;	    }	}    }  else    {      char *lcomm_name;      char lcomm_endc;      if (size <= 1)	align = 0;      else if (size <= 2)	align = 1;      else if (size <= 4)	align = 2;      else	align = 3;      /* The third argument to .lcomm appears to be the real local	 common symbol to create.  References to the symbol named in	 the first argument are turned into references to the third	 argument.  */      if (*input_line_pointer != ',')	{	  as_bad (_("missing real symbol name"));	  ignore_rest_of_line ();	  return;	}      ++input_line_pointer;      lcomm_name = input_line_pointer;      lcomm_endc = get_symbol_end ();      lcomm_sym = symbol_find_or_make (lcomm_name);      *input_line_pointer = lcomm_endc;    }  *end_name = '\0';  sym = symbol_find_or_make (name);  *end_name = endc;  if (S_IS_DEFINED (sym)      || S_GET_VALUE (sym) != 0)    {      as_bad (_("attempt to redefine symbol"));      ignore_rest_of_line ();      return;    }  record_alignment (bss_section, align);  if (! lcomm      || ! S_IS_DEFINED (lcomm_sym))    {      symbolS *def_sym;      offsetT def_size;      if (! lcomm)	{	  def_sym = sym;	  def_size = size;	  S_SET_EXTERNAL (sym);	}      else	{	  symbol_get_tc (lcomm_sym)->output = 1;	  def_sym = lcomm_sym;	  def_size = 0;	}      subseg_set (bss_section, 1);      frag_align (align, 0, 0);      symbol_set_frag (def_sym, frag_now);      pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, def_sym,			def_size, (char *) NULL);      *pfrag = 0;      S_SET_SEGMENT (def_sym, bss_section);      symbol_get_tc (def_sym)->align = align;    }  else if (lcomm)    {      /* Align the size of lcomm_sym.  */      symbol_get_frag (lcomm_sym)->fr_offset =	((symbol_get_frag (lcomm_sym)->fr_offset + (1 << align) - 1)	 &~ ((1 << align) - 1));      if (align > symbol_get_tc (lcomm_sym)->align)	symbol_get_tc (lcomm_sym)->align = align;    }  if (lcomm)    {      /* Make sym an offset from lcomm_sym.  */      S_SET_SEGMENT (sym, bss_section);      symbol_set_frag (sym, symbol_get_frag (lcomm_sym));      S_SET_VALUE (sym, symbol_get_frag (lcomm_sym)->fr_offset);      symbol_get_frag (lcomm_sym)->fr_offset += size;    }  subseg_set (current_seg, current_subseg);  demand_empty_rest_of_line ();}/* The .csect pseudo-op.  This switches us into a different   subsegment.  The first argument is a symbol whose value is the   start of the .csect.  In COFF, csect symbols get special aux   entries defined by the x_csect field of union internal_auxent.  The   optional second argument is the alignment (the default is 2).  */static voidppc_csect (ignore)     int ignore ATTRIBUTE_UNUSED;{  char *name;  char endc;  symbolS *sym;  name = input_line_pointer;  endc = get_symbol_end ();  sym = symbol_find_or_make (name);  *input_line_pointer = endc;  if (S_GET_NAME (sym)[0] == '\0')    {      /* An unnamed csect is assumed to be [PR].  */      symbol_get_tc (sym)->class = XMC_PR;    }  ppc_change_csect (sym);  if (*input_line_pointer == ',')    {      ++input_line_pointer;      symbol_get_tc (sym)->align = get_absolute_expression ();    }  demand_empty_rest_of_line ();}/* Change to a different csect.  */static voidppc_change_csect (sym)     symbolS *sym;{  if (S_IS_DEFINED (sym))    subseg_set (S_GET_SEGMENT (sym), symbol_get_tc (sym)->subseg);  else    {      symbolS **list_ptr;      int after_toc;      int hold_chunksize;      symbolS *list;      /* This is a new csect.  We need to look at the symbol class to	 figure out whether it should go in the text section or the	 data section.  */      after_toc = 0;      switch (symbol_get_tc (sym)->class)	{	case XMC_PR:	case XMC_RO:	case XMC_DB:	case XMC_GL:	case XMC_XO:	case XMC_SV:	case XMC_TI:	case XMC_TB:	  S_SET_SEGMENT (sym, text_section);	  symbol_get_tc (sym)->subseg = ppc_text_subsegment;	  ++ppc_text_subsegment;	  list_ptr = &ppc_text_csects;	  break;	case XMC_RW:	case XMC_TC0:	case XMC_TC:	case XMC_DS:	case XMC_UA:	case XMC_BS:	case XMC_UC:	  if (ppc_toc_csect != NULL	      && (symbol_get_tc (ppc_toc_csect)->subseg + 1		  == ppc_data_subsegment))	    after_toc = 1;	  S_SET_SEGMENT (sym, data_section);	  symbol_get_tc (sym)->subseg = ppc_data_subsegment;	  ++ppc_data_subsegment;	  list_ptr = &ppc_data_csects;	  break;	default:	  abort ();	}      /* We set the obstack chunk size to a small value before         changing subsegments, so that we don't use a lot of memory         space for what may be a small section.  */      hold_chunksize = chunksize;      chunksize = 64;      subseg_new 

⌨️ 快捷键说明

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