sim/mips/
[deliverable/binutils-gdb.git] / opcodes / xtensa-dis.c
CommitLineData
e0001a05 1/* xtensa-dis.c. Disassembly functions for Xtensa.
43cd72b9 2 Copyright 2003, 2004 Free Software Foundation, Inc.
e0001a05
NC
3 Contributed by Bob Wilson at Tensilica, Inc. (bwilson@tensilica.com)
4
5 This file is part of GDB, GAS, and the GNU binutils.
6
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.
11
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.
16
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
f4321104 19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
e0001a05
NC
20 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"
43cd72b9 28#include "libiberty.h"
e0001a05
NC
29#include "sysdep.h"
30#include "dis-asm.h"
31
32#include <setjmp.h>
33
43cd72b9
BW
34extern xtensa_isa xtensa_default_isa;
35
e0001a05
NC
36#ifndef MAX
37#define MAX(a,b) (a > b ? a : b)
38#endif
39
e0001a05
NC
40int show_raw_fields;
41
43cd72b9
BW
42struct dis_private
43{
e0001a05
NC
44 bfd_byte *byte_buf;
45 jmp_buf bailout;
46};
47
43cd72b9 48
e0001a05 49static int
7fa3d080 50fetch_data (struct disassemble_info *info, bfd_vma memaddr)
e0001a05
NC
51{
52 int length, status = 0;
53 struct dis_private *priv = (struct dis_private *) info->private_data;
43cd72b9 54 int insn_size = xtensa_isa_maxlength (xtensa_default_isa);
e0001a05
NC
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
74static void
7fa3d080
BW
75print_xtensa_operand (bfd_vma memaddr,
76 struct disassemble_info *info,
77 xtensa_opcode opc,
78 int opnd,
79 unsigned operand_val)
e0001a05 80{
43cd72b9 81 xtensa_isa isa = xtensa_default_isa;
e0001a05
NC
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
43cd72b9 93 (void) xtensa_operand_decode (isa, opc, opnd, &operand_val);
e0001a05
NC
94 signed_operand_val = (int) operand_val;
95
43cd72b9 96 if (xtensa_operand_is_register (isa, opc, opnd) == 0)
e0001a05 97 {
43cd72b9
BW
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 }
e0001a05 105 else
43cd72b9
BW
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 }
e0001a05
NC
112 }
113 else
43cd72b9
BW
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 }
e0001a05
NC
129}
130
131
132/* Print the Xtensa instruction at address MEMADDR on info->stream.
133 Returns length of the instruction in bytes. */
134
135int
7fa3d080 136print_insn_xtensa (bfd_vma memaddr, struct disassemble_info *info)
e0001a05
NC
137{
138 unsigned operand_val;
43cd72b9 139 int bytes_fetched, size, maxsize, i, n, noperands, nslots;
e0001a05
NC
140 xtensa_isa isa;
141 xtensa_opcode opc;
43cd72b9 142 xtensa_format fmt;
e0001a05
NC
143 struct dis_private priv;
144 static bfd_byte *byte_buf = NULL;
145 static xtensa_insnbuf insn_buffer = NULL;
43cd72b9
BW
146 static xtensa_insnbuf slot_buffer = NULL;
147 int first, first_slot, valid_insn;
e0001a05
NC
148
149 if (!xtensa_default_isa)
43cd72b9 150 xtensa_default_isa = xtensa_isa_init (0, 0);
e0001a05
NC
151
152 info->target = 0;
43cd72b9 153 maxsize = xtensa_isa_maxlength (xtensa_default_isa);
e0001a05
NC
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)
43cd72b9
BW
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 }
e0001a05
NC
174
175 priv.byte_buf = byte_buf;
176
7fa3d080 177 info->private_data = (void *) &priv;
e0001a05
NC
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;
43cd72b9
BW
184 size = 0;
185 nslots = 0;
e0001a05
NC
186
187 /* Fetch the maximum size instruction. */
118fecd3 188 bytes_fetched = fetch_data (info, memaddr);
e0001a05
NC
189
190 /* Copy the bytes into the decode buffer. */
191 memset (insn_buffer, 0, (xtensa_insnbuf_size (isa) *
192 sizeof (xtensa_insnbuf_word)));
43cd72b9
BW
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 }
e0001a05 215
43cd72b9 216 if (!valid_insn)
e0001a05
NC
217 {
218 (*info->fprintf_func) (info->stream, ".byte %#02x", priv.byte_buf[0]);
219 return 1;
220 }
221
43cd72b9
BW
222 if (nslots > 1)
223 (*info->fprintf_func) (info->stream, "{ ");
e0001a05 224
43cd72b9
BW
225 first_slot = 1;
226 for (n = 0; n < nslots; n++)
e0001a05 227 {
43cd72b9
BW
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));
e0001a05 237
43cd72b9
BW
238 /* Print the operands (if any). */
239 noperands = xtensa_opcode_num_operands (isa, opc);
240 first = 1;
e0001a05
NC
241 for (i = 0; i < noperands; i++)
242 {
43cd72b9
BW
243 if (xtensa_operand_is_visible (isa, opc, i) == 0)
244 continue;
e0001a05 245 if (first)
43cd72b9
BW
246 {
247 (*info->fprintf_func) (info->stream, "\t");
248 first = 0;
249 }
e0001a05
NC
250 else
251 (*info->fprintf_func) (info->stream, ", ");
43cd72b9
BW
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 }
e0001a05
NC
257 }
258
43cd72b9
BW
259 if (nslots > 1)
260 (*info->fprintf_func) (info->stream, " }");
261
e0001a05
NC
262 info->bytes_per_chunk = size;
263 info->display_endian = info->endian;
264
265 return size;
266}
267
This page took 0.221711 seconds and 4 git commands to generate.