Coverage Report

Created: 2023-06-29 07:13

/src/binutils-gdb/opcodes/mips-dis.c
Line
Count
Source (jump to first uncovered line)
1
/* Print mips instructions for GDB, the GNU debugger, or for objdump.
2
   Copyright (C) 1989-2023 Free Software Foundation, Inc.
3
   Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
4
5
   This file is part of the GNU opcodes library.
6
7
   This library is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
12
   It is distributed in the hope that it will be useful, but WITHOUT
13
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15
   License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
22
#include "sysdep.h"
23
#include "disassemble.h"
24
#include "libiberty.h"
25
#include "opcode/mips.h"
26
#include "opintl.h"
27
#include "elf-bfd.h"
28
#include "elf/mips.h"
29
#include "elfxx-mips.h"
30
31
/* FIXME: These are needed to figure out if the code is mips16 or
32
   not. The low bit of the address is often a good indicator.  No
33
   symbol table is available when this code runs out in an embedded
34
   system as when it is used for disassembler support in a monitor.  */
35
36
#if !defined(EMBEDDED_ENV)
37
#define SYMTAB_AVAILABLE 1
38
#endif
39
40
/* Mips instructions are at maximum this many bytes long.  */
41
1.92M
#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
15.2k
{
741
15.2k
  const struct mips_abi_choice *c;
742
15.2k
  unsigned int i;
743
744
74.7k
  for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
745
59.4k
    if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
746
59.4k
  && strlen (mips_abi_choices[i].name) == namelen)
747
1.59k
      c = &mips_abi_choices[i];
748
749
15.2k
  return c;
750
15.2k
}
751
752
static const struct mips_arch_choice *
753
choose_arch_by_name (const char *name, unsigned int namelen)
754
65.6k
{
755
65.6k
  const struct mips_arch_choice *c = NULL;
756
65.6k
  unsigned int i;
757
758
2.79M
  for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
759
2.72M
    if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
760
2.72M
  && strlen (mips_arch_choices[i].name) == namelen)
761
38.0k
      c = &mips_arch_choices[i];
762
763
65.6k
  return c;
