]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/nios2-dis.c
ChangeLog rotatation and copyright year update
[thirdparty/binutils-gdb.git] / opcodes / nios2-dis.c
CommitLineData
36591ba1 1/* Altera Nios II disassemble routines
b90efa5b 2 Copyright (C) 2012-2015 Free Software Foundation, Inc.
36591ba1
SL
3 Contributed by Nigel Gray (ngray@altera.com).
4 Contributed by Mentor Graphics, Inc.
5
6 This file is part of the GNU opcodes library.
7
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)
11 any later version.
12
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.
17
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. */
22
23#include "sysdep.h"
24#include "dis-asm.h"
25#include "opcode/nios2.h"
26#include "libiberty.h"
27#include <string.h>
28#include <assert.h>
29
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
34#include "elf-bfd.h"
35#include "elf/nios2.h"
36#endif
37
96ba4233 38/* Default length of Nios II instruction in bytes. */
36591ba1
SL
39#define INSNLEN 4
40
41/* Data structures used by the opcode hash table. */
42typedef struct _nios2_opcode_hash
43{
44 const struct nios2_opcode *opcode;
45 struct _nios2_opcode_hash *next;
46} nios2_opcode_hash;
47
96ba4233
SL
48/* Hash table size. */
49#define OPCODE_HASH_SIZE (IW_R1_OP_UNSHIFTED_MASK + 1)
36591ba1 50
96ba4233
SL
51/* Extract the opcode from an instruction word. */
52static unsigned int
53nios2_r1_extract_opcode (unsigned int x)
54{
55 return GET_IW_R1_OP (x);
56}
57
58/* Pseudo-ops are stored in a different table than regular instructions. */
59
60typedef struct _nios2_disassembler_state
61{
62 const struct nios2_opcode *opcodes;
63 const int *num_opcodes;
64 unsigned int (*extract_opcode) (unsigned int);
65 nios2_opcode_hash *hash[OPCODE_HASH_SIZE];
66 nios2_opcode_hash *ps_hash[OPCODE_HASH_SIZE];
67 const struct nios2_opcode *nop;
68 bfd_boolean init;
69} nios2_disassembler_state;
70
71static nios2_disassembler_state
72nios2_r1_disassembler_state = {
73 nios2_r1_opcodes,
74 &nios2_num_r1_opcodes,
75 nios2_r1_extract_opcode,
76 {},
77 {},
78 NULL,
79 0
80};
36591ba1
SL
81
82/* Function to initialize the opcode hash table. */
83static void
96ba4233 84nios2_init_opcode_hash (nios2_disassembler_state *state)
36591ba1
SL
85{
86 unsigned int i;
87 register const struct nios2_opcode *op;
88
96ba4233
SL
89 for (i = 0; i < OPCODE_HASH_SIZE; i++)
90 for (op = state->opcodes; op < &state->opcodes[*(state->num_opcodes)]; op++)
36591ba1
SL
91 {
92 nios2_opcode_hash *new_hash;
93 nios2_opcode_hash **bucket = NULL;
94
95 if ((op->pinfo & NIOS2_INSN_MACRO) == NIOS2_INSN_MACRO)
96 {
96ba4233 97 if (i == state->extract_opcode (op->match)
36591ba1
SL
98 && (op->pinfo & (NIOS2_INSN_MACRO_MOV | NIOS2_INSN_MACRO_MOVI)
99 & 0x7fffffff))
96ba4233
SL
100 {
101 bucket = &(state->ps_hash[i]);
102 if (strcmp (op->name, "nop") == 0)
103 state->nop = op;
104 }
36591ba1 105 }
96ba4233
SL
106 else if (i == state->extract_opcode (op->match))
107 bucket = &(state->hash[i]);
36591ba1
SL
108
109 if (bucket)
110 {
111 new_hash =
112 (nios2_opcode_hash *) malloc (sizeof (nios2_opcode_hash));
113 if (new_hash == NULL)
114 {
115 fprintf (stderr,
116 "error allocating memory...broken disassembler\n");
117 abort ();
118 }
119 new_hash->opcode = op;
120 new_hash->next = NULL;
121 while (*bucket)
122 bucket = &((*bucket)->next);
123 *bucket = new_hash;
124 }
125 }
96ba4233
SL
126 state->init = 1;
127
36591ba1 128#ifdef DEBUG_HASHTABLE
96ba4233 129 for (i = 0; i < OPCODE_HASH_SIZE; ++i)
36591ba1 130 {
96ba4233 131 nios2_opcode_hash *tmp_hash = state->hash[i];
36591ba1
SL
132 printf ("index: 0x%02X ops: ", i);
133 while (tmp_hash != NULL)
134 {
135 printf ("%s ", tmp_hash->opcode->name);
136 tmp_hash = tmp_hash->next;
137 }
138 printf ("\n");
139 }
140
96ba4233 141 for (i = 0; i < OPCODE_HASH_SIZE; ++i)
36591ba1 142 {
96ba4233 143 nios2_opcode_hash *tmp_hash = state->ps_hash[i];
36591ba1
SL
144 printf ("index: 0x%02X ops: ", i);
145 while (tmp_hash != NULL)
146 {
147 printf ("%s ", tmp_hash->opcode->name);
148 tmp_hash = tmp_hash->next;
149 }
150 printf ("\n");
151 }
152#endif /* DEBUG_HASHTABLE */
153}
154
155/* Return a pointer to an nios2_opcode struct for a given instruction
b4714c7c 156 word OPCODE for bfd machine MACH, or NULL if there is an error. */
36591ba1 157const struct nios2_opcode *
b4714c7c
SL
158nios2_find_opcode_hash (unsigned long opcode,
159 unsigned long mach ATTRIBUTE_UNUSED)
36591ba1
SL
160{
161 nios2_opcode_hash *entry;
96ba4233
SL
162 nios2_disassembler_state *state;
163
164 state = &nios2_r1_disassembler_state;
36591ba1
SL
165
166 /* Build a hash table to shorten the search time. */
96ba4233
SL
167 if (!state->init)
168 nios2_init_opcode_hash (state);
169
170 /* Check for NOP first. Both NOP and MOV are macros that expand into
171 an ADD instruction, and we always want to give priority to NOP. */
172 if (state->nop->match == (opcode & state->nop->mask))
173 return state->nop;
36591ba1
SL
174
175 /* First look in the pseudo-op hashtable. */
96ba4233 176 for (entry = state->ps_hash[state->extract_opcode (opcode)];
36591ba1
SL
177 entry; entry = entry->next)
178 if (entry->opcode->match == (opcode & entry->opcode->mask))
179 return entry->opcode;
180
181 /* Otherwise look in the main hashtable. */
96ba4233 182 for (entry = state->hash[state->extract_opcode (opcode)];
36591ba1
SL
183 entry; entry = entry->next)
184 if (entry->opcode->match == (opcode & entry->opcode->mask))
185 return entry->opcode;
186
187 return NULL;
188}
189
190/* There are 32 regular registers, 32 coprocessor registers,
191 and 32 control registers. */
192#define NUMREGNAMES 32
193
194/* Return a pointer to the base of the coprocessor register name array. */
195static struct nios2_reg *
196nios2_coprocessor_regs (void)
197{
198 static struct nios2_reg *cached = NULL;
199
200 if (!cached)
201 {
202 int i;
203 for (i = NUMREGNAMES; i < nios2_num_regs; i++)
204 if (!strcmp (nios2_regs[i].name, "c0"))
205 {
206 cached = nios2_regs + i;
207 break;
208 }
209 assert (cached);
210 }
211 return cached;
212}
213
214/* Return a pointer to the base of the control register name array. */
215static struct nios2_reg *
216nios2_control_regs (void)
217{
218 static struct nios2_reg *cached = NULL;
219
220 if (!cached)
221 {
222 int i;
223 for (i = NUMREGNAMES; i < nios2_num_regs; i++)
224 if (!strcmp (nios2_regs[i].name, "status"))
225 {
226 cached = nios2_regs + i;
227 break;
228 }
229 assert (cached);
230 }
231 return cached;
232}
233
96ba4233
SL
234/* Helper routine to report internal errors. */
235static void
236bad_opcode (const struct nios2_opcode *op)
237{
238 fprintf (stderr, "Internal error: broken opcode descriptor for `%s %s'\n",
239 op->name, op->args);
240 abort ();
241}
242
36591ba1
SL
243/* The function nios2_print_insn_arg uses the character pointed
244 to by ARGPTR to determine how it print the next token or separator
245 character in the arguments to an instruction. */
246static int
247nios2_print_insn_arg (const char *argptr,
248 unsigned long opcode, bfd_vma address,
96ba4233
SL
249 disassemble_info *info,
250 const struct nios2_opcode *op)
36591ba1
SL
251{
252 unsigned long i = 0;
253 struct nios2_reg *reg_base;
254
255 switch (*argptr)
256 {
257 case ',':
258 case '(':
259 case ')':
260 (*info->fprintf_func) (info->stream, "%c", *argptr);
261 break;
36591ba1 262
96ba4233
SL
263 case 'd':
264 switch (op->format)
265 {
266 case iw_r_type:
267 i = GET_IW_R_C (opcode);
268 reg_base = nios2_regs;
269 break;
270 case iw_custom_type:
271 i = GET_IW_CUSTOM_C (opcode);
272 if (GET_IW_CUSTOM_READC (opcode) == 0)
273 reg_base = nios2_coprocessor_regs ();
274 else
275 reg_base = nios2_regs;
276 break;
277 default:
278 bad_opcode (op);
279 }
36591ba1
SL
280 if (i < NUMREGNAMES)
281 (*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
282 else
283 (*info->fprintf_func) (info->stream, "unknown");
284 break;
36591ba1 285
96ba4233
SL
286 case 's':
287 switch (op->format)
288 {
289 case iw_r_type:
290 i = GET_IW_R_A (opcode);
291 reg_base = nios2_regs;
292 break;
293 case iw_i_type:
294 i = GET_IW_I_A (opcode);
295 reg_base = nios2_regs;
296 break;
297 case iw_custom_type:
298 i = GET_IW_CUSTOM_A (opcode);
299 if (GET_IW_CUSTOM_READA (opcode) == 0)
300 reg_base = nios2_coprocessor_regs ();
301 else
302 reg_base = nios2_regs;
303 break;
304 default:
305 bad_opcode (op);
306 }
36591ba1
SL
307 if (i < NUMREGNAMES)
308 (*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
309 else
310 (*info->fprintf_func) (info->stream, "unknown");
311 break;
36591ba1 312
96ba4233
SL
313 case 't':
314 switch (op->format)
315 {
316 case iw_r_type:
317 i = GET_IW_R_B (opcode);
318 reg_base = nios2_regs;
319 break;
320 case iw_i_type:
321 i = GET_IW_I_B (opcode);
322 reg_base = nios2_regs;
323 break;
324 case iw_custom_type:
325 i = GET_IW_CUSTOM_B (opcode);
326 if (GET_IW_CUSTOM_READB (opcode) == 0)
327 reg_base = nios2_coprocessor_regs ();
328 else
329 reg_base = nios2_regs;
330 break;
331 default:
332 bad_opcode (op);
333 }
36591ba1
SL
334 if (i < NUMREGNAMES)
335 (*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
336 else
337 (*info->fprintf_func) (info->stream, "unknown");
338 break;
96ba4233 339
36591ba1
SL
340 case 'i':
341 /* 16-bit signed immediate. */
96ba4233
SL
342 switch (op->format)
343 {
344 case iw_i_type:
345 i = (signed) (GET_IW_I_IMM16 (opcode) << 16) >> 16;
346 break;
347 default:
348 bad_opcode (op);
349 }
36591ba1
SL
350 (*info->fprintf_func) (info->stream, "%ld", i);
351 break;
96ba4233 352
36591ba1
SL
353 case 'u':
354 /* 16-bit unsigned immediate. */
96ba4233
SL
355 switch (op->format)
356 {
357 case iw_i_type:
358 i = GET_IW_I_IMM16 (opcode);
359 break;
360 default:
361 bad_opcode (op);
362 }
36591ba1
SL
363 (*info->fprintf_func) (info->stream, "%ld", i);
364 break;
96ba4233 365
36591ba1
SL
366 case 'o':
367 /* 16-bit signed immediate address offset. */
96ba4233
SL
368 switch (op->format)
369 {
370 case iw_i_type:
371 i = (signed) (GET_IW_I_IMM16 (opcode) << 16) >> 16;
372 break;
373 default:
374 bad_opcode (op);
375 }
36591ba1
SL
376 address = address + 4 + i;
377 (*info->print_address_func) (address, info);
378 break;
96ba4233 379
36591ba1
SL
380 case 'j':
381 /* 5-bit unsigned immediate. */
96ba4233
SL
382 switch (op->format)
383 {
384 case iw_r_type:
385 i = GET_IW_R_IMM5 (opcode);
386 break;
387 default:
388 bad_opcode (op);
389 }
36591ba1
SL
390 (*info->fprintf_func) (info->stream, "%ld", i);
391 break;
96ba4233 392
36591ba1
SL
393 case 'l':
394 /* 8-bit unsigned immediate. */
96ba4233
SL
395 switch (op->format)
396 {
397 case iw_custom_type:
398 i = GET_IW_CUSTOM_N (opcode);
399 break;
400 default:
401 bad_opcode (op);
402 }
36591ba1
SL
403 (*info->fprintf_func) (info->stream, "%lu", i);
404 break;
96ba4233 405
36591ba1
SL
406 case 'm':
407 /* 26-bit unsigned immediate. */
96ba4233
SL
408 switch (op->format)
409 {
410 case iw_j_type:
411 i = GET_IW_J_IMM26 (opcode);
412 break;
413 default:
414 bad_opcode (op);
415 }
36591ba1
SL
416 /* This translates to an address because it's only used in call
417 instructions. */
418 address = (address & 0xf0000000) | (i << 2);
419 (*info->print_address_func) (address, info);
420 break;
96ba4233 421
36591ba1
SL
422 case 'c':
423 /* Control register index. */
96ba4233
SL
424 switch (op->format)
425 {
426 case iw_r_type:
427 i = GET_IW_R_IMM5 (opcode);
428 break;
429 default:
430 bad_opcode (op);
431 }
36591ba1
SL
432 reg_base = nios2_control_regs ();
433 (*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
434 break;
96ba4233 435
36591ba1
SL
436 default:
437 (*info->fprintf_func) (info->stream, "unknown");
438 break;
439 }
440 return 0;
441}
442
443/* nios2_disassemble does all the work of disassembling a Nios II
444 instruction opcode. */
445static int
446nios2_disassemble (bfd_vma address, unsigned long opcode,
447 disassemble_info *info)
448{
449 const struct nios2_opcode *op;
450
451 info->bytes_per_line = INSNLEN;
452 info->bytes_per_chunk = INSNLEN;
453 info->display_endian = info->endian;
454 info->insn_info_valid = 1;
455 info->branch_delay_insns = 0;
456 info->data_size = 0;
457 info->insn_type = dis_nonbranch;
458 info->target = 0;
459 info->target2 = 0;
460
461 /* Find the major opcode and use this to disassemble
462 the instruction and its arguments. */
b4714c7c 463 op = nios2_find_opcode_hash (opcode, info->mach);
36591ba1
SL
464
465 if (op != NULL)
466 {
96ba4233
SL
467 const char *argstr = op->args;
468 (*info->fprintf_func) (info->stream, "%s", op->name);
469 if (argstr != NULL && *argstr != '\0')
36591ba1 470 {
96ba4233
SL
471 (*info->fprintf_func) (info->stream, "\t");
472 while (*argstr != '\0')
36591ba1 473 {
96ba4233
SL
474 nios2_print_insn_arg (argstr, opcode, address, info, op);
475 ++argstr;
36591ba1
SL
476 }
477 }
96ba4233
SL
478 /* Tell the caller how far to advance the program counter. */
479 info->bytes_per_chunk = op->size;
480 return op->size;
36591ba1
SL
481 }
482 else
483 {
484 /* Handle undefined instructions. */
485 info->insn_type = dis_noninsn;
486 (*info->fprintf_func) (info->stream, "0x%lx", opcode);
96ba4233 487 return INSNLEN;
36591ba1 488 }
36591ba1
SL
489}
490
491
492/* print_insn_nios2 is the main disassemble function for Nios II.
493 The function diassembler(abfd) (source in disassemble.c) returns a
494 pointer to this either print_insn_big_nios2 or
495 print_insn_little_nios2, which in turn call this function when the
496 bfd machine type is Nios II. print_insn_nios2 reads the
497 instruction word at the address given, and prints the disassembled
498 instruction on the stream info->stream using info->fprintf_func. */
499
500static int
501print_insn_nios2 (bfd_vma address, disassemble_info *info,
502 enum bfd_endian endianness)
503{
504 bfd_byte buffer[INSNLEN];
505 int status;
506
507 status = (*info->read_memory_func) (address, buffer, INSNLEN, info);
508 if (status == 0)
509 {
510 unsigned long insn;
511 if (endianness == BFD_ENDIAN_BIG)
512 insn = (unsigned long) bfd_getb32 (buffer);
513 else
514 insn = (unsigned long) bfd_getl32 (buffer);
515 status = nios2_disassemble (address, insn, info);
516 }
517 else
518 {
519 (*info->memory_error_func) (status, address, info);
520 status = -1;
521 }
522 return status;
523}
524
525/* These two functions are the main entry points, accessed from
526 disassemble.c. */
527int
528print_insn_big_nios2 (bfd_vma address, disassemble_info *info)
529{
530 return print_insn_nios2 (address, info, BFD_ENDIAN_BIG);
531}
532
533int
534print_insn_little_nios2 (bfd_vma address, disassemble_info *info)
535{
536 return print_insn_nios2 (address, info, BFD_ENDIAN_LITTLE);
537}