|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)opset.c 4.2 10/27/82"; ! 3: #endif lint ! 4: /* ! 5: * UNIX debugger ! 6: * Instruction printing routines. ! 7: * MACHINE DEPENDENT ! 8: */ ! 9: ! 10: #ifdef ADB ! 11: #include "defs.h" ! 12: #endif ADB ! 13: #ifdef SDB ! 14: #include "head.h" ! 15: #endif SDB ! 16: ! 17: L_INT dot; ! 18: INT dotinc; ! 19: L_INT insoutvar[36]; ! 20: #ifdef ADB ! 21: L_INT var[36]; ! 22: #endif ADB ! 23: ! 24: #undef INSTTAB ! 25: #include "instrs.h" ! 26: ! 27: STRING regname[]; ! 28: STRING fltimm[]; ! 29: POS type, space, incp; ! 30: /* ! 31: * Definitions for registers and for operand classes ! 32: */ ! 33: char *insregname(); /* how to print a register */ ! 34: ! 35: #define R_PC 0xF ! 36: ! 37: #define OC_IMM0 0x0 ! 38: #define OC_IMM1 0x1 ! 39: #define OC_IMM2 0x2 ! 40: #define OC_IMM3 0x3 ! 41: #define OC_INDEX 0x4 ! 42: #define OC_REG 0x5 ! 43: #define OC_DREG 0x6 ! 44: #define OC_ADREG 0x7 ! 45: #define OC_AIREG 0x8 ! 46: #define OC_DAIREG 0x9 ! 47: ! 48: #define OC_BDISP 0xA ! 49: #define OC_DBDISP 0xB ! 50: #define OC_WDISP 0xC ! 51: #define OC_DWDISP 0xD ! 52: #define OC_LDISP 0xE ! 53: #define OC_DLDISP 0xF ! 54: ! 55: #define OC_SHIFT 4 ! 56: #define OC_CONS(oc,reg) (((oc & 0xF) << OC_SHIFT) | (reg & 0xF)) ! 57: #define OC_AMEXT(x) (((x) >> OC_SHIFT) & 0xF) ! 58: #define OC_REGEXT(x) ((x) & 0xF) ! 59: ! 60: /* ! 61: * Definitions for large numbers ! 62: */ ! 63: #include "asnumber.h" ! 64: typedef struct as_number *numberp; ! 65: numberp snarf(); ! 66: numberp snarfreloc(); ! 67: /* ! 68: * Definitions for special instructions ! 69: */ ! 70: #define CASEB 0x8F ! 71: #define CASEW 0xAF ! 72: #define CASEL 0xCF ! 73: /* ! 74: * Definitions for converting TYP's into numbers, booleans, etc. ! 75: * These are shared with the assembler. ! 76: */ ! 77: extern int ty_NORELOC[]; ! 78: extern int ty_float[]; ! 79: extern int ty_nbyte[]; ! 80: extern int ty_nlg[]; ! 81: extern char *ty_string[]; ! 82: ! 83: short ioptab[3][256]; /* two level index by opcode into insttab */ ! 84: ! 85: int mapescbyte(byte) ! 86: u_char byte; ! 87: { ! 88: switch(byte){ ! 89: default: return(0); ! 90: case ESCD: return(1); ! 91: case ESCF: return(2); ! 92: } ! 93: } ! 94: ! 95: mkioptab() ! 96: { ! 97: REG struct insttab *p; ! 98: int mapchar; ! 99: ! 100: for(p = insttab; p->iname; p++){ ! 101: mapchar = mapescbyte(p->eopcode); ! 102: if (ioptab[mapchar][p->popcode]) ! 103: continue; ! 104: ioptab[mapchar][p->popcode] = p - insttab; ! 105: } ! 106: } ! 107: ! 108: u_char snarfuchar(); ! 109: /* ! 110: * Global variables for communicating with the minions and printins ! 111: */ ! 112: static int idsp; ! 113: static short argno; /* which argument one is working on */ ! 114: static char insoutfmt[2]; /* how to format the relocated symbols */ ! 115: #ifdef SDB ! 116: static struct proct *procp; ! 117: #endif SDB ! 118: ! 119: static savevar(val) ! 120: long val; ! 121: { ! 122: var[argno] = val; ! 123: insoutvar[argno] = val; ! 124: } ! 125: ! 126: printins(fmt, Idsp, ins) ! 127: char fmt; ! 128: #ifndef vax ! 129: u_char ins; ! 130: #else ! 131: u_char ins; ! 132: #endif ! 133: int Idsp; ! 134: { ! 135: u_char mode; /* mode */ ! 136: u_char ins2; ! 137: char *indexreg; /* print of which register indexes */ ! 138: char *indexed; /* we indexed */ ! 139: char *operandout(); ! 140: REG u_char *ap; ! 141: REG struct insttab *ip; ! 142: u_char optype; ! 143: int mapchar; ! 144: ! 145: idsp = Idsp; ! 146: type = DSYM; ! 147: space = idsp; ! 148: #ifdef SDB ! 149: procp = adrtoprocp(dot); ! 150: if (procp->paddr == dot){ ! 151: printf("0x%04.4x", ins); ! 152: incp = 2; ! 153: goto ret; ! 154: } ! 155: #endif SDB ! 156: ! 157: #ifdef ADB ! 158: insoutfmt[0] = 0; ! 159: #endif ADB ! 160: #ifdef SDB ! 161: insoutfmt[0] = fmt; ! 162: #endif SDB ! 163: ! 164: incp = 1; ! 165: if ((mapchar = mapescbyte(ins)) != 0){ ! 166: ins2 = snarfuchar(); ! 167: if (ioptab[mapchar][ins2] == 0){ ! 168: /* ! 169: * Oops; not a defined instruction; ! 170: * back over this escape byte. ! 171: */ ! 172: incp -= 1; ! 173: mapchar = 0; ! 174: } else { ! 175: ins = ins2; ! 176: } ! 177: } ! 178: if (ioptab[mapchar][ins] == 0){ ! 179: printf("<undefined operator byte>: %x", ins); ! 180: goto ret; ! 181: } ! 182: ip = &insttab[ioptab[mapchar][ins]]; ! 183: printf("%s\t", ip->iname); ! 184: ! 185: for (ap = ip->argtype, argno = 0; argno < ip->nargs; argno++, ap++) { ! 186: savevar(0x80000000); /* an illegal symbol */ ! 187: optype = *ap; ! 188: if (argno != 0) ! 189: printc(','); ! 190: indexreg = 0; ! 191: indexed = 0; ! 192: do{ ! 193: if (A_ACCEXT(optype) & ACCB){ ! 194: switch(A_TYPEXT(optype)){ ! 195: case TYPB: ! 196: mode = OC_CONS(OC_BDISP, R_PC); ! 197: break; ! 198: case TYPW: ! 199: mode = OC_CONS(OC_WDISP, R_PC); ! 200: break; ! 201: } ! 202: } else { ! 203: mode = snarfuchar(); ! 204: } ! 205: indexreg = operandout(mode, optype); ! 206: if (indexed) ! 207: printf("[%s]", indexed); ! 208: indexed = indexreg; ! 209: } while(indexed); ! 210: } ! 211: if (mapchar == 0){ ! 212: switch(ins){ ! 213: case CASEB: ! 214: case CASEW: ! 215: case CASEL: ! 216: casebody(insoutvar[1], insoutvar[2]); ! 217: break; ! 218: default: ! 219: break; ! 220: } ! 221: } ! 222: ret: ; ! 223: ! 224: #ifdef SDB ! 225: oincr = incp; ! 226: #endif SDB ! 227: #ifdef ADB ! 228: dotinc = incp; ! 229: #endif ADB ! 230: } ! 231: ! 232: casebody(base, limit) ! 233: long base; ! 234: long limit; ! 235: { ! 236: int i; ! 237: POS baseincp; ! 238: POS advincp; ! 239: struct as_number *valuep; ! 240: #define OSIZE (sizeof(short)) ! 241: argno = 0; ! 242: baseincp = incp; ! 243: for (i = 0; i <= limit; i++) { ! 244: printc(EOR); ! 245: #ifdef SDB ! 246: printf(" %d: ", i + base); ! 247: #endif SDB ! 248: #ifdef ADB ! 249: printf(" %R: ", i + base); ! 250: #endif ADB ! 251: valuep = snarfreloc(OSIZE, 0); ! 252: advincp = incp; ! 253: incp = baseincp; ! 254: dispaddress(valuep, OC_CONS(OC_WDISP, R_PC)); ! 255: incp = advincp; ! 256: } ! 257: } ! 258: ! 259: /* ! 260: * magic values to mung an offset to a register into ! 261: * something that psymoff can understand.. all magic ! 262: */ ! 263: /* 0 1 2 3 4 */ ! 264: static long magic_masks[5] = {0, 0x80, 0x8000, 0, 0}; ! 265: static long magic_compl[5] = {0, 0x100, 0x10000,0, 0}; ! 266: /* ! 267: * Snarf up some bytes, and put in the magic relocation flags ! 268: */ ! 269: numberp snarfreloc(nbytes) ! 270: int nbytes; ! 271: { ! 272: numberp back; ! 273: back = snarf(nbytes); ! 274: if (back->num_ulong[0] & magic_masks[nbytes]) ! 275: back->num_ulong[0] -= magic_compl[nbytes]; ! 276: return(back); ! 277: } ! 278: /* ! 279: * The following code is NOT portable from the PDP 11 to the VAX ! 280: * because of the byte ordering problem. ! 281: */ ! 282: numberp snarf(nbytes) ! 283: int nbytes; ! 284: { ! 285: REG int i; ! 286: ! 287: static struct as_number backnumber; ! 288: static struct as_number znumber; /* init'ed to 0 */ ! 289: ! 290: backnumber = znumber; ! 291: for (i = 0; i < nbytes; i++) ! 292: backnumber.num_uchar[i] = snarfuchar(); ! 293: return(&backnumber); ! 294: } ! 295: /* ! 296: * Read one single character, and advance the dot ! 297: */ ! 298: u_char snarfuchar() ! 299: { ! 300: u_char back; ! 301: /* ! 302: * assert: bchkget and inkdot don't have side effects ! 303: */ ! 304: back = (u_char)bchkget(inkdot(incp), idsp); ! 305: incp += 1; ! 306: return(back); ! 307: } ! 308: /* ! 309: * normal operand; return non zero pointer to register ! 310: * name if this is an index instruction. ! 311: */ ! 312: char *operandout(mode, optype) ! 313: u_char mode; ! 314: u_char optype; ! 315: { ! 316: char *r; ! 317: int regnumber; ! 318: int nbytes; ! 319: ! 320: regnumber = OC_REGEXT(mode); ! 321: r = insregname(regnumber); ! 322: switch (OC_AMEXT(mode)){ ! 323: case OC_IMM0: ! 324: case OC_IMM1: ! 325: case OC_IMM2: ! 326: case OC_IMM3: ! 327: shortliteral(mode, optype); ! 328: return(0); ! 329: case OC_INDEX: ! 330: return(r); /* will be printed later */ ! 331: case OC_REG: ! 332: printf("%s", r); ! 333: return(0); ! 334: case OC_DREG: ! 335: printf("(%s)", r); ! 336: return(0); ! 337: case OC_ADREG: ! 338: printf("-(%s)", r); ! 339: return(0); ! 340: case OC_DAIREG: ! 341: printc('*'); ! 342: case OC_AIREG: ! 343: if (regnumber == R_PC){ ! 344: pcimmediate(mode, optype); ! 345: } else { ! 346: printf("(%s)+", r); ! 347: } ! 348: return(0); ! 349: case OC_DBDISP: ! 350: printc('*'); ! 351: case OC_BDISP: ! 352: nbytes = 1; ! 353: break; ! 354: case OC_DWDISP: ! 355: printc('*'); ! 356: case OC_WDISP: ! 357: nbytes = 2; ! 358: break; ! 359: case OC_DLDISP: ! 360: printc('*'); ! 361: case OC_LDISP: ! 362: nbytes = 4; ! 363: break; ! 364: } ! 365: dispaddress(snarfreloc(nbytes), mode); ! 366: return(0); ! 367: } ! 368: ! 369: dispaddress(valuep, mode) ! 370: numberp valuep; ! 371: u_char mode; ! 372: { ! 373: int regnumber = OC_REGEXT(mode); ! 374: ! 375: switch(OC_AMEXT(mode)){ ! 376: case OC_BDISP: ! 377: case OC_DBDISP: ! 378: case OC_WDISP: ! 379: case OC_DWDISP: ! 380: case OC_LDISP: ! 381: case OC_DLDISP: ! 382: if (regnumber == R_PC){ ! 383: /* PC offset addressing */ ! 384: valuep->num_ulong[0] += inkdot(incp); ! 385: } ! 386: } ! 387: #ifdef ADB ! 388: psymoff(valuep->num_ulong[0], type, &insoutfmt[0]); ! 389: if (regnumber != R_PC){ /* } */ ! 390: #endif ADB ! 391: #ifdef SDB ! 392: if(psymoff(valuep->num_ulong[0], regnumber, &insoutfmt[0]) ! 393: && (regnumber != R_PC)){ ! 394: #endif SDB ! 395: printf("(%s)", insregname(regnumber)); ! 396: } ! 397: savevar((long)valuep->num_ulong[0]); ! 398: } ! 399: /* ! 400: * get a register name ! 401: */ ! 402: char *insregname(regnumber) ! 403: int regnumber; ! 404: { ! 405: char *r; ! 406: r = regname[regnumber]; ! 407: #ifdef SDB ! 408: if ( (insoutfmt[0] == 'i') ! 409: && (regnumber >= 6) ! 410: && (regnumber <= 11) ! 411: && (adrtoregvar(regnumber, procp) != -1)) { ! 412: r = sl_name; ! 413: } ! 414: #endif SDB ! 415: return(r); ! 416: } ! 417: /* ! 418: * print out a short literal ! 419: */ ! 420: shortliteral(mode, optype) ! 421: u_char mode; ! 422: u_char optype; ! 423: { ! 424: savevar((long)mode); ! 425: switch(A_TYPEXT(optype)){ ! 426: case TYPF: ! 427: case TYPD: ! 428: case TYPG: ! 429: case TYPH: ! 430: printf("$%s", fltimm[mode]); ! 431: break; ! 432: default: ! 433: #ifdef ADB ! 434: printf("$%r", mode); ! 435: #endif ADB ! 436: #ifdef SDB ! 437: printf("$%d", mode); ! 438: #endif SDB ! 439: break; ! 440: } ! 441: } ! 442: ! 443: pcimmediate(mode, optype) ! 444: u_char mode; ! 445: u_char optype; ! 446: { ! 447: int nbytes; ! 448: ! 449: printc('$'); ! 450: if (mode == OC_DAIREG){ /* PC absolute, always 4 bytes*/ ! 451: dispaddress(snarfreloc(4), mode); ! 452: return; ! 453: } ! 454: nbytes = ty_nbyte[A_TYPEXT(optype)]; ! 455: if (! ty_NORELOC[A_TYPEXT(optype)]){ ! 456: dispaddress(snarfreloc(nbytes), mode); ! 457: return; ! 458: } ! 459: bignumprint(nbytes, optype); ! 460: } ! 461: ! 462: bignumprint(nbytes, optype) ! 463: int nbytes; ! 464: u_char optype; ! 465: { ! 466: numberp valuep; ! 467: int leading_zero = 1; ! 468: REG int bindex; ! 469: REG int nindex; ! 470: REG int ch; ! 471: ! 472: valuep = snarf(nbytes); ! 473: switch(A_TYPEXT(optype)){ ! 474: case TYPF: ! 475: printf("0f%f", valuep->num_num.numFf_float.Ff_value); ! 476: break; ! 477: case TYPD: ! 478: printf("0d%f", valuep->num_num.numFd_float.Fd_value); ! 479: break; ! 480: case TYPG: ! 481: printf("0g::"); goto qprint; ! 482: case TYPH: ! 483: printf("0h::"); goto qprint; ! 484: case TYPQ: ! 485: case TYPO: ! 486: qprint: ! 487: for (bindex = nbytes - 1; bindex >= 0; --bindex){ ! 488: for (nindex = 4; nindex >= 0; nindex -= 4){ ! 489: ch = (valuep->num_uchar[bindex] >> nindex); ! 490: ch &= 0x0F; ! 491: if ( ! (leading_zero &= (ch == 0) ) ){ ! 492: if (ch <= 0x09) ! 493: printc(ch + '0'); ! 494: else ! 495: printc(ch - 0x0A + 'a'); ! 496: } ! 497: } ! 498: } ! 499: break; ! 500: } ! 501: } ! 502: #ifdef SDB ! 503: ! 504: L_INT inkdot(incr) ! 505: int incr; ! 506: { ! 507: L_INT newdot; ! 508: ! 509: newdot = dot + incr; ! 510: return(newdot); ! 511: } ! 512: ! 513: printc(c) ! 514: char c; ! 515: { ! 516: printf("%c", c); ! 517: } ! 518: ! 519: psymoff(v, regnumber, fmt) ! 520: L_INT v; ! 521: char *fmt; ! 522: { ! 523: struct proct *procp; ! 524: REG int diff; ! 525: if (fmt[0] == 'i') { ! 526: switch(regnumber){ ! 527: case 12: /* parameter */ ! 528: if ((diff = adrtoparam((ADDR) v, adrtoprocp(dot))) ! 529: != -1) { ! 530: printf("%s", sl_name); ! 531: prdiff(diff); ! 532: return(0); ! 533: } ! 534: break; ! 535: case 13: /* local */ ! 536: if ((diff = adrtolocal((ADDR) -v, adrtoprocp(dot)) ! 537: ) != -1) { ! 538: printf("%s", sl_name); ! 539: prdiff(diff); ! 540: return(0); ! 541: } ! 542: break; ! 543: default: ! 544: break; ! 545: } ! 546: if (v < firstdata) { ! 547: if ((procp = adrtoprocp((ADDR) v)) != badproc) { ! 548: prlnoff(procp, v); ! 549: return(0); ! 550: } ! 551: } else { ! 552: if ((diff = adrtoext((ADDR) v)) != -1) { ! 553: printf("%s", sl_name); ! 554: prdiff(diff); ! 555: return(0); ! 556: } ! 557: } ! 558: } ! 559: prhex(v); ! 560: return(1); ! 561: } ! 562: ! 563: prdiff(diff) ! 564: { ! 565: if (diff) { ! 566: printf("+"); ! 567: prhex(diff); ! 568: } ! 569: } ! 570: ! 571: #endif SDB
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.