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

📄 tc-tahoe.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 4 页
字号:
  int reg = -1;			/* major register, -1 means absent */  int imreg = -1;		/* Major register in immediate mode */  int ndx = -1;			/* index register number, -1 means absent */  char dec_inc = ' ';		/* Is the SP auto-incremented '+' or				   auto-decremented '-' or neither ' '.  */  int immediate = 0;		/* 1 if '$' immediate mode */  int call_width = 0;		/* If the caller casts the displacement */  int abs_width = 0;		/* The width of the absolute displacment */  int com_width = 0;		/* Displacement width required by branch */  int deferred = 0;		/* 1 if '*' deferral is used */  byte disp_size = 0;		/* How big is this operand. 0 == don't know */  char *op_bad = "";		/* Bad operand error */  char *tp, *temp, c;		/* Temporary holders */  char access = topP->top_access;	/* Save on a deref.  */  char width = topP->top_width;  int really_none = 0;		/* Empty expressions evaluate to 0				   but I need to know if it's there or not */  expressionS *expP;		/* -> expression values for this operand */  /* Does this command restrict the displacement size.  */  if (access == 'b')    com_width = (width == 'b' ? 1 :		 (width == 'w' ? 2 :		  (width == 'l' ? 4 : 0)));  *optex = '\0';		/* This is kind of a back stop for all				   the searches to fail on if needed.*/  if (*point == '*')    {				/* A dereference? */      deferred = 1;      point++;    }  /* Force words into a certain mode */  /* Bitch, Bitch, Bitch! */  /*   * Using the ^ operator is ambigous. If I have an absolute label   * called 'w' set to, say 2, and I have the expression 'w^1', do I get   * 1, forced to be in word displacement mode, or do I get the value of   * 'w' or'ed with 1 (3 in this case).   * The default is 'w' as an offset, so that's what I use.   * Stick with `, it does the same, and isn't ambig.   */  if (*point != '\0' && ((point[1] == '^') || (point[1] == '`')))    switch (*point)      {      case 'b':      case 'B':      case 'w':      case 'W':      case 'l':      case 'L':	if (com_width)	  as_warn (_("Casting a branch displacement is bad form, and is ignored."));	else	  {	    c = (isupper (*point) ? tolower (*point) : *point);	    call_width = ((c == 'b') ? 1 :			  ((c == 'w') ? 2 : 4));	  }	point += 2;	break;      }  /* Setting immediate mode */  if (*point == '$')    {      immediate = 1;      point++;    }  /*   * I've pulled off all the easy stuff off the front, move to the end and   * yank.   */  for (end = point; *end != '\0'; end++)	/* Move to the end.  */    ;  if (end != point)		/* Null string? */    end--;  if (end > point && *end == ' ' && end[-1] != '\'')    end--;			/* Hop white space */  /* Is this an index reg.  */  if ((*end == ']') && (end[-1] != '\''))    {      temp = end;      /* Find opening brace.  */      for (--end; (*end != '[' && end != point); end--)	;      /* If I found the opening brace, get the index register number.  */      if (*end == '[')	{	  tp = end + 1;		/* tp should point to the start of a reg.  */	  ndx = tahoe_reg_parse (&tp);	  if (tp != temp)	    {			/* Reg. parse error.  */	      ndx = -1;	    }	  else	    {	      end--;		/* Found it, move past brace.  */	    }	  if (ndx == -1)	    {	      op_bad = _("Couldn't parse the [index] in this operand.");	      end = point;	/* Force all the rest of the tests to fail.  */	    }	}      else	{	  op_bad = _("Couldn't find the opening '[' for the index of this operand.");	  end = point;		/* Force all the rest of the tests to fail.  */	}    }  /* Post increment? */  if (*end == '+')    {      dec_inc = '+';      /* was:    *end--; */      end--;    }  /* register in parens? */  if ((*end == ')') && (end[-1] != '\''))    {      temp = end;      /* Find opening paren.  */      for (--end; (*end != '(' && end != point); end--)	;      /* If I found the opening paren, get the register number.  */      if (*end == '(')	{	  tp = end + 1;	  reg = tahoe_reg_parse (&tp);	  if (tp != temp)	    {	      /* Not a register, but could be part of the expression.  */	      reg = -1;	      end = temp;	/* Rest the pointer back */	    }	  else	    {	      end--;		/* Found the reg. move before opening paren.  */	    }	}      else	{	  op_bad = _("Couldn't find the opening '(' for the deref of this operand.");	  end = point;		/* Force all the rest of the tests to fail.  */	}    }  /* Pre decrement? */  if (*end == '-')    {      if (dec_inc != ' ')	{	  op_bad = _("Operand can't be both pre-inc and post-dec.");	  end = point;	}      else	{	  dec_inc = '-';	  /* was:      *end--; */	  end--;	}    }  /*   * Everything between point and end is the 'expression', unless it's   * a register name.   */  c = end[1];  end[1] = '\0';  tp = point;  imreg = tahoe_reg_parse (&point);	/* Get the immediate register				      if it is there.*/  if (*point != '\0')    {      /* If there is junk after point, then the it's not immediate reg.  */      point = tp;      imreg = -1;    }  if (imreg != -1 && reg != -1)    op_bad = _("I parsed 2 registers in this operand.");  /*   * Evaluate whats left of the expression to see if it's valid.   * Note again: This assumes that the calling expression has saved   * input_line_pointer. (Nag, nag, nag!)   */  if (*op_bad == '\0')    {      /* Statement has no syntax goofs yet: let's sniff the expression.  */      input_line_pointer = point;      expP = &(topP->exp_of_operand);      topP->seg_of_operand = expression (expP);      switch (expP->X_op)	{	case O_absent:	  /* No expression. For BSD4.2 compatibility, missing expression is	     absolute 0 */	  expP->X_op = O_constant;	  expP->X_add_number = 0;	  really_none = 1;	case O_constant:	  /* for SEG_ABSOLUTE, we shouldnt need to set X_op_symbol,	     X_add_symbol to any particular value.  */	  /* But, we will program defensively. Since this situation occurs	     rarely so it costs us little to do so.  */	  expP->X_add_symbol = NULL;	  expP->X_op_symbol = NULL;	  /* How many bytes are needed to express this abs value? */	  abs_width =	    ((((expP->X_add_number & 0xFFFFFF80) == 0) ||	      ((expP->X_add_number & 0xFFFFFF80) == 0xFFFFFF80)) ? 1 :	     (((expP->X_add_number & 0xFFFF8000) == 0) ||	      ((expP->X_add_number & 0xFFFF8000) == 0xFFFF8000)) ? 2 : 4);	case O_symbol:	  break;	default:	  /*	   * Major bug. We can't handle the case of a operator	   * expression in a synthetic opcode variable-length	   * instruction.  We don't have a frag type that is smart	   * enough to relax a operator, and so we just force all	   * operators to behave like SEG_PASS1s.  Clearly, if there is	   * a demand we can invent a new or modified frag type and	   * then coding up a frag for this case will be easy.	   */	  need_pass_2 = 1;	  op_bad = _("Can't relocate expression error.");	  break;	case O_big:	  /* This is an error. Tahoe doesn't allow any expressions	     bigger that a 32 bit long word. Any bigger has to be referenced	     by address.  */	  op_bad = _("Expression is too large for a 32 bits.");	  break;	}      if (*input_line_pointer != '\0')	{	  op_bad = _("Junk at end of expression.");	}    }  end[1] = c;  /* I'm done, so restore optex */  *optex = segfault;  /*   * At this point in the game, we (in theory) have all the components of   * the operand at least parsed. Now it's time to check for syntax/semantic   * errors, and build the mode.   * This is what I have:   *   deferred = 1 if '*'   *   call_width = 0,1,2,4   *   abs_width = 0,1,2,4   *   com_width = 0,1,2,4   *   immediate = 1 if '$'   *   ndx = -1 or reg num   *   dec_inc = '-' or '+' or ' '   *   reg = -1 or reg num   *   imreg = -1 or reg num   *   topP->exp_of_operand   *   really_none   */  /* Is there a displacement size? */  disp_size = (call_width ? call_width :	       (com_width ? com_width :		abs_width ? abs_width : 0));  if (*op_bad == '\0')    {      if (imreg != -1)	{	  /* Rn */	  mode = TAHOE_DIRECT_REG;	  if (deferred || immediate || (dec_inc != ' ') ||	      (reg != -1) || !really_none)	    op_bad = _("Syntax error in direct register mode.");	  else if (ndx != -1)	    op_bad = _("You can't index a register in direct register mode.");	  else if (imreg == SP_REG && access == 'r')	    op_bad =	      _("SP can't be the source operand with direct register addressing.");	  else if (access == 'a')	    op_bad = _("Can't take the address of a register.");	  else if (access == 'b')	    op_bad = _("Direct Register can't be used in a branch.");	  else if (width == 'q' && ((imreg % 2) || (imreg > 13)))	    op_bad = _("For quad access, the register must be even and < 14.");	  else if (call_width)	    op_bad = _("You can't cast a direct register.");	  if (*op_bad == '\0')	    {	      /* No errors, check for warnings */	      if (width == 'q' && imreg == 12)		as_warn (_("Using reg 14 for quadwords can tromp the FP register."));	      reg = imreg;	    }	  /* We know: imm = -1 */	}      else if (dec_inc == '-')	{	  /* -(SP) */	  mode = TAHOE_AUTO_DEC;	  if (deferred || immediate || !really_none)	    op_bad = _("Syntax error in auto-dec mode.");	  else if (ndx != -1)	    op_bad = _("You can't have an index auto dec mode.");	  else if (access == 'r')	    op_bad = _("Auto dec mode cant be used for reading.");	  else if (reg != SP_REG)	    op_bad = _("Auto dec only works of the SP register.");	  else if (access == 'b')	    op_bad = _("Auto dec can't be used in a branch.");	  else if (width == 'q')	    op_bad = _("Auto dec won't work with quadwords.");	  /* We know: imm = -1, dec_inc != '-' */	}      else if (dec_inc == '+')	{	  if (immediate || !really_none)	    op_bad = _("Syntax error in one of the auto-inc modes.");	  else if (deferred)	    {	      /* *(SP)+ */	      mode = TAHOE_AUTO_INC_DEFERRED;	      if (reg != SP_REG)		op_bad = _("Auto inc deferred only works of the SP register.");	      else if (ndx != -1)		op_bad = _("You can't have an index auto inc deferred mode.");	      else if (access == 'b')		op_bad = _("Auto inc can't be used in a branch.");	    }	  else	    {	      /* (SP)+ */	      mode = TAHOE_AUTO_INC;	      if (access == 'm' || access == 'w')		op_bad = _("You can't write to an auto inc register.");	      else if (reg != SP_REG)		op_bad = _("Auto inc only works of the SP register.");	      else if (access == 'b')		op_bad = _("Auto inc can't be used in a branch.");	      else if (width == 'q')		op_bad = _("Auto inc won't work with quadwords.");	      else if (ndx != -1)		op_bad = _("You can't have an index in auto inc mode.");	    }	  /* We know: imm = -1, dec_inc == ' ' */	}      else if (reg != -1)	{	  if ((ndx != -1) && (reg == SP_REG))	    op_bad = _("You can't index the sp register.");	  if (deferred)	    {	      /* *<disp>(Rn) */	      mode = TAHOE_REG_DISP_DEFERRED;	      if (immediate)		op_bad = _("Syntax error in register displaced mode.");	    }	  else if (really_none)	    {	      /* (Rn) */	      mode = TAHOE_REG_DEFERRED;	      /* if reg = SP then cant be indexed */	    }	  else	    {	      /* <disp>(Rn) */	      mode = TAHOE_REG_DISP;	    }	  /* We know: imm = -1, dec_inc == ' ', Reg = -1 */	}      else	{	  if (really_none)	    op_bad = _("An offest is needed for this operand.");	  if (deferred && immediate)	    {	      /* *$<ADDR> */	      mode = TAHOE_ABSOLUTE_ADDR;	      disp_size = 4;	    }	  else if (immediate)	    {	      /* $<disp> */	      mode = TAHOE_IMMEDIATE;	      if (ndx != -1)		op_bad = _("You can't index a register in immediate mode.");	      if (access == 'a')		op_bad = _("Immediate access can't be used as an address.");	      /* ponder the wisdom of a cast because it doesn't do any good.  */	    }	  else if (deferred)	    {	      /* *<disp> */	      mode = TAHOE_DISP_REL_DEFERRED;	    }	  else	    {	      /* <disp> */	      mode = TAHOE_DISPLACED_RELATIVE;	    }	}    }  /*   * At this point, all the errors we can do have be checked for.   * We can build the 'top'.  */  topP->top_ndx = ndx;  topP->top_reg = reg;  topP->top_mode = mode;  topP->top_error = op_bad;  topP->top_dispsize = disp_size;}				/* tip_op *//* *                  t i p ( ) * * This converts a string into a tahoe instruction. * The string must be a bare single instruction in tahoe (with BSD4 frobs) * format. * It provides at most one fatal error message (which stops the scan) * some warning messages as it finds them. * The tahoe instruction is returned in exploded form. * * The exploded instruction is returned to a struct tit of your choice. * #include "tahoe-inst.h" to know what a struct tit is. * */static voidtip (titP, instring)     struct tit *titP;		/* We build an exploded instruction here.  */     char *instring;		/* Text of a vax instruction: we modify.  */{  register struct tot_wot *twP = NULL;	/* How to bit-encode this opcode.  */  register char *p;		/* 1/skip whitespace.2/scan vot_how */  register char *q;		/*  */  register unsigned char count;	/* counts number of operands seen */  register struct top *operandp;/* scan operands in struct tit */  register char *alloperr = "";	/* error over all operands */  register char c;		/* Remember char, (we clobber it				   with '\0' temporarily).  */  char *save_input_line_pointer;  if (*instring == ' ')    ++instring;			/* Skip leading whitespace.  */  for (p = instring; *p && *p != ' '; p++)    ;				/* MUST end in end-of-string or				   exactly 1 space.  */  /* Scanned up to end of operation-code.  */  /* Operation-code is ended with whitespace.  */  if (p == instring)    {      titP->tit_error = _("No operator");      count = 0;      titP->tit_opcode = 0;    }  else    {      c = *p;      *p = '\0';      /*     * Here with instring pointing to what better be an op-name, and p     * pointing to character just past that.     * We trust instring points to an op-name, with no whitespace.     */      twP = (struct tot_wot *) hash_find (op_hash, instring);      *p = c;			/* Restore char after op-code.  */      if (twP == 0)	{

⌨️ 快捷键说明

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