[ gas/ChangeLog ]
[platform/upstream/binutils.git] / opcodes / ppc-dis.c
1 /* ppc-dis.c -- Disassemble PowerPC instructions
2    Copyright 1994, 1995, 2000, 2001, 2002, 2003
3    Free Software Foundation, Inc.
4    Written by Ian Lance Taylor, Cygnus Support
5
6 This file is part of GDB, GAS, and the GNU binutils.
7
8 GDB, GAS, and the GNU binutils are free software; you can redistribute
9 them and/or modify them under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either version
11 2, or (at your option) any later version.
12
13 GDB, GAS, and the GNU binutils are distributed in the hope that they
14 will be useful, but WITHOUT ANY WARRANTY; without even the implied
15 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16 the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this file; see the file COPYING.  If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
22 #include <stdio.h>
23 #include "sysdep.h"
24 #include "dis-asm.h"
25 #include "opcode/ppc.h"
26
27 /* This file provides several disassembler functions, all of which use
28    the disassembler interface defined in dis-asm.h.  Several functions
29    are provided because this file handles disassembly for the PowerPC
30    in both big and little endian mode and also for the POWER (RS/6000)
31    chip.  */
32
33 static int print_insn_powerpc PARAMS ((bfd_vma, struct disassemble_info *,
34                                        int bigendian, int dialect));
35
36 static int powerpc_dialect PARAMS ((struct disassemble_info *));
37
38 /* Determine which set of machines to disassemble for.  PPC403/601 or
39    BookE.  For convenience, also disassemble instructions supported
40    by the AltiVec vector unit.  */
41
42 int
43 powerpc_dialect(info)
44      struct disassemble_info *info;
45 {
46   int dialect = PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC;
47
48   if (BFD_DEFAULT_TARGET_SIZE == 64)
49     dialect |= PPC_OPCODE_64;
50
51   if (info->disassembler_options
52       && (strcmp (info->disassembler_options, "booke") == 0
53           || strcmp (info->disassembler_options, "booke32") == 0
54           || strcmp (info->disassembler_options, "booke64") == 0))
55     dialect |= PPC_OPCODE_BOOKE | PPC_OPCODE_BOOKE64;
56   else
57     if ((info->mach == bfd_mach_ppc_e500)
58         || (info->disassembler_options
59         && (   strcmp (info->disassembler_options, "e500") == 0
60             || strcmp (info->disassembler_options, "e500x2") == 0)))
61       {
62         dialect |= PPC_OPCODE_BOOKE
63           | PPC_OPCODE_SPE | PPC_OPCODE_ISEL
64           | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
65           | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
66           | PPC_OPCODE_RFMCI;
67         /* efs* and AltiVec conflict.  */
68         dialect &= ~PPC_OPCODE_ALTIVEC;
69       }
70   else
71     if (info->disassembler_options
72         && (strcmp (info->disassembler_options, "efs") == 0))
73       {
74         dialect |= PPC_OPCODE_EFS;
75         /* efs* and AltiVec conflict.  */
76         dialect &= ~PPC_OPCODE_ALTIVEC;
77       }
78   else
79     dialect |= (PPC_OPCODE_403 | PPC_OPCODE_601 | PPC_OPCODE_CLASSIC
80                 | PPC_OPCODE_COMMON);
81
82   if (info->disassembler_options
83       && strcmp (info->disassembler_options, "power4") == 0)
84     dialect |= PPC_OPCODE_POWER4;
85
86   if (info->disassembler_options)
87     {
88       if (strstr (info->disassembler_options, "32") != NULL)
89         dialect &= ~PPC_OPCODE_64;
90       else if (strstr (info->disassembler_options, "64") != NULL)
91         dialect |= PPC_OPCODE_64;
92     }
93
94   return dialect;
95 }
96
97 /* Print a big endian PowerPC instruction.  */
98
99 int
100 print_insn_big_powerpc (memaddr, info)
101      bfd_vma memaddr;
102      struct disassemble_info *info;
103 {
104   return print_insn_powerpc (memaddr, info, 1, powerpc_dialect(info));
105 }
106
107 /* Print a little endian PowerPC instruction.  */
108
109 int
110 print_insn_little_powerpc (memaddr, info)
111      bfd_vma memaddr;
112      struct disassemble_info *info;
113 {
114   return print_insn_powerpc (memaddr, info, 0, powerpc_dialect(info));
115 }
116
117 /* Print a POWER (RS/6000) instruction.  */
118
119 int
120 print_insn_rs6000 (memaddr, info)
121      bfd_vma memaddr;
122      struct disassemble_info *info;
123 {
124   return print_insn_powerpc (memaddr, info, 1, PPC_OPCODE_POWER);
125 }
126
127 /* Print a PowerPC or POWER instruction.  */
128
129 static int
130 print_insn_powerpc (memaddr, info, bigendian, dialect)
131      bfd_vma memaddr;
132      struct disassemble_info *info;
133      int bigendian;
134      int dialect;
135 {
136   bfd_byte buffer[4];
137   int status;
138   unsigned long insn;
139   const struct powerpc_opcode *opcode;
140   const struct powerpc_opcode *opcode_end;
141   unsigned long op;
142
143   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
144   if (status != 0)
145     {
146       (*info->memory_error_func) (status, memaddr, info);
147       return -1;
148     }
149
150   if (bigendian)
151     insn = bfd_getb32 (buffer);
152   else
153     insn = bfd_getl32 (buffer);
154
155   /* Get the major opcode of the instruction.  */
156   op = PPC_OP (insn);
157
158   /* Find the first match in the opcode table.  We could speed this up
159      a bit by doing a binary search on the major opcode.  */
160   opcode_end = powerpc_opcodes + powerpc_num_opcodes;
161   for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++)
162     {
163       unsigned long table_op;
164       const unsigned char *opindex;
165       const struct powerpc_operand *operand;
166       int invalid;
167       int need_comma;
168       int need_paren;
169
170       table_op = PPC_OP (opcode->opcode);
171       if (op < table_op)
172         break;
173       if (op > table_op)
174         continue;
175
176       if ((insn & opcode->mask) != opcode->opcode
177           || (opcode->flags & dialect) == 0)
178         continue;
179
180       if ((dialect & PPC_OPCODE_EFS) && (opcode->flags & PPC_OPCODE_ALTIVEC))
181         continue;
182
183       /* Make two passes over the operands.  First see if any of them
184          have extraction functions, and, if they do, make sure the
185          instruction is valid.  */
186       invalid = 0;
187       for (opindex = opcode->operands; *opindex != 0; opindex++)
188         {
189           operand = powerpc_operands + *opindex;
190           if (operand->extract)
191             (*operand->extract) (insn, dialect, &invalid);
192         }
193       if (invalid)
194         continue;
195
196       /* The instruction is valid.  */
197       (*info->fprintf_func) (info->stream, "%s", opcode->name);
198       if (opcode->operands[0] != 0)
199         (*info->fprintf_func) (info->stream, "\t");
200
201       /* Now extract and print the operands.  */
202       need_comma = 0;
203       need_paren = 0;
204       for (opindex = opcode->operands; *opindex != 0; opindex++)
205         {
206           long value;
207
208           operand = powerpc_operands + *opindex;
209
210           /* Operands that are marked FAKE are simply ignored.  We
211              already made sure that the extract function considered
212              the instruction to be valid.  */
213           if ((operand->flags & PPC_OPERAND_FAKE) != 0)
214             continue;
215
216           /* Extract the value from the instruction.  */
217           if (operand->extract)
218             value = (*operand->extract) (insn, dialect, &invalid);
219           else
220             {
221               value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
222               if ((operand->flags & PPC_OPERAND_SIGNED) != 0
223                   && (value & (1 << (operand->bits - 1))) != 0)
224                 value -= 1 << operand->bits;
225             }
226
227           /* If the operand is optional, and the value is zero, don't
228              print anything.  */
229           if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
230               && (operand->flags & PPC_OPERAND_NEXT) == 0
231               && value == 0)
232             continue;
233
234           if (need_comma)
235             {
236               (*info->fprintf_func) (info->stream, ",");
237               need_comma = 0;
238             }
239
240           /* Print the operand as directed by the flags.  */
241           if ((operand->flags & PPC_OPERAND_GPR) != 0)
242             (*info->fprintf_func) (info->stream, "r%ld", value);
243           else if ((operand->flags & PPC_OPERAND_FPR) != 0)
244             (*info->fprintf_func) (info->stream, "f%ld", value);
245           else if ((operand->flags & PPC_OPERAND_VR) != 0)
246             (*info->fprintf_func) (info->stream, "v%ld", value);
247           else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
248             (*info->print_address_func) (memaddr + value, info);
249           else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
250             (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
251           else if ((operand->flags & PPC_OPERAND_CR) == 0
252                    || (dialect & PPC_OPCODE_PPC) == 0)
253             (*info->fprintf_func) (info->stream, "%ld", value);
254           else
255             {
256               if (operand->bits == 3)
257                 (*info->fprintf_func) (info->stream, "cr%d", value);
258               else
259                 {
260                   static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
261                   int cr;
262                   int cc;
263
264                   cr = value >> 2;
265                   if (cr != 0)
266                     (*info->fprintf_func) (info->stream, "4*cr%d+", cr);
267                   cc = value & 3;
268                   (*info->fprintf_func) (info->stream, "%s", cbnames[cc]);
269                 }
270             }
271
272           if (need_paren)
273             {
274               (*info->fprintf_func) (info->stream, ")");
275               need_paren = 0;
276             }
277
278           if ((operand->flags & PPC_OPERAND_PARENS) == 0)
279             need_comma = 1;
280           else
281             {
282               (*info->fprintf_func) (info->stream, "(");
283               need_paren = 1;
284             }
285         }
286
287       /* We have found and printed an instruction; return.  */
288       return 4;
289     }
290
291   /* We could not find a match.  */
292   (*info->fprintf_func) (info->stream, ".long 0x%lx", insn);
293
294   return 4;
295 }
296
297 void
298 print_ppc_disassembler_options (FILE * stream)
299 {
300   fprintf (stream, "\n\
301 The following PPC specific disassembler options are supported for use with\n\
302 the -M switch:\n");
303
304   fprintf (stream, "  booke|booke32|booke64    Disassemble the BookE instructions\n");
305   fprintf (stream, "  e500|e500x2              Disassemble the e500 instructions\n");
306   fprintf (stream, "  efs                      Disassemble the EFS instructions\n");
307   fprintf (stream, "  power4                   Disassemble the Power4 instructions\n");
308   fprintf (stream, "  32                       Do not disassemble 64-bit instructions\n");
309   fprintf (stream, "  64                       Allow disassembly of 64-bit instructions\n");
310 }