764
65.6k
}
765
766
static const struct mips_arch_choice *
767
choose_arch_by_number (unsigned long mach)
768
1.93M
{
769
1.93M
  static unsigned long hint_bfd_mach;
770
1.93M
  static const struct mips_arch_choice *hint_arch_choice;
771
1.93M
  const struct mips_arch_choice *c;
772
1.93M
  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.93M
  if (hint_bfd_mach == mach
777
1.93M
      && hint_arch_choice != NULL
778
1.93M
      && hint_arch_choice->bfd_mach == hint_bfd_mach)
779
1.60M
    return hint_arch_choice;
780
781
17.0M
  for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
782
16.7M
    {
783
16.7M
      if (mips_arch_choices[i].bfd_mach_valid
784
16.7M
    && mips_arch_choices[i].bfd_mach == mach)
785
2.35k
  {
786
2.35k
    c = &mips_arch_choices[i];
787
2.35k
    hint_bfd_mach = mach;
788
2.35k
    hint_arch_choice = c;
789
2.35k
  }
790
16.7M
    }
791
329k
  return c;
792
1.93M
}
793
794
/* Check if the object uses NewABI conventions.  */
795
796
static int
797
is_newabi (Elf_Internal_Ehdr *header)
798
706k
{
799
  /* There are no old-style ABIs which use 64-bit ELF.  */
800
706k
  if (header->e_ident[EI_CLASS] == ELFCLASS64)
801
416k
    return 1;
802
803
  /* If a 32-bit ELF file, n32 is a new-style ABI.  */
804
290k
  if ((header->e_flags & EF_MIPS_ABI2) != 0)
805
169
    return 1;
806
807
289k
  return 0;
808
290k
}
809
810
/* Check if the object has microMIPS ASE code.  */
811
812
static int
813
is_micromips (Elf_Internal_Ehdr *header)
814
706k
{
815
706k
  if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
816
68.5k
    return 1;
817
818
637k
  return 0;
819
706k
}
820
821
/* Convert ASE flags from .MIPS.abiflags to internal values.  */
822
823
static unsigned long
824
mips_convert_abiflags_ases (unsigned long afl_ases)
825
0
{
826
0
  unsigned long opcode_ases = 0;
827
828
0
  if (afl_ases & AFL_ASE_DSP)
829
0
    opcode_ases |= ASE_DSP;
830
0
  if (afl_ases & AFL_ASE_DSPR2)
831
0
    opcode_ases |= ASE_DSPR2;
832
0
  if (afl_ases & AFL_ASE_EVA)
833
0
    opcode_ases |= ASE_EVA;
834
0
  if (afl_ases & AFL_ASE_MCU)
835
0
    opcode_ases |= ASE_MCU;
836
0
  if (afl_ases & AFL_ASE_MDMX)
837
0
    opcode_ases |= ASE_MDMX;
838
0
  if (afl_ases & AFL_ASE_MIPS3D)
839
0
    opcode_ases |= ASE_MIPS3D;
840
0
  if (afl_ases & AFL_ASE_MT)
841
0
    opcode_ases |= ASE_MT;
842
0
  if (afl_ases & AFL_ASE_SMARTMIPS)
843
0
    opcode_ases |= ASE_SMARTMIPS;
844
0
  if (afl_ases & AFL_ASE_VIRT)
845
0
    opcode_ases |= ASE_VIRT;
846
0
  if (afl_ases & AFL_ASE_MSA)
847
0
    opcode_ases |= ASE_MSA;
848
0
  if (afl_ases & AFL_ASE_XPA)
849
0
    opcode_ases |= ASE_XPA;
850
0
  if (afl_ases & AFL_ASE_DSPR3)
851
0
    opcode_ases |= ASE_DSPR3;
852
0
  if (afl_ases & AFL_ASE_MIPS16E2)
853
0
    opcode_ases |= ASE_MIPS16E2;
854
0
  return opcode_ases;
855
0
}
856
857
/* Calculate combination ASE flags from regular ASE flags.  */
858
859
static unsigned long
860
mips_calculate_combination_ases (int opcode_isa, unsigned long opcode_ases)
861
2.16M
{
862
2.16M
  unsigned long combination_ases = 0;
863
864
2.16M
  if ((opcode_ases & (ASE_XPA | ASE_VIRT)) == (ASE_XPA | ASE_VIRT))
865
173k
    combination_ases |= ASE_XPA_VIRT;
866
2.16M
  if ((opcode_ases & (ASE_MIPS16E2 | ASE_MT)) == (ASE_MIPS16E2 | ASE_MT))
867
3.83k
    combination_ases |= ASE_MIPS16E2_MT;
868
2.16M
  if ((opcode_ases & ASE_EVA)
869
2.16M
      && ((opcode_isa & INSN_ISA_MASK) == ISA_MIPS64R6
870
177k
    || (opcode_isa & INSN_ISA_MASK) == ISA_MIPS32R6))
871
147k
    combination_ases |= ASE_EVA_R6;
872
2.16M
  return combination_ases;
873
2.16M
}
874
875
static void
876
set_default_mips_dis_options (struct disassemble_info *info)
877
1.93M
{
878
1.93M
  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.93M
  mips_isa = ISA_MIPS3;
884
1.93M
  mips_processor = CPU_R3000;
885
1.93M
  micromips_ase = 0;
886
1.93M
  mips_ase = 0;
887
1.93M
  mips_gpr_names = mips_gpr_names_oldabi;
888
1.93M
  mips_fpr_names = mips_fpr_names_numeric;
889
1.93M
  mips_cp0_names = mips_cp0_names_numeric;
890
1.93M
  mips_cp0sel_names = NULL;
891
1.93M
  mips_cp0sel_names_len = 0;
892
1.93M
  mips_cp1_names = mips_cp1_names_numeric;
893
1.93M
  mips_hwr_names = mips_hwr_names_numeric;
894
1.93M
  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.93M
  chosen_arch = choose_arch_by_number (info->mach);
905
1.93M
  if (chosen_arch != NULL)
906
1.60M
    {
907
1.60M
      mips_processor = chosen_arch->processor;
908
1.60M
      mips_isa = chosen_arch->isa;
909
1.60M
      mips_ase = chosen_arch->ase;
910
1.60M
      mips_cp0_names = chosen_arch->cp0_names;
911
1.60M
      mips_cp0sel_names = chosen_arch->cp0sel_names;
912
1.60M
      mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
913
1.60M
      mips_cp1_names = chosen_arch->cp1_names;
914
1.60M
      mips_hwr_names = chosen_arch->hwr_names;
915
1.60M
    }
916
917
  /* Update settings according to the ELF file header flags.  */
918
1.93M
  if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
919
706k
    {
920
706k
      struct bfd *abfd = info->section->owner;
921
706k
      Elf_Internal_Ehdr *header = elf_elfheader (abfd);
922
706k
      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
706k
#ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
930
706k
      abiflags = bfd_mips_elf_get_abiflags (abfd);
931
706k
#endif
932
      /* If an ELF "newabi" binary, use the n32/(n)64 GPR names.  */
933
706k
      if (is_newabi (header))
934
416k
  mips_gpr_names = mips_gpr_names_newabi;
935
      /* If a microMIPS binary, then don't use MIPS16 bindings.  */
936
706k
      micromips_ase = is_micromips (header);
937
      /* OR in any extra ASE flags set in ELF file structures.  */
938
706k
      if (abiflags)
939
0
  mips_ase |= mips_convert_abiflags_ases (abiflags->ases);
940
706k
      else if (header->e_flags & EF_MIPS_ARCH_ASE_MDMX)
941
75.4k
  mips_ase |= ASE_MDMX;
942
706k
    }
943
1.93M
#endif
944
1.93M
  mips_ase |= mips_calculate_combination_ases (mips_isa, mips_ase);
945
1.93M
}
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
573k
{
953
573k
  if (startswith (option, "msa"))
954
4.64k
    {
955
4.64k
      mips_ase |= ASE_MSA;
956
4.64k
      if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
957
4.64k
     || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
958
4.64k
     || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
959
4.64k
     || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
960
1.98k
    mips_ase |= ASE_MSA64;
961
4.64k
      return true;
962
4.64k
    }
963
964
569k
  if (startswith (option, "virt"))
965
31.0k
    {
966
31.0k
      mips_ase |= ASE_VIRT;
967
31.0k
      if (mips_isa & ISA_MIPS64R2
968
31.0k
    || mips_isa & ISA_MIPS64R3
969
31.0k
    || mips_isa & ISA_MIPS64R5
970
31.0k
    || mips_isa & ISA_MIPS64R6)
971
31.0k
  mips_ase |= ASE_VIRT64;
972
31.0k
      return true;
973
31.0k
    }
974
975
538k
  if (startswith (option, "xpa"))
976
193k
    {
977
193k
      mips_ase |= ASE_XPA;
978
193k
      return true;
979
193k
    }
980
981
344k
  if (startswith (option, "ginv"))
982
1.23k
    {
983
1.23k
      mips_ase |= ASE_GINV;
984
1.23k
      return true;
985
1.23k
    }
986
987
343k
  if (startswith (option, "loongson-mmi"))
988
1.07k
    {
989
1.07k
      mips_ase |= ASE_LOONGSON_MMI;
990
1.07k
      return true;
991
1.07k
    }
992
993
342k
  if (startswith (option, "loongson-cam"))
994
4.62k
    {
995
4.62k
      mips_ase |= ASE_LOONGSON_CAM;
996
4.62k
      return true;
997
4.62k
    }
998
  
999
  /* Put here for match ext2 frist */
1000
337k
  if (startswith (option, "loongson-ext2"))
1001
1.40k
    {
1002
1.40k
      mips_ase |= ASE_LOONGSON_EXT2;
1003
1.40k
      return true;
1004
1.40k
    }
1005
1006
336k
  if (startswith (option, "loongson-ext"))
1007
690
    {
1008
690
      mips_ase |= ASE_LOONGSON_EXT;
1009
690
      return true;
1010
690
    }
1011
1012
335k
  return false;
1013
336k
}
1014
1015
static void
1016
parse_mips_dis_option (const char *option, unsigned int len)
1017
579k
{
1018
579k
  unsigned int i, optionlen, vallen;
1019
579k
  const char *val;
1020
579k
  const struct mips_abi_choice *chosen_abi;
1021
579k
  const struct mips_arch_choice *chosen_arch;
1022
1023
  /* Try to match options that are simple flags */
1024
579k
  if (startswith (option, "no-aliases"))
1025
5.85k
    {
1026
5.85k
      no_aliases = 1;
1027
5.85k
      return;
1028
5.85k
    }
1029
1030
573k
  if (parse_mips_ase_option (option))
1031
238k
    {
1032
238k
      mips_ase |= mips_calculate_combination_ases (mips_isa, mips_ase);
1033
238k
      return;
1034
238k
    }
1035
1036
  /* Look for the = that delimits the end of the option name.  */
1037
4.52M
  for (i = 0; i < len; i++)
1038
4.30M
    if (option[i] == '=')
1039
112k
      break;
1040
1041
335k
  if (i == 0)    /* Invalid option: no name before '='.  */
1042
2.01k
    return;
1043
333k
  if (i == len)    /* Invalid option: no '='.  */
1044
223k
    return;
1045
110k
  if (i == (len - 1))  /* Invalid option: no value after '='.  */
1046
2.33k
    return;
1047
1048
108k
  optionlen = i;
1049
108k
  val = option + (optionlen + 1);
1050
108k
  vallen = len - (optionlen + 1);
1051
1052
108k
  if (strncmp ("gpr-names", option, optionlen) == 0
1053
108k
      && strlen ("gpr-names") == optionlen)
1054
1.32k
    {
1055
1.32k
      chosen_abi = choose_abi_by_name (val, vallen);
1056
1.32k
      if (chosen_abi != NULL)
1057
294
  mips_gpr_names = chosen_abi->gpr_names;
1058
1.32k
      return;
1059
1.32k
    }
1060
1061
106k
  if (strncmp ("fpr-names", option, optionlen) == 0
1062
106k
      && strlen ("fpr-names") == optionlen)
1063
9.82k
    {
1064
9.82k
      chosen_abi = choose_abi_by_name (val, vallen);
1065
9.82k
      if (chosen_abi != NULL)
1066
676
  mips_fpr_names = chosen_abi->fpr_names;
1067
9.82k
      return;
1068
9.82k
    }
1069
1070
96.8k
  if (strncmp ("cp0-names", option, optionlen) == 0
1071
96.8k
      && strlen ("cp0-names") == optionlen)
1072
49.0k
    {
1073
49.0k
      chosen_arch = choose_arch_by_name (val, vallen);
1074
49.0k
      if (chosen_arch != NULL)
1075
35.5k
  {
1076
35.5k
    mips_cp0_names = chosen_arch->cp0_names;
1077
35.5k
    mips_cp0sel_names = chosen_arch->cp0sel_names;
1078
35.5k
    mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1079
35.5k
  }
1080
49.0k
      return;
1081
49.0k
    }
1082
1083
47.8k
  if (strncmp ("cp1-names", option, optionlen) == 0
1084
47.8k
      && strlen ("cp1-names") == optionlen)
1085
11.0k
    {
1086
11.0k
      chosen_arch = choose_arch_by_name (val, vallen);
1087
11.0k
      if (chosen_arch != NULL)
1088
544
  mips_cp1_names = chosen_arch->cp1_names;
1089
11.0k
      return;
1090
11.0k
    }
1091
1092
36.7k
  if (strncmp ("hwr-names", option, optionlen) == 0
1093
36.7k
      && strlen ("hwr-names") == optionlen)
1094
1.39k
    {
1095
1.39k
      chosen_arch = choose_arch_by_name (val, vallen);
1096
1.39k
      if (chosen_arch != NULL)
1097
422
  mips_hwr_names = chosen_arch->hwr_names;
1098
1.39k
      return;
1099
1.39k
    }
1100
1101
35.3k
  if (strncmp ("reg-names", option, optionlen) == 0
1102
35.3k
      && strlen ("reg-names") == optionlen)
1103
4.14k
    {
1104
      /* We check both ABI and ARCH here unconditionally, so
1105
   that "numeric" will do the desirable thing: select
1106
   numeric register names for all registers.  Other than
1107
   that, a given name probably won't match both.  */
1108
4.14k
      chosen_abi = choose_abi_by_name (val, vallen);
1109
4.14k
      if (chosen_abi != NULL)
1110
620
  {
1111
620
    mips_gpr_names = chosen_abi->gpr_names;
1112
620
    mips_fpr_names = chosen_abi->fpr_names;
1113
620
  }
1114
4.14k
      chosen_arch = choose_arch_by_name (val, vallen);
1115
4.14k
      if (chosen_arch != NULL)
1116
1.48k
  {
1117
1.48k
    mips_cp0_names = chosen_arch->cp0_names;
1118
1.48k
    mips_cp0sel_names = chosen_arch->cp0sel_names;
1119
1.48k
    mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1120
1.48k
    mips_cp1_names = chosen_arch->cp1_names;
1121
1.48k
    mips_hwr_names = chosen_arch->hwr_names;
1122
1.48k
  }
1123
4.14k
      return;
1124
4.14k
    }
1125
1126
  /* Invalid option.  */
1127
35.3k
}
1128
1129
static void
1130
parse_mips_dis_options (const char *options)
1131
1.93M
{
1132
1.93M
  const char *option_end;
1133
1134
1.93M
  if (options == NULL)
1135
1.65M
    return;
1136
1137
1.20M
  while (*options != '\0')
1138
926k
    {
1139
      /* Skip empty options.  */
1140
926k
      if (*options == ',')
1141
346k
  {
1142
346k
    options++;
1143
346k
    continue;
1144
346k
  }
1145
1146
      /* We know that *options is neither NUL or a comma.  */
1147
579k
      option_end = options + 1;
1148
9.92M
      while (*option_end != ',' && *option_end != '\0')
1149
9.34M
  option_end++;
1150
1151
579k
      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
579k
      options = option_end;
1156
579k
    }
1157
281k
}
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.62k
{
1165
1.62k
  unsigned int i;
1166
1167
31.5k
  for (i = 0; i < len; i++)
1168
30.4k
    if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1169
497
      return &names[i];
1170
1.12k
  return NULL;
1171
1.62k
}
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.74M
{
1179
2.74M
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1180
1181
2.74M
  switch (type)
1182
2.74M
    {
1183
2.66M
    case OP_REG_GP:
1184
2.66M
      infprintf (info->stream, dis_style_register, "%s",
1185
2.66M
     mips_gpr_names[regno]);
1186
2.66M
      break;
1187
1188
32.4k
    case OP_REG_FP:
1189
32.4k
      infprintf (info->stream, dis_style_register, "%s",
1190
32.4k
     mips_fpr_names[regno]);
1191
32.4k
      break;
1192
1193
2.40k
    case OP_REG_CCC:
1194
2.40k
      if (opcode->pinfo & (FP_D | FP_S))
1195
2.10k
  infprintf (info->stream, dis_style_register, "$fcc%d", regno);
1196
300
      else
1197
300
  infprintf (info->stream, dis_style_register, "$cc%d", regno);
1198
2.40k
      break;
1199
1200
5.19k
    case OP_REG_VEC:
1201
5.19k
      if (opcode->membership & INSN_5400)
1202
801
  infprintf (info->stream, dis_style_register, "$f%d", regno);
1203
4.39k
      else
1204
4.39k
  infprintf (info->stream, dis_style_register, "$v%d", regno);
1205
5.19k
      break;
1206
1207
1.52k
    case OP_REG_ACC:
1208
1.52k
      infprintf (info->stream, dis_style_register, "$ac%d", regno);
1209
1.52k
      break;
1210
1211
13.1k
    case OP_REG_COPRO:
1212
13.1k
      if (opcode->name[strlen (opcode->name) - 1] == '0')
1213
2.33k
  infprintf (info->stream, dis_style_register, "%s", mips_cp0_names[regno]);
1214
10.8k
      else
1215
10.8k
  infprintf (info->stream, dis_style_register, "$%d", regno);
1216
13.1k
      break;
1217
1218
1.30k
    case OP_REG_CONTROL:
1219
1.30k
      if (opcode->name[strlen (opcode->name) - 1] == '1')
1220
497
  infprintf (info->stream, dis_style_register, "%s", mips_cp1_names[regno]);
1221
803
      else
1222
803
  infprintf (info->stream, dis_style_register, "$%d", regno);
1223
1.30k
      break;
1224
1225
664
    case OP_REG_HW:
1226
664
      infprintf (info->stream, dis_style_register, "%s", mips_hwr_names[regno]);
1227
664
      break;
1228
1229
11.2k
    case OP_REG_VF:
1230
11.2k
      infprintf (info->stream, dis_style_register, "$vf%d", regno);
1231
11.2k
      break;
1232
1233
323
    case OP_REG_VI:
1234
323
      infprintf (info->stream, dis_style_register, "$vi%d", regno);
1235
323
      break;
1236
1237
223
    case OP_REG_R5900_I:
1238
223
      infprintf (info->stream, dis_style_register, "$I");
1239
223
      break;
1240
1241
282
    case OP_REG_R5900_Q:
1242
282
      infprintf (info->stream, dis_style_register, "$Q");
1243
282
      break;
1244
1245
194
    case OP_REG_R5900_R:
1246
194
      infprintf (info->stream, dis_style_register, "$R");
1247
194
      break;
1248
1249
218
    case OP_REG_R5900_ACC:
1250
218
      infprintf (info->stream, dis_style_register, "$ACC");
1251
218
      break;
1252
1253
13.8k
    case OP_REG_MSA:
1254
13.8k
      infprintf (info->stream, dis_style_register, "$w%d", regno);
1255
13.8k
      break;
1256
1257
455
    case OP_REG_MSA_CTRL:
1258
455
      infprintf (info->stream, dis_style_register, "%s",
1259
455
     msa_control_names[regno]);
1260
455
      break;
1261
1262
2.74M
    }
1263
2.74M
}
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.42M
{
1285
2.42M
  memset (state, 0, sizeof (*state));
1286
2.42M
}
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
14.6k
{
1296
14.6k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1297
1298
14.6k
  if (operand->size == 4)
1299
10.8k
    infprintf (info->stream, style, "%s%s%s%s",
1300
10.8k
      uval & 8 ? "x" : "",
1301
10.8k
      uval & 4 ? "y" : "",
1302
10.8k
      uval & 2 ? "z" : "",
1303
10.8k
      uval & 1 ? "w" : "");
1304
3.84k
  else if (operand->size == 2)
1305
3.84k
    infprintf (info->stream, style, "%c", "xyzw"[uval]);
1306
0
  else
1307
0
    abort ();
1308
14.6k
}
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.93M
{
1317
3.93M
  state->last_reg_type = reg_type;
1318
3.93M
  state->last_regno = regno;
1319
1320
3.93M
  if (!state->seen_dest)
1321
2.16M
    {
1322
2.16M
      state->seen_dest = 1;
1323
2.16M
      state->dest_regno = regno;
1324
2.16M
    }
1325
3.93M
}
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
10.4k
{
1338
10.4k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1339
10.4k
  unsigned int nargs, nstatics, smask, i, j;
1340
10.4k
  void *is = info->stream;
1341
10.4k
  const char *sep;
1342
1343
10.4k
  if (amask == MIPS_SVRS_ALL_ARGS)
1344
237
    {
1345
237
      nargs = 4;
1346
237
      nstatics = 0;
1347
237
    }
1348
10.1k
  else if (amask == MIPS_SVRS_ALL_STATICS)
1349
417
    {
1350
417
      nargs = 0;
1351
417
      nstatics = 4;
1352
417
    }
1353
9.75k
  else
1354
9.75k
    {
1355
9.75k
      nargs = amask >> 2;
1356
9.75k
      nstatics = amask & 3;
1357
9.75k
    }
1358
1359
10.4k
  sep = "";
1360
10.4k
  if (nargs > 0)
1361
1.91k
    {
1362
1.91k
      infprintf (is, dis_style_register, "%s", mips_gpr_names[4]);
1363
1.91k
      if (nargs > 1)
1364
825
  infprintf (is, dis_style_register, "-%s", mips_gpr_names[4 + nargs - 1]);
1365
1.91k
      sep = ",";
1366
1.91k
    }
1367
1368
10.4k
  infprintf (is, dis_style_text, "%s", sep);
1369
10.4k
  infprintf (is, dis_style_immediate, "%d", frame_size);
1370
1371
10.4k
  if (ra)      /* $ra */
1372
6.71k
    {
1373
6.71k
      infprintf (is, dis_style_text, ",");
1374
6.71k
      infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
1375
6.71k
    }
1376
1377
10.4k
  smask = 0;
1378
10.4k
  if (s0)      /* $s0 */
1379
6.99k
    smask |= 1 << 0;
1380
10.4k
  if (s1)      /* $s1 */
1381
5.35k
    smask |= 1 << 1;
1382
10.4k
  if (nsreg > 0)    /* $s2-$s8 */
1383
3.11k
    smask |= ((1 << nsreg) - 1) << 2;
1384
1385
76.6k
  for (i = 0; i < 9; i++)
1386
66.2k
    if (smask & (1 << i))
1387
8.02k
      {
1388
8.02k
  infprintf (is, dis_style_text, ",");
1389
8.02k
  infprintf (is, dis_style_register, "%s",
1390
8.02k
       mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1391
  /* Skip over string of set bits.  */
1392
28.1k
  for (j = i; smask & (2 << j); j++)
1393
20.1k
    continue;
1394
8.02k
  if (j > i)
1395
5.69k
    {
1396
5.69k
      infprintf (is, dis_style_text, "-");
1397
5.69k
      infprintf (is, dis_style_register, "%s",
1398
5.69k
           mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1399
5.69k
    }
1400
8.02k
  i = j + 1;
1401
8.02k
      }
1402
  /* Statics $ax - $a3.  */
1403
10.4k
  if (nstatics == 1)
1404
1.22k
    {
1405
1.22k
      infprintf (is, dis_style_text, ",");
1406
1.22k
      infprintf (is, dis_style_register, "%s", mips_gpr_names[7]);
1407
1.22k
    }
1408
9.18k
  else if (nstatics > 0)
1409
1.33k
    {
1410
1.33k
      infprintf (is, dis_style_text, ",");
1411
1.33k
      infprintf (is, dis_style_register, "%s",
1412
1.33k
     mips_gpr_names[7 - nstatics + 1]);
1413
1.33k
      infprintf (is, dis_style_text, "-");
1414
1.33k
      infprintf (is, dis_style_register, "%s", mips_gpr_names[7]);
1415
1.33k
    }
1416
10.4k
}
1417
1418
1419
/* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1420
   UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1421
   the base address for OP_PCREL operands.  */
1422
1423
static void
1424
print_insn_arg (struct disassemble_info *info,
1425
    struct mips_print_arg_state *state,
1426
    const struct mips_opcode *opcode,
1427
    const struct mips_operand *operand,
1428
    bfd_vma base_pc,
1429
    unsigned int uval)
1430
4.27M
{
1431
4.27M
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1432
4.27M
  void *is = info->stream;
1433
1434
4.27M
  switch (operand->type)
1435
4.27M
    {
1436
1.22M
    case OP_INT:
1437
1.22M
      {
1438
1.22M
  const struct mips_int_operand *int_op;
1439
1440
1.22M
  int_op = (const struct mips_int_operand *) operand;
1441
1.22M
  uval = mips_decode_int_operand (int_op, uval);
1442
1.22M
  state->last_int = uval;
1443
1.22M
  if (int_op->print_hex)
1444
121k
    infprintf (is, dis_style_immediate, "0x%x", uval);
1445
1.10M
  else
1446
1.10M
    infprintf (is, dis_style_immediate, "%d", uval);
1447
1.22M
      }
1448
1.22M
      break;
1449
1450
10.3k
    case OP_MAPPED_INT:
1451
10.3k
      {
1452
10.3k
  const struct mips_mapped_int_operand *mint_op;
1453
1454
10.3k
  mint_op = (const struct mips_mapped_int_operand *) operand;
1455
10.3k
  uval = mint_op->int_map[uval];
1456
10.3k
  state->last_int = uval;
1457
10.3k
  if (mint_op->print_hex)
1458
5.61k
    infprintf (is, dis_style_immediate, "0x%x", uval);
1459
4.73k
  else
1460
4.73k
    infprintf (is, dis_style_immediate, "%d", uval);
1461
10.3k
      }
1462
10.3k
      break;
1463
1464
3.05k
    case OP_MSB:
1465
3.05k
      {
1466
3.05k
  const struct mips_msb_operand *msb_op;
1467
1468
3.05k
  msb_op = (const struct mips_msb_operand *) operand;
1469
3.05k
  uval += msb_op->bias;
1470
3.05k
  if (msb_op->add_lsb)
1471
1.13k
    uval -= state->last_int;
1472
3.05k
  infprintf (is, dis_style_immediate, "0x%x", uval);
1473
3.05k
      }
1474
3.05k
      break;
1475
1476
2.49M
    case OP_REG:
1477
2.69M
    case OP_OPTIONAL_REG:
1478
2.69M
      {
1479
2.69M
  const struct mips_reg_operand *reg_op;
1480
1481
2.69M
  reg_op = (const struct mips_reg_operand *) operand;
1482
2.69M
  uval = mips_decode_reg_operand (reg_op, uval);
1483
2.69M
  print_reg (info, opcode, reg_op->reg_type, uval);
1484
1485
2.69M
  mips_seen_register (state, uval, reg_op->reg_type);
1486
2.69M
      }
1487
2.69M
      break;
1488
1489
1.28k
    case OP_REG_PAIR:
1490
1.28k
      {
1491
1.28k
  const struct mips_reg_pair_operand *pair_op;
1492
1493
1.28k
  pair_op = (const struct mips_reg_pair_operand *) operand;
1494
1.28k
  print_reg (info, opcode, pair_op->reg_type,
1495
1.28k
       pair_op->reg1_map[uval]);
1496
1.28k
  infprintf (is, dis_style_text, ",");
1497
1.28k
  print_reg (info, opcode, pair_op->reg_type,
1498
1.28k
       pair_op->reg2_map[uval]);
1499
1.28k
      }
1500
1.28k
      break;
1501
1502
247k
    case OP_PCREL:
1503
247k
      {
1504
247k
  const struct mips_pcrel_operand *pcrel_op;
1505
1506
247k
  pcrel_op = (const struct mips_pcrel_operand *) operand;
1507
247k
  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
247k
  if (pcrel_op->include_isa_bit
1512
247k
      && info->flavour != bfd_target_unknown_flavour)
1513
178k
    info->target &= -2;
1514
1515
247k
  (*info->print_address_func) (info->target, info);
1516
247k
      }
1517
247k
      break;
1518
1519
258
    case OP_PERF_REG:
1520
258
      infprintf (is, dis_style_register, "%d", uval);
1521
258
      break;
1522
1523
19.7k
    case OP_ADDIUSP_INT:
1524
19.7k
      {
1525
19.7k
  int sval;
1526
1527
19.7k
  sval = mips_signed_operand (operand, uval) * 4;
1528
19.7k
  if (sval >= -8 && sval < 8)
1529
233
    sval ^= 0x400;
1530
19.7k
  infprintf (is, dis_style_immediate, "%d", sval);
1531
19.7k
  break;
1532
2.49M
      }
1533
1534
919
    case OP_CLO_CLZ_DEST:
1535
919
      {
1536
919
  unsigned int reg1, reg2;
1537
1538
919
  reg1 = uval & 31;
1539
919
  reg2 = uval >> 5;
1540
  /* If one is zero use the other.  */
1541
919
  if (reg1 == reg2 || reg2 == 0)
1542
402
    infprintf (is, dis_style_register, "%s", mips_gpr_names[reg1]);
1543
517
  else if (reg1 == 0)
1544
234
    infprintf (is, dis_style_register, "%s", mips_gpr_names[reg2]);
1545
283
  else
1546
283
    {
1547
      /* Bogus, result depends on processor.  */
1548
283
      infprintf (is, dis_style_register, "%s", mips_gpr_names[reg1]);
1549
283
      infprintf (is, dis_style_text, " or ");
1550
283
      infprintf (is, dis_style_register, "%s", mips_gpr_names[reg2]);
1551
283
    }
1552
919
      }
1553
919
      break;
1554
1555
374
    case OP_SAME_RS_RT:
1556
9.28k
    case OP_CHECK_PREV:
1557
21.3k
    case OP_NON_ZERO_REG:
1558
21.3k
      {
1559
21.3k
  print_reg (info, opcode, OP_REG_GP, uval & 31);
1560
21.3k
  mips_seen_register (state, uval, OP_REG_GP);
1561
21.3k
      }
1562
21.3k
      break;
1563
1564
6.04k
    case OP_LWM_SWM_LIST:
1565
6.04k
      if (operand->size == 2)
1566
3.75k
  {
1567
3.75k
    if (uval == 0)
1568
3.08k
      {
1569
3.08k
        infprintf (is, dis_style_register, "%s",
1570
3.08k
       mips_gpr_names[16]);
1571
3.08k
        infprintf (is, dis_style_text, ",");
1572
3.08k
        infprintf (is, dis_style_register, "%s",
1573
3.08k
       mips_gpr_names[31]);
1574
3.08k
      }
1575
673
    else
1576
673
      {
1577
673
        infprintf (is, dis_style_register, "%s",
1578
673
       mips_gpr_names[16]);
1579
673
        infprintf (is, dis_style_text, "-");
1580
673
        infprintf (is, dis_style_register, "%s",
1581
673
       mips_gpr_names[16 + uval]);
1582
673
        infprintf (is, dis_style_text, ",");
1583
673
        infprintf (is, dis_style_register, "%s",
1584
673
       mips_gpr_names[31]);
1585
673
      }
1586
3.75k
  }
1587
2.28k
      else
1588
2.28k
  {
1589
2.28k
    int s_reg_encode;
1590
1591
2.28k
    s_reg_encode = uval & 0xf;
1592
2.28k
    if (s_reg_encode != 0)
1593
1.79k
      {
1594
1.79k
        if (s_reg_encode == 1)
1595
302
    infprintf (is, dis_style_register, "%s", mips_gpr_names[16]);
1596
1.49k
        else if (s_reg_encode < 9)
1597
716
    {
1598
716
      infprintf (is, dis_style_register, "%s",
1599
716
           mips_gpr_names[16]);
1600
716
      infprintf (is, dis_style_text, "-");
1601
716
      infprintf (is, dis_style_register, "%s",
1602
716
           mips_gpr_names[15 + s_reg_encode]);
1603
716
    }
1604
774
        else if (s_reg_encode == 9)
1605
304
    {
1606
304
      infprintf (is, dis_style_register, "%s",
1607
304
           mips_gpr_names[16]);
1608
304
      infprintf (is, dis_style_text, "-");
1609
304
      infprintf (is, dis_style_register, "%s",
1610
304
           mips_gpr_names[23]);
1611
304
      infprintf (is, dis_style_text, ",");
1612
304
      infprintf (is, dis_style_register, "%s",
1613
304
           mips_gpr_names[30]);
1614
304
    }
1615
470
        else
1616
470
    infprintf (is, dis_style_text, "UNKNOWN");
1617
1.79k
      }
1618
1619
2.28k
    if (uval & 0x10) /* For ra.  */
1620
1.51k
      {
1621
1.51k
        if (s_reg_encode == 0)
1622
244
    infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
1623
1.26k
        else
1624
1.26k
    {
1625
1.26k
      infprintf (is, dis_style_text, ",");
1626
1.26k
      infprintf (is, dis_style_register, "%s",
1627
1.26k
           mips_gpr_names[31]);
1628
1.26k
    }
1629
1.51k
      }
1630
2.28k
  }
1631
6.04k
      break;
1632
1633
3.25k
    case OP_ENTRY_EXIT_LIST:
1634
3.25k
      {
1635
3.25k
  const char *sep;
1636
3.25k
  unsigned int amask, smask;
1637
1638
3.25k
  sep = "";
1639
3.25k
  amask = (uval >> 3) & 7;
1640
3.25k
  if (amask > 0 && amask < 5)
1641
1.57k
    {
1642
1.57k
      infprintf (is, dis_style_register, "%s", mips_gpr_names[4]);
1643
1.57k
      if (amask > 1)
1644
422
        {
1645
422
    infprintf (is, dis_style_text, "-");
1646
422
    infprintf (is, dis_style_register, "%s",
1647
422
         mips_gpr_names[amask + 3]);
1648
422
        }
1649
1.57k
      sep = ",";
1650
1.57k
    }
1651
1652
3.25k
  smask = (uval >> 1) & 3;
1653
3.25k
  if (smask == 3)
1654
1.65k
    {
1655
1.65k
      infprintf (is, dis_style_text, "%s??", sep);
1656
1.65k
      sep = ",";
1657
1.65k
    }
1658
1.59k
  else if (smask > 0)
1659
1.30k
    {
1660
1.30k
      infprintf (is, dis_style_text, "%s", sep);
1661
1.30k
      infprintf (is, dis_style_register, "%s", mips_gpr_names[16]);
1662
1.30k
      if (smask > 1)
1663
750
        {
1664
750
    infprintf (is, dis_style_text, "-");
1665
750
    infprintf (is, dis_style_register, "%s",
1666
750
         mips_gpr_names[smask + 15]);
1667
750
        }
1668
1.30k
      sep = ",";
1669
1.30k
    }
1670
1671
3.25k
  if (uval & 1)
1672
2.50k
    {
1673
2.50k
      infprintf (is, dis_style_text, "%s", sep);
1674
2.50k
      infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
1675
2.50k
      sep = ",";
1676
2.50k
    }
1677
1678
3.25k
  if (amask == 5 || amask == 6)
1679
1.10k
    {
1680
1.10k
      infprintf (is, dis_style_text, "%s", sep);
1681
1.10k
      infprintf (is, dis_style_register, "%s", mips_fpr_names[0]);
1682
1.10k
      if (amask == 6)
1683
509
        {
1684
509
    infprintf (is, dis_style_text, "-");
1685
509
    infprintf (is, dis_style_register, "%s", mips_fpr_names[1]);
1686
509
        }
1687
1.10k
    }
1688
3.25k
      }
1689
3.25k
      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
2.11k
    case OP_MDMX_IMM_REG:
1696
2.11k
      {
1697
2.11k
  unsigned int vsel;
1698
1699
2.11k
  vsel = uval >> 5;
1700
2.11k
  uval &= 31;
1701
2.11k
  if ((vsel & 0x10) == 0)
1702
1.10k
    {
1703
1.10k
      int fmt;
1704
1705
1.10k
      vsel &= 0x0f;
1706
2.49k
      for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1707
2.21k
        if ((vsel & 1) == 0)
1708
817
    break;
1709
1.10k
      print_reg (info, opcode, OP_REG_VEC, uval);
1710
1.10k
      infprintf (is, dis_style_text, "[");
1711
1.10k
      infprintf (is, dis_style_immediate, "%d", vsel >> 1);
1712
1.10k
      infprintf (is, dis_style_text, "]");
1713
1.10k
    }
1714
1.01k
  else if ((vsel & 0x08) == 0)
1715
756
    print_reg (info, opcode, OP_REG_VEC, uval);
1716
258
  else
1717
258
    infprintf (is, dis_style_immediate, "0x%x", uval);
1718
2.11k
      }
1719
2.11k
      break;
1720
1721
24.2k
    case OP_REPEAT_PREV_REG:
1722
24.2k
      print_reg (info, opcode, state->last_reg_type, state->last_regno);
1723
24.2k
      break;
1724
1725
345
    case OP_REPEAT_DEST_REG:
1726
345
      print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1727
345
      break;
1728
1729
3.48k
    case OP_PC:
1730
3.48k
      infprintf (is, dis_style_register, "$pc");
1731
3.48k
      break;
1732
1733
1.17k
    case OP_REG28:
1734
1.17k
      print_reg (info, opcode, OP_REG_GP, 28);
1735
1.17k
      break;
1736
1737
716
    case OP_VU0_SUFFIX:
1738
11.0k
    case OP_VU0_MATCH_SUFFIX:
1739
11.0k
      print_vu0_channel (info, operand, uval, dis_style_register);
1740
11.0k
      break;
1741
1742
1.56k
    case OP_IMM_INDEX:
1743
1.56k
      infprintf (is, dis_style_text, "[");
1744
1.56k
      infprintf (is, dis_style_immediate, "%d", uval);
1745
1.56k
      infprintf (is, dis_style_text, "]");
1746
1.56k
      break;
1747
1748
271
    case OP_REG_INDEX:
1749
271
      infprintf (is, dis_style_text, "[");
1750
271
      print_reg (info, opcode, OP_REG_GP, uval);
1751
271
      infprintf (is, dis_style_text, "]");
1752
271
      break;
1753
4.27M
    }
1754
4.27M
}
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
789k
{
1764
789k
  struct mips_print_arg_state state;
1765
789k
  const struct mips_operand *operand;
1766
789k
  const char *s;
1767
789k
  unsigned int uval;
1768
1769
789k
  init_print_arg_state (&state);
1770
4.22M
  for (s = opcode->args; *s; ++s)
1771
3.45M
    {
1772
3.45M
      switch (*s)
1773
3.45M
  {
1774
908k
  case ',':
1775
1.20M
  case '(':
1776
1.50M
  case ')':
1777
1.50M
    break;
1778
1779
259
  case '#':
1780
259
    ++s;
1781
259
    break;
1782
1783
1.94M
  default:
1784
1.94M
    operand = decode_operand (s);
1785
1786
1.94M
    if (operand)
1787
1.94M
      {
1788
1.94M
        uval = mips_extract_operand (operand, insn);
1789
1.94M
        switch (operand->type)
1790
1.94M
    {
1791
1.06M
    case OP_REG:
1792
1.22M
    case OP_OPTIONAL_REG:
1793
1.22M
      {
1794
1.22M
        const struct mips_reg_operand *reg_op;
1795
1796
1.22M
        reg_op = (const struct mips_reg_operand *) operand;
1797
1.22M
        uval = mips_decode_reg_operand (reg_op, uval);
1798
1.22M
        mips_seen_register (&state, uval, reg_op->reg_type);
1799
1.22M
      }
1800
1.22M
    break;
1801
1802
5.35k
    case OP_SAME_RS_RT:
1803
5.35k
      {
1804
5.35k
        unsigned int reg1, reg2;
1805
1806
5.35k
        reg1 = uval & 31;
1807
5.35k
        reg2 = uval >> 5;
1808
1809
5.35k
        if (reg1 != reg2 || reg1 == 0)
1810
4.98k
          return false;
1811
5.35k
      }
1812
374
    break;
1813
1814
14.3k
    case OP_CHECK_PREV:
1815
14.3k
      {
1816
14.3k
        const struct mips_check_prev_operand *prev_op;
1817
1818
14.3k
        prev_op = (const struct mips_check_prev_operand *) operand;
1819
1820
14.3k
        if (!prev_op->zero_ok && uval == 0)
1821
802
          return false;
1822
1823
13.5k
        if (((prev_op->less_than_ok && uval < state.last_regno)
1824
13.5k
      || (prev_op->greater_than_ok && uval > state.last_regno)
1825
13.5k
      || (prev_op->equal_ok && uval == state.last_regno)))
1826
8.91k
          break;
1827
1828
4.64k
        return false;
1829
13.5k
      }
1830
1831
13.9k
    case OP_NON_ZERO_REG:
1832
13.9k
      {
1833
13.9k
        if (uval == 0)
1834
1.07k
          return false;
1835
13.9k
      }
1836
12.8k
    break;
1837
1838
494k
    case OP_INT:
1839
505k
    case OP_MAPPED_INT:
1840
507k
    case OP_MSB:
1841
509k
    case OP_REG_PAIR:
1842
621k
    case OP_PCREL:
1843
621k
    case OP_PERF_REG:
1844
641k
    case OP_ADDIUSP_INT:
1845
642k
    case OP_CLO_CLZ_DEST:
1846
648k
    case OP_LWM_SWM_LIST:
1847
648k
    case OP_ENTRY_EXIT_LIST:
1848
650k
    case OP_MDMX_IMM_REG:
1849
674k
    case OP_REPEAT_PREV_REG:
1850
675k
    case OP_REPEAT_DEST_REG:
1851
678k
    case OP_PC:
1852
678k
    case OP_REG28:
1853
678k
    case OP_VU0_SUFFIX:
1854
689k
    case OP_VU0_MATCH_SUFFIX:
1855
690k
    case OP_IMM_INDEX:
1856
691k
    case OP_REG_INDEX:
1857
691k
    case OP_SAVE_RESTORE_LIST:
1858
691k
      break;
1859
1.94M
    }
1860
1.94M
      }
1861
1.93M
    if (*s == 'm' || *s == '+' || *s == '-')
1862
384k
      ++s;
1863
3.45M
  }
1864
3.45M
    }
1865
778k
  return true;
1866
789k
}
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
717k
{
1879
717k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1880
717k
  void *is = info->stream;
1881
717k
  struct mips_print_arg_state state;
1882
717k
  const struct mips_operand *operand;
1883
717k
  const char *s;
1884
1885
717k
  init_print_arg_state (&state);
1886
4.14M
  for (s = opcode->args; *s; ++s)
1887
3.42M
    {
1888
3.42M
      switch (*s)
1889
3.42M
  {
1890
902k
  case ',':
1891
1.19M
  case '(':
1892
1.49M
  case ')':
1893
1.49M
    infprintf (is, dis_style_text, "%c", *s);
1894
1.49M
    break;
1895
1896
259
  case '#':
1897
259
    ++s;
1898
259
    infprintf (is, dis_style_text, "%c%c", *s, *s);
1899
259
    break;
1900
1901
1.92M
  default:
1902
1.92M
    operand = decode_operand (s);
1903
1.92M
    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.92M
    if (operand->type == OP_SAVE_RESTORE_LIST)
1913
279
      {
1914
        /* Handle this case here because of the complex behavior.  */
1915
279
        unsigned int amask = (insn >> 15) & 0xf;
1916
279
        unsigned int nsreg = (insn >> 23) & 0x7;
1917
279
        unsigned int ra = insn & 0x1000;      /* $ra */
1918
279
        unsigned int s0 = insn & 0x800;     /* $s0 */
1919
279
        unsigned int s1 = insn & 0x400;     /* $s1 */
1920
279
        unsigned int frame_size = (((insn >> 15) & 0xf0)
1921
279
           | ((insn >> 6) & 0x0f)) * 8;
1922
279
        mips_print_save_restore (info, amask, nsreg, ra, s0, s1,
1923
279
               frame_size);
1924
279
      }
1925
1.92M
    else if (operand->type == OP_REG
1926
1.92M
       && s[1] == ','
1927
1.92M
       && s[2] == 'H'
1928
1.92M
       && opcode->name[strlen (opcode->name) - 1] == '0')
1929
964
      {
1930
        /* Coprocessor register 0 with sel field.  */
1931
964
        const struct mips_cp0sel_name *n;
1932
964
        unsigned int reg, sel;
1933
1934
964
        reg = mips_extract_operand (operand, insn);
1935
964
        s += 2;
1936
964
        operand = decode_operand (s);
1937
964
        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
964
        n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1945
964
             mips_cp0sel_names_len,
1946
964
             reg, sel);
1947
964
        if (n != NULL)
1948
271
    infprintf (is, dis_style_register, "%s", n->name);
1949
693
        else
1950
693
    {
1951
693
      infprintf (is, dis_style_register, "$%d", reg);
1952
693
      infprintf (is, dis_style_text, ",");
1953
693
      infprintf (is, dis_style_immediate, "%d", sel);
1954
693
    }
1955
964
      }
1956
1.92M
    else
1957
1.92M
      {
1958
1.92M
        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.92M
        if (operand->type == OP_PCREL)
1964
112k
    {
1965
112k
      const struct mips_pcrel_operand *pcrel_op;
1966
1967
112k
      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
112k
      if (pcrel_op->include_isa_bit)
1971
110k
        base_pc += length;
1972
112k
    }
1973
1974
1.92M
        print_insn_arg (info, &state, opcode, operand, base_pc,
1975
1.92M
            mips_extract_operand (operand, insn));
1976
1.92M
      }
1977
1.92M
    if (*s == 'm' || *s == '+' || *s == '-')
1978
383k
      ++s;
1979
1.92M
    break;
1980
3.42M
  }
1981
3.42M
    }
1982
717k
}
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
639k
{
1994
639k
#define GET_OP(insn, field)     \
1995
750k
  (((insn) >> OP_SH_##field) & OP_MASK_##field)
1996
639k
  static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1997
639k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1998
639k
  const struct mips_opcode *op;
1999
639k
  static bool init = 0;
2000
639k
  void *is = info->stream;
2001
2002
  /* Build a hash table to shorten the search time.  */
2003
639k
  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
639k
  info->bytes_per_chunk = INSNLEN;
2026
639k
  info->display_endian = info->endian;
2027
639k
  info->insn_info_valid = 1;
2028
639k
  info->branch_delay_insns = 0;
2029
639k
  info->data_size = 0;
2030
639k
  info->insn_type = dis_nonbranch;
2031
639k
  info->target = 0;
2032
639k
  info->target2 = 0;
2033
2034
639k
  op = mips_hash[GET_OP (word, OP)];
2035
639k
  if (op != NULL)
2036
639k
    {
2037
546M
      for (; op < &mips_opcodes[NUMOPCODES]; op++)
2038
546M
  {
2039
546M
    if (op->pinfo != INSN_MACRO
2040
546M
        && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2041
546M
        && (word & op->mask) == op->match)
2042
710k
      {
2043
        /* We always disassemble the jalx instruction, except for MIPS r6.  */
2044
710k
        if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
2045
710k
     && (strcmp (op->name, "jalx")
2046
207k
         || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
2047
207k
         || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
2048
207k
    continue;
2049
2050
        /* Figure out instruction type and branch delay information.  */
2051
503k
        if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2052
38.3k
          {
2053
38.3k
      if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2054
22.9k
        info->insn_type = dis_jsr;
2055
15.3k
      else
2056
15.3k
        info->insn_type = dis_branch;
2057
38.3k
      info->branch_delay_insns = 1;
2058
38.3k
    }
2059
465k
        else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
2060
465k
             | INSN_COND_BRANCH_LIKELY)) != 0)
2061
38.0k
    {
2062
38.0k
      if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2063
798
        info->insn_type = dis_condjsr;
2064
37.2k
      else
2065
37.2k
        info->insn_type = dis_condbranch;
2066
38.0k
      info->branch_delay_insns = 1;
2067
38.0k
    }
2068
427k
        else if ((op->pinfo & (INSN_STORE_MEMORY
2069
427k
             | INSN_LOAD_MEMORY)) != 0)
2070
188k
    info->insn_type = dis_dref;
2071
2072
503k
        if (!validate_insn_args (op, decode_mips_operand, word))
2073
11.4k
    continue;
2074
2075
491k
        infprintf (is, dis_style_mnemonic, "%s", op->name);
2076
491k
        if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
2077
3.68k
    {
2078
3.68k
      unsigned int uval;
2079
2080
3.68k
      infprintf (is, dis_style_mnemonic, ".");
2081
3.68k
      uval = mips_extract_operand (&mips_vu0_channel_mask, word);
2082
3.68k
      print_vu0_channel (info, &mips_vu0_channel_mask, uval,
2083
3.68k
             dis_style_mnemonic);
2084
3.68k
    }
2085
2086
491k
        if (op->args[0])
2087
454k
    {
2088
454k
      infprintf (is, dis_style_text, "\t");
2089
454k
      print_insn_args (info, op, decode_mips_operand, word,
2090
454k
           memaddr, 4);
2091
454k
    }
2092
2093
491k
        return INSNLEN;
2094
503k
      }
2095
546M
  }
2096
639k
    }
2097
147k
#undef GET_OP
2098
2099
  /* Handle undefined instructions.  */
2100
147k
  info->insn_type = dis_noninsn;
2101
147k
  infprintf (is, dis_style_assembler_directive, ".word");
2102
147k
  infprintf (is, dis_style_text, "\t");
2103
147k
  infprintf (is, dis_style_immediate, "0x%x", word);
2104
147k
  return INSNLEN;
2105
639k
}
2106

2107
/* Disassemble an operand for a mips16 instruction.  */
2108
2109
static void
2110
print_mips16_insn_arg (struct disassemble_info *info,
2111
           struct mips_print_arg_state *state,
2112
           const struct mips_opcode *opcode,
2113
           char type, bfd_vma memaddr,
2114
           unsigned insn, bool use_extend,
2115
           unsigned extend, bool is_offset)
2116
4.01M
{
2117
4.01M
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
2118
4.01M
  void *is = info->stream;
2119
4.01M
  const struct mips_operand *operand, *ext_operand;
2120
4.01M
  unsigned short ext_size;
2121
4.01M
  unsigned int uval;
2122
4.01M
  bfd_vma baseaddr;
2123
2124
4.01M
  if (!use_extend)
2125
3.84M
    extend = 0;
2126
2127
4.01M
  switch (type)
2128
4.01M
    {
2129
1.21M
    case ',':
2130
1.43M
    case '(':
2131
1.66M
    case ')':
2132
1.66M
      infprintf (is, dis_style_text, "%c", type);
2133
1.66M
      break;
2134
2135
2.35M
    default:
2136
2.35M
      operand = decode_mips16_operand (type, false);
2137
2.35M
      if (!operand)
2138
0
  {
2139
    /* xgettext:c-format */
2140
0
    infprintf (is, dis_style_text, _("# internal error, undefined operand in `%s %s'"),
2141
0
         opcode->name, opcode->args);
2142
0
    return;
2143
0
  }
2144
2145
2.35M
      if (operand->type == OP_SAVE_RESTORE_LIST)
2146
10.1k
  {
2147
    /* Handle this case here because of the complex interaction
2148
       with the EXTEND opcode.  */
2149
10.1k
    unsigned int amask = extend & 0xf;
2150
10.1k
    unsigned int nsreg = (extend >> 8) & 0x7;
2151
10.1k
    unsigned int ra = insn & 0x40;      /* $ra */
2152
10.1k
    unsigned int s0 = insn & 0x20;      /* $s0 */
2153
10.1k
    unsigned int s1 = insn & 0x10;      /* $s1 */
2154
10.1k
    unsigned int frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
2155
10.1k
    if (frame_size == 0 && !use_extend)
2156
2.88k
      frame_size = 128;
2157
10.1k
    mips_print_save_restore (info, amask, nsreg, ra, s0, s1, frame_size);
2158
10.1k
    break;
2159
10.1k
  }
2160
2161
2.34M
      if (is_offset && operand->type == OP_INT)
2162
223k
  {
2163
223k
    const struct mips_int_operand *int_op;
2164
2165
223k
    int_op = (const struct mips_int_operand *) operand;
2166
223k
    info->insn_type = dis_dref;
2167
223k
    info->data_size = 1 << int_op->shift;
2168
223k
  }
2169
2170
2.34M
      ext_size = 0;
2171
2.34M
      if (use_extend)
2172
106k
  {
2173
106k
    ext_operand = decode_mips16_operand (type, true);
2174
106k
    if (ext_operand != operand
2175
106k
        || (operand->type == OP_INT && operand->lsb == 0
2176
73.9k
      && mips_opcode_32bit_p (opcode)))
2177
34.8k
      {
2178
34.8k
        ext_size = ext_operand->size;
2179
34.8k
        operand = ext_operand;
2180
34.8k
      }
2181
106k
  }
2182
2.34M
      if (operand->size == 26)
2183
14.5k
  uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
2184
2.33M
      else if (ext_size == 16 || ext_size == 9)
2185
31.0k
  uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
2186
2.30M
      else if (ext_size == 15)
2187
1.70k
  uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
2188
2.30M
      else if (ext_size == 6)
2189
980
  uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
2190
2.29M
      else
2191
2.29M
  uval = mips_extract_operand (operand, (extend << 16) | insn);
2192
2.34M
      if (ext_size == 9)
2193
922
  uval &= (1U << ext_size) - 1;
2194
2195
2.34M
      baseaddr = memaddr + 2;
2196
2.34M
      if (operand->type == OP_PCREL)
2197
135k
  {
2198
135k
    const struct mips_pcrel_operand *pcrel_op;
2199
2200
135k
    pcrel_op = (const struct mips_pcrel_operand *) operand;
2201
135k
    if (!pcrel_op->include_isa_bit && use_extend)
2202
2.64k
      baseaddr = memaddr - 2;
2203
132k
    else if (!pcrel_op->include_isa_bit)
2204
42.4k
      {
2205
42.4k
        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
42.4k
        if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
2215
42.4k
      && (((info->endian == BFD_ENDIAN_BIG
2216
20.7k
      ? bfd_getb16 (buffer)
2217
20.7k
      : bfd_getl16 (buffer))
2218
20.7k
           & 0xf800) == 0x1800))
2219
449
    baseaddr = memaddr - 4;
2220
42.0k
        else if (info->read_memory_func (memaddr - 2, buffer, 2,
2221
42.0k
                 info) == 0
2222
42.0k
           && (((info->endian == BFD_ENDIAN_BIG
2223
20.3k
           ? bfd_getb16 (buffer)
2224
20.3k
           : bfd_getl16 (buffer))
2225
20.3k
          & 0xf89f) == 0xe800)
2226
42.0k
           && (((info->endian == BFD_ENDIAN_BIG
2227
85
           ? bfd_getb16 (buffer)
2228
85
           : bfd_getl16 (buffer))
2229
85
          & 0x0060) != 0x0060))
2230
85
    baseaddr = memaddr - 2;
2231
41.9k
        else
2232
41.9k
    baseaddr = memaddr;
2233
42.4k
      }
2234
135k
  }
2235
2236
2.34M
      print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
2237
2.34M
      break;
2238
4.01M
    }
2239
4.01M
}
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
939k
{
2249
939k
  if (info->symbols
2250
939k
      && info->symbols[0]
2251
939k
      && (info->symbols[0]->flags & BSF_SYNTHETIC)
2252
939k
      && addr == bfd_asymbol_value (info->symbols[0]) + 12)
2253
0
    return true;
2254
2255
939k
  return false;
2256
939k
}
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
939k
{
2272
939k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
2273
939k
  int status;
2274
939k
  bfd_byte buffer[4];
2275
939k
  const struct mips_opcode *op, *opend;
2276
939k
  struct mips_print_arg_state state;
2277
939k
  void *is = info->stream;
2278
939k
  bool have_second;
2279
939k
  bool extend_only;
2280
939k
  unsigned int second;
2281
939k
  unsigned int first;
2282
939k
  unsigned int full;
2283
2284
939k
  info->bytes_per_chunk = 2;
2285
939k
  info->display_endian = info->endian;
2286
939k
  info->insn_info_valid = 1;
2287
939k
  info->branch_delay_insns = 0;
2288
939k
  info->data_size = 0;
2289
939k
  info->target = 0;
2290
939k
  info->target2 = 0;
2291
2292
939k
#define GET_OP(insn, field) \
2293
939k
  (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2294
  /* Decode PLT entry's GOT slot address word.  */
2295
939k
  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
939k
  else
2315
939k
    {
2316
939k
      info->insn_type = dis_nonbranch;
2317
939k
      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2318
939k
    }
2319
939k
  if (status != 0)
2320
1.91k
    {
2321
1.91k
      (*info->memory_error_func) (status, memaddr, info);
2322
1.91k
      return -1;
2323
1.91k
    }
2324
2325
937k
  extend_only = false;
2326
2327
937k
  if (info->endian == BFD_ENDIAN_BIG)
2328
143k
    first = bfd_getb16 (buffer);
2329
793k
  else
2330
793k
    first = bfd_getl16 (buffer);
2331
2332
937k
  status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2333
937k
  if (status == 0)
2334
935k
    {
2335
935k
      have_second = true;
2336
935k
      if (info->endian == BFD_ENDIAN_BIG)
2337
143k
  second = bfd_getb16 (buffer);
2338
792k
      else
2339
792k
  second = bfd_getl16 (buffer);
2340
935k
      full = (first << 16) | second;
2341
935k
    }
2342
1.78k
  else
2343
1.78k
    {
2344
1.78k
      have_second = false;
2345
1.78k
      second = 0;
2346
1.78k
      full = first;
2347
1.78k
    }
2348
2349
  /* FIXME: Should probably use a hash table on the major opcode here.  */
2350
2351
937k
  opend = mips16_opcodes + bfd_mips16_num_opcodes;
2352
85.3M
  for (op = mips16_opcodes; op < opend; op++)
2353
85.3M
    {
2354
85.3M
      enum match_kind match;
2355
2356
85.3M
      if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor))
2357
10.3M
  continue;
2358
2359
74.9M
      if (op->pinfo == INSN_MACRO
2360
74.9M
    || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2361
16.9M
  match = MATCH_NONE;
2362
57.9M
      else if (mips_opcode_32bit_p (op))
2363
9.22M
  {
2364
9.22M
    if (have_second
2365
9.22M
        && (full & op->mask) == op->match)
2366
21.0k
      match = MATCH_FULL;
2367
9.20M
    else
2368
9.20M
      match = MATCH_NONE;
2369
9.22M
  }
2370
48.7M
      else if ((first & op->mask) == op->match)
2371
868k
  {
2372
868k
    match = MATCH_SHORT;
2373
868k
    second = 0;
2374
868k
    full = first;
2375
868k
  }
2376
47.8M
      else if ((first & 0xf800) == 0xf000
2377
47.8M
         && have_second
2378
47.8M
         && !extend_only
2379
47.8M
         && (second & op->mask) == op->match)
2380
40.1k
  {
2381
40.1k
    if (op->pinfo2 & INSN2_SHORT_ONLY)
2382
6.78k
      {
2383
6.78k
        match = MATCH_NONE;
2384
6.78k
        extend_only = true;
2385
6.78k
      }
2386
33.3k
    else
2387
33.3k
      match = MATCH_FULL;
2388
40.1k
  }
2389
47.8M
      else
2390
47.8M
  match = MATCH_NONE;
2391
2392
74.9M
      if (match != MATCH_NONE)
2393
922k
  {
2394
922k
    const char *s;
2395
2396
922k
    infprintf (is, dis_style_mnemonic, "%s", op->name);
2397
922k
    if (op->args[0] != '\0')
2398
922k
      infprintf (is, dis_style_text, "\t");
2399
2400
922k
    init_print_arg_state (&state);
2401
4.94M
    for (s = op->args; *s != '\0'; s++)
2402
4.02M
      {
2403
4.02M
        if (*s == ','
2404
4.02M
      && s[1] == 'w'
2405
4.02M
      && GET_OP (full, RX) == GET_OP (full, RY))
2406
4.03k
    {
2407
      /* Skip the register and the comma.  */
2408
4.03k
      ++s;
2409
4.03k
      continue;
2410
4.03k
    }
2411
4.02M
        if (*s == ','
2412
4.02M
      && s[1] == 'v'
2413
4.02M
      && GET_OP (full, RZ) == GET_OP (full, RX))
2414
2.27k
    {
2415
      /* Skip the register and the comma.  */
2416
2.27k
      ++s;
2417
2.27k
      continue;
2418
2.27k
    }
2419
4.01M
        if (s[0] == 'N'
2420
4.01M
      && s[1] == ','
2421
4.01M
      && s[2] == 'O'
2422
4.01M
      && op->name[strlen (op->name) - 1] == '0')
2423
662
    {
2424
      /* Coprocessor register 0 with sel field.  */
2425
662
      const struct mips_cp0sel_name *n;
2426
662
      const struct mips_operand *operand;
2427
662
      unsigned int reg, sel;
2428
2429
662
      operand = decode_mips16_operand (*s, true);
2430
662
      reg = mips_extract_operand (operand, (first << 16) | second);
2431
662
      s += 2;
2432
662
      operand = decode_mips16_operand (*s, true);
2433
662
      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
662
      n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2441
662
                 mips_cp0sel_names_len,
2442
662
                 reg, sel);
2443
662
      if (n != NULL)
2444
226
        infprintf (is, dis_style_register, "%s", n->name);
2445
436
      else
2446
436
        {
2447
436
          infprintf (is, dis_style_register, "$%d", reg);
2448
436
          infprintf (is, dis_style_text, ",");
2449
436
          infprintf (is, dis_style_immediate, "%d", sel);
2450
436
        }
2451
662
    }
2452
4.01M
        else
2453
4.01M
    switch (match)
2454
4.01M
      {
2455
177k
        case MATCH_FULL:
2456
177k
          print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
2457
177k
               second, true, first, s[1] == '(');
2458
177k
          break;
2459
3.84M
        case MATCH_SHORT:
2460
3.84M
          print_mips16_insn_arg (info, &state, op, *s, memaddr,
2461
3.84M
               first, false, 0, s[1] == '(');
2462
3.84M
          break;
2463
0
        case MATCH_NONE:  /* Stop the compiler complaining.  */
2464
0
          break;
2465
4.01M
      }
2466
4.01M
      }
2467
2468
    /* Figure out branch instruction type and delay slot information.  */
2469
922k
    if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2470
17.2k
      info->branch_delay_insns = 1;
2471
922k
    if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2472
922k
        || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
2473
41.1k
      {
2474
41.1k
        if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2475
15.2k
    info->insn_type = dis_jsr;
2476
25.9k
        else
2477
25.9k
    info->insn_type = dis_branch;
2478
41.1k
      }
2479
881k
    else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
2480
52.1k
      info->insn_type = dis_condbranch;
2481
2482
922k
    return match == MATCH_FULL ? 4 : 2;
2483
922k
  }
