Coverage Report

Created: 2023-08-28 06:30

/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.43M
#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
0
{
741
0
  const struct mips_abi_choice *c;
742
0
  unsigned int i;
743
744
0
  for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
745
0
    if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
746
0
  && strlen (mips_abi_choices[i].name) == namelen)
747
0
      c = &mips_abi_choices[i];
748
749
0
  return c;
750
0
}
751
752
static const struct mips_arch_choice *
753
choose_arch_by_name (const char *name, unsigned int namelen)
754
0
{
755
0
  const struct mips_arch_choice *c = NULL;
756
0
  unsigned int i;
757
758
0
  for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
759
0
    if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
760
0
  && strlen (mips_arch_choices[i].name) == namelen)
761
0
      c = &mips_arch_choices[i];
762
763
0
  return c;
764
0
}
765
766
static const struct mips_arch_choice *
767
choose_arch_by_number (unsigned long mach)
768
1.17M
{
769
1.17M
  static unsigned long hint_bfd_mach;
770
1.17M
  static const struct mips_arch_choice *hint_arch_choice;
771
1.17M
  const struct mips_arch_choice *c;
772
1.17M
  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.17M
  if (hint_bfd_mach == mach
777
1.17M
      && hint_arch_choice != NULL
778
1.17M
      && hint_arch_choice->bfd_mach == hint_bfd_mach)
779
1.17M
    return hint_arch_choice;
780
781
7.85k
  for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
782
7.52k
    {
783
7.52k
      if (mips_arch_choices[i].bfd_mach_valid
784
7.52k
    && mips_arch_choices[i].bfd_mach == mach)
785
294
  {
786
294
    c = &mips_arch_choices[i];
787
294
    hint_bfd_mach = mach;
788
294
    hint_arch_choice = c;
789
294
  }
790
7.52k
    }
791
330
  return c;
792
1.17M
}
793
794
/* Check if the object uses NewABI conventions.  */
795
796
static int
797
is_newabi (Elf_Internal_Ehdr *header)
798
995k
{
799
  /* There are no old-style ABIs which use 64-bit ELF.  */
800
995k
  if (header->e_ident[EI_CLASS] == ELFCLASS64)
801
428k
    return 1;
802
803
  /* If a 32-bit ELF file, n32 is a new-style ABI.  */
804
566k
  if ((header->e_flags & EF_MIPS_ABI2) != 0)
805
548
    return 1;
806
807
566k
  return 0;
808
566k
}
809
810
/* Check if the object has microMIPS ASE code.  */
811
812
static int
813
is_micromips (Elf_Internal_Ehdr *header)
814
995k
{
815
995k
  if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
816
104k
    return 1;
817
818
890k
  return 0;
819
995k
}
820
821
/* Convert ASE flags from .MIPS.abiflags to internal values.  */
822
823
static unsigned long
824
mips_convert_abiflags_ases (unsigned long afl_ases)
825
0
{
826
0
  unsigned long opcode_ases = 0;
827
828
0
  if (afl_ases & AFL_ASE_DSP)
829
0
    opcode_ases |= ASE_DSP;
830
0
  if (afl_ases & AFL_ASE_DSPR2)
831
0
    opcode_ases |= ASE_DSPR2;
832
0
  if (afl_ases & AFL_ASE_EVA)
833
0
    opcode_ases |= ASE_EVA;
834
0
  if (afl_ases & AFL_ASE_MCU)
835
0
    opcode_ases |= ASE_MCU;
836
0
  if (afl_ases & AFL_ASE_MDMX)
837
0
    opcode_ases |= ASE_MDMX;
838
0
  if (afl_ases & AFL_ASE_MIPS3D)
839
0
    opcode_ases |= ASE_MIPS3D;
840
0
  if (afl_ases & AFL_ASE_MT)
841
0
    opcode_ases |= ASE_MT;
842
0
  if (afl_ases & AFL_ASE_SMARTMIPS)
843
0
    opcode_ases |= ASE_SMARTMIPS;
844
0
  if (afl_ases & AFL_ASE_VIRT)
845
0
    opcode_ases |= ASE_VIRT;
846
0
  if (afl_ases & AFL_ASE_MSA)
847
0
    opcode_ases |= ASE_MSA;
848
0
  if (afl_ases & AFL_ASE_XPA)
849
0
    opcode_ases |= ASE_XPA;
850
0
  if (afl_ases & AFL_ASE_DSPR3)
851
0
    opcode_ases |= ASE_DSPR3;
852
0
  if (afl_ases & AFL_ASE_MIPS16E2)
853
0
    opcode_ases |= ASE_MIPS16E2;
854
0
  return opcode_ases;
855
0
}
856
857
/* Calculate combination ASE flags from regular ASE flags.  */
858
859
static unsigned long
860
mips_calculate_combination_ases (int opcode_isa, unsigned long opcode_ases)
861
1.17M
{
862
1.17M
  unsigned long combination_ases = 0;
863
864
1.17M
  if ((opcode_ases & (ASE_XPA | ASE_VIRT)) == (ASE_XPA | ASE_VIRT))
865
75.1k
    combination_ases |= ASE_XPA_VIRT;
866
1.17M
  if ((opcode_ases & (ASE_MIPS16E2 | ASE_MT)) == (ASE_MIPS16E2 | ASE_MT))
867
259
    combination_ases |= ASE_MIPS16E2_MT;
868
1.17M
  if ((opcode_ases & ASE_EVA)
869
1.17M
      && ((opcode_isa & INSN_ISA_MASK) == ISA_MIPS64R6
870
75.4k
    || (opcode_isa & INSN_ISA_MASK) == ISA_MIPS32R6))
871
72.8k
    combination_ases |= ASE_EVA_R6;
872
1.17M
  return combination_ases;
873
1.17M
}
874
875
static void
876
set_default_mips_dis_options (struct disassemble_info *info)
877
1.17M
{
878
1.17M
  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.17M
  mips_isa = ISA_MIPS3;
884
1.17M
  mips_processor = CPU_R3000;
885
1.17M
  micromips_ase = 0;
886
1.17M
  mips_ase = 0;
887
1.17M
  mips_gpr_names = mips_gpr_names_oldabi;
888
1.17M
  mips_fpr_names = mips_fpr_names_numeric;
889
1.17M
  mips_cp0_names = mips_cp0_names_numeric;
890
1.17M
  mips_cp0sel_names = NULL;
891
1.17M
  mips_cp0sel_names_len = 0;
892
1.17M
  mips_cp1_names = mips_cp1_names_numeric;
893
1.17M
  mips_hwr_names = mips_hwr_names_numeric;
894
1.17M
  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.17M
  chosen_arch = choose_arch_by_number (info->mach);
905
1.17M
  if (chosen_arch != NULL)
906
1.17M
    {
907
1.17M
      mips_processor = chosen_arch->processor;
908
1.17M
      mips_isa = chosen_arch->isa;
909
1.17M
      mips_ase = chosen_arch->ase;
910
1.17M
      mips_cp0_names = chosen_arch->cp0_names;
911
1.17M
      mips_cp0sel_names = chosen_arch->cp0sel_names;
912
1.17M
      mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
913
1.17M
      mips_cp1_names = chosen_arch->cp1_names;
914
1.17M
      mips_hwr_names = chosen_arch->hwr_names;
915
1.17M
    }
916
917
  /* Update settings according to the ELF file header flags.  */
918
1.17M
  if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
919
995k
    {
920
995k
      struct bfd *abfd = info->section->owner;
921
995k
      Elf_Internal_Ehdr *header = elf_elfheader (abfd);
922
995k
      Elf_Internal_ABIFlags_v0 *abiflags = NULL;
923
924
      /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
925
   because we won't then have a MIPS/ELF BFD, however we need
926
   to guard against a link error in a `--enable-targets=...'
927
   configuration with a 32-bit host where the MIPS target is
928
   a secondary, or with MIPS/ECOFF configurations.  */
929
995k
#ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
930
995k
      abiflags = bfd_mips_elf_get_abiflags (abfd);
931
995k
#endif
932
      /* If an ELF "newabi" binary, use the n32/(n)64 GPR names.  */
933
995k
      if (is_newabi (header))
934
429k
  mips_gpr_names = mips_gpr_names_newabi;
935
      /* If a microMIPS binary, then don't use MIPS16 bindings.  */
936
995k
      micromips_ase = is_micromips (header);
937
      /* OR in any extra ASE flags set in ELF file structures.  */
938
995k
      if (abiflags)
939
0
  mips_ase |= mips_convert_abiflags_ases (abiflags->ases);
940
995k
      else if (header->e_flags & EF_MIPS_ARCH_ASE_MDMX)
941
114k
  mips_ase |= ASE_MDMX;
942
995k
    }
943
1.17M
#endif
944
1.17M
  mips_ase |= mips_calculate_combination_ases (mips_isa, mips_ase);
945
1.17M
}
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
0
{
953
0
  if (startswith (option, "msa"))
954
0
    {
955
0
      mips_ase |= ASE_MSA;
956
0
      if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
957
0
     || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
958
0
     || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
959
0
     || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
960
0
    mips_ase |= ASE_MSA64;
961
0
      return true;
962
0
    }
963
964
0
  if (startswith (option, "virt"))
965
0
    {
966
0
      mips_ase |= ASE_VIRT;
967
0
      if (mips_isa & ISA_MIPS64R2
968
0
    || mips_isa & ISA_MIPS64R3
969
0
    || mips_isa & ISA_MIPS64R5
970
0
    || mips_isa & ISA_MIPS64R6)
971
0
  mips_ase |= ASE_VIRT64;
972
0
      return true;
973
0
    }
974
975
0
  if (startswith (option, "xpa"))
976
0
    {
977
0
      mips_ase |= ASE_XPA;
978
0
      return true;
979
0
    }
980
981
0
  if (startswith (option, "ginv"))
982
0
    {
983
0
      mips_ase |= ASE_GINV;
984
0
      return true;
985
0
    }
986
987
0
  if (startswith (option, "loongson-mmi"))
988
0
    {
989
0
      mips_ase |= ASE_LOONGSON_MMI;
990
0
      return true;
991
0
    }
992
993
0
  if (startswith (option, "loongson-cam"))
994
0
    {
995
0
      mips_ase |= ASE_LOONGSON_CAM;
996
0
      return true;
997
0
    }
998
  
999
  /* Put here for match ext2 frist */
1000
0
  if (startswith (option, "loongson-ext2"))
1001
0
    {
1002
0
      mips_ase |= ASE_LOONGSON_EXT2;
1003
0
      return true;
1004
0
    }
1005
1006
0
  if (startswith (option, "loongson-ext"))
1007
0
    {
1008
0
      mips_ase |= ASE_LOONGSON_EXT;
1009
0
      return true;
1010
0
    }
1011
1012
0
  return false;
1013
0
}
1014
1015
static void
1016
parse_mips_dis_option (const char *option, unsigned int len)
1017
0
{
1018
0
  unsigned int i, optionlen, vallen;
1019
0
  const char *val;
1020
0
  const struct mips_abi_choice *chosen_abi;
1021
0
  const struct mips_arch_choice *chosen_arch;
1022
1023
  /* Try to match options that are simple flags */
1024
0
  if (startswith (option, "no-aliases"))
1025
0
    {
1026
0
      no_aliases = 1;
1027
0
      return;
1028
0
    }
1029
1030
0
  if (parse_mips_ase_option (option))
1031
0
    {
1032
0
      mips_ase |= mips_calculate_combination_ases (mips_isa, mips_ase);
1033
0
      return;
1034
0
    }
1035
1036
  /* Look for the = that delimits the end of the option name.  */
1037
0
  for (i = 0; i < len; i++)
1038
0
    if (option[i] == '=')
1039
0
      break;
1040
1041
0
  if (i == 0)   /* Invalid option: no name before '='.  */
1042
0
    return;
1043
0
  if (i == len)   /* Invalid option: no '='.  */
1044
0
    return;
1045
0
  if (i == (len - 1)) /* Invalid option: no value after '='.  */
1046
0
    return;
1047
1048
0
  optionlen = i;
1049
0
  val = option + (optionlen + 1);
1050
0
  vallen = len - (optionlen + 1);
1051
1052
0
  if (strncmp ("gpr-names", option, optionlen) == 0
1053
0
      && strlen ("gpr-names") == optionlen)
1054
0
    {
1055
0
      chosen_abi = choose_abi_by_name (val, vallen);
1056
0
      if (chosen_abi != NULL)
1057
0
  mips_gpr_names = chosen_abi->gpr_names;
1058
0
      return;
1059
0
    }
1060
1061
0
  if (strncmp ("fpr-names", option, optionlen) == 0
1062
0
      && strlen ("fpr-names") == optionlen)
1063
0
    {
1064
0
      chosen_abi = choose_abi_by_name (val, vallen);
1065
0
      if (chosen_abi != NULL)
1066
0
  mips_fpr_names = chosen_abi->fpr_names;
1067
0
      return;
1068
0
    }
1069
1070
0
  if (strncmp ("cp0-names", option, optionlen) == 0
1071
0
      && strlen ("cp0-names") == optionlen)
1072
0
    {
1073
0
      chosen_arch = choose_arch_by_name (val, vallen);
1074
0
      if (chosen_arch != NULL)
1075
0
  {
1076
0
    mips_cp0_names = chosen_arch->cp0_names;
1077
0
    mips_cp0sel_names = chosen_arch->cp0sel_names;
1078
0
    mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1079
0
  }
1080
0
      return;
1081
0
    }
1082
1083
0
  if (strncmp ("cp1-names", option, optionlen) == 0
1084
0
      && strlen ("cp1-names") == optionlen)
1085
0
    {
1086
0
      chosen_arch = choose_arch_by_name (val, vallen);
1087
0
      if (chosen_arch != NULL)
1088
0
  mips_cp1_names = chosen_arch->cp1_names;
1089
0
      return;
1090
0
    }
1091
1092
0
  if (strncmp ("hwr-names", option, optionlen) == 0
1093
0
      && strlen ("hwr-names") == optionlen)
1094
0
    {
1095
0
      chosen_arch = choose_arch_by_name (val, vallen);
1096
0
      if (chosen_arch != NULL)
1097
0
  mips_hwr_names = chosen_arch->hwr_names;
1098
0
      return;
1099
0
    }
1100
1101
0
  if (strncmp ("reg-names", option, optionlen) == 0
1102
0
      && strlen ("reg-names") == optionlen)
1103
0
    {
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
0
      chosen_abi = choose_abi_by_name (val, vallen);
1109
0
      if (chosen_abi != NULL)
1110
0
  {
1111
0
    mips_gpr_names = chosen_abi->gpr_names;
1112
0
    mips_fpr_names = chosen_abi->fpr_names;
1113
0
  }
1114
0
      chosen_arch = choose_arch_by_name (val, vallen);
1115
0
      if (chosen_arch != NULL)
1116
0
  {
1117
0
    mips_cp0_names = chosen_arch->cp0_names;
1118
0
    mips_cp0sel_names = chosen_arch->cp0sel_names;
1119
0
    mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1120
0
    mips_cp1_names = chosen_arch->cp1_names;
1121
0
    mips_hwr_names = chosen_arch->hwr_names;
1122
0
  }
1123
0
      return;
1124
0
    }
1125
1126
  /* Invalid option.  */
1127
0
}
1128
1129
static void
1130
parse_mips_dis_options (const char *options)
1131
1.17M
{
1132
1.17M
  const char *option_end;
1133
1134
1.17M
  if (options == NULL)
1135
1.17M
    return;
1136
1137
0
  while (*options != '\0')
1138
0
    {
1139
      /* Skip empty options.  */
1140
0
      if (*options == ',')
1141
0
  {
1142
0
    options++;
1143
0
    continue;
1144
0
  }
1145
1146
      /* We know that *options is neither NUL or a comma.  */
1147
0
      option_end = options + 1;
1148
0
      while (*option_end != ',' && *option_end != '\0')
1149
0
  option_end++;
1150
1151
0
      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
0
      options = option_end;
1156
0
    }
1157
0
}
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
97
{
1165
97
  unsigned int i;
1166
1167
2.42k
  for (i = 0; i < len; i++)
1168
2.36k
    if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1169
30
      return &names[i];
1170
67
  return NULL;
1171
97
}
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
1.64M
{
1179
1.64M
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1180
1181
1.64M
  switch (type)
1182
1.64M
    {
1183
1.62M
    case OP_REG_GP:
1184
1.62M
      infprintf (info->stream, dis_style_register, "%s",
1185
1.62M
     mips_gpr_names[regno]);
1186
1.62M
      break;
1187
1188
8.59k
    case OP_REG_FP:
1189
8.59k
      infprintf (info->stream, dis_style_register, "%s",
1190
8.59k
     mips_fpr_names[regno]);
1191
8.59k
      break;
1192
1193
1.16k
    case OP_REG_CCC:
1194
1.16k
      if (opcode->pinfo & (FP_D | FP_S))
1195
1.15k
  infprintf (info->stream, dis_style_register, "$fcc%d", regno);
1196
11
      else
1197
11
  infprintf (info->stream, dis_style_register, "$cc%d", regno);
1198
1.16k
      break;
1199
1200
245
    case OP_REG_VEC:
1201
245
      if (opcode->membership & INSN_5400)
1202
0
  infprintf (info->stream, dis_style_register, "$f%d", regno);
1203
245
      else
1204
245
  infprintf (info->stream, dis_style_register, "$v%d", regno);
1205
245
      break;
1206
1207
177
    case OP_REG_ACC:
1208
177
      infprintf (info->stream, dis_style_register, "$ac%d", regno);
1209
177
      break;
1210
1211
11.4k
    case OP_REG_COPRO:
1212
11.4k
      if (opcode->name[strlen (opcode->name) - 1] == '0')
1213
4.26k
  infprintf (info->stream, dis_style_register, "%s", mips_cp0_names[regno]);
1214
7.22k
      else
1215
7.22k
  infprintf (info->stream, dis_style_register, "$%d", regno);
1216
11.4k
      break;
1217
1218
31
    case OP_REG_CONTROL:
1219
31
      if (opcode->name[strlen (opcode->name) - 1] == '1')
1220
3
  infprintf (info->stream, dis_style_register, "%s", mips_cp1_names[regno]);
1221
28
      else
1222
28
  infprintf (info->stream, dis_style_register, "$%d", regno);
1223
31
      break;
1224
1225
0
    case OP_REG_HW:
1226
0
      infprintf (info->stream, dis_style_register, "%s", mips_hwr_names[regno]);
1227
0
      break;
1228
1229
0
    case OP_REG_VF:
1230
0
      infprintf (info->stream, dis_style_register, "$vf%d", regno);
1231
0
      break;
1232
1233
0
    case OP_REG_VI:
1234
0
      infprintf (info->stream, dis_style_register, "$vi%d", regno);
1235
0
      break;
1236
1237
0
    case OP_REG_R5900_I:
1238
0
      infprintf (info->stream, dis_style_register, "$I");
1239
0
      break;
1240
1241
0
    case OP_REG_R5900_Q:
1242
0
      infprintf (info->stream, dis_style_register, "$Q");
1243
0
      break;
1244
1245
0
    case OP_REG_R5900_R:
1246
0
      infprintf (info->stream, dis_style_register, "$R");
1247
0
      break;
1248
1249
0
    case OP_REG_R5900_ACC:
1250
0
      infprintf (info->stream, dis_style_register, "$ACC");
1251
0
      break;
1252
1253
1.54k
    case OP_REG_MSA:
1254
1.54k
      infprintf (info->stream, dis_style_register, "$w%d", regno);
1255
1.54k
      break;
1256
1257
2
    case OP_REG_MSA_CTRL:
1258
2
      infprintf (info->stream, dis_style_register, "%s",
1259
2
     msa_control_names[regno]);
1260
2
      break;
1261
1262
1.64M
    }
1263
1.64M
}
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
1.39M
{
1285
1.39M
  memset (state, 0, sizeof (*state));
1286
1.39M
}
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
0
{
1296
0
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1297
1298
0
  if (operand->size == 4)
1299
0
    infprintf (info->stream, style, "%s%s%s%s",
1300
0
      uval & 8 ? "x" : "",
1301
0
      uval & 4 ? "y" : "",
1302
0
      uval & 2 ? "z" : "",
1303
0
      uval & 1 ? "w" : "");
1304
0
  else if (operand->size == 2)
1305
0
    infprintf (info->stream, style, "%c", "xyzw"[uval]);
1306
0
  else
1307
0
    abort ();
1308
0
}
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
2.31M
{
1317
2.31M
  state->last_reg_type = reg_type;
1318
2.31M
  state->last_regno = regno;
1319
1320
2.31M
  if (!state->seen_dest)
1321
1.26M
    {
1322
1.26M
      state->seen_dest = 1;
1323
1.26M
      state->dest_regno = regno;
1324
1.26M
    }
1325
2.31M
}
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
975
{
1338
975
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1339
975
  unsigned int nargs, nstatics, smask, i, j;
1340
975
  void *is = info->stream;
1341
975
  const char *sep;
1342
1343
975
  if (amask == MIPS_SVRS_ALL_ARGS)
1344
1
    {
1345
1
      nargs = 4;
1346
1
      nstatics = 0;
1347
1
    }
1348
974
  else if (amask == MIPS_SVRS_ALL_STATICS)
1349
0
    {
1350
0
      nargs = 0;
1351
0
      nstatics = 4;
1352
0
    }
1353
974
  else
1354
974
    {
1355
974
      nargs = amask >> 2;
1356
974
      nstatics = amask & 3;
1357
974
    }
1358
1359
975
  sep = "";
1360
975
  if (nargs > 0)
1361
22
    {
1362
22
      infprintf (is, dis_style_register, "%s", mips_gpr_names[4]);
1363
22
      if (nargs > 1)
1364
10
  infprintf (is, dis_style_register, "-%s", mips_gpr_names[4 + nargs - 1]);
1365
22
      sep = ",";
1366
22
    }
1367
1368
975
  infprintf (is, dis_style_text, "%s", sep);
1369
975
  infprintf (is, dis_style_immediate, "%d", frame_size);
1370
1371
975
  if (ra)      /* $ra */
1372
449
    {
1373
449
      infprintf (is, dis_style_text, ",");
1374
449
      infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
1375
449
    }
1376
1377
975
  smask = 0;
1378
975
  if (s0)      /* $s0 */
1379
512
    smask |= 1 << 0;
1380
975
  if (s1)      /* $s1 */
1381
250
    smask |= 1 << 1;
1382
975
  if (nsreg > 0)    /* $s2-$s8 */
1383
23
    smask |= ((1 << nsreg) - 1) << 2;
1384
1385
8.87k
  for (i = 0; i < 9; i++)
1386
7.89k
    if (smask & (1 << i))
1387
627
      {
1388
627
  infprintf (is, dis_style_text, ",");
1389
627
  infprintf (is, dis_style_register, "%s",
1390
627
       mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1391
  /* Skip over string of set bits.  */
1392
879
  for (j = i; smask & (2 << j); j++)
1393
252
    continue;
1394
627
  if (j > i)
1395
154
    {
1396
154
      infprintf (is, dis_style_text, "-");
1397
154
      infprintf (is, dis_style_register, "%s",
1398
154
           mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1399
154
    }
1400
627
  i = j + 1;
1401
627
      }
1402
  /* Statics $ax - $a3.  */
1403
975
  if (nstatics == 1)
1404
6
    {
1405
6
      infprintf (is, dis_style_text, ",");
1406
6
      infprintf (is, dis_style_register, "%s", mips_gpr_names[7]);
1407
6
    }
1408
969
  else if (nstatics > 0)
1409
8
    {
1410
8
      infprintf (is, dis_style_text, ",");
1411
8
      infprintf (is, dis_style_register, "%s",
1412
8
     mips_gpr_names[7 - nstatics + 1]);
1413
8
      infprintf (is, dis_style_text, "-");
1414
8
      infprintf (is, dis_style_register, "%s", mips_gpr_names[7]);
1415
8
    }
1416
975
}
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
2.54M
{
1431
2.54M
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1432
2.54M
  void *is = info->stream;
1433
1434
2.54M
  switch (operand->type)
1435
2.54M
    {
1436
754k
    case OP_INT:
1437
754k
      {
1438
754k
  const struct mips_int_operand *int_op;
1439
1440
754k
  int_op = (const struct mips_int_operand *) operand;
1441
754k
  uval = mips_decode_int_operand (int_op, uval);
1442
754k
  state->last_int = uval;
1443
754k
  if (int_op->print_hex)
1444
65.5k
    infprintf (is, dis_style_immediate, "0x%x", uval);
1445
688k
  else
1446
688k
    infprintf (is, dis_style_immediate, "%d", uval);
1447
754k
      }
1448
754k
      break;
1449
1450
1.62k
    case OP_MAPPED_INT:
1451
1.62k
      {
1452
1.62k
  const struct mips_mapped_int_operand *mint_op;
1453
1454
1.62k
  mint_op = (const struct mips_mapped_int_operand *) operand;
1455
1.62k
  uval = mint_op->int_map[uval];
1456
1.62k
  state->last_int = uval;
1457
1.62k
  if (mint_op->print_hex)
1458
873
    infprintf (is, dis_style_immediate, "0x%x", uval);
1459
751
  else
1460
751
    infprintf (is, dis_style_immediate, "%d", uval);
1461
1.62k
      }
1462
1.62k
      break;
1463
1464
293
    case OP_MSB:
1465
293
      {
1466
293
  const struct mips_msb_operand *msb_op;
1467
1468
293
  msb_op = (const struct mips_msb_operand *) operand;
1469
293
  uval += msb_op->bias;
1470
293
  if (msb_op->add_lsb)
1471
131
    uval -= state->last_int;
1472
293
  infprintf (is, dis_style_immediate, "0x%x", uval);
1473
293
      }
1474
293
      break;
1475
1476
1.51M
    case OP_REG:
1477
1.63M
    case OP_OPTIONAL_REG:
1478
1.63M
      {
1479
1.63M
  const struct mips_reg_operand *reg_op;
1480
1481
1.63M
  reg_op = (const struct mips_reg_operand *) operand;
1482
1.63M
  uval = mips_decode_reg_operand (reg_op, uval);
1483
1.63M
  print_reg (info, opcode, reg_op->reg_type, uval);
1484
1485
1.63M
  mips_seen_register (state, uval, reg_op->reg_type);
1486
1.63M
      }
1487
1.63M
      break;
1488
1489
166
    case OP_REG_PAIR:
1490
166
      {
1491
166
  const struct mips_reg_pair_operand *pair_op;
1492
1493
166
  pair_op = (const struct mips_reg_pair_operand *) operand;
1494
166
  print_reg (info, opcode, pair_op->reg_type,
1495
166
       pair_op->reg1_map[uval]);
1496
166
  infprintf (is, dis_style_text, ",");
1497
166
  print_reg (info, opcode, pair_op->reg_type,
1498
166
       pair_op->reg2_map[uval]);
1499
166
      }
1500
166
      break;
1501
1502
136k
    case OP_PCREL:
1503
136k
      {
1504
136k
  const struct mips_pcrel_operand *pcrel_op;
1505
1506
136k
  pcrel_op = (const struct mips_pcrel_operand *) operand;
1507
136k
  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
136k
  if (pcrel_op->include_isa_bit
1512
136k
      && info->flavour != bfd_target_unknown_flavour)
1513
110k
    info->target &= -2;
1514
1515
136k
  (*info->print_address_func) (info->target, info);
1516
136k
      }
1517
136k
      break;
1518
1519
0
    case OP_PERF_REG:
1520
0
      infprintf (is, dis_style_register, "%d", uval);
1521
0
      break;
1522
1523
489
    case OP_ADDIUSP_INT:
1524
489
      {
1525
489
  int sval;
1526
1527
489
  sval = mips_signed_operand (operand, uval) * 4;
1528
489
  if (sval >= -8 && sval < 8)
1529
15
    sval ^= 0x400;
1530
489
  infprintf (is, dis_style_immediate, "%d", sval);
1531
489
  break;
1532
1.51M
      }
1533
1534
3
    case OP_CLO_CLZ_DEST:
1535
3
      {
1536
3
  unsigned int reg1, reg2;
1537
1538
3
  reg1 = uval & 31;
1539
3
  reg2 = uval >> 5;
1540
  /* If one is zero use the other.  */
1541
3
  if (reg1 == reg2 || reg2 == 0)
1542
0
    infprintf (is, dis_style_register, "%s", mips_gpr_names[reg1]);
1543
3
  else if (reg1 == 0)
1544
0
    infprintf (is, dis_style_register, "%s", mips_gpr_names[reg2]);
1545
3
  else
1546
3
    {
1547
      /* Bogus, result depends on processor.  */
1548
3
      infprintf (is, dis_style_register, "%s", mips_gpr_names[reg1]);
1549
3
      infprintf (is, dis_style_text, " or ");
1550
3
      infprintf (is, dis_style_register, "%s", mips_gpr_names[reg2]);
1551
3
    }
1552
3
      }
1553
3
      break;
1554
1555
37
    case OP_SAME_RS_RT:
1556
1.82k
    case OP_CHECK_PREV:
1557
3.84k
    case OP_NON_ZERO_REG:
1558
3.84k
      {
1559
3.84k
  print_reg (info, opcode, OP_REG_GP, uval & 31);
1560
3.84k
  mips_seen_register (state, uval, OP_REG_GP);
1561
3.84k
      }
1562
3.84k
      break;
1563
1564
826
    case OP_LWM_SWM_LIST:
1565
826
      if (operand->size == 2)
1566
574
  {
1567
574
    if (uval == 0)
1568
379
      {
1569
379
        infprintf (is, dis_style_register, "%s",
1570
379
       mips_gpr_names[16]);
1571
379
        infprintf (is, dis_style_text, ",");
1572
379
        infprintf (is, dis_style_register, "%s",
1573
379
       mips_gpr_names[31]);
1574
379
      }
1575
195
    else
1576
195
      {
1577
195
        infprintf (is, dis_style_register, "%s",
1578
195
       mips_gpr_names[16]);
1579
195
        infprintf (is, dis_style_text, "-");
1580
195
        infprintf (is, dis_style_register, "%s",
1581
195
       mips_gpr_names[16 + uval]);
1582
195
        infprintf (is, dis_style_text, ",");
1583
195
        infprintf (is, dis_style_register, "%s",
1584
195
       mips_gpr_names[31]);
1585
195
      }
1586
574
  }
1587
252
      else
1588
252
  {
1589
252
    int s_reg_encode;
1590
1591
252
    s_reg_encode = uval & 0xf;
1592
252
    if (s_reg_encode != 0)
1593
222
      {
1594
222
        if (s_reg_encode == 1)
1595
43
    infprintf (is, dis_style_register, "%s", mips_gpr_names[16]);
1596
179
        else if (s_reg_encode < 9)
1597
139
    {
1598
139
      infprintf (is, dis_style_register, "%s",
1599
139
           mips_gpr_names[16]);
1600
139
      infprintf (is, dis_style_text, "-");
1601
139
      infprintf (is, dis_style_register, "%s",
1602
139
           mips_gpr_names[15 + s_reg_encode]);
1603
139
    }
1604
40
        else if (s_reg_encode == 9)
1605
2
    {
1606
2
      infprintf (is, dis_style_register, "%s",
1607
2
           mips_gpr_names[16]);
1608
2
      infprintf (is, dis_style_text, "-");
1609
2
      infprintf (is, dis_style_register, "%s",
1610
2
           mips_gpr_names[23]);
1611
2
      infprintf (is, dis_style_text, ",");
1612
2
      infprintf (is, dis_style_register, "%s",
1613
2
           mips_gpr_names[30]);
1614
2
    }
1615
38
        else
1616
38
    infprintf (is, dis_style_text, "UNKNOWN");
1617
222
      }
1618
1619
252
    if (uval & 0x10) /* For ra.  */
1620
52
      {
1621
52
        if (s_reg_encode == 0)
1622
3
    infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
1623
49
        else
1624
49
    {
1625
49
      infprintf (is, dis_style_text, ",");
1626
49
      infprintf (is, dis_style_register, "%s",
1627
49
           mips_gpr_names[31]);
1628
49
    }
1629
52
      }
1630
252
  }
1631
826
      break;
1632
1633
780
    case OP_ENTRY_EXIT_LIST:
1634
780
      {
1635
780
  const char *sep;
1636
780
  unsigned int amask, smask;
1637
1638
780
  sep = "";
1639
780
  amask = (uval >> 3) & 7;
1640
780
  if (amask > 0 && amask < 5)
1641
256
    {
1642
256
      infprintf (is, dis_style_register, "%s", mips_gpr_names[4]);
1643
256
      if (amask > 1)
1644
158
        {
1645
158
    infprintf (is, dis_style_text, "-");
1646
158
    infprintf (is, dis_style_register, "%s",
1647
158
         mips_gpr_names[amask + 3]);
1648
158
        }
1649
256
      sep = ",";
1650
256
    }
1651
1652
780
  smask = (uval >> 1) & 3;
1653
780
  if (smask == 3)
1654
237
    {
1655
237
      infprintf (is, dis_style_text, "%s??", sep);
1656
237
      sep = ",";
1657
237
    }
1658
543
  else if (smask > 0)
1659
515
    {
1660
515
      infprintf (is, dis_style_text, "%s", sep);
1661
515
      infprintf (is, dis_style_register, "%s", mips_gpr_names[16]);
1662
515
      if (smask > 1)
1663
354
        {
1664
354
    infprintf (is, dis_style_text, "-");
1665
354
    infprintf (is, dis_style_register, "%s",
1666
354
         mips_gpr_names[smask + 15]);
1667
354
        }
1668
515
      sep = ",";
1669
515
    }
1670
1671
780
  if (uval & 1)
1672
366
    {
1673
366
      infprintf (is, dis_style_text, "%s", sep);
1674
366
      infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
1675
366
      sep = ",";
1676
366
    }
1677
1678
780
  if (amask == 5 || amask == 6)
1679
208
    {
1680
208
      infprintf (is, dis_style_text, "%s", sep);
1681
208
      infprintf (is, dis_style_register, "%s", mips_fpr_names[0]);
1682
208
      if (amask == 6)
1683
144
        {
1684
144
    infprintf (is, dis_style_text, "-");
1685
144
    infprintf (is, dis_style_register, "%s", mips_fpr_names[1]);
1686
144
        }
1687
208
    }
1688
780
      }
1689
780
      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
78
    case OP_MDMX_IMM_REG:
1696
78
      {
1697
78
  unsigned int vsel;
1698
1699
78
  vsel = uval >> 5;
1700
78
  uval &= 31;
1701
78
  if ((vsel & 0x10) == 0)
1702
53
    {
1703
53
      int fmt;
1704
1705
53
      vsel &= 0x0f;
1706
112
      for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1707
109
        if ((vsel & 1) == 0)
1708
50
    break;
1709
53
      print_reg (info, opcode, OP_REG_VEC, uval);
1710
53
      infprintf (is, dis_style_text, "[");
1711
53
      infprintf (is, dis_style_immediate, "%d", vsel >> 1);
1712
53
      infprintf (is, dis_style_text, "]");
1713
53
    }
1714
25
  else if ((vsel & 0x08) == 0)
1715
22
    print_reg (info, opcode, OP_REG_VEC, uval);
1716
3
  else
1717
3
    infprintf (is, dis_style_immediate, "0x%x", uval);
1718
78
      }
1719
78
      break;
1720
1721
1.21k
    case OP_REPEAT_PREV_REG:
1722
1.21k
      print_reg (info, opcode, state->last_reg_type, state->last_regno);
1723
1.21k
      break;
1724
1725
0
    case OP_REPEAT_DEST_REG:
1726
0
      print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1727
0
      break;
1728
1729
708
    case OP_PC:
1730
708
      infprintf (is, dis_style_register, "$pc");
1731
708
      break;
1732
1733
8
    case OP_REG28:
1734
8
      print_reg (info, opcode, OP_REG_GP, 28);
1735
8
      break;
1736
1737
0
    case OP_VU0_SUFFIX:
1738
0
    case OP_VU0_MATCH_SUFFIX:
1739
0
      print_vu0_channel (info, operand, uval, dis_style_register);
1740
0
      break;
1741
1742
7
    case OP_IMM_INDEX:
1743
7
      infprintf (is, dis_style_text, "[");
1744
7
      infprintf (is, dis_style_immediate, "%d", uval);
1745
7
      infprintf (is, dis_style_text, "]");
1746
7
      break;
1747
1748
4
    case OP_REG_INDEX:
1749
4
      infprintf (is, dis_style_text, "[");
1750
4
      print_reg (info, opcode, OP_REG_GP, uval);
1751
4
      infprintf (is, dis_style_text, "]");
1752
4
      break;
1753
2.54M
    }
1754
2.54M
}
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
416k
{
1764
416k
  struct mips_print_arg_state state;
1765
416k
  const struct mips_operand *operand;
1766
416k
  const char *s;
1767
416k
  unsigned int uval;
1768
1769
416k
  init_print_arg_state (&state);
1770
2.20M
  for (s = opcode->args; *s; ++s)
1771
1.78M
    {
1772
1.78M
      switch (*s)
1773
1.78M
  {
1774
464k
  case ',':
1775
622k
  case '(':
1776
779k
  case ')':
1777
779k
    break;
1778
1779
0
  case '#':
1780
0
    ++s;
1781
0
    break;
1782
1783
1.00M
  default:
1784
1.00M
    operand = decode_operand (s);
1785
1786
1.00M
    if (operand)
1787
1.00M
      {
1788
1.00M
        uval = mips_extract_operand (operand, insn);
1789
1.00M
        switch (operand->type)
1790
1.00M
    {
1791
571k
    case OP_REG:
1792
670k
    case OP_OPTIONAL_REG:
1793
670k
      {
1794
670k
        const struct mips_reg_operand *reg_op;
1795
1796
670k
        reg_op = (const struct mips_reg_operand *) operand;
1797
670k
        uval = mips_decode_reg_operand (reg_op, uval);
1798
670k
        mips_seen_register (&state, uval, reg_op->reg_type);
1799
670k
      }
1800
670k
    break;
1801
1802
1.10k
    case OP_SAME_RS_RT:
1803
1.10k
      {
1804
1.10k
        unsigned int reg1, reg2;
1805
1806
1.10k
        reg1 = uval & 31;
1807
1.10k
        reg2 = uval >> 5;
1808
1809
1.10k
        if (reg1 != reg2 || reg1 == 0)
1810
1.06k
          return false;
1811
1.10k
      }
1812
37
    break;
1813
1814
2.49k
    case OP_CHECK_PREV:
1815
2.49k
      {
1816
2.49k
        const struct mips_check_prev_operand *prev_op;
1817
1818
2.49k
        prev_op = (const struct mips_check_prev_operand *) operand;
1819
1820
2.49k
        if (!prev_op->zero_ok && uval == 0)
1821
83
          return false;
1822
1823
2.41k
        if (((prev_op->less_than_ok && uval < state.last_regno)
1824
2.41k
      || (prev_op->greater_than_ok && uval > state.last_regno)
1825
2.41k
      || (prev_op->equal_ok && uval == state.last_regno)))
1826
1.78k
          break;
1827
1828
624
        return false;
1829
2.41k
      }
1830
1831
2.18k
    case OP_NON_ZERO_REG:
1832
2.18k
      {
1833
2.18k
        if (uval == 0)
1834
80
          return false;
1835
2.18k
      }
1836
2.10k
    break;
1837
1838
270k
    case OP_INT:
1839
271k
    case OP_MAPPED_INT:
1840
272k
    case OP_MSB:
1841
272k
    case OP_REG_PAIR:
1842
328k
    case OP_PCREL:
1843
328k
    case OP_PERF_REG:
1844
329k
    case OP_ADDIUSP_INT:
1845
329k
    case OP_CLO_CLZ_DEST:
1846
330k
    case OP_LWM_SWM_LIST:
1847
330k
    case OP_ENTRY_EXIT_LIST:
1848
330k
    case OP_MDMX_IMM_REG:
1849
331k
    case OP_REPEAT_PREV_REG:
1850
331k
    case OP_REPEAT_DEST_REG:
1851
332k
    case OP_PC:
1852
332k
    case OP_REG28:
1853
332k
    case OP_VU0_SUFFIX:
1854
332k
    case OP_VU0_MATCH_SUFFIX:
1855
332k
    case OP_IMM_INDEX:
1856
332k
    case OP_REG_INDEX:
1857
332k
    case OP_SAVE_RESTORE_LIST:
1858
332k
      break;
1859
1.00M
    }
1860
1.00M
      }
1861
1.00M
    if (*s == 'm' || *s == '+' || *s == '-')
1862
62.7k
      ++s;
1863
1.78M
  }
1864
1.78M
    }
1865
414k
  return true;
1866
416k
}
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
383k
{
1879
383k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1880
383k
  void *is = info->stream;
1881
383k
  struct mips_print_arg_state state;
1882
383k
  const struct mips_operand *operand;
1883
383k
  const char *s;
1884
1885
383k
  init_print_arg_state (&state);
1886
2.16M
  for (s = opcode->args; *s; ++s)
1887
1.78M
    {
1888
1.78M
      switch (*s)
1889
1.78M
  {
1890
463k
  case ',':
1891
621k
  case '(':
1892
779k
  case ')':
1893
779k
    infprintf (is, dis_style_text, "%c", *s);
1894
779k
    break;
1895
1896
0
  case '#':
1897
0
    ++s;
1898
0
    infprintf (is, dis_style_text, "%c%c", *s, *s);
1899
0
    break;
1900
1901
1.00M
  default:
1902
1.00M
    operand = decode_operand (s);
1903
1.00M
    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.00M
    if (operand->type == OP_SAVE_RESTORE_LIST)
1913
0
      {
1914
        /* Handle this case here because of the complex behavior.  */
1915
0
        unsigned int amask = (insn >> 15) & 0xf;
1916
0
        unsigned int nsreg = (insn >> 23) & 0x7;
1917
0
        unsigned int ra = insn & 0x1000;      /* $ra */
1918
0
        unsigned int s0 = insn & 0x800;     /* $s0 */
1919
0
        unsigned int s1 = insn & 0x400;     /* $s1 */
1920
0
        unsigned int frame_size = (((insn >> 15) & 0xf0)
1921
0
           | ((insn >> 6) & 0x0f)) * 8;
1922
0
        mips_print_save_restore (info, amask, nsreg, ra, s0, s1,
1923
0
               frame_size);
1924
0
      }
1925
1.00M
    else if (operand->type == OP_REG
1926
1.00M
       && s[1] == ','
1927
1.00M
       && s[2] == 'H'
1928
1.00M
       && opcode->name[strlen (opcode->name) - 1] == '0')
1929
97
      {
1930
        /* Coprocessor register 0 with sel field.  */
1931
97
        const struct mips_cp0sel_name *n;
1932
97
        unsigned int reg, sel;
1933
1934
97
        reg = mips_extract_operand (operand, insn);
1935
97
        s += 2;
1936
97
        operand = decode_operand (s);
1937
97
        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
97
        n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1945
97
             mips_cp0sel_names_len,
1946
97
             reg, sel);
1947
97
        if (n != NULL)
1948
30
    infprintf (is, dis_style_register, "%s", n->name);
1949
67
        else
1950
67
    {
1951
67
      infprintf (is, dis_style_register, "$%d", reg);
1952
67
      infprintf (is, dis_style_text, ",");
1953
67
      infprintf (is, dis_style_immediate, "%d", sel);
1954
67
    }
1955
97
      }
1956
1.00M
    else
1957
1.00M
      {
1958
1.00M
        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.00M
        if (operand->type == OP_PCREL)
1964
56.4k
    {
1965
56.4k
      const struct mips_pcrel_operand *pcrel_op;
1966
1967
56.4k
      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
56.4k
      if (pcrel_op->include_isa_bit)
1971
56.3k
        base_pc += length;
1972
56.4k
    }
1973
1974
1.00M
        print_insn_arg (info, &state, opcode, operand, base_pc,
1975
1.00M
            mips_extract_operand (operand, insn));
1976
1.00M
      }
1977
1.00M
    if (*s == 'm' || *s == '+' || *s == '-')
1978
62.6k
      ++s;
1979
1.00M
    break;
1980
1.78M
  }
1981
1.78M
    }
1982
383k
}
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
477k
{
1994
477k
#define GET_OP(insn, field)     \
1995
514k
  (((insn) >> OP_SH_##field) & OP_MASK_##field)
1996
477k
  static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1997
477k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1998
477k
  const struct mips_opcode *op;
1999
477k
  static bool init = 0;
2000
477k
  void *is = info->stream;
2001
2002
  /* Build a hash table to shorten the search time.  */
2003
477k
  if (! init)
2004
1
    {
2005
1
      unsigned int i;
2006
2007
65
      for (i = 0; i <= OP_MASK_OP; i++)
2008
64
  {
2009
42.0k
    for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
2010
42.0k
      {
2011
42.0k
        if (op->pinfo == INSN_MACRO
2012
42.0k
      || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2013
4.89k
    continue;
2014
37.1k
        if (i == GET_OP (op->match, OP))
2015
64
    {
2016
64
      mips_hash[i] = op;
2017
64
      break;
2018
64
    }
2019
37.1k
      }
2020
64
  }
2021
2022
1
      init = 1;
2023
1
    }
2024
2025
477k
  info->bytes_per_chunk = INSNLEN;
2026
477k
  info->display_endian = info->endian;
2027
477k
  info->insn_info_valid = 1;
2028
477k
  info->branch_delay_insns = 0;
2029
477k
  info->data_size = 0;
2030
477k
  info->insn_type = dis_nonbranch;
2031
477k
  info->target = 0;
2032
477k
  info->target2 = 0;
2033
2034
477k
  op = mips_hash[GET_OP (word, OP)];
2035
477k
  if (op != NULL)
2036
477k
    {
2037
401M
      for (; op < &mips_opcodes[NUMOPCODES]; op++)
2038
401M
  {
2039
401M
    if (op->pinfo != INSN_MACRO
2040
401M
        && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2041
401M
        && (word & op->mask) == op->match)
2042
506k
      {
2043
        /* We always disassemble the jalx instruction, except for MIPS r6.  */
2044
506k
        if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
2045
506k
     && (strcmp (op->name, "jalx")
2046
138k
         || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
2047
138k
         || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
2048
138k
    continue;
2049
2050
        /* Figure out instruction type and branch delay information.  */
2051
367k
        if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2052
33.8k
          {
2053
33.8k
      if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2054
20.8k
        info->insn_type = dis_jsr;
2055
12.9k
      else
2056
12.9k
        info->insn_type = dis_branch;
2057
33.8k
      info->branch_delay_insns = 1;
2058
33.8k
    }
2059
333k
        else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
2060
333k
             | INSN_COND_BRANCH_LIKELY)) != 0)
2061
29.2k
    {
2062
29.2k
      if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2063
250
        info->insn_type = dis_condjsr;
2064
29.0k
      else
2065
29.0k
        info->insn_type = dis_condbranch;
2066
29.2k
      info->branch_delay_insns = 1;
2067
29.2k
    }
2068
304k
        else if ((op->pinfo & (INSN_STORE_MEMORY
2069
304k
             | INSN_LOAD_MEMORY)) != 0)
2070
137k
    info->insn_type = dis_dref;
2071
2072
367k
        if (!validate_insn_args (op, decode_mips_operand, word))
2073
1.85k
    continue;
2074
2075
365k
        infprintf (is, dis_style_mnemonic, "%s", op->name);
2076
365k
        if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
2077
0
    {
2078
0
      unsigned int uval;
2079
2080
0
      infprintf (is, dis_style_mnemonic, ".");
2081
0
      uval = mips_extract_operand (&mips_vu0_channel_mask, word);
2082
0
      print_vu0_channel (info, &mips_vu0_channel_mask, uval,
2083
0
             dis_style_mnemonic);
2084
0
    }
2085
2086
365k
        if (op->args[0])
2087
339k
    {
2088
339k
      infprintf (is, dis_style_text, "\t");
2089
339k
      print_insn_args (info, op, decode_mips_operand, word,
2090
339k
           memaddr, 4);
2091
339k
    }
2092
2093
365k
        return INSNLEN;
2094
367k
      }
2095
401M
  }
2096
477k
    }
2097
112k
#undef GET_OP
2098
2099
  /* Handle undefined instructions.  */
2100
112k
  info->insn_type = dis_noninsn;
2101
112k
  infprintf (is, dis_style_assembler_directive, ".word");
2102
112k
  infprintf (is, dis_style_text, "\t");
2103
112k
  infprintf (is, dis_style_immediate, "0x%x", word);
2104
112k
  return INSNLEN;
2105
477k
}
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
2.62M
{
2117
2.62M
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
2118
2.62M
  void *is = info->stream;
2119
2.62M
  const struct mips_operand *operand, *ext_operand;
2120
2.62M
  unsigned short ext_size;
2121
2.62M
  unsigned int uval;
2122
2.62M
  bfd_vma baseaddr;
2123
2124
2.62M
  if (!use_extend)
2125
2.57M
    extend = 0;
2126
2127
2.62M
  switch (type)
2128
2.62M
    {
2129
797k
    case ',':
2130
944k
    case '(':
2131
1.09M
    case ')':
2132
1.09M
      infprintf (is, dis_style_text, "%c", type);
2133
1.09M
      break;
2134
2135
1.53M
    default:
2136
1.53M
      operand = decode_mips16_operand (type, false);
2137
1.53M
      if (!operand)
2138
0
  {
2139
    /* xgettext:c-format */
2140
0
    infprintf (is, dis_style_text, _("# internal error, undefined operand in `%s %s'"),
2141
0
         opcode->name, opcode->args);
2142
0
    return;
2143
0
  }
