1 /* xtensa-dis.c. Disassembly functions for Xtensa.
2 Copyright 2003, 2004, 2005, 2007, 2012 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)
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. */
25 #include <sys/types.h>
27 #include "xtensa-isa.h"
29 #include "libiberty.h"
34 extern xtensa_isa xtensa_default_isa
;
37 #define MAX(a,b) (a > b ? a : b)
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
,
68 (*info
->memory_error_func
) (status
, memaddr
, info
);
69 longjmp (priv
->bailout
, 1);
75 print_xtensa_operand (bfd_vma memaddr
,
76 struct disassemble_info
*info
,
81 xtensa_isa isa
= xtensa_default_isa
;
82 int signed_operand_val
;
86 if (operand_val
< 0xa)
87 (*info
->fprintf_func
) (info
->stream
, "%u", operand_val
);
89 (*info
->fprintf_func
) (info
->stream
, "0x%x", operand_val
);
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
);
107 if ((signed_operand_val
> -256) && (signed_operand_val
< 256))
108 (*info
->fprintf_func
) (info
->stream
, "%d", signed_operand_val
);
110 (*info
->fprintf_func
) (info
->stream
, "0x%x", signed_operand_val
);
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
),
120 while (i
< xtensa_operand_num_regs (isa
, opc
, opnd
))
123 (*info
->fprintf_func
) (info
->stream
, ":%s%u",
124 xtensa_regfile_shortname (isa
, opnd_rf
),
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
;
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);
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
165 info
->bytes_per_line
= MAX (maxsize
, 4);
167 /* Allocate buffers the first time through. */
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)
182 /* Don't set "isa" before the setjmp to keep the compiler from griping. */
183 isa
= xtensa_default_isa
;
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
))
201 /* Make sure all the opcodes are valid. */
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
)
218 (*info
->fprintf_func
) (info
->stream
, ".byte %#02x", priv
.byte_buf
[0]);
223 (*info
->fprintf_func
) (info
->stream
, "{ ");
226 for (n
= 0; n
< nslots
; n
++)
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
);
241 for (i
= 0; i
< noperands
; i
++)
243 if (xtensa_operand_is_visible (isa
, opc
, i
) == 0)
247 (*info
->fprintf_func
) (info
->stream
, "\t");
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
);
260 (*info
->fprintf_func
) (info
->stream
, " }");
262 info
->bytes_per_chunk
= size
;
263 info
->display_endian
= info
->endian
;