Remove echo.
[deliverable/binutils-gdb.git] / gdb / rs6000-pinsn.c
CommitLineData
41abdfbd
JG
1/* Print rs6000 instructions for objdump.
2 This file is part of the binutils.
3*/
4
5
6#include <stdio.h>
7#include "defs.h"
8#include "rs6k-opcode.h"
9
10
11/* Print the rs6k instruction at address MEMADDR in debugged memory,
12 on STREAM. Returns length of the instruction, in bytes. */
13
14int
15print_insn (memaddr, stream)
16 CORE_ADDR memaddr;
17 FILE *stream;
18{
19 int pop, eop; /* primary and extended opcodes */
20 int min, max;
21 int best = -1; /* found best opcode index */
22 int oldbest = -1;
23 unsigned int the_insn;
24
25 read_memory (memaddr, &the_insn, sizeof (the_insn));
26 pop = (unsigned)(the_insn >> 26);
27 eop = ((the_insn) >> 1) & 0x3ff;
28 min = 0, max = NOPCODES-1;
29
30 while (min < max) {
31 best = (min + max) / 2;
32
33 /* see if we are running in loops */
34 if (best == oldbest)
35 goto not_found;
36 oldbest = best;
37
38 if (pop < rs6k_ops [best].p_opcode)
39 max = best;
40
41 else if (pop > rs6k_ops [best].p_opcode)
42 min = best;
43
44 else {
45 /* opcode matched, check extended opcode. */
46
47 if (rs6k_ops [best].e_opcode == -1) {
48 /* there is no valid extended opcode, what we've got is
49 just fine. */
50 goto insn_found;
51 }
52
53 else if (eop < rs6k_ops [best].e_opcode) {
54
55 while (pop == rs6k_ops [best].p_opcode) {
56 if (eop == rs6k_ops [best].e_opcode) /* found it! */
57 goto insn_found;
58 --best;
59 }
60 goto not_found;
61 }
62
63 else if (eop > rs6k_ops [best].e_opcode) {
64
65 while (pop == rs6k_ops [best].p_opcode) {
66 if (eop == rs6k_ops [best].e_opcode) /* found it! */
67 goto insn_found;
68 ++best;
69 }
70 goto not_found;
71 }
72
73 else /* eop == rs6k_ops [best].e_opcode */
74 goto insn_found;
75 }
76 }
77
78 best = min;
79 if (pop == rs6k_ops [best].p_opcode &&
80 (rs6k_ops [best].e_opcode == -1 || rs6k_ops [best].e_opcode == eop))
81 goto insn_found;
82
83 else
84 goto not_found;
85
86
87insn_found:
88 print_operator (stream, memaddr, the_insn, best);
89 return 4;
90
91not_found:
92 fprintf (stream, "0x%08x", the_insn);
93 return 4;
94}
95
96
97
98/* condition code names */
99static char *cond_code [] = {
100 "lt", "gt", "eq", "so", "ge", "le", "ne", "ns", "nl", "ng", "z", "nz" };
101
102
103print_operator (stream, memaddr, insn_word, insn_no)
104FILE *stream;
105long memaddr;
106long insn_word;
107int insn_no;
108{
109 char buf [BUFSIZ];
110 char *qq = buf;
111 char *pp = rs6k_ops[insn_no].opr_ext;
112 int tmp;
113 int nocomma = 0; /* true if no comma needed */
114
115 *qq = '\0';
116 if (pp) {
117 while (*pp) {
118
119 switch ( *pp ) {
120 case '.':
121 if (insn_word & 0x1)
122 *qq++ = '.';
123 break;
124
125 case 'l':
126 if (insn_word & 0x1)
127 *qq++ = 'l';
128 break;
129
130 case 't':
131 if ((insn_word & 0x03e00000) == 0x01800000)
132 *qq++ = 't';
133 break;
134
135 case 'f':
136 if ((insn_word & 0x03e00000) == 0x00800000)
137 *qq++ = 'f';
138 break;
139
140 case 'a':
141 if (insn_word & 0x2)
142 *qq++ = 'a';
143 break;
144
145 case 'o':
146 if (insn_word & 0x4000)
147 *qq++ = 'o';
148 break;
149
150 case '1': /* exception #1 for bb/bc ambiguity */
151 tmp = (insn_word >> 21) & 0x1f; /* extract BO */
152 if (tmp != 0xc && tmp != 0x4) {
153 /* you can't use `bb' now. switch to `bc' */
154 *(qq-1) = 'c';
155 ++insn_no;
156 pp = rs6k_ops[insn_no].opr_ext;
157 continue;
158 }
159 break;
160
161 default:
162 abort ();
163 }
164 ++pp;
165 }
166 }
167
168 /* tab between orerator and operand */
169 *qq++ = '\t';
170
171 /* parse the operand now. */
172 pp = rs6k_ops[insn_no].oprnd_format;
173
174 while (1) {
175 switch (*pp) {
176 case TO :
177 sprintf (qq, "%d", (insn_word >> 21) & 0x1f);
178 break;
179
180 case RT :
181 case RS :
182 sprintf (qq, "r%d", (insn_word >> 21) & 0x1f);
183 break;
184
185 case LI :
186 tmp = (insn_word >> 16) & 0x1f;
187 if (tmp > 11) {
188 fprintf (stderr, "Internal error: unknown cond code: 0x%x\n", insn_word);
189 tmp = 0;
190 }
191 sprintf (qq, "%s", cond_code [tmp]);
192 break;
193
194#if 0
195 case A2 :
196 tmp = (insn_word >> 2) & 0x3fff;
197 if (tmp & 0x2000)
198 tmp -= 0x4000;
199 sprintf (qq, "0x%x", tmp * 4 + memaddr);
200 break;
201#endif
202 case A2 :
203 case TA14 :
204 tmp = (insn_word & 0xfffc);
205 if (tmp & 0x8000) /* fix sign extension */
206 tmp -= 0x10000;
207
208 if ((insn_word & 0x2) == 0) /* if AA not set */
209 tmp += memaddr;
210
211 sprintf (qq, "0x%x", tmp);
212 break;
213
214 case TA24 :
215 tmp = insn_word & 0x03fffffc;
216 if (tmp & 0x2000000)
217 tmp -= 0x4000000;
218
219 if ((insn_word & 0x2) == 0) /* if no AA bit set */
220 tmp += memaddr;
221
222 sprintf (qq, "0x%x", tmp);
223 break;
224
225 case LEV : /* for svc only */
226 if (insn_word & 0x2) { /* SA is set */
227 nocomma = 1;
228 *qq = '\0';
229 }
230 else
231 sprintf (qq, "%d", (insn_word >> 5) & 0x7f);
232 break;
233
234 case FL1 : /* for svc only */
235 if (insn_word & 0x2) { /* SA is set */
236 nocomma = 1;
237 *qq = '\0';
238 }
239 else
240 sprintf (qq, "%d", (insn_word >> 12) & 0xf);
241 break;
242
243 case FL2 : /* for svc only */
244 nocomma = 0;
245 if (insn_word & 0x2) /* SA is set */
246 sprintf (qq, "%d", (insn_word >> 2) & 0x3fff);
247 else
248 sprintf (qq, "%d", (insn_word >> 2) & 0x7);
249 break;
250
251 case RA :
252 if (nocomma) {
253 sprintf (qq, "r%d)", (insn_word >> 16) & 0x1f);
254 nocomma = 0;
255 }
256 else
257 sprintf (qq, "r%d", (insn_word >> 16) & 0x1f);
258 break;
259
260 case RB :
261 sprintf (qq, "r%d", (insn_word >> 11) & 0x1f);
262 break;
263
264 case SI :
265 tmp = insn_word & 0xffff;
266 if (tmp & 0x8000)
267 tmp -= 0x10000;
268 sprintf (qq, "%d", tmp);
269 break;
270
271 case UI :
272 sprintf (qq, "%d", insn_word & 0xffff);
273 break;
274
275 case BF :
276 sprintf (qq, "%d", (insn_word >> 23) & 0x7);
277 break;
278
279 case BFA :
280 sprintf (qq, "%d", (insn_word >> 18) & 0x7);
281 break;
282
283 case BT :
284 sprintf (qq, "%d", (insn_word >> 21) & 0x1f);
285 break;
286
287 case BA :
288 sprintf (qq, "%d", (insn_word >> 16) & 0x1f);
289 break;
290
291 case BB :
292 sprintf (qq, "%d", (insn_word >> 11) & 0x1f);
293 break;
294
295 case BO :
296 sprintf (qq, "%d", (insn_word >> 21) & 0x1f);
297 break;
298
299 case BI :
300 sprintf (qq, "%d", (insn_word >> 16) & 0x1f);
301 break;
302
303 case SH :
304 sprintf (qq, "%d", (insn_word >> 11) & 0x1f);
305 break;
306
307 case MB :
308 sprintf (qq, "0x%x", (insn_word >> 6) & 0x1f);
309 break;
310
311 case ME :
312 sprintf (qq, "0x%x", (insn_word >> 1) & 0x1f);
313 break;
314
315 case SPR :
316 sprintf (qq, "%d", (insn_word >> 16) & 0x1f);
317 break;
318
319 case DIS :
320 nocomma = 1;
321 tmp = insn_word & 0xffff;
322 if (tmp & 0x8000)
323 tmp -= 0x10000;
324 sprintf (qq, "%d(", tmp);
325 break;
326
327 case FXM :
328 sprintf (qq, "0x%x", (insn_word >> 12) & 0xff);
329 break;
330
331 case FRT :
332 case FRS :
333 sprintf (qq, "f%d", (insn_word >> 21) & 0x1f);
334 break;
335
336 case FRA :
337 sprintf (qq, "f%d", (insn_word >> 16) & 0x1f);
338 break;
339
340 case FRB :
341 sprintf (qq, "f%d", (insn_word >> 11) & 0x1f);
342 break;
343
344 case FRC :
345 sprintf (qq, "f%d", (insn_word >> 6) & 0x1f);
346 break;
347
348 case FLM :
349 sprintf (qq, "0x%x", (insn_word >> 17) & 0xff);
350 break;
351
352 case NB :
353 sprintf (qq, "%d", (insn_word >> 11) & 0x1f);
354 break;
355
356 case I :
357 sprintf (qq, "%d", (insn_word >> 12) & 0xf);
358 break;
359
360 default :
361 sprintf (qq, "Unknown operand format identifier????");
362 abort ();
363 }
364 while (*qq) ++qq;
365 ++pp;
366
367 if (*pp == '\0')
368 break;
369 else if (!nocomma)
370 *qq++ = ',';
371 }
372 *qq = '\0';
373
374 fprintf (stream, "0x%08x\t%s%s",
375 insn_word, rs6k_ops[insn_no].operator, buf);
376}
377
This page took 0.043636 seconds and 4 git commands to generate.