Commit | Line | Data |
---|---|---|
45eec9e2 BJ |
1 | static char sccsid[] = "@(#)opset.c 4.1 %G%"; |
2 | # | |
3 | /* | |
4 | * | |
5 | * UNIX debugger | |
6 | * | |
7 | * Instruction printing routines. | |
8 | * MACHINE DEPENDENT. | |
9 | */ | |
10 | ||
11 | #include "head.h" | |
12 | SCCSID(@(#)opset.c 2.4); | |
13 | ||
14 | STRING errflg; | |
15 | L_INT dot; | |
16 | INT dotinc; | |
17 | L_INT vvar[36]; | |
18 | ||
19 | ||
20 | /* instruction printing */ | |
21 | ||
22 | /* | |
23 | * Argument access types | |
24 | */ | |
25 | #define ACCA (8<<3) /* address only */ | |
26 | #define ACCR (1<<3) /* read */ | |
27 | #define ACCW (2<<3) /* write */ | |
28 | #define ACCM (3<<3) /* modify */ | |
29 | #define ACCB (4<<3) /* branch displacement */ | |
30 | #define ACCI (5<<3) /* XFC code */ | |
31 | ||
32 | /* | |
33 | * Argument data types | |
34 | */ | |
35 | #define TYPB 0 /* byte */ | |
36 | #define TYPW 1 /* word */ | |
37 | #define TYPL 2 /* long */ | |
38 | #define TYPQ 3 /* quad */ | |
39 | #define TYPF 4 /* floating */ | |
40 | #define TYPD 5 /* double floating */ | |
41 | ||
42 | ||
43 | TYPE struct optab *OPTAB; | |
44 | struct optab { | |
45 | char *iname; | |
46 | char val; | |
47 | char nargs; | |
48 | char argtype[6]; | |
49 | } optab[]; | |
50 | #define SYSTAB struct systab | |
51 | SYSTAB { | |
52 | int argc; | |
53 | char *sname; | |
54 | } systab[]; | |
55 | STRING regname[]; | |
56 | STRING fltimm[]; | |
57 | POS type, space, incp; | |
58 | ||
59 | int ioptab[256]; /* index by opcode to optab */ | |
60 | ||
61 | mkioptab() {/* set up ioptab */ | |
62 | REG OPTAB p=optab; while (p->iname) {ioptab[p->val&LOBYTE]=p-optab; p++;} | |
63 | } | |
64 | ||
65 | extern char *fmtr; | |
66 | extern char *fmtR; | |
67 | ||
68 | printins(fmt,idsp,ins) | |
69 | char fmt; | |
70 | #ifndef vax | |
71 | REG INT ins; | |
72 | #else | |
73 | REG L_INT ins; | |
74 | #endif | |
75 | { | |
76 | short i,b,mode; char **r; long d; char *fmat; | |
77 | struct proct *procp; | |
78 | REG char * ap; | |
79 | REG OPTAB ip; | |
80 | #ifndef vax | |
81 | struct {char b_2,b_3,b_0,b_1;}; | |
82 | #else | |
83 | struct {char b_0,b_1,b_2,b_3;}; | |
84 | #endif | |
85 | procp = adrtoprocp(dot); | |
86 | if (procp->paddr == dot) { | |
87 | printf("0x%04.4x", ins & 0xffff); | |
88 | oincr = 2; | |
89 | return; | |
90 | } | |
91 | ||
92 | type=DSYM; space=idsp; | |
93 | ins &= LOBYTE; | |
94 | ip=optab+ioptab[ins]; printf("%s\t",ip->iname); incp=1; | |
95 | ap=ip->argtype; | |
96 | for (i=0; i<ip->nargs; i++,ap++) { | |
97 | vvar[i]=0x80000000; | |
98 | if (i!=0) printc(','); | |
99 | top: | |
100 | if (*ap&ACCB) b= 0xAF + ((*ap&7)<<5); /* branch displacement */ | |
101 | else {b=bchkget(inkdot(incp),idsp); ++incp;} | |
102 | if (b&0300) {/* not short literal */ | |
103 | char *slnptr; | |
104 | int regno; | |
105 | regno = b & 0xF; | |
106 | if (fmt=='i' && regno >= 6 && regno <= 11 && | |
107 | adrtoregvar(regno, procp) != -1) { | |
108 | slnptr = sl_name; | |
109 | r = &slnptr; | |
110 | } | |
111 | else | |
112 | r= ®name[regno]; | |
113 | mode= b >>= 4; | |
114 | mid: | |
115 | switch ((int)mode) { | |
116 | case 4: /* [r] */ printf("[%s]",*r); goto top; | |
117 | case 5: /* r */ printf("%s",*r); break; | |
118 | case 7: /* -(r) */ printc('-'); | |
119 | base: | |
120 | case 6: /* (r) */ printf("(%s)",*r); break; | |
121 | case 9: /* *(r)+ */ printc('*'); | |
122 | case 8: /* (r)+ */ | |
123 | if (r==(regname+0xF)) {/* PC: immediate or absolute */ | |
124 | printc('$'); if (b==9) goto abs; | |
125 | mode=((*ap&7)<<1)+0xA; goto mid; | |
126 | } | |
127 | printf("(%s)+",*r); break; | |
128 | case 0xB: printc('*'); | |
129 | case 0xA: d=bchkget(inkdot(incp),idsp); ++incp; | |
130 | if (d&0x80) d -= 0x100; fmat=fmtr; | |
131 | disp: | |
132 | vvar[i]=d; | |
133 | if (r==(regname+0xF) && b>=0xA) vvar[i] += dot+incp; | |
134 | if (psymoff(vvar[i],r,fmt) && r!=regname+0xF) | |
135 | goto base; | |
136 | break; | |
137 | case 0xD: printc('*'); | |
138 | case 0xC: d=0; | |
139 | d.b_0 = bchkget(inkdot(incp),idsp); ++incp; | |
140 | d.b_1 = bchkget(inkdot(incp),idsp); ++incp; | |
141 | if (d&0x8000) d -= 0x10000; fmat=fmtr; | |
142 | goto disp; | |
143 | case 0xF: printc('*'); | |
144 | case 0xE: | |
145 | abs: | |
146 | d.b_0 = bchkget(inkdot(incp),idsp); ++incp; | |
147 | d.b_1 = bchkget(inkdot(incp),idsp); ++incp; | |
148 | d.b_2 = bchkget(inkdot(incp),idsp); ++incp; | |
149 | d.b_3 = bchkget(inkdot(incp),idsp); ++incp; | |
150 | fmat=fmtR; goto disp; | |
151 | } | |
152 | } else {/* short literal */ | |
153 | vvar[i]=b; | |
154 | if ((*ap&7)==TYPF || (*ap&7)==TYPD) | |
155 | printf("$%s",fltimm[b]); | |
156 | else printf("$%d",b); | |
157 | } | |
158 | } | |
159 | if (ins==0xCF || ins==0xAF || ins==0x8F) {/* CASEx instr */ | |
160 | for (i=0; i<=vvar[2]; ++i) { | |
161 | printc(EOR); printf(" %d: ",i+vvar[1]); | |
162 | d=get(inkdot(incp+i+i),idsp)&0xFFFF; | |
163 | if (d&0x8000) d -= 0x10000; | |
164 | psymoff(inkdot(incp)+d,type,fmt); | |
165 | } | |
166 | incp += vvar[2]+vvar[2]+2; | |
167 | } | |
168 | oincr=incp; | |
169 | } | |
170 | ||
171 | L_INT inkdot(incr) | |
172 | { | |
173 | L_INT newdot; | |
174 | ||
175 | newdot=dot+incr; | |
176 | return(newdot); | |
177 | } | |
178 | ||
179 | printc(c) | |
180 | char c; { | |
181 | printf("%c", c); | |
182 | } | |
183 | ||
184 | psymoff(v, r, fmt) | |
185 | L_INT v; char fmt, **r; { | |
186 | struct proct *procp; | |
187 | register int diff; | |
188 | if (fmt == 'i') { | |
189 | if (r == regname + 12) { /* parameter */ | |
190 | if ((diff = adrtoparam((ADDR) v, adrtoprocp(dot))) | |
191 | != -1) { | |
192 | printf("%s", sl_name); | |
193 | prdiff(diff); | |
194 | return(0); | |
195 | } | |
196 | } | |
197 | if (r == regname + 13) { /* local */ | |
198 | if ((diff = adrtolocal((ADDR) -v, adrtoprocp(dot)) | |
199 | ) != -1) { | |
200 | printf("%s", sl_name); | |
201 | prdiff(diff); | |
202 | return(0); | |
203 | } | |
204 | } | |
205 | if (v < firstdata) { | |
206 | if ((procp = adrtoprocp((ADDR) v)) != badproc) { | |
207 | prlnoff(procp, v); | |
208 | return(0); | |
209 | } | |
210 | } else { | |
211 | if ((diff = adrtoext((ADDR) v)) != -1) { | |
212 | printf("%s", sl_name); | |
213 | prdiff(diff); | |
214 | return(0); | |
215 | } | |
216 | } | |
217 | } | |
218 | prhex(v); | |
219 | return(1); | |
220 | } | |
221 | ||
222 | ||
223 | prdiff(diff) { | |
224 | if (diff) { | |
225 | printf("+"); | |
226 | prhex(diff); | |
227 | } | |
228 | } |