OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [opcodes/] [mips-dis.c] - Blame information for rev 241

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 khays
/* Print mips instructions for GDB, the GNU debugger, or for objdump.
2
   Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3
   2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009
4
   Free Software Foundation, Inc.
5
   Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
6
 
7
   This file is part of the GNU opcodes library.
8
 
9
   This library is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3, or (at your option)
12
   any later version.
13
 
14
   It is distributed in the hope that it will be useful, but WITHOUT
15
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
17
   License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program; if not, write to the Free Software
21
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22
   MA 02110-1301, USA.  */
23
 
24
#include "sysdep.h"
25
#include "dis-asm.h"
26
#include "libiberty.h"
27
#include "opcode/mips.h"
28
#include "opintl.h"
29
 
30
/* FIXME: These are needed to figure out if the code is mips16 or
31
   not. The low bit of the address is often a good indicator.  No
32
   symbol table is available when this code runs out in an embedded
33
   system as when it is used for disassembler support in a monitor.  */
34
 
35
#if !defined(EMBEDDED_ENV)
36
#define SYMTAB_AVAILABLE 1
37
#include "elf-bfd.h"
38
#include "elf/mips.h"
39
#endif
40
 
41
/* Mips instructions are at maximum this many bytes long.  */
42
#define INSNLEN 4
43
 
44
 
45
/* FIXME: These should be shared with gdb somehow.  */
46
 
47
struct mips_cp0sel_name
48
{
49
  unsigned int cp0reg;
50
  unsigned int sel;
51
  const char * const name;
52
};
53
 
54
/* The mips16 registers.  */
55
static const unsigned int mips16_to_32_reg_map[] =
56
{
57
  16, 17, 2, 3, 4, 5, 6, 7
58
};
59
 
60 158 khays
/* The microMIPS registers with type b.  */
61
#define micromips_to_32_reg_b_map       mips16_to_32_reg_map
62
 
63
/* The microMIPS registers with type c.  */
64
#define micromips_to_32_reg_c_map       mips16_to_32_reg_map
65
 
66
/* The microMIPS registers with type d.  */
67
#define micromips_to_32_reg_d_map       mips16_to_32_reg_map
68
 
69
/* The microMIPS registers with type e.  */
70
#define micromips_to_32_reg_e_map       mips16_to_32_reg_map
71
 
72
/* The microMIPS registers with type f.  */
73
#define micromips_to_32_reg_f_map       mips16_to_32_reg_map
74
 
75
/* The microMIPS registers with type g.  */
76
#define micromips_to_32_reg_g_map       mips16_to_32_reg_map
77
 
78
/* The microMIPS registers with type h.  */
79
static const unsigned int micromips_to_32_reg_h_map[] =
80
{
81
  5, 5, 6, 4, 4, 4, 4, 4
82
};
83
 
84
/* The microMIPS registers with type i.  */
85
static const unsigned int micromips_to_32_reg_i_map[] =
86
{
87
  6, 7, 7, 21, 22, 5, 6, 7
88
};
89
 
90
/* The microMIPS registers with type j: 32 registers.  */
91
 
92
/* The microMIPS registers with type l.  */
93
#define micromips_to_32_reg_l_map       mips16_to_32_reg_map
94
 
95
/* The microMIPS registers with type m.  */
96
static const unsigned int micromips_to_32_reg_m_map[] =
97
{
98
  0, 17, 2, 3, 16, 18, 19, 20
99
};
100
 
101
/* The microMIPS registers with type n.  */
102
#define micromips_to_32_reg_n_map      micromips_to_32_reg_m_map
103
 
104
/* The microMIPS registers with type p: 32 registers.  */
105
 
106
/* The microMIPS registers with type q.  */
107
static const unsigned int micromips_to_32_reg_q_map[] =
108
{
109
  0, 17, 2, 3, 4, 5, 6, 7
110
};
111
 
112
/* reg type s is $29.  */
113
 
114
/* reg type t is the same as the last register.  */
115
 
116
/* reg type y is $31.  */
117
 
118
/* reg type z is $0.  */
119
 
120
/* micromips imm B type.  */
121
static const int micromips_imm_b_map[8] =
122
{
123
  1, 4, 8, 12, 16, 20, 24, -1
124
};
125
 
126
/* micromips imm C type.  */
127
static const int micromips_imm_c_map[16] =
128
{
129
  128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 255, 32768, 65535
130
};
131
 
132
/* micromips imm D type: (-512..511)<<1.  */
133
/* micromips imm E type: (-64..63)<<1.  */
134
/* micromips imm F type: (0..63).  */
135
/* micromips imm G type: (-1..14).  */
136
/* micromips imm H type: (0..15)<<1.  */
137
/* micromips imm I type: (-1..126).  */
138
/* micromips imm J type: (0..15)<<2.  */
139
/* micromips imm L type: (0..15).  */
140
/* micromips imm M type: (1..8).  */
141
/* micromips imm W type: (0..63)<<2.  */
142
/* micromips imm X type: (-8..7).  */
143
/* micromips imm Y type: (-258..-3, 2..257)<<2.  */
144
 
145 18 khays
#define mips16_reg_names(rn)    mips_gpr_names[mips16_to_32_reg_map[rn]]
146
 
147
 
148
static const char * const mips_gpr_names_numeric[32] =
149
{
150
  "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
151
  "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
152
  "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
153
  "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
154
};
155
 
156
static const char * const mips_gpr_names_oldabi[32] =
157
{
158
  "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
159
  "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7",
160
  "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
161
  "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
162
};
163
 
164
static const char * const mips_gpr_names_newabi[32] =
165
{
166
  "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
167
  "a4",   "a5",   "a6",   "a7",   "t0",   "t1",   "t2",   "t3",
168
  "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
169
  "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
170
};
171
 
172
static const char * const mips_fpr_names_numeric[32] =
173
{
174
  "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",
175
  "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
176
  "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
177
  "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
178
};
179
 
180
static const char * const mips_fpr_names_32[32] =
181
{
182
  "fv0",  "fv0f", "fv1",  "fv1f", "ft0",  "ft0f", "ft1",  "ft1f",
183
  "ft2",  "ft2f", "ft3",  "ft3f", "fa0",  "fa0f", "fa1",  "fa1f",
184
  "ft4",  "ft4f", "ft5",  "ft5f", "fs0",  "fs0f", "fs1",  "fs1f",
185
  "fs2",  "fs2f", "fs3",  "fs3f", "fs4",  "fs4f", "fs5",  "fs5f"
186
};
187
 
188
static const char * const mips_fpr_names_n32[32] =
189
{
190
  "fv0",  "ft14", "fv1",  "ft15", "ft0",  "ft1",  "ft2",  "ft3",
191
  "ft4",  "ft5",  "ft6",  "ft7",  "fa0",  "fa1",  "fa2",  "fa3",
192
  "fa4",  "fa5",  "fa6",  "fa7",  "fs0",  "ft8",  "fs1",  "ft9",
193
  "fs2",  "ft10", "fs3",  "ft11", "fs4",  "ft12", "fs5",  "ft13"
194
};
195
 
196
static const char * const mips_fpr_names_64[32] =
197
{
198
  "fv0",  "ft12", "fv1",  "ft13", "ft0",  "ft1",  "ft2",  "ft3",
199
  "ft4",  "ft5",  "ft6",  "ft7",  "fa0",  "fa1",  "fa2",  "fa3",
200
  "fa4",  "fa5",  "fa6",  "fa7",  "ft8",  "ft9",  "ft10", "ft11",
201
  "fs0",  "fs1",  "fs2",  "fs3",  "fs4",  "fs5",  "fs6",  "fs7"
202
};
203
 
204
static const char * const mips_cp0_names_numeric[32] =
205
{
206
  "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
207
  "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
208
  "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
209
  "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
210
};
211
 
212
static const char * const mips_cp0_names_r3000[32] =
213
{
214
  "c0_index",     "c0_random",    "c0_entrylo",   "$3",
215
  "c0_context",   "$5",           "$6",           "$7",
216
  "c0_badvaddr",  "$9",           "c0_entryhi",   "$11",
217
  "c0_sr",        "c0_cause",     "c0_epc",       "c0_prid",
218
  "$16",          "$17",          "$18",          "$19",
219
  "$20",          "$21",          "$22",          "$23",
220
  "$24",          "$25",          "$26",          "$27",
221
  "$28",          "$29",          "$30",          "$31",
222
};
223
 
224
static const char * const mips_cp0_names_r4000[32] =
225
{
226
  "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
227
  "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
228
  "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
229
  "c0_sr",        "c0_cause",     "c0_epc",       "c0_prid",
230
  "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
231
  "c0_xcontext",  "$21",          "$22",          "$23",
232
  "$24",          "$25",          "c0_ecc",       "c0_cacheerr",
233
  "c0_taglo",     "c0_taghi",     "c0_errorepc",  "$31",
234
};
235
 
236
static const char * const mips_cp0_names_mips3264[32] =
237
{
238
  "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
239
  "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
240
  "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
241
  "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
242
  "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
243
  "c0_xcontext",  "$21",          "$22",          "c0_debug",
244
  "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr",
245
  "c0_taglo",     "c0_taghi",     "c0_errorepc",  "c0_desave",
246
};
247
 
248
static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
249
{
250
  { 16, 1, "c0_config1"         },
251
  { 16, 2, "c0_config2"         },
252
  { 16, 3, "c0_config3"         },
253
  { 18, 1, "c0_watchlo,1"       },
254
  { 18, 2, "c0_watchlo,2"       },
255
  { 18, 3, "c0_watchlo,3"       },
256
  { 18, 4, "c0_watchlo,4"       },
257
  { 18, 5, "c0_watchlo,5"       },
258
  { 18, 6, "c0_watchlo,6"       },
259
  { 18, 7, "c0_watchlo,7"       },
260
  { 19, 1, "c0_watchhi,1"       },
261
  { 19, 2, "c0_watchhi,2"       },
262
  { 19, 3, "c0_watchhi,3"       },
263
  { 19, 4, "c0_watchhi,4"       },
264
  { 19, 5, "c0_watchhi,5"       },
265
  { 19, 6, "c0_watchhi,6"       },
266
  { 19, 7, "c0_watchhi,7"       },
267
  { 25, 1, "c0_perfcnt,1"       },
268
  { 25, 2, "c0_perfcnt,2"       },
269
  { 25, 3, "c0_perfcnt,3"       },
270
  { 25, 4, "c0_perfcnt,4"       },
271
  { 25, 5, "c0_perfcnt,5"       },
272
  { 25, 6, "c0_perfcnt,6"       },
273
  { 25, 7, "c0_perfcnt,7"       },
274
  { 27, 1, "c0_cacheerr,1"      },
275
  { 27, 2, "c0_cacheerr,2"      },
276
  { 27, 3, "c0_cacheerr,3"      },
277
  { 28, 1, "c0_datalo"          },
278
  { 29, 1, "c0_datahi"          }
279
};
280
 
281
static const char * const mips_cp0_names_mips3264r2[32] =
282
{
283
  "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
284
  "c0_context",   "c0_pagemask",  "c0_wired",     "c0_hwrena",
285
  "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
286
  "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
287
  "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
288
  "c0_xcontext",  "$21",          "$22",          "c0_debug",
289
  "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr",
290
  "c0_taglo",     "c0_taghi",     "c0_errorepc",  "c0_desave",
291
};
292
 
293
static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
294
{
295
  {  4, 1, "c0_contextconfig"   },
296
  {  0, 1, "c0_mvpcontrol"       },
297
  {  0, 2, "c0_mvpconf0" },
298
  {  0, 3, "c0_mvpconf1" },
299
  {  1, 1, "c0_vpecontrol"      },
300
  {  1, 2, "c0_vpeconf0"        },
301
  {  1, 3, "c0_vpeconf1"        },
302
  {  1, 4, "c0_yqmask"          },
303
  {  1, 5, "c0_vpeschedule"     },
304
  {  1, 6, "c0_vpeschefback"    },
305
  {  2, 1, "c0_tcstatus"        },
306
  {  2, 2, "c0_tcbind"          },
307
  {  2, 3, "c0_tcrestart"       },
308
  {  2, 4, "c0_tchalt"          },
309
  {  2, 5, "c0_tccontext"       },
310
  {  2, 6, "c0_tcschedule"      },
311
  {  2, 7, "c0_tcschefback"     },
312
  {  5, 1, "c0_pagegrain"       },
313
  {  6, 1, "c0_srsconf0"        },
314
  {  6, 2, "c0_srsconf1"        },
315
  {  6, 3, "c0_srsconf2"        },
316
  {  6, 4, "c0_srsconf3"        },
317
  {  6, 5, "c0_srsconf4"        },
318
  { 12, 1, "c0_intctl"          },
319
  { 12, 2, "c0_srsctl"          },
320
  { 12, 3, "c0_srsmap"          },
321
  { 15, 1, "c0_ebase"           },
322
  { 16, 1, "c0_config1"         },
323
  { 16, 2, "c0_config2"         },
324
  { 16, 3, "c0_config3"         },
325
  { 18, 1, "c0_watchlo,1"       },
326
  { 18, 2, "c0_watchlo,2"       },
327
  { 18, 3, "c0_watchlo,3"       },
328
  { 18, 4, "c0_watchlo,4"       },
329
  { 18, 5, "c0_watchlo,5"       },
330
  { 18, 6, "c0_watchlo,6"       },
331
  { 18, 7, "c0_watchlo,7"       },
332
  { 19, 1, "c0_watchhi,1"       },
333
  { 19, 2, "c0_watchhi,2"       },
334
  { 19, 3, "c0_watchhi,3"       },
335
  { 19, 4, "c0_watchhi,4"       },
336
  { 19, 5, "c0_watchhi,5"       },
337
  { 19, 6, "c0_watchhi,6"       },
338
  { 19, 7, "c0_watchhi,7"       },
339
  { 23, 1, "c0_tracecontrol"    },
340
  { 23, 2, "c0_tracecontrol2"   },
341
  { 23, 3, "c0_usertracedata"   },
342
  { 23, 4, "c0_tracebpc"        },
343
  { 25, 1, "c0_perfcnt,1"       },
344
  { 25, 2, "c0_perfcnt,2"       },
345
  { 25, 3, "c0_perfcnt,3"       },
346
  { 25, 4, "c0_perfcnt,4"       },
347
  { 25, 5, "c0_perfcnt,5"       },
348
  { 25, 6, "c0_perfcnt,6"       },
349
  { 25, 7, "c0_perfcnt,7"       },
350
  { 27, 1, "c0_cacheerr,1"      },
351
  { 27, 2, "c0_cacheerr,2"      },
352
  { 27, 3, "c0_cacheerr,3"      },
353
  { 28, 1, "c0_datalo"          },
354
  { 28, 2, "c0_taglo1"          },
355
  { 28, 3, "c0_datalo1"         },
356
  { 28, 4, "c0_taglo2"          },
357
  { 28, 5, "c0_datalo2"         },
358
  { 28, 6, "c0_taglo3"          },
359
  { 28, 7, "c0_datalo3"         },
360
  { 29, 1, "c0_datahi"          },
361
  { 29, 2, "c0_taghi1"          },
362
  { 29, 3, "c0_datahi1"         },
363
  { 29, 4, "c0_taghi2"          },
364
  { 29, 5, "c0_datahi2"         },
365
  { 29, 6, "c0_taghi3"          },
366
  { 29, 7, "c0_datahi3"         },
367
};
368
 