2144
2145
1.53M
      if (operand->type == OP_SAVE_RESTORE_LIST)
2146
975
  {
2147
    /* Handle this case here because of the complex interaction
2148
       with the EXTEND opcode.  */
2149
975
    unsigned int amask = extend & 0xf;
2150
975
    unsigned int nsreg = (extend >> 8) & 0x7;
2151
975
    unsigned int ra = insn & 0x40;      /* $ra */
2152
975
    unsigned int s0 = insn & 0x20;      /* $s0 */
2153
975
    unsigned int s1 = insn & 0x10;      /* $s1 */
2154
975
    unsigned int frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
2155
975
    if (frame_size == 0 && !use_extend)
2156
193
      frame_size = 128;
2157
975
    mips_print_save_restore (info, amask, nsreg, ra, s0, s1, frame_size);
2158
975
    break;
2159
975
  }
2160
2161
1.53M
      if (is_offset && operand->type == OP_INT)
2162
146k
  {
2163
146k
    const struct mips_int_operand *int_op;
2164
2165
146k
    int_op = (const struct mips_int_operand *) operand;
2166
146k
    info->insn_type = dis_dref;
2167
146k
    info->data_size = 1 << int_op->shift;
2168
146k
  }
2169
2170
1.53M
      ext_size = 0;
