1
/* Altera Nios II disassemble routines
2
Copyright (C) 2012, 2013 Free Software Foundation, Inc.
3
Contributed by Nigel Gray (ngray@altera.com).
4
Contributed by Mentor Graphics, Inc.
6
This file is part of the GNU opcodes library.
8
This library is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3, or (at your option)
13
It is distributed in the hope that it will be useful, but WITHOUT
14
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16
License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this file; see the file COPYING. If not, write to the
20
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
21
MA 02110-1301, USA. */
25
#include "opcode/nios2.h"
26
#include "libiberty.h"
30
/* No symbol table is available when this code runs out in an embedded
31
system as when it is used for disassembler support in a monitor. */
32
#if !defined(EMBEDDED_ENV)
33
#define SYMTAB_AVAILABLE 1
35
#include "elf/nios2.h"
38
/* Length of Nios II instruction in bytes. */
41
/* Data structures used by the opcode hash table. */
42
typedef struct _nios2_opcode_hash
44
const struct nios2_opcode *opcode;
45
struct _nios2_opcode_hash *next;
48
static bfd_boolean nios2_hash_init = 0;
49
static nios2_opcode_hash *nios2_hash[(OP_MASK_OP) + 1];
51
/* Separate hash table for pseudo-ops. */
52
static nios2_opcode_hash *nios2_ps_hash[(OP_MASK_OP) + 1];
54
/* Function to initialize the opcode hash table. */
56
nios2_init_opcode_hash (void)
59
register const struct nios2_opcode *op;
61
for (i = 0; i <= OP_MASK_OP; ++i)
63
for (i = 0; i <= OP_MASK_OP; i++)
64
for (op = nios2_opcodes; op < &nios2_opcodes[NUMOPCODES]; op++)
66
nios2_opcode_hash *new_hash;
67
nios2_opcode_hash **bucket = NULL;
69
if ((op->pinfo & NIOS2_INSN_MACRO) == NIOS2_INSN_MACRO)
71
if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP)
72
&& (op->pinfo & (NIOS2_INSN_MACRO_MOV | NIOS2_INSN_MACRO_MOVI)
74
bucket = &(nios2_ps_hash[i]);
76
else if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
77
bucket = &(nios2_hash[i]);
82
(nios2_opcode_hash *) malloc (sizeof (nios2_opcode_hash));
86
"error allocating memory...broken disassembler\n");
89
new_hash->opcode = op;
90
new_hash->next = NULL;
92
bucket = &((*bucket)->next);
97
#ifdef DEBUG_HASHTABLE
98
for (i = 0; i <= OP_MASK_OP; ++i)
100
nios2_opcode_hash *tmp_hash = nios2_hash[i];
101
printf ("index: 0x%02X ops: ", i);
102
while (tmp_hash != NULL)
104
printf ("%s ", tmp_hash->opcode->name);
105
tmp_hash = tmp_hash->next;
110
for (i = 0; i <= OP_MASK_OP; ++i)
112
nios2_opcode_hash *tmp_hash = nios2_ps_hash[i];
113
printf ("index: 0x%02X ops: ", i);
114
while (tmp_hash != NULL)
116
printf ("%s ", tmp_hash->opcode->name);
117
tmp_hash = tmp_hash->next;
121
#endif /* DEBUG_HASHTABLE */
124
/* Return a pointer to an nios2_opcode struct for a given instruction
125
opcode, or NULL if there is an error. */
126
const struct nios2_opcode *
127
nios2_find_opcode_hash (unsigned long opcode)
129
nios2_opcode_hash *entry;
131
/* Build a hash table to shorten the search time. */
132
if (!nios2_hash_init)
133
nios2_init_opcode_hash ();
135
/* First look in the pseudo-op hashtable. */
136
for (entry = nios2_ps_hash[(opcode >> OP_SH_OP) & OP_MASK_OP];
137
entry; entry = entry->next)
138
if (entry->opcode->match == (opcode & entry->opcode->mask))
139
return entry->opcode;
141
/* Otherwise look in the main hashtable. */
142
for (entry = nios2_hash[(opcode >> OP_SH_OP) & OP_MASK_OP];
143
entry; entry = entry->next)
144
if (entry->opcode->match == (opcode & entry->opcode->mask))
145
return entry->opcode;
150
/* There are 32 regular registers, 32 coprocessor registers,
151
and 32 control registers. */
152
#define NUMREGNAMES 32
154
/* Return a pointer to the base of the coprocessor register name array. */
155
static struct nios2_reg *
156
nios2_coprocessor_regs (void)
158
static struct nios2_reg *cached = NULL;
163
for (i = NUMREGNAMES; i < nios2_num_regs; i++)
164
if (!strcmp (nios2_regs[i].name, "c0"))
166
cached = nios2_regs + i;
174
/* Return a pointer to the base of the control register name array. */
175
static struct nios2_reg *
176
nios2_control_regs (void)
178
static struct nios2_reg *cached = NULL;
183
for (i = NUMREGNAMES; i < nios2_num_regs; i++)
184
if (!strcmp (nios2_regs[i].name, "status"))
186
cached = nios2_regs + i;
194
/* The function nios2_print_insn_arg uses the character pointed
195
to by ARGPTR to determine how it print the next token or separator
196
character in the arguments to an instruction. */
198
nios2_print_insn_arg (const char *argptr,
199
unsigned long opcode, bfd_vma address,
200
disassemble_info *info)
203
struct nios2_reg *reg_base;
210
(*info->fprintf_func) (info->stream, "%c", *argptr);
213
i = GET_INSN_FIELD (RRD, opcode);
215
if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
216
&& GET_INSN_FIELD (CUSTOM_C, opcode) == 0)
217
reg_base = nios2_coprocessor_regs ();
219
reg_base = nios2_regs;
222
(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
224
(*info->fprintf_func) (info->stream, "unknown");
227
i = GET_INSN_FIELD (RRS, opcode);
229
if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
230
&& GET_INSN_FIELD (CUSTOM_A, opcode) == 0)
231
reg_base = nios2_coprocessor_regs ();
233
reg_base = nios2_regs;
236
(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
238
(*info->fprintf_func) (info->stream, "unknown");
241
i = GET_INSN_FIELD (RRT, opcode);
243
if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
244
&& GET_INSN_FIELD (CUSTOM_B, opcode) == 0)
245
reg_base = nios2_coprocessor_regs ();
247
reg_base = nios2_regs;
250
(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
252
(*info->fprintf_func) (info->stream, "unknown");
255
/* 16-bit signed immediate. */
256
i = (signed) (GET_INSN_FIELD (IMM16, opcode) << 16) >> 16;
257
(*info->fprintf_func) (info->stream, "%ld", i);
260
/* 16-bit unsigned immediate. */
261
i = GET_INSN_FIELD (IMM16, opcode);
262
(*info->fprintf_func) (info->stream, "%ld", i);
265
/* 16-bit signed immediate address offset. */
266
i = (signed) (GET_INSN_FIELD (IMM16, opcode) << 16) >> 16;
267
address = address + 4 + i;
268
(*info->print_address_func) (address, info);
271
/* 5-bit unsigned immediate. */
272
i = GET_INSN_FIELD (CACHE_OPX, opcode);
273
(*info->fprintf_func) (info->stream, "%ld", i);
276
/* 5-bit unsigned immediate. */
277
i = GET_INSN_FIELD (IMM5, opcode);
278
(*info->fprintf_func) (info->stream, "%ld", i);
281
/* 8-bit unsigned immediate. */
282
/* FIXME - not yet implemented */
283
i = GET_INSN_FIELD (CUSTOM_N, opcode);
284
(*info->fprintf_func) (info->stream, "%lu", i);
287
/* 26-bit unsigned immediate. */
288
i = GET_INSN_FIELD (IMM26, opcode);
289
/* This translates to an address because it's only used in call
291
address = (address & 0xf0000000) | (i << 2);
292
(*info->print_address_func) (address, info);
295
/* Control register index. */
296
i = GET_INSN_FIELD (IMM5, opcode);
297
reg_base = nios2_control_regs ();
298
(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
301
i = GET_INSN_FIELD (IMM5, opcode);
302
(*info->fprintf_func) (info->stream, "%ld", i);
305
(*info->fprintf_func) (info->stream, "unknown");
311
/* nios2_disassemble does all the work of disassembling a Nios II
312
instruction opcode. */
314
nios2_disassemble (bfd_vma address, unsigned long opcode,
315
disassemble_info *info)
317
const struct nios2_opcode *op;
319
info->bytes_per_line = INSNLEN;
320
info->bytes_per_chunk = INSNLEN;
321
info->display_endian = info->endian;
322
info->insn_info_valid = 1;
323
info->branch_delay_insns = 0;
325
info->insn_type = dis_nonbranch;
329
/* Find the major opcode and use this to disassemble
330
the instruction and its arguments. */
331
op = nios2_find_opcode_hash (opcode);
335
bfd_boolean is_nop = FALSE;
336
if (op->pinfo == NIOS2_INSN_MACRO_MOV)
338
/* Check for mov r0, r0 and change to nop. */
340
dst = GET_INSN_FIELD (RRD, opcode);
341
src = GET_INSN_FIELD (RRS, opcode);
342
if (dst == 0 && src == 0)
344
(*info->fprintf_func) (info->stream, "nop");
348
(*info->fprintf_func) (info->stream, "%s", op->name);
351
(*info->fprintf_func) (info->stream, "%s", op->name);
355
const char *argstr = op->args;
356
if (argstr != NULL && *argstr != '\0')
358
(*info->fprintf_func) (info->stream, "\t");
359
while (*argstr != '\0')
361
nios2_print_insn_arg (argstr, opcode, address, info);
369
/* Handle undefined instructions. */
370
info->insn_type = dis_noninsn;
371
(*info->fprintf_func) (info->stream, "0x%lx", opcode);
373
/* Tell the caller how far to advance the program counter. */
378
/* print_insn_nios2 is the main disassemble function for Nios II.
379
The function diassembler(abfd) (source in disassemble.c) returns a
380
pointer to this either print_insn_big_nios2 or
381
print_insn_little_nios2, which in turn call this function when the
382
bfd machine type is Nios II. print_insn_nios2 reads the
383
instruction word at the address given, and prints the disassembled
384
instruction on the stream info->stream using info->fprintf_func. */
387
print_insn_nios2 (bfd_vma address, disassemble_info *info,
388
enum bfd_endian endianness)
390
bfd_byte buffer[INSNLEN];
393
status = (*info->read_memory_func) (address, buffer, INSNLEN, info);
397
if (endianness == BFD_ENDIAN_BIG)
398
insn = (unsigned long) bfd_getb32 (buffer);
400
insn = (unsigned long) bfd_getl32 (buffer);
401
status = nios2_disassemble (address, insn, info);
405
(*info->memory_error_func) (status, address, info);
411
/* These two functions are the main entry points, accessed from
414
print_insn_big_nios2 (bfd_vma address, disassemble_info *info)
416
return print_insn_nios2 (address, info, BFD_ENDIAN_BIG);
420
print_insn_little_nios2 (bfd_vma address, disassemble_info *info)
422
return print_insn_nios2 (address, info, BFD_ENDIAN_LITTLE);