1 #ifndef lint 2 static char sccsid[] = "@(#)opset.c 4.5 05/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 575