1 /* Print IBM RS/6000 instructions for GNU software.
2 Copyright 1991 Free Software Foundation, Inc.
3 Contributed by IBM Corporation.
5 This file is part of GDB and the GNU binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
23 #include "rs6k-opcode.h"
25 /* Print the rs6k instruction at address MEMADDR in debugged memory,
26 on STREAM. Returns length of the instruction, in bytes. */
29 print_insn (memaddr
, stream
)
33 int pop
, eop
; /* primary and extended opcodes */
35 int best
= -1; /* found best opcode index */
37 unsigned int the_insn
;
39 read_memory (memaddr
, &the_insn
, sizeof (the_insn
));
40 pop
= (unsigned)(the_insn
>> 26);
41 eop
= ((the_insn
) >> 1) & 0x3ff;
42 min
= 0, max
= NOPCODES
-1;
45 best
= (min
+ max
) / 2;
47 /* see if we are running in loops */
52 if (pop
< rs6k_ops
[best
].p_opcode
)
55 else if (pop
> rs6k_ops
[best
].p_opcode
)
59 /* opcode matched, check extended opcode. */
61 if (rs6k_ops
[best
].e_opcode
== -1) {
62 /* there is no valid extended opcode, what we've got is
67 else if (eop
< rs6k_ops
[best
].e_opcode
) {
69 while (pop
== rs6k_ops
[best
].p_opcode
) {
70 if (eop
== rs6k_ops
[best
].e_opcode
) /* found it! */
77 else if (eop
> rs6k_ops
[best
].e_opcode
) {
79 while (pop
== rs6k_ops
[best
].p_opcode
) {
80 if (eop
== rs6k_ops
[best
].e_opcode
) /* found it! */
87 else /* eop == rs6k_ops [best].e_opcode */
93 if (pop
== rs6k_ops
[best
].p_opcode
&&
94 (rs6k_ops
[best
].e_opcode
== -1 || rs6k_ops
[best
].e_opcode
== eop
))
102 print_operator (stream
, memaddr
, the_insn
, best
);
106 fprintf (stream
, "0x%08x", the_insn
);
112 /* condition code names */
113 static char *cond_code
[] = {
114 "lt", "gt", "eq", "so", "ge", "le", "ne", "ns", "nl", "ng", "z", "nz" };
117 print_operator (stream
, memaddr
, insn_word
, insn_no
)
125 char *pp
= rs6k_ops
[insn_no
].opr_ext
;
127 int nocomma
= 0; /* true if no comma needed */
145 if ((insn_word
& 0x03e00000) == 0x01800000)
150 if ((insn_word
& 0x03e00000) == 0x00800000)
160 if (insn_word
& 0x4000)
164 case '1': /* exception #1 for bb/bc ambiguity */
165 tmp
= (insn_word
>> 21) & 0x1f; /* extract BO */
166 if (tmp
!= 0xc && tmp
!= 0x4) {
167 /* you can't use `bb' now. switch to `bc' */
170 pp
= rs6k_ops
[insn_no
].opr_ext
;
182 /* tab between operator and operand */
185 /* parse the operand now. */
186 pp
= rs6k_ops
[insn_no
].oprnd_format
;
191 sprintf (qq
, "%d", (insn_word
>> 21) & 0x1f);
196 sprintf (qq
, "r%d", (insn_word
>> 21) & 0x1f);
200 tmp
= (insn_word
>> 16) & 0x1f;
202 fprintf (stderr
, "Internal error: unknown cond code: 0x%x\n", insn_word
);
205 sprintf (qq
, "%s", cond_code
[tmp
]);
210 tmp
= (insn_word
& 0xfffc);
211 if (tmp
& 0x8000) /* fix sign extension */
214 if ((insn_word
& 0x2) == 0) /* if AA not set */
217 sprintf (qq
, "0x%x", tmp
);
221 tmp
= insn_word
& 0x03fffffc;
225 if ((insn_word
& 0x2) == 0) /* if no AA bit set */
228 sprintf (qq
, "0x%x", tmp
);
231 case LEV
: /* for svc only */
232 if (insn_word
& 0x2) { /* SA is set */
237 sprintf (qq
, "%d", (insn_word
>> 5) & 0x7f);
240 case FL1
: /* for svc only */
241 if (insn_word
& 0x2) { /* SA is set */
246 sprintf (qq
, "%d", (insn_word
>> 12) & 0xf);
249 case FL2
: /* for svc only */
251 if (insn_word
& 0x2) /* SA is set */
252 sprintf (qq
, "%d", (insn_word
>> 2) & 0x3fff);
254 sprintf (qq
, "%d", (insn_word
>> 2) & 0x7);
259 sprintf (qq
, "r%d)", (insn_word
>> 16) & 0x1f);
263 sprintf (qq
, "r%d", (insn_word
>> 16) & 0x1f);
267 sprintf (qq
, "r%d", (insn_word
>> 11) & 0x1f);
271 tmp
= insn_word
& 0xffff;
274 sprintf (qq
, "%d", tmp
);
278 sprintf (qq
, "%d", insn_word
& 0xffff);
282 sprintf (qq
, "%d", (insn_word
>> 23) & 0x7);
286 sprintf (qq
, "%d", (insn_word
>> 18) & 0x7);
290 sprintf (qq
, "%d", (insn_word
>> 21) & 0x1f);
294 sprintf (qq
, "%d", (insn_word
>> 16) & 0x1f);
298 sprintf (qq
, "%d", (insn_word
>> 11) & 0x1f);
302 sprintf (qq
, "%d", (insn_word
>> 21) & 0x1f);
306 sprintf (qq
, "%d", (insn_word
>> 16) & 0x1f);
310 sprintf (qq
, "%d", (insn_word
>> 11) & 0x1f);
314 sprintf (qq
, "0x%x", (insn_word
>> 6) & 0x1f);
318 sprintf (qq
, "0x%x", (insn_word
>> 1) & 0x1f);
322 sprintf (qq
, "%d", (insn_word
>> 16) & 0x1f);
327 tmp
= insn_word
& 0xffff;
330 sprintf (qq
, "%d(", tmp
);
334 sprintf (qq
, "0x%x", (insn_word
>> 12) & 0xff);
339 sprintf (qq
, "f%d", (insn_word
>> 21) & 0x1f);
343 sprintf (qq
, "f%d", (insn_word
>> 16) & 0x1f);
347 sprintf (qq
, "f%d", (insn_word
>> 11) & 0x1f);
351 sprintf (qq
, "f%d", (insn_word
>> 6) & 0x1f);
355 sprintf (qq
, "0x%x", (insn_word
>> 17) & 0xff);
359 sprintf (qq
, "%d", (insn_word
>> 11) & 0x1f);
363 sprintf (qq
, "%d", (insn_word
>> 12) & 0xf);
367 sprintf (qq
, "Unknown operand format identifier %d????", *pp
);
370 while (*qq
) ++qq
; /* Walk to end of string printed so far. */
380 fprintf (stream
, "0x%08x\t%s%s",
381 insn_word
, rs6k_ops
[insn_no
].operator, buf
);
This page took 0.038449 seconds and 4 git commands to generate.