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