From cb3898cbb05dc46cff4d8632e00207aeb80e4490 Mon Sep 17 00:00:00 2001 From: Bill Joy Date: Thu, 14 Aug 1980 01:55:07 -0800 Subject: [PATCH] date and time created 80/08/13 18:55:07 by bill SCCS-vsn: old/as.vax/ascode.c 4.1 --- usr/src/old/as.vax/ascode.c | 335 ++++++++++++++++++++++++++++++++++++ 1 file changed, 335 insertions(+) create mode 100644 usr/src/old/as.vax/ascode.c diff --git a/usr/src/old/as.vax/ascode.c b/usr/src/old/as.vax/ascode.c new file mode 100644 index 0000000000..e5d9c50490 --- /dev/null +++ b/usr/src/old/as.vax/ascode.c @@ -0,0 +1,335 @@ +/* Copyright (c) 1980 Regents of the University of California */ +static char sccsid[] = "@(#)ascode.c 4.1 %G%"; +#include +#include +#include +#include "as.h" +#include "assyms.h" + +insout(op, ap, nact) + struct arg *ap; +{ + int jxxflg; + + op &= 0xFF; + jxxflg = nact; + if (nact < 0) + nact = -nact; + if (passno == 1) { + 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; + } + /* + * Check argument compatability with instruction template + */ + for (ap2 = ap+nact, i = nact; --i >= 0;) + argcompat(--ap2, ip->argtype[i], i+1); + } + 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 & ACCB) && (!((atm == AEXP) || (atm == AIMM))) ){ + yyerror("arg %d, branch displacement must be an expression",i); + return; + } + 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; + } + } +} + +extern int d124; + int len124[] = {0,LEN1,LEN2,0,LEN4}; + char mod124[] = {0,0x00,0x20,0,0x40}; + +putins(op, ap, n) + /* + * n had better be positive + */ + register struct arg *ap; +{ + register struct exp *xp; + register int a; + int i,xtrab; + +#ifdef DEBUG + fflush(stdout); +#endif + if (passno == 2) + goto PASS2; + + dotp->xvalue += n+1; /* 1 for the opcode, at least 1 per arg */ + for (i=0; iatype; + if (a & AINDX) + dotp->xvalue++; + switch (a&~(AINDX|ASTAR)) { + case AEXP: + a = itab[op]->argtype[i]; + if (a == ACCB+TYPB) + break; + if (a==ACCB+TYPW){ + dotp->xvalue++; + break; + } + /* + * Reduces to PC relative + */ + xtrab++; + dotp->xvalue += ap->dispsize; + break; + + case ADISP: + xp=ap->xp; + if ((xp->xtype&XTYPE)!=XABS || xp->xtype&XFORW){ + dotp->xvalue += ap->dispsize; + break; + } + if (xp->xvalue==0 && !(a&ASTAR)) + break; + dotp->xvalue++; + if ((xp->xvaluexvalue>MAXBYTE)) + dotp->xvalue++; + if ((xp->xvaluexvalue>MAXWORD)) + dotp->xvalue += 2; + break; + + case AIMM: + if (ap->atype&ASTAR) a=TYPL; + else { + a = itab[op]->argtype[i]; + if (a&ACCA) + a = TYPL; + else + a &= TYPMASK; + xp = ap->xp; + if ( ((xp->xtype&XTYPE)==XABS) + && (!(xp->xtype&XFORW)) + && (xp->xvalue>=0) + && (xp->xvalue<=63) + && (xp->yvalue == 0) + && (a != TYPD) + && (a != TYPF) + ) + break; + } + switch (a) { + case TYPD: + case TYPF: + if ( !(((xp->xtype&XTYPE)==XABS) + && (!(xp->xtype&XFORW)) + && (slitflt(xp))) + ){ + /* it is NOT short */ + dotp->xvalue += ((a==TYPF)? + 4 : 8); + } + break; + case TYPQ: + dotp->xvalue += 8;break; + case TYPL: + dotp->xvalue += 4;break; + case TYPW: + dotp->xvalue += 2;break; + case TYPB: + dotp->xvalue += 1;break; + } /*end of the switch on a*/ + } /*end of the switch on the type*/ + } /*end of looping for all arguments*/ + return; + +PASS2: + +#ifdef UNIX + outb(op); /* the opcode */ +#endif UNIX +#ifdef VMS + *vms_obj_ptr++ = -1; *vms_obj_ptr++ = (char)op; + dotp->xvalue += 1; +#endif VMS + + for (i=0; iatype; + xp=ap->xp; + xtrab=0; + if (a&AINDX) { +#ifdef UNIX + { outb(0x40 | ap->areg2); } +#endif UNIX +#ifdef VMS + { *vms_obj_ptr++ = -1; + *vms_obj_ptr++ = (0x40 | ap->areg2); + dotp->xvalue += 1; } +#endif VMS + a &= ~AINDX; + } + if (a&ASTAR) { + ap->areg1 |= 0x10; + a &= ~ASTAR; + } + switch (a) { + case AREG: /* %r */ + ap->areg1 |= 0x50; + break; + case ABASE: /* (%r) */ + ap->areg1 |= 0x60; + break; + case ADECR: /* -(%r) */ + ap->areg1 |= 0x70; + break; + case AINCR: /* (%r) */ + ap->areg1 |= 0x80; + break; + case AEXP: /* expr */ + a = itab[op]->argtype[i]; + if (a == ACCB+TYPB) { + ap->areg1 = a = + xp->xvalue - (dotp->xvalue + 1); + if (aMAXBYTE) + yyerror("Branch too far"); break; + } + if (a == ACCB+TYPW) { + ap->areg1 = a = xp->xvalue + -= dotp->xvalue + 2; + xp->xtype = XABS; + if (aMAXWORD) + yyerror("Branch too far"); + xp->xvalue = a>>8; + xtrab = LEN1; + break; + } + /* reduces to expr(pc) mode */ + ap->areg1 |= (0xAF + mod124[ap->dispsize]); + xtrab = len124[ap->dispsize]+PCREL; + break; + + case ADISP: /* expr(%r) */ + ap->areg1 |= 0xA0; + if ((xp->xtype&XTYPE)!=XABS || xp->xtype&XFORW){ + ap->areg1 += mod124[ap->dispsize]; + xtrab=len124[ap->dispsize]; + break; + } + if (xp->xvalue==0 && !(ap->areg1&0x10)) { + ap->areg1 ^= 0xC0; + break; + } + xtrab=LEN1; + if ((xp->xvaluexvalue>MAXBYTE)){ + ap->areg1 += 0x20; + xtrab=LEN2; + } + if ((xp->xvaluexvalue>MAXWORD)){ + ap->areg1 += 0x20; + xtrab=LEN4; + } + break; + + case AIMM: /* $expr */ + if (ap->atype&ASTAR) + a=TYPL; + else { + a = itab[op]->argtype[i]; + if (a&ACCA) + a=TYPL; + else + a &= TYPMASK; + if ( ( (xp->xtype&XTYPE) == XABS) + && !(xp->xtype&XFORW) + && (xp->xvalue >= 0) + && (xp->xvalue <= 63) + && (xp->yvalue == 0) + && (a != TYPF) + && (a != TYPD) ) { + ap->areg1 = xp->xvalue; + break; + } + } + ap->areg1 |= 0x8F; + switch (a) { + case TYPD: + case TYPF: + if ( ((xp->xtype&XTYPE)==XABS) + && (!(xp->xtype&XFORW)) + && (slitflt(xp)) + ){ + ap->areg1=extlitflt(xp); + } else { + xtrab = (a==TYPF) ? LEN4: LEN8; + } + break; + case TYPQ: xtrab = LEN8; break; + case TYPL: xtrab = LEN4; break; + case TYPW: xtrab = LEN2; break; + case TYPB: xtrab = LEN1; break; + } + break; + + } /*end of the switch on a*/ + /* + * use the first byte to describe the argument + */ +#ifdef UNIX + outb(ap->areg1); +#endif UNIX +#ifdef VMS + *vms_obj_ptr++ = -1; *vms_obj_ptr++ = (char)(ap->areg1); + dotp->xvalue += 1; + if ((vms_obj_ptr-sobuf) > 400) { + write(objfil,sobuf,vms_obj_ptr-sobuf); + vms_obj_ptr=sobuf+1; + } +#endif VMS + if (xtrab) + /* + * Floating point numbers are written to a.out + * by outrel; they require that the least significant + * 4 bytes of an 8 byte double precision number + * immediately follow the field xvalue, which + * they do. + */ + outrel(&xp->xvalue, xtrab, xp->xtype, xp->xname); + } /*end of the for to pick up all arguments*/ +} -- 2.20.1