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

📄 asparse.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
		shift;		/* bring in the first token for the arg list*/	}		for (argcnt = 1; argcnt <= 6; argcnt++, ap++){		/*		 *	code to process an argument proper		 */	    sawindex  = sawmul = sawsize = 0;	    {		switch(val) {		   default:		     disp:			if( !(INTOKSET(val,				 EBEGOPS				+YUKKYEXPRBEG				+SAFEEXPRBEG)) ) {				ERROR("expression expected");			}			expr(ap->a_xp,val);		     overdisp:			if ( val == LP || sawsize){				shiftover(LP);				findreg(regno);				shiftover(RP);				ap->a_atype = ADISP;				ap->a_areg1 = regno;			} else {				ap->a_atype = AEXP;				ap->a_areg1 = 0;			}			goto index;		   case SIZESPEC: 		     sizespec:			sawsize = yylval;			shift;			goto disp;		   case REG:		   case REGOP: 			findreg(regno);			ap->a_atype = AREG;			ap->a_areg1 = regno;			break;		    		   case VREG: 			findvreg(regno);			ap->a_atype = AVREG;			ap->a_areg1 = regno;			break;		    		   case MUL: 			sawmul = 1;			shift;			if (val == LP) goto base;			if (val == LITOP) goto imm;			if (val == SIZESPEC) goto sizespec;			if (INTOKSET(val,				 EBEGOPS				+YUKKYEXPRBEG				+SAFEEXPRBEG)) goto disp;			ERROR("expression, '(' or '$' expected");			break;		   case LP: 		     base:			shift;	/*consume the LP*/			/*			 *	hack the ambiguity of			 *	movl (expr) (rn), ...			 *	note that (expr) could also			 *	be (rn) (by special hole in the			 *	grammar), which we ensure			 *	means register indirection, instead			 *	of an expression with value n			 */			if (val != REG && val != REGOP){				droppedLP = 1;				val = exprparse(val, &(ap->a_xp));				droppedLP = 0;				goto overdisp;			}			findreg(regno);			shiftover(RP);			if (val == PLUS){				shift;				ap->a_atype = AINCR;			} else				ap->a_atype = ABASE;			ap->a_areg1 = regno;			goto index;		   case LITOP: 		      imm:			shift;			expr(locxp, val);			ap->a_atype = AIMM;			ap->a_areg1 = 0;			ap->a_xp = locxp;			goto index;		   case MP: 			shift;	/* -(reg) */			findreg(regno);			shiftover(RP);			ap->a_atype = ADECR;			ap->a_areg1 = regno;	  index:			/*look for [reg] */			if (val == LB){				shift;				findreg(regno);				shiftover(RB);				sawindex = 1;				ap->a_areg2 = regno;			}			break;		}	/*end of the switch to process an arg*/	    }	/*end of processing an argument*/	    if (sawmul){			/*			 * Make a concession for *(%r)			 * meaning *0(%r) 			 */			if (ap->a_atype == ABASE) {				ap->a_atype = ADISP;				xp->e_xtype = XABS;				xp->e_number = Znumber;				xp->e_number.num_tag = TYPL;				xp->e_xloc = 0;				ap->a_xp = xp++;			}			ap->a_atype |= ASTAR;			sawmul = 0;	    }	    if (sawindex){		ap->a_atype |= AINDX;		sawindex = 0;	    }	    ap->a_dispsize = sawsize == 0 ? d124 : sawsize;		if (val != CM) break;		shiftover(CM);	}	/*processing all the arguments*/	if (argcnt > 6){		yyerror("More than 6 arguments");		goto errorfix;	} 	if (auxval == VINSTn) { 	  format_vinst (np, &vmod, arglist); 	} 	else {		/*	 	 *	See if this is a case instruction,	 	 *	so we can set up tests on the following	 	 *	vector of branch displacements	 	 */		if (yyopcode.Op_eopcode == CORE){			switch(yyopcode.Op_popcode){				case 0x8f:	/* caseb */				case 0xaf:	/* casew */				case 0xcf:	/* casel */					incasetable++;					break;				default:					incasetable = 0;					break;			}		}		insout(yyopcode, arglist,					auxval == INSTn ? argcnt : - argcnt);	}	break;   case IQUAD:		toconv = TYPQ;	goto bignumlist;   case IOCTA:		toconv = TYPO;	goto bignumlist;   case IFFLOAT:	toconv = TYPF;	goto bignumlist;   case IDFLOAT:	toconv = TYPD;	goto bignumlist;   case IGFLOAT:	toconv = TYPG;	goto bignumlist;   case IHFLOAT:	toconv = TYPH;	goto bignumlist;   bignumlist:		/*	 *	eat a list of non 32 bit numbers.	 *	IQUAD and IOCTA can, possibly, return	 *	INT's, if the numbers are "small".	 *	 *	The value of the numbers is coming back	 *	as an expression, NOT in yybignum.	 */	shift;	/* over the opener */	if ((val == BIGNUM) || (val == INT)){		do{			if ((val != BIGNUM) && (val != INT)){				ERROR(ty_float[toconv]				   ? "floating number expected"				   : "integer number expected" );			}			dotp->e_xvalue += ty_nbyte[toconv];			if (passno == 2){				bignumwrite(					((struct exp *)yylval)->e_number,					toconv);			}			xp = explist;			shift;		/* over this number */			if (auxval = (val == CM))				shift;	/* over the comma */		} while (auxval);	/* as long as there are commas */	}	break;	/* end of the case for initialized big numbers */    }	/*end of the switch for looking at each reserved word*/	continue;   errorfix: 	/*	 *	got here by either requesting to skip to the	 *	end of this statement, or by erroring out and	 *	wanting to apply panic mode recovery	 */	while (    (val != NL) 		&& (val != SEMI) 		&& (val != PARSEEOF)	      ){		shift;	}	if (val == NL)		lineno++;	shift;    }	/*end of the loop to read the entire file, line by line*/}	/*end of yyparse*/	format_vinst(stp, vmodp, ap)     struct symtab        *stp;     union  Vinst_mod     *vmodp;     struct arg           *ap;/* This routine is called to reformat the vector instruction from the * assembler notation format into the vector instruction format as * specified in the instrs opcode table. It builds vector instruction * control word, sets the appropriate qualifier fields in the control  * word, sets the vector register fields and the compare/convert codes * in the control word, reshuffles the operands, and then calls the  * insout routine to output the instruction to the object file, in a * normal way. The routine is driven by the vinst_fmt table, whose entries * represent groups of like vector instructions. */{  reg int          i,j;  int              arg_num;  int              avalue;  int              argtype;  struct Opcode	   opcode;  u_char           ctrlcode;  struct arg       *vap;                /* first free vinst argument */  struct Vinst_fmt fmt;  struct Vinst_arg vi_arg;  struct Ctrl_word ctrl_word, *ctrl_word_ptr = &ctrl_word;  int              mod_length;  char             ch;  /* Pick up info from symbol table */  opcode.Op_popcode = ((Iptr)stp)->i_popcode;  opcode.Op_eopcode = ((Iptr)stp)->i_eopcode;  ctrlcode = ((Iptr)stp)->i_ctrlcode;  fmt = vinst_fmt[((Iptr)stp)->s_format];    /* Following is a kluge to allow vector instructions use the   * same mapping mechanism from opcode to the symbol table entry,   * as regular instructions */  itab[opcode.Op_eopcode][opcode.Op_popcode] = (Iptr) stp;  vap = varglist;    *(int *)ctrl_word_ptr = 0;  for (i = 0; i < fmt.vi_nargs; i++) /* process args according to format */    {      vi_arg = fmt.vi_args[i];      switch (vi_arg.va_tag) {      default:	break; /* argument type not defined */      case VOPND:	/* Move source argument into specified vector instruction operand */	arg_num = vi_arg.va_args[0] - 1;	varglist[i] = arglist[arg_num];	argtype = fetcharg(stp, i);        if ((argtype & TYPMASK) == TYPF4) { 	  /* Special check for vmergef */	  if ((varglist[i].a_atype & AMASK) != AIMM)	    yyerror ("Illegal mode");	}        varglist[i].a_atype |= AVECT;	break;      case VLTRL:	/* Generate literal as the instruction's first operand */	xp->e_xvalue = ctrlcode;	xp->e_number.num_tag = TYPL;	xp->e_xloc = 0;	xp->e_xtype = XABS; 	vap->a_atype = AIMM;	vap->a_areg1 = 0;	if (xp >= &explist[NEXP])	  yyerror("Too many expressions; try simplyfing");	else	  vap->a_xp = xp++;	break;      case VCTRL:	/* Generate control word */	for (j = 0; j < 3; j++) {	  /* Set va, vb, vc registers in the control word */	  if (vi_arg.va_args[j] != 0) {	    arg_num = vi_arg.va_args[j];	    if (arg_num == VCODE)	      avalue = ctrlcode; /* set cmp/cvt code */	    else {	      arg_num--;	      argtype = arglist[arg_num].a_atype;	      if (argtype != AVREG)		yyerror("arg %d, must specify a vector register", arg_num + 1);	      else 		avalue = arglist[arg_num].a_areg1;	    }	    switch (j) {	    case VA:	      ctrl_word.va_bits = avalue;	      break;	    case VB:	      ctrl_word.vb_bits = avalue;	      break;	    case VC:	      ctrl_word.vc_bits = avalue;	      break;	    } /* end switch */	  } /* end if */	} /* end for */	break;      } /* end switch */    } /* end for */  /* Process vector instruction modifiers into control word */  mod_length = vmodp->mod_value.mod_length;  if (fmt.vi_args[0].va_tag == VCTRL) {     ctrl_word.mod_bits |= fmt.vi_mod_dflt;    if (mod_length > 0) {      for (i = 1; i <= mod_length; i++) {	switch (ch = vmodp->mod_value.mod_ch[i-1]) {	case 'm':	  if ((fmt.vi_mod_mask & MI) != 0)	    ctrl_word.mod_bits |= mi_bit;	  else	    goto moderror;	  break;	case 'u':	case 'v':	  if ((fmt.vi_mod_mask & EXC) != 0)	    ctrl_word.mod_bits |= exc_bit;	  else	    goto moderror;	  break;	case '0':	  if ((fmt.vi_mod_mask & MTF) != 0) {	    if ((fmt.vi_mod_mask & MOE) != 0)	      ctrl_word.mod_bits |= moe_bit;	  }	  else	    goto moderror;	  break;	case '1':	  if ((fmt.vi_mod_mask & MTF) != 0) {	    if ((fmt.vi_mod_mask & MOE) != 0)	      ctrl_word.mod_bits |= moe_bit;	  ctrl_word.mod_bits |= mtf_bit;	  }	  else	    goto moderror;	  break;	default:	  break;	} /* end switch */	continue;      moderror:	yyerror("vector opcode qualifier %c is not valid for this opcode", ch);      } /* end for */    } /* end if */    /* Finally set up control word as instruction's first operand */    xp->e_xtype = XABS;     xp->e_xvalue = *(int *)ctrl_word_ptr;    xp->e_number.num_tag = TYPW;    xp->e_xloc = 0;        vap->a_atype = AVECT;    vap->a_areg1 = 0;    if (xp >= &explist[NEXP])      yyerror("Too many expressions; try simplyfing");    else      vap->a_xp = xp++;  } /* end if */  else if (mod_length > 0)    yyerror("Vector opcode qualifiers are not valid for this opcode");  /* Finally output this instruction */  insout(opcode, varglist, fmt.vi_nargs);}	/* *	Process a register declaration of the form *	% <expr> * *	Note: *		The scanner has already processed funny registers of the form *	%dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional *	preceding zero digit).  If there was any space between the % and *	the digit, the scanner wouldn't have recognized it, so we *	hack it out here.	/* *	Process a register declaration of the form *	% <expr> * *	Note: *		The scanner has already processed funny registers of the form *	%dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional *	preceding zero digit).  If there was any space between the % and *	the digit, the scanner wouldn't have recognized it, so we *	hack it out here. */inttoktype funnyreg(val, regnoback)	/*what the read head will sit on*/	inttoktype	val;		/*what the read head is sitting on*/	int	*regnoback;		/*call by return*/{	reg	struct	exp *locxp;		struct	exp *loc1xp;		struct	exp **ptrloc1xp = & loc1xp;	expr(locxp, val);	/*and leave the current read head with value*/	if ( (passno == 2) &&	    (   (locxp->e_xtype & XTYPE) != XABS	     || (locxp->e_xvalue < 0)	     || (locxp->e_xvalue >= 16)	    )	  ){		yyerror("Illegal register");		return(0);	}	*regnoback = locxp->e_xvalue;	return(val);} /* *	Shift over error */shiftoerror(token)	int	token;{	char	*tok_to_name();	yyerror("%s expected", tok_to_name(token));}/*VARARGS1*/yyerror(s, a1, a2,a3,a4,a5)	char	*s;{#define	sink stdout	if (anyerrs == 0 && anywarnings == 0 && ! silent) 		fprintf(sink, "Assembler:\n");	anyerrs++;	if (silent)		return;	fprintf(sink, "\"%s\", line %d: ", dotsname, lineno);	fprintf(sink, s, a1, a2,a3,a4,a5);	fprintf(sink, "\n");#undef sink}/*VARARGS1*/yywarning(s, a1, a2,a3,a4,a5)	char	*s;{#define	sink stdout	if (anyerrs == 0 && anywarnings == 0 && ! silent) 		fprintf(sink, "Assembler:\n");	anywarnings++;	if (silent)		return;	fprintf(sink, "\"%s\", line %d: WARNING: ", dotsname, lineno);	fprintf(sink, s, a1, a2,a3,a4,a5);	fprintf(sink, "\n");#undef sink}

⌨️ 快捷键说明

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