1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2    Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3    2000, 2001, 2002, 2003, 2005
4    Free Software Foundation, Inc.
5    Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
6 
7    This file is part of GDB, GAS, and the GNU binutils.
8 
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22    MA 02110-1301, USA.  */
23 
24 #include "sysdep.h"
25 #include "dis-asm.h"
26 #include "libiberty.h"
27 #include "opcode/mips.h"
28 #include "opintl.h"
29 
30 /* FIXME: These are needed to figure out if the code is mips16 or
31    not. The low bit of the address is often a good indicator.  No
32    symbol table is available when this code runs out in an embedded
33    system as when it is used for disassembler support in a monitor.  */
34 
35 #if !defined(EMBEDDED_ENV)
36 #define SYMTAB_AVAILABLE 1
37 #include "elf-bfd.h"
38 #include "elf/mips.h"
39 #endif
40 
41 /* Mips instructions are at maximum this many bytes long.  */
42 #define INSNLEN 4
43 
44 
45 /* FIXME: These should be shared with gdb somehow.  */
46 
47 struct mips_cp0sel_name
48 {
49   unsigned int cp0reg;
50   unsigned int sel;
51   const char * const name;
52 };
53 
54 /* The mips16 register names.  */
55 static const char * const mips16_reg_names[] =
56 {
57   "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
58 };
59 
60 static const char * const mips_gpr_names_numeric[32] =
61 {
62   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
63   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
64   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
65   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
66 };
67 
68 static const char * const mips_gpr_names_oldabi[32] =
69 {
70   "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
71   "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7",
72   "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
73   "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
74 };
75 
76 static const char * const mips_gpr_names_newabi[32] =
77 {
78   "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
79   "a4",   "a5",   "a6",   "a7",   "t0",   "t1",   "t2",   "t3",
80   "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
81   "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
82 };
83 
84 static const char * const mips_fpr_names_numeric[32] =
85 {
86   "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",
87   "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
88   "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
89   "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
90 };
91 
92 static const char * const mips_fpr_names_32[32] =
93 {
94   "fv0",  "fv0f", "fv1",  "fv1f", "ft0",  "ft0f", "ft1",  "ft1f",
95   "ft2",  "ft2f", "ft3",  "ft3f", "fa0",  "fa0f", "fa1",  "fa1f",
96   "ft4",  "ft4f", "ft5",  "ft5f", "fs0",  "fs0f", "fs1",  "fs1f",
97   "fs2",  "fs2f", "fs3",  "fs3f", "fs4",  "fs4f", "fs5",  "fs5f"
98 };
99 
100 static const char * const mips_fpr_names_n32[32] =
101 {
102   "fv0",  "ft14", "fv1",  "ft15", "ft0",  "ft1",  "ft2",  "ft3",
103   "ft4",  "ft5",  "ft6",  "ft7",  "fa0",  "fa1",  "fa2",  "fa3",
104   "fa4",  "fa5",  "fa6",  "fa7",  "fs0",  "ft8",  "fs1",  "ft9",
105   "fs2",  "ft10", "fs3",  "ft11", "fs4",  "ft12", "fs5",  "ft13"
106 };
107 
108 static const char * const mips_fpr_names_64[32] =
109 {
110   "fv0",  "ft12", "fv1",  "ft13", "ft0",  "ft1",  "ft2",  "ft3",
111   "ft4",  "ft5",  "ft6",  "ft7",  "fa0",  "fa1",  "fa2",  "fa3",
112   "fa4",  "fa5",  "fa6",  "fa7",  "ft8",  "ft9",  "ft10", "ft11",
113   "fs0",  "fs1",  "fs2",  "fs3",  "fs4",  "fs5",  "fs6",  "fs7"
114 };
115 
116 static const char * const mips_cp0_names_numeric[32] =
117 {
118   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
119   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
120   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
121   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
122 };
123 
124 static const char * const mips_cp0_names_mips3264[32] =
125 {
126   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
127   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
128   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
129   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
130   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
131   "c0_xcontext",  "$21",          "$22",          "c0_debug",
132   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr",
133   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "c0_desave",
134 };
135 
136 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
137 {
138   { 16, 1, "c0_config1"		},
139   { 16, 2, "c0_config2"		},
140   { 16, 3, "c0_config3"		},
141   { 18, 1, "c0_watchlo,1"	},
142   { 18, 2, "c0_watchlo,2"	},
143   { 18, 3, "c0_watchlo,3"	},
144   { 18, 4, "c0_watchlo,4"	},
145   { 18, 5, "c0_watchlo,5"	},
146   { 18, 6, "c0_watchlo,6"	},
147   { 18, 7, "c0_watchlo,7"	},
148   { 19, 1, "c0_watchhi,1"	},
149   { 19, 2, "c0_watchhi,2"	},
150   { 19, 3, "c0_watchhi,3"	},
151   { 19, 4, "c0_watchhi,4"	},
152   { 19, 5, "c0_watchhi,5"	},
153   { 19, 6, "c0_watchhi,6"	},
154   { 19, 7, "c0_watchhi,7"	},
155   { 25, 1, "c0_perfcnt,1"	},
156   { 25, 2, "c0_perfcnt,2"	},
157   { 25, 3, "c0_perfcnt,3"	},
158   { 25, 4, "c0_perfcnt,4"	},
159   { 25, 5, "c0_perfcnt,5"	},
160   { 25, 6, "c0_perfcnt,6"	},
161   { 25, 7, "c0_perfcnt,7"	},
162   { 27, 1, "c0_cacheerr,1"	},
163   { 27, 2, "c0_cacheerr,2"	},
164   { 27, 3, "c0_cacheerr,3"	},
165   { 28, 1, "c0_datalo"		},
166   { 29, 1, "c0_datahi"		}
167 };
168 
169 static const char * const mips_cp0_names_mips3264r2[32] =
170 {
171   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
172   "c0_context",   "c0_pagemask",  "c0_wired",     "c0_hwrena",
173   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
174   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
175   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
176   "c0_xcontext",  "$21",          "$22",          "c0_debug",
177   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr",
178   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "c0_desave",
179 };
180 
181 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
182 {
183   {  4, 1, "c0_contextconfig"	},
184   {  5, 1, "c0_pagegrain"	},
185   { 12, 1, "c0_intctl"		},
186   { 12, 2, "c0_srsctl"		},
187   { 12, 3, "c0_srsmap"		},
188   { 15, 1, "c0_ebase"		},
189   { 16, 1, "c0_config1"		},
190   { 16, 2, "c0_config2"		},
191   { 16, 3, "c0_config3"		},
192   { 18, 1, "c0_watchlo,1"	},
193   { 18, 2, "c0_watchlo,2"	},
194   { 18, 3, "c0_watchlo,3"	},
195   { 18, 4, "c0_watchlo,4"	},
196   { 18, 5, "c0_watchlo,5"	},
197   { 18, 6, "c0_watchlo,6"	},
198   { 18, 7, "c0_watchlo,7"	},
199   { 19, 1, "c0_watchhi,1"	},
200   { 19, 2, "c0_watchhi,2"	},
201   { 19, 3, "c0_watchhi,3"	},
202   { 19, 4, "c0_watchhi,4"	},
203   { 19, 5, "c0_watchhi,5"	},
204   { 19, 6, "c0_watchhi,6"	},
205   { 19, 7, "c0_watchhi,7"	},
206   { 23, 1, "c0_tracecontrol"	},
207   { 23, 2, "c0_tracecontrol2"	},
208   { 23, 3, "c0_usertracedata"	},
209   { 23, 4, "c0_tracebpc"	},
210   { 25, 1, "c0_perfcnt,1"	},
211   { 25, 2, "c0_perfcnt,2"	},
212   { 25, 3, "c0_perfcnt,3"	},
213   { 25, 4, "c0_perfcnt,4"	},
214   { 25, 5, "c0_perfcnt,5"	},
215   { 25, 6, "c0_perfcnt,6"	},
216   { 25, 7, "c0_perfcnt,7"	},
217   { 27, 1, "c0_cacheerr,1"	},
218   { 27, 2, "c0_cacheerr,2"	},
219   { 27, 3, "c0_cacheerr,3"	},
220   { 28, 1, "c0_datalo"		},
221   { 28, 2, "c0_taglo1"		},
222   { 28, 3, "c0_datalo1"		},
223   { 28, 4, "c0_taglo2"		},
224   { 28, 5, "c0_datalo2"		},
225   { 28, 6, "c0_taglo3"		},
226   { 28, 7, "c0_datalo3"		},
227   { 29, 1, "c0_datahi"		},
228   { 29, 2, "c0_taghi1"		},
229   { 29, 3, "c0_datahi1"		},
230   { 29, 4, "c0_taghi2"		},
231   { 29, 5, "c0_datahi2"		},
232   { 29, 6, "c0_taghi3"		},
233   { 29, 7, "c0_datahi3"		},
234 };
235 
236 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods.  */
237 static const char * const mips_cp0_names_sb1[32] =
238 {
239   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
240   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
241   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
242   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
243   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
244   "c0_xcontext",  "$21",          "$22",          "c0_debug",
245   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr_i",
246   "c0_taglo_i",   "c0_taghi_i",   "c0_errorepc",  "c0_desave",
247 };
248 
249 static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
250 {
251   { 16, 1, "c0_config1"		},
252   { 18, 1, "c0_watchlo,1"	},
253   { 19, 1, "c0_watchhi,1"	},
254   { 22, 0, "c0_perftrace"	},
255   { 23, 3, "c0_edebug"		},
256   { 25, 1, "c0_perfcnt,1"	},
257   { 25, 2, "c0_perfcnt,2"	},
258   { 25, 3, "c0_perfcnt,3"	},
259   { 25, 4, "c0_perfcnt,4"	},
260   { 25, 5, "c0_perfcnt,5"	},
261   { 25, 6, "c0_perfcnt,6"	},
262   { 25, 7, "c0_perfcnt,7"	},
263   { 26, 1, "c0_buserr_pa"	},
264   { 27, 1, "c0_cacheerr_d"	},
265   { 27, 3, "c0_cacheerr_d_pa"	},
266   { 28, 1, "c0_datalo_i"	},
267   { 28, 2, "c0_taglo_d"		},
268   { 28, 3, "c0_datalo_d"	},
269   { 29, 1, "c0_datahi_i"	},
270   { 29, 2, "c0_taghi_d"		},
271   { 29, 3, "c0_datahi_d"	},
272 };
273 
274 static const char * const mips_hwr_names_numeric[32] =
275 {
276   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
277   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
278   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
279   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
280 };
281 
282 static const char * const mips_hwr_names_mips3264r2[32] =
283 {
284   "hwr_cpunum",   "hwr_synci_step", "hwr_cc",     "hwr_ccres",
285   "$4",          "$5",            "$6",           "$7",
286   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
287   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
288   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
289 };
290 
291 struct mips_abi_choice
292 {
293   const char * name;
294   const char * const *gpr_names;
295   const char * const *fpr_names;
296 };
297 
298 struct mips_abi_choice mips_abi_choices[] =
299 {
300   { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
301   { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
302   { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
303   { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
304 };
305 
306 struct mips_arch_choice
307 {
308   const char *name;
309   int bfd_mach_valid;
310   unsigned long bfd_mach;
311   int processor;
312   int isa;
313   const char * const *cp0_names;
314   const struct mips_cp0sel_name *cp0sel_names;
315   unsigned int cp0sel_names_len;
316   const char * const *hwr_names;
317 };
318 
319 const struct mips_arch_choice mips_arch_choices[] =
320 {
321   { "numeric",	0, 0, 0, 0,
322     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
323 
324   { "r3000",	1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1,
325     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
326   { "r3900",	1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1,
327     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
328   { "r4000",	1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3,
329     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
330   { "r4010",	1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2,
331     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
332   { "vr4100",	1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3,
333     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
334   { "vr4111",	1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3,
335     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
336   { "vr4120",	1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3,
337     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
338   { "r4300",	1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3,
339     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
340   { "r4400",	1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3,
341     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
342   { "r4600",	1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3,
343     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
344   { "r4650",	1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3,
345     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
346   { "r5000",	1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4,
347     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
348   { "vr5400",	1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4,
349     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
350   { "vr5500",	1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4,
351     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
352   { "r6000",	1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2,
353     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
354   { "rm7000",	1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4,
355     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
356   { "rm9000",	1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4,
357     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
358   { "r8000",	1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4,
359     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
360   { "r10000",	1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4,
361     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
362   { "r12000",	1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4,
363     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
364   { "mips5",	1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5,
365     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
366 
367   /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
368      Note that MIPS-3D and MDMX are not applicable to MIPS32.  (See
369      _MIPS32 Architecture For Programmers Volume I: Introduction to the
370      MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
371      page 1.  */
372   { "mips32",	1, bfd_mach_mipsisa32, CPU_MIPS32,
373     ISA_MIPS32 | INSN_MIPS16,
374     mips_cp0_names_mips3264,
375     mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
376     mips_hwr_names_numeric },
377 
378   { "mips32r2",	1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
379     ISA_MIPS32R2 | INSN_MIPS16,
380     mips_cp0_names_mips3264r2,
381     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
382     mips_hwr_names_mips3264r2 },
383 
384   /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs.  */
385   { "mips64",	1, bfd_mach_mipsisa64, CPU_MIPS64,
386     ISA_MIPS64 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX,
387     mips_cp0_names_mips3264,
388     mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
389     mips_hwr_names_numeric },
390 
391   { "mips64r2",	1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
392     ISA_MIPS64R2 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX,
393     mips_cp0_names_mips3264r2,
394     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
395     mips_hwr_names_mips3264r2 },
396 
397   { "sb1",	1, bfd_mach_mips_sb1, CPU_SB1,
398     ISA_MIPS64 | INSN_MIPS3D | INSN_SB1,
399     mips_cp0_names_sb1,
400     mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
401     mips_hwr_names_numeric },
402 
403   /* This entry, mips16, is here only for ISA/processor selection; do
404      not print its name.  */
405   { "",		1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3 | INSN_MIPS16,
406     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
407 };
408 
409 /* ISA and processor type to disassemble for, and register names to use.
410    set_default_mips_dis_options and parse_mips_dis_options fill in these
411    values.  */
412 static int mips_processor;
413 static int mips_isa;
414 static const char * const *mips_gpr_names;
415 static const char * const *mips_fpr_names;
416 static const char * const *mips_cp0_names;
417 static const struct mips_cp0sel_name *mips_cp0sel_names;
418 static int mips_cp0sel_names_len;
419 static const char * const *mips_hwr_names;
420 
421 /* Other options */
422 static int no_aliases;	/* If set disassemble as most general inst.  */
423 
424 static const struct mips_abi_choice *
choose_abi_by_name(const char * name,unsigned int namelen)425 choose_abi_by_name (const char *name, unsigned int namelen)
426 {
427   const struct mips_abi_choice *c;
428   unsigned int i;
429 
430   for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
431     if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
432 	&& strlen (mips_abi_choices[i].name) == namelen)
433       c = &mips_abi_choices[i];
434 
435   return c;
436 }
437 
438 static const struct mips_arch_choice *
choose_arch_by_name(const char * name,unsigned int namelen)439 choose_arch_by_name (const char *name, unsigned int namelen)
440 {
441   const struct mips_arch_choice *c = NULL;
442   unsigned int i;
443 
444   for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
445     if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
446 	&& strlen (mips_arch_choices[i].name) == namelen)
447       c = &mips_arch_choices[i];
448 
449   return c;
450 }
451 
452 static const struct mips_arch_choice *
choose_arch_by_number(unsigned long mach)453 choose_arch_by_number (unsigned long mach)
454 {
455   static unsigned long hint_bfd_mach;
456   static const struct mips_arch_choice *hint_arch_choice;
457   const struct mips_arch_choice *c;
458   unsigned int i;
459 
460   /* We optimize this because even if the user specifies no
461      flags, this will be done for every instruction!  */
462   if (hint_bfd_mach == mach
463       && hint_arch_choice != NULL
464       && hint_arch_choice->bfd_mach == hint_bfd_mach)
465     return hint_arch_choice;
466 
467   for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
468     {
469       if (mips_arch_choices[i].bfd_mach_valid
470 	  && mips_arch_choices[i].bfd_mach == mach)
471 	{
472 	  c = &mips_arch_choices[i];
473 	  hint_bfd_mach = mach;
474 	  hint_arch_choice = c;
475 	}
476     }
477   return c;
478 }
479 
480 /* Check if the object uses NewABI conventions.  */
481 
482 static int
is_newabi(Elf_Internal_Ehdr * header)483 is_newabi (Elf_Internal_Ehdr *header)
484 {
485   /* There are no old-style ABIs which use 64-bit ELF.  */
486   if (header->e_ident[EI_CLASS] == ELFCLASS64)
487     return 1;
488 
489   /* If a 32-bit ELF file, n32 is a new-style ABI.  */
490   if ((header->e_flags & EF_MIPS_ABI2) != 0)
491     return 1;
492 
493   return 0;
494 }
495 
496 static void
set_default_mips_dis_options(struct disassemble_info * info)497 set_default_mips_dis_options (struct disassemble_info *info)
498 {
499   const struct mips_arch_choice *chosen_arch;
500 
501   /* Defaults: mipsIII/r3000 (?!), (o)32-style ("oldabi") GPR names,
502      and numeric FPR, CP0 register, and HWR names.  */
503   mips_isa = ISA_MIPS3;
504   mips_processor =  CPU_R3000;
505   mips_gpr_names = mips_gpr_names_oldabi;
506   mips_fpr_names = mips_fpr_names_numeric;
507   mips_cp0_names = mips_cp0_names_numeric;
508   mips_cp0sel_names = NULL;
509   mips_cp0sel_names_len = 0;
510   mips_hwr_names = mips_hwr_names_numeric;
511   no_aliases = 0;
512 
513   /* If an ELF "newabi" binary, use the n32/(n)64 GPR names.  */
514   if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
515     {
516       Elf_Internal_Ehdr *header;
517 
518       header = elf_elfheader (info->section->owner);
519       if (is_newabi (header))
520 	mips_gpr_names = mips_gpr_names_newabi;
521     }
522 
523   /* Set ISA, architecture, and cp0 register names as best we can.  */
524 #if ! SYMTAB_AVAILABLE
525   /* This is running out on a target machine, not in a host tool.
526      FIXME: Where does mips_target_info come from?  */
527   target_processor = mips_target_info.processor;
528   mips_isa = mips_target_info.isa;
529 #else
530   chosen_arch = choose_arch_by_number (info->mach);
531   if (chosen_arch != NULL)
532     {
533       mips_processor = chosen_arch->processor;
534       mips_isa = chosen_arch->isa;
535       mips_cp0_names = chosen_arch->cp0_names;
536       mips_cp0sel_names = chosen_arch->cp0sel_names;
537       mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
538       mips_hwr_names = chosen_arch->hwr_names;
539     }
540 #endif
541 }
542 
543 static void
parse_mips_dis_option(const char * option,unsigned int len)544 parse_mips_dis_option (const char *option, unsigned int len)
545 {
546   unsigned int i, optionlen, vallen;
547   const char *val;
548   const struct mips_abi_choice *chosen_abi;
549   const struct mips_arch_choice *chosen_arch;
550 
551   /* Try to match options that are simple flags */
552   if (strncmp (option, "no-aliases", 10) == 0)
553     {
554       no_aliases = 1;
555       return;
556     }
557 
558   /* Look for the = that delimits the end of the option name.  */
559   for (i = 0; i < len; i++)
560     if (option[i] == '=')
561       break;
562 
563   if (i == 0)		/* Invalid option: no name before '='.  */
564     return;
565   if (i == len)		/* Invalid option: no '='.  */
566     return;
567   if (i == (len - 1))	/* Invalid option: no value after '='.  */
568     return;
569 
570   optionlen = i;
571   val = option + (optionlen + 1);
572   vallen = len - (optionlen + 1);
573 
574   if (strncmp ("gpr-names", option, optionlen) == 0
575       && strlen ("gpr-names") == optionlen)
576     {
577       chosen_abi = choose_abi_by_name (val, vallen);
578       if (chosen_abi != NULL)
579 	mips_gpr_names = chosen_abi->gpr_names;
580       return;
581     }
582 
583   if (strncmp ("fpr-names", option, optionlen) == 0
584       && strlen ("fpr-names") == optionlen)
585     {
586       chosen_abi = choose_abi_by_name (val, vallen);
587       if (chosen_abi != NULL)
588 	mips_fpr_names = chosen_abi->fpr_names;
589       return;
590     }
591 
592   if (strncmp ("cp0-names", option, optionlen) == 0
593       && strlen ("cp0-names") == optionlen)
594     {
595       chosen_arch = choose_arch_by_name (val, vallen);
596       if (chosen_arch != NULL)
597 	{
598 	  mips_cp0_names = chosen_arch->cp0_names;
599 	  mips_cp0sel_names = chosen_arch->cp0sel_names;
600 	  mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
601 	}
602       return;
603     }
604 
605   if (strncmp ("hwr-names", option, optionlen) == 0
606       && strlen ("hwr-names") == optionlen)
607     {
608       chosen_arch = choose_arch_by_name (val, vallen);
609       if (chosen_arch != NULL)
610 	mips_hwr_names = chosen_arch->hwr_names;
611       return;
612     }
613 
614   if (strncmp ("reg-names", option, optionlen) == 0
615       && strlen ("reg-names") == optionlen)
616     {
617       /* We check both ABI and ARCH here unconditionally, so
618 	 that "numeric" will do the desirable thing: select
619 	 numeric register names for all registers.  Other than
620 	 that, a given name probably won't match both.  */
621       chosen_abi = choose_abi_by_name (val, vallen);
622       if (chosen_abi != NULL)
623 	{
624 	  mips_gpr_names = chosen_abi->gpr_names;
625 	  mips_fpr_names = chosen_abi->fpr_names;
626 	}
627       chosen_arch = choose_arch_by_name (val, vallen);
628       if (chosen_arch != NULL)
629 	{
630 	  mips_cp0_names = chosen_arch->cp0_names;
631 	  mips_cp0sel_names = chosen_arch->cp0sel_names;
632 	  mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
633 	  mips_hwr_names = chosen_arch->hwr_names;
634 	}
635       return;
636     }
637 
638   /* Invalid option.  */
639 }
640 
641 static void
parse_mips_dis_options(const char * options)642 parse_mips_dis_options (const char *options)
643 {
644   const char *option_end;
645 
646   if (options == NULL)
647     return;
648 
649   while (*options != '\0')
650     {
651       /* Skip empty options.  */
652       if (*options == ',')
653 	{
654 	  options++;
655 	  continue;
656 	}
657 
658       /* We know that *options is neither NUL or a comma.  */
659       option_end = options + 1;
660       while (*option_end != ',' && *option_end != '\0')
661 	option_end++;
662 
663       parse_mips_dis_option (options, option_end - options);
664 
665       /* Go on to the next one.  If option_end points to a comma, it
666 	 will be skipped above.  */
667       options = option_end;
668     }
669 }
670 
671 static const struct mips_cp0sel_name *
lookup_mips_cp0sel_name(const struct mips_cp0sel_name * names,unsigned int len,unsigned int cp0reg,unsigned int sel)672 lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
673 			 unsigned int len,
674 			 unsigned int cp0reg,
675 			 unsigned int sel)
676 {
677   unsigned int i;
678 
679   for (i = 0; i < len; i++)
680     if (names[i].cp0reg == cp0reg && names[i].sel == sel)
681       return &names[i];
682   return NULL;
683 }
684 
685 /* Print insn arguments for 32/64-bit code.  */
686 
687 static void
print_insn_args(const char * d,register unsigned long int l,bfd_vma pc,struct disassemble_info * info)688 print_insn_args (const char *d,
689 		 register unsigned long int l,
690 		 bfd_vma pc,
691 		 struct disassemble_info *info)
692 {
693   int op, delta;
694   unsigned int lsb, msb, msbd;
695 
696   lsb = 0;
697 
698   for (; *d != '\0'; d++)
699     {
700       switch (*d)
701 	{
702 	case ',':
703 	case '(':
704 	case ')':
705 	case '[':
706 	case ']':
707 	  (*info->fprintf_func) (info->stream, "%c", *d);
708 	  break;
709 
710 	case '+':
711 	  /* Extension character; switch for second char.  */
712 	  d++;
713 	  switch (*d)
714 	    {
715 	    case '\0':
716 	      /* xgettext:c-format */
717 	      (*info->fprintf_func) (info->stream,
718 				     _("# internal error, incomplete extension sequence (+)"));
719 	      return;
720 
721 	    case 'A':
722 	      lsb = (l >> OP_SH_SHAMT) & OP_MASK_SHAMT;
723 	      (*info->fprintf_func) (info->stream, "0x%x", lsb);
724 	      break;
725 
726 	    case 'B':
727 	      msb = (l >> OP_SH_INSMSB) & OP_MASK_INSMSB;
728 	      (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
729 	      break;
730 
731 	    case 'C':
732 	    case 'H':
733 	      msbd = (l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD;
734 	      (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
735 	      break;
736 
737 	    case 'D':
738 	      {
739 		const struct mips_cp0sel_name *n;
740 		unsigned int cp0reg, sel;
741 
742 		cp0reg = (l >> OP_SH_RD) & OP_MASK_RD;
743 		sel = (l >> OP_SH_SEL) & OP_MASK_SEL;
744 
745 		/* CP0 register including 'sel' code for mtcN (et al.), to be
746 		   printed textually if known.  If not known, print both
747 		   CP0 register name and sel numerically since CP0 register
748 		   with sel 0 may have a name unrelated to register being
749 		   printed.  */
750 		n = lookup_mips_cp0sel_name(mips_cp0sel_names,
751 					    mips_cp0sel_names_len, cp0reg, sel);
752 		if (n != NULL)
753 		  (*info->fprintf_func) (info->stream, "%s", n->name);
754 		else
755 		  (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel);
756 		break;
757 	      }
758 
759 	    case 'E':
760 	      lsb = ((l >> OP_SH_SHAMT) & OP_MASK_SHAMT) + 32;
761 	      (*info->fprintf_func) (info->stream, "0x%x", lsb);
762 	      break;
763 
764 	    case 'F':
765 	      msb = ((l >> OP_SH_INSMSB) & OP_MASK_INSMSB) + 32;
766 	      (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
767 	      break;
768 
769 	    case 'G':
770 	      msbd = ((l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD) + 32;
771 	      (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
772 	      break;
773 
774 	    default:
775 	      /* xgettext:c-format */
776 	      (*info->fprintf_func) (info->stream,
777 				     _("# internal error, undefined extension sequence (+%c)"),
778 				     *d);
779 	      return;
780 	    }
781 	  break;
782 
783 	case 's':
784 	case 'b':
785 	case 'r':
786 	case 'v':
787 	  (*info->fprintf_func) (info->stream, "%s",
788 				 mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]);
789 	  break;
790 
791 	case 't':
792 	case 'w':
793 	  (*info->fprintf_func) (info->stream, "%s",
794 				 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
795 	  break;
796 
797 	case 'i':
798 	case 'u':
799 	  (*info->fprintf_func) (info->stream, "0x%x",
800 				 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
801 	  break;
802 
803 	case 'j': /* Same as i, but sign-extended.  */
804 	case 'o':
805 	  delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
806 	  if (delta & 0x8000)
807 	    delta |= ~0xffff;
808 	  (*info->fprintf_func) (info->stream, "%d",
809 				 delta);
810 	  break;
811 
812 	case 'h':
813 	  (*info->fprintf_func) (info->stream, "0x%x",
814 				 (unsigned int) ((l >> OP_SH_PREFX)
815 						 & OP_MASK_PREFX));
816 	  break;
817 
818 	case 'k':
819 	  (*info->fprintf_func) (info->stream, "0x%x",
820 				 (unsigned int) ((l >> OP_SH_CACHE)
821 						 & OP_MASK_CACHE));
822 	  break;
823 
824 	case 'a':
825 	  info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
826 			  | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2));
827 	  (*info->print_address_func) (info->target, info);
828 	  break;
829 
830 	case 'p':
831 	  /* Sign extend the displacement.  */
832 	  delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
833 	  if (delta & 0x8000)
834 	    delta |= ~0xffff;
835 	  info->target = (delta << 2) + pc + INSNLEN;
836 	  (*info->print_address_func) (info->target, info);
837 	  break;
838 
839 	case 'd':
840 	  (*info->fprintf_func) (info->stream, "%s",
841 				 mips_gpr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
842 	  break;
843 
844 	case 'U':
845 	  {
846 	    /* First check for both rd and rt being equal.  */
847 	    unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD;
848 	    if (reg == ((l >> OP_SH_RT) & OP_MASK_RT))
849 	      (*info->fprintf_func) (info->stream, "%s",
850 				     mips_gpr_names[reg]);
851 	    else
852 	      {
853 		/* If one is zero use the other.  */
854 		if (reg == 0)
855 		  (*info->fprintf_func) (info->stream, "%s",
856 					 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
857 		else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0)
858 		  (*info->fprintf_func) (info->stream, "%s",
859 					 mips_gpr_names[reg]);
860 		else /* Bogus, result depends on processor.  */
861 		  (*info->fprintf_func) (info->stream, "%s or %s",
862 					 mips_gpr_names[reg],
863 					 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
864 	      }
865 	  }
866 	  break;
867 
868 	case 'z':
869 	  (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
870 	  break;
871 
872 	case '<':
873 	  (*info->fprintf_func) (info->stream, "0x%x",
874 				 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
875 	  break;
876 
877 	case 'c':
878 	  (*info->fprintf_func) (info->stream, "0x%x",
879 				 (l >> OP_SH_CODE) & OP_MASK_CODE);
880 	  break;
881 
882 	case 'q':
883 	  (*info->fprintf_func) (info->stream, "0x%x",
884 				 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
885 	  break;
886 
887 	case 'C':
888 	  (*info->fprintf_func) (info->stream, "0x%x",
889 				 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
890 	  break;
891 
892 	case 'B':
893 	  (*info->fprintf_func) (info->stream, "0x%x",
894 				 (l >> OP_SH_CODE20) & OP_MASK_CODE20);
895 	  break;
896 
897 	case 'J':
898 	  (*info->fprintf_func) (info->stream, "0x%x",
899 				 (l >> OP_SH_CODE19) & OP_MASK_CODE19);
900 	  break;
901 
902 	case 'S':
903 	case 'V':
904 	  (*info->fprintf_func) (info->stream, "%s",
905 				 mips_fpr_names[(l >> OP_SH_FS) & OP_MASK_FS]);
906 	  break;
907 
908 	case 'T':
909 	case 'W':
910 	  (*info->fprintf_func) (info->stream, "%s",
911 				 mips_fpr_names[(l >> OP_SH_FT) & OP_MASK_FT]);
912 	  break;
913 
914 	case 'D':
915 	  (*info->fprintf_func) (info->stream, "%s",
916 				 mips_fpr_names[(l >> OP_SH_FD) & OP_MASK_FD]);
917 	  break;
918 
919 	case 'R':
920 	  (*info->fprintf_func) (info->stream, "%s",
921 				 mips_fpr_names[(l >> OP_SH_FR) & OP_MASK_FR]);
922 	  break;
923 
924 	case 'E':
925 	  /* Coprocessor register for lwcN instructions, et al.
926 
927 	     Note that there is no load/store cp0 instructions, and
928 	     that FPU (cp1) instructions disassemble this field using
929 	     'T' format.  Therefore, until we gain understanding of
930 	     cp2 register names, we can simply print the register
931 	     numbers.  */
932 	  (*info->fprintf_func) (info->stream, "$%d",
933 				 (l >> OP_SH_RT) & OP_MASK_RT);
934 	  break;
935 
936 	case 'G':
937 	  /* Coprocessor register for mtcN instructions, et al.  Note
938 	     that FPU (cp1) instructions disassemble this field using
939 	     'S' format.  Therefore, we only need to worry about cp0,
940 	     cp2, and cp3.  */
941 	  op = (l >> OP_SH_OP) & OP_MASK_OP;
942 	  if (op == OP_OP_COP0)
943 	    (*info->fprintf_func) (info->stream, "%s",
944 				   mips_cp0_names[(l >> OP_SH_RD) & OP_MASK_RD]);
945 	  else
946 	    (*info->fprintf_func) (info->stream, "$%d",
947 				   (l >> OP_SH_RD) & OP_MASK_RD);
948 	  break;
949 
950 	case 'K':
951 	  (*info->fprintf_func) (info->stream, "%s",
952 				 mips_hwr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
953 	  break;
954 
955 	case 'N':
956 	  (*info->fprintf_func) (info->stream, "$fcc%d",
957 				 (l >> OP_SH_BCC) & OP_MASK_BCC);
958 	  break;
959 
960 	case 'M':
961 	  (*info->fprintf_func) (info->stream, "$fcc%d",
962 				 (l >> OP_SH_CCC) & OP_MASK_CCC);
963 	  break;
964 
965 	case 'P':
966 	  (*info->fprintf_func) (info->stream, "%d",
967 				 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
968 	  break;
969 
970 	case 'e':
971 	  (*info->fprintf_func) (info->stream, "%d",
972 				 (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE);
973 	  break;
974 
975 	case '%':
976 	  (*info->fprintf_func) (info->stream, "%d",
977 				 (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN);
978 	  break;
979 
980 	case 'H':
981 	  (*info->fprintf_func) (info->stream, "%d",
982 				 (l >> OP_SH_SEL) & OP_MASK_SEL);
983 	  break;
984 
985 	case 'O':
986 	  (*info->fprintf_func) (info->stream, "%d",
987 				 (l >> OP_SH_ALN) & OP_MASK_ALN);
988 	  break;
989 
990 	case 'Q':
991 	  {
992 	    unsigned int vsel = (l >> OP_SH_VSEL) & OP_MASK_VSEL;
993 
994 	    if ((vsel & 0x10) == 0)
995 	      {
996 		int fmt;
997 
998 		vsel &= 0x0f;
999 		for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1000 		  if ((vsel & 1) == 0)
1001 		    break;
1002 		(*info->fprintf_func) (info->stream, "$v%d[%d]",
1003 				       (l >> OP_SH_FT) & OP_MASK_FT,
1004 				       vsel >> 1);
1005 	      }
1006 	    else if ((vsel & 0x08) == 0)
1007 	      {
1008 		(*info->fprintf_func) (info->stream, "$v%d",
1009 				       (l >> OP_SH_FT) & OP_MASK_FT);
1010 	      }
1011 	    else
1012 	      {
1013 		(*info->fprintf_func) (info->stream, "0x%x",
1014 				       (l >> OP_SH_FT) & OP_MASK_FT);
1015 	      }
1016 	  }
1017 	  break;
1018 
1019 	case 'X':
1020 	  (*info->fprintf_func) (info->stream, "$v%d",
1021 				 (l >> OP_SH_FD) & OP_MASK_FD);
1022 	  break;
1023 
1024 	case 'Y':
1025 	  (*info->fprintf_func) (info->stream, "$v%d",
1026 				 (l >> OP_SH_FS) & OP_MASK_FS);
1027 	  break;
1028 
1029 	case 'Z':
1030 	  (*info->fprintf_func) (info->stream, "$v%d",
1031 				 (l >> OP_SH_FT) & OP_MASK_FT);
1032 	  break;
1033 
1034 	default:
1035 	  /* xgettext:c-format */
1036 	  (*info->fprintf_func) (info->stream,
1037 				 _("# internal error, undefined modifier(%c)"),
1038 				 *d);
1039 	  return;
1040 	}
1041     }
1042 }
1043 
1044 /* Print the mips instruction at address MEMADDR in debugged memory,
1045    on using INFO.  Returns length of the instruction, in bytes, which is
1046    always INSNLEN.  BIGENDIAN must be 1 if this is big-endian code, 0 if
1047    this is little-endian code.  */
1048 
1049 static int
print_insn_mips(bfd_vma memaddr,unsigned long int word,struct disassemble_info * info)1050 print_insn_mips (bfd_vma memaddr,
1051 		 unsigned long int word,
1052 		 struct disassemble_info *info)
1053 {
1054   const struct mips_opcode *op;
1055   static bfd_boolean init = 0;
1056   static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1057 
1058   /* Build a hash table to shorten the search time.  */
1059   if (! init)
1060     {
1061       unsigned int i;
1062 
1063       for (i = 0; i <= OP_MASK_OP; i++)
1064 	{
1065 	  for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1066 	    {
1067 	      if (op->pinfo == INSN_MACRO
1068 		  || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
1069 		continue;
1070 	      if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
1071 		{
1072 		  mips_hash[i] = op;
1073 		  break;
1074 		}
1075 	    }
1076 	}
1077 
1078       init = 1;
1079     }
1080 
1081   info->bytes_per_chunk = INSNLEN;
1082   info->display_endian = info->endian;
1083   info->insn_info_valid = 1;
1084   info->branch_delay_insns = 0;
1085   info->data_size = 0;
1086   info->insn_type = dis_nonbranch;
1087   info->target = 0;
1088   info->target2 = 0;
1089 
1090   op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
1091   if (op != NULL)
1092     {
1093       for (; op < &mips_opcodes[NUMOPCODES]; op++)
1094 	{
1095 	  if (op->pinfo != INSN_MACRO
1096 	      && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1097 	      && (word & op->mask) == op->match)
1098 	    {
1099 	      const char *d;
1100 
1101 	      /* We always allow to disassemble the jalx instruction.  */
1102 	      if (! OPCODE_IS_MEMBER (op, mips_isa, mips_processor)
1103 		  && strcmp (op->name, "jalx"))
1104 		continue;
1105 
1106 	      /* Figure out instruction type and branch delay information.  */
1107 	      if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1108 	        {
1109 		  if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
1110 		    info->insn_type = dis_jsr;
1111 		  else
1112 		    info->insn_type = dis_branch;
1113 		  info->branch_delay_insns = 1;
1114 		}
1115 	      else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1116 				     | INSN_COND_BRANCH_LIKELY)) != 0)
1117 		{
1118 		  if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
1119 		    info->insn_type = dis_condjsr;
1120 		  else
1121 		    info->insn_type = dis_condbranch;
1122 		  info->branch_delay_insns = 1;
1123 		}
1124 	      else if ((op->pinfo & (INSN_STORE_MEMORY
1125 				     | INSN_LOAD_MEMORY_DELAY)) != 0)
1126 		info->insn_type = dis_dref;
1127 
1128 	      (*info->fprintf_func) (info->stream, "%s", op->name);
1129 
1130 	      d = op->args;
1131 	      if (d != NULL && *d != '\0')
1132 		{
1133 		  (*info->fprintf_func) (info->stream, "\t");
1134 		  print_insn_args (d, word, memaddr, info);
1135 		}
1136 
1137 	      return INSNLEN;
1138 	    }
1139 	}
1140     }
1141 
1142   /* Handle undefined instructions.  */
1143   info->insn_type = dis_noninsn;
1144   (*info->fprintf_func) (info->stream, "0x%x", word);
1145   return INSNLEN;
1146 }
1147 
1148 /* Disassemble an operand for a mips16 instruction.  */
1149 
1150 static void
print_mips16_insn_arg(char type,const struct mips_opcode * op,int l,bfd_boolean use_extend,int extend,bfd_vma memaddr,struct disassemble_info * info)1151 print_mips16_insn_arg (char type,
1152 		       const struct mips_opcode *op,
1153 		       int l,
1154 		       bfd_boolean use_extend,
1155 		       int extend,
1156 		       bfd_vma memaddr,
1157 		       struct disassemble_info *info)
1158 {
1159   switch (type)
1160     {
1161     case ',':
1162     case '(':
1163     case ')':
1164       (*info->fprintf_func) (info->stream, "%c", type);
1165       break;
1166 
1167     case 'y':
1168     case 'w':
1169       (*info->fprintf_func) (info->stream, "%s",
1170 			     mips16_reg_names[((l >> MIPS16OP_SH_RY)
1171 					       & MIPS16OP_MASK_RY)]);
1172       break;
1173 
1174     case 'x':
1175     case 'v':
1176       (*info->fprintf_func) (info->stream, "%s",
1177 			     mips16_reg_names[((l >> MIPS16OP_SH_RX)
1178 					       & MIPS16OP_MASK_RX)]);
1179       break;
1180 
1181     case 'z':
1182       (*info->fprintf_func) (info->stream, "%s",
1183 			     mips16_reg_names[((l >> MIPS16OP_SH_RZ)
1184 					       & MIPS16OP_MASK_RZ)]);
1185       break;
1186 
1187     case 'Z':
1188       (*info->fprintf_func) (info->stream, "%s",
1189 			     mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
1190 					       & MIPS16OP_MASK_MOVE32Z)]);
1191       break;
1192 
1193     case '0':
1194       (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
1195       break;
1196 
1197     case 'S':
1198       (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[29]);
1199       break;
1200 
1201     case 'P':
1202       (*info->fprintf_func) (info->stream, "$pc");
1203       break;
1204 
1205     case 'R':
1206       (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[31]);
1207       break;
1208 
1209     case 'X':
1210       (*info->fprintf_func) (info->stream, "%s",
1211 			     mips_gpr_names[((l >> MIPS16OP_SH_REGR32)
1212 					    & MIPS16OP_MASK_REGR32)]);
1213       break;
1214 
1215     case 'Y':
1216       (*info->fprintf_func) (info->stream, "%s",
1217 			     mips_gpr_names[MIPS16OP_EXTRACT_REG32R (l)]);
1218       break;
1219 
1220     case '<':
1221     case '>':
1222     case '[':
1223     case ']':
1224     case '4':
1225     case '5':
1226     case 'H':
1227     case 'W':
1228     case 'D':
1229     case 'j':
1230     case '6':
1231     case '8':
1232     case 'V':
1233     case 'C':
1234     case 'U':
1235     case 'k':
1236     case 'K':
1237     case 'p':
1238     case 'q':
1239     case 'A':
1240     case 'B':
1241     case 'E':
1242       {
1243 	int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
1244 
1245 	shift = 0;
1246 	signedp = 0;
1247 	extbits = 16;
1248 	pcrel = 0;
1249 	extu = 0;
1250 	branch = 0;
1251 	switch (type)
1252 	  {
1253 	  case '<':
1254 	    nbits = 3;
1255 	    immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
1256 	    extbits = 5;
1257 	    extu = 1;
1258 	    break;
1259 	  case '>':
1260 	    nbits = 3;
1261 	    immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
1262 	    extbits = 5;
1263 	    extu = 1;
1264 	    break;
1265 	  case '[':
1266 	    nbits = 3;
1267 	    immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
1268 	    extbits = 6;
1269 	    extu = 1;
1270 	    break;
1271 	  case ']':
1272 	    nbits = 3;
1273 	    immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
1274 	    extbits = 6;
1275 	    extu = 1;
1276 	    break;
1277 	  case '4':
1278 	    nbits = 4;
1279 	    immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
1280 	    signedp = 1;
1281 	    extbits = 15;
1282 	    break;
1283 	  case '5':
1284 	    nbits = 5;
1285 	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1286 	    info->insn_type = dis_dref;
1287 	    info->data_size = 1;
1288 	    break;
1289 	  case 'H':
1290 	    nbits = 5;
1291 	    shift = 1;
1292 	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1293 	    info->insn_type = dis_dref;
1294 	    info->data_size = 2;
1295 	    break;
1296 	  case 'W':
1297 	    nbits = 5;
1298 	    shift = 2;
1299 	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1300 	    if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
1301 		&& (op->pinfo & MIPS16_INSN_READ_SP) == 0)
1302 	      {
1303 		info->insn_type = dis_dref;
1304 		info->data_size = 4;
1305 	      }
1306 	    break;
1307 	  case 'D':
1308 	    nbits = 5;
1309 	    shift = 3;
1310 	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1311 	    info->insn_type = dis_dref;
1312 	    info->data_size = 8;
1313 	    break;
1314 	  case 'j':
1315 	    nbits = 5;
1316 	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1317 	    signedp = 1;
1318 	    break;
1319 	  case '6':
1320 	    nbits = 6;
1321 	    immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1322 	    break;
1323 	  case '8':
1324 	    nbits = 8;
1325 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1326 	    break;
1327 	  case 'V':
1328 	    nbits = 8;
1329 	    shift = 2;
1330 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1331 	    /* FIXME: This might be lw, or it might be addiu to $sp or
1332                $pc.  We assume it's load.  */
1333 	    info->insn_type = dis_dref;
1334 	    info->data_size = 4;
1335 	    break;
1336 	  case 'C':
1337 	    nbits = 8;
1338 	    shift = 3;
1339 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1340 	    info->insn_type = dis_dref;
1341 	    info->data_size = 8;
1342 	    break;
1343 	  case 'U':
1344 	    nbits = 8;
1345 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1346 	    extu = 1;
1347 	    break;
1348 	  case 'k':
1349 	    nbits = 8;
1350 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1351 	    signedp = 1;
1352 	    break;
1353 	  case 'K':
1354 	    nbits = 8;
1355 	    shift = 3;
1356 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1357 	    signedp = 1;
1358 	    break;
1359 	  case 'p':
1360 	    nbits = 8;
1361 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1362 	    signedp = 1;
1363 	    pcrel = 1;
1364 	    branch = 1;
1365 	    info->insn_type = dis_condbranch;
1366 	    break;
1367 	  case 'q':
1368 	    nbits = 11;
1369 	    immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
1370 	    signedp = 1;
1371 	    pcrel = 1;
1372 	    branch = 1;
1373 	    info->insn_type = dis_branch;
1374 	    break;
1375 	  case 'A':
1376 	    nbits = 8;
1377 	    shift = 2;
1378 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1379 	    pcrel = 1;
1380 	    /* FIXME: This can be lw or la.  We assume it is lw.  */
1381 	    info->insn_type = dis_dref;
1382 	    info->data_size = 4;
1383 	    break;
1384 	  case 'B':
1385 	    nbits = 5;
1386 	    shift = 3;
1387 	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1388 	    pcrel = 1;
1389 	    info->insn_type = dis_dref;
1390 	    info->data_size = 8;
1391 	    break;
1392 	  case 'E':
1393 	    nbits = 5;
1394 	    shift = 2;
1395 	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1396 	    pcrel = 1;
1397 	    break;
1398 	  default:
1399 	    abort ();
1400 	  }
1401 
1402 	if (! use_extend)
1403 	  {
1404 	    if (signedp && immed >= (1 << (nbits - 1)))
1405 	      immed -= 1 << nbits;
1406 	    immed <<= shift;
1407 	    if ((type == '<' || type == '>' || type == '[' || type == ']')
1408 		&& immed == 0)
1409 	      immed = 8;
1410 	  }
1411 	else
1412 	  {
1413 	    if (extbits == 16)
1414 	      immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1415 	    else if (extbits == 15)
1416 	      immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1417 	    else
1418 	      immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1419 	    immed &= (1 << extbits) - 1;
1420 	    if (! extu && immed >= (1 << (extbits - 1)))
1421 	      immed -= 1 << extbits;
1422 	  }
1423 
1424 	if (! pcrel)
1425 	  (*info->fprintf_func) (info->stream, "%d", immed);
1426 	else
1427 	  {
1428 	    bfd_vma baseaddr;
1429 
1430 	    if (branch)
1431 	      {
1432 		immed *= 2;
1433 		baseaddr = memaddr + 2;
1434 	      }
1435 	    else if (use_extend)
1436 	      baseaddr = memaddr - 2;
1437 	    else
1438 	      {
1439 		int status;
1440 		bfd_byte buffer[2];
1441 
1442 		baseaddr = memaddr;
1443 
1444 		/* If this instruction is in the delay slot of a jr
1445                    instruction, the base address is the address of the
1446                    jr instruction.  If it is in the delay slot of jalr
1447                    instruction, the base address is the address of the
1448                    jalr instruction.  This test is unreliable: we have
1449                    no way of knowing whether the previous word is
1450                    instruction or data.  */
1451 		status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1452 						    info);
1453 		if (status == 0
1454 		    && (((info->endian == BFD_ENDIAN_BIG
1455 			  ? bfd_getb16 (buffer)
1456 			  : bfd_getl16 (buffer))
1457 			 & 0xf800) == 0x1800))
1458 		  baseaddr = memaddr - 4;
1459 		else
1460 		  {
1461 		    status = (*info->read_memory_func) (memaddr - 2, buffer,
1462 							2, info);
1463 		    if (status == 0
1464 			&& (((info->endian == BFD_ENDIAN_BIG
1465 			      ? bfd_getb16 (buffer)
1466 			      : bfd_getl16 (buffer))
1467 			     & 0xf81f) == 0xe800))
1468 		      baseaddr = memaddr - 2;
1469 		  }
1470 	      }
1471 	    info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
1472 	    (*info->print_address_func) (info->target, info);
1473 	  }
1474       }
1475       break;
1476 
1477     case 'a':
1478       if (! use_extend)
1479 	extend = 0;
1480       l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1481       info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
1482       (*info->print_address_func) (info->target, info);
1483       info->insn_type = dis_jsr;
1484       info->branch_delay_insns = 1;
1485       break;
1486 
1487     case 'l':
1488     case 'L':
1489       {
1490 	int need_comma, amask, smask;
1491 
1492 	need_comma = 0;
1493 
1494 	l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1495 
1496 	amask = (l >> 3) & 7;
1497 
1498 	if (amask > 0 && amask < 5)
1499 	  {
1500 	    (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]);
1501 	    if (amask > 1)
1502 	      (*info->fprintf_func) (info->stream, "-%s",
1503 				     mips_gpr_names[amask + 3]);
1504 	    need_comma = 1;
1505 	  }
1506 
1507 	smask = (l >> 1) & 3;
1508 	if (smask == 3)
1509 	  {
1510 	    (*info->fprintf_func) (info->stream, "%s??",
1511 				   need_comma ? "," : "");
1512 	    need_comma = 1;
1513 	  }
1514 	else if (smask > 0)
1515 	  {
1516 	    (*info->fprintf_func) (info->stream, "%s%s",
1517 				   need_comma ? "," : "",
1518 				   mips_gpr_names[16]);
1519 	    if (smask > 1)
1520 	      (*info->fprintf_func) (info->stream, "-%s",
1521 				     mips_gpr_names[smask + 15]);
1522 	    need_comma = 1;
1523 	  }
1524 
1525 	if (l & 1)
1526 	  {
1527 	    (*info->fprintf_func) (info->stream, "%s%s",
1528 				   need_comma ? "," : "",
1529 				   mips_gpr_names[31]);
1530 	    need_comma = 1;
1531 	  }
1532 
1533 	if (amask == 5 || amask == 6)
1534 	  {
1535 	    (*info->fprintf_func) (info->stream, "%s$f0",
1536 				   need_comma ? "," : "");
1537 	    if (amask == 6)
1538 	      (*info->fprintf_func) (info->stream, "-$f1");
1539 	  }
1540       }
1541       break;
1542 
1543     default:
1544       /* xgettext:c-format */
1545       (*info->fprintf_func)
1546 	(info->stream,
1547 	 _("# internal disassembler error, unrecognised modifier (%c)"),
1548 	 type);
1549       abort ();
1550     }
1551 }
1552 
1553 /* Disassemble mips16 instructions.  */
1554 
1555 static int
print_insn_mips16(bfd_vma memaddr,struct disassemble_info * info)1556 print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
1557 {
1558   int status;
1559   bfd_byte buffer[2];
1560   int length;
1561   int insn;
1562   bfd_boolean use_extend;
1563   int extend = 0;
1564   const struct mips_opcode *op, *opend;
1565 
1566   info->bytes_per_chunk = 2;
1567   info->display_endian = info->endian;
1568   info->insn_info_valid = 1;
1569   info->branch_delay_insns = 0;
1570   info->data_size = 0;
1571   info->insn_type = dis_nonbranch;
1572   info->target = 0;
1573   info->target2 = 0;
1574 
1575   status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1576   if (status != 0)
1577     {
1578       (*info->memory_error_func) (status, memaddr, info);
1579       return -1;
1580     }
1581 
1582   length = 2;
1583 
1584   if (info->endian == BFD_ENDIAN_BIG)
1585     insn = bfd_getb16 (buffer);
1586   else
1587     insn = bfd_getl16 (buffer);
1588 
1589   /* Handle the extend opcode specially.  */
1590   use_extend = FALSE;
1591   if ((insn & 0xf800) == 0xf000)
1592     {
1593       use_extend = TRUE;
1594       extend = insn & 0x7ff;
1595 
1596       memaddr += 2;
1597 
1598       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1599       if (status != 0)
1600 	{
1601 	  (*info->fprintf_func) (info->stream, "extend 0x%x",
1602 				 (unsigned int) extend);
1603 	  (*info->memory_error_func) (status, memaddr, info);
1604 	  return -1;
1605 	}
1606 
1607       if (info->endian == BFD_ENDIAN_BIG)
1608 	insn = bfd_getb16 (buffer);
1609       else
1610 	insn = bfd_getl16 (buffer);
1611 
1612       /* Check for an extend opcode followed by an extend opcode.  */
1613       if ((insn & 0xf800) == 0xf000)
1614 	{
1615 	  (*info->fprintf_func) (info->stream, "extend 0x%x",
1616 				 (unsigned int) extend);
1617 	  info->insn_type = dis_noninsn;
1618 	  return length;
1619 	}
1620 
1621       length += 2;
1622     }
1623 
1624   /* FIXME: Should probably use a hash table on the major opcode here.  */
1625 
1626   opend = mips16_opcodes + bfd_mips16_num_opcodes;
1627   for (op = mips16_opcodes; op < opend; op++)
1628     {
1629       if (op->pinfo != INSN_MACRO
1630 	  && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1631 	  && (insn & op->mask) == op->match)
1632 	{
1633 	  const char *s;
1634 
1635 	  if (strchr (op->args, 'a') != NULL)
1636 	    {
1637 	      if (use_extend)
1638 		{
1639 		  (*info->fprintf_func) (info->stream, "extend 0x%x",
1640 					 (unsigned int) extend);
1641 		  info->insn_type = dis_noninsn;
1642 		  return length - 2;
1643 		}
1644 
1645 	      use_extend = FALSE;
1646 
1647 	      memaddr += 2;
1648 
1649 	      status = (*info->read_memory_func) (memaddr, buffer, 2,
1650 						  info);
1651 	      if (status == 0)
1652 		{
1653 		  use_extend = TRUE;
1654 		  if (info->endian == BFD_ENDIAN_BIG)
1655 		    extend = bfd_getb16 (buffer);
1656 		  else
1657 		    extend = bfd_getl16 (buffer);
1658 		  length += 2;
1659 		}
1660 	    }
1661 
1662 	  (*info->fprintf_func) (info->stream, "%s", op->name);
1663 	  if (op->args[0] != '\0')
1664 	    (*info->fprintf_func) (info->stream, "\t");
1665 
1666 	  for (s = op->args; *s != '\0'; s++)
1667 	    {
1668 	      if (*s == ','
1669 		  && s[1] == 'w'
1670 		  && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
1671 		      == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
1672 		{
1673 		  /* Skip the register and the comma.  */
1674 		  ++s;
1675 		  continue;
1676 		}
1677 	      if (*s == ','
1678 		  && s[1] == 'v'
1679 		  && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
1680 		      == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
1681 		{
1682 		  /* Skip the register and the comma.  */
1683 		  ++s;
1684 		  continue;
1685 		}
1686 	      print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
1687 				     info);
1688 	    }
1689 
1690 	  if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1691 	    {
1692 	      info->branch_delay_insns = 1;
1693 	      if (info->insn_type != dis_jsr)
1694 		info->insn_type = dis_branch;
1695 	    }
1696 
1697 	  return length;
1698 	}
1699     }
1700 
1701   if (use_extend)
1702     (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
1703   (*info->fprintf_func) (info->stream, "0x%x", insn);
1704   info->insn_type = dis_noninsn;
1705 
1706   return length;
1707 }
1708 
1709 /* In an environment where we do not know the symbol type of the
1710    instruction we are forced to assume that the low order bit of the
1711    instructions' address may mark it as a mips16 instruction.  If we
1712    are single stepping, or the pc is within the disassembled function,
1713    this works.  Otherwise, we need a clue.  Sometimes.  */
1714 
1715 static int
_print_insn_mips(bfd_vma memaddr,struct disassemble_info * info,enum bfd_endian endianness)1716 _print_insn_mips (bfd_vma memaddr,
1717 		  struct disassemble_info *info,
1718 		  enum bfd_endian endianness)
1719 {
1720   bfd_byte buffer[INSNLEN];
1721   int status;
1722 
1723   set_default_mips_dis_options (info);
1724   parse_mips_dis_options (info->disassembler_options);
1725 
1726 #if 1
1727   /* FIXME: If odd address, this is CLEARLY a mips 16 instruction.  */
1728   /* Only a few tools will work this way.  */
1729   if (memaddr & 0x01)
1730     return print_insn_mips16 (memaddr, info);
1731 #endif
1732 
1733 #if SYMTAB_AVAILABLE
1734   if (info->mach == bfd_mach_mips16
1735       || (info->flavour == bfd_target_elf_flavour
1736 	  && info->symbols != NULL
1737 	  && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
1738 	      == STO_MIPS16)))
1739     return print_insn_mips16 (memaddr, info);
1740 #endif
1741 
1742   status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
1743   if (status == 0)
1744     {
1745       unsigned long insn;
1746 
1747       if (endianness == BFD_ENDIAN_BIG)
1748 	insn = (unsigned long) bfd_getb32 (buffer);
1749       else
1750 	insn = (unsigned long) bfd_getl32 (buffer);
1751 
1752       return print_insn_mips (memaddr, insn, info);
1753     }
1754   else
1755     {
1756       (*info->memory_error_func) (status, memaddr, info);
1757       return -1;
1758     }
1759 }
1760 
1761 int
print_insn_big_mips(bfd_vma memaddr,struct disassemble_info * info)1762 print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
1763 {
1764   return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
1765 }
1766 
1767 int
print_insn_little_mips(bfd_vma memaddr,struct disassemble_info * info)1768 print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
1769 {
1770   return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
1771 }
1772 
1773 void
print_mips_disassembler_options(FILE * stream)1774 print_mips_disassembler_options (FILE *stream)
1775 {
1776   unsigned int i;
1777 
1778   fprintf (stream, _("\n\
1779 The following MIPS specific disassembler options are supported for use\n\
1780 with the -M switch (multiple options should be separated by commas):\n"));
1781 
1782   fprintf (stream, _("\n\
1783   gpr-names=ABI            Print GPR names according to  specified ABI.\n\
1784                            Default: based on binary being disassembled.\n"));
1785 
1786   fprintf (stream, _("\n\
1787   fpr-names=ABI            Print FPR names according to specified ABI.\n\
1788                            Default: numeric.\n"));
1789 
1790   fprintf (stream, _("\n\
1791   cp0-names=ARCH           Print CP0 register names according to\n\
1792                            specified architecture.\n\
1793                            Default: based on binary being disassembled.\n"));
1794 
1795   fprintf (stream, _("\n\
1796   hwr-names=ARCH           Print HWR names according to specified \n\
1797 			   architecture.\n\
1798                            Default: based on binary being disassembled.\n"));
1799 
1800   fprintf (stream, _("\n\
1801   reg-names=ABI            Print GPR and FPR names according to\n\
1802                            specified ABI.\n"));
1803 
1804   fprintf (stream, _("\n\
1805   reg-names=ARCH           Print CP0 register and HWR names according to\n\
1806                            specified architecture.\n"));
1807 
1808   fprintf (stream, _("\n\
1809   For the options above, the following values are supported for \"ABI\":\n\
1810    "));
1811   for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
1812     fprintf (stream, " %s", mips_abi_choices[i].name);
1813   fprintf (stream, _("\n"));
1814 
1815   fprintf (stream, _("\n\
1816   For the options above, The following values are supported for \"ARCH\":\n\
1817    "));
1818   for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
1819     if (*mips_arch_choices[i].name != '\0')
1820       fprintf (stream, " %s", mips_arch_choices[i].name);
1821   fprintf (stream, _("\n"));
1822 
1823   fprintf (stream, _("\n"));
1824 }
1825