|
|
1.1 ! root 1: /* ! 2: * @(#)kdb_opset.c 7.3 (Berkeley) 5/26/88 ! 3: */ ! 4: ! 5: #include "../kdb/defs.h" ! 6: ! 7: /* ! 8: * Instruction printing. ! 9: */ ! 10: REGLIST reglist [] = { ! 11: "p1lr", &pcb.pcb_p1lr, "p1br", (int *)&pcb.pcb_p1br, ! 12: "p0lr", &pcb.pcb_p0lr, "p0br", (int *)&pcb.pcb_p0br, ! 13: "ksp", &pcb.pcb_ksp, "esp", &pcb.pcb_esp, ! 14: "ssp", &pcb.pcb_ssp, "psl", &pcb.pcb_psl, ! 15: "pc", &pcb.pcb_pc, "usp", &pcb.pcb_usp, ! 16: "fp", &pcb.pcb_fp, "ap", &pcb.pcb_ap, ! 17: "r11", &pcb.pcb_r11, "r10", &pcb.pcb_r10, ! 18: "r9", &pcb.pcb_r9, "r8", &pcb.pcb_r8, ! 19: "r7", &pcb.pcb_r7, "r6", &pcb.pcb_r6, ! 20: "r5", &pcb.pcb_r5, "r4", &pcb.pcb_r4, ! 21: "r3", &pcb.pcb_r3, "r2", &pcb.pcb_r2, ! 22: "r1", &pcb.pcb_r1, "r0", &pcb.pcb_r0, ! 23: }; ! 24: ! 25: /* ! 26: * Argument data types ! 27: * ! 28: * If you change these definitions, you must also change the tables ! 29: * in assizetab.c ! 30: */ ! 31: #define TYPB 000 /* byte integer */ ! 32: #define TYPW 001 /* word integer */ ! 33: #define TYPL 002 /* long integer */ ! 34: #define TYPQ 003 /* quad integer */ ! 35: #define TYPO 004 /* octa integer */ ! 36: #define TYPF 005 /* F float */ ! 37: #define TYPD 006 /* D float */ ! 38: #define TYPG 007 /* G float */ ! 39: #define TYPH 010 /* H float */ ! 40: #define TYPUNPACKED 011 /* when unpacked into mantissa & exponent */ ! 41: #define TYPNONE 012 /* when nothing */ ! 42: #define TYPLG 4 /* number of bits the above take up */ ! 43: ! 44: #define TYPMASK ((1<<TYPLG)-1) /* the mask (assumes 2's comp arith) */ ! 45: /* ! 46: * Constructors and extractors for argument access kinds and types ! 47: */ ! 48: #define A_CONS(access, type) ((access) | (type)) ! 49: #define A_ACCEXT(consed) ((consed) & (TYPMASK << TYPLG)) ! 50: #define A_TYPEXT(consed) ((consed) & TYPMASK) ! 51: ! 52: /* ! 53: * Argument access types used to test validity of operands to operators ! 54: */ ! 55: #define ACCR (1<<TYPLG) /* read */ ! 56: #define ACCW (2<<TYPLG) /* write */ ! 57: #define ACCB (4<<TYPLG) /* branch displacement */ ! 58: #define ACCA (8<<TYPLG) /* address only */ ! 59: #define ACCV (8<<TYPLG) /* address only */ ! 60: #define ACCM (ACCR | ACCW) /* modify */ ! 61: #define ACCI (ACCB | ACCR) /* XFC code */ ! 62: ! 63: #define ACCESSMASK (ACCA | ACCR | ACCW | ACCB) /* the mask */ ! 64: ! 65: /* ! 66: * Construction of TYPX and ACCX, to make the instrs table ! 67: * easy to use and read. ! 68: */ ! 69: /* ! 70: * For real memory address ! 71: */ ! 72: #define A_AB A_CONS(ACCA, TYPB) ! 73: #define A_AW A_CONS(ACCA, TYPW) ! 74: #define A_AL A_CONS(ACCA, TYPL) ! 75: #define A_AQ A_CONS(ACCA, TYPQ) ! 76: #define A_AO A_CONS(ACCA, TYPO) ! 77: #define A_AF A_CONS(ACCA, TYPF) ! 78: #define A_AD A_CONS(ACCA, TYPD) ! 79: #define A_AG A_CONS(ACCA, TYPG) ! 80: #define A_AH A_CONS(ACCA, TYPH) ! 81: /* ! 82: * For real memory addresses, or register addresses [sic] ! 83: * ! 84: * CHEAT! we just call these read access, since ! 85: * registers are allowed. All field instruction, except insv, ! 86: * are are read access fields. ! 87: */ ! 88: #define A_VB A_CONS(ACCR, TYPB) ! 89: #define A_VW A_CONS(ACCR, TYPW) ! 90: #define A_VL A_CONS(ACCR, TYPL) ! 91: #define A_VQ A_CONS(ACCR, TYPQ) ! 92: #define A_VO A_CONS(ACCR, TYPO) ! 93: #define A_VF A_CONS(ACCR, TYPF) ! 94: #define A_VD A_CONS(ACCR, TYPD) ! 95: #define A_VG A_CONS(ACCR, TYPG) ! 96: #define A_VH A_CONS(ACCR, TYPH) ! 97: /* ! 98: * For branch displacement ! 99: */ ! 100: #define A_BB A_CONS(ACCB, TYPB) ! 101: #define A_BW A_CONS(ACCB, TYPW) ! 102: /* ! 103: * For modification ! 104: */ ! 105: #define A_MB A_CONS(ACCM, TYPB) ! 106: #define A_MW A_CONS(ACCM, TYPW) ! 107: #define A_ML A_CONS(ACCM, TYPL) ! 108: #define A_MF A_CONS(ACCM, TYPF) ! 109: #define A_MD A_CONS(ACCM, TYPD) ! 110: #define A_MG A_CONS(ACCM, TYPG) ! 111: #define A_MH A_CONS(ACCM, TYPH) ! 112: /* ! 113: * For reading ! 114: */ ! 115: #define A_RB A_CONS(ACCR, TYPB) ! 116: #define A_RW A_CONS(ACCR, TYPW) ! 117: #define A_RL A_CONS(ACCR, TYPL) ! 118: #define A_RQ A_CONS(ACCR, TYPQ) ! 119: #define A_RO A_CONS(ACCR, TYPO) ! 120: #define A_RF A_CONS(ACCR, TYPF) ! 121: #define A_RD A_CONS(ACCR, TYPD) ! 122: #define A_RG A_CONS(ACCR, TYPG) ! 123: #define A_RH A_CONS(ACCR, TYPH) ! 124: /* ! 125: * For writing ! 126: */ ! 127: #define A_WB A_CONS(ACCW, TYPB) ! 128: #define A_WW A_CONS(ACCW, TYPW) ! 129: #define A_WL A_CONS(ACCW, TYPL) ! 130: #define A_WQ A_CONS(ACCW, TYPQ) ! 131: #define A_WO A_CONS(ACCW, TYPO) ! 132: #define A_WF A_CONS(ACCW, TYPF) ! 133: #define A_WD A_CONS(ACCW, TYPD) ! 134: #define A_WG A_CONS(ACCW, TYPG) ! 135: #define A_WH A_CONS(ACCW, TYPH) ! 136: ! 137: struct insttab { ! 138: char *iname; ! 139: u_char eopcode; ! 140: u_char popcode; ! 141: char nargs; ! 142: u_char argtype[6]; ! 143: }; ! 144: ! 145: #define OP(name,eopcode,popdcode,nargs,a1,a2,a3,a4,a5,a6) \ ! 146: {name,eopcode,popdcode,nargs,a1,a2,a3,a4,a5,a6} ! 147: /* ! 148: * Definitions for the escape bytes ! 149: */ ! 150: #define CORE 0 ! 151: #define NEW 1 ! 152: #define ESCD 0xfd ! 153: #define ESCF 0xff ! 154: #define mapescbyte(b) ((b) == ESCD ? 1 : (b) == ESCF ? 2 : 0) ! 155: ! 156: static struct insttab insttab[] = { ! 157: #include "../vax/kdb_instrs" ! 158: 0}; ! 159: ! 160: /* ! 161: * Convert TYP[BWLQOFDGH] into {1 if relocation not OK} ! 162: */ ! 163: int ty_NORELOC[] = { ! 164: 0, /* TYPB */ ! 165: 0, /* TYPW */ ! 166: 0, /* TYPL */ ! 167: 1, /* TYPQ */ ! 168: 1, /* TYPO */ ! 169: 1, /* TYPF */ ! 170: 1, /* TYPD */ ! 171: 1, /* TYPG */ ! 172: 1, /* TYPH */ ! 173: 1 /* TYPNONE */ ! 174: }; ! 175: ! 176: /* ! 177: * Convert TYP[BWLQOFDGH] into {1 ... 16} ! 178: */ ! 179: int ty_nbyte[] = { ! 180: 1, /* TYPB */ ! 181: 2, /* TYPW */ ! 182: 4, /* TYPL */ ! 183: 8, /* TYPQ */ ! 184: 16, /* TYPO */ ! 185: 4, /* TYPF */ ! 186: 8, /* TYPD */ ! 187: 8, /* TYPG */ ! 188: 16, /* TYPH */ ! 189: 0 /* TYPNONE */ ! 190: }; ! 191: ! 192: static char *regname[] = { ! 193: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", ! 194: "r8", "r9", "r10","r11","ap", "fp", "sp", "pc" ! 195: }; ! 196: static char *fltimm[] = { ! 197: "0.5", "0.5625", "0.625", "0.6875", "0.75", "0.8125", "0.875", "0.9375", ! 198: "1.0", "1.125", "1.25", "1.375", "1.5", "1.625", "1.75", "1.875", ! 199: "2.0", "2.25", "2.5", "2.75", "3.0", "3.25", "3.5", "3.75", ! 200: "4.0", "4.5", "5.0", "5.5", "6.0", "6.5", "7.0", "7.5", ! 201: "8.0", "9.0", "10.0", "11.0", "12.0", "13.0", "14.0", "15.0", ! 202: "16.0", "18.0", "20.0", "22.0", "24.0", "26.0", "28.0", "30.0", ! 203: "32.0", "36.0", "40.0", "44.0", "48.0", "52.0", "56.0", "60.0", ! 204: "64.0", "72.0", "80.0", "88.0", "96.0", "104.0", "112.0", "120.0" ! 205: }; ! 206: ! 207: static int type, space, incp; ! 208: static long insoutvar[36]; ! 209: /* ! 210: * Definitions for registers and for operand classes ! 211: */ ! 212: static char *insregname(); /* how to print a register */ ! 213: ! 214: #define R_PC 0xF ! 215: ! 216: #define OC_IMM0 0x0 ! 217: #define OC_IMM1 0x1 ! 218: #define OC_IMM2 0x2 ! 219: #define OC_IMM3 0x3 ! 220: #define OC_INDEX 0x4 ! 221: #define OC_REG 0x5 ! 222: #define OC_DREG 0x6 ! 223: #define OC_ADREG 0x7 ! 224: #define OC_AIREG 0x8 ! 225: #define OC_DAIREG 0x9 ! 226: ! 227: #define OC_BDISP 0xA ! 228: #define OC_DBDISP 0xB ! 229: #define OC_WDISP 0xC ! 230: #define OC_DWDISP 0xD ! 231: #define OC_LDISP 0xE ! 232: #define OC_DLDISP 0xF ! 233: ! 234: #define OC_SHIFT 4 ! 235: #define OC_CONS(oc,reg) (((oc & 0xF) << OC_SHIFT) | (reg & 0xF)) ! 236: #define OC_AMEXT(x) (((x) >> OC_SHIFT) & 0xF) ! 237: #define OC_REGEXT(x) ((x) & 0xF) ! 238: ! 239: /* ! 240: * Definitions for large numbers ! 241: */ ! 242: #include "asnumber.h" ! 243: typedef struct as_number *numberp; ! 244: static numberp snarf(); ! 245: static numberp snarfreloc(); ! 246: /* ! 247: * Definitions for special instructions ! 248: */ ! 249: #define CASEB 0x8F ! 250: #define CASEW 0xAF ! 251: #define CASEL 0xCF ! 252: ! 253: /* two level 1-based index by opcode into insttab */ ! 254: static short ioptab[3][256]; ! 255: ! 256: kdbsetup() ! 257: { ! 258: register struct insttab *p; ! 259: int mapchar; ! 260: ! 261: for(p = insttab; p->iname; p++){ ! 262: mapchar = mapescbyte(p->eopcode); ! 263: if (ioptab[mapchar][p->popcode]) ! 264: continue; ! 265: ioptab[mapchar][p->popcode] = (p - insttab) + 1; ! 266: } ! 267: } ! 268: ! 269: static u_char snarfuchar(); ! 270: /* ! 271: * Global variables for communicating with the minions and printins ! 272: */ ! 273: static int idsp; ! 274: static short argno; /* which argument one is working on */ ! 275: static char insoutfmt[2]; /* how to format the relocated symbols */ ! 276: ! 277: static savevar(val) ! 278: long val; ! 279: { ! 280: var[argno] = val; ! 281: insoutvar[argno] = val; ! 282: } ! 283: ! 284: /* ARGSUSED */ ! 285: printins(fmt, Idsp, ins) ! 286: char fmt; ! 287: u_char ins; ! 288: int Idsp; ! 289: { ! 290: u_char mode; /* mode */ ! 291: u_char ins2; ! 292: char *indexreg; /* print of which register indexes */ ! 293: char *indexed; /* we indexed */ ! 294: char *operandout(); ! 295: register u_char *ap; ! 296: register struct insttab *ip; ! 297: u_char optype; ! 298: int mapchar; ! 299: ! 300: idsp = Idsp; ! 301: type = DSYM; ! 302: space = idsp; ! 303: insoutfmt[0] = 0; ! 304: ! 305: incp = 1; ! 306: if ((mapchar = mapescbyte(ins)) != 0){ ! 307: ins2 = snarfuchar(); ! 308: if (ioptab[mapchar][ins2] == 0){ ! 309: /* ! 310: * Oops; not a defined instruction; ! 311: * back over this escape byte. ! 312: */ ! 313: incp -= 1; ! 314: mapchar = 0; ! 315: } else { ! 316: ins = ins2; ! 317: } ! 318: } ! 319: if (ioptab[mapchar][ins] == 0){ ! 320: printf("<undefined operator byte>: %x", ins); ! 321: goto ret; ! 322: } ! 323: ip = &insttab[ioptab[mapchar][ins] - 1]; ! 324: printf("%s\t", ip->iname); ! 325: ! 326: for (ap = ip->argtype, argno = 0; argno < ip->nargs; argno++, ap++) { ! 327: savevar(0x80000000); /* an illegal symbol */ ! 328: optype = *ap; ! 329: if (argno != 0) ! 330: printc(','); ! 331: indexreg = 0; ! 332: indexed = 0; ! 333: do{ ! 334: if (A_ACCEXT(optype) & ACCB){ ! 335: switch(A_TYPEXT(optype)){ ! 336: case TYPB: ! 337: mode = OC_CONS(OC_BDISP, R_PC); ! 338: break; ! 339: case TYPW: ! 340: mode = OC_CONS(OC_WDISP, R_PC); ! 341: break; ! 342: } ! 343: } else { ! 344: mode = snarfuchar(); ! 345: } ! 346: indexreg = operandout(mode, optype); ! 347: if (indexed) ! 348: printf("[%s]", indexed); ! 349: indexed = indexreg; ! 350: } while(indexed); ! 351: } ! 352: if (mapchar == 0){ ! 353: switch(ins){ ! 354: case CASEB: ! 355: case CASEW: ! 356: case CASEL: ! 357: casebody(insoutvar[1], insoutvar[2]); ! 358: break; ! 359: default: ! 360: break; ! 361: } ! 362: } ! 363: ret: ; ! 364: ! 365: dotinc = incp; ! 366: } ! 367: ! 368: casebody(base, limit) ! 369: long base; ! 370: long limit; ! 371: { ! 372: int i; ! 373: u_int baseincp; ! 374: u_int advincp; ! 375: struct as_number *valuep; ! 376: #define OSIZE (sizeof(short)) ! 377: argno = 0; ! 378: baseincp = incp; ! 379: for (i = 0; i <= limit; i++) { ! 380: printc(EOR); ! 381: printf(" %R: ", i + base); ! 382: valuep = snarfreloc(OSIZE, 0); ! 383: advincp = incp; ! 384: incp = baseincp; ! 385: dispaddress(valuep, OC_CONS(OC_WDISP, R_PC)); ! 386: incp = advincp; ! 387: } ! 388: } ! 389: ! 390: /* ! 391: * magic values to mung an offset to a register into ! 392: * something that psymoff can understand.. all magic ! 393: */ ! 394: /* 0 1 2 3 4 */ ! 395: static long magic_masks[5] = {0, 0x80, 0x8000, 0, 0}; ! 396: static long magic_compl[5] = {0, 0x100, 0x10000,0, 0}; ! 397: /* ! 398: * Snarf up some bytes, and put in the magic relocation flags ! 399: */ ! 400: static numberp snarfreloc(nbytes) ! 401: int nbytes; ! 402: { ! 403: numberp back; ! 404: back = snarf(nbytes); ! 405: if (back->num_ulong[0] & magic_masks[nbytes]) ! 406: back->num_ulong[0] -= magic_compl[nbytes]; ! 407: return(back); ! 408: } ! 409: /* ! 410: * The following code is NOT portable from the PDP 11 to the VAX ! 411: * because of the byte ordering problem. ! 412: */ ! 413: static numberp snarf(nbytes) ! 414: int nbytes; ! 415: { ! 416: register int i; ! 417: ! 418: static struct as_number backnumber; ! 419: static struct as_number znumber; /* init'ed to 0 */ ! 420: ! 421: backnumber = znumber; ! 422: for (i = 0; i < nbytes; i++) ! 423: backnumber.num_uchar[i] = snarfuchar(); ! 424: return(&backnumber); ! 425: } ! 426: ! 427: /* ! 428: * Read one single character, and advance the dot ! 429: */ ! 430: static u_char ! 431: snarfuchar() ! 432: { ! 433: u_char back; ! 434: /* ! 435: * assert: bchkget and inkdot don't have side effects ! 436: */ ! 437: back = (u_char)bchkget(inkdot(incp), idsp); ! 438: incp += 1; ! 439: return(back); ! 440: } ! 441: ! 442: /* ! 443: * normal operand; return non zero pointer to register ! 444: * name if this is an index instruction. ! 445: */ ! 446: char *operandout(mode, optype) ! 447: u_char mode; ! 448: u_char optype; ! 449: { ! 450: char *r; ! 451: int regnumber; ! 452: int nbytes; ! 453: ! 454: regnumber = OC_REGEXT(mode); ! 455: r = insregname(regnumber); ! 456: switch (OC_AMEXT(mode)){ ! 457: case OC_IMM0: ! 458: case OC_IMM1: ! 459: case OC_IMM2: ! 460: case OC_IMM3: ! 461: shortliteral(mode, optype); ! 462: return(0); ! 463: case OC_INDEX: ! 464: return(r); /* will be printed later */ ! 465: case OC_REG: ! 466: printf("%s", r); ! 467: return(0); ! 468: case OC_DREG: ! 469: printf("(%s)", r); ! 470: return(0); ! 471: case OC_ADREG: ! 472: printf("-(%s)", r); ! 473: return(0); ! 474: case OC_DAIREG: ! 475: printc('*'); ! 476: case OC_AIREG: ! 477: if (regnumber == R_PC){ ! 478: pcimmediate(mode, optype); ! 479: } else { ! 480: printf("(%s)+", r); ! 481: } ! 482: return(0); ! 483: case OC_DBDISP: ! 484: printc('*'); ! 485: case OC_BDISP: ! 486: nbytes = 1; ! 487: break; ! 488: case OC_DWDISP: ! 489: printc('*'); ! 490: case OC_WDISP: ! 491: nbytes = 2; ! 492: break; ! 493: case OC_DLDISP: ! 494: printc('*'); ! 495: case OC_LDISP: ! 496: nbytes = 4; ! 497: break; ! 498: } ! 499: dispaddress(snarfreloc(nbytes), mode); ! 500: return(0); ! 501: } ! 502: ! 503: dispaddress(valuep, mode) ! 504: numberp valuep; ! 505: u_char mode; ! 506: { ! 507: int regnumber = OC_REGEXT(mode); ! 508: ! 509: switch(OC_AMEXT(mode)){ ! 510: case OC_BDISP: ! 511: case OC_DBDISP: ! 512: case OC_WDISP: ! 513: case OC_DWDISP: ! 514: case OC_LDISP: ! 515: case OC_DLDISP: ! 516: if (regnumber == R_PC){ ! 517: /* PC offset addressing */ ! 518: valuep->num_ulong[0] += inkdot(incp); ! 519: } ! 520: } ! 521: if (regnumber == R_PC) ! 522: psymoff(valuep->num_ulong[0], type, &insoutfmt[0]); ! 523: else { /* } */ ! 524: printf(LPRMODE, valuep->num_ulong[0]); ! 525: printf(insoutfmt); ! 526: printf("(%s)", insregname(regnumber)); ! 527: } ! 528: savevar((long)valuep->num_ulong[0]); ! 529: } ! 530: ! 531: /* ! 532: * get a register name ! 533: */ ! 534: static char * ! 535: insregname(regnumber) ! 536: int regnumber; ! 537: { ! 538: char *r; ! 539: r = regname[regnumber]; ! 540: return(r); ! 541: } ! 542: ! 543: /* ! 544: * print out a short literal ! 545: */ ! 546: shortliteral(mode, optype) ! 547: u_char mode; ! 548: u_char optype; ! 549: { ! 550: savevar((long)mode); ! 551: switch(A_TYPEXT(optype)){ ! 552: case TYPF: ! 553: case TYPD: ! 554: case TYPG: ! 555: case TYPH: ! 556: printf("$%s", fltimm[mode]); ! 557: break; ! 558: default: ! 559: printf("$%r", mode); ! 560: break; ! 561: } ! 562: } ! 563: ! 564: pcimmediate(mode, optype) ! 565: u_char mode; ! 566: u_char optype; ! 567: { ! 568: int nbytes; ! 569: ! 570: printc('$'); ! 571: if (mode == OC_CONS(OC_DAIREG, R_PC)){ /* PC absolute, always 4 bytes*/ ! 572: dispaddress(snarfreloc(4), mode); ! 573: return; ! 574: } ! 575: nbytes = ty_nbyte[A_TYPEXT(optype)]; ! 576: if (! ty_NORELOC[A_TYPEXT(optype)]){ ! 577: dispaddress(snarfreloc(nbytes), mode); ! 578: return; ! 579: } ! 580: bignumprint(nbytes, optype); ! 581: } ! 582: ! 583: bignumprint(nbytes, optype) ! 584: int nbytes; ! 585: u_char optype; ! 586: { ! 587: numberp valuep; ! 588: int leading_zero = 1; ! 589: register int bindex; ! 590: register int nindex; ! 591: register int ch; ! 592: ! 593: valuep = snarf(nbytes); ! 594: switch(A_TYPEXT(optype)){ ! 595: case TYPF: ! 596: printf("0f%f", valuep->num_num.numFf_float.Ff_value); ! 597: break; ! 598: case TYPD: ! 599: printf("0d%f", valuep->num_num.numFd_float.Fd_value); ! 600: break; ! 601: case TYPG: ! 602: printf("0g::"); goto qprint; ! 603: case TYPH: ! 604: printf("0h::"); goto qprint; ! 605: case TYPQ: ! 606: case TYPO: ! 607: qprint: ! 608: for (bindex = nbytes - 1; bindex >= 0; --bindex){ ! 609: for (nindex = 4; nindex >= 0; nindex -= 4){ ! 610: ch = (valuep->num_uchar[bindex] >> nindex); ! 611: ch &= 0x0F; ! 612: if ( ! (leading_zero &= (ch == 0) ) ){ ! 613: if (ch <= 0x09) ! 614: printc(ch + '0'); ! 615: else ! 616: printc(ch - 0x0A + 'a'); ! 617: } ! 618: } ! 619: } ! 620: break; ! 621: } ! 622: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.