1 /* Altera Nios II disassemble routines
2 Copyright (C) 2012-2014 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);