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

📄 tc-sparc.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
    case OPTION_32:    case OPTION_64:      {	const char **list, **l;	sparc_arch_size = c == OPTION_32 ? 32 : 64;	list = bfd_target_list ();	for (l = list; *l != NULL; l++)	  {	    if (sparc_arch_size == 32)	      {		if (strcmp (*l, "elf32-sparc") == 0)		  break;	      }	    else	      {		if (strcmp (*l, "elf64-sparc") == 0)		  break;	      }	  }	if (*l == NULL)	  as_fatal (_("No compiled in support for %d bit object file format"),		    sparc_arch_size);	free (list);      }      break;    case OPTION_TSO:      sparc_memory_model = MM_TSO;      break;    case OPTION_PSO:      sparc_memory_model = MM_PSO;      break;    case OPTION_RMO:      sparc_memory_model = MM_RMO;      break;    case 'V':      print_version_id ();      break;    case 'Q':      /* Qy - do emit .comment	 Qn - do not emit .comment.  */      break;    case 's':      /* Use .stab instead of .stab.excl.  */      break;    case 'q':      /* quick -- Native assembler does fewer checks.  */      break;    case 'K':      if (strcmp (arg, "PIC") != 0)	as_warn (_("Unrecognized option following -K"));      else	sparc_pic_code = 1;      break;    case OPTION_NO_UNDECLARED_REGS:      no_undeclared_regs = 1;      break;    case OPTION_UNDECLARED_REGS:      no_undeclared_regs = 0;      break;#endif    case OPTION_RELAX:      sparc_relax = 1;      break;    case OPTION_NO_RELAX:      sparc_relax = 0;      break;    default:      return 0;    }  return 1;}voidmd_show_usage (stream)     FILE *stream;{  const struct sparc_arch *arch;  int column;  /* We don't get a chance to initialize anything before we're called,     so handle that now.  */  if (! default_init_p)    init_default_arch ();  fprintf (stream, _("SPARC options:\n"));  column = 0;  for (arch = &sparc_arch_table[0]; arch->name; arch++)    {      if (!arch->user_option_p)	continue;      if (arch != &sparc_arch_table[0])	fprintf (stream, " | ");      if (column + strlen(arch->name) > 70)	{	  column = 0;	  fputc ('\n', stream);	}      column += 5 + 2 + strlen(arch->name);      fprintf (stream, "-A%s", arch->name);    }  for (arch = &sparc_arch_table[0]; arch->name; arch++)    {      if (!arch->user_option_p)	continue;      fprintf (stream, " | ");      if (column + strlen(arch->name) > 65)	{	  column = 0;	  fputc ('\n', stream);	}      column += 5 + 7 + strlen(arch->name);      fprintf (stream, "-xarch=%s", arch->name);    }  fprintf (stream, _("\n\			specify variant of SPARC architecture\n\-bump			warn when assembler switches architectures\n\-sparc			ignored\n\--enforce-aligned-data	force .long, etc., to be aligned correctly\n\-relax			relax jumps and branches (default)\n\-no-relax		avoid changing any jumps and branches\n"));#ifdef OBJ_AOUT  fprintf (stream, _("\-k			generate PIC\n"));#endif#ifdef OBJ_ELF  fprintf (stream, _("\-32			create 32 bit object file\n\-64			create 64 bit object file\n"));  fprintf (stream, _("\			[default is %d]\n"), default_arch_size);  fprintf (stream, _("\-TSO			use Total Store Ordering\n\-PSO			use Partial Store Ordering\n\-RMO			use Relaxed Memory Ordering\n"));  fprintf (stream, _("\			[default is %s]\n"), (default_arch_size == 64) ? "RMO" : "TSO");  fprintf (stream, _("\-KPIC			generate PIC\n\-V			print assembler version number\n\-undeclared-regs	ignore application global register usage without\n\			appropriate .register directive (default)\n\-no-undeclared-regs	force error on application global register usage\n\			without appropriate .register directive\n\-q			ignored\n\-Qy, -Qn		ignored\n\-s			ignored\n"));#endif#ifdef SPARC_BIENDIAN  fprintf (stream, _("\-EL			generate code for a little endian machine\n\-EB			generate code for a big endian machine\n\--little-endian-data	generate code for a machine having big endian\n\                        instructions and little endian data.\n"));#endif}/* Native operand size opcode translation.  */struct  {    char *name;    char *name32;    char *name64;  } native_op_table[] ={  {"ldn", "ld", "ldx"},  {"ldna", "lda", "ldxa"},  {"stn", "st", "stx"},  {"stna", "sta", "stxa"},  {"slln", "sll", "sllx"},  {"srln", "srl", "srlx"},  {"sran", "sra", "srax"},  {"casn", "cas", "casx"},  {"casna", "casa", "casxa"},  {"clrn", "clr", "clrx"},  {NULL, NULL, NULL},};/* sparc64 priviledged registers.  */struct priv_reg_entry{  char *name;  int regnum;};struct priv_reg_entry priv_reg_table[] ={  {"tpc", 0},  {"tnpc", 1},  {"tstate", 2},  {"tt", 3},  {"tick", 4},  {"tba", 5},  {"pstate", 6},  {"tl", 7},  {"pil", 8},  {"cwp", 9},  {"cansave", 10},  {"canrestore", 11},  {"cleanwin", 12},  {"otherwin", 13},  {"wstate", 14},  {"fq", 15},  {"ver", 31},  {"", -1},			/* End marker.  */};/* v9a specific asrs.  */struct priv_reg_entry v9a_asr_table[] ={  {"tick_cmpr", 23},  {"sys_tick_cmpr", 25},  {"sys_tick", 24},  {"softint", 22},  {"set_softint", 20},  {"pic", 17},  {"pcr", 16},  {"gsr", 19},  {"dcr", 18},  {"clear_softint", 21},  {"", -1},			/* End marker.  */};static intcmp_reg_entry (parg, qarg)     const PTR parg;     const PTR qarg;{  const struct priv_reg_entry *p = (const struct priv_reg_entry *) parg;  const struct priv_reg_entry *q = (const struct priv_reg_entry *) qarg;  return strcmp (q->name, p->name);}/* This function is called once, at assembler startup time.  It should   set up all the tables, etc. that the MD part of the assembler will   need.  */voidmd_begin (){  register const char *retval = NULL;  int lose = 0;  register unsigned int i = 0;  /* We don't get a chance to initialize anything before md_parse_option     is called, and it may not be called, so handle default initialization     now if not already done.  */  if (! default_init_p)    init_default_arch ();  op_hash = hash_new ();  while (i < (unsigned int) sparc_num_opcodes)    {      const char *name = sparc_opcodes[i].name;      retval = hash_insert (op_hash, name, (PTR) &sparc_opcodes[i]);      if (retval != NULL)	{	  as_bad (_("Internal error: can't hash `%s': %s\n"),		  sparc_opcodes[i].name, retval);	  lose = 1;	}      do	{	  if (sparc_opcodes[i].match & sparc_opcodes[i].lose)	    {	      as_bad (_("Internal error: losing opcode: `%s' \"%s\"\n"),		      sparc_opcodes[i].name, sparc_opcodes[i].args);	      lose = 1;	    }	  ++i;	}      while (i < (unsigned int) sparc_num_opcodes	     && !strcmp (sparc_opcodes[i].name, name));    }  for (i = 0; native_op_table[i].name; i++)    {      const struct sparc_opcode *insn;      char *name = ((sparc_arch_size == 32)		    ? native_op_table[i].name32		    : native_op_table[i].name64);      insn = (struct sparc_opcode *) hash_find (op_hash, name);      if (insn == NULL)	{	  as_bad (_("Internal error: can't find opcode `%s' for `%s'\n"),		  name, native_op_table[i].name);	  lose = 1;	}      else	{	  retval = hash_insert (op_hash, native_op_table[i].name, (PTR) insn);	  if (retval != NULL)	    {	      as_bad (_("Internal error: can't hash `%s': %s\n"),		      sparc_opcodes[i].name, retval);	      lose = 1;	    }	}    }  if (lose)    as_fatal (_("Broken assembler.  No assembly attempted."));  qsort (priv_reg_table, sizeof (priv_reg_table) / sizeof (priv_reg_table[0]),	 sizeof (priv_reg_table[0]), cmp_reg_entry);  /* If -bump, record the architecture level at which we start issuing     warnings.  The behaviour is different depending upon whether an     architecture was explicitly specified.  If it wasn't, we issue warnings     for all upwards bumps.  If it was, we don't start issuing warnings until     we need to bump beyond the requested architecture or when we bump between     conflicting architectures.  */  if (warn_on_bump      && architecture_requested)    {      /* `max_architecture' records the requested architecture.	 Issue warnings if we go above it.  */      warn_after_architecture = max_architecture;      /* Find the highest architecture level that doesn't conflict with	 the requested one.  */      for (max_architecture = SPARC_OPCODE_ARCH_MAX;	   max_architecture > warn_after_architecture;	   --max_architecture)	if (! SPARC_OPCODE_CONFLICT_P (max_architecture,				       warn_after_architecture))	  break;    }}/* Called after all assembly has been done.  */voidsparc_md_end (){  unsigned long mach = bfd_mach_sparc;  if (sparc_arch_size == 64)    switch (current_architecture)      {      case SPARC_OPCODE_ARCH_V9A: mach = bfd_mach_sparc_v9a; break;      case SPARC_OPCODE_ARCH_V9B: mach = bfd_mach_sparc_v9b; break;      default: mach = bfd_mach_sparc_v9; break;      }  else    switch (current_architecture)      {      case SPARC_OPCODE_ARCH_SPARCLET: mach = bfd_mach_sparc_sparclet; break;      case SPARC_OPCODE_ARCH_V9: mach = bfd_mach_sparc_v8plus; break;      case SPARC_OPCODE_ARCH_V9A: mach = bfd_mach_sparc_v8plusa; break;      case SPARC_OPCODE_ARCH_V9B: mach = bfd_mach_sparc_v8plusb; break;      /* The sparclite is treated like a normal sparc.  Perhaps it shouldn't	 be but for now it is (since that's the way it's always been	 treated).  */      default: break;      }  bfd_set_arch_mach (stdoutput, bfd_arch_sparc, mach);}/* Return non-zero if VAL is in the range -(MAX+1) to MAX.  */static INLINE intin_signed_range (val, max)     bfd_signed_vma val, max;{  if (max <= 0)    abort ();  /* Sign-extend the value from the architecture word size, so that     0xffffffff is always considered -1 on sparc32.  */  if (sparc_arch_size == 32)    {      bfd_signed_vma sign = (bfd_signed_vma) 1 << 31;      val = ((val & 0xffffffff) ^ sign) - sign;    }  if (val > max)    return 0;  if (val < ~max)    return 0;  return 1;}/* Return non-zero if VAL is in the range 0 to MAX.  */static INLINE intin_unsigned_range (val, max)     bfd_vma val, max;{  if (val > max)    return 0;  return 1;}/* Return non-zero if VAL is in the range -(MAX/2+1) to MAX.   (e.g. -15 to +31).  */static INLINE intin_bitfield_range (val, max)     bfd_signed_vma val, max;{  if (max <= 0)    abort ();  if (val > max)    return 0;  if (val < ~(max >> 1))    return 0;  return 1;}static intsparc_ffs (mask)     unsigned int mask;{  int i;  if (mask == 0)    return -1;  for (i = 0; (mask & 1) == 0; ++i)    mask >>= 1;  return i;}/* Implement big shift right.  */static bfd_vmaBSR (val, amount)     bfd_vma val;     int amount;{  if (sizeof (bfd_vma) <= 4 && amount >= 32)    as_fatal (_("Support for 64-bit arithmetic not compiled in."));  return val >> amount;}/* For communication between sparc_ip and get_expression.  */static char *expr_end;/* Values for `special_case'.   Instructions that require wierd handling because they're longer than   4 bytes.  */#define SPECIAL_CASE_NONE	0#define	SPECIAL_CASE_SET	1#define SPECIAL_CASE_SETSW	2#define SPECIAL_CASE_SETX	3/* FIXME: sparc-opc.c doesn't have necessary "S" trigger to enable this.  */#define	SPECIAL_CASE_FDIV	4/* Bit masks of various insns.  */#define NOP_INSN 0x01000000#define OR_INSN 0x80100000#define XOR_INSN 0x80180000#define FMOVS_INSN 0x81A00020#define SETHI_INSN 0x01000000#define SLLX_INSN 0x81281000#define SRA_INSN 0x81380000/* The last instruction to be assembled.  */static const struct sparc_opcode *last_insn;/* The assembled opcode of `last_insn'.  */static unsigned long last_opcode;/* Handle the set and setuw synthetic instructions.  */static voidsynthetize_setuw (insn)     const struct sparc_opcode *insn;{  int need_hi22_p = 0;  int rd = (the_insn.opcode & RD (~0)) >> 25;  if (the_insn.exp.X_op == O_constant)    {      if (SPARC_OPCODE_ARCH_V9_P (max_architecture))	{	  if (sizeof (offsetT) > 4	      && (the_insn.exp.X_add_number < 0		  || the_insn.exp.X_add_number > (offsetT) 0xffffffff))	    as_warn (_("set: number not in 0..4294967295 range"));	}      else	{	  if (sizeof (offsetT) > 4	      && (the_insn.exp.X_add_number < -(offsetT) 0x80000000		  || the_insn.exp.X_add_number > (offsetT) 0xffffffff))	    as_warn (_("set: number not in -2147483648..4294967295 range"));	  the_insn.exp.X_add_number = (int) the_insn.exp.X_add_number;	}    }  /* See if operand is absolute and small; skip sethi if so.  */  if (the_insn.exp.X_op != O_constant      || the_insn.exp.X_add_number >= (1 << 12)      || the_insn.exp.X_add_number < -(1 << 12))    {      the_insn.opcode = (SETHI_INSN | RD (rd)			 | ((the_insn.exp.X_add_number >> 10)			    & (the_insn.exp.X_op == O_constant			       ? 0x3fffff : 0)));      the_insn.reloc = (the_insn.exp.X_op != O_constant			? BFD_RELOC_HI22 : BFD_RELOC_NONE);      output_insn (insn, &the_insn);      need_hi22_p = 1;    }  /* See if operand has no low-order bits; skip OR if so.  */  if (the_insn.exp.X_op != O_constant      || (need_hi22_p && (the_insn.exp.X_add_number & 0x3FF) != 0)      || ! need_hi22_p)    {

⌨️ 快捷键说明

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