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