Commit | Line | Data |
---|---|---|
7cb4340a BJ |
1 | # |
2 | /* | |
3 | * | |
4 | * UNIX debugger | |
5 | * | |
6 | */ | |
7 | ||
8 | #include "defs.h" | |
9 | static char sccsid[] = "@(#)opset.c 4.1 %G%"; | |
10 | ||
11 | STRING errflg; | |
12 | L_INT dot; | |
13 | INT dotinc; | |
14 | L_INT var[]; | |
15 | ||
16 | ||
17 | /* instruction printing */ | |
18 | ||
19 | /* | |
20 | * Argument access types | |
21 | */ | |
22 | #define ACCA (8<<3) /* address only */ | |
23 | #define ACCR (1<<3) /* read */ | |
24 | #define ACCW (2<<3) /* write */ | |
25 | #define ACCM (3<<3) /* modify */ | |
26 | #define ACCB (4<<3) /* branch displacement */ | |
27 | #define ACCI (5<<3) /* XFC code */ | |
28 | ||
29 | /* | |
30 | * Argument data types | |
31 | */ | |
32 | #define TYPB 0 /* byte */ | |
33 | #define TYPW 1 /* word */ | |
34 | #define TYPL 2 /* long */ | |
35 | #define TYPQ 3 /* quad */ | |
36 | #define TYPF 4 /* floating */ | |
37 | #define TYPD 5 /* double floating */ | |
38 | ||
39 | ||
40 | TYPE struct optab *OPTAB; | |
41 | struct optab { | |
42 | char *iname; | |
43 | char val; | |
44 | char nargs; | |
45 | char argtype[6]; | |
46 | } optab[]; | |
47 | #define SYSTAB struct systab | |
48 | SYSTAB { | |
49 | int argc; | |
50 | char *sname; | |
51 | } systab[]; | |
52 | STRING regname[]; | |
53 | STRING fltimm[]; | |
54 | POS type, space, incp; | |
55 | ||
56 | int ioptab[256]; /* index by opcode to optab */ | |
57 | ||
58 | mkioptab() {/* set up ioptab */ | |
59 | REG OPTAB p=optab; | |
60 | while (p->iname){ | |
61 | ioptab[p->val&LOBYTE]=p-optab; | |
62 | p++; | |
63 | } | |
64 | } | |
65 | ||
66 | extern char *fmtr; /* not used */ | |
67 | extern char *fmtR; /* not used */ | |
68 | ||
69 | printins(f,idsp,ins) | |
70 | #ifndef vax | |
71 | REG INT ins; | |
72 | #else | |
73 | REG L_INT ins; | |
74 | #endif | |
75 | { | |
76 | short argno; /* argument index */ | |
77 | short mode; /* mode */ | |
78 | char **r; /* register name */ | |
79 | long d; /* assembled byte, word, long or float */ | |
80 | long snarf(); | |
81 | REG char * ap; | |
82 | REG OPTAB ip; | |
83 | ||
84 | type = DSYM; | |
85 | space = idsp; | |
86 | ins &= LOBYTE; | |
87 | ip=optab+ioptab[ins]; | |
88 | printf("%s%8t",ip->iname); | |
89 | incp = 1; | |
90 | ap = ip->argtype; | |
91 | for (argno=0; argno<ip->nargs; argno++,ap++) { | |
92 | var[argno] = 0x80000000; | |
93 | if (argno!=0) printc(','); | |
94 | top: | |
95 | if (*ap&ACCB) | |
96 | mode = 0xAF + ((*ap&7)<<5); /* branch displacement */ | |
97 | else{ | |
98 | mode = bchkget(inkdot(incp),idsp); ++incp; | |
99 | } | |
100 | if (mode & 0300) {/* not short literal */ | |
101 | r = ®name[mode&0xF]; | |
102 | mode >>= 4; | |
103 | switch ((int)mode) { | |
104 | case 4: /* [r] */ | |
105 | printf("[%s]",*r); | |
106 | goto top; | |
107 | case 5: /* r */ | |
108 | printf("%s",*r); | |
109 | break; | |
110 | case 6: /* (r) */ | |
111 | printf("(%s)",*r); | |
112 | break; | |
113 | case 7: /* -(r) */ | |
114 | printf("-(%s)",*r); | |
115 | break; | |
116 | case 9: /* *(r)+ */ | |
117 | printc('*'); | |
118 | case 8: /* (r)+ */ | |
119 | if (r==(regname+0xF)) { | |
120 | printc('$'); | |
121 | if (mode==9){ /* PC absolute, always 4 bytes*/ | |
122 | d = snarf(4, idsp); | |
123 | goto disp; | |
124 | } | |
125 | switch(*ap&7){ | |
126 | case TYPB: | |
127 | d = snarf(1, idsp); | |
128 | goto disp; | |
129 | case TYPW: | |
130 | d = snarf(2, idsp); | |
131 | goto disp; | |
132 | case TYPL: | |
133 | d = snarf(4, idsp); | |
134 | goto disp; | |
135 | case TYPQ: | |
136 | d = snarf(4, idsp); | |
137 | printquad(d, snarf(4, idsp)); | |
138 | break; | |
139 | case TYPF: | |
140 | printfloating(TYPF, snarf(4, idsp), 0); | |
141 | break; | |
142 | case TYPD: | |
143 | d = snarf(4, idsp); | |
144 | printfloating(TYPQ, d, snarf(4, idsp)); | |
145 | break; | |
146 | } /*end of type switch */ | |
147 | /* | |
148 | * here only for TYPQ, TYPf, TYPD | |
149 | * others went to disp | |
150 | */ | |
151 | } else { /*it's not PC immediate or abs*/ | |
152 | printf("(%s)+",*r); | |
153 | } | |
154 | break; | |
155 | case 0xB: /* byte displacement defferred*/ | |
156 | printc('*'); | |
157 | case 0xA: /* byte displacement */ | |
158 | d = snarf(1, idsp); | |
159 | goto disp; | |
160 | case 0xD: /* word displacement deferred */ | |
161 | printc('*'); | |
162 | case 0xC: /* word displacement */ | |
163 | d = snarf(2, idsp); | |
164 | goto disp; | |
165 | case 0xF: /* long displacement deferred */ | |
166 | printc('*'); | |
167 | case 0xE: /* long displacement */ | |
168 | d = snarf(4, idsp); | |
169 | goto disp; | |
170 | disp: | |
171 | var[argno]=d; | |
172 | if (r==(regname+0xF) && mode>=0xA){ | |
173 | /* PC offset addressing */ | |
174 | var[argno] += dot+incp; | |
175 | } | |
176 | psymoff(var[argno],type,""); | |
177 | if (r != regname+0xF) | |
178 | printf("(%s)",*r); | |
179 | break; | |
180 | } /* end of the mode switch */ | |
181 | } else { /* short literal */ | |
182 | var[argno]=mode; | |
183 | if( (*ap&7)==TYPF | |
184 | || (*ap&7)==TYPD) | |
185 | printf("$%s",fltimm[mode]); | |
186 | else | |
187 | printf("$%r",mode); | |
188 | } | |
189 | } | |
190 | if (ins==0xCF || ins==0xAF || ins==0x8F) {/* CASEx instr */ | |
191 | for (argno=0; argno<=var[2]; ++argno) { | |
192 | printc(EOR); | |
193 | printf(" %R: ",argno+var[1]); | |
194 | d=get(inkdot(incp+argno+argno),idsp)&0xFFFF; | |
195 | if (d&0x8000) d -= 0x10000; | |
196 | psymoff(inkdot(incp)+d,type,""); | |
197 | } | |
198 | incp += var[2]+var[2]+2; | |
199 | } | |
200 | dotinc=incp; | |
201 | } | |
202 | ||
203 | /* | |
204 | * magic values to mung an offset to a register into | |
205 | * something that psymoff can understand.. all magic | |
206 | */ | |
207 | /* 0 1 2 3 4 */ | |
208 | static long magic_masks[5] = {0, 0x80, 0x8000, 0, 0}; | |
209 | static long magic_compl[5] = {0, 0x100, 0x10000,0, 0}; | |
210 | ||
211 | /* | |
212 | * The following code is NO LONGER portable from the PDP 11 to the VAX | |
213 | */ | |
214 | long snarf (nbytes, idsp) | |
215 | int nbytes; | |
216 | { | |
217 | register int byteindex; | |
218 | union Long{ | |
219 | char long_bytes[4]; | |
220 | long long_value; | |
221 | } d; | |
222 | ||
223 | d.long_value = 0; | |
224 | for (byteindex = 0; byteindex < nbytes; byteindex++){ | |
225 | d.long_bytes[byteindex] = bchkget(inkdot(incp), idsp); | |
226 | ++incp; | |
227 | } | |
228 | if (d.long_value & magic_masks[nbytes]) | |
229 | d.long_value -= magic_compl[nbytes]; | |
230 | return(d.long_value); | |
231 | } | |
232 | ||
233 | printfloating(type, word_first, word_last) | |
234 | int type; | |
235 | long word_first; | |
236 | long word_last; | |
237 | { | |
238 | union Double{ | |
239 | struct { | |
240 | long word_first; | |
241 | long word_last; | |
242 | } composite; | |
243 | double dvalue; | |
244 | } reconstructed; | |
245 | ||
246 | reconstructed.composite.word_first = word_first; | |
247 | reconstructed.composite.word_last = word_last; | |
248 | printf( "%f", reconstructed.dvalue); | |
249 | } | |
250 | ||
251 | printquad(word_first, word_last) | |
252 | long word_first; | |
253 | long word_last; | |
254 | { | |
255 | union Quad { | |
256 | char quad_bytes[8]; | |
257 | long quad_long[2]; | |
258 | } reconstructed; | |
259 | int leading_zero = 1; | |
260 | int byteindex; | |
261 | int nibbleindex; | |
262 | register int ch; | |
263 | ||
264 | reconstructed.quad_long[0] = word_first; | |
265 | reconstructed.quad_long[1] = word_last; | |
266 | for (byteindex = 7; byteindex >= 0; --byteindex){ | |
267 | for (nibbleindex = 4; nibbleindex >= 0; nibbleindex -= 4){ | |
268 | ch = (reconstructed.quad_bytes[byteindex] | |
269 | >> nibbleindex) & 0x0F; | |
270 | if ( ! (leading_zero &= (ch == 0) ) ){ | |
271 | if (ch <= 0x09) | |
272 | printc(ch + '0'); | |
273 | else | |
274 | printc(ch - 0x0A + 'a'); | |
275 | } | |
276 | } | |
277 | } | |
278 | } |