1 /* xtensa-dis.c. Disassembly functions for Xtensa.
2 Copyright 2003, 2004 Free Software Foundation, Inc.
3 Contributed by Bob Wilson at Tensilica, Inc. (bwilson@tensilica.com)
5 This file is part of GDB, GAS, and the GNU binutils.
7 GDB, GAS, and the GNU binutils are free software; you can redistribute
8 them and/or modify them under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either version 2,
10 or (at your option) any later version.
12 GDB, GAS, and the GNU binutils are distributed in the hope that they
13 will be useful, but WITHOUT ANY WARRANTY; without even the implied
14 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this file; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
24 #include <sys/types.h>
26 #include "xtensa-isa.h"
28 #include "libiberty.h"
34 extern xtensa_isa xtensa_default_isa;
37 #define MAX(a,b) (a > b ? a : b)
43 PARAMS ((struct disassemble_info *, bfd_vma));
44 static void print_xtensa_operand
45 PARAMS ((bfd_vma, struct disassemble_info *, xtensa_opcode, int, unsigned));
55 fetch_data (info, memaddr)
56 struct disassemble_info *info;
59 int length, status = 0;
60 struct dis_private *priv = (struct dis_private *) info->private_data;
61 int insn_size = xtensa_isa_maxlength (xtensa_default_isa);
63 /* Read the maximum instruction size, padding with zeros if we go past
64 the end of the text section. This code will automatically adjust
65 length when we hit the end of the buffer. */
67 memset (priv->byte_buf, 0, insn_size);
68 for (length = insn_size; length > 0; length--)
70 status = (*info->read_memory_func) (memaddr, priv->byte_buf, length,
75 (*info->memory_error_func) (status, memaddr, info);
76 longjmp (priv->bailout, 1);
82 print_xtensa_operand (memaddr, info, opc, opnd, operand_val)
84 struct disassemble_info *info;
89 xtensa_isa isa = xtensa_default_isa;
90 int signed_operand_val;
94 if (operand_val < 0xa)
95 (*info->fprintf_func) (info->stream, "%u", operand_val);
97 (*info->fprintf_func) (info->stream, "0x%x", operand_val);
101 (void) xtensa_operand_decode (isa, opc, opnd, &operand_val);
102 signed_operand_val = (int) operand_val;
104 if (xtensa_operand_is_register (isa, opc, opnd) == 0)
106 if (xtensa_operand_is_PCrelative (isa, opc, opnd) == 1)
108 (void) xtensa_operand_undo_reloc (isa, opc, opnd,
109 &operand_val, memaddr);
110 info->target = operand_val;
111 (*info->print_address_func) (info->target, info);
115 if ((signed_operand_val > -256) && (signed_operand_val < 256))
116 (*info->fprintf_func) (info->stream, "%d", signed_operand_val);
118 (*info->fprintf_func) (info->stream, "0x%x", signed_operand_val);
124 xtensa_regfile opnd_rf = xtensa_operand_regfile (isa, opc, opnd);
125 (*info->fprintf_func) (info->stream, "%s%u",
126 xtensa_regfile_shortname (isa, opnd_rf),
128 while (i < xtensa_operand_num_regs (isa, opc, opnd))
131 (*info->fprintf_func) (info->stream, ":%s%u",
132 xtensa_regfile_shortname (isa, opnd_rf),
140 /* Print the Xtensa instruction at address MEMADDR on info->stream.
141 Returns length of the instruction in bytes. */
144 print_insn_xtensa (memaddr, info)
146 struct disassemble_info *info;
148 unsigned operand_val;
149 int bytes_fetched, size, maxsize, i, n, noperands, nslots;
153 struct dis_private priv;
154 static bfd_byte *byte_buf = NULL;
155 static xtensa_insnbuf insn_buffer = NULL;
156 static xtensa_insnbuf slot_buffer = NULL;
157 int first, first_slot, valid_insn;
159 if (!xtensa_default_isa)
160 xtensa_default_isa = xtensa_isa_init (0, 0);
163 maxsize = xtensa_isa_maxlength (xtensa_default_isa);
165 /* Set bytes_per_line to control the amount of whitespace between the hex
166 values and the opcode. For Xtensa, we always print one "chunk" and we
167 vary bytes_per_chunk to determine how many bytes to print. (objdump
168 would apparently prefer that we set bytes_per_chunk to 1 and vary
169 bytes_per_line but that makes it hard to fit 64-bit instructions on
170 an 80-column screen.) The value of bytes_per_line here is not exactly
171 right, because objdump adds an extra space for each chunk so that the
172 amount of whitespace depends on the chunk size. Oh well, it's good
173 enough.... Note that we set the minimum size to 4 to accomodate
175 info->bytes_per_line = MAX (maxsize, 4);
177 /* Allocate buffers the first time through. */
180 insn_buffer = xtensa_insnbuf_alloc (xtensa_default_isa);
181 slot_buffer = xtensa_insnbuf_alloc (xtensa_default_isa);
182 byte_buf = (bfd_byte *) xmalloc (MAX (maxsize, 4));
185 priv.byte_buf = byte_buf;
187 info->private_data = (PTR) &priv;
188 if (setjmp (priv.bailout) != 0)
192 /* Don't set "isa" before the setjmp to keep the compiler from griping. */
193 isa = xtensa_default_isa;
197 /* Fetch the maximum size instruction. */
198 bytes_fetched = fetch_data (info, memaddr);
200 /* Copy the bytes into the decode buffer. */
201 memset (insn_buffer, 0, (xtensa_insnbuf_size (isa) *
202 sizeof (xtensa_insnbuf_word)));
203 xtensa_insnbuf_from_chars (isa, insn_buffer, priv.byte_buf, bytes_fetched);
205 fmt = xtensa_format_decode (isa, insn_buffer);
206 if (fmt == XTENSA_UNDEFINED
207 || ((size = xtensa_format_length (isa, fmt)) > bytes_fetched))
211 /* Make sure all the opcodes are valid. */
213 nslots = xtensa_format_num_slots (isa, fmt);
214 for (n = 0; n < nslots; n++)
216 xtensa_format_get_slot (isa, fmt, n, insn_buffer, slot_buffer);
217 if (xtensa_opcode_decode (isa, fmt, n, slot_buffer)
228 (*info->fprintf_func) (info->stream, ".byte %#02x", priv.byte_buf[0]);
233 (*info->fprintf_func) (info->stream, "{ ");
236 for (n = 0; n < nslots; n++)
241 (*info->fprintf_func) (info->stream, "; ");
243 xtensa_format_get_slot (isa, fmt, n, insn_buffer, slot_buffer);
244 opc = xtensa_opcode_decode (isa, fmt, n, slot_buffer);
245 (*info->fprintf_func) (info->stream, "%s",
246 xtensa_opcode_name (isa, opc));
248 /* Print the operands (if any). */
249 noperands = xtensa_opcode_num_operands (isa, opc);
251 for (i = 0; i < noperands; i++)
253 if (xtensa_operand_is_visible (isa, opc, i) == 0)
257 (*info->fprintf_func) (info->stream, "\t");
261 (*info->fprintf_func) (info->stream, ", ");
262 (void) xtensa_operand_get_field (isa, opc, i, fmt, n,
263 slot_buffer, &operand_val);
265 print_xtensa_operand (memaddr, info, opc, i, operand_val);
270 (*info->fprintf_func) (info->stream, " }");
272 info->bytes_per_chunk = size;
273 info->display_endian = info->endian;