18912Srrh #ifndef lint 2*21098Sedward static char sccsid[] = "@(#)opset.c 4.5 05/27/85"; 38912Srrh #endif lint 43760Sroot /* 53760Sroot * UNIX debugger 68912Srrh * Instruction printing routines. 78912Srrh * MACHINE DEPENDENT 83760Sroot */ 93760Sroot 108912Srrh #ifdef ADB 113760Sroot #include "defs.h" 128912Srrh #endif ADB 138912Srrh #ifdef SDB 148912Srrh #include "head.h" 158912Srrh #endif SDB 163760Sroot 173760Sroot L_INT dot; 183760Sroot INT dotinc; 198912Srrh L_INT insoutvar[36]; 208912Srrh #ifdef ADB 218912Srrh L_INT var[36]; 228912Srrh #endif ADB 233760Sroot 248912Srrh #undef INSTTAB 258912Srrh #include "instrs.h" 263760Sroot 278912Srrh STRING regname[]; 288912Srrh STRING fltimm[]; 298912Srrh POS type, space, incp; 303760Sroot /* 318912Srrh * Definitions for registers and for operand classes 323760Sroot */ 338912Srrh char *insregname(); /* how to print a register */ 343760Sroot 358912Srrh #define R_PC 0xF 368912Srrh 378912Srrh #define OC_IMM0 0x0 388912Srrh #define OC_IMM1 0x1 398912Srrh #define OC_IMM2 0x2 408912Srrh #define OC_IMM3 0x3 418912Srrh #define OC_INDEX 0x4 428912Srrh #define OC_REG 0x5 438912Srrh #define OC_DREG 0x6 448912Srrh #define OC_ADREG 0x7 458912Srrh #define OC_AIREG 0x8 468912Srrh #define OC_DAIREG 0x9 478912Srrh 488912Srrh #define OC_BDISP 0xA 498912Srrh #define OC_DBDISP 0xB 508912Srrh #define OC_WDISP 0xC 518912Srrh #define OC_DWDISP 0xD 528912Srrh #define OC_LDISP 0xE 538912Srrh #define OC_DLDISP 0xF 548912Srrh 558912Srrh #define OC_SHIFT 4 568912Srrh #define OC_CONS(oc,reg) (((oc & 0xF) << OC_SHIFT) | (reg & 0xF)) 578912Srrh #define OC_AMEXT(x) (((x) >> OC_SHIFT) & 0xF) 588912Srrh #define OC_REGEXT(x) ((x) & 0xF) 598912Srrh 603760Sroot /* 618912Srrh * Definitions for large numbers 623760Sroot */ 638912Srrh #include "asnumber.h" 648912Srrh typedef struct as_number *numberp; 658912Srrh numberp snarf(); 668912Srrh numberp snarfreloc(); 678912Srrh /* 688912Srrh * Definitions for special instructions 698912Srrh */ 708912Srrh #define CASEB 0x8F 718912Srrh #define CASEW 0xAF 728912Srrh #define CASEL 0xCF 738912Srrh /* 748912Srrh * Definitions for converting TYP's into numbers, booleans, etc. 758912Srrh * These are shared with the assembler. 768912Srrh */ 778912Srrh extern int ty_NORELOC[]; 788912Srrh extern int ty_float[]; 798912Srrh extern int ty_nbyte[]; 808912Srrh extern int ty_nlg[]; 818912Srrh extern char *ty_string[]; 823760Sroot 8312402Srrh short ioptab[3][256]; /* two level 1-based index by opcode into insttab */ 843760Sroot 858912Srrh int mapescbyte(byte) 868912Srrh u_char byte; 878912Srrh { 888912Srrh switch(byte){ 898912Srrh default: return(0); 908912Srrh case ESCD: return(1); 918912Srrh case ESCF: return(2); 928912Srrh } 938912Srrh } 943760Sroot 958912Srrh mkioptab() 968912Srrh { 978912Srrh REG struct insttab *p; 988912Srrh int mapchar; 993760Sroot 1008912Srrh for(p = insttab; p->iname; p++){ 1018912Srrh mapchar = mapescbyte(p->eopcode); 1028912Srrh if (ioptab[mapchar][p->popcode]) 1038912Srrh continue; 10412402Srrh ioptab[mapchar][p->popcode] = (p - insttab) + 1; 1053760Sroot } 1063760Sroot } 1073760Sroot 1088912Srrh u_char snarfuchar(); 1098912Srrh /* 1108912Srrh * Global variables for communicating with the minions and printins 1118912Srrh */ 1128912Srrh static int idsp; 1138912Srrh static short argno; /* which argument one is working on */ 1148912Srrh static char insoutfmt[2]; /* how to format the relocated symbols */ 1158912Srrh #ifdef SDB 1168912Srrh static struct proct *procp; 1178912Srrh #endif SDB 1183760Sroot 1198912Srrh static savevar(val) 1208912Srrh long val; 1218912Srrh { 1228912Srrh var[argno] = val; 1238912Srrh insoutvar[argno] = val; 1248912Srrh } 1258912Srrh 1268912Srrh printins(fmt, Idsp, ins) 1278912Srrh char fmt; 1283760Sroot #ifndef vax 1298912Srrh u_char ins; 1303760Sroot #else 1318912Srrh u_char ins; 1323760Sroot #endif 1338912Srrh int Idsp; 1343760Sroot { 1358912Srrh u_char mode; /* mode */ 1368912Srrh u_char ins2; 1378912Srrh char *indexreg; /* print of which register indexes */ 1388912Srrh char *indexed; /* we indexed */ 1398912Srrh char *operandout(); 1408912Srrh REG u_char *ap; 1418912Srrh REG struct insttab *ip; 1428912Srrh u_char optype; 1438912Srrh int mapchar; 1443760Sroot 1458912Srrh idsp = Idsp; 1463760Sroot type = DSYM; 1473760Sroot space = idsp; 1488912Srrh #ifdef SDB 1498912Srrh procp = adrtoprocp(dot); 1508912Srrh if (procp->paddr == dot){ 1518912Srrh printf("0x%04.4x", ins); 1528912Srrh incp = 2; 1538912Srrh goto ret; 1548912Srrh } 1558912Srrh #endif SDB 1568912Srrh 1578912Srrh #ifdef ADB 1588912Srrh insoutfmt[0] = 0; 1598912Srrh #endif ADB 1608912Srrh #ifdef SDB 1618912Srrh insoutfmt[0] = fmt; 1628912Srrh #endif SDB 1638912Srrh 1643760Sroot incp = 1; 1658912Srrh if ((mapchar = mapescbyte(ins)) != 0){ 1668912Srrh ins2 = snarfuchar(); 1678912Srrh if (ioptab[mapchar][ins2] == 0){ 1688912Srrh /* 1698912Srrh * Oops; not a defined instruction; 1708912Srrh * back over this escape byte. 1718912Srrh */ 1728912Srrh incp -= 1; 1738912Srrh mapchar = 0; 1748912Srrh } else { 1758912Srrh ins = ins2; 1763760Sroot } 1778912Srrh } 1788912Srrh if (ioptab[mapchar][ins] == 0){ 1798912Srrh printf("<undefined operator byte>: %x", ins); 1808912Srrh goto ret; 1818912Srrh } 18212402Srrh ip = &insttab[ioptab[mapchar][ins] - 1]; 1838912Srrh printf("%s\t", ip->iname); 1848912Srrh 1858912Srrh for (ap = ip->argtype, argno = 0; argno < ip->nargs; argno++, ap++) { 1868912Srrh savevar(0x80000000); /* an illegal symbol */ 1878912Srrh optype = *ap; 1888912Srrh if (argno != 0) 1898912Srrh printc(','); 1908912Srrh indexreg = 0; 1918912Srrh indexed = 0; 1928912Srrh do{ 1938912Srrh if (A_ACCEXT(optype) & ACCB){ 1948912Srrh switch(A_TYPEXT(optype)){ 1958912Srrh case TYPB: 1968912Srrh mode = OC_CONS(OC_BDISP, R_PC); 1973760Sroot break; 1988912Srrh case TYPW: 1998912Srrh mode = OC_CONS(OC_WDISP, R_PC); 2003760Sroot break; 2018912Srrh } 2028912Srrh } else { 2038912Srrh mode = snarfuchar(); 2048912Srrh } 2058912Srrh indexreg = operandout(mode, optype); 2068912Srrh if (indexed) 2078912Srrh printf("[%s]", indexed); 2088912Srrh indexed = indexreg; 2098912Srrh } while(indexed); 2103760Sroot } 2118912Srrh if (mapchar == 0){ 2128912Srrh switch(ins){ 2138912Srrh case CASEB: 2148912Srrh case CASEW: 2158912Srrh case CASEL: 2168912Srrh casebody(insoutvar[1], insoutvar[2]); 2178912Srrh break; 2188912Srrh default: 2198912Srrh break; 2203760Sroot } 2213760Sroot } 2228912Srrh ret: ; 2238912Srrh 2248912Srrh #ifdef SDB 2258912Srrh oincr = incp; 2268912Srrh #endif SDB 2278912Srrh #ifdef ADB 2288912Srrh dotinc = incp; 2298912Srrh #endif ADB 2303760Sroot } 2313760Sroot 2328912Srrh casebody(base, limit) 2338912Srrh long base; 2348912Srrh long limit; 2358912Srrh { 2368912Srrh int i; 2378912Srrh POS baseincp; 2388912Srrh POS advincp; 2398912Srrh struct as_number *valuep; 2408912Srrh #define OSIZE (sizeof(short)) 2418912Srrh argno = 0; 2428912Srrh baseincp = incp; 2438912Srrh for (i = 0; i <= limit; i++) { 2448912Srrh printc(EOR); 2458912Srrh #ifdef SDB 2468912Srrh printf(" %d: ", i + base); 2478912Srrh #endif SDB 2488912Srrh #ifdef ADB 2498912Srrh printf(" %R: ", i + base); 2508912Srrh #endif ADB 2518912Srrh valuep = snarfreloc(OSIZE, 0); 2528912Srrh advincp = incp; 2538912Srrh incp = baseincp; 2548912Srrh dispaddress(valuep, OC_CONS(OC_WDISP, R_PC)); 2558912Srrh incp = advincp; 2568912Srrh } 2578912Srrh } 2588912Srrh 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}; 2668912Srrh /* 2678912Srrh * Snarf up some bytes, and put in the magic relocation flags 2688912Srrh */ 2698912Srrh numberp snarfreloc(nbytes) 2708912Srrh int nbytes; 2718912Srrh { 2728912Srrh numberp back; 2738912Srrh back = snarf(nbytes); 2748912Srrh if (back->num_ulong[0] & magic_masks[nbytes]) 2758912Srrh back->num_ulong[0] -= magic_compl[nbytes]; 2768912Srrh return(back); 2778912Srrh } 2788912Srrh /* 2798912Srrh * The following code is NOT portable from the PDP 11 to the VAX 2808912Srrh * because of the byte ordering problem. 2818912Srrh */ 2828912Srrh numberp snarf(nbytes) 2838912Srrh int nbytes; 2848912Srrh { 2858912Srrh REG int i; 2863760Sroot 2878912Srrh static struct as_number backnumber; 2888912Srrh static struct as_number znumber; /* init'ed to 0 */ 2898912Srrh 2908912Srrh backnumber = znumber; 2918912Srrh for (i = 0; i < nbytes; i++) 2928912Srrh backnumber.num_uchar[i] = snarfuchar(); 2938912Srrh return(&backnumber); 2948912Srrh } 2953760Sroot /* 2968912Srrh * Read one single character, and advance the dot 2973760Sroot */ 2988912Srrh u_char snarfuchar() 2993760Sroot { 3008912Srrh u_char back; 3018912Srrh /* 3028912Srrh * assert: bchkget and inkdot don't have side effects 3038912Srrh */ 3048912Srrh back = (u_char)bchkget(inkdot(incp), idsp); 3058912Srrh incp += 1; 3068912Srrh return(back); 3078912Srrh } 3088912Srrh /* 3098912Srrh * normal operand; return non zero pointer to register 3108912Srrh * name if this is an index instruction. 3118912Srrh */ 3128912Srrh char *operandout(mode, optype) 3138912Srrh u_char mode; 3148912Srrh u_char optype; 3158912Srrh { 3168912Srrh char *r; 3178912Srrh int regnumber; 3188912Srrh int nbytes; 3193760Sroot 3208912Srrh regnumber = OC_REGEXT(mode); 3218912Srrh r = insregname(regnumber); 3228912Srrh switch (OC_AMEXT(mode)){ 3238912Srrh case OC_IMM0: 3248912Srrh case OC_IMM1: 3258912Srrh case OC_IMM2: 3268912Srrh case OC_IMM3: 3278912Srrh shortliteral(mode, optype); 3288912Srrh return(0); 3298912Srrh case OC_INDEX: 3308912Srrh return(r); /* will be printed later */ 3318912Srrh case OC_REG: 3328912Srrh printf("%s", r); 3338912Srrh return(0); 3348912Srrh case OC_DREG: 3358912Srrh printf("(%s)", r); 3368912Srrh return(0); 3378912Srrh case OC_ADREG: 3388912Srrh printf("-(%s)", r); 3398912Srrh return(0); 3408912Srrh case OC_DAIREG: 3418912Srrh printc('*'); 3428912Srrh case OC_AIREG: 3438912Srrh if (regnumber == R_PC){ 3448912Srrh pcimmediate(mode, optype); 3458912Srrh } else { 3468912Srrh printf("(%s)+", r); 3478912Srrh } 3488912Srrh return(0); 3498912Srrh case OC_DBDISP: 3508912Srrh printc('*'); 3518912Srrh case OC_BDISP: 3528912Srrh nbytes = 1; 3538912Srrh break; 3548912Srrh case OC_DWDISP: 3558912Srrh printc('*'); 3568912Srrh case OC_WDISP: 3578912Srrh nbytes = 2; 3588912Srrh break; 3598912Srrh case OC_DLDISP: 3608912Srrh printc('*'); 3618912Srrh case OC_LDISP: 3628912Srrh nbytes = 4; 3638912Srrh break; 3643760Sroot } 3658912Srrh dispaddress(snarfreloc(nbytes), mode); 3668912Srrh return(0); 3673760Sroot } 3683760Sroot 3698912Srrh dispaddress(valuep, mode) 3708912Srrh numberp valuep; 3718912Srrh u_char mode; 3723760Sroot { 3738912Srrh int regnumber = OC_REGEXT(mode); 3743760Sroot 3758912Srrh switch(OC_AMEXT(mode)){ 3768912Srrh case OC_BDISP: 3778912Srrh case OC_DBDISP: 3788912Srrh case OC_WDISP: 3798912Srrh case OC_DWDISP: 3808912Srrh case OC_LDISP: 3818912Srrh case OC_DLDISP: 3828912Srrh if (regnumber == R_PC){ 3838912Srrh /* PC offset addressing */ 3848912Srrh valuep->num_ulong[0] += inkdot(incp); 3858912Srrh } 3868912Srrh } 3878912Srrh #ifdef ADB 388*21098Sedward if (regnumber == R_PC) 389*21098Sedward psymoff(valuep->num_ulong[0], type, &insoutfmt[0]); 390*21098Sedward else { /* } */ 391*21098Sedward printf(LPRMODE, valuep->num_ulong[0]); 392*21098Sedward printf(insoutfmt); 3938912Srrh #endif ADB 3948912Srrh #ifdef SDB 3958912Srrh if(psymoff(valuep->num_ulong[0], regnumber, &insoutfmt[0]) 3968912Srrh && (regnumber != R_PC)){ 3978912Srrh #endif SDB 3988912Srrh printf("(%s)", insregname(regnumber)); 3998912Srrh } 4008912Srrh savevar((long)valuep->num_ulong[0]); 4013760Sroot } 4028912Srrh /* 4038912Srrh * get a register name 4048912Srrh */ 4058912Srrh char *insregname(regnumber) 4068912Srrh int regnumber; 4078912Srrh { 4088912Srrh char *r; 4098912Srrh r = regname[regnumber]; 4108912Srrh #ifdef SDB 4118912Srrh if ( (insoutfmt[0] == 'i') 4128912Srrh && (regnumber >= 6) 4138912Srrh && (regnumber <= 11) 4148912Srrh && (adrtoregvar(regnumber, procp) != -1)) { 4158912Srrh r = sl_name; 4168912Srrh } 4178912Srrh #endif SDB 4188912Srrh return(r); 4198912Srrh } 4208912Srrh /* 4218912Srrh * print out a short literal 4228912Srrh */ 4238912Srrh shortliteral(mode, optype) 4248912Srrh u_char mode; 4258912Srrh u_char optype; 4268912Srrh { 4278912Srrh savevar((long)mode); 4288912Srrh switch(A_TYPEXT(optype)){ 4298912Srrh case TYPF: 4308912Srrh case TYPD: 4318912Srrh case TYPG: 4328912Srrh case TYPH: 4338912Srrh printf("$%s", fltimm[mode]); 4348912Srrh break; 4358912Srrh default: 4368912Srrh #ifdef ADB 4378912Srrh printf("$%r", mode); 4388912Srrh #endif ADB 4398912Srrh #ifdef SDB 4408912Srrh printf("$%d", mode); 4418912Srrh #endif SDB 4428912Srrh break; 4438912Srrh } 4448912Srrh } 4453760Sroot 4468912Srrh pcimmediate(mode, optype) 4478912Srrh u_char mode; 4488912Srrh u_char optype; 4493760Sroot { 4508912Srrh int nbytes; 4518912Srrh 4528912Srrh printc('$'); 45312171Ssam if (mode == OC_CONS(OC_DAIREG, R_PC)){ /* PC absolute, always 4 bytes*/ 4548912Srrh dispaddress(snarfreloc(4), mode); 4558912Srrh return; 4568912Srrh } 4578912Srrh nbytes = ty_nbyte[A_TYPEXT(optype)]; 4588912Srrh if (! ty_NORELOC[A_TYPEXT(optype)]){ 4598912Srrh dispaddress(snarfreloc(nbytes), mode); 4608912Srrh return; 4618912Srrh } 4628912Srrh bignumprint(nbytes, optype); 4638912Srrh } 4648912Srrh 4658912Srrh bignumprint(nbytes, optype) 4668912Srrh int nbytes; 4678912Srrh u_char optype; 4688912Srrh { 4698912Srrh numberp valuep; 4703760Sroot int leading_zero = 1; 4718912Srrh REG int bindex; 4728912Srrh REG int nindex; 4738912Srrh REG int ch; 4743760Sroot 4758912Srrh valuep = snarf(nbytes); 4768912Srrh switch(A_TYPEXT(optype)){ 4778912Srrh case TYPF: 4788912Srrh printf("0f%f", valuep->num_num.numFf_float.Ff_value); 4798912Srrh break; 4808912Srrh case TYPD: 4818912Srrh printf("0d%f", valuep->num_num.numFd_float.Fd_value); 4828912Srrh break; 4838912Srrh case TYPG: 4848912Srrh printf("0g::"); goto qprint; 4858912Srrh case TYPH: 4868912Srrh printf("0h::"); goto qprint; 4878912Srrh case TYPQ: 4888912Srrh case TYPO: 4898912Srrh qprint: 4908912Srrh for (bindex = nbytes - 1; bindex >= 0; --bindex){ 4918912Srrh for (nindex = 4; nindex >= 0; nindex -= 4){ 4928912Srrh ch = (valuep->num_uchar[bindex] >> nindex); 4938912Srrh ch &= 0x0F; 4948912Srrh if ( ! (leading_zero &= (ch == 0) ) ){ 4958912Srrh if (ch <= 0x09) 4968912Srrh printc(ch + '0'); 4978912Srrh else 4988912Srrh printc(ch - 0x0A + 'a'); 4998912Srrh } 5003760Sroot } 5013760Sroot } 5028912Srrh break; 5033760Sroot } 5043760Sroot } 5058912Srrh #ifdef SDB 5068912Srrh 5078912Srrh L_INT inkdot(incr) 5088912Srrh int incr; 5098912Srrh { 5108912Srrh L_INT newdot; 5118912Srrh 5128912Srrh newdot = dot + incr; 5138912Srrh return(newdot); 5148912Srrh } 5158912Srrh 5168912Srrh printc(c) 5178912Srrh char c; 5188912Srrh { 5198912Srrh printf("%c", c); 5208912Srrh } 5218912Srrh 5228912Srrh psymoff(v, regnumber, fmt) 5238912Srrh L_INT v; 5248912Srrh char *fmt; 5258912Srrh { 5268912Srrh struct proct *procp; 5278912Srrh REG int diff; 5288912Srrh if (fmt[0] == 'i') { 5298912Srrh switch(regnumber){ 5308912Srrh case 12: /* parameter */ 5318912Srrh if ((diff = adrtoparam((ADDR) v, adrtoprocp(dot))) 5328912Srrh != -1) { 5338912Srrh printf("%s", sl_name); 5348912Srrh prdiff(diff); 5358912Srrh return(0); 5368912Srrh } 5378912Srrh break; 5388912Srrh case 13: /* local */ 5398912Srrh if ((diff = adrtolocal((ADDR) -v, adrtoprocp(dot)) 5408912Srrh ) != -1) { 5418912Srrh printf("%s", sl_name); 5428912Srrh prdiff(diff); 5438912Srrh return(0); 5448912Srrh } 5458912Srrh break; 5468912Srrh default: 5478912Srrh break; 5488912Srrh } 5498912Srrh if (v < firstdata) { 5508912Srrh if ((procp = adrtoprocp((ADDR) v)) != badproc) { 5518912Srrh prlnoff(procp, v); 5528912Srrh return(0); 5538912Srrh } 5548912Srrh } else { 5558912Srrh if ((diff = adrtoext((ADDR) v)) != -1) { 5568912Srrh printf("%s", sl_name); 5578912Srrh prdiff(diff); 5588912Srrh return(0); 5598912Srrh } 5608912Srrh } 5618912Srrh } 5628912Srrh prhex(v); 5638912Srrh return(1); 5648912Srrh } 5658912Srrh 5668912Srrh prdiff(diff) 5678912Srrh { 5688912Srrh if (diff) { 5698912Srrh printf("+"); 5708912Srrh prhex(diff); 5718912Srrh } 5728912Srrh } 5738912Srrh 5748912Srrh #endif SDB 575