1 /* ppc-dis.c -- Disassemble PowerPC instructions
2    Copyright 1994, 1995, 2000, 2001, 2002, 2003, 2004, 2005
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, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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 (bfd_vma, struct disassemble_info *, int, int);
34 
35 struct dis_private {
36   /* Stash the result of parsing disassembler_options here.  */
37   int dialect;
38 };
39 
40 /* Determine which set of machines to disassemble for.  PPC403/601 or
41    BookE.  For convenience, also disassemble instructions supported
42    by the AltiVec vector unit.  */
43 
44 static int
powerpc_dialect(struct disassemble_info * info)45 powerpc_dialect (struct disassemble_info *info)
46 {
47   int dialect = PPC_OPCODE_PPC;
48 
49   if (BFD_DEFAULT_TARGET_SIZE == 64)
50     dialect |= PPC_OPCODE_64;
51 
52   if (info->disassembler_options
53       && strstr (info->disassembler_options, "booke") != NULL)
54     dialect |= PPC_OPCODE_BOOKE | PPC_OPCODE_BOOKE64;
55   else if ((info->mach == bfd_mach_ppc_e500)
56 	   || (info->disassembler_options
57 	       && strstr (info->disassembler_options, "e500") != NULL))
58     dialect |= (PPC_OPCODE_BOOKE
59 		| PPC_OPCODE_SPE | PPC_OPCODE_ISEL
60 		| PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
61 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
62 		| PPC_OPCODE_RFMCI);
63   else if (info->disassembler_options
64 	   && strstr (info->disassembler_options, "efs") != NULL)
65     dialect |= PPC_OPCODE_EFS;
66   else
67     dialect |= (PPC_OPCODE_403 | PPC_OPCODE_601 | PPC_OPCODE_CLASSIC
68 		| PPC_OPCODE_COMMON | PPC_OPCODE_ALTIVEC);
69 
70   if (info->disassembler_options
71       && strstr (info->disassembler_options, "power4") != NULL)
72     dialect |= PPC_OPCODE_POWER4;
73 
74   if (info->disassembler_options
75       && strstr (info->disassembler_options, "power5") != NULL)
76     dialect |= PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5;
77 
78   if (info->disassembler_options
79       && strstr (info->disassembler_options, "any") != NULL)
80     dialect |= PPC_OPCODE_ANY;
81 
82   if (info->disassembler_options)
83     {
84       if (strstr (info->disassembler_options, "32") != NULL)
85 	dialect &= ~PPC_OPCODE_64;
86       else if (strstr (info->disassembler_options, "64") != NULL)
87 	dialect |= PPC_OPCODE_64;
88     }
89 
90   ((struct dis_private *) &info->private_data)->dialect = dialect;
91   return dialect;
92 }
93 
94 /* Print a big endian PowerPC instruction.  */
95 
96 int
print_insn_big_powerpc(bfd_vma memaddr,struct disassemble_info * info)97 print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info)
98 {
99   int dialect = ((struct dis_private *) &info->private_data)->dialect;
100   return print_insn_powerpc (memaddr, info, 1, dialect);
101 }
102 
103 /* Print a little endian PowerPC instruction.  */
104 
105 int
print_insn_little_powerpc(bfd_vma memaddr,struct disassemble_info * info)106 print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info)
107 {
108   int dialect = ((struct dis_private *) &info->private_data)->dialect;
109   return print_insn_powerpc (memaddr, info, 0, dialect);
110 }
111 
112 /* Print a POWER (RS/6000) instruction.  */
113 
114 int
print_insn_rs6000(bfd_vma memaddr,struct disassemble_info * info)115 print_insn_rs6000 (bfd_vma memaddr, struct disassemble_info *info)
116 {
117   return print_insn_powerpc (memaddr, info, 1, PPC_OPCODE_POWER);
118 }
119 
120 /* Print a PowerPC or POWER instruction.  */
121 
122 static int
print_insn_powerpc(bfd_vma memaddr,struct disassemble_info * info,int bigendian,int dialect)123 print_insn_powerpc (bfd_vma memaddr,
124 		    struct disassemble_info *info,
125 		    int bigendian,
126 		    int dialect)
127 {
128   bfd_byte buffer[4];
129   int status;
130   unsigned long insn;
131   const struct powerpc_opcode *opcode;
132   const struct powerpc_opcode *opcode_end;
133   unsigned long op;
134 
135   if (dialect == 0)
136     dialect = powerpc_dialect (info);
137 
138   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
139   if (status != 0)
140     {
141       (*info->memory_error_func) (status, memaddr, info);
142       return -1;
143     }
144 
145   if (bigendian)
146     insn = bfd_getb32 (buffer);
147   else
148     insn = bfd_getl32 (buffer);
149 
150   /* Get the major opcode of the instruction.  */
151   op = PPC_OP (insn);
152 
153   /* Find the first match in the opcode table.  We could speed this up
154      a bit by doing a binary search on the major opcode.  */
155   opcode_end = powerpc_opcodes + powerpc_num_opcodes;
156  again:
157   for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++)
158     {
159       unsigned long table_op;
160       const unsigned char *opindex;
161       const struct powerpc_operand *operand;
162       int invalid;
163       int need_comma;
164       int need_paren;
165 
166       table_op = PPC_OP (opcode->opcode);
167       if (op < table_op)
168 	break;
169       if (op > table_op)
170 	continue;
171 
172       if ((insn & opcode->mask) != opcode->opcode
173 	  || (opcode->flags & dialect) == 0)
174 	continue;
175 
176       /* Make two passes over the operands.  First see if any of them
177 	 have extraction functions, and, if they do, make sure the
178 	 instruction is valid.  */
179       invalid = 0;
180       for (opindex = opcode->operands; *opindex != 0; opindex++)
181 	{
182 	  operand = powerpc_operands + *opindex;
183 	  if (operand->extract)
184 	    (*operand->extract) (insn, dialect, &invalid);
185 	}
186       if (invalid)
187 	continue;
188 
189       /* The instruction is valid.  */
190       if (opcode->operands[0] != 0)
191 	(*info->fprintf_func) (info->stream, "%-7s ", opcode->name);
192       else
193 	(*info->fprintf_func) (info->stream, "%s", opcode->name);
194 
195       /* Now extract and print the operands.  */
196       need_comma = 0;
197       need_paren = 0;
198       for (opindex = opcode->operands; *opindex != 0; opindex++)
199 	{
200 	  long value;
201 
202 	  operand = powerpc_operands + *opindex;
203 
204 	  /* Operands that are marked FAKE are simply ignored.  We
205 	     already made sure that the extract function considered
206 	     the instruction to be valid.  */
207 	  if ((operand->flags & PPC_OPERAND_FAKE) != 0)
208 	    continue;
209 
210 	  /* Extract the value from the instruction.  */
211 	  if (operand->extract)
212 	    value = (*operand->extract) (insn, dialect, &invalid);
213 	  else
214 	    {
215 	      value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
216 	      if ((operand->flags & PPC_OPERAND_SIGNED) != 0
217 		  && (value & (1 << (operand->bits - 1))) != 0)
218 		value -= 1 << operand->bits;
219 	    }
220 
221 	  /* If the operand is optional, and the value is zero, don't
222 	     print anything.  */
223 	  if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
224 	      && (operand->flags & PPC_OPERAND_NEXT) == 0
225 	      && value == 0)
226 	    continue;
227 
228 	  if (need_comma)
229 	    {
230 	      (*info->fprintf_func) (info->stream, ",");
231 	      need_comma = 0;
232 	    }
233 
234 	  /* Print the operand as directed by the flags.  */
235 	  if ((operand->flags & PPC_OPERAND_GPR) != 0
236 	      || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
237 	    (*info->fprintf_func) (info->stream, "r%ld", value);
238 	  else if ((operand->flags & PPC_OPERAND_FPR) != 0)
239 	    (*info->fprintf_func) (info->stream, "f%ld", value);
240 	  else if ((operand->flags & PPC_OPERAND_VR) != 0)
241 	    (*info->fprintf_func) (info->stream, "v%ld", value);
242 	  else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
243 	    (*info->print_address_func) (memaddr + value, info);
244 	  else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
245 	    (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
246 	  else if ((operand->flags & PPC_OPERAND_CR) == 0
247 		   || (dialect & PPC_OPCODE_PPC) == 0)
248 	    (*info->fprintf_func) (info->stream, "%ld", value);
249 	  else
250 	    {
251 	      if (operand->bits == 3)
252 		(*info->fprintf_func) (info->stream, "cr%d", value);
253 	      else
254 		{
255 		  static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
256 		  int cr;
257 		  int cc;
258 
259 		  cr = value >> 2;
260 		  if (cr != 0)
261 		    (*info->fprintf_func) (info->stream, "4*cr%d+", cr);
262 		  cc = value & 3;
263 		  (*info->fprintf_func) (info->stream, "%s", cbnames[cc]);
264 		}
265 	    }
266 
267 	  if (need_paren)
268 	    {
269 	      (*info->fprintf_func) (info->stream, ")");
270 	      need_paren = 0;
271 	    }
272 
273 	  if ((operand->flags & PPC_OPERAND_PARENS) == 0)
274 	    need_comma = 1;
275 	  else
276 	    {
277 	      (*info->fprintf_func) (info->stream, "(");
278 	      need_paren = 1;
279 	    }
280 	}
281 
282       /* We have found and printed an instruction; return.  */
283       return 4;
284     }
285 
286   if ((dialect & PPC_OPCODE_ANY) != 0)
287     {
288       dialect = ~PPC_OPCODE_ANY;
289       goto again;
290     }
291 
292   /* We could not find a match.  */
293   (*info->fprintf_func) (info->stream, ".long 0x%lx", insn);
294 
295   return 4;
296 }
297 
298 void
print_ppc_disassembler_options(FILE * stream)299 print_ppc_disassembler_options (FILE *stream)
300 {
301   fprintf (stream, "\n\
302 The following PPC specific disassembler options are supported for use with\n\
303 the -M switch:\n");
304 
305   fprintf (stream, "  booke|booke32|booke64    Disassemble the BookE instructions\n");
306   fprintf (stream, "  e500|e500x2              Disassemble the e500 instructions\n");
307   fprintf (stream, "  efs                      Disassemble the EFS instructions\n");
308   fprintf (stream, "  power4                   Disassemble the Power4 instructions\n");
309   fprintf (stream, "  power5                   Disassemble the Power5 instructions\n");
310   fprintf (stream, "  32                       Do not disassemble 64-bit instructions\n");
311   fprintf (stream, "  64                       Allow disassembly of 64-bit instructions\n");
312 }
313