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