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

📄 tc-hppa.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
  {"%tr1",   25},  {"%tr2",   26},  {"%tr3",   27},  {"%tr4",   28},  {"%tr5",   29},  {"%tr6",   30},  {"%tr7",   31}};/* This table is sorted by order of the length of the string. This is   so we check for <> before we check for <. If we had a <> and checked   for < first, we would get a false match.  */static const struct fp_cond_map fp_cond_map[] ={  {"false?", 0},  {"false", 1},  {"true?", 30},  {"true", 31},  {"!<=>", 3},  {"!?>=", 8},  {"!?<=", 16},  {"!<>", 7},  {"!>=", 11},  {"!?>", 12},  {"?<=", 14},  {"!<=", 19},  {"!?<", 20},  {"?>=", 22},  {"!?=", 24},  {"!=t", 27},  {"<=>", 29},  {"=t", 5},  {"?=", 6},  {"?<", 10},  {"<=", 13},  {"!>", 15},  {"?>", 18},  {">=", 21},  {"!<", 23},  {"<>", 25},  {"!=", 26},  {"!?", 28},  {"?", 2},  {"=", 4},  {"<", 9},  {">", 17}};static const struct selector_entry selector_table[] ={  {"f", e_fsel},  {"l", e_lsel},  {"ld", e_ldsel},  {"lp", e_lpsel},  {"lr", e_lrsel},  {"ls", e_lssel},  {"lt", e_ltsel},  {"ltp", e_ltpsel},  {"n", e_nsel},  {"nl", e_nlsel},  {"nlr", e_nlrsel},  {"p", e_psel},  {"r", e_rsel},  {"rd", e_rdsel},  {"rp", e_rpsel},  {"rr", e_rrsel},  {"rs", e_rssel},  {"rt", e_rtsel},  {"rtp", e_rtpsel},  {"t", e_tsel},};#ifdef OBJ_SOM/* default space and subspace dictionaries */#define GDB_SYMBOLS          GDB_SYMBOLS_SUBSPACE_NAME#define GDB_STRINGS          GDB_STRINGS_SUBSPACE_NAME/* pre-defined subsegments (subspaces) for the HPPA.  */#define SUBSEG_CODE   0#define SUBSEG_LIT    1#define SUBSEG_MILLI  2#define SUBSEG_DATA   0#define SUBSEG_BSS    2#define SUBSEG_UNWIND 3#define SUBSEG_GDB_STRINGS 0#define SUBSEG_GDB_SYMBOLS 1static struct default_subspace_dict pa_def_subspaces[] ={  {"$CODE$", 1, 1, 1, 0, 0, 0, 24, 0x2c, 0, 8, 0, 0, SUBSEG_CODE},  {"$DATA$", 1, 1, 0, 0, 0, 0, 24, 0x1f, 1, 8, 1, 1, SUBSEG_DATA},  {"$LIT$", 1, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, 0, SUBSEG_LIT},  {"$MILLICODE$", 1, 1, 0, 0, 0, 0, 8, 0x2c, 0, 8, 0, 0, SUBSEG_MILLI},  {"$BSS$", 1, 1, 0, 0, 0, 1, 80, 0x1f, 1, 8, 1, 1, SUBSEG_BSS},  {NULL, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 0, 0}};static struct default_space_dict pa_def_spaces[] ={  {"$TEXT$", 0, 1, 1, 0, 8, ASEC_NULL},  {"$PRIVATE$", 1, 1, 1, 1, 16, ASEC_NULL},  {NULL, 0, 0, 0, 0, 0, ASEC_NULL}};/* Misc local definitions used by the assembler.  *//* These macros are used to maintain spaces/subspaces.  */#define SPACE_DEFINED(space_chain)	(space_chain)->sd_defined#define SPACE_USER_DEFINED(space_chain) (space_chain)->sd_user_defined#define SPACE_SPNUM(space_chain)	(space_chain)->sd_spnum#define SPACE_NAME(space_chain)		(space_chain)->sd_name#define SUBSPACE_DEFINED(ss_chain)	(ss_chain)->ssd_defined#define SUBSPACE_NAME(ss_chain)		(ss_chain)->ssd_name#endif/* Return nonzero if the string pointed to by S potentially represents   a right or left half of a FP register  */#define IS_R_SELECT(S)   (*(S) == 'R' || *(S) == 'r')#define IS_L_SELECT(S)   (*(S) == 'L' || *(S) == 'l')/* Insert FIELD into OPCODE starting at bit START.  Continue pa_ip   main loop after insertion.  */#define INSERT_FIELD_AND_CONTINUE(OPCODE, FIELD, START) \  { \    ((OPCODE) |= (FIELD) << (START)); \    continue; \  }/* Simple range checking for FIELD againt HIGH and LOW bounds.   IGNORE is used to suppress the error message.  */#define CHECK_FIELD(FIELD, HIGH, LOW, IGNORE) \  { \    if ((FIELD) > (HIGH) || (FIELD) < (LOW)) \      { \	if (! IGNORE) \          as_bad (_("Field out of range [%d..%d] (%d)."), (LOW), (HIGH), \		  (int) (FIELD));\        break; \      } \  }/* Simple alignment checking for FIELD againt ALIGN (a power of two).   IGNORE is used to suppress the error message.  */#define CHECK_ALIGN(FIELD, ALIGN, IGNORE) \  { \    if ((FIELD) & ((ALIGN) - 1)) \      { \	if (! IGNORE) \          as_bad (_("Field not properly aligned [%d] (%d)."), (ALIGN), \		  (int) (FIELD));\        break; \      } \  }#define is_DP_relative(exp)			\  ((exp).X_op == O_subtract			\   && strcmp (S_GET_NAME ((exp).X_op_symbol), "$global$") == 0)#define is_PC_relative(exp)			\  ((exp).X_op == O_subtract			\   && strcmp (S_GET_NAME ((exp).X_op_symbol), "$PIC_pcrel$0") == 0)/* We need some complex handling for stabs (sym1 - sym2).  Luckily, we'll   always be able to reduce the expression to a constant, so we don't   need real complex handling yet.  */#define is_complex(exp)				\  ((exp).X_op != O_constant && (exp).X_op != O_symbol)/* Actual functions to implement the PA specific code for the assembler.  *//* Called before writing the object file.  Make sure entry/exit and   proc/procend pairs match.  */voidpa_check_eof (){  if (within_entry_exit)    as_fatal (_("Missing .exit\n"));  if (within_procedure)    as_fatal (_("Missing .procend\n"));}/* Returns a pointer to the label_symbol_struct for the current space.   or NULL if no label_symbol_struct exists for the current space.  */static label_symbol_struct *pa_get_label (){  label_symbol_struct *label_chain;  for (label_chain = label_symbols_rootp;       label_chain;       label_chain = label_chain->lss_next)    {#ifdef OBJ_SOM    if (current_space == label_chain->lss_space && label_chain->lss_label)      return label_chain;#endif#ifdef OBJ_ELF    if (now_seg == label_chain->lss_segment && label_chain->lss_label)      return label_chain;#endif    }  return NULL;}/* Defines a label for the current space.  If one is already defined,   this function will replace it with the new label.  */voidpa_define_label (symbol)     symbolS *symbol;{  label_symbol_struct *label_chain = pa_get_label ();  if (label_chain)    label_chain->lss_label = symbol;  else    {      /* Create a new label entry and add it to the head of the chain.  */      label_chain	= (label_symbol_struct *) xmalloc (sizeof (label_symbol_struct));      label_chain->lss_label = symbol;#ifdef OBJ_SOM      label_chain->lss_space = current_space;#endif#ifdef OBJ_ELF      label_chain->lss_segment = now_seg;#endif      label_chain->lss_next = NULL;      if (label_symbols_rootp)	label_chain->lss_next = label_symbols_rootp;      label_symbols_rootp = label_chain;    }}/* Removes a label definition for the current space.   If there is no label_symbol_struct entry, then no action is taken.  */static voidpa_undefine_label (){  label_symbol_struct *label_chain;  label_symbol_struct *prev_label_chain = NULL;  for (label_chain = label_symbols_rootp;       label_chain;       label_chain = label_chain->lss_next)    {      if (1#ifdef OBJ_SOM 	  && current_space == label_chain->lss_space && label_chain->lss_label#endif#ifdef OBJ_ELF 	  && now_seg == label_chain->lss_segment && label_chain->lss_label#endif	  )	{	  /* Remove the label from the chain and free its memory.  */	  if (prev_label_chain)	    prev_label_chain->lss_next = label_chain->lss_next;	  else	    label_symbols_rootp = label_chain->lss_next;	  free (label_chain);	  break;	}      prev_label_chain = label_chain;    }}/* An HPPA-specific version of fix_new.  This is required because the HPPA   code needs to keep track of some extra stuff.  Each call to fix_new_hppa   results in the creation of an instance of an hppa_fix_struct.  An   hppa_fix_struct stores the extra information along with a pointer to the   original fixS.  This is attached to the original fixup via the   tc_fix_data field.  */static voidfix_new_hppa (frag, where, size, add_symbol, offset, exp, pcrel,	      r_type, r_field, r_format, arg_reloc, unwind_bits)     fragS *frag;     int where;     int size;     symbolS *add_symbol;     offsetT offset;     expressionS *exp;     int pcrel;     bfd_reloc_code_real_type r_type;     enum hppa_reloc_field_selector_type_alt r_field;     int r_format;     unsigned int arg_reloc;     int unwind_bits ATTRIBUTE_UNUSED;{  fixS *new_fix;  struct hppa_fix_struct *hppa_fix = (struct hppa_fix_struct *)  obstack_alloc (&notes, sizeof (struct hppa_fix_struct));  if (exp != NULL)    new_fix = fix_new_exp (frag, where, size, exp, pcrel, r_type);  else    new_fix = fix_new (frag, where, size, add_symbol, offset, pcrel, r_type);  new_fix->tc_fix_data = (void *) hppa_fix;  hppa_fix->fx_r_type = r_type;  hppa_fix->fx_r_field = r_field;  hppa_fix->fx_r_format = r_format;  hppa_fix->fx_arg_reloc = arg_reloc;  hppa_fix->segment = now_seg;#ifdef OBJ_SOM  if (r_type == R_ENTRY || r_type == R_EXIT)    new_fix->fx_offset = unwind_bits;#endif  /* foo-$global$ is used to access non-automatic storage.  $global$     is really just a marker and has served its purpose, so eliminate     it now so as not to confuse write.c.  Ditto for $PIC_pcrel$0.  */  if (new_fix->fx_subsy      && (strcmp (S_GET_NAME (new_fix->fx_subsy), "$global$") == 0	  || strcmp (S_GET_NAME (new_fix->fx_subsy), "$PIC_pcrel$0") == 0))    new_fix->fx_subsy = NULL;}/* Parse a .byte, .word, .long expression for the HPPA.  Called by   cons via the TC_PARSE_CONS_EXPRESSION macro.  */voidparse_cons_expression_hppa (exp)     expressionS *exp;{  hppa_field_selector = pa_chk_field_selector (&input_line_pointer);  expression (exp);}/* This fix_new is called by cons via TC_CONS_FIX_NEW.   hppa_field_selector is set by the parse_cons_expression_hppa.  */voidcons_fix_new_hppa (frag, where, size, exp)     fragS *frag;     int where;     int size;     expressionS *exp;{  unsigned int rel_type;  /* Get a base relocation type.  */  if (is_DP_relative (*exp))    rel_type = R_HPPA_GOTOFF;  else if (is_complex (*exp))    rel_type = R_HPPA_COMPLEX;  else    rel_type = R_HPPA;  if (hppa_field_selector != e_psel && hppa_field_selector != e_fsel)    {      as_warn (_("Invalid field selector.  Assuming F%%."));      hppa_field_selector = e_fsel;    }  fix_new_hppa (frag, where, size,		(symbolS *) NULL, (offsetT) 0, exp, 0, rel_type,		hppa_field_selector, size * 8, 0, 0);  /* Reset field selector to its default state.  */  hppa_field_selector = 0;}/* 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 (){  const char *retval = NULL;  int lose = 0;  unsigned int i = 0;  last_call_info = NULL;  call_info_root = NULL;  /* Set the default machine type.  */  if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, DEFAULT_LEVEL))    as_warn (_("could not set architecture and machine"));  /* Folding of text and data segments fails miserably on the PA.     Warn user and disable "-R" option.  */  if (flag_readonly_data_in_text)    {      as_warn (_("-R option not supported on this target."));      flag_readonly_data_in_text = 0;    }#ifdef OBJ_SOM  pa_spaces_begin ();#endif  op_hash = hash_new ();  while (i < NUMOPCODES)    {      const char *name = pa_opcodes[i].name;      retval = hash_insert (op_hash, name, (struct pa_opcode *) &pa_opcodes[i]);      if (retval != NULL && *retval != '\0')	{	  as_fatal (_("Internal error: can't hash `%s': %s\n"), name, retval);	  lose = 1;	}      do	{	  if ((pa_opcodes[i].match & pa_opcodes[i].mask)	      != pa_opcodes[i].match)	    {	      fprintf (stderr, _("internal error: losing opcode: `%s' \"%s\"\n"),		       pa_opcodes[i].name, pa_opcodes[i].args);	      lose = 1;	    }	  ++i;	}      while (i < NUMOPCODES && !strcmp (pa_opcodes[i].name, name));    }  if (lose)    as_fatal (_("Broken assembler.  No assembly attempted."));#ifdef OBJ_SOM  /* SOM will change text_section.  To make sure we never put     anything into the old one switch to the new one now.  */  subseg_set (text_section, 0);#endif#ifdef OBJ_SOM  dummy_symbol = symbol_find_or_make ("L$dummy");  S_SET_SEGMENT (dummy_symbol, text_section);  /* Force the symbol to be converted to a real symbol.  */  (void) symbol_get_bfdsym (dummy_symbol);#endif}/* Assemble a single instruction storing it into a frag.  */voidmd_assemble (str)     char *str;{  char *to;  /* The had better be something to assemble.  */  assert (str);  /* If we are within a procedure definition, make sure we've     defined a label for the procedure; handle case where the     label was defined after the .PROC directive.     Note there's not need to diddle with the segment or fragment     for the label symbol in this case.  We have already switched     into the new $CODE$ subspace at this point.  */  if (within_procedure && last_call_info->start_symbol == NULL)    {      label_symbol_struct *label_symbol = pa_get_label ();      if (label_symbol)	{	  if (label_symbol->lss_label)	    {	      last_call_info->start_symbol = label_symbol->lss_label;	      symbol_get_bfdsym (label_symbol->lss_label)->flags		|= BSF_FUNCTION;#ifdef OBJ_SOM	      /* Also handle allocation of a fixup to hold the unwind		 information when the label appears after the proc/procend.  */	      if (within_entry_exit)		{		  char *where;		  unsigned int u;		  where = frag_more (0);		  u = UNWIND_LOW32 (&last_call_info->ci_unwind.descriptor);		  fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,				NULL, (offsetT) 0, NULL,				0, R_HPPA_ENTRY, e_fsel, 0, 0, u);		}#endif	    }	  else	    as_bad (_("Missing function name for .PROC (corrupted label chain)"));	}      else	as_bad (_("Missing function name for .PROC"));    }  /* Assemble the instruction.  Results are saved into "the_insn".  */  pa_ip (str);  /* Get somewhere to put the assembled instrution.  */  to = frag_more (4);

⌨️ 快捷键说明

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