2171
1.53M
      if (use_extend)
2172
34.4k
  {
2173
34.4k
    ext_operand = decode_mips16_operand (type, true);
2174
34.4k
    if (ext_operand != operand
2175
34.4k
        || (operand->type == OP_INT && operand->lsb == 0
2176
25.7k
      && mips_opcode_32bit_p (opcode)))
2177
8.86k
      {
2178
8.86k
        ext_size = ext_operand->size;
2179
8.86k
        operand = ext_operand;
2180
8.86k
      }
2181
34.4k
  }
2182
1.53M
      if (operand->size == 26)
2183
10.8k
  uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
2184
1.52M
      else if (ext_size == 16 || ext_size == 9)
2185
8.16k
  uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
2186
1.51M
      else if (ext_size == 15)
2187
241
  uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
2188
1.51M
      else if (ext_size == 6)
2189
46
  uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
2190
1.51M
      else
2191
1.51M
  uval = mips_extract_operand (operand, (extend << 16) | insn);
2192
1.53M
      if (ext_size == 9)
2193
0
  uval &= (1U << ext_size) - 1;
2194
2195
1.53M
      baseaddr = memaddr + 2;
2196
1.53M
      if (operand->type == OP_PCREL)
2197
80.1k
  {
2198
80.1k
    const struct mips_pcrel_operand *pcrel_op;
2199
2200
80.1k
    pcrel_op = (const struct mips_pcrel_operand *) operand;
2201
80.1k
    if (!pcrel_op->include_isa_bit && use_extend)
2202
562
      baseaddr = memaddr - 2;
2203
79.5k
    else if (!pcrel_op->include_isa_bit)
2204
25.7k
      {
2205
25.7k
        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
25.7k
        if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
2215
25.7k
      && (((info->endian == BFD_ENDIAN_BIG
2216
25.7k
      ? bfd_getb16 (buffer)
2217
25.7k
      : bfd_getl16 (buffer))
2218
25.7k
           & 0xf800) == 0x1800))
2219
719
    baseaddr = memaddr - 4;
2220
25.0k
        else if (info->read_memory_func (memaddr - 2, buffer, 2,
2221
25.0k
                 info) == 0
2222
25.0k
           && (((info->endian == BFD_ENDIAN_BIG
2223
25.0k
           ? bfd_getb16 (buffer)
2224
25.0k
           : bfd_getl16 (buffer))
2225
25.0k
          & 0xf89f) == 0xe800)
2226
25.0k
           && (((info->endian == BFD_ENDIAN_BIG
2227
107
           ? bfd_getb16 (buffer)
2228
107
           : bfd_getl16 (buffer))
2229
107
          & 0x0060) != 0x0060))
2230
104
    baseaddr = memaddr - 2;
2231
24.9k
        else
2232
24.9k
    baseaddr = memaddr;
2233
25.7k
      }
