|
|
1.1 ! root 1: /* ! 2: * instruction decoding ! 3: * VAX instructions; works only on a VAX for now ! 4: */ ! 5: ! 6: #include "defs.h" ! 7: #include "space.h" ! 8: ! 9: #define LOBYTE 0377 ! 10: ! 11: /* instruction printing */ ! 12: ! 13: /* ! 14: * Argument access types ! 15: */ ! 16: #define ACCA (8<<3) /* address only */ ! 17: #define ACCR (1<<3) /* read */ ! 18: #define ACCW (2<<3) /* write */ ! 19: #define ACCM (3<<3) /* modify */ ! 20: #define ACCB (4<<3) /* branch displacement */ ! 21: #define ACCI (5<<3) /* XFC code */ ! 22: ! 23: /* ! 24: * Argument data types ! 25: */ ! 26: #define TYPB 0 /* byte */ ! 27: #define TYPW 1 /* word */ ! 28: #define TYPL 2 /* long */ ! 29: #define TYPQ 3 /* quad */ ! 30: #define TYPF 4 /* floating */ ! 31: #define TYPD 5 /* double floating */ ! 32: ! 33: typedef struct optab *OPTAB; ! 34: struct optab { ! 35: char *iname; ! 36: char val; ! 37: char nargs; ! 38: char argtype[6]; ! 39: } optab[]; ! 40: char *regname[]; ! 41: char *fltimm[]; ! 42: static ADDR incp; ! 43: ! 44: int ioptab[256]; /* index by opcode to optab */ ! 45: ! 46: mkioptab() {/* set up ioptab */ ! 47: register OPTAB p=optab; ! 48: ! 49: while (p->iname){ ! 50: ioptab[p->val&LOBYTE]=p-optab; ! 51: p++; ! 52: } ! 53: } ! 54: ! 55: printins(idsp) ! 56: { ! 57: register short argno; /* argument index */ ! 58: register short mode; /* mode */ ! 59: register char **r; /* register name */ ! 60: register unsigned char ins; ! 61: long d; /* assembled byte, word, long or float */ ! 62: long snarf(); ! 63: register char * ap; ! 64: register OPTAB ip; ! 65: ! 66: ins = cget(dot, idsp); ! 67: chkerr(); ! 68: ip=optab+ioptab[ins]; ! 69: printf("%s%8t",ip->iname); ! 70: incp = 1; ! 71: ap = ip->argtype; ! 72: for (argno=0; argno<ip->nargs; argno++,ap++) { ! 73: var[argno] = 0x80000000; ! 74: if (argno!=0) printc(','); ! 75: top: ! 76: if (*ap&ACCB) ! 77: mode = 0xAF + ((*ap&7)<<5); /* branch displacement */ ! 78: else{ ! 79: mode = cget(inkdot((WORD)incp), idsp); ! 80: chkerr(); ! 81: ++incp; ! 82: } ! 83: if (mode & 0300) {/* not short literal */ ! 84: r = ®name[mode&0xF]; ! 85: mode >>= 4; ! 86: switch ((int)mode) { ! 87: case 4: /* [r] */ ! 88: printf("[%s]",*r); ! 89: goto top; ! 90: case 5: /* r */ ! 91: printf("%s",*r); ! 92: break; ! 93: case 6: /* (r) */ ! 94: printf("(%s)",*r); ! 95: break; ! 96: case 7: /* -(r) */ ! 97: printf("-(%s)",*r); ! 98: break; ! 99: case 9: /* *(r)+ */ ! 100: printc('*'); ! 101: case 8: /* (r)+ */ ! 102: if (r==(regname+0xF)) { ! 103: printc('$'); ! 104: if (mode==9){ /* PC absolute, always 4 bytes*/ ! 105: d = snarf(4, idsp); ! 106: goto disp; ! 107: } ! 108: switch(*ap&7){ ! 109: case TYPB: ! 110: d = snarf(1, idsp); ! 111: goto disp; ! 112: case TYPW: ! 113: d = snarf(2, idsp); ! 114: goto disp; ! 115: case TYPL: ! 116: d = snarf(4, idsp); ! 117: goto disp; ! 118: case TYPQ: ! 119: d = snarf(4, idsp); ! 120: printquad(d, snarf(4, idsp)); ! 121: break; ! 122: case TYPF: ! 123: printfloating(snarf(4, idsp), 0L); ! 124: break; ! 125: case TYPD: ! 126: d = snarf(4, idsp); ! 127: printfloating(d, snarf(4, idsp)); ! 128: break; ! 129: } /*end of type switch */ ! 130: /* ! 131: * here only for TYPQ, TYPf, TYPD ! 132: * others went to disp ! 133: */ ! 134: } else { /*it's not PC immediate or abs*/ ! 135: printf("(%s)+",*r); ! 136: } ! 137: break; ! 138: case 0xB: /* byte displacement defferred*/ ! 139: printc('*'); ! 140: case 0xA: /* byte displacement */ ! 141: d = snarf(1, idsp); ! 142: goto disp; ! 143: case 0xD: /* word displacement deferred */ ! 144: printc('*'); ! 145: case 0xC: /* word displacement */ ! 146: d = snarf(2, idsp); ! 147: goto disp; ! 148: case 0xF: /* long displacement deferred */ ! 149: printc('*'); ! 150: case 0xE: /* long displacement */ ! 151: d = snarf(4, idsp); ! 152: goto disp; ! 153: disp: ! 154: var[argno]=d; ! 155: if (r==(regname+0xF) && mode>=0xA){ ! 156: /* PC offset addressing */ ! 157: var[argno] += dot+incp; ! 158: } ! 159: psymoff(var[argno],ANYSP,""); ! 160: if (r != regname+0xF) ! 161: printf("(%s)",*r); ! 162: break; ! 163: } /* end of the mode switch */ ! 164: } else { /* short literal */ ! 165: var[argno]=mode; ! 166: if((*ap&7)==TYPF || (*ap&7)==TYPD) ! 167: printf("$%s",fltimm[mode]); ! 168: else ! 169: printf("$%r",mode); ! 170: } ! 171: } ! 172: if (ins==0xCF || ins==0xAF || ins==0x8F) {/* CASEx instr */ ! 173: for (argno=0; argno<=var[2]; ++argno) { ! 174: printc(EOR); ! 175: printf(" %R: ",argno+var[1]); ! 176: d=sget(inkdot((WORD)incp+argno+argno),idsp); ! 177: if (d&0x8000) d -= 0x10000; ! 178: psymoff((WORD)(inkdot((WORD)incp)+d),ANYSP,""); ! 179: } ! 180: incp += var[2]+var[2]+2; ! 181: } ! 182: dotinc=incp; ! 183: } ! 184: ! 185: /* ! 186: * magic values to mung an offset to a register into ! 187: * something that psymoff can understand.. all magic ! 188: */ ! 189: /* 0 1 2 3 4 */ ! 190: static long magic_masks[5] = { ! 191: 0, 0x80, 0x8000, 0, 0}; ! 192: static long magic_compl[5] = { ! 193: 0, 0x100, 0x10000,0, 0}; ! 194: ! 195: static ! 196: long ! 197: snarf(nbytes, idsp) ! 198: int nbytes; ! 199: { ! 200: register int byteindex; ! 201: union Long{ ! 202: char long_bytes[4]; ! 203: long long_value; ! 204: } d; ! 205: ! 206: d.long_value = 0; ! 207: for (byteindex = 0; byteindex < nbytes; byteindex++){ ! 208: d.long_bytes[byteindex] = cget(inkdot((WORD)incp), idsp); ! 209: chkerr(); ! 210: ++incp; ! 211: } ! 212: if (d.long_value & magic_masks[nbytes]) ! 213: d.long_value -= magic_compl[nbytes]; ! 214: return(d.long_value); ! 215: } ! 216: ! 217: static ! 218: printfloating(word_first, word_last) ! 219: long word_first; ! 220: long word_last; ! 221: { ! 222: union Double{ ! 223: struct { ! 224: long word_first; ! 225: long word_last; ! 226: } composite; ! 227: double dvalue; ! 228: } reconstructed; ! 229: ! 230: reconstructed.composite.word_first = word_first; ! 231: reconstructed.composite.word_last = word_last; ! 232: fpout('F', (char *)&reconstructed.dvalue); ! 233: } ! 234: ! 235: static ! 236: printquad(word_first, word_last) ! 237: long word_first; ! 238: long word_last; ! 239: { ! 240: union Quad { ! 241: char quad_bytes[8]; ! 242: long quad_long[2]; ! 243: } reconstructed; ! 244: int leading_zero = 1; ! 245: int byteindex; ! 246: int nibbleindex; ! 247: register int ch; ! 248: ! 249: reconstructed.quad_long[0] = word_first; ! 250: reconstructed.quad_long[1] = word_last; ! 251: for (byteindex = 7; byteindex >= 0; --byteindex){ ! 252: for (nibbleindex = 4; nibbleindex >= 0; nibbleindex -= 4){ ! 253: ch = (reconstructed.quad_bytes[byteindex] ! 254: >> nibbleindex) & 0x0F; ! 255: if ( ! (leading_zero &= (ch == 0) ) ){ ! 256: if (ch <= 0x09) ! 257: printc(ch + '0'); ! 258: else ! 259: printc(ch - 0x0A + 'a'); ! 260: } ! 261: } ! 262: } ! 263: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.