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

📄 tc-ppc.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
unsigned longppc_mach (){  return (ppc_size == PPC_OPCODE_64) ? 620 : 0;}intppc_subseg_align(){  return (ppc_xcoff64) ? 3 : 2;}extern char*ppc_target_format(){#ifdef OBJ_COFF#ifdef TE_PE  return (target_big_endian ? "pe-powerpc" : "pe-powerpcle");#elif TE_POWERMAC#else  return (ppc_xcoff64 ? "aixcoff64-rs6000" : "aixcoff-rs6000");#endif#ifdef TE_POWERMAC  return "xcoff-powermac";#endif#endif#ifdef OBJ_ELF  return (target_big_endian ? "elf32-powerpc" : "elf32-powerpcle");#endif}/* This function is called when the assembler starts up.  It is called   after the options have been parsed and the output file has been   opened.  */voidmd_begin (){  register const struct powerpc_opcode *op;  const struct powerpc_opcode *op_end;  const struct powerpc_macro *macro;  const struct powerpc_macro *macro_end;  boolean dup_insn = false;  ppc_set_cpu ();#ifdef OBJ_ELF  /* Set the ELF flags if desired.  */  if (ppc_flags && !msolaris)    bfd_set_private_flags (stdoutput, ppc_flags);#endif  /* Insert the opcodes into a hash table.  */  ppc_hash = hash_new ();  op_end = powerpc_opcodes + powerpc_num_opcodes;  for (op = powerpc_opcodes; op < op_end; op++)    {      know ((op->opcode & op->mask) == op->opcode);      if ((op->flags & ppc_cpu) != 0	  && ((op->flags & (PPC_OPCODE_32 | PPC_OPCODE_64)) == 0	      || (op->flags & (PPC_OPCODE_32 | PPC_OPCODE_64)) == ppc_size	      || (ppc_cpu & PPC_OPCODE_64_BRIDGE) != 0))	{	  const char *retval;	  retval = hash_insert (ppc_hash, op->name, (PTR) op);	  if (retval != (const char *) NULL)	    {	      /* Ignore Power duplicates for -m601 */	      if ((ppc_cpu & PPC_OPCODE_601) != 0		  && (op->flags & PPC_OPCODE_POWER) != 0)		continue;	      as_bad (_("Internal assembler error for instruction %s"), op->name);	      dup_insn = true;	    }	}    }  /* Insert the macros into a hash table.  */  ppc_macro_hash = hash_new ();  macro_end = powerpc_macros + powerpc_num_macros;  for (macro = powerpc_macros; macro < macro_end; macro++)    {      if ((macro->flags & ppc_cpu) != 0)	{	  const char *retval;	  retval = hash_insert (ppc_macro_hash, macro->name, (PTR) macro);	  if (retval != (const char *) NULL)	    {	      as_bad (_("Internal assembler error for macro %s"), macro->name);	      dup_insn = true;	    }	}    }  if (dup_insn)    abort ();  /* Tell the main code what the endianness is if it is not overidden by the user.  */  if (!set_target_endian)    {      set_target_endian = 1;      target_big_endian = PPC_BIG_ENDIAN;    }#ifdef OBJ_XCOFF  ppc_coff_debug_section = coff_section_from_bfd_index (stdoutput, N_DEBUG);  /* Create dummy symbols to serve as initial csects.  This forces the     text csects to precede the data csects.  These symbols will not     be output.  */  ppc_text_csects = symbol_make ("dummy\001");  symbol_get_tc (ppc_text_csects)->within = ppc_text_csects;  ppc_data_csects = symbol_make ("dummy\001");  symbol_get_tc (ppc_data_csects)->within = ppc_data_csects;#endif#ifdef TE_PE  ppc_current_section = text_section;  ppc_previous_section = 0;#endif}/* Insert an operand value into an instruction.  */static unsigned longppc_insert_operand (insn, operand, val, file, line)     unsigned long insn;     const struct powerpc_operand *operand;     offsetT val;     char *file;     unsigned int line;{  if (operand->bits != 32)    {      long min, max;      offsetT test;      if ((operand->flags & PPC_OPERAND_SIGNED) != 0)	{	  if ((operand->flags & PPC_OPERAND_SIGNOPT) != 0)	    max = (1 << operand->bits) - 1;	  else	    max = (1 << (operand->bits - 1)) - 1;	  min = - (1 << (operand->bits - 1));	  if (ppc_size == PPC_OPCODE_32)	    {	      /* Some people write 32 bit hex constants with the sign		 extension done by hand.  This shouldn't really be		 valid, but, to permit this code to assemble on a 64		 bit host, we sign extend the 32 bit value.  */	      if (val > 0		  && (val & (offsetT) 0x80000000) != 0		  && (val & (offsetT) 0xffffffff) == val)		{		  val -= 0x80000000;		  val -= 0x80000000;		}	    }	}      else	{	  max = (1 << operand->bits) - 1;	  min = 0;	}      if ((operand->flags & PPC_OPERAND_NEGATIVE) != 0)	test = - val;      else	test = val;      if (test < (offsetT) min || test > (offsetT) max)	{	  const char *err =	    _("operand out of range (%s not between %ld and %ld)");	  char buf[100];	  sprint_value (buf, test);	  if (file == (char *) NULL)	    as_bad (err, buf, min, max);	  else	    as_bad_where (file, line, err, buf, min, max);	}    }  if (operand->insert)    {      const char *errmsg;      errmsg = NULL;      insn = (*operand->insert) (insn, (long) val, &errmsg);      if (errmsg != (const char *) NULL)	as_bad (errmsg);    }  else    insn |= (((long) val & ((1 << operand->bits) - 1))	     << operand->shift);  return insn;}#ifdef OBJ_ELF/* Parse @got, etc. and return the desired relocation.  */static bfd_reloc_code_real_typeppc_elf_suffix (str_p, exp_p)     char **str_p;     expressionS *exp_p;{  struct map_bfd {    char *string;    int length;    bfd_reloc_code_real_type reloc;  };  char ident[20];  char *str = *str_p;  char *str2;  int ch;  int len;  struct map_bfd *ptr;#define MAP(str,reloc) { str, sizeof (str)-1, reloc }  static struct map_bfd mapping[] = {    MAP ("l",		BFD_RELOC_LO16),    MAP ("h",		BFD_RELOC_HI16),    MAP ("ha",		BFD_RELOC_HI16_S),    MAP ("brtaken",	BFD_RELOC_PPC_B16_BRTAKEN),    MAP ("brntaken",	BFD_RELOC_PPC_B16_BRNTAKEN),    MAP ("got",		BFD_RELOC_16_GOTOFF),    MAP ("got@l",	BFD_RELOC_LO16_GOTOFF),    MAP ("got@h",	BFD_RELOC_HI16_GOTOFF),    MAP ("got@ha",	BFD_RELOC_HI16_S_GOTOFF),    MAP ("fixup",	BFD_RELOC_CTOR),		/* warnings with -mrelocatable */    MAP ("plt",		BFD_RELOC_24_PLT_PCREL),    MAP ("pltrel24",	BFD_RELOC_24_PLT_PCREL),    MAP ("copy",	BFD_RELOC_PPC_COPY),    MAP ("globdat",	BFD_RELOC_PPC_GLOB_DAT),    MAP ("local24pc",	BFD_RELOC_PPC_LOCAL24PC),    MAP ("local",	BFD_RELOC_PPC_LOCAL24PC),    MAP ("pltrel",	BFD_RELOC_32_PLT_PCREL),    MAP ("plt@l",	BFD_RELOC_LO16_PLTOFF),    MAP ("plt@h",	BFD_RELOC_HI16_PLTOFF),    MAP ("plt@ha",	BFD_RELOC_HI16_S_PLTOFF),    MAP ("sdarel",	BFD_RELOC_GPREL16),    MAP ("sectoff",	BFD_RELOC_32_BASEREL),    MAP ("sectoff@l",	BFD_RELOC_LO16_BASEREL),    MAP ("sectoff@h",	BFD_RELOC_HI16_BASEREL),    MAP ("sectoff@ha",	BFD_RELOC_HI16_S_BASEREL),    MAP ("naddr",	BFD_RELOC_PPC_EMB_NADDR32),    MAP ("naddr16",	BFD_RELOC_PPC_EMB_NADDR16),    MAP ("naddr@l",	BFD_RELOC_PPC_EMB_NADDR16_LO),    MAP ("naddr@h",	BFD_RELOC_PPC_EMB_NADDR16_HI),    MAP ("naddr@ha",	BFD_RELOC_PPC_EMB_NADDR16_HA),    MAP ("sdai16",	BFD_RELOC_PPC_EMB_SDAI16),    MAP ("sda2rel",	BFD_RELOC_PPC_EMB_SDA2REL),    MAP ("sda2i16",	BFD_RELOC_PPC_EMB_SDA2I16),    MAP ("sda21",	BFD_RELOC_PPC_EMB_SDA21),    MAP ("mrkref",	BFD_RELOC_PPC_EMB_MRKREF),    MAP ("relsect",	BFD_RELOC_PPC_EMB_RELSEC16),    MAP ("relsect@l",	BFD_RELOC_PPC_EMB_RELST_LO),    MAP ("relsect@h",	BFD_RELOC_PPC_EMB_RELST_HI),    MAP ("relsect@ha",	BFD_RELOC_PPC_EMB_RELST_HA),    MAP ("bitfld",	BFD_RELOC_PPC_EMB_BIT_FLD),    MAP ("relsda",	BFD_RELOC_PPC_EMB_RELSDA),    MAP ("xgot",	BFD_RELOC_PPC_TOC16),    { (char *)0,	0,	BFD_RELOC_UNUSED }  };  if (*str++ != '@')    return BFD_RELOC_UNUSED;  for (ch = *str, str2 = ident;       (str2 < ident + sizeof (ident) - 1	&& (isalnum (ch) || ch == '@'));       ch = *++str)    {      *str2++ = (islower (ch)) ? ch : tolower (ch);    }  *str2 = '\0';  len = str2 - ident;  ch = ident[0];  for (ptr = &mapping[0]; ptr->length > 0; ptr++)    if (ch == ptr->string[0]	&& len == ptr->length	&& memcmp (ident, ptr->string, ptr->length) == 0)      {	if (exp_p->X_add_number != 0	    && (ptr->reloc == BFD_RELOC_16_GOTOFF		|| ptr->reloc == BFD_RELOC_LO16_GOTOFF		|| ptr->reloc == BFD_RELOC_HI16_GOTOFF		|| ptr->reloc == BFD_RELOC_HI16_S_GOTOFF))	  as_warn (_("identifier+constant@got means identifier@got+constant"));	/* Now check for identifier@suffix+constant */	if (*str == '-' || *str == '+')	  {	    char *orig_line = input_line_pointer;	    expressionS new_exp;	    input_line_pointer = str;	    expression (&new_exp);	    if (new_exp.X_op == O_constant)	      {		exp_p->X_add_number += new_exp.X_add_number;		str = input_line_pointer;	      }	    if (&input_line_pointer != str_p)	      input_line_pointer = orig_line;	  }	*str_p = str;	return ptr->reloc;      }  return BFD_RELOC_UNUSED;}/* Like normal .long/.short/.word, except support @got, etc.  *//* clobbers input_line_pointer, checks *//* end-of-line.  */static voidppc_elf_cons (nbytes)     register int nbytes;	/* 1=.byte, 2=.word, 4=.long */{  expressionS exp;  bfd_reloc_code_real_type reloc;  if (is_it_end_of_statement ())    {      demand_empty_rest_of_line ();      return;    }  do    {      expression (&exp);      if (exp.X_op == O_symbol	  && *input_line_pointer == '@'	  && (reloc = ppc_elf_suffix (&input_line_pointer, &exp)) != BFD_RELOC_UNUSED)	{	  reloc_howto_type *reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc);	  int size = bfd_get_reloc_size (reloc_howto);	  if (size > nbytes)	    as_bad (_("%s relocations do not fit in %d bytes\n"), reloc_howto->name, nbytes);	  else	    {	      register char *p = frag_more ((int) nbytes);	      int offset = nbytes - size;	      fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size, &exp, 0, reloc);	    }	}      else	emit_expr (&exp, (unsigned int) nbytes);    }  while (*input_line_pointer++ == ',');  input_line_pointer--;		/* Put terminator back into stream.  */  demand_empty_rest_of_line ();}/* Solaris pseduo op to change to the .rodata section.  */static voidppc_elf_rdata (xxx)     int xxx;{  char *save_line = input_line_pointer;  static char section[] = ".rodata\n";  /* Just pretend this is .section .rodata */  input_line_pointer = section;  obj_elf_section (xxx);  input_line_pointer = save_line;}/* Pseudo op to make file scope bss items */static voidppc_elf_lcomm(xxx)     int xxx ATTRIBUTE_UNUSED;{  register char *name;  register char c;  register char *p;  offsetT size;  register symbolS *symbolP;  offsetT align;  segT old_sec;  int old_subsec;  char *pfrag;  int align2;  name = input_line_pointer;  c = get_symbol_end ();  /* just after name is now '\0' */  p = input_line_pointer;  *p = c;  SKIP_WHITESPACE ();  if (*input_line_pointer != ',')    {      as_bad (_("Expected comma after symbol-name: rest of line ignored."));      ignore_rest_of_line ();      return;    }  input_line_pointer++;		/* skip ',' */  if ((size = get_absolute_expression ()) < 0)    {      as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);      ignore_rest_of_line ();      return;    }  /* The third argument to .lcomm is the alignment.  */  if (*input_line_pointer != ',')    align = 8;  else    {      ++input_line_pointer;      align = get_absolute_expression ();      if (align <= 0)	{	  as_warn (_("ignoring bad alignment"));	  align = 8;	}    }  *p = 0;  symbolP = symbol_find_or_make (name);  *p = c;  if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))    {      as_bad (_("Ignoring attempt to re-define symbol `%s'."),	      S_GET_NAME (symbolP));      ignore_rest_of_line ();      return;    }  if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)    {      as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),	      S_GET_NAME (symbolP),	      (long) S_GET_VALUE (symbolP),	      (long) size);      ignore_rest_of_line ();      return;    }  /* allocate_bss: */  old_sec = now_seg;  old_subsec = now_subseg;  if (align)    {      /* convert to a power of 2 alignment */      for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2);      if (align != 1)	{	  as_bad (_("Common alignment not a power of 2"));	  ignore_rest_of_line ();	  return;	}    }  else    align2 = 0;  record_alignment (bss_section, align2);  subseg_set (bss_section, 0);  if (align2)    frag_align (align2, 0, 0);  if (S_GET_SEGMENT (symbolP) == bss_section)    symbol_get_frag (symbolP)->fr_symbol = 0;  symbol_set_frag (symbolP, frag_now);  pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,		    (char *) 0);  *pfrag = 0;  S_SET_SIZE (symbolP, size);  S_SET_SEGMENT (symbolP, bss_section);  subseg_set (old_sec, old_subsec);  demand_empty_rest_of_line ();}/* Validate any relocations emitted for -mrelocatable, possibly adding   fixups for word relocations in writable segments, so we can adjust   them at runtime.  */static voidppc_elf_validate_fix (fixp, seg)     fixS *fixp;     segT seg;{  if (fixp->fx_done || fixp->fx_pcrel)    return;  switch (shlib)    {    case SHLIB_NONE:    case SHLIB_PIC:      return;    case SHLIB_MRELOCATABLE:      if (fixp->fx_r_type <= BFD_RELOC_UNUSED

⌨️ 快捷键说明

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