1 /* xtensa-dis.c. Disassembly functions for Xtensa.
2 Copyright 2003 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"
34 #define MAX(a,b) (a > b ? a : b)
37 static char* state_names[256] =
55 "reserved_13", /* 13 */
56 "reserved_14", /* 14 */
57 "reserved_15", /* 15 */
62 "reserved_18", /* 18 */
63 "reserved_19", /* 19 */
64 "reserved_20", /* 20 */
65 "reserved_21", /* 21 */
66 "reserved_22", /* 22 */
67 "reserved_23", /* 23 */
68 "reserved_24", /* 24 */
69 "reserved_25", /* 25 */
70 "reserved_26", /* 26 */
71 "reserved_27", /* 27 */
72 "reserved_28", /* 28 */
73 "reserved_29", /* 29 */
74 "reserved_30", /* 30 */
75 "reserved_31", /* 31 */
82 "reserved_36", /* 36 */
83 "reserved_37", /* 37 */
84 "reserved_38", /* 38 */
85 "reserved_39", /* 39 */
86 "reserved_40", /* 40 */
87 "reserved_41", /* 41 */
88 "reserved_42", /* 42 */
89 "reserved_43", /* 43 */
90 "reserved_44", /* 44 */
91 "reserved_45", /* 45 */
92 "reserved_46", /* 46 */
93 "reserved_47", /* 47 */
94 "reserved_48", /* 48 */
95 "reserved_49", /* 49 */
96 "reserved_50", /* 50 */
97 "reserved_51", /* 51 */
98 "reserved_52", /* 52 */
99 "reserved_53", /* 53 */
100 "reserved_54", /* 54 */
101 "reserved_55", /* 55 */
102 "reserved_56", /* 56 */
103 "reserved_57", /* 57 */
104 "reserved_58", /* 58 */
105 "reserved_59", /* 59 */
106 "reserved_60", /* 60 */
107 "reserved_61", /* 61 */
108 "reserved_62", /* 62 */
109 "reserved_63", /* 63 */
111 "reserved_64", /* 64 */
112 "reserved_65", /* 65 */
113 "reserved_66", /* 66 */
114 "reserved_67", /* 67 */
115 "reserved_68", /* 68 */
116 "reserved_69", /* 69 */
117 "reserved_70", /* 70 */
118 "reserved_71", /* 71 */
123 "reserved_74", /* 74 */
124 "reserved_75", /* 75 */
125 "reserved_76", /* 76 */
126 "reserved_77", /* 77 */
127 "reserved_78", /* 78 */
128 "reserved_79", /* 79 */
129 "reserved_80", /* 80 */
130 "reserved_81", /* 81 */
131 "reserved_82", /* 82 */
135 "reserved_84", /* 84 */
136 "reserved_85", /* 85 */
137 "reserved_86", /* 86 */
138 "reserved_87", /* 87 */
139 "reserved_88", /* 88 */
140 "reserved_89", /* 89 */
146 "reserved_93", /* 93 */
147 "reserved_94", /* 94 */
148 "reserved_95", /* 95 */
150 "ibreakenable", /* 96 */
152 "reserved_97", /* 97 */
154 "cacheattr", /* 98 */
156 "reserved_99", /* 99 */
157 "reserved_100", /* 100 */
158 "reserved_101", /* 101 */
159 "reserved_102", /* 102 */
160 "reserved_103", /* 103 */
164 "reserved_105", /* 105 */
165 "reserved_106", /* 106 */
166 "reserved_107", /* 107 */
167 "reserved_108", /* 108 */
168 "reserved_109", /* 109 */
169 "reserved_110", /* 110 */
170 "reserved_111", /* 111 */
171 "reserved_112", /* 112 */
172 "reserved_113", /* 113 */
173 "reserved_114", /* 114 */
174 "reserved_115", /* 115 */
175 "reserved_116", /* 116 */
176 "reserved_117", /* 117 */
177 "reserved_118", /* 118 */
178 "reserved_119", /* 119 */
179 "reserved_120", /* 120 */
180 "reserved_121", /* 121 */
181 "reserved_122", /* 122 */
182 "reserved_123", /* 123 */
183 "reserved_124", /* 124 */
184 "reserved_125", /* 125 */
185 "reserved_126", /* 126 */
186 "reserved_127", /* 127 */
188 "ibreaka0", /* 128 */
189 "ibreaka1", /* 129 */
190 "ibreaka2", /* 130 */
191 "ibreaka3", /* 131 */
192 "ibreaka4", /* 132 */
193 "ibreaka5", /* 133 */
194 "ibreaka6", /* 134 */
195 "ibreaka7", /* 135 */
196 "ibreaka8", /* 136 */
197 "ibreaka9", /* 137 */
198 "ibreaka10", /* 138 */
199 "ibreaka11", /* 139 */
200 "ibreaka12", /* 140 */
201 "ibreaka13", /* 141 */
202 "ibreaka14", /* 142 */
203 "ibreaka15", /* 143 */
205 "dbreaka0", /* 144 */
206 "dbreaka1", /* 145 */
207 "dbreaka2", /* 146 */
208 "dbreaka3", /* 147 */
209 "dbreaka4", /* 148 */
210 "dbreaka5", /* 149 */
211 "dbreaka6", /* 150 */
212 "dbreaka7", /* 151 */
213 "dbreaka8", /* 152 */
214 "dbreaka9", /* 153 */
215 "dbreaka10", /* 154 */
216 "dbreaka11", /* 155 */
217 "dbreaka12", /* 156 */
218 "dbreaka13", /* 157 */
219 "dbreaka14", /* 158 */
220 "dbreaka15", /* 159 */
222 "dbreakc0", /* 160 */
223 "dbreakc1", /* 161 */
224 "dbreakc2", /* 162 */
225 "dbreakc3", /* 163 */
226 "dbreakc4", /* 164 */
227 "dbreakc5", /* 165 */
228 "dbreakc6", /* 166 */
229 "dbreakc7", /* 167 */
230 "dbreakc8", /* 168 */
231 "dbreakc9", /* 169 */
232 "dbreakc10", /* 170 */
233 "dbreakc11", /* 171 */
234 "dbreakc12", /* 172 */
235 "dbreakc13", /* 173 */
236 "dbreakc14", /* 174 */
237 "dbreakc15", /* 175 */
239 "reserved_176", /* 176 */
258 "reserved_193", /* 193 */
275 "reserved_208", /* 208 */
277 "excsave1", /* 209 */
278 "excsave2", /* 210 */
279 "excsave3", /* 211 */
280 "excsave4", /* 212 */
281 "excsave5", /* 213 */
282 "excsave6", /* 214 */
283 "excsave7", /* 215 */
284 "excsave8", /* 216 */
285 "excsave9", /* 217 */
286 "excsave10", /* 218 */
287 "excsave11", /* 219 */
288 "excsave12", /* 220 */
289 "excsave13", /* 221 */
290 "excsave14", /* 222 */
291 "excsave15", /* 223 */
292 "cpenable", /* 224 */
294 "reserved_225", /* 225 */
296 "interrupt", /* 226 */
297 "interrupt2", /* 227 */
298 "intenable", /* 228 */
300 "reserved_229", /* 229 */
304 "reserved_231", /* 231 */
306 "exccause", /* 232 */
307 "debugcause", /* 233 */
311 "icountlvl", /* 237 */
312 "excvaddr", /* 238 */
314 "reserved_239", /* 239 */
316 "ccompare0", /* 240 */
317 "ccompare1", /* 241 */
318 "ccompare2", /* 242 */
319 "ccompare3", /* 243 */
326 "reserved_248", /* 248 */
327 "reserved_249", /* 249 */
328 "reserved_250", /* 250 */
329 "reserved_251", /* 251 */
330 "reserved_252", /* 252 */
331 "reserved_253", /* 253 */
332 "reserved_254", /* 254 */
333 "reserved_255", /* 255 */
339 static int fetch_data
340 PARAMS ((struct disassemble_info *info, bfd_vma memaddr));
341 static void print_xtensa_operand
342 PARAMS ((bfd_vma, struct disassemble_info *, xtensa_operand,
343 unsigned operand_val, int print_sr_name));
351 fetch_data (info, memaddr)
352 struct disassemble_info *info;
355 int length, status = 0;
356 struct dis_private *priv = (struct dis_private *) info->private_data;
357 int insn_size = xtensa_insn_maxlength (xtensa_default_isa);
359 /* Read the maximum instruction size, padding with zeros if we go past
360 the end of the text section. This code will automatically adjust
361 length when we hit the end of the buffer. */
363 memset (priv->byte_buf, 0, insn_size);
364 for (length = insn_size; length > 0; length--)
366 status = (*info->read_memory_func) (memaddr, priv->byte_buf, length,
371 (*info->memory_error_func) (status, memaddr, info);
372 longjmp (priv->bailout, 1);
378 print_xtensa_operand (memaddr, info, opnd, operand_val, print_sr_name)
380 struct disassemble_info *info;
382 unsigned operand_val;
385 char *kind = xtensa_operand_kind (opnd);
386 int signed_operand_val;
390 if (operand_val < 0xa)
391 (*info->fprintf_func) (info->stream, "%u", operand_val);
393 (*info->fprintf_func) (info->stream, "0x%x", operand_val);
397 operand_val = xtensa_operand_decode (opnd, operand_val);
398 signed_operand_val = (int) operand_val;
400 if (xtensa_operand_isPCRelative (opnd))
402 operand_val = xtensa_operand_undo_reloc (opnd, operand_val, memaddr);
403 info->target = operand_val;
404 (*info->print_address_func) (info->target, info);
406 else if (!strcmp (kind, "i"))
409 && signed_operand_val >= 0
410 && signed_operand_val <= 255)
411 (*info->fprintf_func) (info->stream, "%s",
412 state_names[signed_operand_val]);
413 else if ((signed_operand_val > -256) && (signed_operand_val < 256))
414 (*info->fprintf_func) (info->stream, "%d", signed_operand_val);
416 (*info->fprintf_func) (info->stream, "0x%x",signed_operand_val);
419 (*info->fprintf_func) (info->stream, "%s%u", kind, operand_val);
423 /* Print the Xtensa instruction at address MEMADDR on info->stream.
424 Returns length of the instruction in bytes. */
427 print_insn_xtensa (memaddr, info)
429 struct disassemble_info *info;
431 unsigned operand_val;
432 int bytes_fetched, size, maxsize, i, noperands;
437 struct dis_private priv;
438 static bfd_byte *byte_buf = NULL;
439 static xtensa_insnbuf insn_buffer = NULL;
441 if (!xtensa_default_isa)
442 (void) xtensa_isa_init ();
445 maxsize = xtensa_insn_maxlength (xtensa_default_isa);
447 /* Set bytes_per_line to control the amount of whitespace between the hex
448 values and the opcode. For Xtensa, we always print one "chunk" and we
449 vary bytes_per_chunk to determine how many bytes to print. (objdump
450 would apparently prefer that we set bytes_per_chunk to 1 and vary
451 bytes_per_line but that makes it hard to fit 64-bit instructions on
452 an 80-column screen.) The value of bytes_per_line here is not exactly
453 right, because objdump adds an extra space for each chunk so that the
454 amount of whitespace depends on the chunk size. Oh well, it's good
455 enough.... Note that we set the minimum size to 4 to accomodate
457 info->bytes_per_line = MAX (maxsize, 4);
459 /* Allocate buffers the first time through. */
461 insn_buffer = xtensa_insnbuf_alloc (xtensa_default_isa);
463 byte_buf = (bfd_byte *) malloc (MAX (maxsize, 4));
465 priv.byte_buf = byte_buf;
467 info->private_data = (PTR) &priv;
468 if (setjmp (priv.bailout) != 0)
472 /* Don't set "isa" before the setjmp to keep the compiler from griping. */
473 isa = xtensa_default_isa;
475 /* Fetch the maximum size instruction. */
476 bytes_fetched = fetch_data (info, memaddr);
478 /* Copy the bytes into the decode buffer. */
479 memset (insn_buffer, 0, (xtensa_insnbuf_size (isa) *
480 sizeof (xtensa_insnbuf_word)));
481 xtensa_insnbuf_from_chars (isa, insn_buffer, priv.byte_buf);
483 opc = xtensa_decode_insn (isa, insn_buffer);
484 if (opc == XTENSA_UNDEFINED
485 || ((size = xtensa_insn_length (isa, opc)) > bytes_fetched))
487 (*info->fprintf_func) (info->stream, ".byte %#02x", priv.byte_buf[0]);
491 op_name = (char *) xtensa_opcode_name (isa, opc);
492 (*info->fprintf_func) (info->stream, "%s", op_name);
494 print_sr_name = (!strcasecmp (op_name, "wsr")
495 || !strcasecmp (op_name, "xsr")
496 || !strcasecmp (op_name, "rsr"));
498 /* Print the operands (if any). */
499 noperands = xtensa_num_operands (isa, opc);
504 (*info->fprintf_func) (info->stream, "\t");
505 for (i = 0; i < noperands; i++)
507 xtensa_operand opnd = xtensa_get_operand (isa, opc, i);
512 (*info->fprintf_func) (info->stream, ", ");
513 operand_val = xtensa_operand_get_field (opnd, insn_buffer);
514 print_xtensa_operand (memaddr, info, opnd, operand_val,
519 info->bytes_per_chunk = size;
520 info->display_endian = info->endian;