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 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 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 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