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