369
/* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods.  */
370
static const char * const mips_cp0_names_sb1[32] =
371
{
372
  "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
373
  "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
374
  "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
375
  "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
376
  "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
377
  "c0_xcontext",  "$21",          "$22",          "c0_debug",
378
  "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr_i",
379
  "c0_taglo_i",   "c0_taghi_i",   "c0_errorepc",  "c0_desave",
380
};
381
 
382
static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
383
{
384
  { 16, 1, "c0_config1"         },
385
  { 18, 1, "c0_watchlo,1"       },
386
  { 19, 1, "c0_watchhi,1"       },
387
  { 22, 0, "c0_perftrace"        },
388
  { 23, 3, "c0_edebug"          },
389
  { 25, 1, "c0_perfcnt,1"       },
390
  { 25, 2, "c0_perfcnt,2"       },
391
  { 25, 3, "c0_perfcnt,3"       },
392
  { 25, 4, "c0_perfcnt,4"       },
393
  { 25, 5, "c0_perfcnt,5"       },
394
  { 25, 6, "c0_perfcnt,6"       },
395
  { 25, 7, "c0_perfcnt,7"       },
396
  { 26, 1, "c0_buserr_pa"       },
397
  { 27, 1, "c0_cacheerr_d"      },
398
  { 27, 3, "c0_cacheerr_d_pa"   },
399
  { 28, 1, "c0_datalo_i"        },
400
  { 28, 2, "c0_taglo_d"         },
401
  { 28, 3, "c0_datalo_d"        },
402
  { 29, 1, "c0_datahi_i"        },
403
  { 29, 2, "c0_taghi_d"         },
404
  { 29, 3, "c0_datahi_d"        },
405
};
406
 
407
/* Xlr cop0 register names.  */
408
static const char * const mips_cp0_names_xlr[32] = {
409
  "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
410
  "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
411
  "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
412
  "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
413
  "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
414
  "c0_xcontext",  "$21",          "$22",          "c0_debug",
415
  "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr_i",
416
  "c0_taglo_i",   "c0_taghi_i",   "c0_errorepc",  "c0_desave",
417
};
418
 
419
/* XLR's CP0 Select Registers.  */
420
 
421
static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
422
  {  9, 6, "c0_extintreq"       },
423
  {  9, 7, "c0_extintmask"      },
424
  { 15, 1, "c0_ebase"           },
425
  { 16, 1, "c0_config1"         },
426
  { 16, 2, "c0_config2"         },
427
  { 16, 3, "c0_config3"         },
428
  { 16, 7, "c0_procid2"         },
429
  { 18, 1, "c0_watchlo,1"       },
430
  { 18, 2, "c0_watchlo,2"       },
431
  { 18, 3, "c0_watchlo,3"       },
432
  { 18, 4, "c0_watchlo,4"       },
433
  { 18, 5, "c0_watchlo,5"       },
434
  { 18, 6, "c0_watchlo,6"       },
435
  { 18, 7, "c0_watchlo,7"       },
436
  { 19, 1, "c0_watchhi,1"       },
437
  { 19, 2, "c0_watchhi,2"       },
438
  { 19, 3, "c0_watchhi,3"       },
439
  { 19, 4, "c0_watchhi,4"       },
440
  { 19, 5, "c0_watchhi,5"       },
441
  { 19, 6, "c0_watchhi,6"       },
442
  { 19, 7, "c0_watchhi,7"       },
443
  { 25, 1, "c0_perfcnt,1"       },
444
  { 25, 2, "c0_perfcnt,2"       },
445
  { 25, 3, "c0_perfcnt,3"       },
446
  { 25, 4, "c0_perfcnt,4"       },
447
  { 25, 5, "c0_perfcnt,5"       },
448
  { 25, 6, "c0_perfcnt,6"       },
449
  { 25, 7, "c0_perfcnt,7"       },
450
  { 27, 1, "c0_cacheerr,1"      },
451
  { 27, 2, "c0_cacheerr,2"      },
452
  { 27, 3, "c0_cacheerr,3"      },
453
  { 28, 1, "c0_datalo"          },
454
  { 29, 1, "c0_datahi"          }
455
};
456
 
457
static const char * const mips_hwr_names_numeric[32] =
458
{
459
  "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
460
  "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
461
  "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
462
  "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
463
};
464
 
465
static const char * const mips_hwr_names_mips3264r2[32] =
466
{
467
  "hwr_cpunum",   "hwr_synci_step", "hwr_cc",     "hwr_ccres",
468
  "$4",          "$5",            "$6",           "$7",
469
  "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
470
  "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
471
  "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
472
};
473
 
474
struct mips_abi_choice
475
{
476
  const char * name;
477
  const char * const *gpr_names;
478
  const char * const *fpr_names;
479
};
480
 
