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

📄 tc-v850.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 4 页
字号:
  { "r19", 19 },  { "r2",   2 },  { "r20", 20 },  { "r21", 21 },  { "r22", 22 },  { "r23", 23 },  { "r24", 24 },  { "r25", 25 },  { "r26", 26 },  { "r27", 27 },  { "r28", 28 },  { "r29", 29 },  { "r3",   3 },  { "r30", 30 },  { "r31", 31 },  { "r4",   4 },  { "r5",   5 },  { "r6",   6 },  { "r7",   7 },  { "r8",   8 },  { "r9",   9 },  { "sp",   3 },		/* sp - stack ptr  */  { "tp",   5 },		/* tp - text ptr  */  { "zero", 0 },};#define REG_NAME_CNT						\  (sizeof (pre_defined_registers) / sizeof (struct reg_name))static const struct reg_name system_registers[] = {  { "ctbp",  20 },  { "ctpc",  16 },  { "ctpsw", 17 },  { "dbpc",  18 },  { "dbpsw", 19 },  { "ecr",    4 },  { "eipc",   0 },  { "eipsw",  1 },  { "fepc",   2 },  { "fepsw",  3 },  { "psw",    5 },};#define SYSREG_NAME_CNT						\  (sizeof (system_registers) / sizeof (struct reg_name))static const struct reg_name system_list_registers[] = {  {"PS",      5 },  {"SR",      0 + 1}};#define SYSREGLIST_NAME_CNT					\  (sizeof (system_list_registers) / sizeof (struct reg_name))static const struct reg_name cc_names[] = {  { "c",  0x1 },  { "e",  0x2 },  { "ge", 0xe },  { "gt", 0xf },  { "h",  0xb },  { "l",  0x1 },  { "le", 0x7 },  { "lt", 0x6 },  { "n",  0x4 },  { "nc", 0x9 },  { "ne", 0xa },  { "nh", 0x3 },  { "nl", 0x9 },  { "ns", 0xc },  { "nv", 0x8 },  { "nz", 0xa },  { "p",  0xc },  { "s",  0x4 },  { "sa", 0xd },  { "t",  0x5 },  { "v",  0x0 },  { "z",  0x2 },};#define CC_NAME_CNT					\  (sizeof (cc_names) / sizeof (struct reg_name))/* Do a binary search of the given register table to see if NAME is a   valid regiter name.  Return the register number from the array on   success, or -1 on failure.  */static intreg_name_search (regs, regcount, name, accept_numbers)     const struct reg_name *regs;     int regcount;     const char *name;     boolean accept_numbers;{  int middle, low, high;  int cmp;  symbolS *symbolP;  /* If the register name is a symbol, then evaluate it.  */  if ((symbolP = symbol_find (name)) != NULL)    {      /* If the symbol is an alias for another name then use that.	 If the symbol is an alias for a number, then return the number.  */      if (symbol_equated_p (symbolP))	{	  name	    = S_GET_NAME (symbol_get_value_expression (symbolP)->X_add_symbol);	}      else if (accept_numbers)	{	  int reg = S_GET_VALUE (symbolP);	  if (reg >= 0 && reg <= 31)	    return reg;	}      /* Otherwise drop through and try parsing name normally.  */    }  low = 0;  high = regcount - 1;  do    {      middle = (low + high) / 2;      cmp = strcasecmp (name, regs[middle].name);      if (cmp < 0)	high = middle - 1;      else if (cmp > 0)	low = middle + 1;      else	return regs[middle].value;    }  while (low <= high);  return -1;}/* Summary of register_name(). * * in: Input_line_pointer points to 1st char of operand. * * out: A expressionS. *	The operand may have been a register: in this case, X_op == O_register, *	X_add_number is set to the register number, and truth is returned. *	Input_line_pointer->(next non-blank) char after operand, or is in *	its original state.  */static booleanregister_name (expressionP)     expressionS *expressionP;{  int reg_number;  char *name;  char *start;  char c;  /* Find the spelling of the operand.  */  start = name = input_line_pointer;  c = get_symbol_end ();  reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT,				name, FALSE);  /* Put back the delimiting char.  */  *input_line_pointer = c;  /* Look to see if it's in the register table.  */  if (reg_number >= 0)    {      expressionP->X_op         = O_register;      expressionP->X_add_number = reg_number;      /* Make the rest nice.  */      expressionP->X_add_symbol = NULL;      expressionP->X_op_symbol  = NULL;      return true;    }  else    {      /* Reset the line as if we had not done anything.  */      input_line_pointer = start;      return false;    }}/* Summary of system_register_name(). * * in:  INPUT_LINE_POINTER points to 1st char of operand. *      EXPRESSIONP points to an expression structure to be filled in. *      ACCEPT_NUMBERS is true iff numerical register names may be used. *      ACCEPT_LIST_NAMES is true iff the special names PS and SR may be *      accepted. * * out: A expressionS structure in expressionP. *	The operand may have been a register: in this case, X_op == O_register, *	X_add_number is set to the register number, and truth is returned. *	Input_line_pointer->(next non-blank) char after operand, or is in *	its original state.  */static booleansystem_register_name (expressionP, accept_numbers, accept_list_names)     expressionS *expressionP;     boolean accept_numbers;     boolean accept_list_names;{  int reg_number;  char *name;  char *start;  char c;  /* Find the spelling of the operand.  */  start = name = input_line_pointer;  c = get_symbol_end ();  reg_number = reg_name_search (system_registers, SYSREG_NAME_CNT, name,				accept_numbers);  /* Put back the delimiting char.  */  *input_line_pointer = c;  if (reg_number < 0      && accept_numbers)    {      /* Reset input_line pointer.  */      input_line_pointer = start;      if (isdigit (*input_line_pointer))	{	  reg_number = strtol (input_line_pointer, &input_line_pointer, 10);	  /* Make sure that the register number is allowable.  */	  if (reg_number < 0	      || (reg_number > 5 && reg_number < 16)	      || reg_number > 20)	    {	      reg_number = -1;	    }	}      else if (accept_list_names)	{	  c = get_symbol_end ();	  reg_number = reg_name_search (system_list_registers,					SYSREGLIST_NAME_CNT, name, FALSE);	  /* Put back the delimiting char.  */	  *input_line_pointer = c;	}    }  /* Look to see if it's in the register table.  */  if (reg_number >= 0)    {      expressionP->X_op         = O_register;      expressionP->X_add_number = reg_number;      /* Make the rest nice.  */      expressionP->X_add_symbol = NULL;      expressionP->X_op_symbol  = NULL;      return true;    }  else    {      /* Reset the line as if we had not done anything.  */      input_line_pointer = start;      return false;    }}/* Summary of cc_name(). * * in: INPUT_LINE_POINTER points to 1st char of operand. * * out: A expressionS. *	The operand may have been a register: in this case, X_op == O_register, *	X_add_number is set to the register number, and truth is returned. *	Input_line_pointer->(next non-blank) char after operand, or is in *	its original state.  */static booleancc_name (expressionP)     expressionS *expressionP;{  int reg_number;  char *name;  char *start;  char c;  /* Find the spelling of the operand.  */  start = name = input_line_pointer;  c = get_symbol_end ();  reg_number = reg_name_search (cc_names, CC_NAME_CNT, name, FALSE);  /* Put back the delimiting char.  */  *input_line_pointer = c;  /* Look to see if it's in the register table.  */  if (reg_number >= 0)    {      expressionP->X_op         = O_constant;      expressionP->X_add_number = reg_number;      /* Make the rest nice.  */      expressionP->X_add_symbol = NULL;      expressionP->X_op_symbol  = NULL;      return true;    }  else    {      /* Reset the line as if we had not done anything.  */      input_line_pointer = start;      return false;    }}static voidskip_white_space (void){  while (*input_line_pointer == ' '	 || *input_line_pointer == '\t')    ++input_line_pointer;}/* Summary of parse_register_list (). * * in: INPUT_LINE_POINTER  points to 1st char of a list of registers. *     INSN                is the partially constructed instruction. *     OPERAND             is the operand being inserted. * * out: NULL if the parse completed successfully, otherwise a *      pointer to an error message is returned.  If the parse *      completes the correct bit fields in the instruction *      will be filled in. * * Parses register lists with the syntax: * *   { rX } *   { rX, rY } *   { rX - rY } *   { rX - rY, rZ } *   etc * * and also parses constant epxressions whoes bits indicate the * registers in the lists.  The LSB in the expression refers to * the lowest numbered permissable register in the register list, * and so on upwards.  System registers are considered to be very * high numbers.  */static char *parse_register_list (insn, operand)     unsigned long *insn;     const struct v850_operand *operand;{  static int type1_regs[32] = {    30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24  };  static int type2_regs[32] = {    19, 18, 17, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0, 30, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24  };  static int type3_regs[32] = {     3,  2,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0, 14, 15, 13, 12,  7,  6,  5,  4, 11, 10,  9,  8  };  int *regs;  expressionS exp;  /* Select a register array to parse.  */  switch (operand->shift)    {    case 0xffe00001: regs = type1_regs; break;    case 0xfff8000f: regs = type2_regs; break;    case 0xfff8001f: regs = type3_regs; break;    default:      as_bad (_("unknown operand shift: %x\n"), operand->shift);      return _("internal failure in parse_register_list");    }  skip_white_space ();  /* If the expression starts with a curly brace it is a register list.     Otherwise it is a constant expression, whoes bits indicate which     registers are to be included in the list.  */  if (*input_line_pointer != '{')    {      int reg;      int i;      expression (&exp);      if (exp.X_op != O_constant)	return _("constant expression or register list expected");      if (regs == type1_regs)	{	  if (exp.X_add_number & 0xFFFFF000)	    return _("high bits set in register list expression");	  for (reg = 20; reg < 32; reg++)	    if (exp.X_add_number & (1 << (reg - 20)))	      {		for (i = 0; i < 32; i++)		  if (regs[i] == reg)		    *insn |= (1 << i);	      }	}      else if (regs == type2_regs)	{	  if (exp.X_add_number & 0xFFFE0000)	    return _("high bits set in register list expression");	  for (reg = 1; reg < 16; reg++)	    if (exp.X_add_number & (1 << (reg - 1)))	      {		for (i = 0; i < 32; i++)		  if (regs[i] == reg)		    *insn |= (1 << i);	      }	  if (exp.X_add_number & (1 << 15))	    *insn |= (1 << 3);	  if (exp.X_add_number & (1 << 16))	    *insn |= (1 << 19);	}      else /* regs == type3_regs  */	{	  if (exp.X_add_number & 0xFFFE0000)	    return _("high bits set in register list expression");	  for (reg = 16; reg < 32; reg++)	    if (exp.X_add_number & (1 << (reg - 16)))	      {		for (i = 0; i < 32; i++)		  if (regs[i] == reg)		    *insn |= (1 << i);	      }	  if (exp.X_add_number & (1 << 16))	    *insn |= (1 << 19);	}      return NULL;    }  input_line_pointer++;  /* Parse the register list until a terminator (closing curly brace or     new-line) is found.  */  for (;;)    {      if (register_name (&exp))	{	  int i;	  /* Locate the given register in the list, and if it is there,	     insert the corresponding bit into the instruction.  */	  for (i = 0; i < 32; i++)	    {	      if (regs[i] == exp.X_add_number)		{		  *insn |= (1 << i);		  break;		}	    }	  if (i == 32)	    {	      return _("illegal register included in list");	    }	}      else if (system_register_name (&exp, true, true))	{	  if (regs == type1_regs)	    {	      return _("system registers cannot be included in list");	    }	  else if (exp.X_add_number == 5)	    {	      if (regs == type2_regs)		return _("PSW cannot be included in list");	      else		*insn |= 0x8;	    }	  else if (exp.X_add_number < 4)	    *insn |= 0x80000;	  else	    return _("High value system registers cannot be included in list");	}      else if (*input_line_pointer == '}')	{	  input_line_pointer++;	  break;	}      else if (*input_line_pointer == ',')	{	  input_line_pointer++;	  continue;	}      else if (*input_line_pointer == '-')	{	  /* We have encountered a range of registers: rX - rY.  */	  int j;	  expressionS exp2;	  /* Skip the dash.  */	  ++input_line_pointer;	  /* Get the second register in the range.  */	  if (! register_name (&exp2))	    {	      return _("second register should follow dash in register list");	      exp2.X_add_number = exp.X_add_number;	    }	  /* Add the rest of the registers in the range.  */	  for (j = exp.X_add_number + 1; j <= exp2.X_add_number; j++)	    {	      int i;	      /* Locate the given register in the list, and if it is there,		 insert the corresponding bit into the instruction.  */	      for (i = 0; i < 32; i++)		{		  if (regs[i] == j)		    {		      *insn |= (1 << i);		      break;		    }		}	      if (i == 32)		return _("illegal register included in list");	    }	}      else	{	  break;	}      skip_white_space ();    }  return NULL;}CONST char *md_shortopts = "m:";struct option md_longopts[] = {  {NULL, no_argument, NULL, 0}};size_t md_longopts_size = sizeof (md_longopts);voidmd_show_usage (stream)     FILE *stream;{  fprintf (stream, _(" V850 options:\n"));  fprintf (stream, _("  -mwarn-signed-overflow    Warn if signed immediate values overflow\n"));  fprintf (stream, _("  -mwarn-unsigned-overflow  Warn if unsigned immediate values overflow\n"));  fprintf (stream, _("  -mv850                    The code is targeted at the v850\n"));  fprintf (stream, _("  -mv850e                   The code is targeted at the v850e\n"));  fprintf (stream, _("  -mv850ea                  The code is targeted at the v850ea\n"));  fprintf (stream, _("  -mv850any                 The code is generic, despite any processor specific instructions\n"));}intmd_parse_option (c, arg)     int c;     char *arg;{  if (c != 'm')    {      if (c != 'a')	/* xgettext:c-format  */	fprintf (stderr, _("unknown command line option: -%c%s\n"), c, arg);      return 0;    }  if (strcmp (arg, "warn-signed-overflow") == 0)    {      warn_signed_overflows = TRUE;    }  else if (strcmp (arg, "warn-unsigned-overflow") == 0)    {      warn_unsigned_overflows = TRUE;    }  else if (strcmp (arg, "v850") == 0)    {      machine = 0;      processor_mask = PROCESSOR_V850;    }  else if (strcmp (arg, "v850e") == 0)    {      machine = bfd_mach_v850e;      processor_mask = PROCESSOR_V850E;    }  else if (strcmp (arg, "v850ea") == 0)    {      machine = bfd_mach_v850ea;      processor_mask = PROCESSOR_V850EA;    }  else if (strcmp (arg, "v850any") == 0)    {      /* Tell the world that this is for any v850 chip.  */      machine = 0;      /* But support instructions for the extended versions.  */      processor_mask = PROCESSOR_V850EA;    }  else    {      /* xgettext:c-format  */      fprintf (stderr, _("unknown command line option: -%c%s\n"), c, arg);      return 0;    }  return 1;}symbolS *md_undefined_symbol (name)     char *name ATTRIBUTE_UNUSED;

⌨️ 快捷键说明

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