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