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