2234
80.1k
  }
2235
2236
1.53M
      print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
2237
1.53M
      break;
2238
2.62M
    }
2239
2.62M
}
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
634k
{
2249
634k
  if (info->symbols
2250
634k
      && info->symbols[0]
2251
634k
      && (info->symbols[0]->flags & BSF_SYNTHETIC)
2252
634k
      && addr == bfd_asymbol_value (info->symbols[0]) + 12)
2253
0
    return true;
2254
2255
634k
  return false;
2256
634k
}
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
634k
{
2272
634k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
2273
634k
  int status;
2274
634k
  bfd_byte buffer[4];
2275
634k
  const struct mips_opcode *op, *opend;
2276
634k
  struct mips_print_arg_state state;
2277
634k
  void *is = info->stream;
2278
634k
  bool have_second;
2279
634k
  bool extend_only;
2280
634k
  unsigned int second;
2281
634k
  unsigned int first;
2282
634k
  unsigned int full;
2283
2284
634k
  info->bytes_per_chunk = 2;
2285
634k
  info->display_endian = info->endian;
2286
634k
  info->insn_info_valid = 1;
2287
634k
  info->branch_delay_insns = 0;
2288
634k
  info->data_size = 0;
2289
634k
  info->target = 0;
2290
634k
  info->target2 = 0;
2291
2292
634k
#define GET_OP(insn, field) \
2293
634k
  (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2294
  /* Decode PLT entry's GOT slot address word.  */
2295
634k
  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
634k
  else
2315
634k
    {
2316
634k
      info->insn_type = dis_nonbranch;
2317
634k
      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2318
634k
    }
2319
634k
  if (status != 0)
2320
136
    {
2321
136
      (*info->memory_error_func) (status, memaddr, info);
2322
136
      return -1;
2323
136
    }
2324
2325
634k
  extend_only = false;
2326
2327
634k
  if (info->endian == BFD_ENDIAN_BIG)
2328
333k
    first = bfd_getb16 (buffer);
2329
300k
  else
2330
300k
    first = bfd_getl16 (buffer);
2331
2332
634k
  status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2333
634k
  if (status == 0)
2334
633k
    {
2335
633k
      have_second = true;
2336
633k
      if (info->endian == BFD_ENDIAN_BIG)
2337
333k
  second = bfd_getb16 (buffer);
2338
300k
      else
2339
300k
  second = bfd_getl16 (buffer);
2340
633k
      full = (first << 16) | second;
2341
633k
    }
2342
326
  else
2343
326
    {
2344
326
      have_second = false;
2345
326
      second = 0;
2346
326
      full = first;
2347
326
    }
2348
2349
  /* FIXME: Should probably use a hash table on the major opcode here.  */
2350
2351
634k
  opend = mips16_opcodes + bfd_mips16_num_opcodes;
2352
58.9M
  for (op = mips16_opcodes; op < opend; op++)
2353
58.9M
    {
2354
58.9M
      enum match_kind match;
2355
2356
58.9M
      if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor))
2357
20.4M
  continue;
2358
2359
38.4M
      if (op->pinfo == INSN_MACRO
2360
38.4M
    || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2361
10.1M
  match = MATCH_NONE;
2362
28.3M
      else if (mips_opcode_32bit_p (op))
2363
595k
  {
2364
595k
    if (have_second
2365
595k
        && (full & op->mask) == op->match)
2366
10.9k
      match = MATCH_FULL;
2367
584k
    else
2368
584k
      match = MATCH_NONE;
2369
595k
  }
2370
27.7M
      else if ((first & op->mask) == op->match)
2371
572k
  {
2372
572k
    match = MATCH_SHORT;
2373
572k
    second = 0;
2374
572k
    full = first;
2375
572k
  }
2376
27.1M
      else if ((first & 0xf800) == 0xf000
2377
27.1M
         && have_second
2378
27.1M
         && !extend_only
2379
27.1M
         && (second & op->mask) == op->match)
2380
9.32k
  {
2381
9.32k
    if (op->pinfo2 & INSN2_SHORT_ONLY)
2382
606
      {
2383
606
        match = MATCH_NONE;
2384
606
        extend_only = true;
2385
606
      }
2386
8.72k
    else
2387
8.72k
      match = MATCH_FULL;
2388
9.32k
  }
2389
27.1M
      else
2390
27.1M
  match = MATCH_NONE;
2391
2392
38.4M
      if (match != MATCH_NONE)
2393
592k
  {
2394
592k
    const char *s;
2395
2396
592k
    infprintf (is, dis_style_mnemonic, "%s", op->name);
2397
592k
    if (op->args[0] != '\0')
2398
592k
      infprintf (is, dis_style_text, "\t");
2399
2400
592k
    init_print_arg_state (&state);
2401
3.22M
    for (s = op->args; *s != '\0'; s++)
2402
2.63M
      {
2403
2.63M
        if (*s == ','
2404
2.63M
      && s[1] == 'w'
2405
2.63M
      && GET_OP (full, RX) == GET_OP (full, RY))
2406
2.41k
    {
2407
      /* Skip the register and the comma.  */
2408
2.41k
      ++s;
2409
2.41k
      continue;
2410
2.41k
    }
2411
2.62M
        if (*s == ','
2412
2.62M
      && s[1] == 'v'
2413
2.62M
      && GET_OP (full, RZ) == GET_OP (full, RX))
2414
1.34k
    {
2415
      /* Skip the register and the comma.  */
2416
1.34k
      ++s;
2417
1.34k
      continue;
2418
1.34k
    }
2419
2.62M
        if (s[0] == 'N'
2420
2.62M
      && s[1] == ','
2421
2.62M
      && s[2] == 'O'
2422
2.62M
      && op->name[strlen (op->name) - 1] == '0')
2423
0
    {
2424
      /* Coprocessor register 0 with sel field.  */
2425
0
      const struct mips_cp0sel_name *n;
2426
0
      const struct mips_operand *operand;
2427
0
      unsigned int reg, sel;
2428
2429
0
      operand = decode_mips16_operand (*s, true);
2430
0
      reg = mips_extract_operand (operand, (first << 16) | second);
2431
0
      s += 2;
2432
0
      operand = decode_mips16_operand (*s, true);
2433
0
      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
0
      n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2441
0
                 mips_cp0sel_names_len,
2442
0
                 reg, sel);
2443
0
      if (n != NULL)
2444
0
        infprintf (is, dis_style_register, "%s", n->name);
2445
0
      else
2446
0
        {
2447
0
          infprintf (is, dis_style_register, "$%d", reg);
2448
0
          infprintf (is, dis_style_text, ",");
2449
0
          infprintf (is, dis_style_immediate, "%d", sel);
2450
0
        }
2451
0
    }
2452
2.62M
        else
2453
2.62M
    switch (match)
2454
2.62M
      {
2455
52.5k
        case MATCH_FULL:
2456
52.5k
          print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
2457
52.5k
               second, true, first, s[1] == '(');
2458
52.5k
          break;
2459
2.57M
        case MATCH_SHORT:
2460
2.57M
          print_mips16_insn_arg (info, &state, op, *s, memaddr,
2461
2.57M
               first, false, 0, s[1] == '(');
2462
2.57M
          break;
2463
0
        case MATCH_NONE:  /* Stop the compiler complaining.  */
2464
0
          break;
2465
2.62M
      }
2466
2.62M
      }
2467
2468
    /* Figure out branch instruction type and delay slot information.  */
2469
592k
    if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2470
12.7k
      info->branch_delay_insns = 1;
2471
592k
    if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2472
592k
        || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
2473
27.6k
      {
2474
27.6k
        if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2475
11.3k
    info->insn_type = dis_jsr;
2476
16.2k
        else
2477
16.2k
    info->insn_type = dis_branch;
2478
27.6k
      }
2479
564k
    else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
2480
28.6k
      info->insn_type = dis_condbranch;
2481
2482
592k
    return match == MATCH_FULL ? 4 : 2;
2483
592k
  }