2484
74.9M
    }
2485
14.5k
#undef GET_OP
2486
2487
14.5k
  infprintf (is, dis_style_assembler_directive, ".short");
2488
14.5k
  infprintf (is, dis_style_text, "\t");
2489
14.5k
  infprintf (is, dis_style_immediate, "0x%x", first);
2490
14.5k
  info->insn_type = dis_noninsn;
2491
2492
14.5k
  return 2;
2493
937k
}
2494
2495
/* Disassemble microMIPS instructions.  */
2496
2497
static int
2498
print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2499
350k
{
2500
350k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
2501
350k
  const struct mips_opcode *op, *opend;
2502
350k
  void *is = info->stream;
2503
350k
  bfd_byte buffer[2];
2504
350k
  unsigned int higher;
2505
350k
  unsigned int length;
2506
350k
  int status;
2507
350k
  unsigned int insn;
2508
2509
350k
  info->bytes_per_chunk = 2;
2510
350k
  info->display_endian = info->endian;
2511
350k
  info->insn_info_valid = 1;
2512
350k
  info->branch_delay_insns = 0;
2513
350k
  info->data_size = 0;
2514
350k
  info->insn_type = dis_nonbranch;
2515
350k
  info->target = 0;
2516
350k
  info->target2 = 0;
2517
2518
350k
  status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2519
350k
  if (status != 0)
2520
716
    {
2521
716
      (*info->memory_error_func) (status, memaddr, info);
2522
716
      return -1;
2523
716
    }
2524
2525
350k
  length = 2;
2526
2527
350k
  if (info->endian == BFD_ENDIAN_BIG)
2528
671
    insn = bfd_getb16 (buffer);
2529
349k
  else
2530
349k
    insn = bfd_getl16 (buffer);
2531
2532
350k
  if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2533
233k
    {
2534
      /* This is a 32-bit microMIPS instruction.  */
2535
233k
      higher = insn;
2536
2537
233k
      status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2538
233k
      if (status != 0)
2539
332
  {
2540
332
    infprintf (is, dis_style_text, "micromips 0x%x", higher);
2541
332
    (*info->memory_error_func) (status, memaddr + 2, info);
2542
332
    return -1;
2543
332
  }
2544
2545
233k
      if (info->endian == BFD_ENDIAN_BIG)
2546
521
  insn = bfd_getb16 (buffer);
2547
233k
      else
2548
233k
  insn = bfd_getl16 (buffer);
2549
2550
233k
      insn = insn | (higher << 16);
2551
2552
233k
      length += 2;
2553
233k
    }
2554
2555
  /* FIXME: Should probably use a hash table on the major opcode here.  */
2556
2557
349k
  opend = micromips_opcodes + bfd_micromips_num_opcodes;
2558
209M
  for (op = micromips_opcodes; op < opend; op++)
2559
209M
    {
2560
209M
      if (op->pinfo != INSN_MACRO
2561
209M
    && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2562
209M
    && (insn & op->mask) == op->match
2563
209M
    && ((length == 2 && (op->mask & 0xffff0000) == 0)
2564
353k
        || (length == 4 && (op->mask & 0xffff0000) != 0)))
2565
286k
  {
2566
286k
    if (!validate_insn_args (op, decode_micromips_operand, insn))
2567
0
      continue;
2568
2569
286k
    infprintf (is, dis_style_mnemonic, "%s", op->name);
2570
2571
286k
    if (op->args[0])
2572
263k
      {
2573
263k
        infprintf (is, dis_style_text, "\t");
2574
263k
        print_insn_args (info, op, decode_micromips_operand, insn,
2575
263k
             memaddr + 1, length);
2576
263k
      }
2577
2578
    /* Figure out instruction type and branch delay information.  */
2579
286k
    if ((op->pinfo
2580
286k
         & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2581
33.9k
      info->branch_delay_insns = 1;
2582
286k
    if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2583
286k
         | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2584
21.3k
      {
2585
21.3k
        if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2586
14.5k
    info->insn_type = dis_jsr;
2587
6.80k
        else
2588
6.80k
    info->insn_type = dis_branch;
2589
21.3k
      }
2590
264k
    else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2591
264k
        | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2592
13.1k
      {
2593
13.1k
        if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2594
538
    info->insn_type = dis_condjsr;
2595
12.6k
        else
2596
12.6k
    info->insn_type = dis_condbranch;
2597
13.1k
      }
2598
251k
    else if ((op->pinfo
2599
251k
        & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
2600
104k
      info->insn_type = dis_dref;
2601
2602
286k
    return length;
2603
286k
  }
2604
209M
    }
2605
2606
63.8k
  infprintf (is, dis_style_assembler_directive, ".short");
2607
63.8k
  infprintf (is, dis_style_text, "\t");
2608
63.8k
  if (length != 2)
2609
49.6k
    {
2610
49.6k
      infprintf (is, dis_style_immediate, "0x%x", (insn >> 16) & 0xffff);
2611
49.6k
      infprintf (is, dis_style_text, ", ");
2612
49.6k
    }
2613
63.8k
  infprintf (is, dis_style_immediate, "0x%x", (insn & 0xffff));
2614
2615
63.8k
  info->insn_type = dis_noninsn;
2616
2617
63.8k
  return length;
2618
349k
}
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.28M
{
2631
1.28M
  int i;
2632
1.28M
  int l;
2633
2634
1.65M
  for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2635
372k
    if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
2636
372k
  && ((!micromips_p
2637
0
       && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
2638
0
      || (micromips_p
2639
0
    && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2640
0
      return 1;
2641
372k
    else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2642
372k
        && info->symtab[i]->section == info->section)
2643
372k
      {
2644
372k
  elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
2645
372k
  if ((!micromips_p
2646
372k
       && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2647
372k
      || (micromips_p
2648
372k
    && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2649
0
    return 1;
2650
372k
      }
2651
2652
1.28M
  return 0;
2653
1.28M
}
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.93M
{
2666
1.93M
  bfd_byte buffer[INSNLEN];
2667
1.93M
  int status;
2668
2669
1.93M
  set_default_mips_dis_options (info);
2670
1.93M
  parse_mips_dis_options (info->disassembler_options);
2671
2672
1.93M
  if (info->mach == bfd_mach_mips16)
2673
465k
    return print_insn_mips16 (memaddr, info);
2674
1.46M
  if (info->mach == bfd_mach_mips_micromips)
2675
308k
    return print_insn_micromips (memaddr, info);
2676
2677
1.15M
#if 1
2678
  /* FIXME: If odd address, this is CLEARLY a compressed instruction.  */
2679
  /* Only a few tools will work this way.  */
2680
1.15M
  if (memaddr & 0x01)
2681
515k
    {
2682
515k
      if (micromips_ase)
2683
42.3k
  return print_insn_micromips (memaddr, info);
2684
473k
      else
2685
473k
  return print_insn_mips16 (memaddr, info);
2686
515k
    }
2687
641k
#endif
2688
2689
641k
#if SYMTAB_AVAILABLE
2690
641k
  if (is_compressed_mode_p (info, true))
2691
0
    return print_insn_micromips (memaddr, info);
2692
641k
  if (is_compressed_mode_p (info, false))
2693
0
    return print_insn_mips16 (memaddr, info);
2694
641k
#endif
2695
2696
641k
  status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2697
641k
  if (status == 0)
2698
639k
    {
2699
639k
      int insn;
2700
2701
639k
      if (endianness == BFD_ENDIAN_BIG)
2702
322k
  insn = bfd_getb32 (buffer);
2703
316k
      else
2704
316k
  insn = bfd_getl32 (buffer);
2705
2706
639k
      return print_insn_mips (memaddr, insn, info);
2707
639k
    }
2708
2.42k
  else
2709
2.42k
    {
2710
2.42k
      (*info->memory_error_func) (status, memaddr, info);
2711
2.42k
      return -1;
2712
2.42k
    }
2713
641k
}
2714
2715
int
2716
print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2717
589k
{
2718
589k
  return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2719
589k
}
2720
2721
int
2722
print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2723
1.34M
{
2724
1.34M
  return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2725
1.34M
}
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
}