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));
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
fetch_data(info,memaddr)351 fetch_data (info, memaddr)
352      struct disassemble_info *info;
353      bfd_vma memaddr;
354 {
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);
358 
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.  */
362 
363   memset (priv->byte_buf, 0, insn_size);
364   for (length = insn_size; length > 0; length--)
365     {
366       status = (*info->read_memory_func) (memaddr, priv->byte_buf, length,
367 					  info);
368       if (status == 0)
369 	return length;
370     }
371   (*info->memory_error_func) (status, memaddr, info);
372   longjmp (priv->bailout, 1);
373   /*NOTREACHED*/
374 }
375 
376 
377 static void
print_xtensa_operand(memaddr,info,opnd,operand_val,print_sr_name)378 print_xtensa_operand (memaddr, info, opnd, operand_val, print_sr_name)
379      bfd_vma memaddr;
380      struct disassemble_info *info;
381      xtensa_operand opnd;
382      unsigned operand_val;
383      int print_sr_name;
384 {
385   char *kind = xtensa_operand_kind (opnd);
386   int signed_operand_val;
387 
388   if (show_raw_fields)
389     {
390       if (operand_val < 0xa)
391 	(*info->fprintf_func) (info->stream, "%u", operand_val);
392       else
393 	(*info->fprintf_func) (info->stream, "0x%x", operand_val);
394       return;
395     }
396 
397   operand_val = xtensa_operand_decode (opnd, operand_val);
398   signed_operand_val = (int) operand_val;
399 
400   if (xtensa_operand_isPCRelative (opnd))
401     {
402       operand_val = xtensa_operand_undo_reloc (opnd, operand_val, memaddr);
403       info->target = operand_val;
404       (*info->print_address_func) (info->target, info);
405     }
406   else if (!strcmp (kind, "i"))
407     {
408       if (print_sr_name
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);
415       else
416 	(*info->fprintf_func) (info->stream, "0x%x",signed_operand_val);
417     }
418   else
419     (*info->fprintf_func) (info->stream, "%s%u", kind, operand_val);
420 }
421 
422 
423 /* Print the Xtensa instruction at address MEMADDR on info->stream.
424    Returns length of the instruction in bytes.  */
425 
426 int
print_insn_xtensa(memaddr,info)427 print_insn_xtensa (memaddr, info)
428      bfd_vma memaddr;
429      struct disassemble_info *info;
430 {
431   unsigned operand_val;
432   int bytes_fetched, size, maxsize, i, noperands;
433   xtensa_isa isa;
434   xtensa_opcode opc;
435   char *op_name;
436   int print_sr_name;
437   struct dis_private priv;
438   static bfd_byte *byte_buf = NULL;
439   static xtensa_insnbuf insn_buffer = NULL;
440 
441   if (!xtensa_default_isa)
442     (void) xtensa_isa_init ();
443 
444   info->target = 0;
445   maxsize = xtensa_insn_maxlength (xtensa_default_isa);
446 
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
456      literal pools.  */
457   info->bytes_per_line = MAX (maxsize, 4);
458 
459   /* Allocate buffers the first time through.  */
460   if (!insn_buffer)
461     insn_buffer = xtensa_insnbuf_alloc (xtensa_default_isa);
462   if (!byte_buf)
463     byte_buf = (bfd_byte *) malloc (MAX (maxsize, 4));
464 
465   priv.byte_buf = byte_buf;
466 
467   info->private_data = (PTR) &priv;
468   if (setjmp (priv.bailout) != 0)
469       /* Error return.  */
470       return -1;
471 
472   /* Don't set "isa" before the setjmp to keep the compiler from griping.  */
473   isa = xtensa_default_isa;
474 
475   /* Fetch the maximum size instruction.  */
476   bytes_fetched = fetch_data (info, memaddr);
477 
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);
482 
483   opc = xtensa_decode_insn (isa, insn_buffer);
484   if (opc == XTENSA_UNDEFINED
485       || ((size = xtensa_insn_length (isa, opc)) > bytes_fetched))
486     {
487       (*info->fprintf_func) (info->stream, ".byte %#02x", priv.byte_buf[0]);
488       return 1;
489     }
490 
491   op_name = (char *) xtensa_opcode_name (isa, opc);
492   (*info->fprintf_func) (info->stream, "%s", op_name);
493 
494   print_sr_name = (!strcasecmp (op_name, "wsr")
495 		   || !strcasecmp (op_name, "xsr")
496 		   || !strcasecmp (op_name, "rsr"));
497 
498   /* Print the operands (if any).  */
499   noperands = xtensa_num_operands (isa, opc);
500   if (noperands > 0)
501     {
502       int first = 1;
503 
504       (*info->fprintf_func) (info->stream, "\t");
505       for (i = 0; i < noperands; i++)
506 	{
507 	  xtensa_operand opnd = xtensa_get_operand (isa, opc, i);
508 
509 	  if (first)
510 	    first = 0;
511 	  else
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,
515 				print_sr_name);
516         }
517     }
518 
519   info->bytes_per_chunk = size;
520   info->display_endian = info->endian;
521 
522   return size;
523 }
524 
525