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

📄 asparse.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
   case ILONG:	curlen = NBPW;   goto elist;   elist:	seg_type = val;	shift;	/*	 *	Expression List processing	 */	if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){	    do{		/*		 *	expression list consists of a list of :		 *	<expr>		 *	<expr> : <expr> 		 *		(pack expr2 into expr1 bits		 */		expr(locxp, val);		/*		 *	now, pointing at the next token		 */		if (val == COLON){			shiftover(COLON);			expr(pval, val);			if ((locxp->e_xtype & XTYPE) != XABS) /* tekmdp */				yyerror("Width not absolute");			field_width = locxp->e_xvalue;			locxp = pval;			if (bitoff + field_width > curlen)				flushfield(curlen);			if (field_width > curlen)				yyerror("Expression crosses field boundary");		} else {			field_width = curlen;			flushfield(curlen);		}		if ((locxp->e_xtype & XTYPE) != XABS) {			if (bitoff)				yyerror("Illegal relocation in field");			switch(curlen){				case NBPW/4:	reloc_how = TYPB; break;				case NBPW/2:	reloc_how = TYPW; break;				case NBPW:	reloc_how = TYPL; break;			}			if (passno == 1){				dotp->e_xvalue += ty_nbyte[reloc_how];			} else {				outrel(locxp, reloc_how);			}		} else {			/*			 *				 *	See if we are doing a case instruction.			 *	If so, then see if the branch distance,			 *	stored as a word,			 *	is going to loose sig bits.			 */			if (passno == 2 && incasetable){				if (  (locxp->e_xvalue < -32768)				    ||(locxp->e_xvalue > 32767)){					yyerror("Case will branch too far: try -bswitch flag");				}			}			field_value = locxp->e_xvalue & ( (1L << field_width)-1);			bitfield |= field_value << bitoff;			bitoff += field_width;		}		xp = explist;		if (auxval = (val == CM))			shift;	    } while (auxval);	}	/* there existed an expression at all */	flushfield(curlen);	if ( ( curlen == NBPW/4) && bitoff)		dotp->e_xvalue ++;	break;	/*end of case IBYTE, IWORD, ILONG, IINT*/   case ISPACE: 	/* .space <expr> */	shift;	expr(locxp, val);	if ((locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */		yyerror("Space size not absolute");	space_value = locxp->e_xvalue;	if (space_value < 0)			/* jlr005 */		yyerror("Space size negative");  ospace:	flushfield(NBPW/4);	{		static char spacebuf[128];		while (space_value > sizeof(spacebuf)){			outs(spacebuf, sizeof(spacebuf));			space_value -= sizeof(spacebuf);		}		outs(spacebuf, space_value);	}	break;	/*	 *	.fill rep, size, value	 *	repeat rep times: fill size bytes with (truncated) value	 *	size must be between 1 and 8	 */   case	IFILL:	shift;	expr(locxp, val);	if ( (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */		yyerror("Fill repetition count not absolute");	fill_rep = locxp->e_xvalue;	shiftover(CM);	expr(locxp, val);	if ( (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */		yyerror("Fill size not absolute");	fill_size = locxp->e_xvalue;	if (fill_size <= 0 || fill_size > 8)		yyerror("Fill count not in in 1..8");	shiftover(CM);	expr(locxp, val);	if (passno == 2 && (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */		yyerror("Fill value not absolute");	flushfield(NBPW/4);	/*RAP001		Update the location counter on both passes. Used to do it		only for pass 1, causing a relocation problem. Whoever		may have thought bwrite did update it (like Outb, outs, ..)		but it doesn't, so it has to be done here.	*/	dotp->e_xvalue += fill_rep * fill_size;	if (passno == 2) {		while(fill_rep-- > 0)			bwrite((char *)&locxp->e_xvalue, fill_size, txtfil);	}	break;   case IASCII:		/* .ascii [ <stringlist> ] */   case IASCIZ: 	/* .asciz [ <stringlist> ] */	auxval = val;	shift;	/*	 *	Code to consume a string list	 *	 *	stringlist: empty | STRING | stringlist STRING	 */	while (val == STRING){		int	mystrlen;		flushfield(NBPW/4);		if (bitoff)			dotp->e_xvalue++;		stringp = (struct strdesc *)yylval;		/*		 *	utilize the string scanner cheat;		 *	the scanner appended a null byte on the string,		 *	but didn't charge it to sd_strlen		 */		mystrlen = stringp->sd_strlen;		mystrlen += (auxval == IASCIZ) ? 1 : 0;		if (passno == 2){			if (stringp->sd_place & STR_CORE){				outs(stringp->sd_string, mystrlen);			} else {				int	i, nread;				fseek(strfile, stringp->sd_stroff, 0);				for (i = 0; i < mystrlen;/*VOID*/){					nread = fread(yytext, 1,						min(mystrlen - i,						  sizeof(yytext)), strfile);					outs(yytext, nread);					i += nread;				}			}		} else {			dotp->e_xvalue += mystrlen;		}		shift;		/*over the STRING*/		if (val == CM)	/*could be a split string*/			shift;	}	break;	   case IORG: 	/* .org <expr> */	shift;	expr(locxp, val);	if ((locxp->e_xtype & XTYPE) == XABS)	/* tekmdp */		orgwarn++;	else if ((locxp->e_xtype & ~XXTRN) != dotp->e_xtype)		yyerror("Illegal expression to set origin");	space_value = locxp->e_xvalue - dotp->e_xvalue;	if (space_value < 0)		yyerror("Backwards 'org'");	goto ospace;	break;/* * *	Process stabs.  Stabs are created only by the f77 *	and the C compiler with the -g flag set. *	We only look at the stab ONCE, during pass 1, and *	virtually remove the stab from the intermediate file *	so it isn't seen during pass2.  This makes for some *	hairy processing to handle labels occuring in *	stab entries, but since most expressions in the *	stab are integral we save lots of time in the second *	pass by not looking at the stabs. *	A stab that is tagged floating will be bumped during *	the jxxx resolution phase.  A stab tagged fixed will *	not be be bumped. * *	.stab:	Old fashioned stabs *	.stabn: For stabs without names *	.stabs:	For stabs with string names *	.stabd: For stabs for line numbers or bracketing, *		without a string name, without *		a final expression.  The value of the *		final expression is taken to be  the current *		location counter, and is patched by the 2nd pass * *	.stab{<expr>,}*NCPName,<expr>, <expr>, <expr>, <expr> *	.stabn		 <expr>, <expr>, <expr>, <expr> *	.stabs   STRING, <expr>, <expr>, <expr>, <expr> *	.stabd		 <expr>, <expr>, <expr> # .  */   case ISTAB: 	yyerror(".stab directive no longer supported");	goto errorfix;  tailstab:	expr(locxp, val);	if (! (locxp->e_xvalue & STABTYPS)){		yyerror("Invalid type in %s", stabname);		goto errorfix;	}	stpt->s_ptype = locxp->e_xvalue;	shiftover(CM);	expr(locxp, val);	stpt->s_other = locxp->e_xvalue;	shiftover(CM);	expr(locxp, val);	stpt->s_desc = locxp->e_xvalue;	shiftover(CM);	exprisname = 0;	expr(locxp, val);	p = locxp->e_xname;	if ((locxp->e_xtype&XTYPE)!=XUNDEF) {	/* 004 not forward reference */		stpt->s_value = locxp->e_xvalue;		stpt->s_index = dotp - usedot;		if (exprisname){			switch(stpt->s_ptype) {				case N_GSYM:				case N_FNAME:				case N_RSYM:				case N_SSYM:				case N_LSYM:				case N_PSYM:				case N_BCOMM:				case N_ECOMM:				case N_LENG:					stpt->s_tag = FIXEDSTAB;					break;				/* Special handling of LCSYM.  Although				 * the named symbol representing the lcomm has				 * been seen, the address (s_value field)				 * will be changed in freezesymtab() once				 * the start address of BSS is known.				 * So treat this as a forward reference.				 */				case N_LCSYM:					stpt->s_tag = FIXEDSTAB;					stpt->s_dest = p;					stpt->s_index = p->s_index;					stpt->s_type = p->s_type | STABFLAG;					stpt->s_value = 0;					break;				default:					stpt->s_tag = FLOATINGSTAB;					break;			}		} else			stpt->s_tag = FIXEDSTAB;	/* Forward reference. */	/* Final address will be calculated in stabfix(), when */	/* stpt->s_dest->s_value has been assigned its final */	/* address. */	} else {		stpt->s_tag = FORWARDSTAB;		stpt->s_dest = p;		stpt->s_index = p->s_index;		stpt->s_type = p->s_type | STABFLAG;		/* e_xvalue may contain an offset, as in the case v.4+2; */		/* although the address of v.4 is unknown here, the 2 */		/* will be added in stabfix(). */		stpt->s_value = locxp->e_xvalue;	}	/*	 *	tokptr now points at one token beyond	 *	the current token stored in val and yylval,	 *	which are the next tokens after the end of	 *	this .stab directive.  This next token must	 *	be either a SEMI or NL, so is of width just	 *	one.  Therefore, to point to the next token	 *	after the end of this stab, just back up one..	 */	buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype));	break;	/*end of the .stab*/   case ISTABDOT:		stabname = ".stabd";	stpt = (struct symtab *)yylval;	/*	 *	We clobber everything after the	 *	.stabd and its pointer... we MUST	 *	be able to get back to this .stabd	 *	so that we can resolve its final value	 */	stabstart = tokptr;	shift;		/*over the ISTABDOT*/	if (passno == 1){		expr(locxp, val);		if (! (locxp->e_xvalue & STABTYPS)){			yyerror("Invalid type in .stabd");			goto errorfix;		}		stpt->s_ptype = locxp->e_xvalue;		shiftover(CM);		expr(locxp, val);		stpt->s_other = locxp->e_xvalue;		shiftover(CM);		expr(locxp, val);		stpt->s_desc = locxp->e_xvalue;		/*		 *		 *	Now, clobber everything but the		 *	.stabd pseudo and the pointer		 *	to its symbol table entry		 *	tokptr points to the next token,		 *	build the skip up to this		 */		buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype));	}	/*	 *	pass 1:	Assign a good guess for its position	 *		(ensures they are sorted into right place)/	 *	pass 2:	Fix the actual value	 */	stpt->s_value = dotp->e_xvalue;	stpt->s_index = dotp - usedot;	stpt->s_tag = FLOATINGSTAB;	/*although it has no effect in pass 2*/	break;   case ISTABNONE:   case ISTABSTR:        stabname = ((val == ISTABSTR) ? ".stabs" : ".stabn");	auxval = val;	if (passno == 2) goto errorfix;	stpt = (struct symtab *)yylval;	stabstart = tokptr;	(bytetoktype *)stabstart -= sizeof(struct symtab *);	(bytetoktype *)stabstart -= sizeof(bytetoktype);	shift;	if (auxval == ISTABSTR){		stringp = (struct strdesc *)yylval;		shiftover(STRING);		stpt->s_name = (char *)stringp;		/*		 *	We want the trailing null included in this string.		 *	We utilize the cheat the string scanner used,		 *	and merely increment the string length		 */		stringp->sd_strlen += 1;		shiftover(CM);	} else {		stpt->s_name = (char *)savestr("\0", 0, STR_BOTH);	}	goto tailstab;	break;   case ICOMM:		/* .comm  <name> , <expr> */   case ILCOMM: 	/* .lcomm <name> , <expr> */	auxval = val;	shift;	np = (struct symtab *)yylval;	shiftover(NAME);	shiftover(CM);	expr(locxp, val);	if ( (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */		yyerror("comm size not absolute");	if (passno == 1 && (np->s_type&XTYPE) != XUNDEF)		yyerror("Redefinition of %s", FETCHNAME(np));	if (passno==1) {		np->s_value = locxp->e_xvalue;		if (auxval == ICOMM)			np->s_type |= XXTRN;		else {			np->s_type &= ~XTYPE;			np->s_type |= XBSS;		}	}	break;   case IALIGN: 		/* .align <align_expr> [, <fill_expr> ]*/   	{		int	align_expr;		int	fill_expr;		/* Get the .align statement, and shift over .align.		 */		stpt = (struct symtab *)yylval;		shift;		/* Evaluate the alignment expression.		 */		expr(locxp, val);		if ( (locxp->e_xtype & XTYPE) != XABS) {			yyerror("Alignment expression not absolute");			break ;		} else if ( ! LEGAL_ALIGN_VAL(locxp->e_xvalue)) {			yyerror("Illegal value for alignment expression");			break ;		} else if (locxp->e_xvalue > ALIGN_GUARANTEE) {			/*			 * If more alignment was specified, than is guaranteed			 * by the loader, then issue a warning and convert			 * the value to the maximum guaranteed by the loader.			 */			if (passno == 1){				yywarning(					".align %d is NOT preserved by the loader",					locxp->e_xvalue);				yywarning(".align %d converted to .align %d",					locxp->e_xvalue,					ALIGN_GUARANTEE);			}			align_expr = ALIGN_GUARANTEE;		} else {			/* Use the user specified alignment expression.			 */			align_expr = locxp->e_xvalue;		}		/* Evalutate the fill expression if there is one, else use 0.		 */		if (val == CM) {			shiftover(CM);			expr(locxp, val);			if (passno == 2 && (locxp->e_xtype & XTYPE) != XABS) {				yyerror("Fill expression not absolute");				break;			} else {				fill_expr = locxp->e_xvalue;			}		} else {			fill_expr = 0;	/* default to 0 */		}		/* Create the appropriate entry for the .align, so it		 * can be used in calculating positions for symbols.		 */		jalign(align_expr, fill_expr, stpt);	}	break;   case VINST0:		/* vector instructions w/o arguments*/	np = (struct symtab *)yylval;	incasetable = 0;	shift;		vmod.imod = 0;	if (val == VMODIFIER){	  vmod.imod = yylval; /* save vector instr modifiers */	  shift;              /* now bring in the first token for the arg list*/	} /* end if VMODIFIER */	format_vinst (np, &vmod, (struct arg *)0);	break;   case INST0: 		/* instructions w/o arguments*/	incasetable = 0;	insout(yyopcode, (struct arg *)0, 0);	shift;		break;   case INSTn:		/* instructions with arguments*/   case IJXXX: 		/* UNIX style jump instructions */   case VINSTn:		/* vector instructions with arguments*/	if (val == VINSTn){		np = (struct symtab *)yylval;		auxval = val;		shift;		/* bring in the first token for the arg list*/	  	vmod.imod = 0;	  	if (val == VMODIFIER){	    	vmod.imod = yylval; /* save vector instr modifiers */	    	shift;            /* now bring in the first token for the arg list*/	  	} /* end if VMODIFIER */		/*	 	 *	Code to process an argument list	 	 */		ap = arglist;		xp = explist;		} /* end if VINSTn */	else {		auxval = val;		/*	 	 *	Code to process an argument list	 	 */		ap = arglist;		xp = explist;	

⌨️ 快捷键说明

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