1 /* Print mips instructions for GDB, the GNU debugger, or for objdump. 2 Copyright (C) 1989-2016 Free Software Foundation, Inc. 3 Contributed by Nobuyuki Hikichi(hikichi (at) sra.co.jp). 4 5 This file is part of the GNU opcodes library. 6 7 This library is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 It is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 MA 02110-1301, USA. */ 21 22 #include "sysdep.h" 23 #include "dis-asm.h" 24 #include "libiberty.h" 25 #include "opcode/mips.h" 26 #include "opintl.h" 27 28 /* FIXME: These are needed to figure out if the code is mips16 or 29 not. The low bit of the address is often a good indicator. No 30 symbol table is available when this code runs out in an embedded 31 system as when it is used for disassembler support in a monitor. */ 32 33 #if !defined(EMBEDDED_ENV) 34 #define SYMTAB_AVAILABLE 1 35 #include "elf-bfd.h" 36 #include "elf/mips.h" 37 #endif 38 39 /* Mips instructions are at maximum this many bytes long. */ 40 #define INSNLEN 4 41 42 43 /* FIXME: These should be shared with gdb somehow. */ 45 46 struct mips_cp0sel_name 47 { 48 unsigned int cp0reg; 49 unsigned int sel; 50 const char * const name; 51 }; 52 53 static const char * const mips_gpr_names_numeric[32] = 54 { 55 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", 56 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", 57 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 58 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" 59 }; 60 61 static const char * const mips_gpr_names_oldabi[32] = 62 { 63 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 64 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 65 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 66 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" 67 }; 68 69 static const char * const mips_gpr_names_newabi[32] = 70 { 71 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 72 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", 73 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 74 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" 75 }; 76 77 static const char * const mips_fpr_names_numeric[32] = 78 { 79 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", 80 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", 81 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", 82 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31" 83 }; 84 85 static const char * const mips_fpr_names_32[32] = 86 { 87 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f", 88 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f", 89 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f", 90 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f" 91 }; 92 93 static const char * const mips_fpr_names_n32[32] = 94 { 95 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3", 96 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3", 97 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9", 98 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13" 99 }; 100 101 static const char * const mips_fpr_names_64[32] = 102 { 103 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3", 104 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3", 105 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11", 106 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7" 107 }; 108 109 static const char * const mips_cp0_names_numeric[32] = 110 { 111 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", 112 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", 113 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 114 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" 115 }; 116 117 static const char * const mips_cp1_names_numeric[32] = 118 { 119 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", 120 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", 121 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 122 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" 123 }; 124 125 static const char * const mips_cp0_names_r3000[32] = 126 { 127 "c0_index", "c0_random", "c0_entrylo", "$3", 128 "c0_context", "$5", "$6", "$7", 129 "c0_badvaddr", "$9", "c0_entryhi", "$11", 130 "c0_sr", "c0_cause", "c0_epc", "c0_prid", 131 "$16", "$17", "$18", "$19", 132 "$20", "$21", "$22", "$23", 133 "$24", "$25", "$26", "$27", 134 "$28", "$29", "$30", "$31", 135 }; 136 137 static const char * const mips_cp0_names_r4000[32] = 138 { 139 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", 140 "c0_context", "c0_pagemask", "c0_wired", "$7", 141 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare", 142 "c0_sr", "c0_cause", "c0_epc", "c0_prid", 143 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi", 144 "c0_xcontext", "$21", "$22", "$23", 145 "$24", "$25", "c0_ecc", "c0_cacheerr", 146 "c0_taglo", "c0_taghi", "c0_errorepc", "$31", 147 }; 148 149 static const char * const mips_cp0_names_r5900[32] = 150 { 151 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", 152 "c0_context", "c0_pagemask", "c0_wired", "$7", 153 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare", 154 "c0_sr", "c0_cause", "c0_epc", "c0_prid", 155 "c0_config", "$17", "$18", "$19", 156 "$20", "$21", "$22", "c0_badpaddr", 157 "c0_depc", "c0_perfcnt", "$26", "$27", 158 "c0_taglo", "c0_taghi", "c0_errorepc", "$31" 159 }; 160 161 static const char * const mips_cp0_names_mips3264[32] = 162 { 163 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", 164 "c0_context", "c0_pagemask", "c0_wired", "$7", 165 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare", 166 "c0_status", "c0_cause", "c0_epc", "c0_prid", 167 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi", 168 "c0_xcontext", "$21", "$22", "c0_debug", 169 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr", 170 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave", 171 }; 172 173 static const char * const mips_cp1_names_mips3264[32] = 174 { 175 "c1_fir", "c1_ufr", "$2", "$3", 176 "c1_unfr", "$5", "$6", "$7", 177 "$8", "$9", "$10", "$11", 178 "$12", "$13", "$14", "$15", 179 "$16", "$17", "$18", "$19", 180 "$20", "$21", "$22", "$23", 181 "$24", "c1_fccr", "c1_fexr", "$27", 182 "c1_fenr", "$29", "$30", "c1_fcsr" 183 }; 184 185 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] = 186 { 187 { 16, 1, "c0_config1" }, 188 { 16, 2, "c0_config2" }, 189 { 16, 3, "c0_config3" }, 190 { 18, 1, "c0_watchlo,1" }, 191 { 18, 2, "c0_watchlo,2" }, 192 { 18, 3, "c0_watchlo,3" }, 193 { 18, 4, "c0_watchlo,4" }, 194 { 18, 5, "c0_watchlo,5" }, 195 { 18, 6, "c0_watchlo,6" }, 196 { 18, 7, "c0_watchlo,7" }, 197 { 19, 1, "c0_watchhi,1" }, 198 { 19, 2, "c0_watchhi,2" }, 199 { 19, 3, "c0_watchhi,3" }, 200 { 19, 4, "c0_watchhi,4" }, 201 { 19, 5, "c0_watchhi,5" }, 202 { 19, 6, "c0_watchhi,6" }, 203 { 19, 7, "c0_watchhi,7" }, 204 { 25, 1, "c0_perfcnt,1" }, 205 { 25, 2, "c0_perfcnt,2" }, 206 { 25, 3, "c0_perfcnt,3" }, 207 { 25, 4, "c0_perfcnt,4" }, 208 { 25, 5, "c0_perfcnt,5" }, 209 { 25, 6, "c0_perfcnt,6" }, 210 { 25, 7, "c0_perfcnt,7" }, 211 { 27, 1, "c0_cacheerr,1" }, 212 { 27, 2, "c0_cacheerr,2" }, 213 { 27, 3, "c0_cacheerr,3" }, 214 { 28, 1, "c0_datalo" }, 215 { 29, 1, "c0_datahi" } 216 }; 217 218 static const char * const mips_cp0_names_mips3264r2[32] = 219 { 220 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", 221 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena", 222 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare", 223 "c0_status", "c0_cause", "c0_epc", "c0_prid", 224 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi", 225 "c0_xcontext", "$21", "$22", "c0_debug", 226 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr", 227 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave", 228 }; 229 230 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] = 231 { 232 { 4, 1, "c0_contextconfig" }, 233 { 0, 1, "c0_mvpcontrol" }, 234 { 0, 2, "c0_mvpconf0" }, 235 { 0, 3, "c0_mvpconf1" }, 236 { 1, 1, "c0_vpecontrol" }, 237 { 1, 2, "c0_vpeconf0" }, 238 { 1, 3, "c0_vpeconf1" }, 239 { 1, 4, "c0_yqmask" }, 240 { 1, 5, "c0_vpeschedule" }, 241 { 1, 6, "c0_vpeschefback" }, 242 { 2, 1, "c0_tcstatus" }, 243 { 2, 2, "c0_tcbind" }, 244 { 2, 3, "c0_tcrestart" }, 245 { 2, 4, "c0_tchalt" }, 246 { 2, 5, "c0_tccontext" }, 247 { 2, 6, "c0_tcschedule" }, 248 { 2, 7, "c0_tcschefback" }, 249 { 5, 1, "c0_pagegrain" }, 250 { 6, 1, "c0_srsconf0" }, 251 { 6, 2, "c0_srsconf1" }, 252 { 6, 3, "c0_srsconf2" }, 253 { 6, 4, "c0_srsconf3" }, 254 { 6, 5, "c0_srsconf4" }, 255 { 12, 1, "c0_intctl" }, 256 { 12, 2, "c0_srsctl" }, 257 { 12, 3, "c0_srsmap" }, 258 { 15, 1, "c0_ebase" }, 259 { 16, 1, "c0_config1" }, 260 { 16, 2, "c0_config2" }, 261 { 16, 3, "c0_config3" }, 262 { 18, 1, "c0_watchlo,1" }, 263 { 18, 2, "c0_watchlo,2" }, 264 { 18, 3, "c0_watchlo,3" }, 265 { 18, 4, "c0_watchlo,4" }, 266 { 18, 5, "c0_watchlo,5" }, 267 { 18, 6, "c0_watchlo,6" }, 268 { 18, 7, "c0_watchlo,7" }, 269 { 19, 1, "c0_watchhi,1" }, 270 { 19, 2, "c0_watchhi,2" }, 271 { 19, 3, "c0_watchhi,3" }, 272 { 19, 4, "c0_watchhi,4" }, 273 { 19, 5, "c0_watchhi,5" }, 274 { 19, 6, "c0_watchhi,6" }, 275 { 19, 7, "c0_watchhi,7" }, 276 { 23, 1, "c0_tracecontrol" }, 277 { 23, 2, "c0_tracecontrol2" }, 278 { 23, 3, "c0_usertracedata" }, 279 { 23, 4, "c0_tracebpc" }, 280 { 25, 1, "c0_perfcnt,1" }, 281 { 25, 2, "c0_perfcnt,2" }, 282 { 25, 3, "c0_perfcnt,3" }, 283 { 25, 4, "c0_perfcnt,4" }, 284 { 25, 5, "c0_perfcnt,5" }, 285 { 25, 6, "c0_perfcnt,6" }, 286 { 25, 7, "c0_perfcnt,7" }, 287 { 27, 1, "c0_cacheerr,1" }, 288 { 27, 2, "c0_cacheerr,2" }, 289 { 27, 3, "c0_cacheerr,3" }, 290 { 28, 1, "c0_datalo" }, 291 { 28, 2, "c0_taglo1" }, 292 { 28, 3, "c0_datalo1" }, 293 { 28, 4, "c0_taglo2" }, 294 { 28, 5, "c0_datalo2" }, 295 { 28, 6, "c0_taglo3" }, 296 { 28, 7, "c0_datalo3" }, 297 { 29, 1, "c0_datahi" }, 298 { 29, 2, "c0_taghi1" }, 299 { 29, 3, "c0_datahi1" }, 300 { 29, 4, "c0_taghi2" }, 301 { 29, 5, "c0_datahi2" }, 302 { 29, 6, "c0_taghi3" }, 303 { 29, 7, "c0_datahi3" }, 304 }; 305 306 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */ 307 static const char * const mips_cp0_names_sb1[32] = 308 { 309 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", 310 "c0_context", "c0_pagemask", "c0_wired", "$7", 311 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare", 312 "c0_status", "c0_cause", "c0_epc", "c0_prid", 313 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi", 314 "c0_xcontext", "$21", "$22", "c0_debug", 315 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i", 316 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave", 317 }; 318 319 static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] = 320 { 321 { 16, 1, "c0_config1" }, 322 { 18, 1, "c0_watchlo,1" }, 323 { 19, 1, "c0_watchhi,1" }, 324 { 22, 0, "c0_perftrace" }, 325 { 23, 3, "c0_edebug" }, 326 { 25, 1, "c0_perfcnt,1" }, 327 { 25, 2, "c0_perfcnt,2" }, 328 { 25, 3, "c0_perfcnt,3" }, 329 { 25, 4, "c0_perfcnt,4" }, 330 { 25, 5, "c0_perfcnt,5" }, 331 { 25, 6, "c0_perfcnt,6" }, 332 { 25, 7, "c0_perfcnt,7" }, 333 { 26, 1, "c0_buserr_pa" }, 334 { 27, 1, "c0_cacheerr_d" }, 335 { 27, 3, "c0_cacheerr_d_pa" }, 336 { 28, 1, "c0_datalo_i" }, 337 { 28, 2, "c0_taglo_d" }, 338 { 28, 3, "c0_datalo_d" }, 339 { 29, 1, "c0_datahi_i" }, 340 { 29, 2, "c0_taghi_d" }, 341 { 29, 3, "c0_datahi_d" }, 342 }; 343 344 /* Xlr cop0 register names. */ 345 static const char * const mips_cp0_names_xlr[32] = { 346 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", 347 "c0_context", "c0_pagemask", "c0_wired", "$7", 348 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare", 349 "c0_status", "c0_cause", "c0_epc", "c0_prid", 350 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi", 351 "c0_xcontext", "$21", "$22", "c0_debug", 352 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i", 353 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave", 354 }; 355 356 /* XLR's CP0 Select Registers. */ 357 358 static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = { 359 { 9, 6, "c0_extintreq" }, 360 { 9, 7, "c0_extintmask" }, 361 { 15, 1, "c0_ebase" }, 362 { 16, 1, "c0_config1" }, 363 { 16, 2, "c0_config2" }, 364 { 16, 3, "c0_config3" }, 365 { 16, 7, "c0_procid2" }, 366 { 18, 1, "c0_watchlo,1" }, 367 { 18, 2, "c0_watchlo,2" }, 368 { 18, 3, "c0_watchlo,3" }, 369 { 18, 4, "c0_watchlo,4" }, 370 { 18, 5, "c0_watchlo,5" }, 371 { 18, 6, "c0_watchlo,6" }, 372 { 18, 7, "c0_watchlo,7" }, 373 { 19, 1, "c0_watchhi,1" }, 374 { 19, 2, "c0_watchhi,2" }, 375 { 19, 3, "c0_watchhi,3" }, 376 { 19, 4, "c0_watchhi,4" }, 377 { 19, 5, "c0_watchhi,5" }, 378 { 19, 6, "c0_watchhi,6" }, 379 { 19, 7, "c0_watchhi,7" }, 380 { 25, 1, "c0_perfcnt,1" }, 381 { 25, 2, "c0_perfcnt,2" }, 382 { 25, 3, "c0_perfcnt,3" }, 383 { 25, 4, "c0_perfcnt,4" }, 384 { 25, 5, "c0_perfcnt,5" }, 385 { 25, 6, "c0_perfcnt,6" }, 386 { 25, 7, "c0_perfcnt,7" }, 387 { 27, 1, "c0_cacheerr,1" }, 388 { 27, 2, "c0_cacheerr,2" }, 389 { 27, 3, "c0_cacheerr,3" }, 390 { 28, 1, "c0_datalo" }, 391 { 29, 1, "c0_datahi" } 392 }; 393 394 static const char * const mips_hwr_names_numeric[32] = 395 { 396 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", 397 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", 398 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 399 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" 400 }; 401 402 static const char * const mips_hwr_names_mips3264r2[32] = 403 { 404 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres", 405 "$4", "$5", "$6", "$7", 406 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", 407 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 408 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" 409 }; 410 411 static const char * const msa_control_names[32] = 412 { 413 "msa_ir", "msa_csr", "msa_access", "msa_save", 414 "msa_modify", "msa_request", "msa_map", "msa_unmap", 415 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", 416 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 417 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" 418 }; 419 420 struct mips_abi_choice 421 { 422 const char * name; 423 const char * const *gpr_names; 424 const char * const *fpr_names; 425 }; 426 427 struct mips_abi_choice mips_abi_choices[] = 428 { 429 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric }, 430 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 }, 431 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 }, 432 { "64", mips_gpr_names_newabi, mips_fpr_names_64 }, 433 }; 434 435 struct mips_arch_choice 436 { 437 const char *name; 438 int bfd_mach_valid; 439 unsigned long bfd_mach; 440 int processor; 441 int isa; 442 int ase; 443 const char * const *cp0_names; 444 const struct mips_cp0sel_name *cp0sel_names; 445 unsigned int cp0sel_names_len; 446 const char * const *cp1_names; 447 const char * const *hwr_names; 448 }; 449 450 const struct mips_arch_choice mips_arch_choices[] = 451 { 452 { "numeric", 0, 0, 0, 0, 0, 453 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 454 mips_hwr_names_numeric }, 455 456 { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, 0, 457 mips_cp0_names_r3000, NULL, 0, mips_cp1_names_numeric, 458 mips_hwr_names_numeric }, 459 { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, 0, 460 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 461 mips_hwr_names_numeric }, 462 { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, 0, 463 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric, 464 mips_hwr_names_numeric }, 465 { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, 0, 466 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 467 mips_hwr_names_numeric }, 468 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 0, 469 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 470 mips_hwr_names_numeric }, 471 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 0, 472 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 473 mips_hwr_names_numeric }, 474 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 0, 475 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 476 mips_hwr_names_numeric }, 477 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 0, 478 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 479 mips_hwr_names_numeric }, 480 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 0, 481 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric, 482 mips_hwr_names_numeric }, 483 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 0, 484 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 485 mips_hwr_names_numeric }, 486 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 0, 487 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 488 mips_hwr_names_numeric }, 489 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 0, 490 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 491 mips_hwr_names_numeric }, 492 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 0, 493 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 494 mips_hwr_names_numeric }, 495 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 0, 496 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 497 mips_hwr_names_numeric }, 498 { "r5900", 1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, 0, 499 mips_cp0_names_r5900, NULL, 0, mips_cp1_names_numeric, 500 mips_hwr_names_numeric }, 501 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 0, 502 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 503 mips_hwr_names_numeric }, 504 { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0, 505 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 506 mips_hwr_names_numeric }, 507 { "rm9000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0, 508 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 509 mips_hwr_names_numeric }, 510 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 0, 511 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 512 mips_hwr_names_numeric }, 513 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 0, 514 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 515 mips_hwr_names_numeric }, 516 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 0, 517 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 518 mips_hwr_names_numeric }, 519 { "r14000", 1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, 0, 520 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 521 mips_hwr_names_numeric }, 522 { "r16000", 1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, 0, 523 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 524 mips_hwr_names_numeric }, 525 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 0, 526 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 527 mips_hwr_names_numeric }, 528 529 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs. 530 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See 531 _MIPS32 Architecture For Programmers Volume I: Introduction to the 532 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95), 533 page 1. */ 534 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32, 535 ISA_MIPS32, ASE_SMARTMIPS, 536 mips_cp0_names_mips3264, 537 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264), 538 mips_cp1_names_mips3264, mips_hwr_names_numeric }, 539 540 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2, 541 ISA_MIPS32R2, 542 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D 543 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA), 544 mips_cp0_names_mips3264r2, 545 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), 546 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 }, 547 548 { "mips32r3", 1, bfd_mach_mipsisa32r3, CPU_MIPS32R3, 549 ISA_MIPS32R3, 550 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D 551 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA), 552 mips_cp0_names_mips3264r2, 553 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), 554 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 }, 555 556 { "mips32r5", 1, bfd_mach_mipsisa32r5, CPU_MIPS32R5, 557 ISA_MIPS32R5, 558 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D 559 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA), 560 mips_cp0_names_mips3264r2, 561 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), 562 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 }, 563 564 { "mips32r6", 1, bfd_mach_mipsisa32r6, CPU_MIPS32R6, 565 ISA_MIPS32R6, 566 (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP 567 | ASE_DSPR2 | ASE_DSPR3), 568 mips_cp0_names_mips3264r2, 569 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), 570 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 }, 571 572 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */ 573 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64, 574 ISA_MIPS64, ASE_MIPS3D | ASE_MDMX, 575 mips_cp0_names_mips3264, 576 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264), 577 mips_cp1_names_mips3264, mips_hwr_names_numeric }, 578 579 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2, 580 ISA_MIPS64R2, 581 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT 582 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA), 583 mips_cp0_names_mips3264r2, 584 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), 585 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 }, 586 587 { "mips64r3", 1, bfd_mach_mipsisa64r3, CPU_MIPS64R3, 588 ISA_MIPS64R3, 589 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT 590 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA), 591 mips_cp0_names_mips3264r2, 592 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), 593 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 }, 594 595 { "mips64r5", 1, bfd_mach_mipsisa64r5, CPU_MIPS64R5, 596 ISA_MIPS64R5, 597 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT 598 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA), 599 mips_cp0_names_mips3264r2, 600 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), 601 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 }, 602 603 { "mips64r6", 1, bfd_mach_mipsisa64r6, CPU_MIPS64R6, 604 ISA_MIPS64R6, 605 (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64 606 | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3), 607 mips_cp0_names_mips3264r2, 608 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), 609 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 }, 610 611 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1, 612 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D, 613 mips_cp0_names_sb1, 614 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1), 615 mips_cp1_names_mips3264, mips_hwr_names_numeric }, 616 617 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E, 618 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric, 619 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric }, 620 621 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F, 622 ISA_MIPS3 | INSN_LOONGSON_2F, 0, mips_cp0_names_numeric, 623 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric }, 624 625 { "loongson3a", 1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A, 626 ISA_MIPS64R2 | INSN_LOONGSON_3A, 0, mips_cp0_names_numeric, 627 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric }, 628 629 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON, 630 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0, 631 mips_cp1_names_mips3264, mips_hwr_names_numeric }, 632 633 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP, 634 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric, 635 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric }, 636 637 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2, 638 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric, 639 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric }, 640 641 { "octeon3", 1, bfd_mach_mips_octeon3, CPU_OCTEON3, 642 ISA_MIPS64R5 | INSN_OCTEON3, ASE_VIRT | ASE_VIRT64, 643 mips_cp0_names_numeric, 644 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric }, 645 646 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR, 647 ISA_MIPS64 | INSN_XLR, 0, 648 mips_cp0_names_xlr, 649 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr), 650 mips_cp1_names_mips3264, mips_hwr_names_numeric }, 651 652 /* XLP is mostly like XLR, with the prominent exception it is being 653 MIPS64R2. */ 654 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR, 655 ISA_MIPS64R2 | INSN_XLR, 0, 656 mips_cp0_names_xlr, 657 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr), 658 mips_cp1_names_mips3264, mips_hwr_names_numeric }, 659 660 /* This entry, mips16, is here only for ISA/processor selection; do 661 not print its name. */ 662 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3, 0, 663 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric, 664 mips_hwr_names_numeric }, 665 }; 666 667 /* ISA and processor type to disassemble for, and register names to use. 668 set_default_mips_dis_options and parse_mips_dis_options fill in these 669 values. */ 670 static int mips_processor; 671 static int mips_isa; 672 static int mips_ase; 673 static int micromips_ase; 674 static const char * const *mips_gpr_names; 675 static const char * const *mips_fpr_names; 676 static const char * const *mips_cp0_names; 677 static const struct mips_cp0sel_name *mips_cp0sel_names; 678 static int mips_cp0sel_names_len; 679 static const char * const *mips_cp1_names; 680 static const char * const *mips_hwr_names; 681 682 /* Other options */ 683 static int no_aliases; /* If set disassemble as most general inst. */ 684 685 static const struct mips_abi_choice * 687 choose_abi_by_name (const char *name, unsigned int namelen) 688 { 689 const struct mips_abi_choice *c; 690 unsigned int i; 691 692 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++) 693 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0 694 && strlen (mips_abi_choices[i].name) == namelen) 695 c = &mips_abi_choices[i]; 696 697 return c; 698 } 699 700 static const struct mips_arch_choice * 701 choose_arch_by_name (const char *name, unsigned int namelen) 702 { 703 const struct mips_arch_choice *c = NULL; 704 unsigned int i; 705 706 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++) 707 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0 708 && strlen (mips_arch_choices[i].name) == namelen) 709 c = &mips_arch_choices[i]; 710 711 return c; 712 } 713 714 static const struct mips_arch_choice * 715 choose_arch_by_number (unsigned long mach) 716 { 717 static unsigned long hint_bfd_mach; 718 static const struct mips_arch_choice *hint_arch_choice; 719 const struct mips_arch_choice *c; 720 unsigned int i; 721 722 /* We optimize this because even if the user specifies no 723 flags, this will be done for every instruction! */ 724 if (hint_bfd_mach == mach 725 && hint_arch_choice != NULL 726 && hint_arch_choice->bfd_mach == hint_bfd_mach) 727 return hint_arch_choice; 728 729 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++) 730 { 731 if (mips_arch_choices[i].bfd_mach_valid 732 && mips_arch_choices[i].bfd_mach == mach) 733 { 734 c = &mips_arch_choices[i]; 735 hint_bfd_mach = mach; 736 hint_arch_choice = c; 737 } 738 } 739 return c; 740 } 741 742 /* Check if the object uses NewABI conventions. */ 743 744 static int 745 is_newabi (Elf_Internal_Ehdr *header) 746 { 747 /* There are no old-style ABIs which use 64-bit ELF. */ 748 if (header->e_ident[EI_CLASS] == ELFCLASS64) 749 return 1; 750 751 /* If a 32-bit ELF file, n32 is a new-style ABI. */ 752 if ((header->e_flags & EF_MIPS_ABI2) != 0) 753 return 1; 754 755 return 0; 756 } 757 758 /* Check if the object has microMIPS ASE code. */ 759 760 static int 761 is_micromips (Elf_Internal_Ehdr *header) 762 { 763 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0) 764 return 1; 765 766 return 0; 767 } 768 769 static void 770 set_default_mips_dis_options (struct disassemble_info *info) 771 { 772 const struct mips_arch_choice *chosen_arch; 773 774 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code 775 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR, 776 CP0 register, and HWR names. */ 777 mips_isa = ISA_MIPS3; 778 mips_processor = CPU_R3000; 779 micromips_ase = 0; 780 mips_ase = 0; 781 mips_gpr_names = mips_gpr_names_oldabi; 782 mips_fpr_names = mips_fpr_names_numeric; 783 mips_cp0_names = mips_cp0_names_numeric; 784 mips_cp0sel_names = NULL; 785 mips_cp0sel_names_len = 0; 786 mips_cp1_names = mips_cp1_names_numeric; 787 mips_hwr_names = mips_hwr_names_numeric; 788 no_aliases = 0; 789 790 /* Update settings according to the ELF file header flags. */ 791 if (info->flavour == bfd_target_elf_flavour && info->section != NULL) 792 { 793 Elf_Internal_Ehdr *header; 794 795 header = elf_elfheader (info->section->owner); 796 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */ 797 if (is_newabi (header)) 798 mips_gpr_names = mips_gpr_names_newabi; 799 /* If a microMIPS binary, then don't use MIPS16 bindings. */ 800 micromips_ase = is_micromips (header); 801 } 802 803 /* Set ISA, architecture, and cp0 register names as best we can. */ 804 #if ! SYMTAB_AVAILABLE 805 /* This is running out on a target machine, not in a host tool. 806 FIXME: Where does mips_target_info come from? */ 807 target_processor = mips_target_info.processor; 808 mips_isa = mips_target_info.isa; 809 mips_ase = mips_target_info.ase; 810 #else 811 chosen_arch = choose_arch_by_number (info->mach); 812 if (chosen_arch != NULL) 813 { 814 mips_processor = chosen_arch->processor; 815 mips_isa = chosen_arch->isa; 816 mips_ase = chosen_arch->ase; 817 mips_cp0_names = chosen_arch->cp0_names; 818 mips_cp0sel_names = chosen_arch->cp0sel_names; 819 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len; 820 mips_cp1_names = chosen_arch->cp1_names; 821 mips_hwr_names = chosen_arch->hwr_names; 822 } 823 #endif 824 } 825 826 static void 827 parse_mips_dis_option (const char *option, unsigned int len) 828 { 829 unsigned int i, optionlen, vallen; 830 const char *val; 831 const struct mips_abi_choice *chosen_abi; 832 const struct mips_arch_choice *chosen_arch; 833 834 /* Try to match options that are simple flags */ 835 if (CONST_STRNEQ (option, "no-aliases")) 836 { 837 no_aliases = 1; 838 return; 839 } 840 841 if (CONST_STRNEQ (option, "msa")) 842 { 843 mips_ase |= ASE_MSA; 844 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2 845 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3 846 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5 847 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6) 848 mips_ase |= ASE_MSA64; 849 return; 850 } 851 852 if (CONST_STRNEQ (option, "virt")) 853 { 854 mips_ase |= ASE_VIRT; 855 if (mips_isa & ISA_MIPS64R2 856 || mips_isa & ISA_MIPS64R3 857 || mips_isa & ISA_MIPS64R5 858 || mips_isa & ISA_MIPS64R6) 859 mips_ase |= ASE_VIRT64; 860 return; 861 } 862 863 if (CONST_STRNEQ (option, "xpa")) 864 { 865 mips_ase |= ASE_XPA; 866 return; 867 } 868 869 870 /* Look for the = that delimits the end of the option name. */ 871 for (i = 0; i < len; i++) 872 if (option[i] == '=') 873 break; 874 875 if (i == 0) /* Invalid option: no name before '='. */ 876 return; 877 if (i == len) /* Invalid option: no '='. */ 878 return; 879 if (i == (len - 1)) /* Invalid option: no value after '='. */ 880 return; 881 882 optionlen = i; 883 val = option + (optionlen + 1); 884 vallen = len - (optionlen + 1); 885 886 if (strncmp ("gpr-names", option, optionlen) == 0 887 && strlen ("gpr-names") == optionlen) 888 { 889 chosen_abi = choose_abi_by_name (val, vallen); 890 if (chosen_abi != NULL) 891 mips_gpr_names = chosen_abi->gpr_names; 892 return; 893 } 894 895 if (strncmp ("fpr-names", option, optionlen) == 0 896 && strlen ("fpr-names") == optionlen) 897 { 898 chosen_abi = choose_abi_by_name (val, vallen); 899 if (chosen_abi != NULL) 900 mips_fpr_names = chosen_abi->fpr_names; 901 return; 902 } 903 904 if (strncmp ("cp0-names", option, optionlen) == 0 905 && strlen ("cp0-names") == optionlen) 906 { 907 chosen_arch = choose_arch_by_name (val, vallen); 908 if (chosen_arch != NULL) 909 { 910 mips_cp0_names = chosen_arch->cp0_names; 911 mips_cp0sel_names = chosen_arch->cp0sel_names; 912 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len; 913 } 914 return; 915 } 916 917 if (strncmp ("cp1-names", option, optionlen) == 0 918 && strlen ("cp1-names") == optionlen) 919 { 920 chosen_arch = choose_arch_by_name (val, vallen); 921 if (chosen_arch != NULL) 922 mips_cp1_names = chosen_arch->cp1_names; 923 return; 924 } 925 926 if (strncmp ("hwr-names", option, optionlen) == 0 927 && strlen ("hwr-names") == optionlen) 928 { 929 chosen_arch = choose_arch_by_name (val, vallen); 930 if (chosen_arch != NULL) 931 mips_hwr_names = chosen_arch->hwr_names; 932 return; 933 } 934 935 if (strncmp ("reg-names", option, optionlen) == 0 936 && strlen ("reg-names") == optionlen) 937 { 938 /* We check both ABI and ARCH here unconditionally, so 939 that "numeric" will do the desirable thing: select 940 numeric register names for all registers. Other than 941 that, a given name probably won't match both. */ 942 chosen_abi = choose_abi_by_name (val, vallen); 943 if (chosen_abi != NULL) 944 { 945 mips_gpr_names = chosen_abi->gpr_names; 946 mips_fpr_names = chosen_abi->fpr_names; 947 } 948 chosen_arch = choose_arch_by_name (val, vallen); 949 if (chosen_arch != NULL) 950 { 951 mips_cp0_names = chosen_arch->cp0_names; 952 mips_cp0sel_names = chosen_arch->cp0sel_names; 953 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len; 954 mips_cp1_names = chosen_arch->cp1_names; 955 mips_hwr_names = chosen_arch->hwr_names; 956 } 957 return; 958 } 959 960 /* Invalid option. */ 961 } 962 963 static void 964 parse_mips_dis_options (const char *options) 965 { 966 const char *option_end; 967 968 if (options == NULL) 969 return; 970 971 while (*options != '\0') 972 { 973 /* Skip empty options. */ 974 if (*options == ',') 975 { 976 options++; 977 continue; 978 } 979 980 /* We know that *options is neither NUL or a comma. */ 981 option_end = options + 1; 982 while (*option_end != ',' && *option_end != '\0') 983 option_end++; 984 985 parse_mips_dis_option (options, option_end - options); 986 987 /* Go on to the next one. If option_end points to a comma, it 988 will be skipped above. */ 989 options = option_end; 990 } 991 } 992 993 static const struct mips_cp0sel_name * 994 lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names, 995 unsigned int len, 996 unsigned int cp0reg, 997 unsigned int sel) 998 { 999 unsigned int i; 1000 1001 for (i = 0; i < len; i++) 1002 if (names[i].cp0reg == cp0reg && names[i].sel == sel) 1003 return &names[i]; 1004 return NULL; 1005 } 1006 1007 /* Print register REGNO, of type TYPE, for instruction OPCODE. */ 1008 1009 static void 1010 print_reg (struct disassemble_info *info, const struct mips_opcode *opcode, 1011 enum mips_reg_operand_type type, int regno) 1012 { 1013 switch (type) 1014 { 1015 case OP_REG_GP: 1016 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]); 1017 break; 1018 1019 case OP_REG_FP: 1020 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]); 1021 break; 1022 1023 case OP_REG_CCC: 1024 if (opcode->pinfo & (FP_D | FP_S)) 1025 info->fprintf_func (info->stream, "$fcc%d", regno); 1026 else 1027 info->fprintf_func (info->stream, "$cc%d", regno); 1028 break; 1029 1030 case OP_REG_VEC: 1031 if (opcode->membership & INSN_5400) 1032 info->fprintf_func (info->stream, "$f%d", regno); 1033 else 1034 info->fprintf_func (info->stream, "$v%d", regno); 1035 break; 1036 1037 case OP_REG_ACC: 1038 info->fprintf_func (info->stream, "$ac%d", regno); 1039 break; 1040 1041 case OP_REG_COPRO: 1042 if (opcode->name[strlen (opcode->name) - 1] == '0') 1043 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]); 1044 else if (opcode->name[strlen (opcode->name) - 1] == '1') 1045 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]); 1046 else 1047 info->fprintf_func (info->stream, "$%d", regno); 1048 break; 1049 1050 case OP_REG_HW: 1051 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]); 1052 break; 1053 1054 case OP_REG_VF: 1055 info->fprintf_func (info->stream, "$vf%d", regno); 1056 break; 1057 1058 case OP_REG_VI: 1059 info->fprintf_func (info->stream, "$vi%d", regno); 1060 break; 1061 1062 case OP_REG_R5900_I: 1063 info->fprintf_func (info->stream, "$I"); 1064 break; 1065 1066 case OP_REG_R5900_Q: 1067 info->fprintf_func (info->stream, "$Q"); 1068 break; 1069 1070 case OP_REG_R5900_R: 1071 info->fprintf_func (info->stream, "$R"); 1072 break; 1073 1074 case OP_REG_R5900_ACC: 1075 info->fprintf_func (info->stream, "$ACC"); 1076 break; 1077 1078 case OP_REG_MSA: 1079 info->fprintf_func (info->stream, "$w%d", regno); 1080 break; 1081 1082 case OP_REG_MSA_CTRL: 1083 info->fprintf_func (info->stream, "%s", msa_control_names[regno]); 1084 break; 1085 1086 } 1087 } 1088 1089 /* Used to track the state carried over from previous operands in 1091 an instruction. */ 1092 struct mips_print_arg_state { 1093 /* The value of the last OP_INT seen. We only use this for OP_MSB, 1094 where the value is known to be unsigned and small. */ 1095 unsigned int last_int; 1096 1097 /* The type and number of the last OP_REG seen. We only use this for 1098 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */ 1099 enum mips_reg_operand_type last_reg_type; 1100 unsigned int last_regno; 1101 unsigned int dest_regno; 1102 unsigned int seen_dest; 1103 }; 1104 1105 /* Initialize STATE for the start of an instruction. */ 1106 1107 static inline void 1108 init_print_arg_state (struct mips_print_arg_state *state) 1109 { 1110 memset (state, 0, sizeof (*state)); 1111 } 1112 1113 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND, 1114 whose value is given by UVAL. */ 1115 1116 static void 1117 print_vu0_channel (struct disassemble_info *info, 1118 const struct mips_operand *operand, unsigned int uval) 1119 { 1120 if (operand->size == 4) 1121 info->fprintf_func (info->stream, "%s%s%s%s", 1122 uval & 8 ? "x" : "", 1123 uval & 4 ? "y" : "", 1124 uval & 2 ? "z" : "", 1125 uval & 1 ? "w" : ""); 1126 else if (operand->size == 2) 1127 info->fprintf_func (info->stream, "%c", "xyzw"[uval]); 1128 else 1129 abort (); 1130 } 1131 1132 /* Record information about a register operand. */ 1133 1134 static void 1135 mips_seen_register (struct mips_print_arg_state *state, 1136 unsigned int regno, 1137 enum mips_reg_operand_type reg_type) 1138 { 1139 state->last_reg_type = reg_type; 1140 state->last_regno = regno; 1141 1142 if (!state->seen_dest) 1143 { 1144 state->seen_dest = 1; 1145 state->dest_regno = regno; 1146 } 1147 } 1148 1149 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state. 1150 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is 1151 the base address for OP_PCREL operands. */ 1152 1153 static void 1154 print_insn_arg (struct disassemble_info *info, 1155 struct mips_print_arg_state *state, 1156 const struct mips_opcode *opcode, 1157 const struct mips_operand *operand, 1158 bfd_vma base_pc, 1159 unsigned int uval) 1160 { 1161 const fprintf_ftype infprintf = info->fprintf_func; 1162 void *is = info->stream; 1163 1164 switch (operand->type) 1165 { 1166 case OP_INT: 1167 { 1168 const struct mips_int_operand *int_op; 1169 1170 int_op = (const struct mips_int_operand *) operand; 1171 uval = mips_decode_int_operand (int_op, uval); 1172 state->last_int = uval; 1173 if (int_op->print_hex) 1174 infprintf (is, "0x%x", uval); 1175 else 1176 infprintf (is, "%d", uval); 1177 } 1178 break; 1179 1180 case OP_MAPPED_INT: 1181 { 1182 const struct mips_mapped_int_operand *mint_op; 1183 1184 mint_op = (const struct mips_mapped_int_operand *) operand; 1185 uval = mint_op->int_map[uval]; 1186 state->last_int = uval; 1187 if (mint_op->print_hex) 1188 infprintf (is, "0x%x", uval); 1189 else 1190 infprintf (is, "%d", uval); 1191 } 1192 break; 1193 1194 case OP_MSB: 1195 { 1196 const struct mips_msb_operand *msb_op; 1197 1198 msb_op = (const struct mips_msb_operand *) operand; 1199 uval += msb_op->bias; 1200 if (msb_op->add_lsb) 1201 uval -= state->last_int; 1202 infprintf (is, "0x%x", uval); 1203 } 1204 break; 1205 1206 case OP_REG: 1207 case OP_OPTIONAL_REG: 1208 { 1209 const struct mips_reg_operand *reg_op; 1210 1211 reg_op = (const struct mips_reg_operand *) operand; 1212 uval = mips_decode_reg_operand (reg_op, uval); 1213 print_reg (info, opcode, reg_op->reg_type, uval); 1214 1215 mips_seen_register (state, uval, reg_op->reg_type); 1216 } 1217 break; 1218 1219 case OP_REG_PAIR: 1220 { 1221 const struct mips_reg_pair_operand *pair_op; 1222 1223 pair_op = (const struct mips_reg_pair_operand *) operand; 1224 print_reg (info, opcode, pair_op->reg_type, 1225 pair_op->reg1_map[uval]); 1226 infprintf (is, ","); 1227 print_reg (info, opcode, pair_op->reg_type, 1228 pair_op->reg2_map[uval]); 1229 } 1230 break; 1231 1232 case OP_PCREL: 1233 { 1234 const struct mips_pcrel_operand *pcrel_op; 1235 1236 pcrel_op = (const struct mips_pcrel_operand *) operand; 1237 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval); 1238 1239 /* Preserve the ISA bit for the GDB disassembler, 1240 otherwise clear it. */ 1241 if (info->flavour != bfd_target_unknown_flavour) 1242 info->target &= -2; 1243 1244 (*info->print_address_func) (info->target, info); 1245 } 1246 break; 1247 1248 case OP_PERF_REG: 1249 infprintf (is, "%d", uval); 1250 break; 1251 1252 case OP_ADDIUSP_INT: 1253 { 1254 int sval; 1255 1256 sval = mips_signed_operand (operand, uval) * 4; 1257 if (sval >= -8 && sval < 8) 1258 sval ^= 0x400; 1259 infprintf (is, "%d", sval); 1260 break; 1261 } 1262 1263 case OP_CLO_CLZ_DEST: 1264 { 1265 unsigned int reg1, reg2; 1266 1267 reg1 = uval & 31; 1268 reg2 = uval >> 5; 1269 /* If one is zero use the other. */ 1270 if (reg1 == reg2 || reg2 == 0) 1271 infprintf (is, "%s", mips_gpr_names[reg1]); 1272 else if (reg1 == 0) 1273 infprintf (is, "%s", mips_gpr_names[reg2]); 1274 else 1275 /* Bogus, result depends on processor. */ 1276 infprintf (is, "%s or %s", mips_gpr_names[reg1], 1277 mips_gpr_names[reg2]); 1278 } 1279 break; 1280 1281 case OP_SAME_RS_RT: 1282 case OP_CHECK_PREV: 1283 case OP_NON_ZERO_REG: 1284 { 1285 print_reg (info, opcode, OP_REG_GP, uval & 31); 1286 mips_seen_register (state, uval, OP_REG_GP); 1287 } 1288 break; 1289 1290 case OP_LWM_SWM_LIST: 1291 if (operand->size == 2) 1292 { 1293 if (uval == 0) 1294 infprintf (is, "%s,%s", 1295 mips_gpr_names[16], 1296 mips_gpr_names[31]); 1297 else 1298 infprintf (is, "%s-%s,%s", 1299 mips_gpr_names[16], 1300 mips_gpr_names[16 + uval], 1301 mips_gpr_names[31]); 1302 } 1303 else 1304 { 1305 int s_reg_encode; 1306 1307 s_reg_encode = uval & 0xf; 1308 if (s_reg_encode != 0) 1309 { 1310 if (s_reg_encode == 1) 1311 infprintf (is, "%s", mips_gpr_names[16]); 1312 else if (s_reg_encode < 9) 1313 infprintf (is, "%s-%s", 1314 mips_gpr_names[16], 1315 mips_gpr_names[15 + s_reg_encode]); 1316 else if (s_reg_encode == 9) 1317 infprintf (is, "%s-%s,%s", 1318 mips_gpr_names[16], 1319 mips_gpr_names[23], 1320 mips_gpr_names[30]); 1321 else 1322 infprintf (is, "UNKNOWN"); 1323 } 1324 1325 if (uval & 0x10) /* For ra. */ 1326 { 1327 if (s_reg_encode == 0) 1328 infprintf (is, "%s", mips_gpr_names[31]); 1329 else 1330 infprintf (is, ",%s", mips_gpr_names[31]); 1331 } 1332 } 1333 break; 1334 1335 case OP_ENTRY_EXIT_LIST: 1336 { 1337 const char *sep; 1338 unsigned int amask, smask; 1339 1340 sep = ""; 1341 amask = (uval >> 3) & 7; 1342 if (amask > 0 && amask < 5) 1343 { 1344 infprintf (is, "%s", mips_gpr_names[4]); 1345 if (amask > 1) 1346 infprintf (is, "-%s", mips_gpr_names[amask + 3]); 1347 sep = ","; 1348 } 1349 1350 smask = (uval >> 1) & 3; 1351 if (smask == 3) 1352 { 1353 infprintf (is, "%s??", sep); 1354 sep = ","; 1355 } 1356 else if (smask > 0) 1357 { 1358 infprintf (is, "%s%s", sep, mips_gpr_names[16]); 1359 if (smask > 1) 1360 infprintf (is, "-%s", mips_gpr_names[smask + 15]); 1361 sep = ","; 1362 } 1363 1364 if (uval & 1) 1365 { 1366 infprintf (is, "%s%s", sep, mips_gpr_names[31]); 1367 sep = ","; 1368 } 1369 1370 if (amask == 5 || amask == 6) 1371 { 1372 infprintf (is, "%s%s", sep, mips_fpr_names[0]); 1373 if (amask == 6) 1374 infprintf (is, "-%s", mips_fpr_names[1]); 1375 } 1376 } 1377 break; 1378 1379 case OP_SAVE_RESTORE_LIST: 1380 /* Should be handled by the caller due to extend behavior. */ 1381 abort (); 1382 1383 case OP_MDMX_IMM_REG: 1384 { 1385 unsigned int vsel; 1386 1387 vsel = uval >> 5; 1388 uval &= 31; 1389 if ((vsel & 0x10) == 0) 1390 { 1391 int fmt; 1392 1393 vsel &= 0x0f; 1394 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1) 1395 if ((vsel & 1) == 0) 1396 break; 1397 print_reg (info, opcode, OP_REG_VEC, uval); 1398 infprintf (is, "[%d]", vsel >> 1); 1399 } 1400 else if ((vsel & 0x08) == 0) 1401 print_reg (info, opcode, OP_REG_VEC, uval); 1402 else 1403 infprintf (is, "0x%x", uval); 1404 } 1405 break; 1406 1407 case OP_REPEAT_PREV_REG: 1408 print_reg (info, opcode, state->last_reg_type, state->last_regno); 1409 break; 1410 1411 case OP_REPEAT_DEST_REG: 1412 print_reg (info, opcode, state->last_reg_type, state->dest_regno); 1413 break; 1414 1415 case OP_PC: 1416 infprintf (is, "$pc"); 1417 break; 1418 1419 case OP_VU0_SUFFIX: 1420 case OP_VU0_MATCH_SUFFIX: 1421 print_vu0_channel (info, operand, uval); 1422 break; 1423 1424 case OP_IMM_INDEX: 1425 infprintf (is, "[%d]", uval); 1426 break; 1427 1428 case OP_REG_INDEX: 1429 infprintf (is, "["); 1430 print_reg (info, opcode, OP_REG_GP, uval); 1431 infprintf (is, "]"); 1432 break; 1433 } 1434 } 1435 1436 /* Validate the arguments for INSN, which is described by OPCODE. 1437 Use DECODE_OPERAND to get the encoding of each operand. */ 1438 1439 static bfd_boolean 1440 validate_insn_args (const struct mips_opcode *opcode, 1441 const struct mips_operand *(*decode_operand) (const char *), 1442 unsigned int insn) 1443 { 1444 struct mips_print_arg_state state; 1445 const struct mips_operand *operand; 1446 const char *s; 1447 unsigned int uval; 1448 1449 init_print_arg_state (&state); 1450 for (s = opcode->args; *s; ++s) 1451 { 1452 switch (*s) 1453 { 1454 case ',': 1455 case '(': 1456 case ')': 1457 break; 1458 1459 case '#': 1460 ++s; 1461 break; 1462 1463 default: 1464 operand = decode_operand (s); 1465 1466 if (operand) 1467 { 1468 uval = mips_extract_operand (operand, insn); 1469 switch (operand->type) 1470 { 1471 case OP_REG: 1472 case OP_OPTIONAL_REG: 1473 { 1474 const struct mips_reg_operand *reg_op; 1475 1476 reg_op = (const struct mips_reg_operand *) operand; 1477 uval = mips_decode_reg_operand (reg_op, uval); 1478 mips_seen_register (&state, uval, reg_op->reg_type); 1479 } 1480 break; 1481 1482 case OP_SAME_RS_RT: 1483 { 1484 unsigned int reg1, reg2; 1485 1486 reg1 = uval & 31; 1487 reg2 = uval >> 5; 1488 1489 if (reg1 != reg2 || reg1 == 0) 1490 return FALSE; 1491 } 1492 break; 1493 1494 case OP_CHECK_PREV: 1495 { 1496 const struct mips_check_prev_operand *prev_op; 1497 1498 prev_op = (const struct mips_check_prev_operand *) operand; 1499 1500 if (!prev_op->zero_ok && uval == 0) 1501 return FALSE; 1502 1503 if (((prev_op->less_than_ok && uval < state.last_regno) 1504 || (prev_op->greater_than_ok && uval > state.last_regno) 1505 || (prev_op->equal_ok && uval == state.last_regno))) 1506 break; 1507 1508 return FALSE; 1509 } 1510 1511 case OP_NON_ZERO_REG: 1512 { 1513 if (uval == 0) 1514 return FALSE; 1515 } 1516 break; 1517 1518 case OP_INT: 1519 case OP_MAPPED_INT: 1520 case OP_MSB: 1521 case OP_REG_PAIR: 1522 case OP_PCREL: 1523 case OP_PERF_REG: 1524 case OP_ADDIUSP_INT: 1525 case OP_CLO_CLZ_DEST: 1526 case OP_LWM_SWM_LIST: 1527 case OP_ENTRY_EXIT_LIST: 1528 case OP_MDMX_IMM_REG: 1529 case OP_REPEAT_PREV_REG: 1530 case OP_REPEAT_DEST_REG: 1531 case OP_PC: 1532 case OP_VU0_SUFFIX: 1533 case OP_VU0_MATCH_SUFFIX: 1534 case OP_IMM_INDEX: 1535 case OP_REG_INDEX: 1536 break; 1537 1538 case OP_SAVE_RESTORE_LIST: 1539 /* Should be handled by the caller due to extend behavior. */ 1540 abort (); 1541 } 1542 } 1543 if (*s == 'm' || *s == '+' || *s == '-') 1544 ++s; 1545 } 1546 } 1547 return TRUE; 1548 } 1549 1550 /* Print the arguments for INSN, which is described by OPCODE. 1551 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC 1552 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL 1553 operand is for a branch or jump. */ 1554 1555 static void 1556 print_insn_args (struct disassemble_info *info, 1557 const struct mips_opcode *opcode, 1558 const struct mips_operand *(*decode_operand) (const char *), 1559 unsigned int insn, bfd_vma insn_pc, unsigned int length) 1560 { 1561 const fprintf_ftype infprintf = info->fprintf_func; 1562 void *is = info->stream; 1563 struct mips_print_arg_state state; 1564 const struct mips_operand *operand; 1565 const char *s; 1566 1567 init_print_arg_state (&state); 1568 for (s = opcode->args; *s; ++s) 1569 { 1570 switch (*s) 1571 { 1572 case ',': 1573 case '(': 1574 case ')': 1575 infprintf (is, "%c", *s); 1576 break; 1577 1578 case '#': 1579 ++s; 1580 infprintf (is, "%c%c", *s, *s); 1581 break; 1582 1583 default: 1584 operand = decode_operand (s); 1585 if (!operand) 1586 { 1587 /* xgettext:c-format */ 1588 infprintf (is, 1589 _("# internal error, undefined operand in `%s %s'"), 1590 opcode->name, opcode->args); 1591 return; 1592 } 1593 if (operand->type == OP_REG 1594 && s[1] == ',' 1595 && s[2] == 'H' 1596 && opcode->name[strlen (opcode->name) - 1] == '0') 1597 { 1598 /* Coprocessor register 0 with sel field (MT ASE). */ 1599 const struct mips_cp0sel_name *n; 1600 unsigned int reg, sel; 1601 1602 reg = mips_extract_operand (operand, insn); 1603 s += 2; 1604 operand = decode_operand (s); 1605 sel = mips_extract_operand (operand, insn); 1606 1607 /* CP0 register including 'sel' code for mftc0, to be 1608 printed textually if known. If not known, print both 1609 CP0 register name and sel numerically since CP0 register 1610 with sel 0 may have a name unrelated to register being 1611 printed. */ 1612 n = lookup_mips_cp0sel_name (mips_cp0sel_names, 1613 mips_cp0sel_names_len, 1614 reg, sel); 1615 if (n != NULL) 1616 infprintf (is, "%s", n->name); 1617 else 1618 infprintf (is, "$%d,%d", reg, sel); 1619 } 1620 else 1621 { 1622 bfd_vma base_pc = insn_pc; 1623 1624 /* Adjust the PC relative base so that branch/jump insns use 1625 the following PC as the base but genuinely PC relative 1626 operands use the current PC. */ 1627 if (operand->type == OP_PCREL) 1628 { 1629 const struct mips_pcrel_operand *pcrel_op; 1630 1631 pcrel_op = (const struct mips_pcrel_operand *) operand; 1632 /* The include_isa_bit flag is sufficient to distinguish 1633 branch/jump from other PC relative operands. */ 1634 if (pcrel_op->include_isa_bit) 1635 base_pc += length; 1636 } 1637 1638 print_insn_arg (info, &state, opcode, operand, base_pc, 1639 mips_extract_operand (operand, insn)); 1640 } 1641 if (*s == 'm' || *s == '+' || *s == '-') 1642 ++s; 1643 break; 1644 } 1645 } 1646 } 1647 1648 /* Print the mips instruction at address MEMADDR in debugged memory, 1650 on using INFO. Returns length of the instruction, in bytes, which is 1651 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if 1652 this is little-endian code. */ 1653 1654 static int 1655 print_insn_mips (bfd_vma memaddr, 1656 int word, 1657 struct disassemble_info *info) 1658 { 1659 #define GET_OP(insn, field) \ 1660 (((insn) >> OP_SH_##field) & OP_MASK_##field) 1661 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1]; 1662 const fprintf_ftype infprintf = info->fprintf_func; 1663 const struct mips_opcode *op; 1664 static bfd_boolean init = 0; 1665 void *is = info->stream; 1666 1667 /* Build a hash table to shorten the search time. */ 1668 if (! init) 1669 { 1670 unsigned int i; 1671 1672 for (i = 0; i <= OP_MASK_OP; i++) 1673 { 1674 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++) 1675 { 1676 if (op->pinfo == INSN_MACRO 1677 || (no_aliases && (op->pinfo2 & INSN2_ALIAS))) 1678 continue; 1679 if (i == GET_OP (op->match, OP)) 1680 { 1681 mips_hash[i] = op; 1682 break; 1683 } 1684 } 1685 } 1686 1687 init = 1; 1688 } 1689 1690 info->bytes_per_chunk = INSNLEN; 1691 info->display_endian = info->endian; 1692 info->insn_info_valid = 1; 1693 info->branch_delay_insns = 0; 1694 info->data_size = 0; 1695 info->insn_type = dis_nonbranch; 1696 info->target = 0; 1697 info->target2 = 0; 1698 1699 op = mips_hash[GET_OP (word, OP)]; 1700 if (op != NULL) 1701 { 1702 for (; op < &mips_opcodes[NUMOPCODES]; op++) 1703 { 1704 if (op->pinfo != INSN_MACRO 1705 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS)) 1706 && (word & op->mask) == op->match) 1707 { 1708 /* We always disassemble the jalx instruction, except for MIPS r6. */ 1709 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor) 1710 && (strcmp (op->name, "jalx") 1711 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6 1712 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)) 1713 continue; 1714 1715 /* Figure out instruction type and branch delay information. */ 1716 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0) 1717 { 1718 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0) 1719 info->insn_type = dis_jsr; 1720 else 1721 info->insn_type = dis_branch; 1722 info->branch_delay_insns = 1; 1723 } 1724 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY 1725 | INSN_COND_BRANCH_LIKELY)) != 0) 1726 { 1727 if ((op->pinfo & INSN_WRITE_GPR_31) != 0) 1728 info->insn_type = dis_condjsr; 1729 else 1730 info->insn_type = dis_condbranch; 1731 info->branch_delay_insns = 1; 1732 } 1733 else if ((op->pinfo & (INSN_STORE_MEMORY 1734 | INSN_LOAD_MEMORY)) != 0) 1735 info->insn_type = dis_dref; 1736 1737 if (!validate_insn_args (op, decode_mips_operand, word)) 1738 continue; 1739 1740 infprintf (is, "%s", op->name); 1741 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX) 1742 { 1743 unsigned int uval; 1744 1745 infprintf (is, "."); 1746 uval = mips_extract_operand (&mips_vu0_channel_mask, word); 1747 print_vu0_channel (info, &mips_vu0_channel_mask, uval); 1748 } 1749 1750 if (op->args[0]) 1751 { 1752 infprintf (is, "\t"); 1753 print_insn_args (info, op, decode_mips_operand, word, 1754 memaddr, 4); 1755 } 1756 1757 return INSNLEN; 1758 } 1759 } 1760 } 1761 #undef GET_OP 1762 1763 /* Handle undefined instructions. */ 1764 info->insn_type = dis_noninsn; 1765 infprintf (is, "0x%x", word); 1766 return INSNLEN; 1767 } 1768 1769 /* Disassemble an operand for a mips16 instruction. */ 1771 1772 static void 1773 print_mips16_insn_arg (struct disassemble_info *info, 1774 struct mips_print_arg_state *state, 1775 const struct mips_opcode *opcode, 1776 char type, bfd_vma memaddr, 1777 unsigned insn, bfd_boolean use_extend, 1778 unsigned extend, bfd_boolean is_offset) 1779 { 1780 const fprintf_ftype infprintf = info->fprintf_func; 1781 void *is = info->stream; 1782 const struct mips_operand *operand, *ext_operand; 1783 unsigned int uval; 1784 bfd_vma baseaddr; 1785 1786 if (!use_extend) 1787 extend = 0; 1788 1789 switch (type) 1790 { 1791 case ',': 1792 case '(': 1793 case ')': 1794 infprintf (is, "%c", type); 1795 break; 1796 1797 default: 1798 operand = decode_mips16_operand (type, FALSE); 1799 if (!operand) 1800 { 1801 /* xgettext:c-format */ 1802 infprintf (is, _("# internal error, undefined operand in `%s %s'"), 1803 opcode->name, opcode->args); 1804 return; 1805 } 1806 1807 if (operand->type == OP_SAVE_RESTORE_LIST) 1808 { 1809 /* Handle this case here because of the complex interation 1810 with the EXTEND opcode. */ 1811 unsigned int amask, nargs, nstatics, nsreg, smask, frame_size, i, j; 1812 const char *sep; 1813 1814 amask = extend & 0xf; 1815 if (amask == MIPS16_ALL_ARGS) 1816 { 1817 nargs = 4; 1818 nstatics = 0; 1819 } 1820 else if (amask == MIPS16_ALL_STATICS) 1821 { 1822 nargs = 0; 1823 nstatics = 4; 1824 } 1825 else 1826 { 1827 nargs = amask >> 2; 1828 nstatics = amask & 3; 1829 } 1830 1831 sep = ""; 1832 if (nargs > 0) 1833 { 1834 infprintf (is, "%s", mips_gpr_names[4]); 1835 if (nargs > 1) 1836 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]); 1837 sep = ","; 1838 } 1839 1840 frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8; 1841 if (frame_size == 0 && !use_extend) 1842 frame_size = 128; 1843 infprintf (is, "%s%d", sep, frame_size); 1844 1845 if (insn & 0x40) /* $ra */ 1846 infprintf (is, ",%s", mips_gpr_names[31]); 1847 1848 nsreg = (extend >> 8) & 0x7; 1849 smask = 0; 1850 if (insn & 0x20) /* $s0 */ 1851 smask |= 1 << 0; 1852 if (insn & 0x10) /* $s1 */ 1853 smask |= 1 << 1; 1854 if (nsreg > 0) /* $s2-$s8 */ 1855 smask |= ((1 << nsreg) - 1) << 2; 1856 1857 for (i = 0; i < 9; i++) 1858 if (smask & (1 << i)) 1859 { 1860 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]); 1861 /* Skip over string of set bits. */ 1862 for (j = i; smask & (2 << j); j++) 1863 continue; 1864 if (j > i) 1865 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]); 1866 i = j + 1; 1867 } 1868 /* Statics $ax - $a3. */ 1869 if (nstatics == 1) 1870 infprintf (is, ",%s", mips_gpr_names[7]); 1871 else if (nstatics > 0) 1872 infprintf (is, ",%s-%s", 1873 mips_gpr_names[7 - nstatics + 1], 1874 mips_gpr_names[7]); 1875 break; 1876 } 1877 1878 if (is_offset && operand->type == OP_INT) 1879 { 1880 const struct mips_int_operand *int_op; 1881 1882 int_op = (const struct mips_int_operand *) operand; 1883 info->insn_type = dis_dref; 1884 info->data_size = 1 << int_op->shift; 1885 } 1886 1887 if (operand->size == 26) 1888 /* In this case INSN is the first two bytes of the instruction 1889 and EXTEND is the second two bytes. */ 1890 uval = ((insn & 0x1f) << 21) | ((insn & 0x3e0) << 11) | extend; 1891 else 1892 { 1893 /* Calculate the full field value. */ 1894 uval = mips_extract_operand (operand, insn); 1895 if (use_extend) 1896 { 1897 ext_operand = decode_mips16_operand (type, TRUE); 1898 if (ext_operand != operand) 1899 { 1900 operand = ext_operand; 1901 if (operand->size == 16) 1902 uval = (((extend & 0x1f) << 11) | (extend & 0x7e0) 1903 | (uval & 0x1f)); 1904 else if (operand->size == 15) 1905 uval |= ((extend & 0xf) << 11) | (extend & 0x7f0); 1906 else 1907 uval = ((((extend >> 6) & 0x1f) | (extend & 0x20)) 1908 & ((1U << operand->size) - 1)); 1909 } 1910 } 1911 } 1912 1913 baseaddr = memaddr + 2; 1914 if (operand->type == OP_PCREL) 1915 { 1916 const struct mips_pcrel_operand *pcrel_op; 1917 1918 pcrel_op = (const struct mips_pcrel_operand *) operand; 1919 if (!pcrel_op->include_isa_bit && use_extend) 1920 baseaddr = memaddr - 2; 1921 else if (!pcrel_op->include_isa_bit) 1922 { 1923 bfd_byte buffer[2]; 1924 1925 /* If this instruction is in the delay slot of a JR 1926 instruction, the base address is the address of the 1927 JR instruction. If it is in the delay slot of a JALR 1928 instruction, the base address is the address of the 1929 JALR instruction. This test is unreliable: we have 1930 no way of knowing whether the previous word is 1931 instruction or data. */ 1932 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0 1933 && (((info->endian == BFD_ENDIAN_BIG 1934 ? bfd_getb16 (buffer) 1935 : bfd_getl16 (buffer)) 1936 & 0xf800) == 0x1800)) 1937 baseaddr = memaddr - 4; 1938 else if (info->read_memory_func (memaddr - 2, buffer, 2, 1939 info) == 0 1940 && (((info->endian == BFD_ENDIAN_BIG 1941 ? bfd_getb16 (buffer) 1942 : bfd_getl16 (buffer)) 1943 & 0xf81f) == 0xe800)) 1944 baseaddr = memaddr - 2; 1945 else 1946 baseaddr = memaddr; 1947 } 1948 } 1949 1950 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval); 1951 break; 1952 } 1953 } 1954 1955 1956 /* Check if the given address is the last word of a MIPS16 PLT entry. 1957 This word is data and depending on the value it may interfere with 1958 disassembly of further PLT entries. We make use of the fact PLT 1959 symbols are marked BSF_SYNTHETIC. */ 1960 static bfd_boolean 1961 is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr) 1962 { 1963 if (info->symbols 1964 && info->symbols[0] 1965 && (info->symbols[0]->flags & BSF_SYNTHETIC) 1966 && addr == bfd_asymbol_value (info->symbols[0]) + 12) 1967 return TRUE; 1968 1969 return FALSE; 1970 } 1971 1972 /* Disassemble mips16 instructions. */ 1973 1974 static int 1975 print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info) 1976 { 1977 const fprintf_ftype infprintf = info->fprintf_func; 1978 int status; 1979 bfd_byte buffer[4]; 1980 int length; 1981 int insn; 1982 bfd_boolean use_extend; 1983 int extend = 0; 1984 const struct mips_opcode *op, *opend; 1985 struct mips_print_arg_state state; 1986 void *is = info->stream; 1987 1988 info->bytes_per_chunk = 2; 1989 info->display_endian = info->endian; 1990 info->insn_info_valid = 1; 1991 info->branch_delay_insns = 0; 1992 info->data_size = 0; 1993 info->target = 0; 1994 info->target2 = 0; 1995 1996 #define GET_OP(insn, field) \ 1997 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field) 1998 /* Decode PLT entry's GOT slot address word. */ 1999 if (is_mips16_plt_tail (info, memaddr)) 2000 { 2001 info->insn_type = dis_noninsn; 2002 status = (*info->read_memory_func) (memaddr, buffer, 4, info); 2003 if (status == 0) 2004 { 2005 unsigned int gotslot; 2006 2007 if (info->endian == BFD_ENDIAN_BIG) 2008 gotslot = bfd_getb32 (buffer); 2009 else 2010 gotslot = bfd_getl32 (buffer); 2011 infprintf (is, ".word\t0x%x", gotslot); 2012 2013 return 4; 2014 } 2015 } 2016 else 2017 { 2018 info->insn_type = dis_nonbranch; 2019 status = (*info->read_memory_func) (memaddr, buffer, 2, info); 2020 } 2021 if (status != 0) 2022 { 2023 (*info->memory_error_func) (status, memaddr, info); 2024 return -1; 2025 } 2026 2027 length = 2; 2028 2029 if (info->endian == BFD_ENDIAN_BIG) 2030 insn = bfd_getb16 (buffer); 2031 else 2032 insn = bfd_getl16 (buffer); 2033 2034 /* Handle the extend opcode specially. */ 2035 use_extend = FALSE; 2036 if ((insn & 0xf800) == 0xf000) 2037 { 2038 use_extend = TRUE; 2039 extend = insn & 0x7ff; 2040 2041 memaddr += 2; 2042 2043 status = (*info->read_memory_func) (memaddr, buffer, 2, info); 2044 if (status != 0) 2045 { 2046 infprintf (is, "extend 0x%x", (unsigned int) extend); 2047 (*info->memory_error_func) (status, memaddr, info); 2048 return -1; 2049 } 2050 2051 if (info->endian == BFD_ENDIAN_BIG) 2052 insn = bfd_getb16 (buffer); 2053 else 2054 insn = bfd_getl16 (buffer); 2055 2056 /* Check for an extend opcode followed by an extend opcode. */ 2057 if ((insn & 0xf800) == 0xf000) 2058 { 2059 infprintf (is, "extend 0x%x", (unsigned int) extend); 2060 info->insn_type = dis_noninsn; 2061 return length; 2062 } 2063 2064 length += 2; 2065 } 2066 2067 /* FIXME: Should probably use a hash table on the major opcode here. */ 2068 2069 opend = mips16_opcodes + bfd_mips16_num_opcodes; 2070 for (op = mips16_opcodes; op < opend; op++) 2071 { 2072 if (op->pinfo != INSN_MACRO 2073 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS)) 2074 && (insn & op->mask) == op->match) 2075 { 2076 const char *s; 2077 2078 if (op->args[0] == 'a' || op->args[0] == 'i') 2079 { 2080 if (use_extend) 2081 { 2082 infprintf (is, "extend 0x%x", (unsigned int) extend); 2083 info->insn_type = dis_noninsn; 2084 return length - 2; 2085 } 2086 2087 use_extend = FALSE; 2088 2089 memaddr += 2; 2090 2091 status = (*info->read_memory_func) (memaddr, buffer, 2, 2092 info); 2093 if (status == 0) 2094 { 2095 use_extend = TRUE; 2096 if (info->endian == BFD_ENDIAN_BIG) 2097 extend = bfd_getb16 (buffer); 2098 else 2099 extend = bfd_getl16 (buffer); 2100 length += 2; 2101 } 2102 } 2103 2104 infprintf (is, "%s", op->name); 2105 if (op->args[0] != '\0') 2106 infprintf (is, "\t"); 2107 2108 init_print_arg_state (&state); 2109 for (s = op->args; *s != '\0'; s++) 2110 { 2111 if (*s == ',' 2112 && s[1] == 'w' 2113 && GET_OP (insn, RX) == GET_OP (insn, RY)) 2114 { 2115 /* Skip the register and the comma. */ 2116 ++s; 2117 continue; 2118 } 2119 if (*s == ',' 2120 && s[1] == 'v' 2121 && GET_OP (insn, RZ) == GET_OP (insn, RX)) 2122 { 2123 /* Skip the register and the comma. */ 2124 ++s; 2125 continue; 2126 } 2127 print_mips16_insn_arg (info, &state, op, *s, memaddr, insn, 2128 use_extend, extend, s[1] == '('); 2129 } 2130 2131 /* Figure out branch instruction type and delay slot information. */ 2132 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0) 2133 info->branch_delay_insns = 1; 2134 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0 2135 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0) 2136 { 2137 if ((op->pinfo & INSN_WRITE_GPR_31) != 0) 2138 info->insn_type = dis_jsr; 2139 else 2140 info->insn_type = dis_branch; 2141 } 2142 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0) 2143 info->insn_type = dis_condbranch; 2144 2145 return length; 2146 } 2147 } 2148 #undef GET_OP 2149 2150 if (use_extend) 2151 infprintf (is, "0x%x", extend | 0xf000); 2152 infprintf (is, "0x%x", insn); 2153 info->insn_type = dis_noninsn; 2154 2155 return length; 2156 } 2157 2158 /* Disassemble microMIPS instructions. */ 2159 2160 static int 2161 print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) 2162 { 2163 const fprintf_ftype infprintf = info->fprintf_func; 2164 const struct mips_opcode *op, *opend; 2165 void *is = info->stream; 2166 bfd_byte buffer[2]; 2167 unsigned int higher; 2168 unsigned int length; 2169 int status; 2170 unsigned int insn; 2171 2172 info->bytes_per_chunk = 2; 2173 info->display_endian = info->endian; 2174 info->insn_info_valid = 1; 2175 info->branch_delay_insns = 0; 2176 info->data_size = 0; 2177 info->insn_type = dis_nonbranch; 2178 info->target = 0; 2179 info->target2 = 0; 2180 2181 status = (*info->read_memory_func) (memaddr, buffer, 2, info); 2182 if (status != 0) 2183 { 2184 (*info->memory_error_func) (status, memaddr, info); 2185 return -1; 2186 } 2187 2188 length = 2; 2189 2190 if (info->endian == BFD_ENDIAN_BIG) 2191 insn = bfd_getb16 (buffer); 2192 else 2193 insn = bfd_getl16 (buffer); 2194 2195 if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000) 2196 { 2197 /* This is a 32-bit microMIPS instruction. */ 2198 higher = insn; 2199 2200 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info); 2201 if (status != 0) 2202 { 2203 infprintf (is, "micromips 0x%x", higher); 2204 (*info->memory_error_func) (status, memaddr + 2, info); 2205 return -1; 2206 } 2207 2208 if (info->endian == BFD_ENDIAN_BIG) 2209 insn = bfd_getb16 (buffer); 2210 else 2211 insn = bfd_getl16 (buffer); 2212 2213 insn = insn | (higher << 16); 2214 2215 length += 2; 2216 } 2217 2218 /* FIXME: Should probably use a hash table on the major opcode here. */ 2219 2220 opend = micromips_opcodes + bfd_micromips_num_opcodes; 2221 for (op = micromips_opcodes; op < opend; op++) 2222 { 2223 if (op->pinfo != INSN_MACRO 2224 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS)) 2225 && (insn & op->mask) == op->match 2226 && ((length == 2 && (op->mask & 0xffff0000) == 0) 2227 || (length == 4 && (op->mask & 0xffff0000) != 0))) 2228 { 2229 if (!validate_insn_args (op, decode_micromips_operand, insn)) 2230 continue; 2231 2232 infprintf (is, "%s", op->name); 2233 2234 if (op->args[0]) 2235 { 2236 infprintf (is, "\t"); 2237 print_insn_args (info, op, decode_micromips_operand, insn, 2238 memaddr + 1, length); 2239 } 2240 2241 /* Figure out instruction type and branch delay information. */ 2242 if ((op->pinfo 2243 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0) 2244 info->branch_delay_insns = 1; 2245 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY) 2246 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0) 2247 { 2248 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0) 2249 info->insn_type = dis_jsr; 2250 else 2251 info->insn_type = dis_branch; 2252 } 2253 else if (((op->pinfo & INSN_COND_BRANCH_DELAY) 2254 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0) 2255 { 2256 if ((op->pinfo & INSN_WRITE_GPR_31) != 0) 2257 info->insn_type = dis_condjsr; 2258 else 2259 info->insn_type = dis_condbranch; 2260 } 2261 else if ((op->pinfo 2262 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0) 2263 info->insn_type = dis_dref; 2264 2265 return length; 2266 } 2267 } 2268 2269 infprintf (is, "0x%x", insn); 2270 info->insn_type = dis_noninsn; 2271 2272 return length; 2273 } 2274 2275 /* Return 1 if a symbol associated with the location being disassembled 2276 indicates a compressed mode, either MIPS16 or microMIPS, according to 2277 MICROMIPS_P. We iterate over all the symbols at the address being 2278 considered assuming if at least one of them indicates code compression, 2279 then such code has been genuinely produced here (other symbols could 2280 have been derived from function symbols defined elsewhere or could 2281 define data). Otherwise, return 0. */ 2282 2283 static bfd_boolean 2284 is_compressed_mode_p (struct disassemble_info *info, bfd_boolean micromips_p) 2285 { 2286 int i; 2287 int l; 2288 2289 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++) 2290 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0 2291 && ((!micromips_p 2292 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i)) 2293 || (micromips_p 2294 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i)))) 2295 return 1; 2296 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour 2297 && info->symtab[i]->section == info->section) 2298 { 2299 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i]; 2300 if ((!micromips_p 2301 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other)) 2302 || (micromips_p 2303 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other))) 2304 return 1; 2305 } 2306 2307 return 0; 2308 } 2309 2310 /* In an environment where we do not know the symbol type of the 2311 instruction we are forced to assume that the low order bit of the 2312 instructions' address may mark it as a mips16 instruction. If we 2313 are single stepping, or the pc is within the disassembled function, 2314 this works. Otherwise, we need a clue. Sometimes. */ 2315 2316 static int 2317 _print_insn_mips (bfd_vma memaddr, 2318 struct disassemble_info *info, 2319 enum bfd_endian endianness) 2320 { 2321 bfd_byte buffer[INSNLEN]; 2322 int status; 2323 2324 set_default_mips_dis_options (info); 2325 parse_mips_dis_options (info->disassembler_options); 2326 2327 if (info->mach == bfd_mach_mips16) 2328 return print_insn_mips16 (memaddr, info); 2329 if (info->mach == bfd_mach_mips_micromips) 2330 return print_insn_micromips (memaddr, info); 2331 2332 #if 1 2333 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */ 2334 /* Only a few tools will work this way. */ 2335 if (memaddr & 0x01) 2336 { 2337 if (micromips_ase) 2338 return print_insn_micromips (memaddr, info); 2339 else 2340 return print_insn_mips16 (memaddr, info); 2341 } 2342 #endif 2343 2344 #if SYMTAB_AVAILABLE 2345 if (is_compressed_mode_p (info, TRUE)) 2346 return print_insn_micromips (memaddr, info); 2347 if (is_compressed_mode_p (info, FALSE)) 2348 return print_insn_mips16 (memaddr, info); 2349 #endif 2350 2351 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info); 2352 if (status == 0) 2353 { 2354 int insn; 2355 2356 if (endianness == BFD_ENDIAN_BIG) 2357 insn = bfd_getb32 (buffer); 2358 else 2359 insn = bfd_getl32 (buffer); 2360 2361 return print_insn_mips (memaddr, insn, info); 2362 } 2363 else 2364 { 2365 (*info->memory_error_func) (status, memaddr, info); 2366 return -1; 2367 } 2368 } 2369 2370 int 2371 print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info) 2372 { 2373 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG); 2374 } 2375 2376 int 2377 print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info) 2378 { 2379 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE); 2380 } 2381 2382 void 2384 print_mips_disassembler_options (FILE *stream) 2385 { 2386 unsigned int i; 2387 2388 fprintf (stream, _("\n\ 2389 The following MIPS specific disassembler options are supported for use\n\ 2390 with the -M switch (multiple options should be separated by commas):\n")); 2391 2392 fprintf (stream, _("\n\ 2393 msa Recognize MSA instructions.\n")); 2394 2395 fprintf (stream, _("\n\ 2396 virt Recognize the virtualization ASE instructions.\n")); 2397 2398 fprintf (stream, _("\n\ 2399 xpa Recognize the eXtended Physical Address (XPA) ASE instructions.\n")); 2400 2401 fprintf (stream, _("\n\ 2402 gpr-names=ABI Print GPR names according to specified ABI.\n\ 2403 Default: based on binary being disassembled.\n")); 2404 2405 fprintf (stream, _("\n\ 2406 fpr-names=ABI Print FPR names according to specified ABI.\n\ 2407 Default: numeric.\n")); 2408 2409 fprintf (stream, _("\n\ 2410 cp0-names=ARCH Print CP0 register names according to\n\ 2411 specified architecture.\n\ 2412 Default: based on binary being disassembled.\n")); 2413 2414 fprintf (stream, _("\n\ 2415 hwr-names=ARCH Print HWR names according to specified \n\ 2416 architecture.\n\ 2417 Default: based on binary being disassembled.\n")); 2418 2419 fprintf (stream, _("\n\ 2420 reg-names=ABI Print GPR and FPR names according to\n\ 2421 specified ABI.\n")); 2422 2423 fprintf (stream, _("\n\ 2424 reg-names=ARCH Print CP0 register and HWR names according to\n\ 2425 specified architecture.\n")); 2426 2427 fprintf (stream, _("\n\ 2428 For the options above, the following values are supported for \"ABI\":\n\ 2429 ")); 2430 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++) 2431 fprintf (stream, " %s", mips_abi_choices[i].name); 2432 fprintf (stream, _("\n")); 2433 2434 fprintf (stream, _("\n\ 2435 For the options above, The following values are supported for \"ARCH\":\n\ 2436 ")); 2437 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++) 2438 if (*mips_arch_choices[i].name != '\0') 2439 fprintf (stream, " %s", mips_arch_choices[i].name); 2440 fprintf (stream, _("\n")); 2441 2442 fprintf (stream, _("\n")); 2443 } 2444