2009-07-26 Michael Eager <eager@eagercon.com>
[binutils.git] / opcodes / xtensa-dis.c
blob5dfdb22a416ff5a56315e6cdffda971f272a5fee
1 /* xtensa-dis.c. Disassembly functions for Xtensa.
2 Copyright 2003, 2004, 2007 Free Software Foundation, Inc.
3 Contributed by Bob Wilson at Tensilica, Inc. (bwilson@tensilica.com)
5 This file is part of the GNU opcodes library.
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.
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.
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. */
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"
32 #include <setjmp.h>
34 extern xtensa_isa xtensa_default_isa;
36 #ifndef MAX
37 #define MAX(a,b) (a > b ? a : b)
38 #endif
40 int show_raw_fields;
42 struct dis_private
44 bfd_byte *byte_buf;
45 jmp_buf bailout;
49 static int
50 fetch_data (struct disassemble_info *info, bfd_vma memaddr)
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);
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. */
60 memset (priv->byte_buf, 0, insn_size);
61 for (length = insn_size; length > 0; length--)
63 status = (*info->read_memory_func) (memaddr, priv->byte_buf, length,
64 info);
65 if (status == 0)
66 return length;
68 (*info->memory_error_func) (status, memaddr, info);
69 longjmp (priv->bailout, 1);
70 /*NOTREACHED*/
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)
81 xtensa_isa isa = xtensa_default_isa;
82 int signed_operand_val;
84 if (show_raw_fields)
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;
93 (void) xtensa_operand_decode (isa, opc, opnd, &operand_val);
94 signed_operand_val = (int) operand_val;
96 if (xtensa_operand_is_register (isa, opc, opnd) == 0)
98 if (xtensa_operand_is_PCrelative (isa, opc, opnd) == 1)
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);
105 else
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);
113 else
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))
122 operand_val++;
123 (*info->fprintf_func) (info->stream, ":%s%u",
124 xtensa_regfile_shortname (isa, opnd_rf),
125 operand_val);
126 i++;
132 /* Print the Xtensa instruction at address MEMADDR on info->stream.
133 Returns length of the instruction in bytes. */
136 print_insn_xtensa (bfd_vma memaddr, struct disassemble_info *info)
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;
149 if (!xtensa_default_isa)
150 xtensa_default_isa = xtensa_isa_init (0, 0);
152 info->target = 0;
153 maxsize = xtensa_isa_maxlength (xtensa_default_isa);
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);
167 /* Allocate buffers the first time through. */
168 if (!insn_buffer)
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));
175 priv.byte_buf = byte_buf;
177 info->private_data = (void *) &priv;
178 if (setjmp (priv.bailout) != 0)
179 /* Error return. */
180 return -1;
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;
187 /* Fetch the maximum size instruction. */
188 bytes_fetched = fetch_data (info, memaddr);
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);
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
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++)
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)
210 valid_insn = 0;
211 break;
216 if (!valid_insn)
218 (*info->fprintf_func) (info->stream, ".byte %#02x", priv.byte_buf[0]);
219 return 1;
222 if (nslots > 1)
223 (*info->fprintf_func) (info->stream, "{ ");
225 first_slot = 1;
226 for (n = 0; n < nslots; n++)
228 if (first_slot)
229 first_slot = 0;
230 else
231 (*info->fprintf_func) (info->stream, "; ");
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));
238 /* Print the operands (if any). */
239 noperands = xtensa_opcode_num_operands (isa, opc);
240 first = 1;
241 for (i = 0; i < noperands; i++)
243 if (xtensa_operand_is_visible (isa, opc, i) == 0)
244 continue;
245 if (first)
247 (*info->fprintf_func) (info->stream, "\t");
248 first = 0;
250 else
251 (*info->fprintf_func) (info->stream, ", ");
252 (void) xtensa_operand_get_field (isa, opc, i, fmt, n,
253 slot_buffer, &operand_val);
255 print_xtensa_operand (memaddr, info, opc, i, operand_val);
259 if (nslots > 1)
260 (*info->fprintf_func) (info->stream, " }");
262 info->bytes_per_chunk = size;
263 info->display_endian = info->endian;
265 return size;