Coverage Report

Created: 2023-08-28 06:31

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