|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)opset.c 4.5 5/27/85"; ! 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 1-based 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) + 1; ! 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] - 1]; ! 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: if (regnumber == R_PC) ! 389: psymoff(valuep->num_ulong[0], type, &insoutfmt[0]); ! 390: else { /* } */ ! 391: printf(LPRMODE, valuep->num_ulong[0]); ! 392: printf(insoutfmt); ! 393: #endif ADB ! 394: #ifdef SDB ! 395: if(psymoff(valuep->num_ulong[0], regnumber, &insoutfmt[0]) ! 396: && (regnumber != R_PC)){ ! 397: #endif SDB ! 398: printf("(%s)", insregname(regnumber)); ! 399: } ! 400: savevar((long)valuep->num_ulong[0]); ! 401: } ! 402: /* ! 403: * get a register name ! 404: */ ! 405: char *insregname(regnumber) ! 406: int regnumber; ! 407: { ! 408: char *r; ! 409: r = regname[regnumber]; ! 410: #ifdef SDB ! 411: if ( (insoutfmt[0] == 'i') ! 412: && (regnumber >= 6) ! 413: && (regnumber <= 11) ! 414: && (adrtoregvar(regnumber, procp) != -1)) { ! 415: r = sl_name; ! 416: } ! 417: #endif SDB ! 418: return(r); ! 419: } ! 420: /* ! 421: * print out a short literal ! 422: */ ! 423: shortliteral(mode, optype) ! 424: u_char mode; ! 425: u_char optype; ! 426: { ! 427: savevar((long)mode); ! 428: switch(A_TYPEXT(optype)){ ! 429: case TYPF: ! 430: case TYPD: ! 431: case TYPG: ! 432: case TYPH: ! 433: printf("$%s", fltimm[mode]); ! 434: break; ! 435: default: ! 436: #ifdef ADB ! 437: printf("$%r", mode); ! 438: #endif ADB ! 439: #ifdef SDB ! 440: printf("$%d", mode); ! 441: #endif SDB ! 442: break; ! 443: } ! 444: } ! 445: ! 446: pcimmediate(mode, optype) ! 447: u_char mode; ! 448: u_char optype; ! 449: { ! 450: int nbytes; ! 451: ! 452: printc('$'); ! 453: if (mode == OC_CONS(OC_DAIREG, R_PC)){ /* PC absolute, always 4 bytes*/ ! 454: dispaddress(snarfreloc(4), mode); ! 455: return; ! 456: } ! 457: nbytes = ty_nbyte[A_TYPEXT(optype)]; ! 458: if (! ty_NORELOC[A_TYPEXT(optype)]){ ! 459: dispaddress(snarfreloc(nbytes), mode); ! 460: return; ! 461: } ! 462: bignumprint(nbytes, optype); ! 463: } ! 464: ! 465: bignumprint(nbytes, optype) ! 466: int nbytes; ! 467: u_char optype; ! 468: { ! 469: numberp valuep; ! 470: int leading_zero = 1; ! 471: REG int bindex; ! 472: REG int nindex; ! 473: REG int ch; ! 474: ! 475: valuep = snarf(nbytes); ! 476: switch(A_TYPEXT(optype)){ ! 477: case TYPF: ! 478: printf("0f%f", valuep->num_num.numFf_float.Ff_value); ! 479: break; ! 480: case TYPD: ! 481: printf("0d%f", valuep->num_num.numFd_float.Fd_value); ! 482: break; ! 483: case TYPG: ! 484: printf("0g::"); goto qprint; ! 485: case TYPH: ! 486: printf("0h::"); goto qprint; ! 487: case TYPQ: ! 488: case TYPO: ! 489: qprint: ! 490: for (bindex = nbytes - 1; bindex >= 0; --bindex){ ! 491: for (nindex = 4; nindex >= 0; nindex -= 4){ ! 492: ch = (valuep->num_uchar[bindex] >> nindex); ! 493: ch &= 0x0F; ! 494: if ( ! (leading_zero &= (ch == 0) ) ){ ! 495: if (ch <= 0x09) ! 496: printc(ch + '0'); ! 497: else ! 498: printc(ch - 0x0A + 'a'); ! 499: } ! 500: } ! 501: } ! 502: break; ! 503: } ! 504: } ! 505: #ifdef SDB ! 506: ! 507: L_INT inkdot(incr) ! 508: int incr; ! 509: { ! 510: L_INT newdot; ! 511: ! 512: newdot = dot + incr; ! 513: return(newdot); ! 514: } ! 515: ! 516: printc(c) ! 517: char c; ! 518: { ! 519: printf("%c", c); ! 520: } ! 521: ! 522: psymoff(v, regnumber, fmt) ! 523: L_INT v; ! 524: char *fmt; ! 525: { ! 526: struct proct *procp; ! 527: REG int diff; ! 528: if (fmt[0] == 'i') { ! 529: switch(regnumber){ ! 530: case 12: /* parameter */ ! 531: if ((diff = adrtoparam((ADDR) v, adrtoprocp(dot))) ! 532: != -1) { ! 533: printf("%s", sl_name); ! 534: prdiff(diff); ! 535: return(0); ! 536: } ! 537: break; ! 538: case 13: /* local */ ! 539: if ((diff = adrtolocal((ADDR) -v, adrtoprocp(dot)) ! 540: ) != -1) { ! 541: printf("%s", sl_name); ! 542: prdiff(diff); ! 543: return(0); ! 544: } ! 545: break; ! 546: default: ! 547: break; ! 548: } ! 549: if (v < firstdata) { ! 550: if ((procp = adrtoprocp((ADDR) v)) != badproc) { ! 551: prlnoff(procp, v); ! 552: return(0); ! 553: } ! 554: } else { ! 555: if ((diff = adrtoext((ADDR) v)) != -1) { ! 556: printf("%s", sl_name); ! 557: prdiff(diff); ! 558: return(0); ! 559: } ! 560: } ! 561: } ! 562: prhex(v); ! 563: return(1); ! 564: } ! 565: ! 566: prdiff(diff) ! 567: { ! 568: if (diff) { ! 569: printf("+"); ! 570: prhex(diff); ! 571: } ! 572: } ! 573: ! 574: #endif SDB
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.