* GDB 6.5 released from GDB 6.5 branch.
[deliverable/binutils-gdb.git] / opcodes / xtensa-dis.c
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)
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
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
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"
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
This page took 0.036138 seconds and 4 git commands to generate.