Coverage Report

Created: 2025-06-24 06:45

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