Changeset 609 for branches/GNU/src/binutils/opcodes/mips-dis.c
- Timestamp:
- Aug 16, 2003, 6:59:22 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GNU/src/binutils/opcodes/mips-dis.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.1.1.2
r608 r609 1 1 /* Print mips instructions for GDB, the GNU debugger, or for objdump. 2 2 Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3 2000, 2001 3 2000, 2001, 2002, 2003 4 4 Free Software Foundation, Inc. 5 5 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp). … … 23 23 #include "sysdep.h" 24 24 #include "dis-asm.h" 25 #include "libiberty.h" 25 26 #include "opcode/mips.h" 26 27 #include "opintl.h" … … 29 30 not. The low bit of the address is often a good indicator. No 30 31 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 system as when it is used for disassembler support in a monitor. */ 32 33 33 34 #if !defined(EMBEDDED_ENV) … … 40 41 #define INSNLEN 4 41 42 43 static void set_default_mips_dis_options 44 PARAMS ((struct disassemble_info *)); 45 static void parse_mips_dis_option 46 PARAMS ((const char *, unsigned int)); 47 static void parse_mips_dis_options 48 PARAMS ((const char *)); 42 49 static int _print_insn_mips 43 50 PARAMS ((bfd_vma, struct disassemble_info *, enum bfd_endian)); 44 51 static int print_insn_mips 45 52 PARAMS ((bfd_vma, unsigned long int, struct disassemble_info *)); 46 static void print_insn_arg 53 static void print_insn_args 47 54 PARAMS ((const char *, unsigned long, bfd_vma, struct disassemble_info *)); 48 55 static int print_insn_mips16 49 56 PARAMS ((bfd_vma, struct disassemble_info *)); 57 static int is_newabi 58 PARAMS ((Elf_Internal_Ehdr *)); 50 59 static void print_mips16_insn_arg 51 PARAMS ((int, const struct mips_opcode *, int, b oolean, int, bfd_vma,60 PARAMS ((int, const struct mips_opcode *, int, bfd_boolean, int, bfd_vma, 52 61 struct disassemble_info *)); 53 62 … … 55 64 /* FIXME: These should be shared with gdb somehow. */ 56 65 66 struct mips_cp0sel_name { 67 unsigned int cp0reg; 68 unsigned int sel; 69 const char * const name; 70 }; 71 57 72 /* The mips16 register names. */ 58 static const char * const mips16_reg_names[] = 73 static const char * const mips16_reg_names[] = { 74 "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3" 75 }; 76 77 static const char * const mips_gpr_names_numeric[32] = { 78 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", 79 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", 80 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 81 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" 82 }; 83 84 static const char * const mips_gpr_names_oldabi[32] = { 85 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 86 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 87 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 88 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" 89 }; 90 91 static const char * const mips_gpr_names_newabi[32] = { 92 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 93 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", 94 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 95 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" 96 }; 97 98 static const char * const mips_fpr_names_numeric[32] = { 99 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", 100 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", 101 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", 102 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31" 103 }; 104 105 static const char * const mips_fpr_names_32[32] = { 106 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f", 107 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f", 108 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f", 109 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f" 110 }; 111 112 static const char * const mips_fpr_names_n32[32] = { 113 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3", 114 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3", 115 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9", 116 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13" 117 }; 118 119 static const char * const mips_fpr_names_64[32] = { 120 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3", 121 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3", 122 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11", 123 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7" 124 }; 125 126 static const char * const mips_cp0_names_numeric[32] = { 127 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", 128 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", 129 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 130 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" 131 }; 132 133 static const char * const mips_cp0_names_mips3264[32] = { 134 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", 135 "c0_context", "c0_pagemask", "c0_wired", "$7", 136 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare", 137 "c0_status", "c0_cause", "c0_epc", "c0_prid", 138 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi", 139 "c0_xcontext", "$21", "$22", "c0_debug", 140 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr", 141 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave", 142 }; 143 144 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] = { 145 { 16, 1, "c0_config1" }, 146 { 16, 2, "c0_config2" }, 147 { 16, 3, "c0_config3" }, 148 { 18, 1, "c0_watchlo,1" }, 149 { 18, 2, "c0_watchlo,2" }, 150 { 18, 3, "c0_watchlo,3" }, 151 { 18, 4, "c0_watchlo,4" }, 152 { 18, 5, "c0_watchlo,5" }, 153 { 18, 6, "c0_watchlo,6" }, 154 { 18, 7, "c0_watchlo,7" }, 155 { 19, 1, "c0_watchhi,1" }, 156 { 19, 2, "c0_watchhi,2" }, 157 { 19, 3, "c0_watchhi,3" }, 158 { 19, 4, "c0_watchhi,4" }, 159 { 19, 5, "c0_watchhi,5" }, 160 { 19, 6, "c0_watchhi,6" }, 161 { 19, 7, "c0_watchhi,7" }, 162 { 25, 1, "c0_perfcnt,1" }, 163 { 25, 2, "c0_perfcnt,2" }, 164 { 25, 3, "c0_perfcnt,3" }, 165 { 25, 4, "c0_perfcnt,4" }, 166 { 25, 5, "c0_perfcnt,5" }, 167 { 25, 6, "c0_perfcnt,6" }, 168 { 25, 7, "c0_perfcnt,7" }, 169 { 27, 1, "c0_cacheerr,1" }, 170 { 27, 2, "c0_cacheerr,2" }, 171 { 27, 3, "c0_cacheerr,3" }, 172 { 28, 1, "c0_datalo" }, 173 { 29, 1, "c0_datahi" } 174 }; 175 176 static const char * const mips_cp0_names_mips3264r2[32] = { 177 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", 178 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena", 179 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare", 180 "c0_status", "c0_cause", "c0_epc", "c0_prid", 181 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi", 182 "c0_xcontext", "$21", "$22", "c0_debug", 183 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr", 184 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave", 185 }; 186 187 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] = { 188 { 4, 1, "c0_contextconfig" }, 189 { 5, 1, "c0_pagegrain" }, 190 { 12, 1, "c0_intctl" }, 191 { 12, 2, "c0_srsctl" }, 192 { 12, 3, "c0_srsmap" }, 193 { 15, 1, "c0_ebase" }, 194 { 16, 1, "c0_config1" }, 195 { 16, 2, "c0_config2" }, 196 { 16, 3, "c0_config3" }, 197 { 18, 1, "c0_watchlo,1" }, 198 { 18, 2, "c0_watchlo,2" }, 199 { 18, 3, "c0_watchlo,3" }, 200 { 18, 4, "c0_watchlo,4" }, 201 { 18, 5, "c0_watchlo,5" }, 202 { 18, 6, "c0_watchlo,6" }, 203 { 18, 7, "c0_watchlo,7" }, 204 { 19, 1, "c0_watchhi,1" }, 205 { 19, 2, "c0_watchhi,2" }, 206 { 19, 3, "c0_watchhi,3" }, 207 { 19, 4, "c0_watchhi,4" }, 208 { 19, 5, "c0_watchhi,5" }, 209 { 19, 6, "c0_watchhi,6" }, 210 { 19, 7, "c0_watchhi,7" }, 211 { 23, 1, "c0_tracecontrol" }, 212 { 23, 2, "c0_tracecontrol2" }, 213 { 23, 3, "c0_usertracedata" }, 214 { 23, 4, "c0_tracebpc" }, 215 { 25, 1, "c0_perfcnt,1" }, 216 { 25, 2, "c0_perfcnt,2" }, 217 { 25, 3, "c0_perfcnt,3" }, 218 { 25, 4, "c0_perfcnt,4" }, 219 { 25, 5, "c0_perfcnt,5" }, 220 { 25, 6, "c0_perfcnt,6" }, 221 { 25, 7, "c0_perfcnt,7" }, 222 { 27, 1, "c0_cacheerr,1" }, 223 { 27, 2, "c0_cacheerr,2" }, 224 { 27, 3, "c0_cacheerr,3" }, 225 { 28, 1, "c0_datalo" }, 226 { 28, 2, "c0_taglo1" }, 227 { 28, 3, "c0_datalo1" }, 228 { 28, 4, "c0_taglo2" }, 229 { 28, 5, "c0_datalo2" }, 230 { 28, 6, "c0_taglo3" }, 231 { 28, 7, "c0_datalo3" }, 232 { 29, 1, "c0_datahi" }, 233 { 29, 2, "c0_taghi1" }, 234 { 29, 3, "c0_datahi1" }, 235 { 29, 4, "c0_taghi2" }, 236 { 29, 5, "c0_datahi2" }, 237 { 29, 6, "c0_taghi3" }, 238 { 29, 7, "c0_datahi3" }, 239 }; 240 241 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */ 242 static const char * const mips_cp0_names_sb1[32] = { 243 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", 244 "c0_context", "c0_pagemask", "c0_wired", "$7", 245 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare", 246 "c0_status", "c0_cause", "c0_epc", "c0_prid", 247 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi", 248 "c0_xcontext", "$21", "$22", "c0_debug", 249 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i", 250 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave", 251 }; 252 253 static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] = { 254 { 16, 1, "c0_config1" }, 255 { 18, 1, "c0_watchlo,1" }, 256 { 19, 1, "c0_watchhi,1" }, 257 { 22, 0, "c0_perftrace" }, 258 { 23, 3, "c0_edebug" }, 259 { 25, 1, "c0_perfcnt,1" }, 260 { 25, 2, "c0_perfcnt,2" }, 261 { 25, 3, "c0_perfcnt,3" }, 262 { 25, 4, "c0_perfcnt,4" }, 263 { 25, 5, "c0_perfcnt,5" }, 264 { 25, 6, "c0_perfcnt,6" }, 265 { 25, 7, "c0_perfcnt,7" }, 266 { 26, 1, "c0_buserr_pa" }, 267 { 27, 1, "c0_cacheerr_d" }, 268 { 27, 3, "c0_cacheerr_d_pa" }, 269 { 28, 1, "c0_datalo_i" }, 270 { 28, 2, "c0_taglo_d" }, 271 { 28, 3, "c0_datalo_d" }, 272 { 29, 1, "c0_datahi_i" }, 273 { 29, 2, "c0_taghi_d" }, 274 { 29, 3, "c0_datahi_d" }, 275 }; 276 277 static const char * const mips_hwr_names_numeric[32] = { 278 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", 279 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", 280 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 281 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" 282 }; 283 284 static const char * const mips_hwr_names_mips3264r2[32] = { 285 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres", 286 "$4", "$5", "$6", "$7", 287 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", 288 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 289 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" 290 }; 291 292 struct mips_abi_choice { 293 const char *name; 294 const char * const *gpr_names; 295 const char * const *fpr_names; 296 }; 297 298 struct mips_abi_choice mips_abi_choices[] = { 299 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric }, 300 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 }, 301 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 }, 302 { "64", mips_gpr_names_newabi, mips_fpr_names_64 }, 303 }; 304 305 struct mips_arch_choice { 306 const char *name; 307 int bfd_mach_valid; 308 unsigned long bfd_mach; 309 int processor; 310 int isa; 311 const char * const *cp0_names; 312 const struct mips_cp0sel_name *cp0sel_names; 313 unsigned int cp0sel_names_len; 314 const char * const *hwr_names; 315 }; 316 317 const struct mips_arch_choice mips_arch_choices[] = { 318 { "numeric", 0, 0, 0, 0, 319 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 320 321 { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, 322 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 323 { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, 324 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 325 { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, 326 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 327 { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, 328 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 329 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 330 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 331 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 332 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 333 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 334 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 335 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 336 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 337 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 338 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 339 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 340 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 341 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 342 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 343 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 344 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 345 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 346 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 347 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 348 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 349 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 350 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 351 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 352 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 353 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 354 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 355 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 356 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 357 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 358 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 359 360 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs. 361 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See 362 _MIPS32 Architecture For Programmers Volume I: Introduction to the 363 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95), 364 page 1. */ 365 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32, 366 ISA_MIPS32 | INSN_MIPS16, 367 mips_cp0_names_mips3264, 368 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264), 369 mips_hwr_names_numeric }, 370 371 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2, 372 ISA_MIPS32R2 | INSN_MIPS16, 373 mips_cp0_names_mips3264r2, 374 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), 375 mips_hwr_names_mips3264r2 }, 376 377 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */ 378 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64, 379 ISA_MIPS64 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX, 380 mips_cp0_names_mips3264, 381 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264), 382 mips_hwr_names_numeric }, 383 384 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1, 385 ISA_MIPS64 | INSN_MIPS3D | INSN_SB1, 386 mips_cp0_names_sb1, 387 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1), 388 mips_hwr_names_numeric }, 389 390 /* This entry, mips16, is here only for ISA/processor selection; do 391 not print its name. */ 392 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3 | INSN_MIPS16, 393 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, 394 }; 395 396 /* ISA and processor type to disassemble for, and register names to use. 397 set_default_mips_dis_options and parse_mips_dis_options fill in these 398 values. */ 399 static int mips_processor; 400 static int mips_isa; 401 static const char * const *mips_gpr_names; 402 static const char * const *mips_fpr_names; 403 static const char * const *mips_cp0_names; 404 static const struct mips_cp0sel_name *mips_cp0sel_names; 405 static int mips_cp0sel_names_len; 406 static const char * const *mips_hwr_names; 407 408 static const struct mips_abi_choice *choose_abi_by_name 409 PARAMS ((const char *, unsigned int)); 410 static const struct mips_arch_choice *choose_arch_by_name 411 PARAMS ((const char *, unsigned int)); 412 static const struct mips_arch_choice *choose_arch_by_number 413 PARAMS ((unsigned long)); 414 static const struct mips_cp0sel_name *lookup_mips_cp0sel_name 415 PARAMS ((const struct mips_cp0sel_name *, unsigned int, unsigned int, 416 unsigned int)); 417 418 419 static const struct mips_abi_choice * 420 choose_abi_by_name (name, namelen) 421 const char *name; 422 unsigned int namelen; 59 423 { 60 "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3" 61 }; 62 63 static const char * const mips32_reg_names[] = 424 const struct mips_abi_choice *c; 425 unsigned int i; 426 427 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++) 428 { 429 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0 430 && strlen (mips_abi_choices[i].name) == namelen) 431 c = &mips_abi_choices[i]; 432 } 433 return c; 434 } 435 436 static const struct mips_arch_choice * 437 choose_arch_by_name (name, namelen) 438 const char *name; 439 unsigned int namelen; 64 440 { 65 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 66 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 67 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 68 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", 69 "sr", "lo", "hi", "bad", "cause", "pc", 70 "fv0", "$f1", "fv1", "$f3", "ft0", "$f5", "ft1", "$f7", 71 "ft2", "$f9", "ft3", "$f11", "fa0", "$f13", "fa1", "$f15", 72 "ft4", "f17", "ft5", "f19", "fs0", "f21", "fs1", "f23", 73 "fs2", "$f25", "fs3", "$f27", "fs4", "$f29", "fs5", "$f31", 74 "fsr", "fir", "fp", "inx", "rand", "tlblo", "ctxt", "tlbhi", 75 "epc", "prid" 76 }; 77 78 static const char * const mips64_reg_names[] = 441 const struct mips_arch_choice *c = NULL; 442 unsigned int i; 443 444 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++) 445 { 446 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0 447 && strlen (mips_arch_choices[i].name) == namelen) 448 c = &mips_arch_choices[i]; 449 } 450 return c; 451 } 452 453 static const struct mips_arch_choice * 454 choose_arch_by_number (mach) 455 unsigned long mach; 79 456 { 80 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 81 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", 82 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 83 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", 84 "sr", "lo", "hi", "bad", "cause", "pc", 85 "fv0", "$f1", "fv1", "$f3", "ft0", "ft1", "ft2", "ft3", 86 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3", 87 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11", 88 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", 89 "fsr", "fir", "fp", "inx", "rand", "tlblo", "ctxt", "tlbhi", 90 "epc", "prid" 91 }; 92 93 /* Scalar register names. _print_insn_mips() decides which register name 94 table to use. */ 95 static const char * const *reg_names = NULL; 96 97 98 /* Print insn arguments for 32/64-bit code */ 457 static unsigned long hint_bfd_mach; 458 static const struct mips_arch_choice *hint_arch_choice; 459 const struct mips_arch_choice *c; 460 unsigned int i; 461 462 /* We optimize this because even if the user specifies no 463 flags, this will be done for every instruction! */ 464 if (hint_bfd_mach == mach 465 && hint_arch_choice != NULL 466 && hint_arch_choice->bfd_mach == hint_bfd_mach) 467 return hint_arch_choice; 468 469 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++) 470 { 471 if (mips_arch_choices[i].bfd_mach_valid 472 && mips_arch_choices[i].bfd_mach == mach) 473 { 474 c = &mips_arch_choices[i]; 475 hint_bfd_mach = mach; 476 hint_arch_choice = c; 477 } 478 } 479 return c; 480 } 481 482 void 483 set_default_mips_dis_options (info) 484 struct disassemble_info *info; 485 { 486 const struct mips_arch_choice *chosen_arch; 487 488 /* Defaults: mipsIII/r3000 (?!), (o)32-style ("oldabi") GPR names, 489 and numeric FPR, CP0 register, and HWR names. */ 490 mips_isa = ISA_MIPS3; 491 mips_processor = CPU_R3000; 492 mips_gpr_names = mips_gpr_names_oldabi; 493 mips_fpr_names = mips_fpr_names_numeric; 494 mips_cp0_names = mips_cp0_names_numeric; 495 mips_cp0sel_names = NULL; 496 mips_cp0sel_names_len = 0; 497 mips_hwr_names = mips_hwr_names_numeric; 498 499 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */ 500 if (info->flavour == bfd_target_elf_flavour && info->symbols != NULL) 501 { 502 Elf_Internal_Ehdr *header; 503 504 header = elf_elfheader (bfd_asymbol_bfd (*(info->symbols))); 505 if (is_newabi (header)) 506 mips_gpr_names = mips_gpr_names_newabi; 507 } 508 509 /* Set ISA, architecture, and cp0 register names as best we can. */ 510 #if ! SYMTAB_AVAILABLE 511 /* This is running out on a target machine, not in a host tool. 512 FIXME: Where does mips_target_info come from? */ 513 target_processor = mips_target_info.processor; 514 mips_isa = mips_target_info.isa; 515 #else 516 chosen_arch = choose_arch_by_number (info->mach); 517 if (chosen_arch != NULL) 518 { 519 mips_processor = chosen_arch->processor; 520 mips_isa = chosen_arch->isa; 521 mips_cp0_names = chosen_arch->cp0_names; 522 mips_cp0sel_names = chosen_arch->cp0sel_names; 523 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len; 524 mips_hwr_names = chosen_arch->hwr_names; 525 } 526 #endif 527 } 528 529 void 530 parse_mips_dis_option (option, len) 531 const char *option; 532 unsigned int len; 533 { 534 unsigned int i, optionlen, vallen; 535 const char *val; 536 const struct mips_abi_choice *chosen_abi; 537 const struct mips_arch_choice *chosen_arch; 538 539 /* Look for the = that delimits the end of the option name. */ 540 for (i = 0; i < len; i++) 541 { 542 if (option[i] == '=') 543 break; 544 } 545 if (i == 0) /* Invalid option: no name before '='. */ 546 return; 547 if (i == len) /* Invalid option: no '='. */ 548 return; 549 if (i == (len - 1)) /* Invalid option: no value after '='. */ 550 return; 551 552 optionlen = i; 553 val = option + (optionlen + 1); 554 vallen = len - (optionlen + 1); 555 556 if (strncmp("gpr-names", option, optionlen) == 0 557 && strlen("gpr-names") == optionlen) 558 { 559 chosen_abi = choose_abi_by_name (val, vallen); 560 if (chosen_abi != NULL) 561 mips_gpr_names = chosen_abi->gpr_names; 562 return; 563 } 564 565 if (strncmp("fpr-names", option, optionlen) == 0 566 && strlen("fpr-names") == optionlen) 567 { 568 chosen_abi = choose_abi_by_name (val, vallen); 569 if (chosen_abi != NULL) 570 mips_fpr_names = chosen_abi->fpr_names; 571 return; 572 } 573 574 if (strncmp("cp0-names", option, optionlen) == 0 575 && strlen("cp0-names") == optionlen) 576 { 577 chosen_arch = choose_arch_by_name (val, vallen); 578 if (chosen_arch != NULL) 579 { 580 mips_cp0_names = chosen_arch->cp0_names; 581 mips_cp0sel_names = chosen_arch->cp0sel_names; 582 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len; 583 } 584 return; 585 } 586 587 if (strncmp("hwr-names", option, optionlen) == 0 588 && strlen("hwr-names") == optionlen) 589 { 590 chosen_arch = choose_arch_by_name (val, vallen); 591 if (chosen_arch != NULL) 592 mips_hwr_names = chosen_arch->hwr_names; 593 return; 594 } 595 596 if (strncmp("reg-names", option, optionlen) == 0 597 && strlen("reg-names") == optionlen) 598 { 599 /* We check both ABI and ARCH here unconditionally, so 600 that "numeric" will do the desirable thing: select 601 numeric register names for all registers. Other than 602 that, a given name probably won't match both. */ 603 chosen_abi = choose_abi_by_name (val, vallen); 604 if (chosen_abi != NULL) 605 { 606 mips_gpr_names = chosen_abi->gpr_names; 607 mips_fpr_names = chosen_abi->fpr_names; 608 } 609 chosen_arch = choose_arch_by_name (val, vallen); 610 if (chosen_arch != NULL) 611 { 612 mips_cp0_names = chosen_arch->cp0_names; 613 mips_cp0sel_names = chosen_arch->cp0sel_names; 614 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len; 615 mips_hwr_names = chosen_arch->hwr_names; 616 } 617 return; 618 } 619 620 /* Invalid option. */ 621 } 622 623 void 624 parse_mips_dis_options (options) 625 const char *options; 626 { 627 const char *option_end; 628 629 if (options == NULL) 630 return; 631 632 while (*options != '\0') 633 { 634 /* Skip empty options. */ 635 if (*options == ',') 636 { 637 options++; 638 continue; 639 } 640 641 /* We know that *options is neither NUL or a comma. */ 642 option_end = options + 1; 643 while (*option_end != ',' && *option_end != '\0') 644 option_end++; 645 646 parse_mips_dis_option (options, option_end - options); 647 648 /* Go on to the next one. If option_end points to a comma, it 649 will be skipped above. */ 650 options = option_end; 651 } 652 } 653 654 static const struct mips_cp0sel_name * 655 lookup_mips_cp0sel_name(names, len, cp0reg, sel) 656 const struct mips_cp0sel_name *names; 657 unsigned int len, cp0reg, sel; 658 { 659 unsigned int i; 660 661 for (i = 0; i < len; i++) 662 if (names[i].cp0reg == cp0reg && names[i].sel == sel) 663 return &names[i]; 664 return NULL; 665 } 666 667 668 /* Print insn arguments for 32/64-bit code. */ 99 669 100 670 static void 101 print_insn_arg (d, l, pc, info)671 print_insn_args (d, l, pc, info) 102 672 const char *d; 103 673 register unsigned long int l; … … 105 675 struct disassemble_info *info; 106 676 { 107 int delta; 108 109 switch (*d) 110 { 111 case ',': 112 case '(': 113 case ')': 114 (*info->fprintf_func) (info->stream, "%c", *d); 115 break; 116 117 case 's': 118 case 'b': 119 case 'r': 120 case 'v': 121 (*info->fprintf_func) (info->stream, "%s", 122 reg_names[(l >> OP_SH_RS) & OP_MASK_RS]); 123 break; 124 125 case 't': 126 case 'w': 127 (*info->fprintf_func) (info->stream, "%s", 128 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]); 129 break; 130 131 case 'i': 132 case 'u': 133 (*info->fprintf_func) (info->stream, "0x%x", 134 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE); 135 break; 136 137 case 'j': /* same as i, but sign-extended */ 138 case 'o': 139 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA; 140 if (delta & 0x8000) 141 delta |= ~0xffff; 142 (*info->fprintf_func) (info->stream, "%d", 143 delta); 144 break; 145 146 case 'h': 147 (*info->fprintf_func) (info->stream, "0x%x", 148 (unsigned int) ((l >> OP_SH_PREFX) 149 & OP_MASK_PREFX)); 150 break; 151 152 case 'k': 153 (*info->fprintf_func) (info->stream, "0x%x", 154 (unsigned int) ((l >> OP_SH_CACHE) 155 & OP_MASK_CACHE)); 156 break; 157 158 case 'a': 159 (*info->print_address_func) 160 ((((pc + 4) & ~ (bfd_vma) 0x0fffffff) 161 | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)), 162 info); 163 break; 164 165 case 'p': 166 /* sign extend the displacement */ 167 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA; 168 if (delta & 0x8000) 169 delta |= ~0xffff; 170 (*info->print_address_func) 171 ((delta << 2) + pc + INSNLEN, 172 info); 173 break; 174 175 case 'd': 176 (*info->fprintf_func) (info->stream, "%s", 177 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]); 178 break; 179 180 case 'U': 181 { 182 /* First check for both rd and rt being equal. */ 183 unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD; 184 if (reg == ((l >> OP_SH_RT) & OP_MASK_RT)) 185 (*info->fprintf_func) (info->stream, "%s", 186 reg_names[reg]); 187 else 188 { 189 /* If one is zero use the other. */ 190 if (reg == 0) 191 (*info->fprintf_func) (info->stream, "%s", 192 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]); 193 else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0) 194 (*info->fprintf_func) (info->stream, "%s", 195 reg_names[reg]); 196 else /* Bogus, result depends on processor. */ 197 (*info->fprintf_func) (info->stream, "%s or %s", 198 reg_names[reg], 199 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]); 200 } 201 } 202 break; 203 204 case 'z': 205 (*info->fprintf_func) (info->stream, "%s", reg_names[0]); 206 break; 207 208 case '<': 209 (*info->fprintf_func) (info->stream, "0x%x", 210 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT); 211 break; 212 213 case 'c': 214 (*info->fprintf_func) (info->stream, "0x%x", 215 (l >> OP_SH_CODE) & OP_MASK_CODE); 216 break; 217 218 case 'q': 219 (*info->fprintf_func) (info->stream, "0x%x", 220 (l >> OP_SH_CODE2) & OP_MASK_CODE2); 221 break; 222 223 case 'C': 224 (*info->fprintf_func) (info->stream, "0x%x", 225 (l >> OP_SH_COPZ) & OP_MASK_COPZ); 226 break; 227 228 case 'B': 229 (*info->fprintf_func) (info->stream, "0x%x", 230 (l >> OP_SH_CODE20) & OP_MASK_CODE20); 231 break; 232 233 case 'J': 234 (*info->fprintf_func) (info->stream, "0x%x", 235 (l >> OP_SH_CODE19) & OP_MASK_CODE19); 236 break; 237 238 case 'S': 239 case 'V': 240 (*info->fprintf_func) (info->stream, "$f%d", 241 (l >> OP_SH_FS) & OP_MASK_FS); 242 break; 243 244 case 'T': 245 case 'W': 246 (*info->fprintf_func) (info->stream, "$f%d", 247 (l >> OP_SH_FT) & OP_MASK_FT); 248 break; 249 250 case 'D': 251 (*info->fprintf_func) (info->stream, "$f%d", 252 (l >> OP_SH_FD) & OP_MASK_FD); 253 break; 254 255 case 'R': 256 (*info->fprintf_func) (info->stream, "$f%d", 257 (l >> OP_SH_FR) & OP_MASK_FR); 258 break; 259 260 case 'E': 261 (*info->fprintf_func) (info->stream, "%s", 262 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]); 263 break; 264 265 case 'G': 266 (*info->fprintf_func) (info->stream, "%s", 267 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]); 268 break; 269 270 case 'N': 271 (*info->fprintf_func) (info->stream, "$fcc%d", 272 (l >> OP_SH_BCC) & OP_MASK_BCC); 273 break; 274 275 case 'M': 276 (*info->fprintf_func) (info->stream, "$fcc%d", 277 (l >> OP_SH_CCC) & OP_MASK_CCC); 278 break; 279 280 case 'P': 281 (*info->fprintf_func) (info->stream, "%d", 282 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG); 283 break; 284 285 case 'H': 286 (*info->fprintf_func) (info->stream, "%d", 287 (l >> OP_SH_SEL) & OP_MASK_SEL); 288 break; 289 290 default: 291 /* xgettext:c-format */ 292 (*info->fprintf_func) (info->stream, 293 _("# internal error, undefined modifier(%c)"), 294 *d); 295 break; 677 int op, delta; 678 unsigned int lsb, msb, msbd; 679 680 lsb = 0; 681 682 for (; *d != '\0'; d++) 683 { 684 switch (*d) 685 { 686 case ',': 687 case '(': 688 case ')': 689 case '[': 690 case ']': 691 (*info->fprintf_func) (info->stream, "%c", *d); 692 break; 693 694 case '+': 695 /* Extension character; switch for second char. */ 696 d++; 697 switch (*d) 698 { 699 case '\0': 700 /* xgettext:c-format */ 701 (*info->fprintf_func) (info->stream, 702 _("# internal error, incomplete extension sequence (+)")); 703 return; 704 705 case 'A': 706 lsb = (l >> OP_SH_SHAMT) & OP_MASK_SHAMT; 707 (*info->fprintf_func) (info->stream, "0x%x", lsb); 708 break; 709 710 case 'B': 711 msb = (l >> OP_SH_INSMSB) & OP_MASK_INSMSB; 712 (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1); 713 break; 714 715 case 'C': 716 msbd = (l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD; 717 (*info->fprintf_func) (info->stream, "0x%x", msbd + 1); 718 break; 719 720 case 'D': 721 { 722 const struct mips_cp0sel_name *n; 723 unsigned int cp0reg, sel; 724 725 cp0reg = (l >> OP_SH_RD) & OP_MASK_RD; 726 sel = (l >> OP_SH_SEL) & OP_MASK_SEL; 727 728 /* CP0 register including 'sel' code for mtcN (et al.), to be 729 printed textually if known. If not known, print both 730 CP0 register name and sel numerically since CP0 register 731 with sel 0 may have a name unrelated to register being 732 printed. */ 733 n = lookup_mips_cp0sel_name(mips_cp0sel_names, 734 mips_cp0sel_names_len, cp0reg, sel); 735 if (n != NULL) 736 (*info->fprintf_func) (info->stream, "%s", n->name); 737 else 738 (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel); 739 break; 740 } 741 742 default: 743 /* xgettext:c-format */ 744 (*info->fprintf_func) (info->stream, 745 _("# internal error, undefined extension sequence (+%c)"), 746 *d); 747 return; 748 } 749 break; 750 751 case 's': 752 case 'b': 753 case 'r': 754 case 'v': 755 (*info->fprintf_func) (info->stream, "%s", 756 mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]); 757 break; 758 759 case 't': 760 case 'w': 761 (*info->fprintf_func) (info->stream, "%s", 762 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]); 763 break; 764 765 case 'i': 766 case 'u': 767 (*info->fprintf_func) (info->stream, "0x%x", 768 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE); 769 break; 770 771 case 'j': /* Same as i, but sign-extended. */ 772 case 'o': 773 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA; 774 if (delta & 0x8000) 775 delta |= ~0xffff; 776 (*info->fprintf_func) (info->stream, "%d", 777 delta); 778 break; 779 780 case 'h': 781 (*info->fprintf_func) (info->stream, "0x%x", 782 (unsigned int) ((l >> OP_SH_PREFX) 783 & OP_MASK_PREFX)); 784 break; 785 786 case 'k': 787 (*info->fprintf_func) (info->stream, "0x%x", 788 (unsigned int) ((l >> OP_SH_CACHE) 789 & OP_MASK_CACHE)); 790 break; 791 792 case 'a': 793 info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff) 794 | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)); 795 (*info->print_address_func) (info->target, info); 796 break; 797 798 case 'p': 799 /* Sign extend the displacement. */ 800 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA; 801 if (delta & 0x8000) 802 delta |= ~0xffff; 803 info->target = (delta << 2) + pc + INSNLEN; 804 (*info->print_address_func) (info->target, info); 805 break; 806 807 case 'd': 808 (*info->fprintf_func) (info->stream, "%s", 809 mips_gpr_names[(l >> OP_SH_RD) & OP_MASK_RD]); 810 break; 811 812 case 'U': 813 { 814 /* First check for both rd and rt being equal. */ 815 unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD; 816 if (reg == ((l >> OP_SH_RT) & OP_MASK_RT)) 817 (*info->fprintf_func) (info->stream, "%s", 818 mips_gpr_names[reg]); 819 else 820 { 821 /* If one is zero use the other. */ 822 if (reg == 0) 823 (*info->fprintf_func) (info->stream, "%s", 824 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]); 825 else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0) 826 (*info->fprintf_func) (info->stream, "%s", 827 mips_gpr_names[reg]); 828 else /* Bogus, result depends on processor. */ 829 (*info->fprintf_func) (info->stream, "%s or %s", 830 mips_gpr_names[reg], 831 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]); 832 } 833 } 834 break; 835 836 case 'z': 837 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]); 838 break; 839 840 case '<': 841 (*info->fprintf_func) (info->stream, "0x%x", 842 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT); 843 break; 844 845 case 'c': 846 (*info->fprintf_func) (info->stream, "0x%x", 847 (l >> OP_SH_CODE) & OP_MASK_CODE); 848 break; 849 850 case 'q': 851 (*info->fprintf_func) (info->stream, "0x%x", 852 (l >> OP_SH_CODE2) & OP_MASK_CODE2); 853 break; 854 855 case 'C': 856 (*info->fprintf_func) (info->stream, "0x%x", 857 (l >> OP_SH_COPZ) & OP_MASK_COPZ); 858 break; 859 860 case 'B': 861 (*info->fprintf_func) (info->stream, "0x%x", 862 (l >> OP_SH_CODE20) & OP_MASK_CODE20); 863 break; 864 865 case 'J': 866 (*info->fprintf_func) (info->stream, "0x%x", 867 (l >> OP_SH_CODE19) & OP_MASK_CODE19); 868 break; 869 870 case 'S': 871 case 'V': 872 (*info->fprintf_func) (info->stream, "%s", 873 mips_fpr_names[(l >> OP_SH_FS) & OP_MASK_FS]); 874 break; 875 876 case 'T': 877 case 'W': 878 (*info->fprintf_func) (info->stream, "%s", 879 mips_fpr_names[(l >> OP_SH_FT) & OP_MASK_FT]); 880 break; 881 882 case 'D': 883 (*info->fprintf_func) (info->stream, "%s", 884 mips_fpr_names[(l >> OP_SH_FD) & OP_MASK_FD]); 885 break; 886 887 case 'R': 888 (*info->fprintf_func) (info->stream, "%s", 889 mips_fpr_names[(l >> OP_SH_FR) & OP_MASK_FR]); 890 break; 891 892 case 'E': 893 /* Coprocessor register for lwcN instructions, et al. 894 895 Note that there is no load/store cp0 instructions, and 896 that FPU (cp1) instructions disassemble this field using 897 'T' format. Therefore, until we gain understanding of 898 cp2 register names, we can simply print the register 899 numbers. */ 900 (*info->fprintf_func) (info->stream, "$%d", 901 (l >> OP_SH_RT) & OP_MASK_RT); 902 break; 903 904 case 'G': 905 /* Coprocessor register for mtcN instructions, et al. Note 906 that FPU (cp1) instructions disassemble this field using 907 'S' format. Therefore, we only need to worry about cp0, 908 cp2, and cp3. */ 909 op = (l >> OP_SH_OP) & OP_MASK_OP; 910 if (op == OP_OP_COP0) 911 (*info->fprintf_func) (info->stream, "%s", 912 mips_cp0_names[(l >> OP_SH_RD) & OP_MASK_RD]); 913 else 914 (*info->fprintf_func) (info->stream, "$%d", 915 (l >> OP_SH_RD) & OP_MASK_RD); 916 break; 917 918 case 'K': 919 (*info->fprintf_func) (info->stream, "%s", 920 mips_hwr_names[(l >> OP_SH_RD) & OP_MASK_RD]); 921 break; 922 923 case 'N': 924 (*info->fprintf_func) (info->stream, "$fcc%d", 925 (l >> OP_SH_BCC) & OP_MASK_BCC); 926 break; 927 928 case 'M': 929 (*info->fprintf_func) (info->stream, "$fcc%d", 930 (l >> OP_SH_CCC) & OP_MASK_CCC); 931 break; 932 933 case 'P': 934 (*info->fprintf_func) (info->stream, "%d", 935 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG); 936 break; 937 938 case 'e': 939 (*info->fprintf_func) (info->stream, "%d", 940 (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE); 941 break; 942 943 case '%': 944 (*info->fprintf_func) (info->stream, "%d", 945 (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN); 946 break; 947 948 case 'H': 949 (*info->fprintf_func) (info->stream, "%d", 950 (l >> OP_SH_SEL) & OP_MASK_SEL); 951 break; 952 953 case 'O': 954 (*info->fprintf_func) (info->stream, "%d", 955 (l >> OP_SH_ALN) & OP_MASK_ALN); 956 break; 957 958 case 'Q': 959 { 960 unsigned int vsel = (l >> OP_SH_VSEL) & OP_MASK_VSEL; 961 if ((vsel & 0x10) == 0) 962 { 963 int fmt; 964 vsel &= 0x0f; 965 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1) 966 if ((vsel & 1) == 0) 967 break; 968 (*info->fprintf_func) (info->stream, "$v%d[%d]", 969 (l >> OP_SH_FT) & OP_MASK_FT, 970 vsel >> 1); 971 } 972 else if ((vsel & 0x08) == 0) 973 { 974 (*info->fprintf_func) (info->stream, "$v%d", 975 (l >> OP_SH_FT) & OP_MASK_FT); 976 } 977 else 978 { 979 (*info->fprintf_func) (info->stream, "0x%x", 980 (l >> OP_SH_FT) & OP_MASK_FT); 981 } 982 } 983 break; 984 985 case 'X': 986 (*info->fprintf_func) (info->stream, "$v%d", 987 (l >> OP_SH_FD) & OP_MASK_FD); 988 break; 989 990 case 'Y': 991 (*info->fprintf_func) (info->stream, "$v%d", 992 (l >> OP_SH_FS) & OP_MASK_FS); 993 break; 994 995 case 'Z': 996 (*info->fprintf_func) (info->stream, "$v%d", 997 (l >> OP_SH_FT) & OP_MASK_FT); 998 break; 999 1000 default: 1001 /* xgettext:c-format */ 1002 (*info->fprintf_func) (info->stream, 1003 _("# internal error, undefined modifier(%c)"), 1004 *d); 1005 return; 1006 } 296 1007 } 297 1008 } 298 1009 299 1010 300 /* Figure out the MIPS ISA and CPU based on the machine number. */ 301 302 static void 303 mips_isa_type (mach, isa, cputype) 304 int mach; 305 int *isa; 306 int *cputype; 1011 /* Check if the object uses NewABI conventions. */ 1012 1013 static int 1014 is_newabi (header) 1015 Elf_Internal_Ehdr *header; 307 1016 { 308 switch (mach) 309 { 310 case bfd_mach_mips3000: 311 *cputype = CPU_R3000; 312 *isa = ISA_MIPS1; 313 break; 314 case bfd_mach_mips3900: 315 *cputype = CPU_R3900; 316 *isa = ISA_MIPS1; 317 break; 318 case bfd_mach_mips4000: 319 *cputype = CPU_R4000; 320 *isa = ISA_MIPS3; 321 break; 322 case bfd_mach_mips4010: 323 *cputype = CPU_R4010; 324 *isa = ISA_MIPS2; 325 break; 326 case bfd_mach_mips4100: 327 *cputype = CPU_VR4100; 328 *isa = ISA_MIPS3; 329 break; 330 case bfd_mach_mips4111: 331 *cputype = CPU_R4111; 332 *isa = ISA_MIPS3; 333 break; 334 case bfd_mach_mips4300: 335 *cputype = CPU_R4300; 336 *isa = ISA_MIPS3; 337 break; 338 case bfd_mach_mips4400: 339 *cputype = CPU_R4400; 340 *isa = ISA_MIPS3; 341 break; 342 case bfd_mach_mips4600: 343 *cputype = CPU_R4600; 344 *isa = ISA_MIPS3; 345 break; 346 case bfd_mach_mips4650: 347 *cputype = CPU_R4650; 348 *isa = ISA_MIPS3; 349 break; 350 case bfd_mach_mips5000: 351 *cputype = CPU_R5000; 352 *isa = ISA_MIPS4; 353 break; 354 case bfd_mach_mips6000: 355 *cputype = CPU_R6000; 356 *isa = ISA_MIPS2; 357 break; 358 case bfd_mach_mips8000: 359 *cputype = CPU_R8000; 360 *isa = ISA_MIPS4; 361 break; 362 case bfd_mach_mips10000: 363 *cputype = CPU_R10000; 364 *isa = ISA_MIPS4; 365 break; 366 case bfd_mach_mips12000: 367 *cputype = CPU_R12000; 368 *isa = ISA_MIPS4; 369 break; 370 case bfd_mach_mips16: 371 *cputype = CPU_MIPS16; 372 *isa = ISA_MIPS3; 373 break; 374 case bfd_mach_mips32: 375 *cputype = CPU_MIPS32; 376 *isa = ISA_MIPS32; 377 break; 378 case bfd_mach_mips32_4k: 379 *cputype = CPU_MIPS32_4K; 380 *isa = ISA_MIPS32; 381 break; 382 case bfd_mach_mips5: 383 *cputype = CPU_MIPS5; 384 *isa = ISA_MIPS5; 385 break; 386 case bfd_mach_mips64: 387 *cputype = CPU_MIPS64; 388 *isa = ISA_MIPS64; 389 break; 390 case bfd_mach_mips_sb1: 391 *cputype = CPU_SB1; 392 *isa = ISA_MIPS64; 393 break; 394 default: 395 *cputype = CPU_R3000; 396 *isa = ISA_MIPS3; 397 break; 398 } 399 } 400 401 /* Figure out ISA from disassemble_info data */ 402 403 static int 404 get_mips_isa (info) 405 struct disassemble_info *info; 406 { 407 int isa; 408 int cpu; 409 410 mips_isa_type (info->mach, &isa, &cpu); 411 return isa; 1017 /* There are no old-style ABIs which use 64-bit ELF. */ 1018 if (header->e_ident[EI_CLASS] == ELFCLASS64) 1019 return 1; 1020 1021 /* If a 32-bit ELF file, n32 is a new-style ABI. */ 1022 if ((header->e_flags & EF_MIPS_ABI2) != 0) 1023 return 1; 1024 1025 return 0; 412 1026 } 413 1027 … … 425 1039 { 426 1040 register const struct mips_opcode *op; 427 int target_processor, mips_isa; 428 static boolean init = 0; 1041 static bfd_boolean init = 0; 429 1042 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1]; 430 1043 … … 446 1059 } 447 1060 } 448 1061 } 449 1062 450 1063 init = 1; 451 1064 } 452 453 #if ! SYMTAB_AVAILABLE454 /* This is running out on a target machine, not in a host tool.455 FIXME: Where does mips_target_info come from? */456 target_processor = mips_target_info.processor;457 mips_isa = mips_target_info.isa;458 #else459 mips_isa_type (info->mach, &mips_isa, &target_processor);460 #endif461 1065 462 1066 info->bytes_per_chunk = INSNLEN; 463 1067 info->display_endian = info->endian; 1068 info->insn_info_valid = 1; 1069 info->branch_delay_insns = 0; 1070 info->data_size = 0; 1071 info->insn_type = dis_nonbranch; 1072 info->target = 0; 1073 info->target2 = 0; 464 1074 465 1075 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP]; … … 472 1082 register const char *d; 473 1083 474 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor, 0)) 1084 /* We always allow to disassemble the jalx instruction. */ 1085 if (! OPCODE_IS_MEMBER (op, mips_isa, mips_processor) 1086 && strcmp (op->name, "jalx")) 475 1087 continue; 1088 1089 /* Figure out instruction type and branch delay information. */ 1090 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0) 1091 { 1092 if ((info->insn_type & INSN_WRITE_GPR_31) != 0) 1093 info->insn_type = dis_jsr; 1094 else 1095 info->insn_type = dis_branch; 1096 info->branch_delay_insns = 1; 1097 } 1098 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY 1099 | INSN_COND_BRANCH_LIKELY)) != 0) 1100 { 1101 if ((info->insn_type & INSN_WRITE_GPR_31) != 0) 1102 info->insn_type = dis_condjsr; 1103 else 1104 info->insn_type = dis_condbranch; 1105 info->branch_delay_insns = 1; 1106 } 1107 else if ((op->pinfo & (INSN_STORE_MEMORY 1108 | INSN_LOAD_MEMORY_DELAY)) != 0) 1109 info->insn_type = dis_dref; 476 1110 477 1111 (*info->fprintf_func) (info->stream, "%s", op->name); … … 480 1114 if (d != NULL && *d != '\0') 481 1115 { 482 (*info->fprintf_func) (info->stream, "\t"); 483 for (; *d != '\0'; d++) 484 print_insn_arg (d, word, memaddr, info); 1116 (*info->fprintf_func) (info->stream, "\t"); 1117 print_insn_args (d, word, memaddr, info); 485 1118 } 486 1119 … … 491 1124 492 1125 /* Handle undefined instructions. */ 1126 info->insn_type = dis_noninsn; 493 1127 (*info->fprintf_func) (info->stream, "0x%x", word); 494 1128 return INSNLEN; … … 511 1145 int status; 512 1146 1147 set_default_mips_dis_options (info); 1148 parse_mips_dis_options (info->disassembler_options); 1149 513 1150 #if 1 514 1151 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */ … … 519 1156 520 1157 #if SYMTAB_AVAILABLE 521 if (info->mach == 161158 if (info->mach == bfd_mach_mips16 522 1159 || (info->flavour == bfd_target_elf_flavour 523 1160 && info->symbols != NULL … … 527 1164 #endif 528 1165 529 /* Use mips64_reg_names for new ABI. */530 if (info->flavour == bfd_target_elf_flavour531 && info->symbols != NULL532 && (((get_mips_isa(info) | INSN_ISA_MASK) & ISA_MIPS2) != 0)533 && ((elf_elfheader (bfd_asymbol_bfd(*(info->symbols)))->e_flags534 & EF_MIPS_ABI2) != 0))535 reg_names = mips64_reg_names;536 else537 reg_names = mips32_reg_names;538 539 1166 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info); 540 1167 if (status == 0) … … 543 1170 544 1171 if (endianness == BFD_ENDIAN_BIG) 545 1172 insn = (unsigned long) bfd_getb32 (buffer); 546 1173 else 547 1174 insn = (unsigned long) bfd_getl32 (buffer); … … 584 1211 int length; 585 1212 int insn; 586 b oolean use_extend;1213 bfd_boolean use_extend; 587 1214 int extend = 0; 588 1215 const struct mips_opcode *op, *opend; … … 612 1239 613 1240 /* Handle the extend opcode specially. */ 614 use_extend = false;1241 use_extend = FALSE; 615 1242 if ((insn & 0xf800) == 0xf000) 616 1243 { 617 use_extend = true;1244 use_extend = TRUE; 618 1245 extend = insn & 0x7ff; 619 1246 … … 665 1292 } 666 1293 667 use_extend = false;1294 use_extend = FALSE; 668 1295 669 1296 memaddr += 2; … … 673 1300 if (status == 0) 674 1301 { 675 use_extend = true;1302 use_extend = TRUE; 676 1303 if (info->endian == BFD_ENDIAN_BIG) 677 1304 extend = bfd_getb16 (buffer); … … 736 1363 const struct mips_opcode *op; 737 1364 int l; 738 b oolean use_extend;1365 bfd_boolean use_extend; 739 1366 int extend; 740 1367 bfd_vma memaddr; … … 776 1403 777 1404 case '0': 778 (*info->fprintf_func) (info->stream, "%s", mips 32_reg_names[0]);1405 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]); 779 1406 break; 780 1407 781 1408 case 'S': 782 (*info->fprintf_func) (info->stream, "%s", mips 32_reg_names[29]);1409 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[29]); 783 1410 break; 784 1411 … … 788 1415 789 1416 case 'R': 790 (*info->fprintf_func) (info->stream, "%s", mips 32_reg_names[31]);1417 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[31]); 791 1418 break; 792 1419 793 1420 case 'X': 794 1421 (*info->fprintf_func) (info->stream, "%s", 795 mips 32_reg_names[((l >> MIPS16OP_SH_REGR32)796 & MIPS16OP_MASK_REGR32)]);1422 mips_gpr_names[((l >> MIPS16OP_SH_REGR32) 1423 & MIPS16OP_MASK_REGR32)]); 797 1424 break; 798 1425 799 1426 case 'Y': 800 1427 (*info->fprintf_func) (info->stream, "%s", 801 mips 32_reg_names[MIPS16OP_EXTRACT_REG32R (l)]);1428 mips_gpr_names[MIPS16OP_EXTRACT_REG32R (l)]); 802 1429 break; 803 1430 … … 1011 1638 { 1012 1639 bfd_vma baseaddr; 1013 bfd_vma val;1014 1640 1015 1641 if (branch) … … 1054 1680 } 1055 1681 } 1056 val = (baseaddr & ~ ((1 << shift) - 1)) + immed; 1057 (*info->print_address_func) (val, info); 1058 info->target = val; 1682 info->target = (baseaddr & ~((1 << shift) - 1)) + immed; 1683 (*info->print_address_func) (info->target, info); 1059 1684 } 1060 1685 } … … 1065 1690 extend = 0; 1066 1691 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2); 1067 (*info->print_address_func) (((memaddr + 4) & 0xf0000000) | l, info); 1692 info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l; 1693 (*info->print_address_func) (info->target, info); 1068 1694 info->insn_type = dis_jsr; 1069 info->target = ((memaddr + 4) & 0xf0000000) | l;1070 1695 info->branch_delay_insns = 1; 1071 1696 break; … … 1084 1709 if (amask > 0 && amask < 5) 1085 1710 { 1086 (*info->fprintf_func) (info->stream, "%s", mips 32_reg_names[4]);1711 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]); 1087 1712 if (amask > 1) 1088 1713 (*info->fprintf_func) (info->stream, "-%s", 1089 mips 32_reg_names[amask + 3]);1714 mips_gpr_names[amask + 3]); 1090 1715 need_comma = 1; 1091 1716 } … … 1102 1727 (*info->fprintf_func) (info->stream, "%s%s", 1103 1728 need_comma ? "," : "", 1104 mips 32_reg_names[16]);1729 mips_gpr_names[16]); 1105 1730 if (smask > 1) 1106 1731 (*info->fprintf_func) (info->stream, "-%s", 1107 mips 32_reg_names[smask + 15]);1732 mips_gpr_names[smask + 15]); 1108 1733 need_comma = 1; 1109 1734 } … … 1113 1738 (*info->fprintf_func) (info->stream, "%s%s", 1114 1739 need_comma ? "," : "", 1115 mips 32_reg_names[31]);1740 mips_gpr_names[31]); 1116 1741 need_comma = 1; 1117 1742 } … … 1136 1761 } 1137 1762 } 1763 1764 void 1765 print_mips_disassembler_options (stream) 1766 FILE *stream; 1767 { 1768 unsigned int i; 1769 1770 fprintf (stream, _("\n\ 1771 The following MIPS specific disassembler options are supported for use\n\ 1772 with the -M switch (multiple options should be separated by commas):\n")); 1773 1774 fprintf (stream, _("\n\ 1775 gpr-names=ABI Print GPR names according to specified ABI.\n\ 1776 Default: based on binary being disassembled.\n")); 1777 1778 fprintf (stream, _("\n\ 1779 fpr-names=ABI Print FPR names according to specified ABI.\n\ 1780 Default: numeric.\n")); 1781 1782 fprintf (stream, _("\n\ 1783 cp0-names=ARCH Print CP0 register names according to\n\ 1784 specified architecture.\n\ 1785 Default: based on binary being disassembled.\n")); 1786 1787 fprintf (stream, _("\n\ 1788 hwr-names=ARCH Print HWR names according to specified \n\ 1789 architecture.\n\ 1790 Default: based on binary being disassembled.\n")); 1791 1792 fprintf (stream, _("\n\ 1793 reg-names=ABI Print GPR and FPR names according to\n\ 1794 specified ABI.\n")); 1795 1796 fprintf (stream, _("\n\ 1797 reg-names=ARCH Print CP0 register and HWR names according to\n\ 1798 specified architecture.\n")); 1799 1800 fprintf (stream, _("\n\ 1801 For the options above, the following values are supported for \"ABI\":\n\ 1802 ")); 1803 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++) 1804 fprintf (stream, " %s", mips_abi_choices[i].name); 1805 fprintf (stream, _("\n")); 1806 1807 fprintf (stream, _("\n\ 1808 For the options above, The following values are supported for \"ARCH\":\n\ 1809 ")); 1810 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++) 1811 if (*mips_arch_choices[i].name != '\0') 1812 fprintf (stream, " %s", mips_arch_choices[i].name); 1813 fprintf (stream, _("\n")); 1814 1815 fprintf (stream, _("\n")); 1816 } -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.