Bell 32V development
authorTom London <tbl@research.uucp>
Wed, 21 Mar 1979 12:27:38 +0000 (07:27 -0500)
committerTom London <tbl@research.uucp>
Wed, 21 Mar 1979 12:27:38 +0000 (07:27 -0500)
Work on file usr/src/cmd/as/as0.y
Work on file usr/src/cmd/as/as1.c
Work on file usr/src/cmd/as/as2.c
Work on file usr/src/cmd/as/as3.c

Co-Authored-By: John Reiser <jfr@research.uucp>
Synthesized-from: 32v

usr/src/cmd/as/as0.y [new file with mode: 0644]
usr/src/cmd/as/as1.c [new file with mode: 0644]
usr/src/cmd/as/as2.c [new file with mode: 0644]
usr/src/cmd/as/as3.c [new file with mode: 0644]

diff --git a/usr/src/cmd/as/as0.y b/usr/src/cmd/as/as0.y
new file mode 100644 (file)
index 0000000..3eafbd8
--- /dev/null
@@ -0,0 +1,803 @@
+%token COLON
+%token PLUS MINUS
+%token MUL DIV
+%token IOR XOR AND
+%token TILDE LSH RSH
+%token LITOP REGOP
+%token CM NL LB RB LP RP MP SEMI
+%token INT NAME REG
+%token NOCHAR SP ALPH DIG SQ SH
+%token INST0 INSTn IJXXX
+%token ISPACE IBYTE IWORD IINT ILONG
+%token IDATA IGLOBAL ISET ITEXT ICOMM ILCOMM IALIGN
+%token IFLOAT IDOUBLE IORG
+%token ISTAB
+%token ILSYM
+%token FLTNUM
+%token NOTYET
+
+%nonassoc COLON
+%left PLUS MINUS
+%left IOR XOR AND
+%left MUL DIV LSH RSH TILDE
+
+%{
+#include <stdio.h>
+#include "as.h"
+#include "as.yh"
+static char AS0[]="@(#)as0.y 1.16 79/03/21 22:27:23"; /* SCCS id */
+struct arg *ap = { arglist};
+struct exp     *xp = { explist};
+int    i, ii;
+long   li;
+struct exp     usedot[];
+struct exp     *dotp = &usedot[0];
+int    anyerrs;
+int argcnt;
+int    passno  = 1;
+FILE   *tmpfil;
+FILE   *relfil;
+FILE   *txtfil;
+int    hshused;
+long   tsize;
+long   dsize;
+long   bitfield;
+int    bitoff;
+int    usrname;
+int lclname;
+struct symtab *lastnam;
+char   yytext[NCPS+2];
+char   sname[8];
+struct symtab  *stpt;
+%}
+
+%%
+
+%{
+       struct exp *pval;
+%}
+
+wholefile: file = {
+               curlen = NBPW/4;
+               flushfield(NBPW/4);
+       }
+
+file:  /* empty */ = {
+               goto reset;
+       }
+       | file linstruction NL = {
+               lineno++;
+               goto reset;
+       }
+       | file linstruction SEMI = {
+               goto reset;
+       }
+       | file error NL = {
+               lineno++;
+               yyerrok;
+       reset:
+               ap = arglist; argcnt=0;
+               xp = explist;
+               usrname = 0;
+       }
+       ;
+
+labels:                /* empty */
+       | labels NAME COLON = {
+               flushfield(NBPW/4);
+               if (($2->type&XTYPE)!=XUNDEF) {
+                       if(($2->type&XTYPE)!=dotp->xtype || $2->value!=dotp->xvalue
+                        || passno==1 && $2->index != dotp->xloc)
+                               if ($2->name[0] != 'L' || $2->name[1] != 'L')
+                                       yyerror("%.8s redefined", $2->name);
+               }
+               $2->type &= ~(XTYPE|XFORW);
+               $2->type |= dotp->xtype;
+               $2->value = dotp->xvalue;
+               if (passno==1)
+                       $2->index = dotp-usedot;
+       }
+       ;
+
+linstruction:  labels instruction
+               ;
+
+instruction:
+       ISET NAME CM expr = {
+               $2->type &= (XXTRN|XFORW);
+               $2->type |= $4->xtype&(XTYPE|XFORW);
+               $2->value = $4->xvalue;
+               if (passno==1)
+                       $2->index = $4->xloc;
+               if (($4->xtype&XTYPE)==XUNDEF)
+                       yyerror("Illegal set");
+       }
+       | setlcl NAME CM expr = {
+               if ($4->xtype!=XABS) yyerror("Illegal lsym");
+               $2->value=$4->xvalue; $2->type=XABS;
+       }
+       | IGLOBAL NAME = {
+               $2->type |= XXTRN;
+       }
+       | IDATA = {
+               i = -IDATA;
+               goto chloc;
+       }
+       | IDATA expr = {
+               i = IDATA;
+               goto chloc;
+       }
+       | ITEXT = {
+               i = -ITEXT;
+               goto chloc;
+       }
+       | ITEXT expr = {
+               i = ITEXT;
+       chloc:
+               if (i < 0) {
+                       ii = 0;
+                       i = -i;
+               } else {
+                       if ($2->xtype != XABS || (ii=$2->xvalue) >= NLOC) {
+                               yyerror("illegal location counter");
+                               ii = 0;
+                       }
+               }
+               if (i == IDATA)
+                       ii += NLOC;
+               flushfield(NBPW/4);
+               dotp = &usedot[ii];
+               if (passno==2) {
+                       if (usefile[ii] == NULL) {
+                               tmpn2[TMPC] = 'a'+ii;
+                               if ((usefile[ii]=fopen(tmpn2, "w"))==NULL) {
+                                       yyerror("cannot create temp");
+                                       delexit();
+                               }
+                               tmpn3[TMPC] = 'a'+ii;
+                               if ((rusefile[ii]=fopen(tmpn3, "w"))==NULL) {
+                                       yyerror("cannot create temp");
+                                       delexit();
+                               }
+                       }
+                       txtfil = usefile[ii];
+                       relfil = rusefile[ii];
+               }
+       }
+       | IBYTE setchar explist = {
+               flushfield(NBPW/4);
+               if (bitoff)
+                       dotp->xvalue++;
+       }
+       | ILONG setlong explist = {
+               flushfield(NBPW);
+       }
+       | IINT setlong explist = {
+               flushfield(NBPW);
+       }
+       | IWORD setword explist = {
+               flushfield(NBPW/2);
+       }
+       | ISPACE expr = {
+               if ($2->xtype != XABS)
+                       yyerror("space size not absolute");
+               li = $2->xvalue;
+       ospace:
+               flushfield(NBPW/4);
+               while (--li>=0) outb(0);
+       }
+       | IORG expr = {
+               if ($2->xtype==XABS)
+                       orgwarn++;
+               else if ($2->xtype!=dotp->xtype)
+                       yyerror("Illegal 'org'");
+               li = $2->xvalue - dotp->xvalue;
+               if (li < 0)
+                       yyerror("Backwards 'org'");
+               goto ospace;
+       }
+       | ISTAB expr CM expr CM expr CM expr CM expr CM expr CM expr CM expr CM
+               expr CM expr CM expr CM expr = {
+               if (passno == 1) 
+                       if ($18->xvalue & STABTYPS) {
+                               struct symtab *p;
+                               stpt = symalloc();
+                               stpt->name[0] = $2->xvalue;
+                               stpt->name[1] = $4->xvalue;
+                               stpt->name[2] = $6->xvalue;
+                               stpt->name[3] = $8->xvalue;
+                               stpt->name[4] = $10->xvalue;
+                               stpt->name[5] = $12->xvalue;
+                               stpt->name[6] = $14->xvalue;
+                               stpt->name[7] = $16->xvalue;
+                               stpt->ptype = $18->xvalue;
+                               stpt->other = $20->xvalue;
+                               stpt->desc = $22->xvalue;
+                               p = $24->xname;
+                               if(p == NULL) {
+                                       stpt->value = $24->xvalue;
+                               }
+                               else {
+                                       stpt->value = $24->xname;
+                                       stpt->index = p->index;
+                                       stpt->type = p->type | 0200;
+/*
+printf("FORWARD REF FOR .STAB...\n");
+printf("value (xname) = %x value(value(xname) = %x\n", stpt->value, stpt->value->value);
+printf("name: %.8s\n\n", (stpt->value)->name);
+*/
+                               }
+                       }
+                       else yyerror("Invalid type in .stab");
+       }
+       | comm NAME CM expr = {
+               if ($4->xtype != XABS)
+                       yyerror("comm size not absolute");
+               if (passno==1 && ($2->type&XTYPE)!=XUNDEF)
+                       yyerror("Redefinition of %.8s", $2->name);
+               if (passno==1) {
+                       $2->value = $4->xvalue;
+                       if ($1==ICOMM)
+                               $2->type |= XXTRN;
+                       else {
+                               $2->type &= ~XTYPE;
+                               $2->type |= XBSS;
+                       }
+               }
+       }
+       | IALIGN expr = {
+               jalign($2);
+       }
+       | INST0 = {
+               insout($1, 0, 0);
+       }
+       | INSTn args = {
+               insout($1, arglist, argcnt);
+       }
+       | IJXXX args = {
+               insout($1, arglist, -argcnt);
+       }
+       | floating flist
+       |  /* empty */
+       ;
+
+comm:  ICOMM = {
+               $$ = ICOMM;
+       }
+       | ILCOMM = {
+               $$ = ILCOMM;
+       }
+       ;
+explist: /* empty */
+       | explist CM outexpr
+       | outexpr
+       ;
+
+outexpr: expr = {
+               i = curlen;
+               pval = $1;
+               flushfield(curlen);
+               goto outx;
+       }
+       | expr COLON expr = {
+               if ($1->xtype != XABS)
+                       yyerror("Width expression not absolute");
+               i = $1->xvalue;
+               pval = $3;
+               if (bitoff+i > curlen)
+                       flushfield(curlen);
+               if (i > curlen)
+                       yyerror("Expression crosses field boundary");
+       outx:
+                if ((pval->xtype&XTYPE)!=XABS) {
+                       if (bitoff) yyerror("Illegal relocation in field");
+                       i=LEN1+!PCREL;
+                       if (curlen==NBPW) i=LEN4+!PCREL; if (curlen==NBPW/2) i=LEN2+!PCREL;
+                       outrel(&pval->xvalue,i,pval->xtype,pval->xname);
+               } else {
+                       li = pval->xvalue & ((1L<<i)-1);
+                       bitfield |= li << bitoff; bitoff += i;
+               }
+               ap = arglist;
+               xp = explist;
+       }
+
+floating: IFLOAT = {
+               curlen = 4;
+       }
+       | IDOUBLE = {
+               curlen = 8;
+       }
+
+flist: /* empty */
+       | flist CM fltout
+       | fltout
+       ;
+
+fltout:        FLTNUM = {
+               dotp->xvalue += curlen;
+               if (passno==2)
+                       putflt($1, curlen);
+       }
+       ;
+
+setlcl: ILSYM = {
+               lclname=1;
+       }
+
+setchar: = {
+               curlen = NBPW/4;
+       }
+
+setlong: = {
+               curlen = NBPW;
+       }
+
+setword: = {
+               curlen = NBPW/2;
+       }
+
+args:  arg = {if(++argcnt>6) yyerror("More than 6 arguments"); ++ap;}
+       | args CM arg = {if(++argcnt>6) yyerror("More than 6 arguments"); ++ap;}
+       ;
+arg:   reg = {
+               ap->atype = AREG;
+               ap->areg1 = $1;
+       }
+       | argb1 LB reg RB = {
+               ap->atype |= AINDX;
+               ap->areg2 = $3;
+       }
+       | argb1
+       ;
+argb1: MP reg RP = {
+               ap->atype = ADECR;
+               ap->areg1 = $2;
+       }
+       | MUL argb2 = {
+               if (ap->atype == ABASE) {/* concession for *(%r) meaning *0(%r) */
+                       ap->atype = ADISP; xp->xtype = XABS; xp->xvalue = 0; xp->xloc = 0;
+                       ap->xp = xp++;
+               }
+               ap->atype |= ASTAR;
+       }
+       | argb2
+       ;
+argb2: expr = {
+               ap->atype = AEXP;
+               ap->xp = $1;
+               ap->areg1 = 0;
+       }
+       |       LP reg RP = {
+               ap->atype = ABASE;
+               ap->areg1 = $2;
+       }
+       | expr LP reg RP = {
+               ap->atype = ADISP;
+               ap->xp = $1;
+               ap->areg1 = $3;
+       }
+       | LP reg RP PLUS = {
+               ap->atype = AINCR;
+               ap->areg1 = $2;
+       }
+       | LITOP expr = {
+               ap->atype = AIMM;
+               ap->areg1 = 0;
+               ap->xp = $2;
+       }
+       ;
+
+reg:
+       REG
+       | REGOP expr = {
+               if (passno==2 && (($2->xtype&XTYPE)!=XABS || $2->xvalue<0 || $2->xvalue>=16))
+                       yyerror("Illegal register");
+               $$ = $2->xvalue;
+       };
+
+expr:  NAME = {
+               $$ = xp++;
+               $$->xtype = $1->type;
+               if (($1->type&XTYPE)==XUNDEF) {
+                       $$->xname = $1;
+                       $$->xvalue = 0;
+                       if (passno==1)
+                               $1->type |= XFORW;
+               } else {
+                       $$->xvalue = $1->value;
+                       $$->xname = NULL;
+               }
+       }
+       | INT = {
+               $$ = xp++;
+               $$->yvalue = 0;
+               $$->xtype = XABS;
+               $$->xvalue = * (long *)$1;
+               $$->xloc = 0;
+               $$->xname = NULL;
+       }
+       | FLTNUM = {
+               $$ = xp++;
+               $$->yvalue = * (((long *)$1)+1);
+               $$->xtype = XABS;
+               $$->xvalue = * (long *)$1;
+               $$->xloc = 0;
+               $$->xname = NULL;
+       }
+       | LP expr RP = {
+               $$ = $2;
+       }
+       | expr PLUS expr = {
+               goto comb;
+       }
+       | expr MINUS expr = {
+               goto comb;
+       }
+       | expr TILDE expr = {
+               goto comb;
+       }
+       | expr IOR expr = {
+               goto comb;
+       }
+       | expr XOR expr = {
+               goto comb;
+       }
+       | expr AND expr = {
+               goto comb;
+       }
+       | expr LSH expr = {
+               goto comb;
+       }
+       | expr RSH expr = {
+               goto comb;
+       }
+       | expr MUL expr = {
+               goto comb;
+       }
+       | expr DIV expr = {
+       comb:
+               $$ = combine($2, $1, $3);
+       }
+       | nothing MINUS expr = {
+               goto comb;
+       }
+       | nothing TILDE expr = {
+               goto comb;
+       }
+       | REG = {
+       sugar:
+               $$ = xp++;
+               $$->xtype = XABS;
+               $$->xvalue = $1 & 0xFF;
+               $$->xloc = 0;
+       }
+       | INST0 = {goto sugar;}
+       | INSTn = {goto sugar;}
+       ;
+
+nothing: = {
+               $$ = xp++;
+               $$->xtype = XABS;
+               $$->xvalue = 0;
+       }
+
+%%
+
+yyerror(s, a)
+char *s;
+{
+       if (anyerrs==0)
+               fprintf(stderr, "Assembler:\n");
+       anyerrs++;
+       fprintf(stderr, "line %d: ", lineno);
+       fprintf(stderr, s, a);
+       fprintf(stderr, "\n");
+       yyerrok;
+}
+
+/*
+ * Tables for combination of operands.
+ */
+
+/* table for + */
+readonly char pltab[6][6] = {
+/*     UND     ABS     TXT     DAT     BSS     EXT */
+/*UND*/        XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
+/*ABS*/        XUNDEF, XABS,   XTEXT,  XDATA,  XBSS,   XXTRN,
+/*TXT*/        XUNDEF, XTEXT,  ERR,    ERR,    ERR,    ERR,
+/*DAT*/        XUNDEF, XDATA,  ERR,    ERR,    ERR,    ERR,
+/*BSS*/        XUNDEF, XBSS,   ERR,    ERR,    ERR,    ERR,
+/*EXT*/        XUNDEF, XXTRN,  ERR,    ERR,    ERR,    ERR,
+};
+
+/* table for - */
+readonly char mintab[6][6] = {
+/*     UND     ABS     TXT     DAT     BSS     EXT */
+/*UND*/        XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
+/*ABS*/        XUNDEF, XABS,   ERR,    ERR,    ERR,    ERR,
+/*TXT*/        XUNDEF, XTEXT,  XABS,   ERR,    ERR,    ERR,
+/*DAT*/        XUNDEF, XDATA,  ERR,    XABS,   ERR,    ERR,
+/*BSS*/        XUNDEF, XBSS,   ERR,    ERR,    XABS,   ERR,
+/*EXT*/        XUNDEF, XXTRN,  ERR,    ERR,    ERR,    ERR,
+};
+
+/* table for other operators */
+readonly char othtab[6][6] = {
+/*     UND     ABS     TXT     DAT     BSS     EXT */
+/*UND*/        XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
+/*ABS*/        XUNDEF, XABS,   ERR,    ERR,    ERR,    ERR,
+/*TXT*/        XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
+/*DAT*/        XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
+/*BSS*/        XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
+/*EXT*/        XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
+};
+
+struct exp *
+combine(op, r1, r2)
+register struct exp *r1, *r2;
+{
+       register t1, t2, type, loc;
+
+       lastnam=0; /* kluge for jxxx instructions */
+       t1 = r1->xtype&XTYPE;
+       t2 = r2->xtype&XTYPE;
+       if (r1->xtype==XXTRN+XUNDEF)
+               t1 = XTXRN;
+       if (r2->xtype==XXTRN+XUNDEF)
+               t2 = XTXRN;
+       if (passno==1)
+               if (r1->xloc!=r2->xloc && t1==t2)
+                       t1 = t2 = XTXRN;        /* error on != loc ctrs */
+       t1 >>= 1;
+       t2 >>= 1;
+       switch (op) {
+
+       case PLUS:
+               r1->xvalue += r2->xvalue;
+               type = pltab[t1][t2];
+               break;
+
+       case MINUS:
+               r1->xvalue -= r2->xvalue;
+               type = mintab[t1][t2];
+               break;
+
+       case IOR:
+               r1->xvalue |= r2->xvalue;
+               goto comm;
+
+       case XOR:
+               r1->xvalue ^= r2->xvalue;
+               goto comm;
+
+       case AND:
+               r1->xvalue &= r2->xvalue;
+               goto comm;
+
+       case LSH:
+               r1->xvalue <<= r2->xvalue;
+               goto comm;
+
+       case RSH:
+               r1->xvalue >>= r2->xvalue;
+               goto comm;
+
+       case TILDE:
+               r1->xvalue |= ~ r2->xvalue;
+               goto comm;
+
+       case MUL:
+               r1->xvalue *= r2->xvalue;
+               goto comm;
+
+       case DIV:
+               if (r2->xvalue == 0)
+                       yyerror("Divide check");
+               else
+                       r1->xvalue /= r2->xvalue;
+               goto comm;
+
+       comm:
+               type = othtab[t1][t2];
+               break;
+
+       default:
+               yyerror("Internal error: unknown operator");
+       }
+       if (t2==(XTXRN>>1))
+               r1->xname = r2->xname;
+       r1->xtype = type | (r1->xtype|r2->xtype)&(XFORW|XXTRN);
+       if (type==ERR)
+               yyerror("Relocation error");
+       return(r1);
+}
+
+readonly short type[] = {
+       EOF,
+       SP,     0,      0,      0,      0,      0,      0,      0,
+       0,      SP,     NL,     0,      0,      SP,     0,      0,
+       0,      0,      0,      0,      0,      0,      0,      0,
+       0,      0,      0,      0,      0,      0,      0,      0,
+       SP,     0,      0,      SH,     LITOP,  REG,    AND,    SQ,
+       LP,     RP,     MUL,    PLUS,   CM,     MINUS,  ALPH,   DIV,
+       DIG,    DIG,    DIG,    DIG,    DIG,    DIG,    DIG,    DIG,
+       DIG,    DIG,    COLON,  SEMI,   LSH,    0,      RSH,    0,
+       0,      ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
+       ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
+       ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
+       ALPH,   ALPH,   ALPH,   LB,     0,      RB,     XOR,    ALPH,
+       0,      ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
+       ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
+       ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
+       ALPH,   ALPH,   ALPH,   0,      IOR,    0,      TILDE,  0,
+};
+
+yylex()
+{
+       register short val;
+       register base;
+       register char *cp;
+       struct symtab *op;
+       static long intval;
+       static double fltval;
+       char fltchr[64];
+
+       if (passno!=1) {
+               val = get2(tmpfil);
+               if (val==NAME)
+                       fread(&yylval, sizeof(yylval), 1, tmpfil);
+               else if (val==INT) {
+                       fread(&intval, sizeof(intval), 1, tmpfil);
+                       yylval = &intval;
+               } else if (val==FLTNUM) {
+                       fread(&fltval, sizeof(fltval), 1, tmpfil);
+                       yylval = &fltval;
+               } else
+                       yylval = get2(tmpfil);
+               return(val);
+       }
+loop:
+       switch(yylval = (type+1)[val = getchar()]) {
+
+       case SH:
+               while ((val = getchar()) != '\n' && val>0)
+                       ;
+               val = NL;
+               goto ret;
+
+       case SP:
+               goto loop;
+
+       case REG:
+               val = getchar();
+               if (val>='0' && val<='9') {
+                       yylval = val-'0';
+                       if (val=='1') {
+                               if ((val = getchar())>='0' && val<='5')
+                                       yylval = 10+val-'0';
+                               else
+                                       ungetc(val, stdin);
+                       }
+                       while ((val = getchar()) == '+' || val=='-' ) {
+                               if (val=='+')
+                                       yylval++;
+                               else
+                                       yylval--;
+                       }
+                       ungetc(val, stdin);
+                       val = REG;
+               } else {
+                       ungetc(val, stdin);
+                       val = REGOP;
+               }
+               goto ret;
+
+       case EOF:
+               val = 0;
+               goto ret;
+
+       case ALPH:
+               cp = yytext;
+               do {
+                       if (cp <= &yytext[NCPS])
+                               *cp++ = val;
+               } while ((type+1)[val=getchar()]==ALPH || (type+1)[val]==DIG);
+               *cp = '\0';
+               while (val=='\t' || val==' ')
+                       val = getchar();
+               ungetc(val, stdin);
+               base = 1;
+               if (val==':') {
+                       base = usrname;
+                       usrname = 1;
+               }
+               if ((op = *lookup(1))->tag) {
+                       yylval = op->type;
+                       val = op->tag+256;
+                       goto ret;
+               } else {
+                       lastnam = yylval = op;
+                       usrname = base;
+                       val = NAME;
+                       goto ret;
+               }
+
+       case DIG:
+               intval = val-'0';
+               if (val=='0') {
+                       val = getchar();
+                       if (val=='x' || val=='X') {
+                               base = 16;
+                       } else if (val=='d' || val=='D' || val=='f' || val=='F') {
+                               char *p = fltchr;
+                               double atof();
+                               while (p < &fltchr[63] && ((val=getchar())=='.'
+                                || val=='e' || val=='d' || val=='E' || val=='D'
+                                || val=='-' || val=='+' || (type+1)[val]==DIG))
+                                       *p++ = val;
+                               ungetc(val, stdin);
+                               *p++ = '\0';
+                               fltval = atof(fltchr);
+                               val = FLTNUM;
+                               goto ret;
+                       } else {
+                               ungetc(val, stdin);
+                               base = 8;
+                       }
+               } else
+                       base = 10;
+               while ((type+1)[val=getchar()]==DIG
+                   || (base==16 && (val>='a' && val<='f'||val>='A' && val<='F'))) {
+                       if (base==8)
+                               intval <<= 3;
+                       else if (base==10)
+                               intval *= 10;
+                       else
+                               intval <<= 4;
+                       if (val>='a' && val<='f')
+                               val -= 'a' - 10 - '0';
+                       else if (val>='A' && val<='F')
+                               val -= 'A' - 10 - '0';
+                       intval += val-'0';
+               }
+               ungetc(val, stdin);
+               val = INT;
+               goto ret;
+
+       case MINUS:
+               if ((val = getchar())=='(') yylval=val=MP;
+               else {ungetc(val,stdin); val=MINUS;}
+               goto ret;
+
+       case SQ:
+               if ((yylval = getchar()) == '\n')
+                       lineno++;
+               intval = yylval;
+               val = INT;
+               goto ret;
+
+       case 0:
+               yyerror("Illegal character");
+               val = NOCHAR;
+               goto ret;
+
+       default:
+               val = yylval;
+               goto ret;
+       }
+ret:
+       put2(val, tmpfil);
+       if (val==NAME)
+               fwrite(&yylval, sizeof(yylval), 1, tmpfil);
+       else if (val==INT) {
+               fwrite(&intval, sizeof(intval), 1, tmpfil);
+               yylval = &intval;
+       } else if (val==FLTNUM) {
+               fwrite(&fltval, sizeof(fltval), 1, tmpfil);
+               yylval = &fltval;
+       } else
+               put2(yylval, tmpfil);
+       return(val);
+}
+
diff --git a/usr/src/cmd/as/as1.c b/usr/src/cmd/as/as1.c
new file mode 100644 (file)
index 0000000..14b9fbb
--- /dev/null
@@ -0,0 +1,491 @@
+#
+char AS1[] = "@(#)as1.c 1.21 79/03/21 22:27:27";       /* sccs ident */
+#include <stdio.h>
+#include <signal.h>
+#include <a.out.h>
+#include "as.h"
+#include "as.yh"
+
+int    curlen;
+int    lineno  = 1;
+long   datbase;
+struct symtab *nextsym,*rovjxxx;
+char *endcore;
+struct hdr hdr = {
+       0410, 0, 0, 0, 0, 0, 0, 0,
+};
+
+#ifndef vax
+       struct {short hiword; short loword;}; /* stupid fp-11 */
+#endif
+
+writel(p,n,f) long *p; FILE *f; {
+#ifdef vax
+       fwrite(p,sizeof(*p),n,f);
+#else
+       while (n--) {
+               fwrite(&(*p).loword,2,1,f);
+               fwrite(&(*p).hiword,2,1,f);
+               p++;
+       }
+#endif
+}
+
+symwrite(p,n,f) struct symtab *p; FILE *f; {
+#ifdef vax
+       while (n--) {
+               fwrite(&(p->name[0]), sizeof(symtab[0].name), 1, f);
+               fwrite(p->ptype ? &(p->ptype) : &(p->type),
+                       sizeof(symtab[0].type), 1, f);
+               fwrite(&(p->other), sizeof(symtab[0].other), 1, f);
+               fwrite(&(p->desc), sizeof(symtab[0].desc), 1, f);
+               fwrite(&(p->value), sizeof(symtab[0].value), 1, f);
+               p++;
+       }
+#else
+       while (n--) {
+               fwrite(p,sizeof(symtab[0])-sizeof(p->value),1,f);
+               writel(&(p->value),1,f); p++;
+       }
+#endif
+}
+
+char   *tmpn1;
+char   *tmpn2;
+char   *tmpn3;
+struct exp     usedot[NLOC+NLOC];
+FILE   *usefile[NLOC+NLOC];
+FILE   *rusefile[NLOC+NLOC];
+extern char _sibuf[BUFSIZ],_sobuf[BUFSIZ];
+extern short njxxx;
+extern int d124;
+
+main(argc, argv)
+char **argv;
+{
+       int symcmp();
+       register struct instab *ip;
+       register struct symtab *sp;
+       int c;
+       long v;
+       register struct symtab **hp;
+       char *outfile = "a.out";
+       int infound = 0;
+       int delexit();
+
+       while (argc > 1) {
+               if (argv[1][0]=='-' && argv[1][1]=='o') {
+                       if (argc <3) {
+                               yyerror("-o what?");
+                               exit(1);
+                       }
+                       outfile = argv[2];
+                       argc -= 2;
+                       argv += 2;
+                       continue;
+               }
+               if (argv[1][0]=='-' && argv[1][1]=='d') {
+                       d124=argv[1][2]-'0';
+                       if (d124!=1 && d124!=2 && d124!=4) {
+                               yyerror("-d[124] only"); exit(1);
+                       }
+                       argc--; argv++; continue;
+               }
+               if (infound) {
+                       yyerror(">1 argument.");
+                       exit(1);
+               }
+               infound++;
+               if (freopen(argv[1], "r", stdin) == NULL) {
+                       yyerror("as: Can't open %s\n", argv[1]);
+                       exit(2);
+               }
+               setbuf(stdin,_sibuf);
+               argc--;
+               argv++;
+       }
+       nextsym=symtab=endcore=sbrk(0); rovjxxx= nextsym-1;
+       c = -1;
+       for (ip=instab; ip->name[0]!=0; ip++) {
+               register char *p1, *p2;
+               for (p1=ip->name,p2=yytext; p2<yytext+NCPS;)
+                       *p2++ = *p1++;
+               *p2++ = 0;
+               usrname = 0;
+               hp = lookup(0);
+               if (*hp==NULL) {
+                       *hp = ip;
+                       if (ip->tag!=(INSTn-256) && ip->tag!=(INST0-256) && ip->tag!=0)
+                               continue; /* was pseudo-op */
+/*                     c++;
+/*                     if (c>=NINST) {
+/*                             yyerror("Instruction table overflow");
+/*                             continue;
+/*                     }
+*/
+                       itab[ip->opcode&0xFF] = ip; /* given opcode, find instruction */
+               }
+       }
+       for (c=0; c<NLOC; c++) {
+               usedot[c].xtype = XTEXT;
+               usedot[c+NLOC].xtype = XDATA;
+       }
+       if (signal(SIGINT, SIG_IGN) != SIG_IGN)
+               signal(SIGINT, delexit);
+       tmpn1 = mktemp("/tmp/asXXXXX");
+       tmpfil = fopen(tmpn1, "w");
+       if (tmpfil==NULL) {
+               yyerror("Bad temp1file");
+               delexit();
+       }
+       setbuf(tmpfil,_sobuf);
+       yyparse();
+       if (anyerrs)
+               delexit();
+       jxxxfix();
+       stabfix();
+       fclose(tmpfil);
+       tmpfil = fopen(tmpn1, "r");
+       if (tmpfil==NULL) {
+               yyerror("Bad tmp1file (r)");
+               delexit();
+       }
+       setbuf(tmpfil,_sibuf);
+       /* round and assign text segment origins */
+       tsize = 0;
+       for (c=0; c<NLOC; c++) {
+               v = round(usedot[c].xvalue, FW);
+               usedot[c].xvalue = tsize;
+               tsize += v;
+       }
+       /* round and assign data segment origins */
+       datbase = round(tsize, PAGRND);
+       for (c=0; c<NLOC; c++) {
+               v = round(usedot[NLOC+c].xvalue, FW);
+               usedot[NLOC+c].xvalue = datbase+dsize;
+               dsize += v;
+       }
+       hdr.bsize = dsize;
+       /* assign final values to symbols */
+       for (sp=symtab; sp<nextsym; sp++) {
+               if ((sp->name[0]&0xFF)>=0xFE) continue; /* ignore jxxx entries */
+               if ((sp->type&XTYPE)==XUNDEF)
+                       sp->type = XXTRN+XUNDEF;
+               else if ((sp->type&XTYPE)==XDATA)
+                       sp->value += usedot[sp->index].xvalue;
+               else if ((sp->type&XTYPE)==XTEXT)
+                       sp->value += usedot[sp->index].xvalue;
+               else if ((sp->type&XTYPE)==XBSS) {
+                       long bs;
+                       bs = sp->value;
+                       sp->value = hdr.bsize + datbase;
+                       hdr.bsize += bs;
+               }
+       }
+       hdr.bsize -= dsize;
+       tmpn2 = mktemp("/tmp/aaatXXXXX");
+       txtfil = fopen(outfile, "w");
+       if (txtfil==NULL) {
+               yyerror("Cannot create %s", outfile);
+               delexit();
+       }
+       setbuf(txtfil,_sobuf);
+       usefile[0] = txtfil;
+       tmpn3 = mktemp("/tmp/abatXXXXX");
+       relfil = fopen(tmpn3, "w");
+       if (relfil==NULL) {
+               yyerror("temp file can't be opened");
+               delexit();
+       }
+       rusefile[0] = relfil;
+       hdr.tsize = tsize;
+       hdr.dsize = dsize;
+       hdr.ssize = 
+               (sizeof(symtab[0])-
+               (sizeof(symtab[0].tag)+sizeof(symtab[0].index)+
+                       sizeof(symtab[0].ptype)))*
+               (nextsym-symtab-njxxx);
+       /* hdr.trsize, hdr.drsize set by outrel */
+       writel(&hdr,8,txtfil);
+       tsize = 0;
+       dsize = 0;
+       lineno = 1;
+       dotp = &usedot[0];
+       passno = 2;
+/*
+       for (sp=symtab; sp<nextsym; sp++)
+               sp->index = 20000;
+*/
+       setindices();
+       yyparse();
+       /* round csects to FW */
+       for (c=0; c<NLOC; c++) {
+               if (usefile[c]) {
+                       txtfil=usefile[c]; dotp= &usedot[c];
+                       while (usedot[c].xvalue&FW) outb(0);
+                       if (c>0)
+                               fclose(usefile[c]);
+                       fclose(rusefile[c]);
+               }
+               if (usefile[NLOC+c]) {
+                       txtfil = usefile[NLOC+c]; dotp= &usedot[c+NLOC];
+                       relfil = rusefile[NLOC+c];
+                       while (usedot[c+NLOC].xvalue&FW) outb(0);
+                       fclose(txtfil);
+                       fclose(relfil);
+               }
+       }
+       txtfil = usefile[0];
+       /* append csect text onto text for csect 0 */
+       for (c=1; c<NLOC+NLOC; c++) {
+               register ch;
+               if (usefile[c]) {
+                       tmpn2[TMPC] = c+'a';
+                       relfil = fopen(tmpn2, "r");
+                       if (relfil==NULL) {
+                               yyerror("cannot reopen temp");
+                               continue;
+                       }
+                       while ((ch = getc(relfil))>=0)
+                               putc(ch, txtfil);
+                       fclose(relfil);
+               }
+       }
+       /* append relocation info onto text */
+       for (c=0; c<NLOC+NLOC; c++) {
+               register ch;
+               if (rusefile[c]) {
+                       tmpn3[TMPC] = c+'a';
+                       relfil = fopen(tmpn3, "r");
+                       if (relfil==NULL) {
+                               yyerror("cannot reopen temp");
+                               continue;
+                       }
+                       while ((ch = getc(relfil))>=0)
+                               putc(ch, txtfil);
+                       fclose(relfil);
+               }
+       }
+       remjxxx();
+/*
+       qsort(symtab, nextsym-symtab, sizeof(symtab[0]), symcmp);
+*/
+       for (sp=symtab; sp<nextsym; sp++) {
+               sp->type &= ~XFORW;
+               sp->index = 0;
+       }
+       symwrite(symtab, nextsym-symtab, txtfil);
+       fseek(txtfil,0L,0); /* a little half-passedness here to get rsize correct */
+       writel(&hdr,8,txtfil);
+       delete();
+       if (anyerrs==0 && orgwarn)
+               yyerror("Caution: absolute origins.\n");
+       exit(anyerrs!=0);
+}
+
+
+delexit()
+{
+       delete();
+       exit(1);
+}
+
+delete()
+{
+       register c;
+
+       if (tmpn1)
+               unlink(tmpn1);
+       for (c=0; c<NLOC+NLOC; c++) {
+               if (tmpn2) {
+                       tmpn2[TMPC] = c+'a';
+                       unlink(tmpn2);
+               }
+               if (tmpn3) {
+                       tmpn3[TMPC] = c+'a';
+                       unlink(tmpn3);
+               }
+       }
+}
+
+struct symtab *
+symalloc() {
+if((char *)++nextsym>=endcore) {
+       register int *p;
+       if(-1==sbrk(200*sizeof(*symtab)))
+               {yyerror("Memory overflow"); delexit();}
+       p=endcore += 200*sizeof(*symtab); while (p>(char *)nextsym) *--p=0;
+}
+/*if(++nextsym-symtab>NSYM) yyerror("Symbol table overflow");
+*/
+return(nextsym-1);
+}
+
+struct symtab **
+lookup(instflg)
+{
+       register int ihash; int un;
+       register struct symtab **hp;
+       register char *p1, *p2;
+       static struct symtab *local;
+
+       if (lclname!=0) {
+               lclname=0;
+               *(hp= &local) = symalloc();
+               p1=yytext; p2=(*hp)->name;
+               while (*p2++ = *p1++);
+               return(hp);
+       }
+       un = usrname;
+       usrname = 1;
+       ihash = 0;
+       p1 = yytext;
+       while (*p1) {
+               ihash += ihash + *p1++;
+       }
+       ihash &= 077777;
+       while (p1<yytext+NCPS)
+               *p1++ = 0;
+       hp = &hshtab[ihash%NHASH];
+       while (*hp) {
+               if (hp>=symtab && (*hp)->ptype) {
+                       printf("IGNORING LOOKUP %s %x %x %x\n",
+                       (*hp)->name, (*hp)->ptype, (*hp)->type, (*hp)->type & STABTYPS);
+                       goto no;
+                       }
+               p2 = (*hp)->name;
+               for (p1=yytext; p1<yytext+NCPS;)
+                       if (*p1++ != *p2++)
+                               goto no;
+/*             if (un == ((*hp)->tag==0)) */
+                       return(hp);
+       no:
+               if (++hp >= &hshtab[NHASH])
+                       hp = hshtab;
+       }
+       if(++hshused >= NHASH) {
+               yyerror("Symbol table overflow");
+               delexit();
+       }
+       if (instflg) {
+               *hp = symalloc();
+               for (p1=yytext,p2=(*hp)->name; p1<yytext+NCPS;)
+                       *p2++ = *p1++;
+       }
+       return(hp);
+}
+
+outb(val) {dotp->xvalue++; if (passno==2) fwrite(&val,1,1,txtfil);}
+
+int reflen[] = {0,0,1,1,2,2,4,4,8,8};
+
+outrel(pval,reftype,reltype,xsym)
+long *pval; register int reftype,reltype; struct symtab *xsym; {
+/* reftype: PCREL or not, plus length LEN1, LEN2, LEN4, LEN8
+/* reltype: csect ("segment") number (XTEXT, XDATA, ...) associated with 'val'
+/* xsym: symbol table pointer
+*/
+long ts; char tc;
+long tl;
+short t;
+if (passno!=2) {
+       dotp->xvalue += reflen[reftype]; return;
+}
+if (bitoff&07) yyerror("Padding error");
+reltype &= ~XFORW;
+if (reltype==XUNDEF) yyerror("Undefined reference");
+if (reltype!=XABS || reftype&PCREL) {
+       /* write the address portion of a relocation datum */
+       if (dotp>= &usedot[NLOC]) {
+               hdr.drsize += sizeof(dotp->xvalue) + 3 + sizeof tc;
+               tl=dotp->xvalue-datbase; writel(&tl,1,relfil);
+       } else {
+               hdr.trsize += sizeof(dotp->xvalue) + 3 + sizeof tc;
+               writel(&dotp->xvalue,1,relfil);
+       }
+       /* write the properties portion of a relocation datum */
+       if (reltype==XXTRN+XUNDEF) {
+               setindex(xsym);
+               ts=(xsym->index);
+               tc = (XXTRN<<3)|(reftype-LEN1);
+       } else if ((reltype&XTYPE)==XUNDEFO) {
+               setindex(xsym);
+               ts=(xsym->index);
+               tc = ((XXTRN+2)<<3)|(reftype-LEN1);
+       } else  {
+               ts=(reltype);
+               tc = (reftype-LEN1);
+       }
+       fwrite((char *)&ts, 3, 1, relfil);
+       fwrite(&tc, sizeof(tc), 1, relfil);
+}
+/* write the raw ("unrelocated") value to the text file */
+t=reflen[reftype]; dotp->xvalue += t;
+if (reftype&PCREL) *pval -= dotp->xvalue;
+#ifdef vax
+       fwrite(pval,1,t,txtfil);
+#else
+       if (t>2) {
+               fwrite(&((*pval).loword),1,2,txtfil);
+               fwrite(&((*pval).hiword),1,t-2,txtfil);
+       } else fwrite(&((*pval).loword),1,t,txtfil);
+#endif
+}
+
+setindex(xsym)
+register struct symtab *xsym;
+{
+       return;
+/*     
+       if (xsym->index == 20000)
+               xsym->index = gindex++;
+       if (gindex >= 1023)
+               yyerror("Too many external symbols");
+*/
+}
+
+flushfield(n)
+{
+       if (bitoff==0) return;
+       n=((bitoff+n-1)/n)*n;
+       while (n>0) {outb((int)bitfield); bitfield >>= 8; n -= 8;}
+       bitoff=0; bitfield=0;
+}
+
+putflt(fp, s)
+double *fp;
+{fwrite(fp,1,s,txtfil);}
+
+symcmp(p, q)
+register struct symtab *p, *q;
+{
+       if (p->index < q->index)
+               return(-1);
+       if (p->index > q->index)
+               return(1);
+       if (p->value < q->value)
+               return(-1);
+       if (p->value > q->value)
+               return(1);
+       return(0);
+}
+
+stabfix() {
+       register struct symtab *sp;
+       register struct symtab *p;
+       
+       for(sp=symtab; sp<nextsym; sp++) {
+               if(sp->ptype && (sp->type & 0200)) {
+                       p = sp->value;
+                       sp->value = p->value;
+                       sp->index = p->index;
+                       sp->type = p->type;
+/*
+printf("STABFIX: %s (old %s) to %d offsets %d %d\n", sp->name, p->name, sp->value, sp, p);
+*/
+/*
+                       sp->ptype = (sp->ptype & STABTYPS) | (p->type & N_EXT);
+*/
+               }
+       }
+}
diff --git a/usr/src/cmd/as/as2.c b/usr/src/cmd/as/as2.c
new file mode 100644 (file)
index 0000000..9a24f1f
--- /dev/null
@@ -0,0 +1,352 @@
+#
+char AS2[] = "@(#)as2.c 1.29 79/03/21 22:27:31";       /* sccs ident */
+#include       <stdio.h>
+#include       "as.h"
+#define JBR 0x11
+#define BRW 0x31
+extern struct symtab *nextsym;
+struct tshdr {/* overlays symtab struct */
+       char tsflag; /* 0xFF==active, 0xFE==inactive */
+       char tsbump; /* 0->short, 1->long */
+       short tsfear; /* possible bump value */
+       short tsline; /* source line number, for debugging and error messages */
+       short dest;  /* symtab ordinal of destination label */
+       char type;
+       char tag;
+       short index; /* usetab ordinal of csect */
+       long value;  /* estimated PC of following instruction */
+       char    ptype;
+       char    other;
+       short   desc;
+};
+
+jxxxbump(ts1,displ) register struct tshdr *ts1; {
+register struct symtab *sp2;
+/* printf("\njxxxbump %d  %.8s",displ,symtab[ts1->dest].name);  */
+ts1->tsflag=0xFE; ts1->tsbump=1; /* no longer in doubt, alas */
+for (sp2=symtab; sp2<nextsym; sp2++)
+       if ((sp2->type&XTYPE)==ts1->type && sp2->index==ts1->index &&
+                       sp2->value>=ts1->value && sp2!=ts1) sp2->value += ts1->tsfear;
+usedot[ts1->index].xvalue += ts1->tsfear;
+}
+
+jxxxfix() {/* pass 1.5, resolve jxxx instructions and .align in .text */
+register struct tshdr *sp1; register struct symtab *sp2,*sp3;
+#define TUNNEL 4
+register struct tshdr *tunnel;
+register int displ,nchange;
+for (;;) {/* lazy topological sort */
+       nchange=0;
+       tunnel=0;
+       for (sp1=symtab; sp1<nextsym; sp1++) {
+               if (sp1->dest== -1) continue; /* .align in .text */
+               displ=sp1->tsflag&0xFF;
+               if (sp1->tsfear==1 || displ==0xFE && sp1->tsbump) tunnel=sp1;
+               if (displ<0xFF) continue;
+               sp2= &symtab[sp1->dest];
+               if (sp1->index!=sp2->index) {
+                       yyerror("Intersegment jxxx, line %d",sp1->tsline); continue;
+               }
+               displ=sp2->value - sp1->value;
+               if (displ<-128 || displ>127) {
+                       if (1<sp1->tsfear && tunnel && tunnel->dest==sp1->dest
+                         && tunnel->index==sp1->index
+                         && tunnel->value - sp1->value>=-125) {/* entrance is 3 back */
+                               sp1->tsfear=TUNNEL; sp1->dest=((struct symtab *)tunnel)-symtab;
+                               sp1->tsflag=0xFE; continue;
+                       } else {jxxxbump(sp1,displ); tunnel=sp1; ++nchange; continue;}
+               }
+                       /* immediate lose */
+               if (displ>=0) {/* forward search for intervening jxxx */
+                       for (sp3=sp1+1; sp3<nextsym; sp3++) {
+                               if ((((struct tshdr *)sp3)->tsflag&0xFF)<0xFF
+                                       || sp3->index!=sp1->index) continue;
+                               if (sp3->value > sp2->value) break; /* beyond destination */
+                               displ += sp3->tsfear; /* assume worst case */
+                       }
+                       if (displ<=127) sp1->tsflag=0xFE; /* win! */
+               } else {/* backward search for intervening jxxx */
+                       for (sp3=sp1-1; sp3>=symtab; sp3--) {
+                               if ((((struct tshdr *)sp3)->tsflag&0xFF)<0xFF
+                                       || sp3->index!=sp1->index) continue;
+                               if (sp3->value <= sp2->value) break; /* beyond destination */
+                               displ -= sp3->tsfear; /* assume worst case */
+                       }
+                       if (displ>=-128) sp1->tsflag=0xFE; /* win! */
+               }
+       }
+       if (nchange==0) break;
+}
+for (sp1=symtab; sp1<nextsym; sp1++) /* handle .align in .text */
+       if (sp1->dest== -1 && (displ = sp1->value & (unsigned)(sp1->tsfear)))
+               jxxxbump(sp1,sp1->tsfear -= displ-1);
+}
+
+short njxxx;
+struct symtab *lastnam;
+struct tshdr *rovjxxx /* = {symtab-1}*/ ;
+
+remjxxx() {/* remove jxxx entries from symbol table */
+register struct symtab *sp1,*sp2;
+for (sp1=symtab; sp1<nextsym; sp1++) {
+       if ((((struct tshdr *)sp1)->tsflag&0xFF)<0xFE) continue;
+       sp2=sp1; /* found first */
+       for (;;) {
+               register char *cp1,*cp2;
+               while ((((struct tshdr *)sp1)->tsflag&0xFF)>=0xFE) sp1++;
+               if (sp1>=nextsym) {nextsym=sp2; return;}
+               *sp2 = *sp1;
+               sp2++; sp1++;
+       }
+} njxxx=0;
+}
+
+ijxout(op,ap,nact) struct arg *ap; {/* handle jxxx instructions */
+register struct arg *aplast;
+aplast=ap+nact-1;
+if (passno!=2) {/* record the jxxx in a special symbol table entry */
+       register struct tshdr *ts2;
+       putins(op,ap,nact); /* assume minimal length */
+       ts2=(struct tshdr *)(symalloc()); ts2->tsflag=0xFF;
+       ts2->tsfear=3; if (op==JBR) ts2->tsfear=1;
+       ts2->tsline=lineno;
+       if (lastnam==0) yyerror("jxxx destination not a label");
+       ts2->dest=lastnam-symtab; ts2->type=dotp->xtype;
+       ts2->index=dotp-usedot; ts2->value=dotp->xvalue; njxxx++;
+} else {/* pass2, resolve */
+       register long displ; register struct exp *xp; register struct tshdr *sp;
+       /* forward search for special symbol table entry */
+       while (((++rovjxxx)->tsflag&0xFF)<0xFE);
+       xp=aplast->xp;
+       if (rovjxxx->tsfear==TUNNEL) {
+               sp= &symtab[rovjxxx->dest]; xp->xvalue=sp->value;
+               if (1==sp->tsfear) xp->xvalue -= 2; /* brw */
+       }
+       if (rovjxxx->tsbump==0) putins(op,ap,nact);
+       else {
+               if (op!=JBR) {
+                       displ=xp->xvalue; xp->xvalue=rovjxxx->value+rovjxxx->tsfear;
+                       putins(op^1,ap,nact); xp->xvalue=displ;
+               }
+               putins(BRW,aplast,1);
+       }
+}}
+
+jalign(xp) register struct exp *xp; {
+       if (xp->xtype != XABS || 0>xp->xvalue || xp->xvalue>16) {
+               yyerror("Illegal `align' argument"); return;
+       }
+       flushfield(NBPW/4);
+       if (dotp<(usedot+NLOC)) {/* .align in .text */
+               if (passno!=2) {/* record in symbol table entry */
+                       register struct tshdr *ts2;
+                       ts2=(struct tshdr *)(symalloc()); ts2->tsflag=0xFF;
+                       ts2->tsfear=(1<<xp->xvalue)-1; ts2->tsline=lineno;
+                       ts2->dest= -1; ts2->type=dotp->xtype;
+                       ts2->index=dotp-usedot; ts2->value=dotp->xvalue;
+                       njxxx++; return;
+               } else while (((++rovjxxx)->tsflag&0xFF)<0xFE);
+       }
+       while (dotp->xvalue & ((1<<xp->xvalue)-1)) outb(0);
+}
+
+insout(op, ap, nact)
+struct arg *ap;
+{
+       int jxxflg;
+
+       op &= 0xFF; if (0>(jxxflg=nact)) nact= -nact;
+       if (passno!=2) {
+               register struct arg *ap2; register struct instab *ip; int i,nexp;
+               ip=itab[op]; nexp=ip->nargs;
+               if (nact<nexp) yyerror("Too few arguments");
+               if (nact>nexp) {yyerror("Too many arguments"); nact=nexp;}
+               for (ap2=ap+nact, i=nact; --i>=0;) argcompat(--ap2,ip->argtyp[i],i);
+       }
+       if (jxxflg<0) ijxout(op,ap,nact);
+       else putins(op, ap, nact);
+}
+
+argcompat(act, exp, i)
+struct arg *act;
+int exp,i;
+{
+       register at,atm;
+
+       at = act->atype; atm=at&AMASK;
+
+       if ((exp&ACCA) && (atm==AREG)) {
+               yyerror("arg %d, addressing a register",i); return;}
+       if ((exp&ACCW) && (atm==AIMM) && !(at&ASTAR)) {
+               yyerror("arg %d, modifying a constant",i); return;}
+       if (at&AINDX) {
+               if (act->areg2==017) {
+                       yyerror("arg %d, PC used as index",i); return;}
+               if (atm==AREG) {
+                       yyerror("arg %d, indexing the register file",i); return;}
+               if (atm==AIMM) {
+                       yyerror("arg %d, indexing a constant",i); return;}
+               if (((atm==ADECR) || (atm==AINCR)) && (act->areg1==act->areg2)) {
+                       yyerror("arg %d, indexing with modified register",i); return;}
+       }
+}
+
+int d124 = {4};
+int len124[] = {0,LEN1,LEN2,0,LEN4};
+char mod124[] = {0,0x00,0x20,0,0x40};
+
+putins(op, ap, n)
+register struct arg *ap;
+{
+/* op had better be positive */
+       register struct exp *xp;
+       register int a; int i,xtrab;
+
+       if (passno!=2) {
+               dotp->xvalue += n+1;    /* 1 for the opcode, at least 1 per arg */
+               for (i=0; i<n; i++,ap++) {/* some args take more than 1 byte */
+                       a=ap->atype;
+                       if (a&AINDX) dotp->xvalue++;
+                       switch (a&~(AINDX|ASTAR)) {
+                               case AEXP: {
+                                       a=itab[op]->argtyp[i];
+                                       if (a==ACCB+TYPB) break;
+                                       if (a==ACCB+TYPW) {dotp->xvalue++; break;}
+                                       dotp->xvalue += d124; break;
+                               }
+                               case ADISP: {
+                                       xp=ap->xp;
+                                       if ((xp->xtype&XTYPE)!=XABS || xp->xtype&XFORW)
+                                               {dotp->xvalue += d124; break;}
+                                       if (xp->xvalue==0 && !(a&ASTAR)) break;
+                                       dotp->xvalue++;
+                                       if ((xp->xvalue<-128) || (xp->xvalue>127)) dotp->xvalue++;
+                                       if ((xp->xvalue<-32768) || (xp->xvalue>32767))
+                                               dotp->xvalue += 2;
+                                       break;
+                               }
+                               case AIMM: {
+                                       if (ap->atype&ASTAR) a=TYPL;
+                                       else {
+                                               xp=ap->xp;
+                                               if ((xp->xtype&XTYPE)==XABS && !(xp->xtype&XFORW)
+                                                       && xp->xvalue>=0 && xp->xvalue<=63) break;
+                                               a=itab[op]->argtyp[i];
+                                               if (a&ACCA) a=TYPL; else a &= TYPMASK;
+                                       }
+                                       switch (a) {
+                                               case TYPD: case TYPF:
+                                                       if (xp->yvalue==0 &&
+                                                          (xp->xvalue & 0x000043f0)==xp->xvalue) break;
+                                                       if (a==TYPF) dotp->xvalue -= 4;
+                                               case TYPQ: dotp->xvalue += 4;
+                                               case TYPL: dotp->xvalue += 2;
+                                               case TYPW: dotp->xvalue++;
+                                               case TYPB: dotp->xvalue++;
+                                       }
+                               }
+                       }
+               }
+               return;
+       }
+       /* pass2 here */
+       outb(op); /* the opcode */
+       for (i=0; i<n; i++,ap++) {/* now for the arguments */
+               a=ap->atype; xp=ap->xp; xtrab=0;
+               if (a&AINDX) {outb(0x40 | ap->areg2); a &= ~AINDX;}
+               if (a&ASTAR) {ap->areg1 |= 0x10; a &= ~ASTAR;}
+               switch (a) {
+                       case AREG:  ap->areg1 |= 0x50; break; /* %r */
+                       case ABASE: ap->areg1 |= 0x60; break; /* (%r) */
+                       case ADECR: ap->areg1 |= 0x70; break; /* -(%r) */
+                       case AINCR: ap->areg1 |= 0x80; break; /* (%r)+ */
+                       case AEXP: {/* expr */
+                               a=itab[op]->argtyp[i];
+                               if (a==ACCB+TYPB) {
+                                       ap->areg1=a=xp->xvalue - dotp->xvalue -1;
+                                       if (a<-128 || a>127) yyerror("Branch too far"); break;
+                               }
+                               if (a==ACCB+TYPW) {
+                                       ap->areg1=a=xp->xvalue -= dotp->xvalue +2; xp->xtype=XABS;
+                                       if (a<-32768 || a>32767) yyerror("Branch too far");
+                                       xp->xvalue = a>>8; xtrab=LEN1; break;
+                               }
+                               /* reduces to expr(pc) mode */
+                               ap->areg1 |= (0xAF+mod124[d124]); xtrab=len124[d124]+PCREL; break;
+                       }
+                       case ADISP: {/* expr(%r) */
+                               ap->areg1 |= 0xA0;
+                               if ((xp->xtype&XTYPE)!=XABS || xp->xtype&XFORW)
+                                       {ap->areg1 += mod124[d124]; xtrab=len124[d124]; break;}
+                               if (xp->xvalue==0 && !(ap->areg1&0x10)) {ap->areg1 ^= 0xC0; break;}
+                               xtrab=LEN1;
+                               if ((xp->xvalue<-128) || (xp->xvalue>127))
+                                       {ap->areg1 += 0x20; xtrab=LEN2;}
+                               if ((xp->xvalue<-32768) || (xp->xvalue>32767))
+                                       {ap->areg1 += 0x20; xtrab=LEN4;}
+                               break;
+                       }
+                       case AIMM: { /* $expr */
+                               if (ap->atype&ASTAR) a=TYPL;
+                               else {
+                                       if ((xp->xtype&XTYPE)==XABS && !(xp->xtype&XFORW) &&
+                                               xp->xvalue>=0 && xp->xvalue<=63) {ap->areg1=xp->xvalue; break;}
+                                       a=itab[op]->argtyp[i];
+                                       if (a&ACCA) a=TYPL; else a &= TYPMASK;
+                               }
+                               ap->areg1 |= 0x8F;
+                               switch (a) {
+                                       case TYPD: case TYPF:
+                                               if (xp->yvalue==0 &&
+                                                  (xp->xvalue & 0x000043f0)==xp->xvalue) {
+                                                       ap->areg1 = xp->xvalue>>4; break;
+                                               }
+                                               if (a==TYPF) {xtrab = LEN4; break;}
+                                       case TYPQ: xtrab = LEN8; break;
+                                       case TYPL: xtrab = LEN4; break;
+                                       case TYPW: xtrab = LEN2; break;
+                                       case TYPB: xtrab = LEN1; break;
+                               }
+                       }
+               }
+               outb(ap->areg1);/* first byte to describe arg */
+               if (xtrab) outrel(&xp->xvalue,xtrab,xp->xtype,xp->xname);
+       }
+}
+
+get2(f)
+register FILE *f;
+{
+       short r;
+       register char *p;
+       r = 0;
+       p = (char *)&r;
+       *p++ = getc(f);
+       *p = getc(f);
+       return(r);
+}
+
+put2(v, f)
+register FILE *f;
+short v;
+{
+       register char *p;
+       short lv;
+
+       p = (char *)&lv;
+       lv = v;
+       putc(*p++, f);
+       putc(*p, f);
+}
+
+setindices() {
+       register int i;
+       register struct symtab *sp;
+       
+       i = 0;
+       for (sp=symtab; sp<nextsym; sp++) {
+               if ((((struct tshdr *)sp)->tsflag&0xFF)<0xFE) {
+                       sp->index = i++;
+               }
+       }
+}
diff --git a/usr/src/cmd/as/as3.c b/usr/src/cmd/as/as3.c
new file mode 100644 (file)
index 0000000..1216117
--- /dev/null
@@ -0,0 +1,74 @@
+#
+char AS3[] = "@(#)as3.c 1.10 79/03/21 22:27:36";       /* sccs ident */
+#include <stdio.h>
+#include "as.h"
+#include "as.yh"
+
+#define OP(a,b,c,d,e,f,g,h,i) {a,b,(c==0 ? INST0-256:INSTn-256),c,d,e,f,g,h,i}
+
+readonly struct instab instab[] = {
+{".space", 0, ISPACE-256},
+{".byte", 0, IBYTE-256},
+{".word", 0, IWORD-256},
+{".long", 0, ILONG-256},
+{".int", 0, IINT-256},
+{".data", 0, IDATA-256},
+{".globl", 0, IGLOBAL-256},
+{".set", 0, ISET-256},
+{".text", 0, ITEXT-256},
+{".comm", 0, ICOMM-256},
+{".lcomm", 0, ILCOMM-256},
+{".lsym", 0, ILSYM-256},
+{".align", 0, IALIGN-256},
+{".float", 0, IFLOAT-256},
+{".double", 0, IDOUBLE-256},
+{".org", 0, IORG-256},
+{".stab", 0, ISTAB-256},
+{"r0",0,REG-256},
+{"r1",1,REG-256},
+{"r2",2,REG-256},
+{"r3",3,REG-256},
+{"r4",4,REG-256},
+{"r5",5,REG-256},
+{"r6",6,REG-256},
+{"r7",7,REG-256},
+{"r8",8,REG-256},
+{"r9",9,REG-256},
+{"r10",10,REG-256},
+{"r11",11,REG-256},
+{"r12",12,REG-256},
+{"r13",13,REG-256},
+{"r14",14,REG-256},
+{"r15",15,REG-256},
+{"ap",12,REG-256},
+{"fp",13,REG-256},
+{"sp",14,REG-256},
+{"pc",15,REG-256},
+{"jcc",0x1e,IJXXX-256},
+{"jcs",0x1f,IJXXX-256},
+{"jeql",0x13,IJXXX-256},
+{"jeqlu",0x13,IJXXX-256},
+{"jgeq",0x18,IJXXX-256},
+{"jgequ",0x1e,IJXXX-256},
+{"jgtr",0x14,IJXXX-256},
+{"jgtru",0x1a,IJXXX-256},
+{"jleq",0x15,IJXXX-256},
+{"jlequ",0x1b,IJXXX-256},
+{"jlss",0x19,IJXXX-256},
+{"jlssu",0x1f,IJXXX-256},
+{"jneq",0x12,IJXXX-256},
+{"jnequ",0x12,IJXXX-256},
+{"jvc",0x1c,IJXXX-256},
+{"jvs",0x1d,IJXXX-256},
+{"jbr",0x11,IJXXX-256},
+{"jbc",0xe1,IJXXX-256},
+{"jbs",0xe0,IJXXX-256},
+{"jbcc",0xe5,IJXXX-256},
+{"jbsc",0xe4,IJXXX-256},
+{"jbcs",0xe3,IJXXX-256},
+{"jbss",0xe2,IJXXX-256},
+{"jlbc",0xe9,IJXXX-256},
+{"jlbs",0xe8,IJXXX-256},
+#include "instrs"
+0
+};