📄 asparse.c
字号:
/************************************************************************ * * * Copyright (c) 1984, 1988 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//****************************************************************** * * Modification History * * 006 Tanya Klinchina, 20-Nov-1989 * Added support for vector instructions. * * 005 jlr, 21-Jun-1988 * Catch .space <negative-number> and give a message instead of * dumping core. * * 004 Jon Reeves, 13-Aug-1987 * Fix to change 002: a stab that referenced a defined variable * that had previously been forward referenced was getting the * variable's value doubled. * * 003 David L Ballenger, 24-Feb-1986 * Fix handling of .align statements so that fill expressions are * correctly handled. Also, move checking of the alignment * expressions to yyparse() in this module from jalign() in * asjxxx.c. * * 002- Victoria Holt, 07-May-85 * Fixed problem with N_LCSYM stabs. The code that processed * them only worked when the stab was making a forward * reference. Also fixed the "hack" that masked and shifted an * offset into the n_desc and n_other fields of the nlist to prevent * it from getting munged later. * * Rich Phillips, 02-Aug-84 * 001- Update the location counter on pass2 when processing a .fill. * It used to only update it for pass 1, causing relocation information * problems. * * Based on: asparse.c 4.17 7/1/83 * *******************************************************************/#ifndef lintstatic char sccsid[] = "@(#)asparse.c 4.4 ULTRIX 11/9/90";#endif /* not lint */#include <stdio.h>#include "as.h"#include "asscan.h"#include "assyms.h"#include "asexpr.h"int lgensym[10];char genref[10];long bitfield;int bitoff;int curlen; /* current length of literals *//* * The following three variables are communication between various * modules to special case a number of things. They are properly * categorized as hacks. */extern struct symtab *lastnam;/*last name seen by the lexical analyzer*/int exprisname; /*last factor in an expression was a name*/int droppedLP; /*one is analyzing an expression beginning with*/ /*a left parenthesis, which has already been*/ /*shifted. (Used to parse (<expr>)(rn)*/char yytext[NCPName+2]; /*the lexical image*/int yylval; /*the lexical value; sloppy typing*/struct Opcode yyopcode; /* lexical value for an opcode */Bignum yybignum; /* lexical value for a big number *//* * Expression and argument managers */struct exp *xp; /*next free expression slot, used by expr.c*/struct exp explist[NEXP]; /*max of 20 expressions in one opcode*/struct arg arglist[NARG]; /*building up operands in instructions*/struct arg varglist[NARG]; /*building up operands in vector instructions*/readonly struct Vinst_fmt vinst_fmt[FMTMAX] = { { /* FMT0 entry is not used */ 0, }, { /* FMT1 - VLD */ (MOE | MTF | MI), /* modifier mask */ 0, /* default modifiers */ 3, /* # instr operands */ { {VCTRL, 0, 0, VARG3}, /* cntrl.rw, vc */ {VOPND, VARG1}, /* base.ab */ {VOPND, VARG2}, /* stride.rl */ }, }, { /* FMT2 - VST */ (MOE | MTF), /* modifier mask */ 0, /* default modifiers */ 3, /* # instr opearands */ { {VCTRL, 0, 0, VARG1}, /* cntrl.rw, vc */ {VOPND, VARG2}, /* base.ab */ {VOPND, VARG3}, /* stride.rl */ }, }, { /* FMT3 - VGATH */ (MOE | MTF | MI), /* modifier mask */ 0, /* default modifiers */ 2, /* # instr opearands */ { {VCTRL, 0, VARG2, VARG3}, /* cntrl.rw, vb,vc */ {VOPND, VARG1}, /* base.ab */ }, }, { /* FMT4 - VSCAT */ (MOE | MTF), /* modifier mask */ 0, /* default modifiers */ 2, /* # instr opearands */ { {VCTRL, 0, VARG3, VARG1}, /* cntrl.rw, vc, vb */ {VOPND, VARG2}, /* base.ab */ }, }, { /* FMT5 - VVADD,VVSUB,VVMUL,VVDIV,VVSLLL */ (MOE | MTF | EXC), /* modifier mask */ 0, /* default modifiers */ 1, /* # instr opearands */ { {VCTRL, VARG1, VARG2, VARG3}, /* cntrl.rw, va, vb, vc */ }, }, { /* FMT6 - VVSLLL, VVSRLL, VVBISL, VVXORL, VVBICL */ (MOE | MTF), /* modifier mask */ 0, /* default modifiers */ 1, /* # instr opearands */ { {VCTRL, VARG1, VARG2, VARG3}, /* cntrl.rw, va, vb, vc */ }, }, { /* FMT7 - VVCMPx */ (MOE | MTF), /* modifier mask */ 0, /* default modifiers */ 1, /* # instr opearands */ { {VCTRL, VARG1, VARG2, VCODE}, /* cntrl.rw, va,vb,cmp */ }, }, { /* FMT8 - VVCVT */ (MOE | MTF | EXC), /* modifier mask */ 0, /* default modifiers */ 1, /* # instr opearands */ { {VCTRL, VCODE, VARG1, VARG2}, /* cntrl.rw, cvt,vb,vc */ }, }, { /* FMT9 - VVMERGE */ (MTF), /* modifier mask */ mtf_bit, /* default modifiers */ 1, /* # instr opearands */ { {VCTRL, VARG1, VARG2, VARG3}, /* cntrl.rw, va, vb, vc */ }, }, { /* FMT10- VSADDx,VSSUBx,VSMULx,VSDIVx */ (MOE | MTF | EXC), /* modifier mask */ 0, /* default modifiers */ 2, /* # instr opearands */ { {VCTRL, 0, VARG2, VARG3}, /* cntrl.rw, vb,vc */ {VOPND, VARG1}, /* scalar.ry */ }, }, { /* FMT11- VSSLLLx,VSSRLLx,VSBISLx,VSXORLx */ (MOE | MTF), /* modifier mask */ 0, /* default modifiers */ 2, /* # instr opearands */ { {VCTRL, 0, VARG2, VARG3}, /* cntrl.rw, vb,vc */ {VOPND, VARG1}, /* scalar.ry */ }, }, { /* FMT12 - VSCMPx */ (MOE | MTF), /* modifier mask */ 0, /* default modifiers */ 2, /* # instr opearands */ { {VCTRL, 0, VARG2, VCODE}, /* cntrl.rw, vb,cmp */ {VOPND, VARG1}, /* src.ry */ }, }, { /* FMT13 - VSMERGEx */ (MTF), /* modifier mask */ mtf_bit, /* default modifiers */ 2, /* # instr opearands */ { {VCTRL, 0, VARG2, VARG3}, /* cntrl.rw, vb,vc */ {VOPND, VARG1}, /* src.rq */ }, }, { /* FMT14 - IOTA */ (MTF), /* modifier mask */ mtf_bit, /* default modifiers */ 2, /* # instr opearands */ { {VCTRL, 0, 0, VARG2}, /* cntrl.rw, vc */ {VOPND, VARG1}, /* stride.rl */ }, }, { /* FMT15 - MTVP, MFVP */ 0, /* modifier mask */ 0, /* default modifiers */ 2, /* # instr opearands */ { {VLTRL, VCODE}, /* #leteral */ {VOPND, VARG1}, /* src/dst.wl */ }, }, { /* FMT16 - VSYNC */ 0, /* modifier mask */ 0, /* default modifiers */ 1, /* # instr opearands */ { {VLTRL, VCODE}, /* #literal */ }, }};/* * Sets to accelerate token discrimination */char tokensets[(LASTTOKEN) - (FIRSTTOKEN) + 1];static char UDotsname[64]; /*name of the assembly source*/yyparse(){ reg struct exp *locxp; /* * loc1xp and ptrloc1xp are used in the * expression lookahead */ struct exp *loc1xp; /*must be non register*/ struct exp **ptrloc1xp = & loc1xp; struct exp *pval; /*hacking expr:expr*/ reg struct symtab *np; reg int argcnt; reg inttoktype val; /*what yylex gives*/ reg inttoktype auxval; /*saves val*/ reg struct arg *ap; /*first free argument*/ reg struct symtab *p; reg struct symtab *stpt; struct strdesc *stringp; /*handles string lists*/ int regno; /*handles arguments*/ int *ptrregno = ®no; int sawmul; /*saw * */ int sawindex; /*saw [rn]*/ int sawsize; int seg_type; /*the kind of segment: data or text*/ int seg_number; /*the segment number*/ int space_value; /*how much .space needs*/ int fill_rep; /*how many reps for .fill */ int fill_size; /*how many bytes for .fill */ int field_width; /*how wide a field is to be*/ int field_value; /*the value to stuff in a field*/ char *stabname; /*name of stab dealing with*/ ptrall stabstart; /*where the stab starts in the buffer*/ int reloc_how; /* how to relocate expressions */ int toconv; /* how to convert bignums */ int incasetable; /* set if in a case table */ union Vinst_mod vmod; incasetable = 0; xp = explist; ap = arglist; val = yylex(); while (val != PARSEEOF){ /* primary loop */ while (INTOKSET(val, LINSTBEGIN)){ if (val == INT) { int i = ((struct exp *)yylval)->e_xvalue; shift; if (val != COLON){ yyerror("Local label %d is not followed by a ':' for a label definition", i); goto errorfix; } if (i < 0 || i > 9) { yyerror("Local labels are 0-9"); goto errorfix; } (void)sprintf(yytext, "L%d\001%d", i, lgensym[i]); lgensym[i]++; genref[i] = 0; yylval = (int)*lookup(passno == 1); val = NAME; np = (struct symtab *)yylval; goto restlab; } if (val == NL){ lineno++; shift; } else if (val == SEMI) shift; else { /*its a name, so we have a label or def */ if (val != NAME){ ERROR("Name expected for a label"); } np = (struct symtab *)yylval; shiftover(NAME); if (val != COLON) { yyerror("\"%s\" is not followed by a ':' for a label definition", FETCHNAME(np)); goto errorfix; }restlab: shift; flushfield(NBPW/4); if ((np->s_type&XTYPE)!=XUNDEF) { if( (np->s_type&XTYPE)!=dotp->e_xtype || np->s_value!=dotp->e_xvalue || ( (passno==1) &&(np->s_index != dotp->e_xloc) ) ){#ifndef DEBUG if (FETCHNAME(np)[0] != 'L')#endif /* not DEBUG */ { if (passno == 1) yyerror("%s redefined", FETCHNAME(np)); else yyerror("%s redefined: PHASE ERROR, 1st: %d, 2nd: %d", FETCHNAME(np), np->s_value, dotp->e_xvalue); } } } np->s_type &= ~(XTYPE|XFORW); np->s_type |= dotp->e_xtype; np->s_value = dotp->e_xvalue; if (passno == 1){ np->s_index = dotp-usedot; if (FETCHNAME(np)[0] == 'L'){ nlabels++; } np->s_tag = LABELID; } } /*end of this being a label*/ } /*end of to consuming all labels, NLs and SEMIS */ xp = explist; ap = arglist; /* * process the INSTRUCTION body */ switch(val){ default: ERROR("Unrecognized instruction or directive"); case IABORT: shift; sawabort(); /*NOTREACHED*/ break; case PARSEEOF: tokptr -= sizeof(bytetoktype); *tokptr++ = VOID; tokptr[1] = VOID; tokptr[2] = PARSEEOF; break; case IFILE: shift; stringp = (struct strdesc *)yylval; shiftover(STRING); dotsname = &UDotsname[0]; movestr(dotsname, stringp->sd_string, min(stringp->sd_strlen, sizeof(UDotsname))); break; case ILINENO: shift; /*over the ILINENO*/ expr(locxp, val); lineno = locxp->e_xvalue; break; case ISET: /* .set <name> , <expr> */ shift; np = (struct symtab *)yylval; shiftover(NAME); shiftover(CM); expr(locxp, val); np->s_type &= (XXTRN|XFORW); np->s_type |= locxp->e_xtype&(XTYPE|XFORW); np->s_value = locxp->e_xvalue; if (passno==1) np->s_index = locxp->e_xloc; if ((locxp->e_xtype&XTYPE) == XUNDEF) yyerror("Illegal set?"); break; case ILSYM: /*.lsym name , expr */ shift; np = (struct symtab *)yylval; shiftover(NAME); shiftover(CM); expr(locxp, val); /* * Build the unique occurance of the * symbol. * The character scanner will have * already entered it into the symbol * table, but we should remove it */ if (passno == 1){ stpt = (struct symtab *)symalloc(); stpt->s_name = np->s_name; np->s_tag = OBSOLETE; /*invalidate original */ nforgotten++; np = stpt; if ( (locxp->e_xtype & XTYPE) != XABS) yyerror("Illegal second argument to lsym"); np->s_value = locxp->e_xvalue; np->s_type = XABS; np->s_tag = ILSYM; } break; case IGLOBAL: /*.globl <name> */ shift; np = (struct symtab *)yylval; shiftover(NAME); np->s_type |= XXTRN; break; case IDATA: /*.data [ <expr> ] */ case ITEXT: /*.text [ <expr> ] */ seg_type = -val; shift; if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){ expr(locxp, val); seg_type = -seg_type; /*now, it is positive*/ } if (seg_type < 0) { /*there wasn't an associated expr*/ seg_number = 0; seg_type = -seg_type; } else { if ( ((locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ || (seg_number = locxp->e_xvalue) >= NLOC) { yyerror("illegal location counter"); seg_number = 0; } } if (seg_type == IDATA) seg_number += NLOC; flushfield(NBPW/4); dotp = &usedot[seg_number]; if (passno==2) { /* go salt away in pass 2*/ txtfil = usefile[seg_number]; relfil = rusefile[seg_number]; } break; /* * Storage filler directives: * * .byte [<exprlist>] * * exprlist: empty | exprlist outexpr * outexpr: <expr> | <expr> : <expr> */ case IBYTE: curlen = NBPW/4; goto elist; case IWORD: curlen = NBPW/2; goto elist; case IINT: curlen = NBPW; goto elist;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -