Coverage Report

Created: 2024-05-21 06:29

/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-2024 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.58M
#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
78.5k
{
741
78.5k
  const struct mips_abi_choice *c;
742
78.5k
  unsigned int i;
743
744
391k
  for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
745
313k
    if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
746
313k
  && strlen (mips_abi_choices[i].name) == namelen)
747
1.17k
      c = &mips_abi_choices[i];
748
749
78.5k
  return c;
750
78.5k
}
751
752
static const struct mips_arch_choice *
753
choose_arch_by_name (const char *name, unsigned int namelen)
754
69.9k
{
755
69.9k
  const struct mips_arch_choice *c = NULL;
756
69.9k
  unsigned int i;
757
758
3.61M
  for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
759
3.54M
    if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
760
3.54M
  && strlen (mips_arch_choices[i].name) == namelen)
761
10.8k
      c = &mips_arch_choices[i];
762
763
69.9k
  return c;
764
69.9k
}
765
766
static const struct mips_arch_choice *
767
choose_arch_by_number (unsigned long mach)
768
1.76M
{
769
1.76M
  static unsigned long hint_bfd_mach;
770
1.76M
  static const struct mips_arch_choice *hint_arch_choice;
771
1.76M
  const struct mips_arch_choice *c;
772
1.76M
  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.76M
  if (hint_bfd_mach == mach
777
1.76M
      && hint_arch_choice != NULL
778
1.76M
      && hint_arch_choice->bfd_mach == hint_bfd_mach)
779
1.56M
    return hint_arch_choice;
780
781
10.5M
  for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
782
10.3M
    {
783
10.3M
      if (mips_arch_choices[i].bfd_mach_valid
784
10.3M
    && mips_arch_choices[i].bfd_mach == mach)
785
2.01k
  {
786
2.01k
    c = &mips_arch_choices[i];
787
2.01k
    hint_bfd_mach = mach;
788
2.01k
    hint_arch_choice = c;
789
2.01k
  }
790
10.3M
    }
791
203k
  return c;
792
1.76M
}
793
794
/* Check if the object uses NewABI conventions.  */
795
796
static int
797
is_newabi (Elf_Internal_Ehdr *header)
798
604k
{
799
  /* There are no old-style ABIs which use 64-bit ELF.  */
800
604k
  if (header->e_ident[EI_CLASS] == ELFCLASS64)
801
230k
    return 1;
802
803
  /* If a 32-bit ELF file, n32 is a new-style ABI.  */
804
373k
  if ((header->e_flags & EF_MIPS_ABI2) != 0)
805
1.65k
    return 1;
806
807
371k
  return 0;
808
373k
}
809
810
/* Check if the object has microMIPS ASE code.  */
811
812
static int
813
is_micromips (Elf_Internal_Ehdr *header)
814
604k
{
815
604k
  if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
816
136k
    return 1;
817
818
468k
  return 0;
819
604k
}
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
1.90M
{
862
1.90M
  unsigned long combination_ases = 0;
863
864
1.90M
  if ((opcode_ases & (ASE_XPA | ASE_VIRT)) == (ASE_XPA | ASE_VIRT))
865
119k
    combination_ases |= ASE_XPA_VIRT;
866
1.90M
  if ((opcode_ases & (ASE_MIPS16E2 | ASE_MT)) == (ASE_MIPS16E2 | ASE_MT))
867
16.0k
    combination_ases |= ASE_MIPS16E2_MT;
868
1.90M
  if ((opcode_ases & ASE_EVA)
869
1.90M
      && ((opcode_isa & INSN_ISA_MASK) == ISA_MIPS64R6
870
135k
    || (opcode_isa & INSN_ISA_MASK) == ISA_MIPS32R6))
871
91.4k
    combination_ases |= ASE_EVA_R6;
872
1.90M
  return combination_ases;
873
1.90M
}
874
875
static void
876
set_default_mips_dis_options (struct disassemble_info *info)
877
1.76M
{
878
1.76M
  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.76M
  mips_isa = ISA_MIPS3;
884
1.76M
  mips_processor = CPU_R3000;
885
1.76M
  micromips_ase = 0;
886
1.76M
  mips_ase = 0;
887
1.76M
  mips_gpr_names = mips_gpr_names_oldabi;
888
1.76M
  mips_fpr_names = mips_fpr_names_numeric;
889
1.76M
  mips_cp0_names = mips_cp0_names_numeric;
890
1.76M
  mips_cp0sel_names = NULL;
891
1.76M
  mips_cp0sel_names_len = 0;
892
1.76M
  mips_cp1_names = mips_cp1_names_numeric;
893
1.76M
  mips_hwr_names = mips_hwr_names_numeric;
894
1.76M
  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.76M
  chosen_arch = choose_arch_by_number (info->mach);
905
1.76M
  if (chosen_arch != NULL)
906
1.56M
    {
907
1.56M
      mips_processor = chosen_arch->processor;
908
1.56M
      mips_isa = chosen_arch->isa;
909
1.56M
      mips_ase = chosen_arch->ase;
910
1.56M
      mips_cp0_names = chosen_arch->cp0_names;
911
1.56M
      mips_cp0sel_names = chosen_arch->cp0sel_names;
912
1.56M
      mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
913
1.56M
      mips_cp1_names = chosen_arch->cp1_names;
914
1.56M
      mips_hwr_names = chosen_arch->hwr_names;
915
1.56M
    }
916
917
  /* Update settings according to the ELF file header flags.  */
918
1.76M
  if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
919
604k
    {
920
604k
      struct bfd *abfd = info->section->owner;
921
604k
      Elf_Internal_Ehdr *header = elf_elfheader (abfd);
922
604k
      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
604k
#ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
930
604k
      abiflags = bfd_mips_elf_get_abiflags (abfd);
931
604k
#endif
932
      /* If an ELF "newabi" binary, use the n32/(n)64 GPR names.  */
933
604k
      if (is_newabi (header))
934
232k
  mips_gpr_names = mips_gpr_names_newabi;
935
      /* If a microMIPS binary, then don't use MIPS16 bindings.  */
936
604k
      micromips_ase = is_micromips (header);
937
      /* OR in any extra ASE flags set in ELF file structures.  */
938
604k
      if (abiflags)
939
0
  mips_ase |= mips_convert_abiflags_ases (abiflags->ases);
940
604k
      else if (header->e_flags & EF_MIPS_ARCH_ASE_MDMX)
941
134k
  mips_ase |= ASE_MDMX;
942
604k
    }
943
1.76M
#endif
944
1.76M
  mips_ase |= mips_calculate_combination_ases (mips_isa, mips_ase);
945
1.76M
}
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
684k
{
953
684k
  if (startswith (option, "msa"))
954
47.6k
    {
955
47.6k
      mips_ase |= ASE_MSA;
956
47.6k
      if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
957
47.6k
     || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
958
47.6k
     || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
959
47.6k
     || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
960
1.53k
    mips_ase |= ASE_MSA64;
961
47.6k
      return true;
962
47.6k
    }
963
964
636k
  if (startswith (option, "virt"))
965
48.4k
    {
966
48.4k
      mips_ase |= ASE_VIRT;
967
48.4k
      if (mips_isa & ISA_MIPS64R2
968
48.4k
    || mips_isa & ISA_MIPS64R3
969
48.4k
    || mips_isa & ISA_MIPS64R5
970
48.4k
    || mips_isa & ISA_MIPS64R6)
971
48.4k
  mips_ase |= ASE_VIRT64;
972
48.4k
      return true;
973
48.4k
    }
974
975
588k
  if (startswith (option, "xpa"))
976
5.69k
    {
977
5.69k
      mips_ase |= ASE_XPA;
978
5.69k
      return true;
979
5.69k
    }
980
981
582k
  if (startswith (option, "ginv"))
982
11.3k
    {
983
11.3k
      mips_ase |= ASE_GINV;
984
11.3k
      return true;
985
11.3k
    }
986
987
571k
  if (startswith (option, "loongson-mmi"))
988
1.10k
    {
989
1.10k
      mips_ase |= ASE_LOONGSON_MMI;
990
1.10k
      return true;
991
1.10k
    }
992
993
569k
  if (startswith (option, "loongson-cam"))
994
16.1k
    {
995
16.1k
      mips_ase |= ASE_LOONGSON_CAM;
996
16.1k
      return true;
997
16.1k
    }
998
  
999
  /* Put here for match ext2 frist */
1000
553k
  if (startswith (option, "loongson-ext2"))
1001
1.05k
    {
1002
1.05k
      mips_ase |= ASE_LOONGSON_EXT2;
1003
1.05k
      return true;
1004
1.05k
    }
1005
1006
552k
  if (startswith (option, "loongson-ext"))
1007
2.38k
    {
1008
2.38k
      mips_ase |= ASE_LOONGSON_EXT;
1009
2.38k
      return true;
1010
2.38k
    }
1011
1012
550k
  return false;
1013
552k
}
1014
1015
static void
1016
parse_mips_dis_option (const char *option, unsigned int len)
1017
688k
{
1018
688k
  unsigned int i, optionlen, vallen;
1019
688k
  const char *val;
1020
688k
  const struct mips_abi_choice *chosen_abi;
1021
688k
  const struct mips_arch_choice *chosen_arch;
1022
1023
  /* Try to match options that are simple flags */
1024
688k
  if (startswith (option, "no-aliases"))
1025
4.53k
    {
1026
4.53k
      no_aliases = 1;
1027
4.53k
      return;
1028
4.53k
    }
1029
1030
684k
  if (parse_mips_ase_option (option))
1031
133k
    {
1032
133k
      mips_ase |= mips_calculate_combination_ases (mips_isa, mips_ase);
1033
133k
      return;
1034
133k
    }
1035
1036
  /* Look for the = that delimits the end of the option name.  */
1037
7.08M
  for (i = 0; i < len; i++)
1038
6.72M
    if (option[i] == '=')
1039
195k
      break;
1040
1041
550k
  if (i == 0)    /* Invalid option: no name before '='.  */
1042
1.20k
    return;
1043
549k
  if (i == len)    /* Invalid option: no '='.  */
1044
354k
    return;
1045
194k
  if (i == (len - 1))  /* Invalid option: no value after '='.  */
1046
3.13k
    return;
1047
1048
191k
  optionlen = i;
1049
191k
  val = option + (optionlen + 1);
1050
191k
  vallen = len - (optionlen + 1);
1051
1052
191k
  if (strncmp ("gpr-names", option, optionlen) == 0
1053
191k
      && strlen ("gpr-names") == optionlen)
1054
13.3k
    {
1055
13.3k
      chosen_abi = choose_abi_by_name (val, vallen);
1056
13.3k
      if (chosen_abi != NULL)
1057
550
  mips_gpr_names = chosen_abi->gpr_names;
1058
13.3k
      return;
1059
13.3k
    }
1060
1061
178k
  if (strncmp ("fpr-names", option, optionlen) == 0
1062
178k
      && strlen ("fpr-names") == optionlen)
1063
1.16k
    {
1064
1.16k
      chosen_abi = choose_abi_by_name (val, vallen);
1065
1.16k
      if (chosen_abi != NULL)
1066
254
  mips_fpr_names = chosen_abi->fpr_names;
1067
1.16k
      return;
1068
1.16k
    }
1069
1070
177k
  if (strncmp ("cp0-names", option, optionlen) == 0
1071
177k
      && strlen ("cp0-names") == optionlen)
1072
2.82k
    {
1073
2.82k
      chosen_arch = choose_arch_by_name (val, vallen);
1074
2.82k
      if (chosen_arch != NULL)
1075
1.09k
  {
1076
1.09k
    mips_cp0_names = chosen_arch->cp0_names;
1077
1.09k
    mips_cp0sel_names = chosen_arch->cp0sel_names;
1078
1.09k
    mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1079
1.09k
  }
1080
2.82k
      return;
1081
2.82k
    }
1082
1083
174k
  if (strncmp ("cp1-names", option, optionlen) == 0
1084
174k
      && strlen ("cp1-names") == optionlen)
1085
990
    {
1086
990
      chosen_arch = choose_arch_by_name (val, vallen);
1087
990
      if (chosen_arch != NULL)
1088
262
  mips_cp1_names = chosen_arch->cp1_names;
1089
990
      return;
1090
990
    }
1091
1092
173k
  if (strncmp ("hwr-names", option, optionlen) == 0
1093
173k
      && strlen ("hwr-names") == optionlen)
1094
2.07k
    {
1095
2.07k
      chosen_arch = choose_arch_by_name (val, vallen);
1096
2.07k
      if (chosen_arch != NULL)
1097
256
  mips_hwr_names = chosen_arch->hwr_names;
1098
2.07k
      return;
1099
2.07k
    }
1100
1101
171k
  if (strncmp ("reg-names", option, optionlen) == 0
1102
171k
      && strlen ("reg-names") == optionlen)
1103
64.0k
    {
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
64.0k
      chosen_abi = choose_abi_by_name (val, vallen);
1109
64.0k
      if (chosen_abi != NULL)
1110
368
  {
1111
368
    mips_gpr_names = chosen_abi->gpr_names;
1112
368
    mips_fpr_names = chosen_abi->fpr_names;
1113
368
  }
1114
64.0k
      chosen_arch = choose_arch_by_name (val, vallen);
1115
64.0k
      if (chosen_arch != NULL)
1116
9.22k
  {
1117
9.22k
    mips_cp0_names = chosen_arch->cp0_names;
1118
9.22k
    mips_cp0sel_names = chosen_arch->cp0sel_names;
1119
9.22k
    mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1120
9.22k
    mips_cp1_names = chosen_arch->cp1_names;
1121
9.22k
    mips_hwr_names = chosen_arch->hwr_names;
1122
9.22k
  }
1123
64.0k
      return;
1124
64.0k
    }
1125
1126
  /* Invalid option.  */
1127
171k
}
1128
1129
static void
1130
parse_mips_dis_options (const char *options)
1131
1.76M
{
1132
1.76M
  const char *option_end;
1133
1134
1.76M
  if (options == NULL)
1135
1.49M
    return;
1136
1137
1.44M
  while (*options != '\0')
1138
1.17M
    {
1139
      /* Skip empty options.  */
1140
1.17M
      if (*options == ',')
1141
484k
  {
1142
484k
    options++;
1143
484k
    continue;
1144
484k
  }
1145
1146
      /* We know that *options is neither NUL or a comma.  */
1147
688k
      option_end = options + 1;
1148
9.85M
      while (*option_end != ',' && *option_end != '\0')
1149
9.16M
  option_end++;
1150
1151
688k
      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
688k
      options = option_end;
1156
688k
    }
1157
276k
}
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.54k
{
1165
1.54k
  unsigned int i;
1166
1167
28.5k
  for (i = 0; i < len; i++)
1168
27.5k
    if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1169
582
      return &names[i];
1170
959
  return NULL;
1171
1.54k
}
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.36M
{
1179
2.36M
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1180
1181
2.36M
  switch (type)
1182
2.36M
    {
1183
2.28M
    case OP_REG_GP:
1184
2.28M
      infprintf (info->stream, dis_style_register, "%s",
1185
2.28M
     mips_gpr_names[regno]);
1186
2.28M
      break;
1187
1188
28.2k
    case OP_REG_FP:
1189
28.2k
      infprintf (info->stream, dis_style_register, "%s",
1190
28.2k
     mips_fpr_names[regno]);
1191
28.2k
      break;
1192
1193
3.26k
    case OP_REG_CCC:
1194
3.26k
      if (opcode->pinfo & (FP_D | FP_S))
1195
2.99k
  infprintf (info->stream, dis_style_register, "$fcc%d", regno);
1196
273
      else
1197
273
  infprintf (info->stream, dis_style_register, "$cc%d", regno);
1198
3.26k
      break;
1199
1200
4.26k
    case OP_REG_VEC:
1201
4.26k
      if (opcode->membership & INSN_5400)
1202
582
  infprintf (info->stream, dis_style_register, "$f%d", regno);
1203
3.67k
      else
1204
3.67k
  infprintf (info->stream, dis_style_register, "$v%d", regno);
1205
4.26k
      break;
1206
1207
1.29k
    case OP_REG_ACC:
1208
1.29k
      infprintf (info->stream, dis_style_register, "$ac%d", regno);
1209
1.29k
      break;
1210
1211
25.8k
    case OP_REG_COPRO:
1212
25.8k
      if (opcode->name[strlen (opcode->name) - 1] == '0')
1213
4.19k
  infprintf (info->stream, dis_style_register, "%s", mips_cp0_names[regno]);
1214
21.6k
      else
1215
21.6k
  infprintf (info->stream, dis_style_register, "$%d", regno);
1216
25.8k
      break;
1217
1218
859
    case OP_REG_CONTROL:
1219
859
      if (opcode->name[strlen (opcode->name) - 1] == '1')
1220
388
  infprintf (info->stream, dis_style_register, "%s", mips_cp1_names[regno]);
1221
471
      else
1222
471
  infprintf (info->stream, dis_style_register, "$%d", regno);
1223
859
      break;
1224
1225
498
    case OP_REG_HW:
1226
498
      infprintf (info->stream, dis_style_register, "%s", mips_hwr_names[regno]);
1227
498
      break;
1228
1229
6.19k
    case OP_REG_VF:
1230
6.19k
      infprintf (info->stream, dis_style_register, "$vf%d", regno);
1231
6.19k
      break;
1232
1233
285
    case OP_REG_VI:
1234
285
      infprintf (info->stream, dis_style_register, "$vi%d", regno);
1235
285
      break;
1236
1237
195
    case OP_REG_R5900_I:
1238
195
      infprintf (info->stream, dis_style_register, "$I");
1239
195
      break;
1240
1241
263
    case OP_REG_R5900_Q:
1242
263
      infprintf (info->stream, dis_style_register, "$Q");
1243
263
      break;
1244
1245
194
    case OP_REG_R5900_R:
1246
194
      infprintf (info->stream, dis_style_register, "$R");
1247
194
      break;
1248
1249
197
    case OP_REG_R5900_ACC:
1250
197
      infprintf (info->stream, dis_style_register, "$ACC");
1251
197
      break;
1252
1253
10.1k
    case OP_REG_MSA:
1254
10.1k
      infprintf (info->stream, dis_style_register, "$w%d", regno);
1255
10.1k
      break;
1256
1257
382
    case OP_REG_MSA_CTRL:
1258
382
      infprintf (info->stream, dis_style_register, "%s",
1259
382
     msa_control_names[regno]);
1260
382
      break;
1261
1262
2.36M
    }
1263
2.36M
}
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.16M
{
1285
2.16M
  memset (state, 0, sizeof (*state));
1286
2.16M
}
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
8.32k
{
1296
8.32k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1297
1298
8.32k
  if (operand->size == 4)
1299
5.97k
    infprintf (info->stream, style, "%s%s%s%s",
1300
5.97k
      uval & 8 ? "x" : "",
1301
5.97k
      uval & 4 ? "y" : "",
1302
5.97k
      uval & 2 ? "z" : "",
1303
5.97k
      uval & 1 ? "w" : "");
1304
2.34k
  else if (operand->size == 2)
1305
2.34k
    infprintf (info->stream, style, "%c", "xyzw"[uval]);
1306
0
  else
1307
0
    abort ();
1308
8.32k
}
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.53M
{
1317
3.53M
  state->last_reg_type = reg_type;
1318
3.53M
  state->last_regno = regno;
1319
1320
3.53M
  if (!state->seen_dest)
1321
1.91M
    {
1322
1.91M
      state->seen_dest = 1;
1323
1.91M
      state->dest_regno = regno;
1324
1.91M
    }
1325
3.53M
}
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
6.56k
{
1338
6.56k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1339
6.56k
  unsigned int nargs, nstatics, smask, i, j;
1340
6.56k
  void *is = info->stream;
1341
6.56k
  const char *sep;
1342
1343
6.56k
  if (amask == MIPS_SVRS_ALL_ARGS)
1344
248
    {
1345
248
      nargs = 4;
1346
248
      nstatics = 0;
1347
248
    }
1348
6.31k
  else if (amask == MIPS_SVRS_ALL_STATICS)
1349
529
    {
1350
529
      nargs = 0;
1351
529
      nstatics = 4;
1352
529
    }
1353
5.78k
  else
1354
5.78k
    {
1355
5.78k
      nargs = amask >> 2;
1356
5.78k
      nstatics = amask & 3;
1357
5.78k
    }
1358
1359
6.56k
  sep = "";
1360
6.56k
  if (nargs > 0)
1361
1.34k
    {
1362
1.34k
      infprintf (is, dis_style_register, "%s", mips_gpr_names[4]);
1363
1.34k
      if (nargs > 1)
1364
599
  infprintf (is, dis_style_register, "-%s", mips_gpr_names[4 + nargs - 1]);
1365
1.34k
      sep = ",";
1366
1.34k
    }
1367
1368
6.56k
  infprintf (is, dis_style_text, "%s", sep);
1369
6.56k
  infprintf (is, dis_style_immediate, "%d", frame_size);
1370
1371
6.56k
  if (ra)      /* $ra */
1372
4.56k
    {
1373
4.56k
      infprintf (is, dis_style_text, ",");
1374
4.56k
      infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
1375
4.56k
    }
1376
1377
6.56k
  smask = 0;
1378
6.56k
  if (s0)      /* $s0 */
1379
4.68k
    smask |= 1 << 0;
1380
6.56k
  if (s1)      /* $s1 */
1381
3.78k
    smask |= 1 << 1;
1382
6.56k
  if (nsreg > 0)    /* $s2-$s8 */
1383
2.10k
    smask |= ((1 << nsreg) - 1) << 2;
1384
1385
47.4k
  for (i = 0; i < 9; i++)
1386
40.8k
    if (smask & (1 << i))
1387
5.45k
      {
1388
5.45k
  infprintf (is, dis_style_text, ",");
1389
5.45k
  infprintf (is, dis_style_register, "%s",
1390
5.45k
       mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1391
  /* Skip over string of set bits.  */
1392
18.5k
  for (j = i; smask & (2 << j); j++)
1393
13.1k
    continue;
1394
5.45k
  if (j > i)
1395
3.88k
    {
1396
3.88k
      infprintf (is, dis_style_text, "-");
1397
3.88k
      infprintf (is, dis_style_register, "%s",
1398
3.88k
           mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1399
3.88k
    }
1400
5.45k
  i = j + 1;
1401
5.45k
      }
1402
  /* Statics $ax - $a3.  */
1403
6.56k
  if (nstatics == 1)
1404
849
    {
1405
849
      infprintf (is, dis_style_text, ",");
1406
849
      infprintf (is, dis_style_register, "%s", mips_gpr_names[7]);
1407
849
    }
1408
5.71k
  else if (nstatics > 0)
1409
1.07k
    {
1410
1.07k
      infprintf (is, dis_style_text, ",");
1411
1.07k
      infprintf (is, dis_style_register, "%s",
1412
1.07k
     mips_gpr_names[7 - nstatics + 1]);
1413
1.07k
      infprintf (is, dis_style_text, "-");
1414
1.07k
      infprintf (is, dis_style_register, "%s", mips_gpr_names[7]);
1415
1.07k
    }
1416
6.56k
}
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
3.67M
{
1431
3.67M
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1432
3.67M
  void *is = info->stream;
1433
1434
3.67M
  switch (operand->type)
1435
3.67M
    {
1436
1.07M
    case OP_INT:
1437
1.07M
      {
1438
1.07M
  const struct mips_int_operand *int_op;
1439
1440
1.07M
  int_op = (const struct mips_int_operand *) operand;
1441
1.07M
  uval = mips_decode_int_operand (int_op, uval);
1442
1.07M
  state->last_int = uval;
1443
1.07M
  if (int_op->print_hex)
1444
137k
    infprintf (is, dis_style_immediate, "0x%x", uval);
1445
933k
  else
1446
933k
    infprintf (is, dis_style_immediate, "%d", uval);
1447
1.07M
      }
1448
1.07M
      break;
1449
1450
4.17k
    case OP_MAPPED_INT:
1451
4.17k
      {
1452
4.17k
  const struct mips_mapped_int_operand *mint_op;
1453
1454
4.17k
  mint_op = (const struct mips_mapped_int_operand *) operand;
1455
4.17k
  uval = mint_op->int_map[uval];
1456
4.17k
  state->last_int = uval;
1457
4.17k
  if (mint_op->print_hex)
1458
2.52k
    infprintf (is, dis_style_immediate, "0x%x", uval);
1459
1.64k
  else
1460
1.64k
    infprintf (is, dis_style_immediate, "%d", uval);
1461
4.17k
      }
1462
4.17k
      break;
1463
1464
2.12k
    case OP_MSB:
1465
2.12k
      {
1466
2.12k
  const struct mips_msb_operand *msb_op;
1467
1468
2.12k
  msb_op = (const struct mips_msb_operand *) operand;
1469
2.12k
  uval += msb_op->bias;
1470
2.12k
  if (msb_op->add_lsb)
1471
877
    uval -= state->last_int;
1472
2.12k
  infprintf (is, dis_style_immediate, "0x%x", uval);
1473
2.12k
      }
1474
2.12k
      break;
1475
1476
2.11M
    case OP_REG:
1477
2.34M
    case OP_OPTIONAL_REG:
1478
2.34M
      {
1479
2.34M
  const struct mips_reg_operand *reg_op;
1480
1481
2.34M
  reg_op = (const struct mips_reg_operand *) operand;
1482
2.34M
  uval = mips_decode_reg_operand (reg_op, uval);
1483
2.34M
  print_reg (info, opcode, reg_op->reg_type, uval);
1484
1485
2.34M
  mips_seen_register (state, uval, reg_op->reg_type);
1486
2.34M
      }
1487
2.34M
      break;
1488
1489
571
    case OP_REG_PAIR:
1490
571
      {
1491
571
  const struct mips_reg_pair_operand *pair_op;
1492
1493
571
  pair_op = (const struct mips_reg_pair_operand *) operand;
1494
571
  print_reg (info, opcode, pair_op->reg_type,
1495
571
       pair_op->reg1_map[uval]);
1496
571
  infprintf (is, dis_style_text, ",");
1497
571
  print_reg (info, opcode, pair_op->reg_type,
1498
571
       pair_op->reg2_map[uval]);
1499
571
      }
1500
571
      break;
1501
1502
210k
    case OP_PCREL:
1503
210k
      {
1504
210k
  const struct mips_pcrel_operand *pcrel_op;
1505
1506
210k
  pcrel_op = (const struct mips_pcrel_operand *) operand;
1507
210k
  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
210k
  if (pcrel_op->include_isa_bit
1512
210k
      && info->flavour != bfd_target_unknown_flavour)
1513
154k
    info->target &= -2;
1514
1515
210k
  (*info->print_address_func) (info->target, info);
1516
210k
      }
1517
210k
      break;
1518
1519
258
    case OP_PERF_REG:
1520
258
      infprintf (is, dis_style_register, "%d", uval);
1521
258
      break;
1522
1523
2.52k
    case OP_ADDIUSP_INT:
1524
2.52k
      {
1525
2.52k
  int sval;
1526
1527
2.52k
  sval = mips_signed_operand (operand, uval) * 4;
1528
2.52k
  if (sval >= -8 && sval < 8)
1529
217
    sval ^= 0x400;
1530
2.52k
  infprintf (is, dis_style_immediate, "%d", sval);
1531
2.52k
  break;
1532
2.11M
      }
1533
1534
866
    case OP_CLO_CLZ_DEST:
1535
866
      {
1536
866
  unsigned int reg1, reg2;
1537
1538
866
  reg1 = uval & 31;
1539
866
  reg2 = uval >> 5;
1540
  /* If one is zero use the other.  */
1541
866
  if (reg1 == reg2 || reg2 == 0)
1542
394
    infprintf (is, dis_style_register, "%s", mips_gpr_names[reg1]);
1543
472
  else if (reg1 == 0)
1544
202
    infprintf (is, dis_style_register, "%s", mips_gpr_names[reg2]);
1545
270
  else
1546
270
    {
1547
      /* Bogus, result depends on processor.  */
1548
270
      infprintf (is, dis_style_register, "%s", mips_gpr_names[reg1]);
1549
270
      infprintf (is, dis_style_text, " or ");
1550
270
      infprintf (is, dis_style_register, "%s", mips_gpr_names[reg2]);
1551
270
    }
1552
866
      }
1553
866
      break;
1554
1555
240
    case OP_SAME_RS_RT:
1556
5.75k
    case OP_CHECK_PREV:
1557
13.0k
    case OP_NON_ZERO_REG:
1558
13.0k
      {
1559
13.0k
  print_reg (info, opcode, OP_REG_GP, uval & 31);
1560
13.0k
  mips_seen_register (state, uval, OP_REG_GP);
1561
13.0k
      }
1562
13.0k
      break;
1563
1564
3.65k
    case OP_LWM_SWM_LIST:
1565
3.65k
      if (operand->size == 2)
1566
2.02k
  {
1567
2.02k
    if (uval == 0)
1568
1.39k
      {
1569
1.39k
        infprintf (is, dis_style_register, "%s",
1570
1.39k
       mips_gpr_names[16]);
1571
1.39k
        infprintf (is, dis_style_text, ",");
1572
1.39k
        infprintf (is, dis_style_register, "%s",
1573
1.39k
       mips_gpr_names[31]);
1574
1.39k
      }
1575
630
    else
1576
630
      {
1577
630
        infprintf (is, dis_style_register, "%s",
1578
630
       mips_gpr_names[16]);
1579
630
        infprintf (is, dis_style_text, "-");
1580
630
        infprintf (is, dis_style_register, "%s",
1581
630
       mips_gpr_names[16 + uval]);
1582
630
        infprintf (is, dis_style_text, ",");
1583
630
        infprintf (is, dis_style_register, "%s",
1584
630
       mips_gpr_names[31]);
1585
630
      }
1586
2.02k
  }
1587
1.63k
      else
1588
1.63k
  {
1589
1.63k
    int s_reg_encode;
1590
1591
1.63k
    s_reg_encode = uval & 0xf;
1592
1.63k
    if (s_reg_encode != 0)
1593
1.34k
      {
1594
1.34k
        if (s_reg_encode == 1)
1595
367
    infprintf (is, dis_style_register, "%s", mips_gpr_names[16]);
1596
980
        else if (s_reg_encode < 9)
1597
433
    {
1598
433
      infprintf (is, dis_style_register, "%s",
1599
433
           mips_gpr_names[16]);
1600
433
      infprintf (is, dis_style_text, "-");
1601
433
      infprintf (is, dis_style_register, "%s",
1602
433
           mips_gpr_names[15 + s_reg_encode]);
1603
433
    }
1604
547
        else if (s_reg_encode == 9)
1605
256
    {
1606
256
      infprintf (is, dis_style_register, "%s",
1607
256
           mips_gpr_names[16]);
1608
256
      infprintf (is, dis_style_text, "-");
1609
256
      infprintf (is, dis_style_register, "%s",
1610
256
           mips_gpr_names[23]);
1611
256
      infprintf (is, dis_style_text, ",");
1612
256
      infprintf (is, dis_style_register, "%s",
1613
256
           mips_gpr_names[30]);
1614
256
    }
1615
291
        else
1616
291
    infprintf (is, dis_style_text, "UNKNOWN");
1617
1.34k
      }
1618
1619
1.63k
    if (uval & 0x10) /* For ra.  */
1620
1.03k
      {
1621
1.03k
        if (s_reg_encode == 0)
1622
264
    infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
1623
766
        else
1624
766
    {
1625
766
      infprintf (is, dis_style_text, ",");
1626
766
      infprintf (is, dis_style_register, "%s",
1627
766
           mips_gpr_names[31]);
1628
766
    }
1629
1.03k
      }
1630
1.63k
  }
1631
3.65k
      break;
1632
1633
3.21k
    case OP_ENTRY_EXIT_LIST:
1634
3.21k
      {
1635
3.21k
  const char *sep;
1636
3.21k
  unsigned int amask, smask;
1637
1638
3.21k
  sep = "";
1639
3.21k
  amask = (uval >> 3) & 7;
1640
3.21k
  if (amask > 0 && amask < 5)
1641
2.02k
    {
1642
2.02k
      infprintf (is, dis_style_register, "%s", mips_gpr_names[4]);
1643
2.02k
      if (amask > 1)
1644
346
        {
1645
346
    infprintf (is, dis_style_text, "-");
1646
346
    infprintf (is, dis_style_register, "%s",
1647
346
         mips_gpr_names[amask + 3]);
1648
346
        }
1649
2.02k
      sep = ",";
1650
2.02k
    }
1651
1652
3.21k
  smask = (uval >> 1) & 3;
1653
3.21k
  if (smask == 3)
1654
2.02k
    {
1655
2.02k
      infprintf (is, dis_style_text, "%s??", sep);
1656
2.02k
      sep = ",";
1657
2.02k
    }
1658
1.18k
  else if (smask > 0)
1659
922
    {
1660
922
      infprintf (is, dis_style_text, "%s", sep);
1661
922
      infprintf (is, dis_style_register, "%s", mips_gpr_names[16]);
1662
922
      if (smask > 1)
1663
624
        {
1664
624
    infprintf (is, dis_style_text, "-");
1665
624
    infprintf (is, dis_style_register, "%s",
1666
624
         mips_gpr_names[smask + 15]);
1667
624
        }
1668
922
      sep = ",";
1669
922
    }
1670
1671
3.21k
  if (uval & 1)
1672
2.57k
    {
1673
2.57k
      infprintf (is, dis_style_text, "%s", sep);
1674
2.57k
      infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
1675
2.57k
      sep = ",";
1676
2.57k
    }
1677
1678
3.21k
  if (amask == 5 || amask == 6)
1679
735
    {
1680
735
      infprintf (is, dis_style_text, "%s", sep);
1681
735
      infprintf (is, dis_style_register, "%s", mips_fpr_names[0]);
1682
735
      if (amask == 6)
1683
484
        {
1684
484
    infprintf (is, dis_style_text, "-");
1685
484
    infprintf (is, dis_style_register, "%s", mips_fpr_names[1]);
1686
484
        }
1687
735
    }
1688
3.21k
      }
1689
3.21k
      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.89k
    case OP_MDMX_IMM_REG:
1696
1.89k
      {
1697
1.89k
  unsigned int vsel;
1698
1699
1.89k
  vsel = uval >> 5;
1700
1.89k
  uval &= 31;
1701
1.89k
  if ((vsel & 0x10) == 0)
1702
964
    {
1703
964
      int fmt;
1704
1705
964
      vsel &= 0x0f;
1706
2.25k
      for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1707
1.96k
        if ((vsel & 1) == 0)
1708
675
    break;
1709
964
      print_reg (info, opcode, OP_REG_VEC, uval);
1710
964
      infprintf (is, dis_style_text, "[");
1711
964
      infprintf (is, dis_style_immediate, "%d", vsel >> 1);
1712
964
      infprintf (is, dis_style_text, "]");
1713
964
    }
1714
933
  else if ((vsel & 0x08) == 0)
1715
597
    print_reg (info, opcode, OP_REG_VEC, uval);
1716
336
  else
1717
336
    infprintf (is, dis_style_immediate, "0x%x", uval);
1718
1.89k
      }
1719
1.89k
      break;
1720
1721
3.70k
    case OP_REPEAT_PREV_REG:
1722
3.70k
      print_reg (info, opcode, state->last_reg_type, state->last_regno);
1723
3.70k
      break;
1724
1725
278
    case OP_REPEAT_DEST_REG:
1726
278
      print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1727
278
      break;
1728
1729
2.52k
    case OP_PC:
1730
2.52k
      infprintf (is, dis_style_register, "$pc");
1731
2.52k
      break;
1732
1733
791
    case OP_REG28:
1734
791
      print_reg (info, opcode, OP_REG_GP, 28);
1735
791
      break;
1736
1737
713
    case OP_VU0_SUFFIX:
1738
6.26k
    case OP_VU0_MATCH_SUFFIX:
1739
6.26k
      print_vu0_channel (info, operand, uval, dis_style_register);
1740
6.26k
      break;
1741
1742
827
    case OP_IMM_INDEX:
1743
827
      infprintf (is, dis_style_text, "[");
1744
827
      infprintf (is, dis_style_immediate, "%d", uval);
1745
827
      infprintf (is, dis_style_text, "]");
1746
827
      break;
1747
1748
259
    case OP_REG_INDEX:
1749
259
      infprintf (is, dis_style_text, "[");
1750
259
      print_reg (info, opcode, OP_REG_GP, uval);
1751
259
      infprintf (is, dis_style_text, "]");
1752
259
      break;
1753
3.67M
    }
1754
3.67M
}
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
760k
{
1764
760k
  struct mips_print_arg_state state;
1765
760k
  const struct mips_operand *operand;
1766
760k
  const char *s;
1767
760k
  unsigned int uval;
1768
1769
760k
  init_print_arg_state (&state);
1770
3.97M
  for (s = opcode->args; *s; ++s)
1771
3.22M
    {
1772
3.22M
      switch (*s)
1773
3.22M
  {
1774
874k
  case ',':
1775
1.13M
  case '(':
1776
1.39M
  case ')':
1777
1.39M
    break;
1778
1779
214
  case '#':
1780
214
    ++s;
1781
214
    break;
1782
1783
1.83M
  default:
1784
1.83M
    operand = decode_operand (s);
1785
1786
1.83M
    if (operand)
1787
1.83M
      {
1788
1.83M
        uval = mips_extract_operand (operand, insn);
1789
1.83M
        switch (operand->type)
1790
1.83M
    {
1791
985k
    case OP_REG:
1792
1.18M
    case OP_OPTIONAL_REG:
1793
1.18M
      {
1794
1.18M
        const struct mips_reg_operand *reg_op;
1795
1796
1.18M
        reg_op = (const struct mips_reg_operand *) operand;
1797
1.18M
        uval = mips_decode_reg_operand (reg_op, uval);
1798
1.18M
        mips_seen_register (&state, uval, reg_op->reg_type);
1799
1.18M
      }
1800
1.18M
    break;
1801
1802
3.16k
    case OP_SAME_RS_RT:
1803
3.16k
      {
1804
3.16k
        unsigned int reg1, reg2;
1805
1806
3.16k
        reg1 = uval & 31;
1807
3.16k
        reg2 = uval >> 5;
1808
1809
3.16k
        if (reg1 != reg2 || reg1 == 0)
1810
2.92k
          return false;
1811
3.16k
      }
1812
240
    break;
1813
1814
8.63k
    case OP_CHECK_PREV:
1815
8.63k
      {
1816
8.63k
        const struct mips_check_prev_operand *prev_op;
1817
1818
8.63k
        prev_op = (const struct mips_check_prev_operand *) operand;
1819
1820
8.63k
        if (!prev_op->zero_ok && uval == 0)
1821
299
          return false;
1822
1823
8.33k
        if (((prev_op->less_than_ok && uval < state.last_regno)
1824
8.33k
      || (prev_op->greater_than_ok && uval > state.last_regno)
1825
8.33k
      || (prev_op->equal_ok && uval == state.last_regno)))
1826
5.51k
          break;
1827
1828
2.82k
        return false;
1829
8.33k
      }
1830
1831
8.47k
    case OP_NON_ZERO_REG:
1832
8.47k
      {
1833
8.47k
        if (uval == 0)
1834
864
          return false;
1835
8.47k
      }
1836
7.60k
    break;
1837
1838
491k
    case OP_INT:
1839
495k
    case OP_MAPPED_INT:
1840
497k
    case OP_MSB:
1841
498k
    case OP_REG_PAIR:
1842
608k
    case OP_PCREL:
1843
608k
    case OP_PERF_REG:
1844
611k
    case OP_ADDIUSP_INT:
1845
612k
    case OP_CLO_CLZ_DEST:
1846
615k
    case OP_LWM_SWM_LIST:
1847
615k
    case OP_ENTRY_EXIT_LIST:
1848
617k
    case OP_MDMX_IMM_REG:
1849
621k
    case OP_REPEAT_PREV_REG:
1850
621k
    case OP_REPEAT_DEST_REG:
1851
623k
    case OP_PC:
1852
623k
    case OP_REG28:
1853
624k
    case OP_VU0_SUFFIX:
1854
629k
    case OP_VU0_MATCH_SUFFIX:
1855
630k
    case OP_IMM_INDEX:
1856
630k
    case OP_REG_INDEX:
1857
631k
    case OP_SAVE_RESTORE_LIST:
1858
631k
      break;
1859
1.83M
    }
1860
1.83M
      }
1861
1.82M
    if (*s == 'm' || *s == '+' || *s == '-')
1862
192k
      ++s;
1863
3.22M
  }
1864
3.22M
    }
1865
753k
  return true;
1866
760k
}
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
685k
{
1879
685k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1880
685k
  void *is = info->stream;
1881
685k
  struct mips_print_arg_state state;
1882
685k
  const struct mips_operand *operand;
1883
685k
  const char *s;
1884
1885
685k
  init_print_arg_state (&state);
1886
3.89M
  for (s = opcode->args; *s; ++s)
1887
3.20M
    {
1888
3.20M
      switch (*s)
1889
3.20M
  {
1890
870k
  case ',':
1891
1.12M
  case '(':
1892
1.38M
  case ')':
1893
1.38M
    infprintf (is, dis_style_text, "%c", *s);
1894
1.38M
    break;
1895
1896
214
  case '#':
1897
214
    ++s;
1898
214
    infprintf (is, dis_style_text, "%c%c", *s, *s);
1899
214
    break;
1900
1901
1.82M
  default:
1902
1.82M
    operand = decode_operand (s);
1903
1.82M
    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.82M
    if (operand->type == OP_SAVE_RESTORE_LIST)
1913
285
      {
1914
        /* Handle this case here because of the complex behavior.  */
1915
285
        unsigned int amask = (insn >> 15) & 0xf;
1916
285
        unsigned int nsreg = (insn >> 23) & 0x7;
1917
285
        unsigned int ra = insn & 0x1000;      /* $ra */
1918
285
        unsigned int s0 = insn & 0x800;     /* $s0 */
1919
285
        unsigned int s1 = insn & 0x400;     /* $s1 */
1920
285
        unsigned int frame_size = (((insn >> 15) & 0xf0)
1921
285
           | ((insn >> 6) & 0x0f)) * 8;
1922
285
        mips_print_save_restore (info, amask, nsreg, ra, s0, s1,
1923
285
               frame_size);
1924
285
      }
1925
1.82M
    else if (operand->type == OP_REG
1926
1.82M
       && s[1] == ','
1927
1.82M
       && s[2] == 'H'
1928
1.82M
       && opcode->name[strlen (opcode->name) - 1] == '0')
1929
853
      {
1930
        /* Coprocessor register 0 with sel field.  */
1931
853
        const struct mips_cp0sel_name *n;
1932
853
        unsigned int reg, sel;
1933
1934
853
        reg = mips_extract_operand (operand, insn);
1935
853
        s += 2;
1936
853
        operand = decode_operand (s);
1937
853
        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
853
        n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1945
853
             mips_cp0sel_names_len,
1946
853
             reg, sel);
1947
853
        if (n != NULL)
1948
320
    infprintf (is, dis_style_register, "%s", n->name);
1949
533
        else
1950
533
    {
1951
533
      infprintf (is, dis_style_register, "$%d", reg);
1952
533
      infprintf (is, dis_style_text, ",");
1953
533
      infprintf (is, dis_style_immediate, "%d", sel);
1954
533
    }
1955
853
      }
1956
1.82M
    else
1957
1.82M
      {
1958
1.82M
        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.82M
        if (operand->type == OP_PCREL)
1964
110k
    {
1965
110k
      const struct mips_pcrel_operand *pcrel_op;
1966
1967
110k
      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
110k
      if (pcrel_op->include_isa_bit)
1971
107k
        base_pc += length;
1972
110k
    }
1973
1974
1.82M
        print_insn_arg (info, &state, opcode, operand, base_pc,
1975
1.82M
            mips_extract_operand (operand, insn));
1976
1.82M
      }
1977
1.82M
    if (*s == 'm' || *s == '+' || *s == '-')
1978
192k
      ++s;
1979
1.82M
    break;
1980
3.20M
  }
1981
3.20M
    }
1982
685k
}
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
861k
{
1994
861k
#define GET_OP(insn, field)     \
1995
972k
  (((insn) >> OP_SH_##field) & OP_MASK_##field)
1996
861k
  static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1997
861k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1998
861k
  const struct mips_opcode *op;
1999
861k
  static bool init = 0;
2000
861k
  void *is = info->stream;
2001
2002
  /* Build a hash table to shorten the search time.  */
2003
861k
  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
861k
  info->bytes_per_chunk = INSNLEN;
2026
861k
  info->display_endian = info->endian;
2027
861k
  info->insn_info_valid = 1;
2028
861k
  info->branch_delay_insns = 0;
2029
861k
  info->data_size = 0;
2030
861k
  info->insn_type = dis_nonbranch;
2031
861k
  info->target = 0;
2032
861k
  info->target2 = 0;
2033
2034
861k
  op = mips_hash[GET_OP (word, OP)];
2035
861k
  if (op != NULL)
2036
861k
    {
2037
871M
      for (; op < &mips_opcodes[NUMOPCODES]; op++)
2038
871M
  {
2039
871M
    if (op->pinfo != INSN_MACRO
2040
871M
        && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2041
871M
        && (word & op->mask) == op->match)
2042
940k
      {
2043
        /* We always disassemble the jalx instruction, except for MIPS r6.  */
2044
940k
        if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
2045
940k
     && (strcmp (op->name, "jalx")
2046
321k
         || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
2047
321k
         || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
2048
321k
    continue;
2049
2050
        /* Figure out instruction type and branch delay information.  */
2051
619k
        if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2052
52.2k
          {
2053
52.2k
      if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2054
29.9k
        info->insn_type = dis_jsr;
2055
22.2k
      else
2056
22.2k
        info->insn_type = dis_branch;
2057
52.2k
      info->branch_delay_insns = 1;
2058
52.2k
    }
2059
567k
        else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
2060
567k
             | INSN_COND_BRANCH_LIKELY)) != 0)
2061
46.5k
    {
2062
46.5k
      if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2063
1.31k
        info->insn_type = dis_condjsr;
2064
45.1k
      else
2065
45.1k
        info->insn_type = dis_condbranch;
2066
46.5k
      info->branch_delay_insns = 1;
2067
46.5k
    }
2068
521k
        else if ((op->pinfo & (INSN_STORE_MEMORY
2069
521k
             | INSN_LOAD_MEMORY)) != 0)
2070
201k
    info->insn_type = dis_dref;
2071
2072
619k
        if (!validate_insn_args (op, decode_mips_operand, word))
2073
6.91k
    continue;
2074
2075
612k
        infprintf (is, dis_style_mnemonic, "%s", op->name);
2076
612k
        if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
2077
2.05k
    {
2078
2.05k
      unsigned int uval;
2079
2080
2.05k
      infprintf (is, dis_style_mnemonic, ".");
2081
2.05k
      uval = mips_extract_operand (&mips_vu0_channel_mask, word);
2082
2.05k
      print_vu0_channel (info, &mips_vu0_channel_mask, uval,
2083
2.05k
             dis_style_mnemonic);
2084
2.05k
    }
2085
2086
612k
        if (op->args[0])
2087
555k
    {
2088
555k
      infprintf (is, dis_style_text, "\t");
2089
555k
      print_insn_args (info, op, decode_mips_operand, word,
2090
555k
           memaddr, 4);
2091
555k
    }
2092
2093
612k
        return INSNLEN;
2094
619k
      }
2095
871M
  }
2096
861k
    }
2097
248k
#undef GET_OP
2098
2099
  /* Handle undefined instructions.  */
2100
248k
  info->insn_type = dis_noninsn;
2101
248k
  infprintf (is, dis_style_assembler_directive, ".word");
2102
248k
  infprintf (is, dis_style_text, "\t");
2103
248k
  infprintf (is, dis_style_immediate, "0x%x", word);
2104
248k
  return INSNLEN;
2105
861k
}
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
3.16M
{
2117
3.16M
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
2118
3.16M
  void *is = info->stream;
2119
3.16M
  const struct mips_operand *operand, *ext_operand;
2120
3.16M
  unsigned short ext_size;
2121
3.16M
  unsigned int uval;
2122
3.16M
  bfd_vma baseaddr;
2123
2124
3.16M
  if (!use_extend)
2125
3.03M
    extend = 0;
2126
2127
3.16M
  switch (type)
2128
3.16M
    {
2129
970k
    case ',':
2130
1.13M
    case '(':
2131
1.30M
    case ')':
2132
1.30M
      infprintf (is, dis_style_text, "%c", type);
2133
1.30M
      break;
2134
2135
1.85M
    default:
2136
1.85M
      operand = decode_mips16_operand (type, false);
2137
1.85M
      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
1.85M
      if (operand->type == OP_SAVE_RESTORE_LIST)
2146
6.27k
  {
2147
    /* Handle this case here because of the complex interaction
2148
       with the EXTEND opcode.  */
2149
6.27k
    unsigned int amask = extend & 0xf;
2150
6.27k
    unsigned int nsreg = (extend >> 8) & 0x7;
2151
6.27k
    unsigned int ra = insn & 0x40;      /* $ra */
2152
6.27k
    unsigned int s0 = insn & 0x20;      /* $s0 */
2153
6.27k
    unsigned int s1 = insn & 0x10;      /* $s1 */
2154
6.27k
    unsigned int frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
2155
6.27k
    if (frame_size == 0 && !use_extend)
2156
1.42k
      frame_size = 128;
2157
6.27k
    mips_print_save_restore (info, amask, nsreg, ra, s0, s1, frame_size);
2158
6.27k
    break;
2159
6.27k
  }
2160
2161
1.85M
      if (is_offset && operand->type == OP_INT)
2162
168k
  {
2163
168k
    const struct mips_int_operand *int_op;
2164
2165
168k
    int_op = (const struct mips_int_operand *) operand;
2166
168k
    info->insn_type = dis_dref;
2167
168k
    info->data_size = 1 << int_op->shift;
2168
168k
  }
2169
2170
1.85M
      ext_size = 0;
2171
1.85M
      if (use_extend)
2172
80.2k
  {
2173
80.2k
    ext_operand = decode_mips16_operand (type, true);
2174
80.2k
    if (ext_operand != operand
2175
80.2k
        || (operand->type == OP_INT && operand->lsb == 0
2176
56.2k
      && mips_opcode_32bit_p (opcode)))
2177
25.6k
      {
2178
25.6k
        ext_size = ext_operand->size;
2179
25.6k
        operand = ext_operand;
2180
25.6k
      }
2181
80.2k
  }
2182
1.85M
      if (operand->size == 26)
2183
12.1k
  uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
2184
1.83M
      else if (ext_size == 16 || ext_size == 9)
2185
23.1k
  uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
2186
1.81M
      else if (ext_size == 15)
2187
1.19k
  uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
2188
1.81M
      else if (ext_size == 6)
2189
559
  uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
2190
1.81M
      else
2191
1.81M
  uval = mips_extract_operand (operand, (extend << 16) | insn);
2192
1.85M
      if (ext_size == 9)
2193
885
  uval &= (1U << ext_size) - 1;
2194
2195
1.85M
      baseaddr = memaddr + 2;
2196
1.85M
      if (operand->type == OP_PCREL)
2197
99.9k
  {
2198
99.9k
    const struct mips_pcrel_operand *pcrel_op;
2199
2200
99.9k
    pcrel_op = (const struct mips_pcrel_operand *) operand;
2201
99.9k
    if (!pcrel_op->include_isa_bit && use_extend)
2202
2.10k
      baseaddr = memaddr - 2;
2203
97.8k
    else if (!pcrel_op->include_isa_bit)
2204
35.1k
      {
2205
35.1k
        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
35.1k
        if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
2215
35.1k
      && (((info->endian == BFD_ENDIAN_BIG
2216
20.4k
      ? bfd_getb16 (buffer)
2217
20.4k
      : bfd_getl16 (buffer))
2218
20.4k
           & 0xf800) == 0x1800))
2219
315
    baseaddr = memaddr - 4;
2220
34.8k
        else if (info->read_memory_func (memaddr - 2, buffer, 2,
2221
34.8k
                 info) == 0
2222
34.8k
           && (((info->endian == BFD_ENDIAN_BIG
2223
20.1k
           ? bfd_getb16 (buffer)
2224
20.1k
           : bfd_getl16 (buffer))
2225
20.1k
          & 0xf89f) == 0xe800)
2226
34.8k
           && (((info->endian == BFD_ENDIAN_BIG
2227
42
           ? bfd_getb16 (buffer)
2228
42
           : bfd_getl16 (buffer))
2229
42
          & 0x0060) != 0x0060))
2230
42
    baseaddr = memaddr - 2;
2231
34.8k
        else
2232
34.8k
    baseaddr = memaddr;
2233
35.1k
      }
2234
99.9k
  }
2235
2236
1.85M
      print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
2237
1.85M
      break;
2238
3.16M
    }
2239
3.16M
}
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
735k
{
2249
735k
  if (info->symbols
2250
735k
      && info->symbols[0]
2251
735k
      && (info->symbols[0]->flags & BSF_SYNTHETIC)
2252
735k
      && addr == bfd_asymbol_value (info->symbols[0]) + 12)
2253
0
    return true;
2254
2255
735k
  return false;
2256
735k
}
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
735k
{
2272
735k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
2273
735k
  int status;
2274
735k
  bfd_byte buffer[4];
2275
735k
  const struct mips_opcode *op, *opend;
2276
735k
  struct mips_print_arg_state state;
2277
735k
  void *is = info->stream;
2278
735k
  bool have_second;
2279
735k
  bool extend_only;
2280
735k
  unsigned int second;
2281
735k
  unsigned int first;
2282
735k
  unsigned int full;
2283
2284
735k
  info->bytes_per_chunk = 2;
2285
735k
  info->display_endian = info->endian;
2286
735k
  info->insn_info_valid = 1;
2287
735k
  info->branch_delay_insns = 0;
2288
735k
  info->data_size = 0;
2289
735k
  info->target = 0;
2290
735k
  info->target2 = 0;
2291
2292
735k
#define GET_OP(insn, field) \
2293
735k
  (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2294
  /* Decode PLT entry's GOT slot address word.  */
2295
735k
  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
735k
  else
2315
735k
    {
2316
735k
      info->insn_type = dis_nonbranch;
2317
735k
      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2318
735k
    }
2319
735k
  if (status != 0)
2320
1.76k
    {
2321
1.76k
      (*info->memory_error_func) (status, memaddr, info);
2322
1.76k
      return -1;
2323
1.76k
    }
2324
2325
733k
  extend_only = false;
2326
2327
733k
  if (info->endian == BFD_ENDIAN_BIG)
2328
126k
    first = bfd_getb16 (buffer);
2329
607k
  else
2330
607k
    first = bfd_getl16 (buffer);
2331
2332
733k
  status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2333
733k
  if (status == 0)
2334
731k
    {
2335
731k
      have_second = true;
2336
731k
      if (info->endian == BFD_ENDIAN_BIG)
2337
125k
  second = bfd_getb16 (buffer);
2338
605k
      else
2339
605k
  second = bfd_getl16 (buffer);
2340
731k
      full = (first << 16) | second;
2341
731k
    }
2342
1.79k
  else
2343
1.79k
    {
2344
1.79k
      have_second = false;
2345
1.79k
      second = 0;
2346
1.79k
      full = first;
2347
1.79k
    }
2348
2349
  /* FIXME: Should probably use a hash table on the major opcode here.  */
2350
2351
733k
  opend = mips16_opcodes + bfd_mips16_num_opcodes;
2352
63.0M
  for (op = mips16_opcodes; op < opend; op++)
2353
63.0M
    {
2354
63.0M
      enum match_kind match;
2355
2356
63.0M
      if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor))
2357
8.30M
  continue;
2358
2359
54.7M
      if (op->pinfo == INSN_MACRO
2360
54.7M
    || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2361
12.4M
  match = MATCH_NONE;
2362
42.2M
      else if (mips_opcode_32bit_p (op))
2363
6.87M
  {
2364
6.87M
    if (have_second
2365
6.87M
        && (full & op->mask) == op->match)
2366
17.4k
      match = MATCH_FULL;
2367
6.85M
    else
2368
6.85M
      match = MATCH_NONE;
2369
6.87M
  }
2370
35.3M
      else if ((first & op->mask) == op->match)
2371
678k
  {
2372
678k
    match = MATCH_SHORT;
2373
678k
    second = 0;
2374
678k
    full = first;
2375
678k
  }
2376
34.6M
      else if ((first & 0xf800) == 0xf000
2377
34.6M
         && have_second
2378
34.6M
         && !extend_only
2379
34.6M
         && (second & op->mask) == op->match)
2380
29.0k
  {
2381
29.0k
    if (op->pinfo2 & INSN2_SHORT_ONLY)
2382
4.68k
      {
2383
4.68k
        match = MATCH_NONE;
2384
4.68k
        extend_only = true;
2385
4.68k
      }
2386
24.3k
    else
2387
24.3k
      match = MATCH_FULL;
2388
29.0k
  }
2389
34.6M
      else
2390
34.6M
  match = MATCH_NONE;
2391
2392
54.7M
      if (match != MATCH_NONE)
2393
720k
  {
2394
720k
    const char *s;
2395
2396
720k
    infprintf (is, dis_style_mnemonic, "%s", op->name);
2397
720k
    if (op->args[0] != '\0')
2398
719k
      infprintf (is, dis_style_text, "\t");
2399
2400
720k
    init_print_arg_state (&state);
2401
3.89M
    for (s = op->args; *s != '\0'; s++)
2402
3.17M
      {
2403
3.17M
        if (*s == ','
2404
3.17M
      && s[1] == 'w'
2405
3.17M
      && GET_OP (full, RX) == GET_OP (full, RY))
2406
3.63k
    {
2407
      /* Skip the register and the comma.  */
2408
3.63k
      ++s;
2409
3.63k
      continue;
2410
3.63k
    }
2411
3.16M
        if (*s == ','
2412
3.16M
      && s[1] == 'v'
2413
3.16M
      && GET_OP (full, RZ) == GET_OP (full, RX))
2414
1.25k
    {
2415
      /* Skip the register and the comma.  */
2416
1.25k
      ++s;
2417
1.25k
      continue;
2418
1.25k
    }
2419
3.16M
        if (s[0] == 'N'
2420
3.16M
      && s[1] == ','
2421
3.16M
      && s[2] == 'O'
2422
3.16M
      && op->name[strlen (op->name) - 1] == '0')
2423
688
    {
2424
      /* Coprocessor register 0 with sel field.  */
2425
688
      const struct mips_cp0sel_name *n;
2426
688
      const struct mips_operand *operand;
2427
688
      unsigned int reg, sel;
2428
2429
688
      operand = decode_mips16_operand (*s, true);
2430
688
      reg = mips_extract_operand (operand, (first << 16) | second);
2431
688
      s += 2;
2432
688
      operand = decode_mips16_operand (*s, true);
2433
688
      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
688
      n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2441
688
                 mips_cp0sel_names_len,
2442
688
                 reg, sel);
2443
688
      if (n != NULL)
2444
262
        infprintf (is, dis_style_register, "%s", n->name);
2445
426
      else
2446
426
        {
2447
426
          infprintf (is, dis_style_register, "$%d", reg);
2448
426
          infprintf (is, dis_style_text, ",");
2449
426
          infprintf (is, dis_style_immediate, "%d", sel);
2450
426
        }
2451
688
    }
2452
3.16M
        else
2453
3.16M
    switch (match)
2454
3.16M
      {
2455
132k
        case MATCH_FULL:
2456
132k
          print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
2457
132k
               second, true, first, s[1] == '(');
2458
132k
          break;
2459
3.03M
        case MATCH_SHORT:
2460
3.03M
          print_mips16_insn_arg (info, &state, op, *s, memaddr,
2461
3.03M
               first, false, 0, s[1] == '(');
2462
3.03M
          break;
2463
0
        case MATCH_NONE:  /* Stop the compiler complaining.  */
2464
0
          break;
2465
3.16M
      }
2466
3.16M
      }
2467
2468
    /* Figure out branch instruction type and delay slot information.  */
2469
720k
    if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2470
14.5k
      info->branch_delay_insns = 1;
2471
720k
    if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2472
720k
        || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
2473
30.8k
      {
2474
30.8k
        if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2475
12.5k
    info->insn_type = dis_jsr;
2476
18.3k
        else
2477
18.3k
    info->insn_type = dis_branch;
2478
30.8k
      }
2479
689k
    else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
2480
34.5k
      info->insn_type = dis_condbranch;
2481
2482
720k
    return match == MATCH_FULL ? 4 : 2;
2483
720k
  }
2484
54.7M
    }
2485
13.4k
#undef GET_OP
2486
2487
13.4k
  infprintf (is, dis_style_assembler_directive, ".short");
2488
13.4k
  infprintf (is, dis_style_text, "\t");
2489
13.4k
  infprintf (is, dis_style_immediate, "0x%x", first);
2490
13.4k
  info->insn_type = dis_noninsn;
2491
2492
13.4k
  return 2;
2493
733k
}
2494
2495
/* Disassemble microMIPS instructions.  */
2496
2497
static int
2498
print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2499
170k
{
2500
170k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
2501
170k
  const struct mips_opcode *op, *opend;
2502
170k
  void *is = info->stream;
2503
170k
  bfd_byte buffer[2];
2504
170k
  unsigned int higher;
2505
170k
  unsigned int length;
2506
170k
  int status;
2507
170k
  unsigned int insn;
2508
2509
170k
  info->bytes_per_chunk = 2;
2510
170k
  info->display_endian = info->endian;
2511
170k
  info->insn_info_valid = 1;
2512
170k
  info->branch_delay_insns = 0;
2513
170k
  info->data_size = 0;
2514
170k
  info->insn_type = dis_nonbranch;
2515
170k
  info->target = 0;
2516
170k
  info->target2 = 0;
2517
2518
170k
  status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2519
170k
  if (status != 0)
2520
595
    {
2521
595
      (*info->memory_error_func) (status, memaddr, info);
2522
595
      return -1;
2523
595
    }
2524
2525
170k
  length = 2;
2526
2527
170k
  if (info->endian == BFD_ENDIAN_BIG)
2528
0
    insn = bfd_getb16 (buffer);
2529
170k
  else
2530
170k
    insn = bfd_getl16 (buffer);
2531
2532
170k
  if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2533
118k
    {
2534
      /* This is a 32-bit microMIPS instruction.  */
2535
118k
      higher = insn;
2536
2537
118k
      status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2538
118k
      if (status != 0)
2539
268
  {
2540
268
    infprintf (is, dis_style_text, "micromips 0x%x", higher);
2541
268
    (*info->memory_error_func) (status, memaddr + 2, info);
2542
268
    return -1;
2543
268
  }
2544
2545
118k
      if (info->endian == BFD_ENDIAN_BIG)
2546
0
  insn = bfd_getb16 (buffer);
2547
118k
      else
2548
118k
  insn = bfd_getl16 (buffer);
2549
2550
118k
      insn = insn | (higher << 16);
2551
2552
118k
      length += 2;
2553
118k
    }
2554
2555
  /* FIXME: Should probably use a hash table on the major opcode here.  */
2556
2557
169k
  opend = micromips_opcodes + bfd_micromips_num_opcodes;
2558
103M
  for (op = micromips_opcodes; op < opend; op++)
2559
103M
    {
2560
103M
      if (op->pinfo != INSN_MACRO
2561
103M
    && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2562
103M
    && (insn & op->mask) == op->match
2563
103M
    && ((length == 2 && (op->mask & 0xffff0000) == 0)
2564
173k
        || (length == 4 && (op->mask & 0xffff0000) != 0)))
2565
140k
  {
2566
140k
    if (!validate_insn_args (op, decode_micromips_operand, insn))
2567
0
      continue;
2568
2569
140k
    infprintf (is, dis_style_mnemonic, "%s", op->name);
2570
2571
140k
    if (op->args[0])
2572
130k
      {
2573
130k
        infprintf (is, dis_style_text, "\t");
2574
130k
        print_insn_args (info, op, decode_micromips_operand, insn,
2575
130k
             memaddr + 1, length);
2576
130k
      }
2577
2578
    /* Figure out instruction type and branch delay information.  */
2579
140k
    if ((op->pinfo
2580
140k
         & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2581
15.9k
      info->branch_delay_insns = 1;
2582
140k
    if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2583
140k
         | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2584
9.19k
      {
2585
9.19k
        if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2586
6.53k
    info->insn_type = dis_jsr;
2587
2.66k
        else
2588
2.66k
    info->insn_type = dis_branch;
2589
9.19k
      }
2590
131k
    else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2591
131k
        | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2592
6.87k
      {
2593
6.87k
        if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2594
519
    info->insn_type = dis_condjsr;
2595
6.35k
        else
2596
6.35k
    info->insn_type = dis_condbranch;
2597
6.87k
      }
2598
124k
    else if ((op->pinfo
2599
124k
        & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
2600
55.0k
      info->insn_type = dis_dref;
2601
2602
140k
    return length;
2603
140k
  }
2604
103M
    }
2605
2606
28.8k
  infprintf (is, dis_style_assembler_directive, ".short");
2607
28.8k
  infprintf (is, dis_style_text, "\t");
2608
28.8k
  if (length != 2)
2609
24.1k
    {
2610
24.1k
      infprintf (is, dis_style_immediate, "0x%x", (insn >> 16) & 0xffff);
2611
24.1k
      infprintf (is, dis_style_text, ", ");
2612
24.1k
    }
2613
28.8k
  infprintf (is, dis_style_immediate, "0x%x", (insn & 0xffff));
2614
2615
28.8k
  info->insn_type = dis_noninsn;
2616
2617
28.8k
  return length;
2618
169k
}
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.72M
{
2631
1.72M
  int i;
2632
1.72M
  int l;
2633
2634
5.92M
  for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2635
4.20M
    if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
2636
4.20M
  && ((!micromips_p
2637
5.43k
       && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
2638
5.43k
      || (micromips_p
2639
5.43k
    && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2640
0
      return 1;
2641
4.20M
    else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2642
4.20M
        && info->symtab[i]->section == info->section)
2643
506k
      {
2644
506k
  elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
2645
506k
  if ((!micromips_p
2646
506k
       && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2647
506k
      || (micromips_p
2648
506k
    && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2649
0
    return 1;
2650
506k
      }
2651
2652
1.72M
  return 0;
2653
1.72M
}
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.76M
{
2666
1.76M
  bfd_byte buffer[INSNLEN];
2667
1.76M
  int status;
2668
2669
1.76M
  set_default_mips_dis_options (info);
2670
1.76M
  parse_mips_dis_options (info->disassembler_options);
2671
2672
1.76M
  if (info->mach == bfd_mach_mips16)
2673
360k
    return print_insn_mips16 (memaddr, info);
2674
1.40M
  if (info->mach == bfd_mach_mips_micromips)
2675
143k
    return print_insn_micromips (memaddr, info);
2676
2677
1.26M
#if 1
2678
  /* FIXME: If odd address, this is CLEARLY a compressed instruction.  */
2679
  /* Only a few tools will work this way.  */
2680
1.26M
  if (memaddr & 0x01)
2681
402k
    {
2682
402k
      if (micromips_ase)
2683
27.4k
  return print_insn_micromips (memaddr, info);
2684
375k
      else
2685
375k
  return print_insn_mips16 (memaddr, info);
2686
402k
    }
2687
863k
#endif
2688
2689
863k
#if SYMTAB_AVAILABLE
2690
863k
  if (is_compressed_mode_p (info, true))
2691
0
    return print_insn_micromips (memaddr, info);
2692
863k
  if (is_compressed_mode_p (info, false))
2693
0
    return print_insn_mips16 (memaddr, info);
2694
863k
#endif
2695
2696
863k
  status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2697
863k
  if (status == 0)
2698
861k
    {
2699
861k
      int insn;
2700
2701
861k
      if (endianness == BFD_ENDIAN_BIG)
2702
314k
  insn = bfd_getb32 (buffer);
2703
546k
      else
2704
546k
  insn = bfd_getl32 (buffer);
2705
2706
861k
      return print_insn_mips (memaddr, insn, info);
2707
861k
    }
2708
2.36k
  else
2709
2.36k
    {
2710
2.36k
      (*info->memory_error_func) (status, memaddr, info);
2711
2.36k
      return -1;
2712
2.36k
    }
2713
863k
}
2714
2715
int
2716
print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2717
534k
{
2718
534k
  return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2719
534k
}
2720
2721
int
2722
print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2723
1.23M
{
2724
1.23M
  return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2725
1.23M
}
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
}