Add Xtensa port
[platform/upstream/binutils.git] / opcodes / xtensa-dis.c
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)
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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
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 "sysdep.h"
29 #include "dis-asm.h"
30
31 #include <setjmp.h>
32
33 #ifndef MAX
34 #define MAX(a,b) (a > b ? a : b)
35 #endif
36
37 static char* state_names[256] =
38 {
39   "lbeg",                       /* 0 */
40   "lend",                       /* 1 */
41   "lcount",                     /* 2 */
42   "sar",                        /* 3 */
43   "br",                         /* 4 */
44
45   "reserved_5",                 /* 5 */
46   "reserved_6",                 /* 6 */
47   "reserved_7",                 /* 7 */
48
49   "av",                         /* 8 */
50   "avh",                        /* 9 */
51   "bv",                         /* 10 */
52   "sav",                        /* 11 */
53   "scompare1",                  /* 12 */
54
55   "reserved_13",                /* 13 */
56   "reserved_14",                /* 14 */
57   "reserved_15",                /* 15 */
58
59   "acclo",                      /* 16 */
60   "acchi",                      /* 17 */
61
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 */
76
77   "mr0",                        /* 32 */
78   "mr1",                        /* 33 */
79   "mr2",                        /* 34 */
80   "mr3",                        /* 35 */
81
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 */
110
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 */
119
120   "wb",                         /* 72 */
121   "ws",                         /* 73 */
122
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 */
132
133   "ptevaddr",                   /* 83 */
134
135   "reserved_84",                /* 84 */
136   "reserved_85",                /* 85 */
137   "reserved_86",                /* 86 */
138   "reserved_87",                /* 87 */
139   "reserved_88",                /* 88 */
140   "reserved_89",                /* 89 */
141
142   "rasid",                      /* 90 */
143   "itlbcfg",                    /* 91 */
144   "dtlbcfg",                    /* 92 */
145
146   "reserved_93",                /* 93 */
147   "reserved_94",                /* 94 */
148   "reserved_95",                /* 95 */
149
150   "ibreakenable",               /* 96 */
151
152   "reserved_97",                /* 97 */
153
154   "cacheattr",                  /* 98 */
155
156   "reserved_99",                /* 99 */
157   "reserved_100",               /* 100 */
158   "reserved_101",               /* 101 */
159   "reserved_102",               /* 102 */
160   "reserved_103",               /* 103 */
161
162   "ddr",                        /* 104 */
163
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 */
187
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 */
204                            
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 */
221                            
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 */
238
239   "reserved_176",               /* 176 */
240
241   "epc1",                       /* 177 */
242   "epc2",                       /* 178 */
243   "epc3",                       /* 179 */
244   "epc4",                       /* 180 */
245   "epc5",                       /* 181 */
246   "epc6",                       /* 182 */
247   "epc7",                       /* 183 */
248   "epc8",                       /* 184 */
249   "epc9",                       /* 185 */
250   "epc10",                      /* 186 */
251   "epc11",                      /* 187 */
252   "epc12",                      /* 188 */
253   "epc13",                      /* 189 */
254   "epc14",                      /* 190 */
255   "epc15",                      /* 191 */
256   "depc",                       /* 192 */
257
258   "reserved_193",               /* 193 */
259
260   "eps2",                       /* 194 */
261   "eps3",                       /* 195 */
262   "eps4",                       /* 196 */
263   "eps5",                       /* 197 */
264   "eps6",                       /* 198 */
265   "eps7",                       /* 199 */
266   "eps8",                       /* 200 */
267   "eps9",                       /* 201 */
268   "eps10",                      /* 202 */
269   "eps11",                      /* 203 */
270   "eps12",                      /* 204 */
271   "eps13",                      /* 205 */
272   "eps14",                      /* 206 */
273   "eps15",                      /* 207 */
274
275   "reserved_208",               /* 208 */
276
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 */
293
294   "reserved_225",               /* 225 */
295
296   "interrupt",                  /* 226 */
297   "interrupt2",                 /* 227 */
298   "intenable",                  /* 228 */
299
300   "reserved_229",               /* 229 */
301
302   "ps",                         /* 230 */
303
304   "reserved_231",               /* 231 */
305
306   "exccause",                   /* 232 */
307   "debugcause",                 /* 233 */
308   "ccount",                     /* 234 */
309   "prid",                       /* 235 */
310   "icount",                     /* 236 */
311   "icountlvl",                  /* 237 */
312   "excvaddr",                   /* 238 */
313
314   "reserved_239",               /* 239 */
315
316   "ccompare0",                  /* 240 */
317   "ccompare1",                  /* 241 */
318   "ccompare2",                  /* 242 */
319   "ccompare3",                  /* 243 */
320
321   "misc0",                      /* 244 */
322   "misc1",                      /* 245 */
323   "misc2",                      /* 246 */
324   "misc3",                      /* 247 */
325
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 */
334 };
335
336
337 int show_raw_fields;
338
339 static int fetch_data
340   PARAMS ((struct disassemble_info *info, bfd_vma memaddr, int numBytes));
341 static void print_xtensa_operand
342   PARAMS ((bfd_vma, struct disassemble_info *, xtensa_operand,
343            unsigned operand_val, int print_sr_name));
344
345 struct dis_private {
346   bfd_byte *byte_buf;
347   jmp_buf bailout;
348 };
349
350 static int
351 fetch_data (info, memaddr, numBytes)
352      struct disassemble_info *info;
353      bfd_vma memaddr;
354      int numBytes;
355 {
356   int length, status = 0;
357   struct dis_private *priv = (struct dis_private *) info->private_data;
358   int insn_size = (numBytes != 0 ? numBytes :
359                    xtensa_insn_maxlength (xtensa_default_isa));
360
361   /* Read the maximum instruction size, padding with zeros if we go past
362      the end of the text section.  This code will automatically adjust
363      length when we hit the end of the buffer.  */
364
365   memset (priv->byte_buf, 0, insn_size);
366   for (length = insn_size; length > 0; length--)
367     {
368       status = (*info->read_memory_func) (memaddr, priv->byte_buf, length,
369                                           info);
370       if (status == 0)
371         return length;
372     }
373   (*info->memory_error_func) (status, memaddr, info);
374   longjmp (priv->bailout, 1);
375   /*NOTREACHED*/
376 }
377
378
379 static void
380 print_xtensa_operand (memaddr, info, opnd, operand_val, print_sr_name)
381      bfd_vma memaddr;
382      struct disassemble_info *info;
383      xtensa_operand opnd;
384      unsigned operand_val;
385      int print_sr_name;
386 {
387   char *kind = xtensa_operand_kind (opnd);
388   int signed_operand_val;
389     
390   if (show_raw_fields)
391     {
392       if (operand_val < 0xa)
393         (*info->fprintf_func) (info->stream, "%u", operand_val);
394       else
395         (*info->fprintf_func) (info->stream, "0x%x", operand_val);
396       return;
397     }
398
399   operand_val = xtensa_operand_decode (opnd, operand_val);
400   signed_operand_val = (int) operand_val;
401
402   if (xtensa_operand_isPCRelative (opnd))
403     {
404       operand_val = xtensa_operand_undo_reloc (opnd, operand_val, memaddr);
405       info->target = operand_val;
406       (*info->print_address_func) (info->target, info);
407     }
408   else if (!strcmp (kind, "i"))
409     {
410       if (print_sr_name
411           && signed_operand_val >= 0
412           && signed_operand_val <= 255)
413         (*info->fprintf_func) (info->stream, "%s",
414                                state_names[signed_operand_val]);
415       else if ((signed_operand_val > -256) && (signed_operand_val < 256))
416         (*info->fprintf_func) (info->stream, "%d", signed_operand_val);
417       else
418         (*info->fprintf_func) (info->stream, "0x%x",signed_operand_val);
419     }
420   else
421     (*info->fprintf_func) (info->stream, "%s%u", kind, operand_val);
422 }
423
424
425 /* Print the Xtensa instruction at address MEMADDR on info->stream.
426    Returns length of the instruction in bytes.  */
427
428 int
429 print_insn_xtensa (memaddr, info)
430      bfd_vma memaddr;
431      struct disassemble_info *info;
432 {
433   unsigned operand_val;
434   int bytes_fetched, size, maxsize, i, noperands;
435   xtensa_isa isa;
436   xtensa_opcode opc;
437   char *op_name;
438   int print_sr_name;
439   struct dis_private priv;
440   static bfd_byte *byte_buf = NULL;
441   static xtensa_insnbuf insn_buffer = NULL;
442
443   if (!xtensa_default_isa)
444     (void) xtensa_isa_init ();
445
446   info->target = 0;
447   maxsize = xtensa_insn_maxlength (xtensa_default_isa);
448
449   /* Set bytes_per_line to control the amount of whitespace between the hex
450      values and the opcode.  For Xtensa, we always print one "chunk" and we
451      vary bytes_per_chunk to determine how many bytes to print.  (objdump
452      would apparently prefer that we set bytes_per_chunk to 1 and vary
453      bytes_per_line but that makes it hard to fit 64-bit instructions on
454      an 80-column screen.)  The value of bytes_per_line here is not exactly
455      right, because objdump adds an extra space for each chunk so that the
456      amount of whitespace depends on the chunk size.  Oh well, it's good
457      enough....  Note that we set the minimum size to 4 to accomodate
458      literal pools.  */
459   info->bytes_per_line = MAX (maxsize, 4);
460
461   /* Allocate buffers the first time through.  */
462   if (!insn_buffer)
463     insn_buffer = xtensa_insnbuf_alloc (xtensa_default_isa);
464   if (!byte_buf)
465     byte_buf = (bfd_byte *) malloc (MAX (maxsize, 4));
466
467   priv.byte_buf = byte_buf;
468
469   info->private_data = (PTR) &priv;
470   if (setjmp (priv.bailout) != 0)
471       /* Error return.  */
472       return -1;
473
474   /* Don't set "isa" before the setjmp to keep the compiler from griping.  */
475   isa = xtensa_default_isa;
476
477   /* Fetch the maximum size instruction.  */
478   bytes_fetched = fetch_data (info, memaddr, 0);
479
480   /* Copy the bytes into the decode buffer.  */
481   memset (insn_buffer, 0, (xtensa_insnbuf_size (isa) *
482                            sizeof (xtensa_insnbuf_word)));
483   xtensa_insnbuf_from_chars (isa, insn_buffer, priv.byte_buf);
484
485   opc = xtensa_decode_insn (isa, insn_buffer);
486   if (opc == XTENSA_UNDEFINED
487       || ((size = xtensa_insn_length (isa, opc)) > bytes_fetched))
488     {
489       (*info->fprintf_func) (info->stream, ".byte %#02x", priv.byte_buf[0]);
490       return 1;
491     }
492
493   op_name = (char *) xtensa_opcode_name (isa, opc);
494   (*info->fprintf_func) (info->stream, "%s", op_name);
495
496   print_sr_name = (!strcasecmp (op_name, "wsr")
497                    || !strcasecmp (op_name, "xsr")
498                    || !strcasecmp (op_name, "rsr"));
499
500   /* Print the operands (if any).  */
501   noperands = xtensa_num_operands (isa, opc);
502   if (noperands > 0)
503     {
504       int first = 1;
505
506       (*info->fprintf_func) (info->stream, "\t");
507       for (i = 0; i < noperands; i++)
508         {
509           xtensa_operand opnd = xtensa_get_operand (isa, opc, i);
510
511           if (first)
512             first = 0;
513           else
514             (*info->fprintf_func) (info->stream, ", ");
515           operand_val = xtensa_operand_get_field (opnd, insn_buffer);
516           print_xtensa_operand (memaddr, info, opnd, operand_val,
517                                 print_sr_name);
518         }
519     }
520
521   info->bytes_per_chunk = size;
522   info->display_endian = info->endian;
523
524   return size;
525 }
526