Upload Tizen:Base source
[external/binutils.git] / opcodes / xtensa-dis.c
1 /* xtensa-dis.c.  Disassembly functions for Xtensa.
2    Copyright 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
3    Contributed by Bob Wilson at Tensilica, Inc. (bwilson@tensilica.com)
4
5    This file is part of the GNU opcodes library.
6
7    This library 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 3, or (at your option)
10    any later version.
11
12    It is distributed in the hope that it will be useful, but WITHOUT
13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15    License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this file; see the file COPYING.  If not, write to the
19    Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
20    MA 02110-1301, USA.  */
21
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <sys/types.h>
25 #include <string.h>
26 #include "xtensa-isa.h"
27 #include "ansidecl.h"
28 #include "libiberty.h"
29 #include "sysdep.h"
30 #include "dis-asm.h"
31
32 #include <setjmp.h>
33
34 extern xtensa_isa xtensa_default_isa;
35
36 #ifndef MAX
37 #define MAX(a,b) (a > b ? a : b)
38 #endif
39
40 int show_raw_fields;
41
42 struct dis_private
43 {
44   bfd_byte *byte_buf;
45   jmp_buf bailout;
46 };
47
48
49 static int
50 fetch_data (struct disassemble_info *info, bfd_vma memaddr)
51 {
52   int length, status = 0;
53   struct dis_private *priv = (struct dis_private *) info->private_data;
54   int insn_size = xtensa_isa_maxlength (xtensa_default_isa);
55
56   /* Read the maximum instruction size, padding with zeros if we go past
57      the end of the text section.  This code will automatically adjust
58      length when we hit the end of the buffer.  */
59
60   memset (priv->byte_buf, 0, insn_size);
61   for (length = insn_size; length > 0; length--)
62     {
63       status = (*info->read_memory_func) (memaddr, priv->byte_buf, length,
64                                           info);
65       if (status == 0)
66         return length;
67     }
68   (*info->memory_error_func) (status, memaddr, info);
69   longjmp (priv->bailout, 1);
70   /*NOTREACHED*/
71 }
72
73
74 static void
75 print_xtensa_operand (bfd_vma memaddr,
76                       struct disassemble_info *info,
77                       xtensa_opcode opc,
78                       int opnd,
79                       unsigned operand_val)
80 {
81   xtensa_isa isa = xtensa_default_isa;
82   int signed_operand_val;
83     
84   if (show_raw_fields)
85     {
86       if (operand_val < 0xa)
87         (*info->fprintf_func) (info->stream, "%u", operand_val);
88       else
89         (*info->fprintf_func) (info->stream, "0x%x", operand_val);
90       return;
91     }
92
93   (void) xtensa_operand_decode (isa, opc, opnd, &operand_val);
94   signed_operand_val = (int) operand_val;
95
96   if (xtensa_operand_is_register (isa, opc, opnd) == 0)
97     {
98       if (xtensa_operand_is_PCrelative (isa, opc, opnd) == 1)
99         {
100           (void) xtensa_operand_undo_reloc (isa, opc, opnd,
101                                             &operand_val, memaddr);
102           info->target = operand_val;
103           (*info->print_address_func) (info->target, info);
104         }
105       else
106         {
107           if ((signed_operand_val > -256) && (signed_operand_val < 256))
108             (*info->fprintf_func) (info->stream, "%d", signed_operand_val);
109           else
110             (*info->fprintf_func) (info->stream, "0x%x", signed_operand_val);
111         }
112     }
113   else
114     {
115       int i = 1;
116       xtensa_regfile opnd_rf = xtensa_operand_regfile (isa, opc, opnd);
117       (*info->fprintf_func) (info->stream, "%s%u",
118                              xtensa_regfile_shortname (isa, opnd_rf),
119                              operand_val);
120       while (i < xtensa_operand_num_regs (isa, opc, opnd))
121         {
122           operand_val++;
123           (*info->fprintf_func) (info->stream, ":%s%u",
124                                  xtensa_regfile_shortname (isa, opnd_rf),
125                                  operand_val);
126           i++;
127         } 
128     }
129 }
130
131
132 /* Print the Xtensa instruction at address MEMADDR on info->stream.
133    Returns length of the instruction in bytes.  */
134
135 int
136 print_insn_xtensa (bfd_vma memaddr, struct disassemble_info *info)
137 {
138   unsigned operand_val;
139   int bytes_fetched, size, maxsize, i, n, noperands, nslots;
140   xtensa_isa isa;
141   xtensa_opcode opc;
142   xtensa_format fmt;
143   struct dis_private priv;
144   static bfd_byte *byte_buf = NULL;
145   static xtensa_insnbuf insn_buffer = NULL;
146   static xtensa_insnbuf slot_buffer = NULL;
147   int first, first_slot, valid_insn;
148
149   if (!xtensa_default_isa)
150     xtensa_default_isa = xtensa_isa_init (0, 0);
151
152   info->target = 0;
153   maxsize = xtensa_isa_maxlength (xtensa_default_isa);
154
155   /* Set bytes_per_line to control the amount of whitespace between the hex
156      values and the opcode.  For Xtensa, we always print one "chunk" and we
157      vary bytes_per_chunk to determine how many bytes to print.  (objdump
158      would apparently prefer that we set bytes_per_chunk to 1 and vary
159      bytes_per_line but that makes it hard to fit 64-bit instructions on
160      an 80-column screen.)  The value of bytes_per_line here is not exactly
161      right, because objdump adds an extra space for each chunk so that the
162      amount of whitespace depends on the chunk size.  Oh well, it's good
163      enough....  Note that we set the minimum size to 4 to accomodate
164      literal pools.  */
165   info->bytes_per_line = MAX (maxsize, 4);
166
167   /* Allocate buffers the first time through.  */
168   if (!insn_buffer)
169     {
170       insn_buffer = xtensa_insnbuf_alloc (xtensa_default_isa);
171       slot_buffer = xtensa_insnbuf_alloc (xtensa_default_isa);
172       byte_buf = (bfd_byte *) xmalloc (MAX (maxsize, 4));
173     }
174
175   priv.byte_buf = byte_buf;
176
177   info->private_data = (void *) &priv;
178   if (setjmp (priv.bailout) != 0)
179       /* Error return.  */
180       return -1;
181
182   /* Don't set "isa" before the setjmp to keep the compiler from griping.  */
183   isa = xtensa_default_isa;
184   size = 0;
185   nslots = 0;
186
187   /* Fetch the maximum size instruction.  */
188   bytes_fetched = fetch_data (info, memaddr);
189
190   /* Copy the bytes into the decode buffer.  */
191   memset (insn_buffer, 0, (xtensa_insnbuf_size (isa) *
192                            sizeof (xtensa_insnbuf_word)));
193   xtensa_insnbuf_from_chars (isa, insn_buffer, priv.byte_buf, bytes_fetched);
194
195   fmt = xtensa_format_decode (isa, insn_buffer);
196   if (fmt == XTENSA_UNDEFINED
197       || ((size = xtensa_format_length (isa, fmt)) > bytes_fetched))
198     valid_insn = 0;
199   else
200     {
201       /* Make sure all the opcodes are valid.  */
202       valid_insn = 1;
203       nslots = xtensa_format_num_slots (isa, fmt);
204       for (n = 0; n < nslots; n++)
205         {
206           xtensa_format_get_slot (isa, fmt, n, insn_buffer, slot_buffer);
207           if (xtensa_opcode_decode (isa, fmt, n, slot_buffer)
208               == XTENSA_UNDEFINED)
209             {
210               valid_insn = 0;
211               break;
212             }
213         }
214     }
215
216   if (!valid_insn)
217     {
218       (*info->fprintf_func) (info->stream, ".byte %#02x", priv.byte_buf[0]);
219       return 1;
220     }
221
222   if (nslots > 1)
223     (*info->fprintf_func) (info->stream, "{ ");
224
225   first_slot = 1;
226   for (n = 0; n < nslots; n++)
227     {
228       if (first_slot)
229         first_slot = 0;
230       else
231         (*info->fprintf_func) (info->stream, "; ");
232
233       xtensa_format_get_slot (isa, fmt, n, insn_buffer, slot_buffer);
234       opc = xtensa_opcode_decode (isa, fmt, n, slot_buffer);
235       (*info->fprintf_func) (info->stream, "%s",
236                              xtensa_opcode_name (isa, opc));
237
238       /* Print the operands (if any).  */
239       noperands = xtensa_opcode_num_operands (isa, opc);
240       first = 1;
241       for (i = 0; i < noperands; i++)
242         {
243           if (xtensa_operand_is_visible (isa, opc, i) == 0)
244             continue;
245           if (first)
246             {
247               (*info->fprintf_func) (info->stream, "\t");
248               first = 0;
249             }
250           else
251             (*info->fprintf_func) (info->stream, ", ");
252           (void) xtensa_operand_get_field (isa, opc, i, fmt, n,
253                                            slot_buffer, &operand_val);
254
255           print_xtensa_operand (memaddr, info, opc, i, operand_val);
256         }
257     }
258
259   if (nslots > 1)
260     (*info->fprintf_func) (info->stream, " }");
261
262   info->bytes_per_chunk = size;
263   info->display_endian = info->endian;
264
265   return size;
266 }
267