2484
38.4M
    }
2485
41.6k
#undef GET_OP
2486
2487
41.6k
  infprintf (is, dis_style_assembler_directive, ".short");
2488
41.6k
  infprintf (is, dis_style_text, "\t");
2489
41.6k
  infprintf (is, dis_style_immediate, "0x%x", first);
2490
41.6k
  info->insn_type = dis_noninsn;
2491
2492
41.6k
  return 2;
2493
634k
}
2494
2495
/* Disassemble microMIPS instructions.  */
2496
2497
static int
2498
print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2499
63.6k
{
2500
63.6k
  const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
2501
63.6k
  const struct mips_opcode *op, *opend;
2502
63.6k
  void *is = info->stream;
2503
63.6k
  bfd_byte buffer[2];
2504
63.6k
  unsigned int higher;
2505
63.6k
  unsigned int length;
2506
63.6k
  int status;
2507
63.6k
  unsigned int insn;
2508
2509
63.6k
  info->bytes_per_chunk = 2;
2510
63.6k
  info->display_endian = info->endian;
2511
63.6k
  info->insn_info_valid = 1;
2512
63.6k
  info->branch_delay_insns = 0;
2513
63.6k
  info->data_size = 0;
2514
63.6k
  info->insn_type = dis_nonbranch;
2515
63.6k
  info->target = 0;
2516
63.6k
  info->target2 = 0;
2517
2518
63.6k
  status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2519
63.6k
  if (status != 0)
2520
49
    {
2521
49
      (*info->memory_error_func) (status, memaddr, info);
2522
49
      return -1;
2523
49
    }
2524
2525
63.6k
  length = 2;
2526
2527
63.6k
  if (info->endian == BFD_ENDIAN_BIG)
2528
930
    insn = bfd_getb16 (buffer);
2529
62.7k
  else
2530
62.7k
    insn = bfd_getl16 (buffer);
2531
2532
63.6k
  if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2533
44.9k
    {
2534
      /* This is a 32-bit microMIPS instruction.  */
2535
44.9k
      higher = insn;
2536
2537
44.9k
      status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2538
44.9k
      if (status != 0)
2539
50
  {
2540
50
    infprintf (is, dis_style_text, "micromips 0x%x", higher);
2541
50
    (*info->memory_error_func) (status, memaddr + 2, info);
2542
50
    return -1;
2543
50
  }
2544
2545
44.8k
      if (info->endian == BFD_ENDIAN_BIG)
2546
705
  insn = bfd_getb16 (buffer);
2547
44.1k
      else
2548
44.1k
  insn = bfd_getl16 (buffer);
2549
2550
44.8k
      insn = insn | (higher << 16);
2551
2552
44.8k
      length += 2;
2553
44.8k
    }
2554
2555
  /* FIXME: Should probably use a hash table on the major opcode here.  */
2556
2557
63.5k
  opend = micromips_opcodes + bfd_micromips_num_opcodes;
2558
43.4M
  for (op = micromips_opcodes; op < opend; op++)
2559
43.3M
    {
2560
43.3M
      if (op->pinfo != INSN_MACRO
2561
43.3M
    && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2562
43.3M
    && (insn & op->mask) == op->match
2563
43.3M
    && ((length == 2 && (op->mask & 0xffff0000) == 0)
2564
62.6k
        || (length == 4 && (op->mask & 0xffff0000) != 0)))
2565
48.6k
  {
2566
48.6k
    if (!validate_insn_args (op, decode_micromips_operand, insn))
2567
0
      continue;
2568
2569
48.6k
    infprintf (is, dis_style_mnemonic, "%s", op->name);
2570
2571
48.6k
    if (op->args[0])
2572
44.7k
      {
2573
44.7k
        infprintf (is, dis_style_text, "\t");
2574
44.7k
        print_insn_args (info, op, decode_micromips_operand, insn,
2575
44.7k
             memaddr + 1, length);
2576
44.7k
      }
2577
2578
    /* Figure out instruction type and branch delay information.  */
2579
48.6k
    if ((op->pinfo
2580
48.6k
         & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2581
5.00k
      info->branch_delay_insns = 1;
2582
48.6k
    if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2583
48.6k
         | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2584
3.27k
      {
2585
3.27k
        if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2586
2.58k
    info->insn_type = dis_jsr;
2587
689
        else
2588
689
    info->insn_type = dis_branch;
2589
3.27k
      }
2590
45.3k
    else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2591
45.3k
        | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2592
1.78k
      {
2593
1.78k
        if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2594
144
    info->insn_type = dis_condjsr;
2595
1.64k
        else
2596
1.64k
    info->insn_type = dis_condbranch;
2597
1.78k
      }
2598
43.5k
    else if ((op->pinfo
2599
43.5k
        & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
2600
19.1k
      info->insn_type = dis_dref;
2601
2602
48.6k
    return length;
2603
48.6k
  }
2604
43.3M
    }
2605
2606
14.9k
  infprintf (is, dis_style_assembler_directive, ".short");
2607
14.9k
  infprintf (is, dis_style_text, "\t");
2608
14.9k
  if (length != 2)
2609
12.8k
    {
2610
12.8k
      infprintf (is, dis_style_immediate, "0x%x", (insn >> 16) & 0xffff);
2611
12.8k
      infprintf (is, dis_style_text, ", ");
2612
12.8k
    }
2613
14.9k
  infprintf (is, dis_style_immediate, "0x%x", (insn & 0xffff));
2614
2615
14.9k
  info->insn_type = dis_noninsn;
2616
2617
14.9k
  return length;
2618
63.5k
}
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
955k
{
2631
955k
  int i;
2632
955k
  int l;
2633
2634
1.32M
  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
955k
  return 0;
2653
955k
}
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.17M
{
2666
1.17M
  bfd_byte buffer[INSNLEN];
2667
1.17M
  int status;
2668
2669
1.17M
  set_default_mips_dis_options (info);
2670
1.17M
  parse_mips_dis_options (info->disassembler_options);
2671
2672
1.17M
  if (info->mach == bfd_mach_mips16)
2673
0
    return print_insn_mips16 (memaddr, info);
2674
1.17M
  if (info->mach == bfd_mach_mips_micromips)
2675
0
    return print_insn_micromips (memaddr, info);
2676
2677
1.17M
#if 1
2678
  /* FIXME: If odd address, this is CLEARLY a compressed instruction.  */
2679
  /* Only a few tools will work this way.  */
2680
1.17M
  if (memaddr & 0x01)
2681
697k
    {
2682
697k
      if (micromips_ase)
2683
63.6k
  return print_insn_micromips (memaddr, info);
2684
634k
      else
2685
634k
  return print_insn_mips16 (memaddr, info);
2686
697k
    }
2687
477k
#endif
2688
2689
477k
#if SYMTAB_AVAILABLE
2690
477k
  if (is_compressed_mode_p (info, true))
2691
0
    return print_insn_micromips (memaddr, info);
2692
477k
  if (is_compressed_mode_p (info, false))
2693
0
    return print_insn_mips16 (memaddr, info);
2694
477k
#endif
2695
2696
477k
  status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2697
477k
  if (status == 0)
2698
477k
    {
2699
477k
      int insn;
2700
2701
477k
      if (endianness == BFD_ENDIAN_BIG)
2702
411k
  insn = bfd_getb32 (buffer);
2703
66.0k
      else
2704
66.0k
  insn = bfd_getl32 (buffer);
2705
2706
477k
      return print_insn_mips (memaddr, insn, info);
2707
477k
    }
2708
304
  else
2709
304
    {
2710
304
      (*info->memory_error_func) (status, memaddr, info);
2711
304
      return -1;
2712
304
    }
2713
477k
}
2714
2715
int
2716
print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2717
746k
{
2718
746k
  return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2719
746k
}
2720
2721
int
2722
print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2723
429k
{
2724
429k
  return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2725
429k
}
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
}