|
|
1.1 ! root 1: /* a6 -- pdp-11 assembler pass 2 */ ! 2: #include "as2.h" ! 3: #define BR 0400 ! 4: #define JMP 0100 ! 5: ! 6: struct adr { ! 7: int xval; /* index value */ ! 8: int xrel; /* index reloc. */ ! 9: struct expr *xsym; /* index global */ ! 10: } adrbuf[2]; ! 11: struct adr *adrp; ! 12: ! 13: opline(op) ! 14: OP op; ! 15: { ! 16: struct expr x; ! 17: register int w,src,dst,rlimit,swapf,t; ! 18: ! 19: if (ISCHAR(op)) { ! 20: if (op.v==5) {/* file name of source */ ! 21: register char *cp=argb; ! 22: line=1; ! 23: while ((unsigned)(t=getw())<0200) if (cp<(argb+sizeof(argb))) *cp++=t; ! 24: *cp++='\n'; *cp++='\0'; return; ! 25: } ! 26: if (op.v=='<') goto opl17; ! 27: xpr: ! 28: x=expres(op); outw(x.typ,x.val); return; ! 29: } ! 30: t=op.xp->typ; ! 31: if (t==T_REG || t==T_ESTTXT || t==T_ESTDAT || t<T_FLOPD || t>T_JXX) goto xpr; ! 32: w=op.xp->val; ! 33: op=readop(); adrp=adrbuf; swapf=0; rlimit= 07777; ! 34: switch (t) { ! 35: case T_REG: ! 36: case T_ESTTXT: ! 37: case T_ESTDAT: ! 38: goto xpr; ! 39: ! 40: case T_MUL: swapf++; rlimit=01000; goto opl13; ! 41: case T_FLOPF: swapf++; ! 42: case T_FLOPD: rlimit=0400; ! 43: case T_DOUBLE: ! 44: opl13: src=addres(); ! 45: op2a: readop(); /* prime the pump */ ! 46: op2b: dst=addres(); ! 47: if (swapf) {t=src; src=dst; dst=t;} ! 48: if ((src<<=6)>=rlimit) error('x'); ! 49: outw(0,w|src|dst); ! 50: { ! 51: register struct adr *p; ! 52: for (p=adrbuf; p<adrp; p++) { ! 53: xsymbol=p->xsym; outw(p->xrel,p->xval); ! 54: } ! 55: } ! 56: return; ! 57: case T_SINGLE: src=0; goto op2b; ! 58: ! 59: case T_MOVF: ! 60: rlimit=0400; ! 61: if ((src=addres())>=4) swapf++; /* src is freg */ ! 62: else w=0174000; ! 63: goto op2a; ! 64: case T_JBR: ! 65: case T_JXX: ! 66: x=expres(op); ! 67: if (passno==0) { ! 68: if (0!=(t=setbr(x.val)) && w!=BR) t+=2; ! 69: *dot+=t+2; return; ! 70: } else { ! 71: if (getbr()==0) goto dobranch; ! 72: if (w!=BR) outw(T_ABS,w^0402); /* flip jump to .+6 */ ! 73: outw(T_ABS,JMP+037); outw(x.typ,x.val); return; ! 74: } ! 75: case T_SOB: ! 76: x=expres(op); chkreg(&x); w |= x.val<<6; x=expres(readop()); ! 77: if (passno==0) {outw(0,w|x.val); return;} ! 78: if ((x.val= *dot-x.val)<-2 || x.val>0175) {error('b'); outw(0,w); return;} ! 79: x.val+=4; goto f1; ! 80: case T_BRANCH: ! 81: x=expres(op); ! 82: if (passno!=0) { ! 83: dobranch: ! 84: if ((x.val-= *dot)<-254 || x.val>256) {error('b'); outw(0,w); return;} ! 85: f1: ! 86: if (x.val&1 || x.typ!= *dotrel) {error('b'); outw(0,w); return;} ! 87: outw(0,w|(((x.val>>1)-1)&0377)); return; ! 88: } ! 89: outw(0,w|x.val); return; ! 90: case T_JSR: x=expres(op); chkreg(&x); src=x.val; goto op2a; ! 91: case T_RTS: x=expres(op); chkreg(&x); outw(0,w|x.val); return; ! 92: case T_SYS: ! 93: x=expres(op); if ((unsigned)x.val>=256 || x.typ>T_ABS) errora(); ! 94: outw(x.typ,w|x.val); return; ! 95: case T_BYTE: ! 96: for (;;) { ! 97: x=expres(op); outb(x.typ,x.val); if (!LAST(',')) return; ! 98: op=readop(); ! 99: } ! 100: case T_STRING: ! 101: opl17: ! 102: for (;;) { ! 103: if ((unsigned)(t=getw())>=0600) {getw(); return;} ! 104: outb(T_ABS,t&0377); ! 105: } ! 106: case T_EVEN: ! 107: if (*dot&1) { ! 108: if (*dotrel!=T_BSS) outb(0,0); ! 109: else (*dot)++; ! 110: } ! 111: return; ! 112: ! 113: case T_IF: x=expres(op); ! 114: case T_ENDIF: return; ! 115: ! 116: case T_GLOBL: ! 117: for (;;) if (!ISCHAR(op)) { ! 118: op.xp->typ |= T_EXTERN; ! 119: op=readop(); if (!LAST(',')) break; ! 120: op=readop(); ! 121: } else break; ! 122: return; ! 123: ! 124: case T__TEXT: ! 125: case T__DATA: ! 126: case T__BSS: ! 127: *dot=(*dot+1)&~1; ! 128: savdot[*dotrel-T_TEXT] = *dot; ! 129: if (passno!=0 && t!=T__BSS) { ! 130: fseek(txtf,tseek[t-T__TEXT],0); ! 131: fseek(relf,rseek[t-T__TEXT],0); ! 132: } ! 133: *dot = savdot[t-T__TEXT]; ! 134: *dotrel = t-T__TEXT+T_TEXT; ! 135: return; ! 136: ! 137: case T_COMM: ! 138: if (!ISCHAR(op)) { ! 139: readop(); x=expres(readop()); ! 140: if ((op.xp->typ&037)==T_UNDEF) { ! 141: op.xp->typ |= T_EXTERN; op.xp->val=x.val; ! 142: } ! 143: } ! 144: return; ! 145: } ! 146: } ! 147: ! 148: addres() /* returns 6-bit pdp-11 addressing mode */ ! 149: { ! 150: register int indir=0; ! 151: struct expr x; ! 152: ! 153: again: ! 154: if (LAST('(')) { ! 155: x=expres(readop()); chkreg(&x); chkrp(); ! 156: if (!LAST('+')) { ! 157: if (indir!=0) {/* concession for "*(r)" meaning "*0(r)" */ ! 158: adrp->xval=0; adrp->xrel=0; adrp->xsym=xsymbol; adrp++; ! 159: return(x.val|070); ! 160: } else return(010|x.val); ! 161: } ! 162: readop(); return(indir|020|x.val); ! 163: } else if (LAST('-')) { ! 164: readop(); ! 165: if (!LAST('(')) { ! 166: savop=lastop; lastop.v='-'; /* fall through to end of else-if */ ! 167: } else { ! 168: x=expres(readop()); chkreg(&x); chkrp(); ! 169: return(indir|040|x.val); ! 170: } ! 171: } else if (LAST('$')) { ! 172: x=expres(readop()); ! 173: adrp->xval=x.val; adrp->xrel=x.typ; adrp->xsym=xsymbol; adrp++; ! 174: return(indir|027); ! 175: } else if (LAST('*')) { ! 176: if (indir) error('*'); ! 177: indir=010; readop(); goto again; ! 178: } ! 179: x=expres(lastop); ! 180: if (LAST('(')) { ! 181: adrp->xval=x.val; adrp->xrel=x.typ; adrp->xsym=xsymbol; adrp++; ! 182: x=expres(readop()); chkreg(&x); chkrp(); ! 183: return(indir|060|x.val); ! 184: } ! 185: if (x.typ==T_REG) { ! 186: chkreg(&x); return(indir|x.val); ! 187: } else { ! 188: x.typ|=PCREL; x.val=x.val-*dot-4; if (adrp!=adrbuf) x.val-=2; ! 189: adrp->xval=x.val; adrp->xrel=(unsigned short)x.typ; adrp->xsym=xsymbol; adrp++; ! 190: return(indir|067); ! 191: } ! 192: } ! 193: ! 194: errora() ! 195: { ! 196: error('a'); ! 197: } ! 198: ! 199: chkreg(p) ! 200: register struct expr *p; ! 201: { ! 202: if (((unsigned)p->val)>7 || (p->typ!=T_ABS && ((unsigned)p->typ)<=T_BSS)) { ! 203: errora(); p->typ=0; p->val=0; ! 204: } ! 205: } ! 206: ! 207: errore() ! 208: { ! 209: error('e'); ! 210: } ! 211: ! 212: chkrp() ! 213: { ! 214: if (!LAST(')')) {error(')'); return;} ! 215: readop(); ! 216: } ! 217: ! 218: #define BRLEN 1024 ! 219: char brtab[BRLEN/8]; ! 220: char bit[8] = {1,2,4,8,16,32,64,128}; ! 221: int brtabp; ! 222: ! 223: setbr(d) ! 224: register int d; ! 225: { ! 226: register int t; ! 227: ! 228: if (brtabp>=BRLEN) return(2); ! 229: t=brtabp++; ! 230: if ((d-= *dot)>0) d-=brdelt; ! 231: if (d>=-254 && d<=256) return(0); ! 232: brtab[t>>3] |= bit[t&7]; ! 233: return(2); ! 234: } ! 235: ! 236: getbr() ! 237: { ! 238: register int t; ! 239: ! 240: if (brtabp>=BRLEN) return(1); ! 241: t=brtabp++; ! 242: return(brtab[t>>3]&bit[t&7]); ! 243: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.