481
struct mips_abi_choice mips_abi_choices[] =
482
{
483
  { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
484
  { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
485
  { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
486
  { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
487
};
488
 
489
struct mips_arch_choice
490
{
491
  const char *name;
492
  int bfd_mach_valid;
493
  unsigned long bfd_mach;
494
  int processor;
495
  int isa;
496
  const char * const *cp0_names;
497
  const struct mips_cp0sel_name *cp0sel_names;
498
  unsigned int cp0sel_names_len;
499
  const char * const *hwr_names;
500
};
501
 
502
const struct mips_arch_choice mips_arch_choices[] =
503
{
504
  { "numeric",  0, 0, 0, 0,
505
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
506
 
507
  { "r3000",    1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1,
508
    mips_cp0_names_r3000, NULL, 0, mips_hwr_names_numeric },
509
  { "r3900",    1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1,
510
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
511
  { "r4000",    1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3,
512
    mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric },
513
  { "r4010",    1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2,
514
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
515
  { "vr4100",   1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3,
516
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
517
  { "vr4111",   1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3,
518
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
519
  { "vr4120",   1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3,
520
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
521
  { "r4300",    1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3,
522
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
523
  { "r4400",    1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3,
524
    mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric },
525
  { "r4600",    1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3,
526
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
527
  { "r4650",    1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3,
528
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
529
  { "r5000",    1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4,
530
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
531
  { "vr5400",   1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4,
532
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
533
  { "vr5500",   1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4,
534
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
535
  { "r6000",    1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2,
536
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
537
  { "rm7000",   1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4,
538
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
539
  { "rm9000",   1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4,
540
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
541
  { "r8000",    1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4,
542
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
543
  { "r10000",   1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4,
544
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
545
  { "r12000",   1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4,
546
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
547
  { "r14000",   1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4,
548
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
549
  { "r16000",   1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4,
550
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
551
  { "mips5",    1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5,
552
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
553
 
554
  /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
555
     Note that MIPS-3D and MDMX are not applicable to MIPS32.  (See
556
     _MIPS32 Architecture For Programmers Volume I: Introduction to the
557
     MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
558
     page 1.  */
559
  { "mips32",   1, bfd_mach_mipsisa32, CPU_MIPS32,
560
    ISA_MIPS32 | INSN_SMARTMIPS,
561
    mips_cp0_names_mips3264,
562
    mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
563
    mips_hwr_names_numeric },
564
 
565
  { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
566
    (ISA_MIPS32R2 | INSN_SMARTMIPS | INSN_DSP | INSN_DSPR2
567 158 khays
     | INSN_MIPS3D | INSN_MT | INSN_MCU),
568 18 khays
    mips_cp0_names_mips3264r2,
569
    mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
570
    mips_hwr_names_mips3264r2 },
571
 
572
  /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs.  */
573
  { "mips64",   1, bfd_mach_mipsisa64, CPU_MIPS64,
574
    ISA_MIPS64 | INSN_MIPS3D | INSN_MDMX,
575
    mips_cp0_names_mips3264,
576
    mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
577
    mips_hwr_names_numeric },
578
 
579
  { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
580
    (ISA_MIPS64R2 | INSN_MIPS3D | INSN_DSP | INSN_DSPR2
581 158 khays
     | INSN_DSP64 | INSN_MT | INSN_MDMX | INSN_MCU),
582 18 khays
    mips_cp0_names_mips3264r2,
583
    mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
584
    mips_hwr_names_mips3264r2 },
585
 
586
  { "sb1",      1, bfd_mach_mips_sb1, CPU_SB1,
587
    ISA_MIPS64 | INSN_MIPS3D | INSN_SB1,
588
    mips_cp0_names_sb1,
589
    mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
590
    mips_hwr_names_numeric },
591
 
592
  { "loongson2e",   1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
593
    ISA_MIPS3 | INSN_LOONGSON_2E, mips_cp0_names_numeric,
594
    NULL, 0, mips_hwr_names_numeric },
595
 
596
  { "loongson2f",   1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
597
    ISA_MIPS3 | INSN_LOONGSON_2F, mips_cp0_names_numeric,
598
    NULL, 0, mips_hwr_names_numeric },
599
 
600
  { "loongson3a",   1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
601
    ISA_MIPS64 | INSN_LOONGSON_3A, mips_cp0_names_numeric,
602
    NULL, 0, mips_hwr_names_numeric },
603
 
604
  { "octeon",   1, bfd_mach_mips_octeon, CPU_OCTEON,
605
    ISA_MIPS64R2 | INSN_OCTEON, mips_cp0_names_numeric, NULL, 0,
606
    mips_hwr_names_numeric },
607
 
608 166 khays
  { "octeon+",   1, bfd_mach_mips_octeonp, CPU_OCTEONP,
609
    ISA_MIPS64R2 | INSN_OCTEONP, mips_cp0_names_numeric,
610
    NULL, 0, mips_hwr_names_numeric },
611
 
612
  { "octeon2",   1, bfd_mach_mips_octeon2, CPU_OCTEON2,
613
    ISA_MIPS64R2 | INSN_OCTEON2, mips_cp0_names_numeric,
614
    NULL, 0, mips_hwr_names_numeric },
615
 
616 18 khays
  { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
617
    ISA_MIPS64 | INSN_XLR,
618
    mips_cp0_names_xlr,
619
    mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
620
    mips_hwr_names_numeric },
621
 
622
  /* This entry, mips16, is here only for ISA/processor selection; do
623
     not print its name.  */
624
  { "",         1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3,
625
    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
626
};
627
 
628
/* ISA and processor type to disassemble for, and register names to use.
629
   set_default_mips_dis_options and parse_mips_dis_options fill in these
630
   values.  */
631
static int mips_processor;
632
static int mips_isa;
633 158 khays
static int micromips_ase;
634 18 khays
static const char * const *mips_gpr_names;
635
static const char * const *mips_fpr_names;
636
static const char * const *mips_cp0_names;
637
static const struct mips_cp0sel_name *mips_cp0sel_names;
638
static int mips_cp0sel_names_len;
639
static const char * const *mips_hwr_names;
640
 
641
/* Other options */
642
static int no_aliases;  /* If set disassemble as most general inst.  */
643
 
644
static const struct mips_abi_choice *
645
choose_abi_by_name (const char *name, unsigned int namelen)
646
{
647
  const struct mips_abi_choice *c;
648
  unsigned int i;
649
 
650
  for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
651
    if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
652
        && strlen (mips_abi_choices[i].name) == namelen)
653
      c = &mips_abi_choices[i];
654
 
655
  return c;
656
}
657
 
658
static const struct mips_arch_choice *
659
choose_arch_by_name (const char *name, unsigned int namelen)
660
{
661
  const struct mips_arch_choice *c = NULL;
662
  unsigned int i;
663
 
664
  for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
665
    if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
666
        && strlen (mips_arch_choices[i].name) == namelen)
667
      c = &mips_arch_choices[i];
668
 
669
  return c;
670
}
671
 
672
static const struct mips_arch_choice *
673
choose_arch_by_number (unsigned long mach)
674
{
675
  static unsigned long hint_bfd_mach;
676
  static const struct mips_arch_choice *hint_arch_choice;
677
  const struct mips_arch_choice *c;
678
  unsigned int i;
679
 
680
  /* We optimize this because even if the user specifies no
681
     flags, this will be done for every instruction!  */
682
  if (hint_bfd_mach == mach
683
      && hint_arch_choice != NULL
684
      && hint_arch_choice->bfd_mach == hint_bfd_mach)
685
    return hint_arch_choice;
686
 
687
  for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
688
    {
689
      if (mips_arch_choices[i].bfd_mach_valid
690
          && mips_arch_choices[i].bfd_mach == mach)
691
        {
692
          c = &mips_arch_choices[i];
693
          hint_bfd_mach = mach;
694
          hint_arch_choice = c;
695
        }
696
    }
697
  return c;
698
}
699
 
700
/* Check if the object uses NewABI conventions.  */
701
 
702
static int
703
is_newabi (Elf_Internal_Ehdr *header)
704
{
705
  /* There are no old-style ABIs which use 64-bit ELF.  */
706
  if (header->e_ident[EI_CLASS] == ELFCLASS64)
707
    return 1;
708
 
709
  /* If a 32-bit ELF file, n32 is a new-style ABI.  */
710
  if ((header->e_flags & EF_MIPS_ABI2) != 0)
711
    return 1;
712
 
713
  return 0;
714
}
715
 
716 158 khays
/* Check if the object has microMIPS ASE code.  */
717
 
718
static int
719
is_micromips (Elf_Internal_Ehdr *header)
720
{
721
  if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
722
    return 1;
723
 
724
  return 0;
725
}
726
 
727 18 khays
static void
728
set_default_mips_dis_options (struct disassemble_info *info)
729
{
730
  const struct mips_arch_choice *chosen_arch;
731
 
732 158 khays
  /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
733
     is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
734
     CP0 register, and HWR names.  */
735 18 khays
  mips_isa = ISA_MIPS3;
736 158 khays
  mips_processor = CPU_R3000;
737
  micromips_ase = 0;
738 18 khays
  mips_gpr_names = mips_gpr_names_oldabi;
739
  mips_fpr_names = mips_fpr_names_numeric;
740
  mips_cp0_names = mips_cp0_names_numeric;
741
  mips_cp0sel_names = NULL;
742
  mips_cp0sel_names_len = 0;
743
  mips_hwr_names = mips_hwr_names_numeric;
744
  no_aliases = 0;
745
 
746 158 khays
  /* Update settings according to the ELF file header flags.  */
747 18 khays
  if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
748
    {
749
      Elf_Internal_Ehdr *header;
750
 
751
      header = elf_elfheader (info->section->owner);
752 158 khays
      /* If an ELF "newabi" binary, use the n32/(n)64 GPR names.  */
753 18 khays
      if (is_newabi (header))
754
        mips_gpr_names = mips_gpr_names_newabi;
755 158 khays
      /* If a microMIPS binary, then don't use MIPS16 bindings.  */
756
      micromips_ase = is_micromips (header);
757 18 khays
    }
758
 
759
  /* Set ISA, architecture, and cp0 register names as best we can.  */
760
#if ! SYMTAB_AVAILABLE
761
  /* This is running out on a target machine, not in a host tool.
762
     FIXME: Where does mips_target_info come from?  */
763
  target_processor = mips_target_info.processor;
764
  mips_isa = mips_target_info.isa;
765
#else
766
  chosen_arch = choose_arch_by_number (info->mach);
767
  if (chosen_arch != NULL)
768
    {
769
      mips_processor = chosen_arch->processor;
770
      mips_isa = chosen_arch->isa;
771
      mips_cp0_names = chosen_arch->cp0_names;
772
      mips_cp0sel_names = chosen_arch->cp0sel_names;
773
      mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
774
      mips_hwr_names = chosen_arch->hwr_names;
775
    }
776
#endif
777
}
778
 
779
static void
780
parse_mips_dis_option (const char *option, unsigned int len)
781
{
782
  unsigned int i, optionlen, vallen;
783
  const char *val;
784
  const struct mips_abi_choice *chosen_abi;
785
  const struct mips_arch_choice *chosen_arch;
786
 
787
  /* Try to match options that are simple flags */
788
  if (CONST_STRNEQ (option, "no-aliases"))
789
    {
790
      no_aliases = 1;
791
      return;
792
    }
793
 
794
  /* Look for the = that delimits the end of the option name.  */
795
  for (i = 0; i < len; i++)
796
    if (option[i] == '=')
797
      break;
798
 
799
  if (i == 0)            /* Invalid option: no name before '='.  */
800
    return;
801
  if (i == len)         /* Invalid option: no '='.  */
802
    return;
803
  if (i == (len - 1))   /* Invalid option: no value after '='.  */
804
    return;
805
 
806
  optionlen = i;
807
  val = option + (optionlen + 1);
808
  vallen = len - (optionlen + 1);
809
 
810
  if (strncmp ("gpr-names", option, optionlen) == 0
811
      && strlen ("gpr-names") == optionlen)
812
    {
813
      chosen_abi = choose_abi_by_name (val, vallen);
814
      if (chosen_abi != NULL)
815
        mips_gpr_names = chosen_abi->gpr_names;
816
      return;
817
    }
818
 
819
  if (strncmp ("fpr-names", option, optionlen) == 0
820
      && strlen ("fpr-names") == optionlen)
821
    {
822
      chosen_abi = choose_abi_by_name (val, vallen);
823
      if (chosen_abi != NULL)
824
        mips_fpr_names = chosen_abi->fpr_names;
825
      return;
826
    }
827
 
828
  if (strncmp ("cp0-names", option, optionlen) == 0
829
      && strlen ("cp0-names") == optionlen)
830
    {
831
      chosen_arch = choose_arch_by_name (val, vallen);
832
      if (chosen_arch != NULL)
833
        {
834
          mips_cp0_names = chosen_arch->cp0_names;
835
          mips_cp0sel_names = chosen_arch->cp0sel_names;
836
          mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
837
        }
838
      return;
839
    }
840
 
841
  if (strncmp ("hwr-names", option, optionlen) == 0
842
      && strlen ("hwr-names") == optionlen)
843
    {
844
      chosen_arch = choose_arch_by_name (val, vallen);
845
      if (chosen_arch != NULL)
846
        mips_hwr_names = chosen_arch->hwr_names;
847
      return;
848
    }
849
 
850
  if (strncmp ("reg-names", option, optionlen) == 0
851
      && strlen ("reg-names") == optionlen)
852
    {
853
      /* We check both ABI and ARCH here unconditionally, so
854
         that "numeric" will do the desirable thing: select
855
         numeric register names for all registers.  Other than
856
         that, a given name probably won't match both.  */
857
      chosen_abi = choose_abi_by_name (val, vallen);
858
      if (chosen_abi != NULL)
859
        {
860
          mips_gpr_names = chosen_abi->gpr_names;
861
          mips_fpr_names = chosen_abi->fpr_names;
862
        }
863
      chosen_arch = choose_arch_by_name (val, vallen);
864
      if (chosen_arch != NULL)
865
        {
866
          mips_cp0_names = chosen_arch->cp0_names;
867
          mips_cp0sel_names = chosen_arch->cp0sel_names;
868
          mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
869
          mips_hwr_names = chosen_arch->hwr_names;
870
        }
871
      return;
872
    }
873
 
874
  /* Invalid option.  */
875
}
876
 
877
static void
878
parse_mips_dis_options (const char *options)
879
{
880
  const char *option_end;
881
 
882
  if (options == NULL)
883
    return;
884
 
885
  while (*options != '\0')
886
    {
887
      /* Skip empty options.  */
888
      if (*options == ',')
889
        {
890
          options++;
891
          continue;
892
        }
893
 
894
      /* We know that *options is neither NUL or a comma.  */
895
      option_end = options + 1;
896
      while (*option_end != ',' && *option_end != '\0')
897
        option_end++;
898
 
899
      parse_mips_dis_option (options, option_end - options);
900
 
901
      /* Go on to the next one.  If option_end points to a comma, it
902
         will be skipped above.  */
903
      options = option_end;
904
    }
905
}
906
 
907
static const struct mips_cp0sel_name *
908
lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
909
                         unsigned int len,
910
                         unsigned int cp0reg,
911
                         unsigned int sel)
912
{
913
  unsigned int i;
914
 
915
  for (i = 0; i < len; i++)
916
    if (names[i].cp0reg == cp0reg && names[i].sel == sel)
917
      return &names[i];
918
  return NULL;
919
}
920
 
921
/* Print insn arguments for 32/64-bit code.  */
922
 
923
static void
924
print_insn_args (const char *d,
925
                 register unsigned long int l,
926
                 bfd_vma pc,
927
                 struct disassemble_info *info,
928
                 const struct mips_opcode *opp)
929
{
930
  int op, delta;
931
  unsigned int lsb, msb, msbd;
932
 
933
  lsb = 0;
934
 
935
  for (; *d != '\0'; d++)
936
    {
937
      switch (*d)
938
        {
939
        case ',':
940
        case '(':
941
        case ')':
942
        case '[':
943
        case ']':
944
          (*info->fprintf_func) (info->stream, "%c", *d);
945
          break;
946
 
947
        case '+':
948
          /* Extension character; switch for second char.  */
949
          d++;
950
          switch (*d)
951
            {
952
            case '\0':
953
              /* xgettext:c-format */
954
              (*info->fprintf_func) (info->stream,
955
                                     _("# internal error, incomplete extension sequence (+)"));
956
              return;
957
 
958
            case 'A':
959
              lsb = (l >> OP_SH_SHAMT) & OP_MASK_SHAMT;
960
              (*info->fprintf_func) (info->stream, "0x%x", lsb);
961
              break;
962
 
963
            case 'B':
964
              msb = (l >> OP_SH_INSMSB) & OP_MASK_INSMSB;
965
              (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
966
              break;
967
 
968
            case '1':
969
              (*info->fprintf_func) (info->stream, "0x%lx",
970
                                     (l >> OP_SH_UDI1) & OP_MASK_UDI1);
971
              break;
972
 
973
            case '2':
974
              (*info->fprintf_func) (info->stream, "0x%lx",
975
                                     (l >> OP_SH_UDI2) & OP_MASK_UDI2);
976
              break;
977
 
978
            case '3':
979
              (*info->fprintf_func) (info->stream, "0x%lx",
980
                                     (l >> OP_SH_UDI3) & OP_MASK_UDI3);
981
              break;
982
 
983
            case '4':
984
              (*info->fprintf_func) (info->stream, "0x%lx",
985
                                     (l >> OP_SH_UDI4) & OP_MASK_UDI4);
986
              break;
987
 
988
            case 'C':
989
            case 'H':
990
              msbd = (l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD;
991
              (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
992
              break;
993
 
994
            case 'D':
995
              {
996
                const struct mips_cp0sel_name *n;
997
                unsigned int cp0reg, sel;
998
 
999
                cp0reg = (l >> OP_SH_RD) & OP_MASK_RD;
1000
                sel = (l >> OP_SH_SEL) & OP_MASK_SEL;
1001
 
1002
                /* CP0 register including 'sel' code for mtcN (et al.), to be
1003
                   printed textually if known.  If not known, print both
1004
                   CP0 register name and sel numerically since CP0 register
1005
                   with sel 0 may have a name unrelated to register being
1006
                   printed.  */
1007
                n = lookup_mips_cp0sel_name(mips_cp0sel_names,
1008
                                            mips_cp0sel_names_len, cp0reg, sel);
1009
                if (n != NULL)
1010
                  (*info->fprintf_func) (info->stream, "%s", n->name);
1011
                else
1012
                  (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel);
1013
                break;
1014
              }
1015
 
1016
            case 'E':
1017
              lsb = ((l >> OP_SH_SHAMT) & OP_MASK_SHAMT) + 32;
1018
              (*info->fprintf_func) (info->stream, "0x%x", lsb);
1019
              break;
1020
 
1021
            case 'F':
1022
              msb = ((l >> OP_SH_INSMSB) & OP_MASK_INSMSB) + 32;
1023
              (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
1024
              break;
1025
 
1026
            case 'G':
1027
              msbd = ((l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD) + 32;
1028
              (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
1029
              break;
1030
 
1031
            case 't': /* Coprocessor 0 reg name */
1032
              (*info->fprintf_func) (info->stream, "%s",
1033
                                     mips_cp0_names[(l >> OP_SH_RT) &
1034
                                                     OP_MASK_RT]);
1035
              break;
1036
 
1037
            case 'T': /* Coprocessor 0 reg name */
1038
              {
1039
                const struct mips_cp0sel_name *n;
1040
                unsigned int cp0reg, sel;
1041
 
1042
                cp0reg = (l >> OP_SH_RT) & OP_MASK_RT;
1043
                sel = (l >> OP_SH_SEL) & OP_MASK_SEL;
1044
 
1045
                /* CP0 register including 'sel' code for mftc0, to be
1046
                   printed textually if known.  If not known, print both
1047
                   CP0 register name and sel numerically since CP0 register
1048
                   with sel 0 may have a name unrelated to register being
1049
                   printed.  */
1050
                n = lookup_mips_cp0sel_name(mips_cp0sel_names,
1051
                                            mips_cp0sel_names_len, cp0reg, sel);
1052
                if (n != NULL)
1053
                  (*info->fprintf_func) (info->stream, "%s", n->name);
1054
                else
1055
                  (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel);
1056
                break;
1057
              }
1058
 
1059
            case 'x':           /* bbit bit index */
1060
              (*info->fprintf_func) (info->stream, "0x%lx",
1061
                                     (l >> OP_SH_BBITIND) & OP_MASK_BBITIND);
1062
              break;
1063
 
1064
            case 'p':           /* cins, cins32, exts and exts32 position */
1065
              (*info->fprintf_func) (info->stream, "0x%lx",
1066
                                     (l >> OP_SH_CINSPOS) & OP_MASK_CINSPOS);
1067
              break;
1068
 
1069
            case 's':           /* cins and exts length-minus-one */
1070
              (*info->fprintf_func) (info->stream, "0x%lx",
1071
                                     (l >> OP_SH_CINSLM1) & OP_MASK_CINSLM1);
1072
              break;
1073
 
1074
            case 'S':           /* cins32 and exts32 length-minus-one field */
1075
              (*info->fprintf_func) (info->stream, "0x%lx",
1076
                                     (l >> OP_SH_CINSLM1) & OP_MASK_CINSLM1);
1077
              break;
1078
 
1079
            case 'Q':           /* seqi/snei immediate field */
1080
              op = (l >> OP_SH_SEQI) & OP_MASK_SEQI;
1081
              /* Sign-extend it.  */
1082
              op = (op ^ 512) - 512;
1083
              (*info->fprintf_func) (info->stream, "%d", op);
1084
              break;
1085
 
1086
            case 'a':           /* 8-bit signed offset in bit 6 */
1087
              delta = (l >> OP_SH_OFFSET_A) & OP_MASK_OFFSET_A;
1088
              if (delta & 0x80)
1089
                delta |= ~OP_MASK_OFFSET_A;
1090
              (*info->fprintf_func) (info->stream, "%d", delta);
1091
              break;
1092
 
1093
            case 'b':           /* 8-bit signed offset in bit 3 */
1094
              delta = (l >> OP_SH_OFFSET_B) & OP_MASK_OFFSET_B;
1095
              if (delta & 0x80)
1096
                delta |= ~OP_MASK_OFFSET_B;
1097
              (*info->fprintf_func) (info->stream, "%d", delta);
1098
              break;
1099
 
1100
            case 'c':           /* 9-bit signed offset in bit 6 */
1101
              delta = (l >> OP_SH_OFFSET_C) & OP_MASK_OFFSET_C;
1102
              if (delta & 0x100)
1103
                delta |= ~OP_MASK_OFFSET_C;
1104
              /* Left shift 4 bits to print the real offset.  */
1105
              (*info->fprintf_func) (info->stream, "%d", delta << 4);
1106
              break;
1107
 
1108
            case 'z':
1109
              (*info->fprintf_func) (info->stream, "%s",
1110
                                     mips_gpr_names[(l >> OP_SH_RZ) & OP_MASK_RZ]);
1111
              break;
1112
 
1113
            case 'Z':
1114
              (*info->fprintf_func) (info->stream, "%s",
1115
                                     mips_fpr_names[(l >> OP_SH_FZ) & OP_MASK_FZ]);
1116
              break;
1117
 
1118
            default:
1119
              /* xgettext:c-format */
1120
              (*info->fprintf_func) (info->stream,
1121
                                     _("# internal error, undefined extension sequence (+%c)"),
1122
                                     *d);
1123
              return;
1124
            }
1125
          break;
1126
 
1127
        case '2':
1128
          (*info->fprintf_func) (info->stream, "0x%lx",
1129
                                 (l >> OP_SH_BP) & OP_MASK_BP);
1130
          break;
1131
 
1132
        case '3':
1133
          (*info->fprintf_func) (info->stream, "0x%lx",
1134
                                 (l >> OP_SH_SA3) & OP_MASK_SA3);
1135
          break;
1136
 
1137
        case '4':
1138
          (*info->fprintf_func) (info->stream, "0x%lx",
1139
                                 (l >> OP_SH_SA4) & OP_MASK_SA4);
1140
          break;
1141
 
1142
        case '5':
1143
          (*info->fprintf_func) (info->stream, "0x%lx",
1144
                                 (l >> OP_SH_IMM8) & OP_MASK_IMM8);
1145
          break;
1146
 
1147
        case '6':
1148
          (*info->fprintf_func) (info->stream, "0x%lx",
1149
                                 (l >> OP_SH_RS) & OP_MASK_RS);
1150
          break;
1151
 
1152
        case '7':
1153
          (*info->fprintf_func) (info->stream, "$ac%ld",
1154
                                 (l >> OP_SH_DSPACC) & OP_MASK_DSPACC);
1155
          break;
1156
 
1157
        case '8':
1158
          (*info->fprintf_func) (info->stream, "0x%lx",
1159
                                 (l >> OP_SH_WRDSP) & OP_MASK_WRDSP);
1160
          break;
1161
 
1162
        case '9':
1163
          (*info->fprintf_func) (info->stream, "$ac%ld",
1164
                                 (l >> OP_SH_DSPACC_S) & OP_MASK_DSPACC_S);
1165
          break;
1166
 
1167
        case '0': /* dsp 6-bit signed immediate in bit 20 */
1168
          delta = ((l >> OP_SH_DSPSFT) & OP_MASK_DSPSFT);
1169
          if (delta & 0x20) /* test sign bit */
1170
            delta |= ~OP_MASK_DSPSFT;
1171
          (*info->fprintf_func) (info->stream, "%d", delta);
1172
          break;
1173
 
1174
        case ':': /* dsp 7-bit signed immediate in bit 19 */
1175
          delta = ((l >> OP_SH_DSPSFT_7) & OP_MASK_DSPSFT_7);
1176
          if (delta & 0x40) /* test sign bit */
1177
            delta |= ~OP_MASK_DSPSFT_7;
1178
          (*info->fprintf_func) (info->stream, "%d", delta);
1179
          break;
1180
 
1181 158 khays
        case '~':
1182
          delta = (l >> OP_SH_OFFSET12) & OP_MASK_OFFSET12;
1183
          if (delta & 0x800)
1184
            delta |= ~0x7ff;
1185
          (*info->fprintf_func) (info->stream, "%d", delta);
1186
          break;
1187
 
1188
        case '\\':
1189
          (*info->fprintf_func) (info->stream, "0x%lx",
1190
                                 (l >> OP_SH_3BITPOS) & OP_MASK_3BITPOS);
1191
          break;
1192
 
1193 18 khays
        case '\'':
1194
          (*info->fprintf_func) (info->stream, "0x%lx",
1195
                                 (l >> OP_SH_RDDSP) & OP_MASK_RDDSP);
1196
          break;
1197
 
1198
        case '@': /* dsp 10-bit signed immediate in bit 16 */
1199
          delta = ((l >> OP_SH_IMM10) & OP_MASK_IMM10);
1200
          if (delta & 0x200) /* test sign bit */
1201
            delta |= ~OP_MASK_IMM10;
1202
          (*info->fprintf_func) (info->stream, "%d", delta);
1203
          break;
1204
 
1205
        case '!':
1206
          (*info->fprintf_func) (info->stream, "%ld",
1207
                                 (l >> OP_SH_MT_U) & OP_MASK_MT_U);
1208
          break;
1209
 
1210
        case '$':
1211
          (*info->fprintf_func) (info->stream, "%ld",
1212
                                 (l >> OP_SH_MT_H) & OP_MASK_MT_H);
1213
          break;
1214
 
1215
        case '*':
1216
          (*info->fprintf_func) (info->stream, "$ac%ld",
1217
                                 (l >> OP_SH_MTACC_T) & OP_MASK_MTACC_T);
1218
          break;
1219
 
1220
        case '&':
1221
          (*info->fprintf_func) (info->stream, "$ac%ld",
1222
                                 (l >> OP_SH_MTACC_D) & OP_MASK_MTACC_D);
1223
          break;
1224
 
1225
        case 'g':
1226
          /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2.  */
1227
          (*info->fprintf_func) (info->stream, "$%ld",
1228
                                 (l >> OP_SH_RD) & OP_MASK_RD);
1229
          break;
1230
 
1231
        case 's':
1232
        case 'b':
1233
        case 'r':
1234
        case 'v':
1235
          (*info->fprintf_func) (info->stream, "%s",
1236
                                 mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]);
1237
          break;
1238
 
1239
        case 't':
1240
        case 'w':
1241
          (*info->fprintf_func) (info->stream, "%s",
1242
                                 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
1243
          break;
1244
 
1245
        case 'i':
1246
        case 'u':
1247
          (*info->fprintf_func) (info->stream, "0x%lx",
1248
                                 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
1249
          break;
1250
 
1251
        case 'j': /* Same as i, but sign-extended.  */
1252
        case 'o':
1253
          delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
1254
          if (delta & 0x8000)
1255
            delta |= ~0xffff;
1256
          (*info->fprintf_func) (info->stream, "%d",
1257
                                 delta);
1258
          break;
1259
 
1260
        case 'h':
1261
          (*info->fprintf_func) (info->stream, "0x%x",
1262
                                 (unsigned int) ((l >> OP_SH_PREFX)
1263
                                                 & OP_MASK_PREFX));
1264
          break;
1265
 
1266
        case 'k':
1267
          (*info->fprintf_func) (info->stream, "0x%x",
1268
                                 (unsigned int) ((l >> OP_SH_CACHE)
1269
                                                 & OP_MASK_CACHE));
1270
          break;
1271
 
1272
        case 'a':
1273
          info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
1274
                          | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2));
1275
          /* For gdb disassembler, force odd address on jalx.  */
1276
          if (info->flavour == bfd_target_unknown_flavour
1277
              && strcmp (opp->name, "jalx") == 0)
1278
            info->target |= 1;
1279
          (*info->print_address_func) (info->target, info);
1280
          break;
1281
 
1282
        case 'p':
1283
          /* Sign extend the displacement.  */
1284
          delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
1285
          if (delta & 0x8000)
1286
            delta |= ~0xffff;
1287
          info->target = (delta << 2) + pc + INSNLEN;
1288
          (*info->print_address_func) (info->target, info);
1289
          break;
1290
 
1291
        case 'd':
1292
          (*info->fprintf_func) (info->stream, "%s",
1293
                                 mips_gpr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
1294
          break;
1295
 
1296
        case 'U':
1297
          {
1298
            /* First check for both rd and rt being equal.  */
1299
            unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD;
1300
            if (reg == ((l >> OP_SH_RT) & OP_MASK_RT))
1301
              (*info->fprintf_func) (info->stream, "%s",
1302
                                     mips_gpr_names[reg]);
1303
            else
1304
              {
1305
                /* If one is zero use the other.  */
1306
                if (reg == 0)
1307
                  (*info->fprintf_func) (info->stream, "%s",
1308
                                         mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
1309
                else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0)
1310
                  (*info->fprintf_func) (info->stream, "%s",
1311
                                         mips_gpr_names[reg]);
1312
                else /* Bogus, result depends on processor.  */
1313
                  (*info->fprintf_func) (info->stream, "%s or %s",
1314
                                         mips_gpr_names[reg],
1315
                                         mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
1316
              }
1317
          }
1318
          break;
1319
 
1320
        case 'z':
1321
          (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
1322
          break;
1323
 
1324
        case '<':
1325
        case '1':
1326
          (*info->fprintf_func) (info->stream, "0x%lx",
1327
                                 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
1328
          break;
1329
 
1330
        case 'c':
1331
          (*info->fprintf_func) (info->stream, "0x%lx",
1332
                                 (l >> OP_SH_CODE) & OP_MASK_CODE);
1333
          break;
1334
 
1335
        case 'q':
1336
          (*info->fprintf_func) (info->stream, "0x%lx",
1337
                                 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
1338
          break;
1339
 
1340
        case 'C':
1341
          (*info->fprintf_func) (info->stream, "0x%lx",
1342
                                 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
1343
          break;
1344
 
1345
        case 'B':
1346
          (*info->fprintf_func) (info->stream, "0x%lx",
1347
 
1348
                                 (l >> OP_SH_CODE20) & OP_MASK_CODE20);
1349
          break;
1350
 
1351
        case 'J':
1352
          (*info->fprintf_func) (info->stream, "0x%lx",
1353
                                 (l >> OP_SH_CODE19) & OP_MASK_CODE19);
1354
          break;
1355
 
1356
        case 'S':
1357
        case 'V':
1358
          (*info->fprintf_func) (info->stream, "%s",
1359
                                 mips_fpr_names[(l >> OP_SH_FS) & OP_MASK_FS]);
1360
          break;
1361
 
1362
        case 'T':
1363
        case 'W':
1364
          (*info->fprintf_func) (info->stream, "%s",
1365
                                 mips_fpr_names[(l >> OP_SH_FT) & OP_MASK_FT]);
1366
          break;
1367
 
1368
        case 'D':
1369
          (*info->fprintf_func) (info->stream, "%s",
1370
                                 mips_fpr_names[(l >> OP_SH_FD) & OP_MASK_FD]);
1371
          break;
1372
 
1373
        case 'R':
1374
          (*info->fprintf_func) (info->stream, "%s",
1375
                                 mips_fpr_names[(l >> OP_SH_FR) & OP_MASK_FR]);
1376
          break;
1377
 
1378
        case 'E':
1379
          /* Coprocessor register for lwcN instructions, et al.
1380
 
1381
             Note that there is no load/store cp0 instructions, and
1382
             that FPU (cp1) instructions disassemble this field using
1383
             'T' format.  Therefore, until we gain understanding of
1384
             cp2 register names, we can simply print the register
1385
             numbers.  */
1386
          (*info->fprintf_func) (info->stream, "$%ld",
1387
                                 (l >> OP_SH_RT) & OP_MASK_RT);
1388
          break;
1389
 
1390
        case 'G':
1391
          /* Coprocessor register for mtcN instructions, et al.  Note
1392
             that FPU (cp1) instructions disassemble this field using
1393
             'S' format.  Therefore, we only need to worry about cp0,
1394
             cp2, and cp3.  */
1395
          op = (l >> OP_SH_OP) & OP_MASK_OP;
1396
          if (op == OP_OP_COP0)
1397
            (*info->fprintf_func) (info->stream, "%s",
1398
                                   mips_cp0_names[(l >> OP_SH_RD) & OP_MASK_RD]);
1399
          else
1400
            (*info->fprintf_func) (info->stream, "$%ld",
1401
                                   (l >> OP_SH_RD) & OP_MASK_RD);
1402
          break;
1403
 
1404
        case 'K':
1405
          (*info->fprintf_func) (info->stream, "%s",
1406
                                 mips_hwr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
1407
          break;
1408
 
1409
        case 'N':
1410
          (*info->fprintf_func) (info->stream,
1411
                                 ((opp->pinfo & (FP_D | FP_S)) != 0
1412
                                  ? "$fcc%ld" : "$cc%ld"),
1413
                                 (l >> OP_SH_BCC) & OP_MASK_BCC);
1414
          break;
1415
 
1416
        case 'M':
1417
          (*info->fprintf_func) (info->stream, "$fcc%ld",
1418
                                 (l >> OP_SH_CCC) & OP_MASK_CCC);
1419
          break;
1420
 
1421
        case 'P':
1422
          (*info->fprintf_func) (info->stream, "%ld",
1423
                                 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
1424
          break;
1425
 
1426
        case 'e':
1427
          (*info->fprintf_func) (info->stream, "%ld",
1428
                                 (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE);
1429
          break;
1430
 
1431
        case '%':
1432
          (*info->fprintf_func) (info->stream, "%ld",
1433
                                 (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN);
1434
          break;
1435
 
1436
        case 'H':
1437
          (*info->fprintf_func) (info->stream, "%ld",
1438
                                 (l >> OP_SH_SEL) & OP_MASK_SEL);
1439
          break;
1440
 
1441
        case 'O':
1442
          (*info->fprintf_func) (info->stream, "%ld",
1443
                                 (l >> OP_SH_ALN) & OP_MASK_ALN);
1444
          break;
1445
 
1446
        case 'Q':
1447
          {
1448
            unsigned int vsel = (l >> OP_SH_VSEL) & OP_MASK_VSEL;
1449
 
1450
            if ((vsel & 0x10) == 0)
1451
              {
1452
                int fmt;
1453
 
1454
                vsel &= 0x0f;
1455
                for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1456
                  if ((vsel & 1) == 0)
1457
                    break;
1458
                (*info->fprintf_func) (info->stream, "$v%ld[%d]",
1459
                                       (l >> OP_SH_FT) & OP_MASK_FT,
1460
                                       vsel >> 1);
1461
              }
1462
            else if ((vsel & 0x08) == 0)
1463
              {
1464
                (*info->fprintf_func) (info->stream, "$v%ld",
1465
                                       (l >> OP_SH_FT) & OP_MASK_FT);
1466
              }
1467
            else
1468
              {
1469
                (*info->fprintf_func) (info->stream, "0x%lx",
1470
                                       (l >> OP_SH_FT) & OP_MASK_FT);
1471
              }
1472
          }
1473
          break;
1474
 
1475
        case 'X':
1476
          (*info->fprintf_func) (info->stream, "$v%ld",
1477
                                 (l >> OP_SH_FD) & OP_MASK_FD);
1478
          break;
1479
 
1480
        case 'Y':
1481
          (*info->fprintf_func) (info->stream, "$v%ld",
1482
                                 (l >> OP_SH_FS) & OP_MASK_FS);
1483
          break;
1484
 
1485
        case 'Z':
1486
          (*info->fprintf_func) (info->stream, "$v%ld",
1487
                                 (l >> OP_SH_FT) & OP_MASK_FT);
1488
          break;
1489
 
1490
        default:
1491
          /* xgettext:c-format */
1492
          (*info->fprintf_func) (info->stream,
1493
                                 _("# internal error, undefined modifier (%c)"),
1494
                                 *d);
1495
          return;
1496
        }
1497
    }
1498
}
1499
 
1500
/* Print the mips instruction at address MEMADDR in debugged memory,
1501
   on using INFO.  Returns length of the instruction, in bytes, which is
1502
   always INSNLEN.  BIGENDIAN must be 1 if this is big-endian code, 0 if
1503
   this is little-endian code.  */
1504
 
1505
static int
1506
print_insn_mips (bfd_vma memaddr,
1507
                 unsigned long int word,
1508
                 struct disassemble_info *info)
1509
{
1510
  const struct mips_opcode *op;
1511
  static bfd_boolean init = 0;
1512
  static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1513
 
1514
  /* Build a hash table to shorten the search time.  */
1515
  if (! init)
1516
    {
1517
      unsigned int i;
1518
 
1519
      for (i = 0; i <= OP_MASK_OP; i++)
1520
        {
1521
          for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1522
            {
1523
              if (op->pinfo == INSN_MACRO
1524
                  || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
1525
                continue;
1526
              if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
1527
                {
1528
                  mips_hash[i] = op;
1529
                  break;
1530
                }
1531
            }
1532
        }
1533
 
1534
      init = 1;
1535
    }
1536
 
1537
  info->bytes_per_chunk = INSNLEN;
1538
  info->display_endian = info->endian;
1539
  info->insn_info_valid = 1;
1540
  info->branch_delay_insns = 0;
1541
  info->data_size = 0;
1542
  info->insn_type = dis_nonbranch;
1543
  info->target = 0;
1544
  info->target2 = 0;
1545
 
1546
  op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
1547
  if (op != NULL)
1548
    {
1549
      for (; op < &mips_opcodes[NUMOPCODES]; op++)
1550
        {
1551
          if (op->pinfo != INSN_MACRO
1552
              && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1553
              && (word & op->mask) == op->match)
1554
            {
1555
              const char *d;
1556
 
1557
              /* We always allow to disassemble the jalx instruction.  */
1558
              if (! OPCODE_IS_MEMBER (op, mips_isa, mips_processor)
1559
                  && strcmp (op->name, "jalx"))
1560
                continue;
1561
 
1562
              /* Figure out instruction type and branch delay information.  */
1563
              if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1564
                {
1565
                  if ((op->pinfo & (INSN_WRITE_GPR_31
1566
                                    | INSN_WRITE_GPR_D)) != 0)
1567
                    info->insn_type = dis_jsr;
1568
                  else
1569
                    info->insn_type = dis_branch;
1570
                  info->branch_delay_insns = 1;
1571
                }
1572
              else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1573
                                     | INSN_COND_BRANCH_LIKELY)) != 0)
1574
                {
1575
                  if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1576
                    info->insn_type = dis_condjsr;
1577
                  else
1578
                    info->insn_type = dis_condbranch;
1579
                  info->branch_delay_insns = 1;
1580
                }
1581
              else if ((op->pinfo & (INSN_STORE_MEMORY
1582
                                     | INSN_LOAD_MEMORY_DELAY)) != 0)
1583
                info->insn_type = dis_dref;
1584
 
1585
              (*info->fprintf_func) (info->stream, "%s", op->name);
1586
 
1587
              d = op->args;
1588
              if (d != NULL && *d != '\0')
1589
                {
1590
                  (*info->fprintf_func) (info->stream, "\t");
1591
                  print_insn_args (d, word, memaddr, info, op);
1592
                }
1593
 
1594
              return INSNLEN;
1595
            }
1596
        }
1597
    }
1598
 
1599
  /* Handle undefined instructions.  */
1600
  info->insn_type = dis_noninsn;
1601
  (*info->fprintf_func) (info->stream, "0x%lx", word);
1602
  return INSNLEN;
1603
}
1604
 
1605
/* Disassemble an operand for a mips16 instruction.  */
1606
 
1607
static void
1608
print_mips16_insn_arg (char type,
1609
                       const struct mips_opcode *op,
1610
                       int l,
1611
                       bfd_boolean use_extend,
1612
                       int extend,
1613
                       bfd_vma memaddr,
1614
                       struct disassemble_info *info)
1615
{
1616
  switch (type)
1617
    {
1618
    case ',':
1619
    case '(':
1620
    case ')':
1621
      (*info->fprintf_func) (info->stream, "%c", type);
1622
      break;
1623
 
1624
    case 'y':
1625
    case 'w':
1626
      (*info->fprintf_func) (info->stream, "%s",
1627
                             mips16_reg_names(((l >> MIPS16OP_SH_RY)
1628
                                               & MIPS16OP_MASK_RY)));
1629
      break;
1630
 
1631
    case 'x':
1632
    case 'v':
1633
      (*info->fprintf_func) (info->stream, "%s",
1634
                             mips16_reg_names(((l >> MIPS16OP_SH_RX)
1635
                                               & MIPS16OP_MASK_RX)));
1636
      break;
1637
 
1638
    case 'z':
1639
      (*info->fprintf_func) (info->stream, "%s",
1640
                             mips16_reg_names(((l >> MIPS16OP_SH_RZ)
1641
                                               & MIPS16OP_MASK_RZ)));
1642
      break;
1643
 
1644
    case 'Z':
1645
      (*info->fprintf_func) (info->stream, "%s",
1646
                             mips16_reg_names(((l >> MIPS16OP_SH_MOVE32Z)
1647
                                               & MIPS16OP_MASK_MOVE32Z)));
1648
      break;
1649
 
1650
    case '0':
1651
      (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
1652
      break;
1653
 
1654
    case 'S':
1655
      (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[29]);
1656
      break;
1657
 
1658
    case 'P':
1659
      (*info->fprintf_func) (info->stream, "$pc");
1660
      break;
1661
 
1662
    case 'R':
1663
      (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[31]);
1664
      break;
1665
 
1666
    case 'X':
1667
      (*info->fprintf_func) (info->stream, "%s",
1668
                             mips_gpr_names[((l >> MIPS16OP_SH_REGR32)
1669
                                            & MIPS16OP_MASK_REGR32)]);
1670
      break;
1671
 
1672
    case 'Y':
1673
      (*info->fprintf_func) (info->stream, "%s",
1674
                             mips_gpr_names[MIPS16OP_EXTRACT_REG32R (l)]);
1675
      break;
1676
 
1677
    case '<':
1678
    case '>':
1679
    case '[':
1680
    case ']':
1681
    case '4':
1682
    case '5':
1683
    case 'H':
1684
    case 'W':
1685
    case 'D':
1686
    case 'j':
1687
    case '6':
1688
    case '8':
1689
    case 'V':
1690
    case 'C':
1691
    case 'U':
1692
    case 'k':
1693
    case 'K':
1694
    case 'p':
1695
    case 'q':
1696
    case 'A':
1697
    case 'B':
1698
    case 'E':
1699
      {
1700
        int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
1701
 
1702
        shift = 0;
1703
        signedp = 0;
1704
        extbits = 16;
1705
        pcrel = 0;
1706
        extu = 0;
1707
        branch = 0;
1708
        switch (type)
1709
          {
1710
          case '<':
1711
            nbits = 3;
1712
            immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
1713
            extbits = 5;
1714
            extu = 1;
1715
            break;
1716
          case '>':
1717
            nbits = 3;
1718
            immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
1719
            extbits = 5;
1720
            extu = 1;
1721
            break;
1722
          case '[':
1723
            nbits = 3;
1724
            immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
1725
            extbits = 6;
1726
            extu = 1;
1727
            break;
1728
          case ']':
1729
            nbits = 3;
1730
            immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
1731
            extbits = 6;
1732
            extu = 1;
1733
            break;
1734
          case '4':
1735
            nbits = 4;
1736
            immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
1737
            signedp = 1;
1738
            extbits = 15;
1739
            break;
1740
          case '5':
1741
            nbits = 5;
1742
            immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1743
            info->insn_type = dis_dref;
1744
            info->data_size = 1;
1745
            break;
1746
          case 'H':
1747
            nbits = 5;
1748
            shift = 1;
1749
            immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1750
            info->insn_type = dis_dref;
1751
            info->data_size = 2;
1752
            break;
1753
          case 'W':
1754
            nbits = 5;
1755
            shift = 2;
1756
            immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1757
            if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
1758
                && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
1759
              {
1760
                info->insn_type = dis_dref;
1761
                info->data_size = 4;
1762
              }
1763
            break;
1764
          case 'D':
1765
            nbits = 5;
1766
            shift = 3;
1767
            immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1768
            info->insn_type = dis_dref;
1769
            info->data_size = 8;
1770
            break;
1771
          case 'j':
1772
            nbits = 5;
1773
            immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1774
            signedp = 1;
1775
            break;
1776
          case '6':
1777
            nbits = 6;
1778
            immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1779
            break;
1780
          case '8':
1781
            nbits = 8;
1782
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1783
            break;
1784
          case 'V':
1785
            nbits = 8;
1786
            shift = 2;
1787
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1788
            /* FIXME: This might be lw, or it might be addiu to $sp or
1789
               $pc.  We assume it's load.  */
1790
            info->insn_type = dis_dref;
1791
            info->data_size = 4;
1792
            break;
1793
          case 'C':
1794
            nbits = 8;
1795
            shift = 3;
1796
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1797
            info->insn_type = dis_dref;
1798
            info->data_size = 8;
1799
            break;
1800
          case 'U':
1801
            nbits = 8;
1802
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1803
            extu = 1;
1804
            break;
1805
          case 'k':
1806
            nbits = 8;
1807
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1808
            signedp = 1;
1809
            break;
1810
          case 'K':
1811
            nbits = 8;
1812
            shift = 3;
1813
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1814
            signedp = 1;
1815
            break;
1816
          case 'p':
1817
            nbits = 8;
1818
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1819
            signedp = 1;
1820
            pcrel = 1;
1821
            branch = 1;
1822
            break;
1823
          case 'q':
1824
            nbits = 11;
1825
            immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
1826
            signedp = 1;
1827
            pcrel = 1;
1828
            branch = 1;
1829
            break;
1830
          case 'A':
1831
            nbits = 8;
1832
            shift = 2;
1833
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1834
            pcrel = 1;
1835
            /* FIXME: This can be lw or la.  We assume it is lw.  */
1836
            info->insn_type = dis_dref;
1837
            info->data_size = 4;
1838
            break;
1839
          case 'B':
1840
            nbits = 5;
1841
            shift = 3;
1842
            immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1843
            pcrel = 1;
1844
            info->insn_type = dis_dref;
1845
            info->data_size = 8;
1846
            break;
1847
          case 'E':
1848
            nbits = 5;
1849
            shift = 2;
1850
            immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1851
            pcrel = 1;
1852
            break;
1853
          default:
1854
            abort ();
1855
          }
1856
 
1857
        if (! use_extend)
1858
          {
1859
            if (signedp && immed >= (1 << (nbits - 1)))
1860
              immed -= 1 << nbits;
1861
            immed <<= shift;
1862
            if ((type == '<' || type == '>' || type == '[' || type == ']')
1863
                && immed == 0)
1864
              immed = 8;
1865
          }
1866
        else
1867
          {
1868
            if (extbits == 16)
1869
              immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1870
            else if (extbits == 15)
1871
              immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1872
            else
1873
              immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1874
            immed &= (1 << extbits) - 1;
1875
            if (! extu && immed >= (1 << (extbits - 1)))
1876
              immed -= 1 << extbits;
1877
          }
1878
 
1879
        if (! pcrel)
1880
          (*info->fprintf_func) (info->stream, "%d", immed);
1881
        else
1882
          {
1883
            bfd_vma baseaddr;
1884
 
1885
            if (branch)
1886
              {
1887
                immed *= 2;
1888
                baseaddr = memaddr + 2;
1889
              }
1890
            else if (use_extend)
1891
              baseaddr = memaddr - 2;
1892
            else
1893
              {
1894
                int status;
1895
                bfd_byte buffer[2];
1896
 
1897
                baseaddr = memaddr;
1898
 
1899
                /* If this instruction is in the delay slot of a jr
1900
                   instruction, the base address is the address of the
1901
                   jr instruction.  If it is in the delay slot of jalr
1902
                   instruction, the base address is the address of the
1903
                   jalr instruction.  This test is unreliable: we have
1904
                   no way of knowing whether the previous word is
1905
                   instruction or data.  */
1906
                status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1907
                                                    info);
1908
                if (status == 0
1909
                    && (((info->endian == BFD_ENDIAN_BIG
1910
                          ? bfd_getb16 (buffer)
1911
                          : bfd_getl16 (buffer))
1912
                         & 0xf800) == 0x1800))
1913
                  baseaddr = memaddr - 4;
1914
                else
1915
                  {
1916
                    status = (*info->read_memory_func) (memaddr - 2, buffer,
1917
                                                        2, info);
1918
                    if (status == 0
1919
                        && (((info->endian == BFD_ENDIAN_BIG
1920
                              ? bfd_getb16 (buffer)
1921
                              : bfd_getl16 (buffer))
1922
                             & 0xf81f) == 0xe800))
1923
                      baseaddr = memaddr - 2;
1924
                  }
1925
              }
1926
            info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
1927
            if (pcrel && branch
1928
                && info->flavour == bfd_target_unknown_flavour)
1929
              /* For gdb disassembler, maintain odd address.  */
1930
              info->target |= 1;
1931
            (*info->print_address_func) (info->target, info);
1932
          }
1933
      }
1934
      break;
1935
 
1936
    case 'a':
1937
      {
1938
        int jalx = l & 0x400;
1939
 
1940
        if (! use_extend)
1941
          extend = 0;
1942
        l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1943
        if (!jalx && info->flavour == bfd_target_unknown_flavour)
1944
          /* For gdb disassembler, maintain odd address.  */
1945
          l |= 1;
1946
      }
1947
      info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
1948
      (*info->print_address_func) (info->target, info);
1949
      break;
1950
 
1951
    case 'l':
1952
    case 'L':
1953
      {
1954
        int need_comma, amask, smask;
1955
 
1956
        need_comma = 0;
1957
 
1958
        l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1959
 
1960
        amask = (l >> 3) & 7;
1961
 
1962
        if (amask > 0 && amask < 5)
1963
          {
1964
            (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]);
1965
            if (amask > 1)
1966
              (*info->fprintf_func) (info->stream, "-%s",
1967
                                     mips_gpr_names[amask + 3]);
1968
            need_comma = 1;
1969
          }
1970
 
1971
        smask = (l >> 1) & 3;
1972
        if (smask == 3)
1973
          {
1974
            (*info->fprintf_func) (info->stream, "%s??",
1975
                                   need_comma ? "," : "");
1976
            need_comma = 1;
1977
          }
1978
        else if (smask > 0)
1979
          {
1980
            (*info->fprintf_func) (info->stream, "%s%s",
1981
                                   need_comma ? "," : "",
1982
                                   mips_gpr_names[16]);
1983
            if (smask > 1)
1984
              (*info->fprintf_func) (info->stream, "-%s",
1985
                                     mips_gpr_names[smask + 15]);
1986
            need_comma = 1;
1987
          }
1988
 
1989
        if (l & 1)
1990
          {
1991
            (*info->fprintf_func) (info->stream, "%s%s",
1992
                                   need_comma ? "," : "",
1993
                                   mips_gpr_names[31]);
1994
            need_comma = 1;
1995
          }
1996
 
1997
        if (amask == 5 || amask == 6)
1998
          {
1999
            (*info->fprintf_func) (info->stream, "%s$f0",
2000
                                   need_comma ? "," : "");
2001
            if (amask == 6)
2002
              (*info->fprintf_func) (info->stream, "-$f1");
2003
          }
2004
      }
2005
      break;
2006
 
2007
    case 'm':
2008
    case 'M':
2009
      /* MIPS16e save/restore.  */
2010
      {
2011
      int need_comma = 0;
2012
      int amask, args, statics;
2013
      int nsreg, smask;
2014
      int framesz;
2015
      int i, j;
2016
 
2017
      l = l & 0x7f;
2018
      if (use_extend)
2019
        l |= extend << 16;
2020
 
2021
      amask = (l >> 16) & 0xf;
2022
      if (amask == MIPS16_ALL_ARGS)
2023
        {
2024
          args = 4;
2025
          statics = 0;
2026
        }
2027
      else if (amask == MIPS16_ALL_STATICS)
2028
        {
2029
          args = 0;
2030
          statics = 4;
2031
        }
2032
      else
2033
        {
2034
          args = amask >> 2;
2035
          statics = amask & 3;
2036
        }
2037
 
2038
      if (args > 0) {
2039
          (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]);
2040
          if (args > 1)
2041
            (*info->fprintf_func) (info->stream, "-%s",
2042
                                   mips_gpr_names[4 + args - 1]);
2043
          need_comma = 1;
2044
      }
2045
 
2046
      framesz = (((l >> 16) & 0xf0) | (l & 0x0f)) * 8;
2047
      if (framesz == 0 && !use_extend)
2048
        framesz = 128;
2049
 
2050
      (*info->fprintf_func) (info->stream, "%s%d",
2051
                             need_comma ? "," : "",
2052
                             framesz);
2053
 
2054
      if (l & 0x40)                   /* $ra */
2055
        (*info->fprintf_func) (info->stream, ",%s", mips_gpr_names[31]);
2056
 
2057
      nsreg = (l >> 24) & 0x7;
2058
      smask = 0;
2059
      if (l & 0x20)                   /* $s0 */
2060
        smask |= 1 << 0;
2061
      if (l & 0x10)                   /* $s1 */
2062
        smask |= 1 << 1;
2063
      if (nsreg > 0)                  /* $s2-$s8 */
2064
        smask |= ((1 << nsreg) - 1) << 2;
2065
 
2066
      /* Find first set static reg bit.  */
2067
      for (i = 0; i < 9; i++)
2068
        {
2069
          if (smask & (1 << i))
2070
            {
2071
              (*info->fprintf_func) (info->stream, ",%s",
2072
                                     mips_gpr_names[i == 8 ? 30 : (16 + i)]);
2073
              /* Skip over string of set bits.  */
2074
              for (j = i; smask & (2 << j); j++)
2075
                continue;
2076
              if (j > i)
2077
                (*info->fprintf_func) (info->stream, "-%s",
2078
                                       mips_gpr_names[j == 8 ? 30 : (16 + j)]);
2079
              i = j + 1;
2080
            }
2081
        }
2082
 
2083
      /* Statics $ax - $a3.  */
2084
      if (statics == 1)
2085
        (*info->fprintf_func) (info->stream, ",%s", mips_gpr_names[7]);
2086
      else if (statics > 0)
2087
        (*info->fprintf_func) (info->stream, ",%s-%s",
2088
                               mips_gpr_names[7 - statics + 1],
2089
                               mips_gpr_names[7]);
2090
      }
2091
      break;
2092
 
2093
    default:
2094
      /* xgettext:c-format */
2095
      (*info->fprintf_func)
2096
        (info->stream,
2097
         _("# internal disassembler error, unrecognised modifier (%c)"),
2098
         type);
2099
      abort ();
2100
    }
2101
}
2102
 
2103
/* Disassemble mips16 instructions.  */
2104
 
2105
static int
2106
print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
2107
{
2108
  int status;
2109
  bfd_byte buffer[2];
2110
  int length;
2111
  int insn;
2112
  bfd_boolean use_extend;
2113
  int extend = 0;
2114
  const struct mips_opcode *op, *opend;
2115
 
2116
  info->bytes_per_chunk = 2;
2117
  info->display_endian = info->endian;
2118
  info->insn_info_valid = 1;
2119
  info->branch_delay_insns = 0;
2120
  info->data_size = 0;
2121
  info->insn_type = dis_nonbranch;
2122
  info->target = 0;
2123
  info->target2 = 0;
2124
 
2125
  status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2126
  if (status != 0)
2127
    {
2128
      (*info->memory_error_func) (status, memaddr, info);
2129
      return -1;
2130
    }
2131
 
2132
  length = 2;
2133
 
2134
  if (info->endian == BFD_ENDIAN_BIG)
2135
    insn = bfd_getb16 (buffer);
2136
  else
2137
    insn = bfd_getl16 (buffer);
2138
 
2139
  /* Handle the extend opcode specially.  */
2140
  use_extend = FALSE;
2141
  if ((insn & 0xf800) == 0xf000)
2142
    {
2143
      use_extend = TRUE;
2144
      extend = insn & 0x7ff;
2145
 
2146
      memaddr += 2;
2147
 
2148
      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2149
      if (status != 0)
2150
        {
2151
          (*info->fprintf_func) (info->stream, "extend 0x%x",
2152
                                 (unsigned int) extend);
2153
          (*info->memory_error_func) (status, memaddr, info);
2154
          return -1;
2155
        }
2156
 
2157
      if (info->endian == BFD_ENDIAN_BIG)
2158
        insn = bfd_getb16 (buffer);
2159
      else
2160
        insn = bfd_getl16 (buffer);
2161
 
2162
      /* Check for an extend opcode followed by an extend opcode.  */
2163
      if ((insn & 0xf800) == 0xf000)
2164
        {
2165
          (*info->fprintf_func) (info->stream, "extend 0x%x",
2166
                                 (unsigned int) extend);
2167
          info->insn_type = dis_noninsn;
2168
          return length;
2169
        }
2170
 
2171
      length += 2;
2172
    }
2173
 
2174
  /* FIXME: Should probably use a hash table on the major opcode here.  */
2175
 
2176
  opend = mips16_opcodes + bfd_mips16_num_opcodes;
2177
  for (op = mips16_opcodes; op < opend; op++)
2178
    {
2179
      if (op->pinfo != INSN_MACRO
2180
          && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2181
          && (insn & op->mask) == op->match)
2182
        {
2183
          const char *s;
2184
 
2185
          if (strchr (op->args, 'a') != NULL)
2186
            {
2187
              if (use_extend)
2188
                {
2189
                  (*info->fprintf_func) (info->stream, "extend 0x%x",
2190
                                         (unsigned int) extend);
2191
                  info->insn_type = dis_noninsn;
2192
                  return length - 2;
2193
                }
2194
 
2195
              use_extend = FALSE;
2196
 
2197
              memaddr += 2;
2198
 
2199
              status = (*info->read_memory_func) (memaddr, buffer, 2,
2200
                                                  info);
2201
              if (status == 0)
2202
                {
2203
                  use_extend = TRUE;
2204
                  if (info->endian == BFD_ENDIAN_BIG)
2205
                    extend = bfd_getb16 (buffer);
2206
                  else
2207
                    extend = bfd_getl16 (buffer);
2208
                  length += 2;
2209
                }
2210
            }
2211
 
2212
          (*info->fprintf_func) (info->stream, "%s", op->name);
2213
          if (op->args[0] != '\0')
2214
            (*info->fprintf_func) (info->stream, "\t");
2215
 
2216
          for (s = op->args; *s != '\0'; s++)
2217
            {
2218
              if (*s == ','
2219
                  && s[1] == 'w'
2220
                  && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
2221
                      == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
2222
                {
2223
                  /* Skip the register and the comma.  */
2224
                  ++s;
2225
                  continue;
2226
                }
2227
              if (*s == ','
2228
                  && s[1] == 'v'
2229
                  && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
2230
                      == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
2231
                {
2232
                  /* Skip the register and the comma.  */
2233
                  ++s;
2234
                  continue;
2235
                }
2236
              print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
2237
                                     info);
2238
            }
2239
 
2240
          /* Figure out branch instruction type and delay slot information.  */
2241
          if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2242
            info->branch_delay_insns = 1;
2243
          if ((op->pinfo & (INSN_UNCOND_BRANCH_DELAY
2244
                            | MIPS16_INSN_UNCOND_BRANCH)) != 0)
2245
            {
2246
              if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2247
                info->insn_type = dis_jsr;
2248
              else
2249
                info->insn_type = dis_branch;
2250
            }
2251
          else if ((op->pinfo & MIPS16_INSN_COND_BRANCH) != 0)
2252
            info->insn_type = dis_condbranch;
2253
 
2254
          return length;
2255
        }
2256
    }
2257
 
2258
  if (use_extend)
2259
    (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
2260
  (*info->fprintf_func) (info->stream, "0x%x", insn);
2261
  info->insn_type = dis_noninsn;
2262
 
2263
  return length;
2264
}
2265
 
2266 158 khays
/* Disassemble microMIPS instructions.  */
2267
 
2268
static int
2269
print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2270
{
2271 166 khays
  const fprintf_ftype infprintf = info->fprintf_func;
2272 158 khays
  const struct mips_opcode *op, *opend;
2273
  unsigned int lsb, msbd, msb;
2274
  void *is = info->stream;
2275
  unsigned int regno;
2276
  bfd_byte buffer[2];
2277
  int lastregno = 0;
2278
  int higher;
2279
  int length;
2280
  int status;
2281
  int delta;
2282
  int immed;
2283
  int insn;
2284
 
2285
  lsb = 0;
2286
 
2287
  info->bytes_per_chunk = 2;
2288
  info->display_endian = info->endian;
2289
  info->insn_info_valid = 1;
2290
  info->branch_delay_insns = 0;
2291
  info->data_size = 0;
2292
  info->insn_type = dis_nonbranch;
2293
  info->target = 0;
2294
  info->target2 = 0;
2295
 
2296
  status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2297
  if (status != 0)
2298
    {
2299
      (*info->memory_error_func) (status, memaddr, info);
2300
      return -1;
2301
    }
2302
 
2303
  length = 2;
2304
 
2305
  if (info->endian == BFD_ENDIAN_BIG)
2306
    insn = bfd_getb16 (buffer);
2307
  else
2308
    insn = bfd_getl16 (buffer);
2309
 
2310
  if ((insn & 0xfc00) == 0x7c00)
2311
    {
2312
      /* This is a 48-bit microMIPS instruction.  */
2313
      higher = insn;
2314
 
2315
      status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2316
      if (status != 0)
2317
        {
2318 166 khays
          infprintf (is, "micromips 0x%x", higher);
2319 158 khays
          (*info->memory_error_func) (status, memaddr + 2, info);
2320
          return -1;
2321
        }
2322
      if (info->endian == BFD_ENDIAN_BIG)
2323
        insn = bfd_getb16 (buffer);
2324
      else
2325
        insn = bfd_getl16 (buffer);
2326
      higher = (higher << 16) | insn;
2327
 
2328
      status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
2329
      if (status != 0)
2330
        {
2331 166 khays
          infprintf (is, "micromips 0x%x", higher);
2332 158 khays
          (*info->memory_error_func) (status, memaddr + 4, info);
2333
          return -1;
2334
        }
2335
      if (info->endian == BFD_ENDIAN_BIG)
2336
        insn = bfd_getb16 (buffer);
2337
      else
2338
        insn = bfd_getl16 (buffer);
2339 166 khays
      infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
2340 158 khays
 
2341
      info->insn_type = dis_noninsn;
2342
      return 6;
2343
    }
2344
  else if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2345
    {
2346
      /* This is a 32-bit microMIPS instruction.  */
2347
      higher = insn;
2348
 
2349
      status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2350
      if (status != 0)
2351
        {
2352 166 khays
          infprintf (is, "micromips 0x%x", higher);
2353 158 khays
          (*info->memory_error_func) (status, memaddr + 2, info);
2354
          return -1;
2355
        }
2356
 
2357
      if (info->endian == BFD_ENDIAN_BIG)
2358
        insn = bfd_getb16 (buffer);
2359
      else
2360
        insn = bfd_getl16 (buffer);
2361
 
2362
      insn = insn | (higher << 16);
2363
 
2364
      length += 2;
2365
    }
2366
 
2367
  /* FIXME: Should probably use a hash table on the major opcode here.  */
2368
 
2369
#define GET_OP(insn, field) \
2370
  (((insn) >> MICROMIPSOP_SH_##field) & MICROMIPSOP_MASK_##field)
2371
  opend = micromips_opcodes + bfd_micromips_num_opcodes;
2372
  for (op = micromips_opcodes; op < opend; op++)
2373
    {
2374
      if (op->pinfo != INSN_MACRO
2375
          && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2376
          && (insn & op->mask) == op->match
2377
          && ((length == 2 && (op->mask & 0xffff0000) == 0)
2378
              || (length == 4 && (op->mask & 0xffff0000) != 0)))
2379
        {
2380
          const char *s;
2381
 
2382 166 khays
          infprintf (is, "%s", op->name);
2383 158 khays
          if (op->args[0] != '\0')
2384 166 khays
            infprintf (is, "\t");
2385 158 khays
 
2386
          for (s = op->args; *s != '\0'; s++)
2387
            {
2388
              switch (*s)
2389
                {
2390
                case ',':
2391
                case '(':
2392
                case ')':
2393 166 khays
                  infprintf (is, "%c", *s);
2394 158 khays
                  break;
2395
 
2396
                case '.':
2397
                  delta = GET_OP (insn, OFFSET10);
2398
                  if (delta & 0x200)
2399
                    delta |= ~0x3ff;
2400 166 khays
                  infprintf (is, "%d", delta);
2401 158 khays
                  break;
2402
 
2403
                case '1':
2404 166 khays
                  infprintf (is, "0x%lx", GET_OP (insn, STYPE));
2405 158 khays
                  break;
2406
 
2407
                case '<':
2408 166 khays
                  infprintf (is, "0x%lx", GET_OP (insn, SHAMT));
2409 158 khays
                  break;
2410
 
2411
                case '\\':
2412 166 khays
                  infprintf (is, "0x%lx", GET_OP (insn, 3BITPOS));
2413 158 khays
                  break;
2414
 
2415
                case '|':
2416 166 khays
                  infprintf (is, "0x%lx", GET_OP (insn, TRAP));
2417 158 khays
                  break;
2418
 
2419
                case '~':
2420
                  delta = GET_OP (insn, OFFSET12);
2421
                  if (delta & 0x800)
2422
                    delta |= ~0x7ff;
2423 166 khays
                  infprintf (is, "%d", delta);
2424 158 khays
                  break;
2425
 
2426
                case 'a':
2427
                  if (strcmp (op->name, "jalx") == 0)
2428
                    info->target = (((memaddr + 4) & ~(bfd_vma) 0x0fffffff)
2429
                                    | (GET_OP (insn, TARGET) << 2));
2430
                  else
2431
                    info->target = (((memaddr + 4) & ~(bfd_vma) 0x07ffffff)
2432
                                    | ((GET_OP (insn, TARGET)) << 1));
2433
                  /* For gdb disassembler, force odd address on jalx.  */
2434
                  if (info->flavour == bfd_target_unknown_flavour
2435
                      && strcmp (op->name, "jalx") == 0)
2436
                    info->target |= 1;
2437
                  (*info->print_address_func) (info->target, info);
2438
                  break;
2439
 
2440
                case 'b':
2441
                case 'r':
2442
                case 's':
2443
                case 'v':
2444 166 khays
                  infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS)]);
2445 158 khays
                  break;
2446
 
2447
                case 'c':
2448 166 khays
                  infprintf (is, "0x%lx", GET_OP (insn, CODE));
2449 158 khays
                  break;
2450
 
2451
                case 'd':
2452 166 khays
                  infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RD)]);
2453 158 khays
                  break;
2454
 
2455
                case 'h':
2456 166 khays
                  infprintf (is, "0x%lx", GET_OP (insn, PREFX));
2457 158 khays
                  break;
2458
 
2459
                case 'i':
2460
                case 'u':
2461 166 khays
                  infprintf (is, "0x%lx", GET_OP (insn, IMMEDIATE));
2462 158 khays
                  break;
2463
 
2464
                case 'j': /* Same as i, but sign-extended.  */
2465
                case 'o':
2466
                  delta = (GET_OP (insn, DELTA) ^ 0x8000) - 0x8000;
2467 166 khays
                  infprintf (is, "%d", delta);
2468 158 khays
                  break;
2469
 
2470
                case 'k':
2471 166 khays
                  infprintf (is, "0x%x", GET_OP (insn, CACHE));
2472 158 khays
                  break;
2473
 
2474
                case 'n':
2475
                  {
2476
                    int s_reg_encode;
2477
 
2478
                    immed = GET_OP (insn, RT);
2479
                    s_reg_encode = immed & 0xf;
2480
                    if (s_reg_encode != 0)
2481
                      {
2482
                        if (s_reg_encode == 1)
2483 166 khays
                          infprintf (is, "%s", mips_gpr_names[16]);
2484 158 khays
                        else if (s_reg_encode < 9)
2485 166 khays
                          infprintf (is, "%s-%s",
2486 158 khays
                                   mips_gpr_names[16],
2487
                                   mips_gpr_names[15 + s_reg_encode]);
2488
                        else if (s_reg_encode == 9)
2489 166 khays
                          infprintf (is, "%s-%s,%s",
2490 158 khays
                                   mips_gpr_names[16],
2491
                                   mips_gpr_names[23],
2492
                                   mips_gpr_names[30]);
2493
                        else
2494 166 khays
                          infprintf (is, "UNKNOWN");
2495 158 khays
                      }
2496
 
2497
                    if (immed & 0x10) /* For ra.  */
2498
                      {
2499
                        if (s_reg_encode == 0)
2500 166 khays
                          infprintf (is, "%s", mips_gpr_names[31]);
2501 158 khays
                        else
2502 166 khays
                          infprintf (is, ",%s", mips_gpr_names[31]);
2503 158 khays
                      }
2504
                    break;
2505
                  }
2506
 
2507
                case 'p':
2508
                  /* Sign-extend the displacement.  */
2509
                  delta = (GET_OP (insn, DELTA) ^ 0x8000) - 0x8000;
2510
                  info->target = (delta << 1) + memaddr + length;
2511
                  (*info->print_address_func) (info->target, info);
2512
                  break;
2513
 
2514
                case 'q':
2515 166 khays
                  infprintf (is, "0x%lx", GET_OP (insn, CODE2));
2516 158 khays
                  break;
2517
 
2518
                case 't':
2519
                case 'w':
2520 166 khays
                  infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RT)]);
2521 158 khays
                  break;
2522
 
2523
                case 'y':
2524 166 khays
                  infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS3)]);
2525 158 khays
                  break;
2526
 
2527
                case 'z':
2528 166 khays
                  infprintf (is, "%s", mips_gpr_names[0]);
2529 158 khays
                  break;
2530
 
2531
                case 'B':
2532 166 khays
                  infprintf (is, "0x%lx", GET_OP (insn, CODE10));
2533 158 khays
                  break;
2534
 
2535
                case 'C':
2536 166 khays
                  infprintf (is, "0x%lx", GET_OP (insn, COPZ));
2537 158 khays
                  break;
2538
 
2539
                case 'D':
2540 166 khays
                  infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FD)]);
2541 158 khays
                  break;
2542
 
2543
                case 'E':
2544
                  /* Coprocessor register for lwcN instructions, et al.
2545
 
2546
                    Note that there is no load/store cp0 instructions, and
2547
                    that FPU (cp1) instructions disassemble this field using
2548
                    'T' format.  Therefore, until we gain understanding of
2549
                    cp2 register names, we can simply print the register
2550
                    numbers.  */
2551 166 khays
                  infprintf (is, "$%ld", GET_OP (insn, RT));
2552 158 khays
                  break;
2553
 
2554
                case 'G':
2555
                  /* Coprocessor register for mtcN instructions, et al.  Note
2556
                     that FPU (cp1) instructions disassemble this field using
2557
                     'S' format.  Therefore, we only need to worry about cp0,
2558
                     cp2, and cp3.
2559
                     The microMIPS encoding does not have a coprocessor
2560
                     identifier field as such, so we must work out the
2561
                     coprocessor number by looking at the opcode.  */
2562
                  switch (insn
2563
                          & ~((MICROMIPSOP_MASK_RT << MICROMIPSOP_SH_RT)
2564
                              | (MICROMIPSOP_MASK_RS << MICROMIPSOP_SH_RS)))
2565
                    {
2566
                    case 0x000000fc:                            /* mfc0  */
2567
                    case 0x000002fc:                            /* mtc0  */
2568
                    case 0x580000fc:                            /* dmfc0 */
2569
                    case 0x580002fc:                            /* dmtc0 */
2570 166 khays
                      infprintf (is, "%s", mips_cp0_names[GET_OP (insn, RS)]);
2571 158 khays
                      break;
2572
                    default:
2573 166 khays
                      infprintf (is, "$%ld", GET_OP (insn, RS));
2574 158 khays
                      break;
2575
                    }
2576
                  break;
2577
 
2578
                case 'H':
2579 166 khays
                  infprintf (is, "%ld", GET_OP (insn, SEL));
2580 158 khays
                  break;
2581
 
2582
                case 'K':
2583 166 khays
                  infprintf (is, "%s", mips_hwr_names[GET_OP (insn, RS)]);
2584 158 khays
                  break;
2585
 
2586
                case 'M':
2587 166 khays
                  infprintf (is, "$fcc%ld", GET_OP (insn, CCC));
2588 158 khays
                  break;
2589
 
2590
                case 'N':
2591 166 khays
                  infprintf (is,
2592 158 khays
                           (op->pinfo & (FP_D | FP_S)) != 0
2593
                           ? "$fcc%ld" : "$cc%ld",
2594
                           GET_OP (insn, BCC));
2595
                  break;
2596
 
2597
                case 'R':
2598 166 khays
                  infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FR)]);
2599 158 khays
                  break;
2600
 
2601
                case 'S':
2602
                case 'V':
2603 166 khays
                  infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FS)]);
2604 158 khays
                  break;
2605
 
2606
                case 'T':
2607 166 khays
                  infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FT)]);
2608 158 khays
                  break;
2609
 
2610
                case '+':
2611
                  /* Extension character; switch for second char.  */
2612
                  s++;
2613
                  switch (*s)
2614
                    {
2615
                    case 'A':
2616
                      lsb = GET_OP (insn, EXTLSB);
2617 166 khays
                      infprintf (is, "0x%x", lsb);
2618 158 khays
                      break;
2619
 
2620
                    case 'B':
2621
                      msb = GET_OP (insn, INSMSB);
2622 166 khays
                      infprintf (is, "0x%x", msb - lsb + 1);
2623 158 khays
                      break;
2624
 
2625
                    case 'C':
2626
                    case 'H':
2627
                      msbd = GET_OP (insn, EXTMSBD);
2628 166 khays
                      infprintf (is, "0x%x", msbd + 1);
2629 158 khays
                      break;
2630
 
2631
                    case 'D':
2632
                      {
2633
                        const struct mips_cp0sel_name *n;
2634
                        unsigned int cp0reg, sel;
2635
 
2636
                        cp0reg = GET_OP (insn, RS);
2637
                        sel = GET_OP (insn, SEL);
2638
 
2639
                        /* CP0 register including 'sel' code for mtcN
2640
                           (et al.), to be printed textually if known.
2641
                           If not known, print both CP0 register name and
2642
                           sel numerically since CP0 register with sel 0 may
2643
                           have a name unrelated to register being printed.  */
2644
                        n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2645
                                                     mips_cp0sel_names_len,
2646
                                                     cp0reg, sel);
2647
                        if (n != NULL)
2648 166 khays
                          infprintf (is, "%s", n->name);
2649 158 khays
                        else
2650 166 khays
                          infprintf (is, "$%d,%d", cp0reg, sel);
2651 158 khays
                        break;
2652
                      }
2653
 
2654
                    case 'E':
2655
                      lsb = GET_OP (insn, EXTLSB) + 32;
2656 166 khays
                      infprintf (is, "0x%x", lsb);
2657 158 khays
                      break;
2658
 
2659
                    case 'F':
2660
                      msb = GET_OP (insn, INSMSB) + 32;
2661 166 khays
                      infprintf (is, "0x%x", msb - lsb + 1);
2662 158 khays
                      break;
2663
 
2664
                    case 'G':
2665
                      msbd = GET_OP (insn, EXTMSBD) + 32;
2666 166 khays
                      infprintf (is, "0x%x", msbd + 1);
2667 158 khays
                      break;
2668
 
2669
                    default:
2670
                      /* xgettext:c-format */
2671 166 khays
                      infprintf (is,
2672 158 khays
                               _("# internal disassembler error, "
2673
                                 "unrecognized modifier (+%c)"),
2674
                               *s);
2675
                      abort ();
2676
                    }
2677
                  break;
2678
 
2679
                case 'm':
2680
                  /* Extension character; switch for second char.  */
2681
                  s++;
2682
                  switch (*s)
2683
                    {
2684
                    case 'a':   /* global pointer.  */
2685 166 khays
                      infprintf (is, "%s", mips_gpr_names[28]);
2686 158 khays
                      break;
2687
 
2688
                    case 'b':
2689
                      regno = micromips_to_32_reg_b_map[GET_OP (insn, MB)];
2690 166 khays
                      infprintf (is, "%s", mips_gpr_names[regno]);
2691 158 khays
                      break;
2692
 
2693
                    case 'c':
2694
                      regno = micromips_to_32_reg_c_map[GET_OP (insn, MC)];
2695 166 khays
                      infprintf (is, "%s", mips_gpr_names[regno]);
2696 158 khays
                      break;
2697
 
2698
                    case 'd':
2699
                      regno = micromips_to_32_reg_d_map[GET_OP (insn, MD)];
2700 166 khays
                      infprintf (is, "%s", mips_gpr_names[regno]);
2701 158 khays
                      break;
2702
 
2703
                    case 'e':
2704
                      regno = micromips_to_32_reg_e_map[GET_OP (insn, ME)];
2705 166 khays
                      infprintf (is, "%s", mips_gpr_names[regno]);
2706 158 khays
                      break;
2707
 
2708
                    case 'f':
2709
                      /* Save lastregno for "mt" to print out later.  */
2710
                      lastregno = micromips_to_32_reg_f_map[GET_OP (insn, MF)];
2711 166 khays
                      infprintf (is, "%s", mips_gpr_names[lastregno]);
2712 158 khays
                      break;
2713
 
2714
                    case 'g':
2715
                      regno = micromips_to_32_reg_g_map[GET_OP (insn, MG)];
2716 166 khays
                      infprintf (is, "%s", mips_gpr_names[regno]);
2717 158 khays
                      break;
2718
 
2719
                    case 'h':
2720
                      regno = micromips_to_32_reg_h_map[GET_OP (insn, MH)];
2721 166 khays
                      infprintf (is, "%s", mips_gpr_names[regno]);
2722 158 khays
                      break;
2723
 
2724
                    case 'i':
2725
                      regno = micromips_to_32_reg_i_map[GET_OP (insn, MI)];
2726 166 khays
                      infprintf (is, "%s", mips_gpr_names[regno]);
2727 158 khays
                      break;
2728
 
2729
                    case 'j':
2730 166 khays
                      infprintf (is, "%s", mips_gpr_names[GET_OP (insn, MJ)]);
2731 158 khays
                      break;
2732
 
2733
                    case 'l':
2734
                      regno = micromips_to_32_reg_l_map[GET_OP (insn, ML)];
2735 166 khays
                      infprintf (is, "%s", mips_gpr_names[regno]);
2736 158 khays
                      break;
2737
 
2738
                    case 'm':
2739
                      regno = micromips_to_32_reg_m_map[GET_OP (insn, MM)];
2740 166 khays
                      infprintf (is, "%s", mips_gpr_names[regno]);
2741 158 khays
                      break;
2742
 
2743
                    case 'n':
2744
                      regno = micromips_to_32_reg_n_map[GET_OP (insn, MN)];
2745 166 khays
                      infprintf (is, "%s", mips_gpr_names[regno]);
2746 158 khays
                      break;
2747
 
2748
                    case 'p':
2749
                      /* Save lastregno for "mt" to print out later.  */
2750
                      lastregno = GET_OP (insn, MP);
2751 166 khays
                      infprintf (is, "%s", mips_gpr_names[lastregno]);
2752 158 khays
                      break;
2753
 
2754
                    case 'q':
2755
                      regno = micromips_to_32_reg_q_map[GET_OP (insn, MQ)];
2756 166 khays
                      infprintf (is, "%s", mips_gpr_names[regno]);
2757 158 khays
                      break;
2758
 
2759
                    case 'r':   /* program counter.  */
2760 166 khays
                      infprintf (is, "$pc");
2761 158 khays
                      break;
2762
 
2763
                    case 's':   /* stack pointer.  */
2764
                      lastregno = 29;
2765 166 khays
                      infprintf (is, "%s", mips_gpr_names[29]);
2766 158 khays
                      break;
2767
 
2768
                    case 't':
2769 166 khays
                      infprintf (is, "%s", mips_gpr_names[lastregno]);
2770 158 khays
                      break;
2771
 
2772
                    case 'z':   /* $0.  */
2773 166 khays
                      infprintf (is, "%s", mips_gpr_names[0]);
2774 158 khays
                      break;
2775
 
2776
                    case 'A':
2777
                      /* Sign-extend the immediate.  */
2778
                      immed = ((GET_OP (insn, IMMA) ^ 0x40) - 0x40) << 2;
2779 166 khays
                      infprintf (is, "%d", immed);
2780 158 khays
                      break;
2781
 
2782
                    case 'B':
2783
                      immed = micromips_imm_b_map[GET_OP (insn, IMMB)];
2784 166 khays
                      infprintf (is, "%d", immed);
2785 158 khays
                      break;
2786
 
2787
                    case 'C':
2788
                      immed = micromips_imm_c_map[GET_OP (insn, IMMC)];
2789 166 khays
                      infprintf (is, "0x%lx", immed);
2790 158 khays
                      break;
2791
 
2792
                    case 'D':
2793
                      /* Sign-extend the displacement.  */
2794
                      delta = (GET_OP (insn, IMMD) ^ 0x200) - 0x200;
2795
                      info->target = (delta << 1) + memaddr + length;
2796
                      (*info->print_address_func) (info->target, info);
2797
                      break;
2798
 
2799
                    case 'E':
2800
                      /* Sign-extend the displacement.  */
2801
                      delta = (GET_OP (insn, IMME) ^ 0x40) - 0x40;
2802
                      info->target = (delta << 1) + memaddr + length;
2803
                      (*info->print_address_func) (info->target, info);
2804
                      break;
2805
 
2806
                    case 'F':
2807
                      immed = GET_OP (insn, IMMF);
2808 166 khays
                      infprintf (is, "0x%x", immed);
2809 158 khays
                      break;
2810
 
2811
                    case 'G':
2812
                      immed = (insn >> MICROMIPSOP_SH_IMMG) + 1;
2813
                      immed = (immed & MICROMIPSOP_MASK_IMMG) - 1;
2814 166 khays
                      infprintf (is, "%d", immed);
2815 158 khays
                      break;
2816
 
2817
                    case 'H':
2818
                      immed = GET_OP (insn, IMMH) << 1;
2819 166 khays
                      infprintf (is, "%d", immed);
2820 158 khays
                      break;
2821
 
2822
                    case 'I':
2823
                      immed = (insn >> MICROMIPSOP_SH_IMMI) + 1;
2824
                      immed = (immed & MICROMIPSOP_MASK_IMMI) - 1;
2825 166 khays
                      infprintf (is, "%d", immed);
2826 158 khays
                      break;
2827
 
2828
                    case 'J':
2829
                      immed = GET_OP (insn, IMMJ) << 2;
2830 166 khays
                      infprintf (is, "%d", immed);
2831 158 khays
                      break;
2832
 
2833
                    case 'L':
2834
                      immed = GET_OP (insn, IMML);
2835 166 khays
                      infprintf (is, "%d", immed);
2836 158 khays
                      break;
2837
 
2838
                    case 'M':
2839
                      immed = (insn >> MICROMIPSOP_SH_IMMM) - 1;
2840
                      immed = (immed & MICROMIPSOP_MASK_IMMM) + 1;
2841 166 khays
                      infprintf (is, "%d", immed);
2842 158 khays
                      break;
2843
 
2844
                    case 'N':
2845
                      immed = GET_OP (insn, IMMN);
2846
                      if (immed == 0)
2847 166 khays
                        infprintf (is, "%s,%s",
2848 158 khays
                                 mips_gpr_names[16],
2849
                                 mips_gpr_names[31]);
2850
                      else
2851 166 khays
                        infprintf (is, "%s-%s,%s",
2852 158 khays
                                 mips_gpr_names[16],
2853
                                 mips_gpr_names[16 + immed],
2854
                                 mips_gpr_names[31]);
2855
                      break;
2856
 
2857
                    case 'O':
2858
                      immed = GET_OP (insn, IMMO);
2859 166 khays
                      infprintf (is, "0x%x", immed);
2860 158 khays
                      break;
2861
 
2862
                    case 'P':
2863
                      immed = GET_OP (insn, IMMP) << 2;
2864 166 khays
                      infprintf (is, "%d", immed);
2865 158 khays
                      break;
2866
 
2867
                    case 'Q':
2868
                      /* Sign-extend the immediate.  */
2869
                      immed = (GET_OP (insn, IMMQ) ^ 0x400000) - 0x400000;
2870
                      immed <<= 2;
2871 166 khays
                      infprintf (is, "%d", immed);
2872 158 khays
                      break;
2873
 
2874
                    case 'U':
2875
                      immed = GET_OP (insn, IMMU) << 2;
2876 166 khays
                      infprintf (is, "%d", immed);
2877 158 khays
                      break;
2878
 
2879
                    case 'W':
2880
                      immed = GET_OP (insn, IMMW) << 2;
2881 166 khays
                      infprintf (is, "%d", immed);
2882 158 khays
                      break;
2883
 
2884
                    case 'X':
2885
                      /* Sign-extend the immediate.  */
2886
                      immed = (GET_OP (insn, IMMX) ^ 0x8) - 0x8;
2887 166 khays
                      infprintf (is, "%d", immed);
2888 158 khays
                      break;
2889
 
2890
                    case 'Y':
2891
                      /* Sign-extend the immediate.  */
2892
                      immed = (GET_OP (insn, IMMY) ^ 0x100) - 0x100;
2893
                      if (immed >= -2 && immed <= 1)
2894
                        immed ^= 0x100;
2895
                      immed = immed << 2;
2896 166 khays
                      infprintf (is, "%d", immed);
2897 158 khays
                      break;
2898
 
2899
                    default:
2900
                      /* xgettext:c-format */
2901 166 khays
                      infprintf (is,
2902 158 khays
                               _("# internal disassembler error, "
2903
                                 "unrecognized modifier (m%c)"),
2904
                               *s);
2905
                      abort ();
2906
                    }
2907
                  break;
2908
 
2909
                default:
2910
                  /* xgettext:c-format */
2911 166 khays
                  infprintf (is,
2912 158 khays
                           _("# internal disassembler error, "
2913
                             "unrecognized modifier (%c)"),
2914
                           *s);
2915
                  abort ();
2916
                }
2917
            }
2918
 
2919
          /* Figure out instruction type and branch delay information.  */
2920
          if ((op->pinfo
2921
               & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2922
            info->branch_delay_insns = 1;
2923
          if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2924
               | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2925
            {
2926
              if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_GPR_T)) != 0)
2927
                info->insn_type = dis_jsr;
2928
              else
2929
                info->insn_type = dis_branch;
2930
            }
2931
          else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2932
                    | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2933
            {
2934
              if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2935
                info->insn_type = dis_condjsr;
2936
              else
2937
                info->insn_type = dis_condbranch;
2938
            }
2939
          else if ((op->pinfo
2940
                    & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY_DELAY)) != 0)
2941
            info->insn_type = dis_dref;
2942
 
2943
          return length;
2944
        }
2945
    }
2946
#undef GET_OP
2947
 
2948 166 khays
  infprintf (is, "0x%x", insn);
2949 158 khays
  info->insn_type = dis_noninsn;
2950
 
2951
  return length;
2952
}
2953
 
2954
/* Return 1 if a symbol associated with the location being disassembled
2955
   indicates a compressed (MIPS16 or microMIPS) mode.  We iterate over
2956
   all the symbols at the address being considered assuming if at least
2957
   one of them indicates code compression, then such code has been
2958
   genuinely produced here (other symbols could have been derived from
2959
   function symbols defined elsewhere or could define data).  Otherwise,
2960
   return 0.  */
2961
 
2962
static bfd_boolean
2963
is_compressed_mode_p (struct disassemble_info *info)
2964
{
2965
  elf_symbol_type *symbol;
2966
  int pos;
2967
  int i;
2968
 
2969
  for (i = 0; i < info->num_symbols; i++)
2970
    {
2971
      pos = info->symtab_pos + i;
2972
 
2973
      if (bfd_asymbol_flavour (info->symtab[pos]) != bfd_target_elf_flavour)
2974
        continue;
2975
 
2976
      symbol = (elf_symbol_type *) info->symtab[pos];
2977
      if ((!micromips_ase
2978
           && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2979
          || (micromips_ase
2980
              && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2981
            return 1;
2982
    }
2983
 
2984
  return 0;
2985
}
2986
 
2987 18 khays
/* In an environment where we do not know the symbol type of the
2988
   instruction we are forced to assume that the low order bit of the
2989
   instructions' address may mark it as a mips16 instruction.  If we
2990
   are single stepping, or the pc is within the disassembled function,
2991
   this works.  Otherwise, we need a clue.  Sometimes.  */
2992
 
2993
static int
2994
_print_insn_mips (bfd_vma memaddr,
2995
                  struct disassemble_info *info,
2996
                  enum bfd_endian endianness)
2997
{
2998 158 khays
  int (*print_insn_compr) (bfd_vma, struct disassemble_info *);
2999 18 khays
  bfd_byte buffer[INSNLEN];
3000
  int status;
3001
 
3002
  set_default_mips_dis_options (info);
3003
  parse_mips_dis_options (info->disassembler_options);
3004
 
3005 158 khays
  if (info->mach == bfd_mach_mips16)
3006
    return print_insn_mips16 (memaddr, info);
3007
  if (info->mach == bfd_mach_mips_micromips)
3008
    return print_insn_micromips (memaddr, info);
3009
 
3010
  print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips;
3011
 
3012 18 khays
#if 1
3013 158 khays
  /* FIXME: If odd address, this is CLEARLY a compressed instruction.  */
3014 18 khays
  /* Only a few tools will work this way.  */
3015
  if (memaddr & 0x01)
3016 158 khays
    return print_insn_compr (memaddr, info);
3017 18 khays
#endif
3018
 
3019
#if SYMTAB_AVAILABLE
3020 158 khays
  if (is_compressed_mode_p (info))
3021
    return print_insn_compr (memaddr, info);
3022 18 khays
#endif
3023
 
3024
  status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
3025
  if (status == 0)
3026
    {
3027
      unsigned long insn;
3028
 
3029
      if (endianness == BFD_ENDIAN_BIG)
3030
        insn = (unsigned long) bfd_getb32 (buffer);
3031
      else
3032
        insn = (unsigned long) bfd_getl32 (buffer);
3033
 
3034
      return print_insn_mips (memaddr, insn, info);
3035
    }
3036
  else
3037
    {
3038
      (*info->memory_error_func) (status, memaddr, info);
3039
      return -1;
3040
    }
3041
}
3042
 
3043
int
3044
print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
3045
{
3046
  return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
3047
}
3048
 
3049
int
3050
print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
3051
{
3052
  return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
3053
}
3054
 
3055
void
3056
print_mips_disassembler_options (FILE *stream)
3057
{
3058
  unsigned int i;
3059
 
3060
  fprintf (stream, _("\n\
3061
The following MIPS specific disassembler options are supported for use\n\
3062
with the -M switch (multiple options should be separated by commas):\n"));
3063
 
3064
  fprintf (stream, _("\n\
3065
  gpr-names=ABI            Print GPR names according to  specified ABI.\n\
3066
                           Default: based on binary being disassembled.\n"));
3067
 
3068
  fprintf (stream, _("\n\
3069
  fpr-names=ABI            Print FPR names according to specified ABI.\n\
3070
                           Default: numeric.\n"));
3071
 
3072
  fprintf (stream, _("\n\
3073
  cp0-names=ARCH           Print CP0 register names according to\n\
3074
                           specified architecture.\n\
3075
                           Default: based on binary being disassembled.\n"));
3076
 
3077
  fprintf (stream, _("\n\
3078
  hwr-names=ARCH           Print HWR names according to specified \n\
3079
                           architecture.\n\
3080
                           Default: based on binary being disassembled.\n"));
3081
 
3082
  fprintf (stream, _("\n\
3083
  reg-names=ABI            Print GPR and FPR names according to\n\
3084
                           specified ABI.\n"));
3085
 
3086
  fprintf (stream, _("\n\
3087
  reg-names=ARCH           Print CP0 register and HWR names according to\n\
3088
                           specified architecture.\n"));
3089
 
3090
  fprintf (stream, _("\n\
3091
  For the options above, the following values are supported for \"ABI\":\n\
3092
   "));
3093
  for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
3094
    fprintf (stream, " %s", mips_abi_choices[i].name);
3095
  fprintf (stream, _("\n"));
3096
 
3097
  fprintf (stream, _("\n\
3098
  For the options above, The following values are supported for \"ARCH\":\n\
3099
   "));
3100
  for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
3101
    if (*mips_arch_choices[i].name != '\0')
3102
      fprintf (stream, " %s", mips_arch_choices[i].name);
3103
  fprintf (stream, _("\n"));
3104
 
3105
  fprintf (stream, _("\n"));
3106
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.