Fixup gdb.python/py-value.exp for bare-metal aarch64-elf
[deliverable/binutils-gdb.git] / opcodes / xtensa-dis.c
CommitLineData
e0001a05 1/* xtensa-dis.c. Disassembly functions for Xtensa.
6f2750fe 2 Copyright (C) 2003-2016 Free Software Foundation, Inc.
e0001a05
NC
3 Contributed by Bob Wilson at Tensilica, Inc. (bwilson@tensilica.com)
4
9b201bb5 5 This file is part of the GNU opcodes library.
e0001a05 6
9b201bb5
NC
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.
e0001a05 11
9b201bb5
NC
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.
e0001a05 16
9b201bb5
NC
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. */
e0001a05 21
df7b86aa 22#include "sysdep.h"
e0001a05
NC
23#include <stdlib.h>
24#include <stdio.h>
25#include <sys/types.h>
26#include <string.h>
27#include "xtensa-isa.h"
28#include "ansidecl.h"
43cd72b9 29#include "libiberty.h"
e0001a05
NC
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 44 bfd_byte *byte_buf;
8df14d78 45 OPCODES_SIGJMP_BUF bailout;
e0001a05
NC
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);
8df14d78 69 OPCODES_SIGLONGJMP (priv->bailout, 1);
e0001a05
NC
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 82 int signed_operand_val;
43e65147 83
e0001a05
NC
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++;
43e65147 127 }
43cd72b9 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;
8df14d78 178 if (OPCODES_SIGSETJMP (priv.bailout) != 0)
e0001a05
NC
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.664748 seconds and 4 git commands to generate.