static char sccsid[] = "@(#)opset.c 4.1 10/9/80"; # /* * * UNIX debugger * * Instruction printing routines. * MACHINE DEPENDENT. */ #include "head.h" SCCSID(@(#)opset.c 2.4); STRING errflg; L_INT dot; INT dotinc; L_INT vvar[36]; /* instruction printing */ /* * Argument access types */ #define ACCA (8<<3) /* address only */ #define ACCR (1<<3) /* read */ #define ACCW (2<<3) /* write */ #define ACCM (3<<3) /* modify */ #define ACCB (4<<3) /* branch displacement */ #define ACCI (5<<3) /* XFC code */ /* * Argument data types */ #define TYPB 0 /* byte */ #define TYPW 1 /* word */ #define TYPL 2 /* long */ #define TYPQ 3 /* quad */ #define TYPF 4 /* floating */ #define TYPD 5 /* double floating */ TYPE struct optab *OPTAB; struct optab { char *iname; char val; char nargs; char argtype[6]; } optab[]; #define SYSTAB struct systab SYSTAB { int argc; char *sname; } systab[]; STRING regname[]; STRING fltimm[]; POS type, space, incp; int ioptab[256]; /* index by opcode to optab */ mkioptab() {/* set up ioptab */ REG OPTAB p=optab; while (p->iname) {ioptab[p->val&LOBYTE]=p-optab; p++;} } extern char *fmtr; extern char *fmtR; printins(fmt,idsp,ins) char fmt; #ifndef vax REG INT ins; #else REG L_INT ins; #endif { short i,b,mode; char **r; char *fmat; struct proct *procp; REG char * ap; REG OPTAB ip; #ifndef vax union { long l; struct { char _2,_3,_0,_1; } b; } d; #else union { long l; struct { char _0,_1,_2,_3; } b; } d; #endif procp = adrtoprocp(dot); if (procp->paddr == dot) { printf("0x%04.4x", ins & 0xffff); oincr = 2; return; } type=DSYM; space=idsp; ins &= LOBYTE; ip=optab+ioptab[ins]; printf("%s\t",ip->iname); incp=1; ap=ip->argtype; for (i=0; i<ip->nargs; i++,ap++) { vvar[i]=0x80000000; if (i!=0) printc(','); top: if (*ap&ACCB) b= 0xAF + ((*ap&7)<<5); /* branch displacement */ else {b=bchkget(inkdot(incp),idsp); ++incp;} if (b&0300) {/* not short literal */ char *slnptr; int regno; regno = b & 0xF; if (fmt=='i' && regno >= 6 && regno <= 11 && adrtoregvar(regno, procp) != -1) { slnptr = sl_name; r = &slnptr; } else r= ®name[regno]; mode= b >>= 4; mid: switch ((int)mode) { case 4: /* [r] */ printf("[%s]",*r); goto top; case 5: /* r */ printf("%s",*r); break; case 7: /* -(r) */ printc('-'); base: case 6: /* (r) */ printf("(%s)",*r); break; case 9: /* *(r)+ */ printc('*'); case 8: /* (r)+ */ if (r==(regname+0xF)) {/* PC: immediate or absolute */ printc('$'); if (b==9) goto abs; mode=((*ap&7)<<1)+0xA; goto mid; } printf("(%s)+",*r); break; case 0xB: printc('*'); case 0xA: d.l=bchkget(inkdot(incp),idsp); ++incp; if (d.l&0x80) d.l -= 0x100; fmat=fmtr; disp: vvar[i]=d.l; if (r==(regname+0xF) && b>=0xA) vvar[i] += dot+incp; if (psymoff(vvar[i],r,fmt) && r!=regname+0xF) goto base; break; case 0xD: printc('*'); case 0xC: d.l=0; d.b._0 = bchkget(inkdot(incp),idsp); ++incp; d.b._1 = bchkget(inkdot(incp),idsp); ++incp; if (d.l&0x8000) d.l -= 0x10000; fmat=fmtr; goto disp; case 0xF: printc('*'); case 0xE: abs: d.b._0 = bchkget(inkdot(incp),idsp); ++incp; d.b._1 = bchkget(inkdot(incp),idsp); ++incp; d.b._2 = bchkget(inkdot(incp),idsp); ++incp; d.b._3 = bchkget(inkdot(incp),idsp); ++incp; fmat=fmtR; goto disp; } } else {/* short literal */ vvar[i]=b; if ((*ap&7)==TYPF || (*ap&7)==TYPD) printf("$%s",fltimm[b]); else printf("$%d",b); } } if (ins==0xCF || ins==0xAF || ins==0x8F) {/* CASEx instr */ for (i=0; i<=vvar[2]; ++i) { printc(EOR); printf(" %d: ",i+vvar[1]); d.l=get(inkdot(incp+i+i),idsp)&0xFFFF; if (d.l&0x8000) d.l -= 0x10000; psymoff(inkdot(incp)+d.l,type,fmt); } incp += vvar[2]+vvar[2]+2; } oincr=incp; } L_INT inkdot(incr) { L_INT newdot; newdot=dot+incr; return(newdot); } printc(c) char c; { printf("%c", c); } psymoff(v, r, fmt) L_INT v; char fmt, **r; { struct proct *procp; register int diff; if (fmt == 'i') { if (r == regname + 12) { /* parameter */ if ((diff = adrtoparam((ADDR) v, adrtoprocp(dot))) != -1) { printf("%s", sl_name); prdiff(diff); return(0); } } if (r == regname + 13) { /* local */ if ((diff = adrtolocal((ADDR) -v, adrtoprocp(dot)) ) != -1) { printf("%s", sl_name); prdiff(diff); return(0); } } if (v < firstdata) { if ((procp = adrtoprocp((ADDR) v)) != badproc) { prlnoff(procp, v); return(0); } } else { if ((diff = adrtoext((ADDR) v)) != -1) { printf("%s", sl_name); prdiff(diff); return(0); } } } prhex(v); return(1); } prdiff(diff) { if (diff) { printf("+"); prhex(diff); } }