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

📄 m68k-parse.y

📁 基于4个mips核的noc设计
💻 Y
📖 第 1 页 / 共 2 页
字号:
zpc:	  LPC	| LZPC	;/* ',' zapc when it may be omitted.  */optczapc:	  /* empty */		{		  $$ = ZADDR0;		}	| ',' zapc		{		  $$ = $2;		}	;/* ',' EXPR when it may be omitted.  */optcexpr:	  /* empty */		{		  $$.exp.X_op = O_absent;		  $$.size = SIZE_UNSPEC;		}	| ',' EXPR		{		  $$ = $2;		}	;/* EXPR ',' when it may be omitted.  */optexprc:	  /* empty */		{		  $$.exp.X_op = O_absent;		  $$.size = SIZE_UNSPEC;		}	| EXPR ','		{		  $$ = $1;		}	;/* A register list for the movem instruction.  */reglist:	  reglistpair	| reglistpair '/' ireglist		{		  $$ = $1 | $3;		}	| reglistreg '/' ireglist		{		  $$ = (1 << $1) | $3;		}	;/* We use ireglist when we know we are looking at a reglist, and we   can safely reduce a simple register to reglistreg.  If we permitted   reglist to reduce to reglistreg, it would be ambiguous whether a   plain register were a DREG/AREG/FPREG or a REGLST.  */ireglist:	  reglistreg		{		  $$ = 1 << $1;		}	| reglistpair	| reglistpair '/' ireglist		{		  $$ = $1 | $3;		}	| reglistreg '/' ireglist		{		  $$ = (1 << $1) | $3;		}	;reglistpair:	  reglistreg '-' reglistreg		{		  if ($1 <= $3)		    $$ = (1 << ($3 + 1)) - 1 - ((1 << $1) - 1);		  else		    $$ = (1 << ($1 + 1)) - 1 - ((1 << $3) - 1);		}	;reglistreg:	  DR		{		  $$ = $1 - DATA0;		}	| AR		{		  $$ = $1 - ADDR0 + 8;		}	| FPR		{		  $$ = $1 - FP0 + 16;		}	| FPCR		{		  if ($1 == FPI)		    $$ = 24;		  else if ($1 == FPS)		    $$ = 25;		  else		    $$ = 26;		}	;%%/* The string to parse is stored here, and modified by yylex.  */static char *str;/* The original string pointer.  */static char *strorig;/* If *CCP could be a register, return the register number and advance   *CCP.  Otherwise don't change *CCP, and return 0.  */static enum m68k_registerm68k_reg_parse (ccp)     register char **ccp;{  char *start = *ccp;  char c;  char *p;  symbolS *symbolp;  if (flag_reg_prefix_optional)    {      if (*start == REGISTER_PREFIX)	start++;      p = start;    }  else    {      if (*start != REGISTER_PREFIX)	return 0;      p = start + 1;    }  if (! is_name_beginner (*p))    return 0;  p++;  while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')    p++;  c = *p;  *p = 0;  symbolp = symbol_find (start);  *p = c;  if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)    {      *ccp = p;      return S_GET_VALUE (symbolp);    }  /* In MRI mode, something like foo.bar can be equated to a register     name.  */  while (flag_mri && c == '.')    {      ++p;      while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')	p++;      c = *p;      *p = '\0';      symbolp = symbol_find (start);      *p = c;      if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)	{	  *ccp = p;	  return S_GET_VALUE (symbolp);	}    }  return 0;}/* The lexer.  */static intyylex (){  enum m68k_register reg;  char *s;  int parens;  int c = 0;  int tail = 0;  char *hold;  if (*str == ' ')    ++str;  if (*str == '\0')    return 0;  /* Various special characters are just returned directly.  */  switch (*str)    {    case '@':      /* In MRI mode, this can be the start of an octal number.  */      if (flag_mri)	{	  if (isdigit (str[1])	      || ((str[1] == '+' || str[1] == '-')		  && isdigit (str[2])))	    break;	}      /* Fall through.  */    case '#':    case '&':    case ',':    case ')':    case '/':    case '[':    case ']':      return *str++;    case '+':      /* It so happens that a '+' can only appear at the end of an         operand.  If it appears anywhere else, it must be a unary         plus on an expression.  */      if (str[1] == '\0')	return *str++;      break;    case '-':      /* A '-' can only appear in -(ar), rn-rn, or ar@-.  If it         appears anywhere else, it must be a unary minus on an         expression.  */      if (str[1] == '\0')	return *str++;      s = str + 1;      if (*s == '(')	++s;      if (m68k_reg_parse (&s) != 0)	return *str++;      break;    case '(':      /* A '(' can only appear in `(reg)', `(expr,...', `([', `@(', or         `)('.  If it appears anywhere else, it must be starting an         expression.  */      if (str[1] == '['	  || (str > strorig	      && (str[-1] == '@'		  || str[-1] == ')')))	return *str++;      s = str + 1;      if (m68k_reg_parse (&s) != 0)	return *str++;      /* Check for the case of '(expr,...' by scanning ahead.  If we         find a comma outside of balanced parentheses, we return '('.         If we find an unbalanced right parenthesis, then presumably         the '(' really starts an expression.  */      parens = 0;      for (s = str + 1; *s != '\0'; s++)	{	  if (*s == '(')	    ++parens;	  else if (*s == ')')	    {	      if (parens == 0)		break;	      --parens;	    }	  else if (*s == ',' && parens == 0)	    {	      /* A comma can not normally appear in an expression, so		 this is a case of '(expr,...'.  */	      return *str++;	    }	}    }  /* See if it's a register.  */  reg = m68k_reg_parse (&str);  if (reg != 0)    {      int ret;      yylval.reg = reg;      if (reg >= DATA0 && reg <= DATA7)	ret = DR;      else if (reg >= ADDR0 && reg <= ADDR7)	ret = AR;      else if (reg >= FP0 && reg <= FP7)	return FPR;      else if (reg == FPI	       || reg == FPS	       || reg == FPC)	return FPCR;      else if (reg == PC)	return LPC;      else if (reg >= ZDATA0 && reg <= ZDATA7)	ret = ZDR;      else if (reg >= ZADDR0 && reg <= ZADDR7)	ret = ZAR;      else if (reg == ZPC)	return LZPC;      else	return CREG;      /* If we get here, we have a data or address register.  We	 must check for a size or scale; if we find one, we must	 return INDEXREG.  */      s = str;      if (*s != '.' && *s != ':' && *s != '*')	return ret;      yylval.indexreg.reg = reg;      if (*s != '.' && *s != ':')	yylval.indexreg.size = SIZE_UNSPEC;      else	{	  ++s;	  switch (*s)	    {	    case 'w':	    case 'W':	      yylval.indexreg.size = SIZE_WORD;	      ++s;	      break;	    case 'l':	    case 'L':	      yylval.indexreg.size = SIZE_LONG;	      ++s;	      break;	    default:	      yyerror (_("illegal size specification"));	      yylval.indexreg.size = SIZE_UNSPEC;	      break;	    }	}      yylval.indexreg.scale = 1;      if (*s == '*' || *s == ':')	{	  expressionS scale;	  ++s;	  hold = input_line_pointer;	  input_line_pointer = s;	  expression (&scale);	  s = input_line_pointer;	  input_line_pointer = hold;	  if (scale.X_op != O_constant)	    yyerror (_("scale specification must resolve to a number"));	  else	    {	      switch (scale.X_add_number)		{		case 1:		case 2:		case 4:		case 8:		  yylval.indexreg.scale = scale.X_add_number;		  break;		default:		  yyerror (_("invalid scale value"));		  break;		}	    }	}      str = s;      return INDEXREG;    }  /* It must be an expression.  Before we call expression, we need to     look ahead to see if there is a size specification.  We must do     that first, because otherwise foo.l will be treated as the symbol     foo.l, rather than as the symbol foo with a long size     specification.  The grammar requires that all expressions end at     the end of the operand, or with ',', '(', ']', ')'.  */  parens = 0;  for (s = str; *s != '\0'; s++)    {      if (*s == '(')	{	  if (parens == 0	      && s > str	      && (s[-1] == ')' || isalnum ((unsigned char) s[-1])))	    break;	  ++parens;	}      else if (*s == ')')	{	  if (parens == 0)	    break;	  --parens;	}      else if (parens == 0	       && (*s == ',' || *s == ']'))	break;    }  yylval.exp.size = SIZE_UNSPEC;  if (s <= str + 2      || (s[-2] != '.' && s[-2] != ':'))    tail = 0;  else    {      switch (s[-1])	{	case 's':	case 'S':	case 'b':	case 'B':	  yylval.exp.size = SIZE_BYTE;	  break;	case 'w':	case 'W':	  yylval.exp.size = SIZE_WORD;	  break;	case 'l':	case 'L':	  yylval.exp.size = SIZE_LONG;	  break;	default:	  break;	}      if (yylval.exp.size != SIZE_UNSPEC)	tail = 2;    }#ifdef OBJ_ELF  {    /* Look for @PLTPC, etc.  */    char *cp;    yylval.exp.pic_reloc = pic_none;    cp = s - tail;    if (cp - 6 > str && cp[-6] == '@')      {	if (strncmp (cp - 6, "@PLTPC", 6) == 0)	  {	    yylval.exp.pic_reloc = pic_plt_pcrel;	    tail += 6;	  }	else if (strncmp (cp - 6, "@GOTPC", 6) == 0)	  {	    yylval.exp.pic_reloc = pic_got_pcrel;	    tail += 6;	  }      }    else if (cp - 4 > str && cp[-4] == '@')      {	if (strncmp (cp - 4, "@PLT", 4) == 0)	  {	    yylval.exp.pic_reloc = pic_plt_off;	    tail += 4;	  }	else if (strncmp (cp - 4, "@GOT", 4) == 0)	  {	    yylval.exp.pic_reloc = pic_got_off;	    tail += 4;	  }      }  }#endif  if (tail != 0)    {      c = s[-tail];      s[-tail] = 0;    }  hold = input_line_pointer;  input_line_pointer = str;  expression (&yylval.exp.exp);  str = input_line_pointer;  input_line_pointer = hold;  if (tail != 0)    {      s[-tail] = c;      str = s;    }  return EXPR;}/* Parse an m68k operand.  This is the only function which is called   from outside this file.  */intm68k_ip_op (s, oparg)     char *s;     struct m68k_op *oparg;{  memset (oparg, 0, sizeof *oparg);  oparg->error = NULL;  oparg->index.reg = ZDATA0;  oparg->index.scale = 1;  oparg->disp.exp.X_op = O_absent;  oparg->odisp.exp.X_op = O_absent;  str = strorig = s;  op = oparg;  return yyparse ();}/* The error handler.  */static voidyyerror (s)     const char *s;{  op->error = s;}

⌨️ 快捷键说明

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