175fd0b74Schristos /* Altera Nios II disassemble routines
2*e992f068Schristos Copyright (C) 2012-2022 Free Software Foundation, Inc.
375fd0b74Schristos Contributed by Nigel Gray (ngray@altera.com).
475fd0b74Schristos Contributed by Mentor Graphics, Inc.
575fd0b74Schristos
675fd0b74Schristos This file is part of the GNU opcodes library.
775fd0b74Schristos
875fd0b74Schristos This library is free software; you can redistribute it and/or modify
975fd0b74Schristos it under the terms of the GNU General Public License as published by
1075fd0b74Schristos the Free Software Foundation; either version 3, or (at your option)
1175fd0b74Schristos any later version.
1275fd0b74Schristos
1375fd0b74Schristos It is distributed in the hope that it will be useful, but WITHOUT
1475fd0b74Schristos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1575fd0b74Schristos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
1675fd0b74Schristos License for more details.
1775fd0b74Schristos
1875fd0b74Schristos You should have received a copy of the GNU General Public License
1975fd0b74Schristos along with this file; see the file COPYING. If not, write to the
2075fd0b74Schristos Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
2175fd0b74Schristos MA 02110-1301, USA. */
2275fd0b74Schristos
2375fd0b74Schristos #include "sysdep.h"
24ede78133Schristos #include "disassemble.h"
25ede78133Schristos #include "opintl.h"
2675fd0b74Schristos #include "opcode/nios2.h"
2775fd0b74Schristos #include "libiberty.h"
2875fd0b74Schristos #include <string.h>
2975fd0b74Schristos #include <assert.h>
3075fd0b74Schristos
3175fd0b74Schristos /* No symbol table is available when this code runs out in an embedded
3275fd0b74Schristos system as when it is used for disassembler support in a monitor. */
3375fd0b74Schristos #if !defined(EMBEDDED_ENV)
3475fd0b74Schristos #define SYMTAB_AVAILABLE 1
3575fd0b74Schristos #include "elf-bfd.h"
3675fd0b74Schristos #include "elf/nios2.h"
3775fd0b74Schristos #endif
3875fd0b74Schristos
3975fd0b74Schristos /* Default length of Nios II instruction in bytes. */
4075fd0b74Schristos #define INSNLEN 4
4175fd0b74Schristos
4275fd0b74Schristos /* Data structures used by the opcode hash table. */
4375fd0b74Schristos typedef struct _nios2_opcode_hash
4475fd0b74Schristos {
4575fd0b74Schristos const struct nios2_opcode *opcode;
4675fd0b74Schristos struct _nios2_opcode_hash *next;
4775fd0b74Schristos } nios2_opcode_hash;
4875fd0b74Schristos
4975fd0b74Schristos /* Hash table size. */
5075fd0b74Schristos #define OPCODE_HASH_SIZE (IW_R1_OP_UNSHIFTED_MASK + 1)
5175fd0b74Schristos
5275fd0b74Schristos /* Extract the opcode from an instruction word. */
5375fd0b74Schristos static unsigned int
nios2_r1_extract_opcode(unsigned int x)5475fd0b74Schristos nios2_r1_extract_opcode (unsigned int x)
5575fd0b74Schristos {
5675fd0b74Schristos return GET_IW_R1_OP (x);
5775fd0b74Schristos }
5875fd0b74Schristos
5975fd0b74Schristos static unsigned int
nios2_r2_extract_opcode(unsigned int x)6075fd0b74Schristos nios2_r2_extract_opcode (unsigned int x)
6175fd0b74Schristos {
6275fd0b74Schristos return GET_IW_R2_OP (x);
6375fd0b74Schristos }
6475fd0b74Schristos
6575fd0b74Schristos /* We maintain separate hash tables for R1 and R2 opcodes, and pseudo-ops
6675fd0b74Schristos are stored in a different table than regular instructions. */
6775fd0b74Schristos
6875fd0b74Schristos typedef struct _nios2_disassembler_state
6975fd0b74Schristos {
7075fd0b74Schristos const struct nios2_opcode *opcodes;
7175fd0b74Schristos const int *num_opcodes;
7275fd0b74Schristos unsigned int (*extract_opcode) (unsigned int);
7375fd0b74Schristos nios2_opcode_hash *hash[OPCODE_HASH_SIZE];
7475fd0b74Schristos nios2_opcode_hash *ps_hash[OPCODE_HASH_SIZE];
7575fd0b74Schristos const struct nios2_opcode *nop;
76*e992f068Schristos bool init;
7775fd0b74Schristos } nios2_disassembler_state;
7875fd0b74Schristos
7975fd0b74Schristos static nios2_disassembler_state
8075fd0b74Schristos nios2_r1_disassembler_state = {
8175fd0b74Schristos nios2_r1_opcodes,
8275fd0b74Schristos &nios2_num_r1_opcodes,
8375fd0b74Schristos nios2_r1_extract_opcode,
8475fd0b74Schristos {},
8575fd0b74Schristos {},
8675fd0b74Schristos NULL,
8775fd0b74Schristos 0
8875fd0b74Schristos };
8975fd0b74Schristos
9075fd0b74Schristos static nios2_disassembler_state
9175fd0b74Schristos nios2_r2_disassembler_state = {
9275fd0b74Schristos nios2_r2_opcodes,
9375fd0b74Schristos &nios2_num_r2_opcodes,
9475fd0b74Schristos nios2_r2_extract_opcode,
9575fd0b74Schristos {},
9675fd0b74Schristos {},
9775fd0b74Schristos NULL,
9875fd0b74Schristos 0
9975fd0b74Schristos };
10075fd0b74Schristos
10175fd0b74Schristos /* Function to initialize the opcode hash table. */
10275fd0b74Schristos static void
nios2_init_opcode_hash(nios2_disassembler_state * state)10375fd0b74Schristos nios2_init_opcode_hash (nios2_disassembler_state *state)
10475fd0b74Schristos {
10575fd0b74Schristos unsigned int i;
10675fd0b74Schristos register const struct nios2_opcode *op;
10775fd0b74Schristos
10875fd0b74Schristos for (i = 0; i < OPCODE_HASH_SIZE; i++)
10975fd0b74Schristos for (op = state->opcodes; op < &state->opcodes[*(state->num_opcodes)]; op++)
11075fd0b74Schristos {
11175fd0b74Schristos nios2_opcode_hash *new_hash;
11275fd0b74Schristos nios2_opcode_hash **bucket = NULL;
11375fd0b74Schristos
11475fd0b74Schristos if ((op->pinfo & NIOS2_INSN_MACRO) == NIOS2_INSN_MACRO)
11575fd0b74Schristos {
11675fd0b74Schristos if (i == state->extract_opcode (op->match)
11775fd0b74Schristos && (op->pinfo & (NIOS2_INSN_MACRO_MOV | NIOS2_INSN_MACRO_MOVI)
11875fd0b74Schristos & 0x7fffffff))
11975fd0b74Schristos {
12075fd0b74Schristos bucket = &(state->ps_hash[i]);
12175fd0b74Schristos if (strcmp (op->name, "nop") == 0)
12275fd0b74Schristos state->nop = op;
12375fd0b74Schristos }
12475fd0b74Schristos }
12575fd0b74Schristos else if (i == state->extract_opcode (op->match))
12675fd0b74Schristos bucket = &(state->hash[i]);
12775fd0b74Schristos
12875fd0b74Schristos if (bucket)
12975fd0b74Schristos {
13075fd0b74Schristos new_hash =
13175fd0b74Schristos (nios2_opcode_hash *) malloc (sizeof (nios2_opcode_hash));
13275fd0b74Schristos if (new_hash == NULL)
13375fd0b74Schristos {
134ede78133Schristos /* xgettext:c-format */
135ede78133Schristos opcodes_error_handler (_("out of memory"));
136ede78133Schristos exit (1);
13775fd0b74Schristos }
13875fd0b74Schristos new_hash->opcode = op;
13975fd0b74Schristos new_hash->next = NULL;
14075fd0b74Schristos while (*bucket)
14175fd0b74Schristos bucket = &((*bucket)->next);
14275fd0b74Schristos *bucket = new_hash;
14375fd0b74Schristos }
14475fd0b74Schristos }
14575fd0b74Schristos state->init = 1;
14675fd0b74Schristos
14775fd0b74Schristos #ifdef DEBUG_HASHTABLE
14875fd0b74Schristos for (i = 0; i < OPCODE_HASH_SIZE; ++i)
14975fd0b74Schristos {
15075fd0b74Schristos nios2_opcode_hash *tmp_hash = state->hash[i];
15175fd0b74Schristos printf ("index: 0x%02X ops: ", i);
15275fd0b74Schristos while (tmp_hash != NULL)
15375fd0b74Schristos {
15475fd0b74Schristos printf ("%s ", tmp_hash->opcode->name);
15575fd0b74Schristos tmp_hash = tmp_hash->next;
15675fd0b74Schristos }
15775fd0b74Schristos printf ("\n");
15875fd0b74Schristos }
15975fd0b74Schristos
16075fd0b74Schristos for (i = 0; i < OPCODE_HASH_SIZE; ++i)
16175fd0b74Schristos {
16275fd0b74Schristos nios2_opcode_hash *tmp_hash = state->ps_hash[i];
16375fd0b74Schristos printf ("index: 0x%02X ops: ", i);
16475fd0b74Schristos while (tmp_hash != NULL)
16575fd0b74Schristos {
16675fd0b74Schristos printf ("%s ", tmp_hash->opcode->name);
16775fd0b74Schristos tmp_hash = tmp_hash->next;
16875fd0b74Schristos }
16975fd0b74Schristos printf ("\n");
17075fd0b74Schristos }
17175fd0b74Schristos #endif /* DEBUG_HASHTABLE */
17275fd0b74Schristos }
17375fd0b74Schristos
17475fd0b74Schristos /* Return a pointer to an nios2_opcode struct for a given instruction
17575fd0b74Schristos word OPCODE for bfd machine MACH, or NULL if there is an error. */
17675fd0b74Schristos const struct nios2_opcode *
nios2_find_opcode_hash(unsigned long opcode,unsigned long mach)17775fd0b74Schristos nios2_find_opcode_hash (unsigned long opcode, unsigned long mach)
17875fd0b74Schristos {
17975fd0b74Schristos nios2_opcode_hash *entry;
18075fd0b74Schristos nios2_disassembler_state *state;
18175fd0b74Schristos
18275fd0b74Schristos /* Select the right instruction set, hash tables, and opcode accessor
18375fd0b74Schristos for the mach variant. */
18475fd0b74Schristos if (mach == bfd_mach_nios2r2)
18575fd0b74Schristos state = &nios2_r2_disassembler_state;
18675fd0b74Schristos else
18775fd0b74Schristos state = &nios2_r1_disassembler_state;
18875fd0b74Schristos
18975fd0b74Schristos /* Build a hash table to shorten the search time. */
19075fd0b74Schristos if (!state->init)
19175fd0b74Schristos nios2_init_opcode_hash (state);
19275fd0b74Schristos
19375fd0b74Schristos /* Check for NOP first. Both NOP and MOV are macros that expand into
19475fd0b74Schristos an ADD instruction, and we always want to give priority to NOP. */
19575fd0b74Schristos if (state->nop->match == (opcode & state->nop->mask))
19675fd0b74Schristos return state->nop;
19775fd0b74Schristos
19875fd0b74Schristos /* First look in the pseudo-op hashtable. */
19975fd0b74Schristos for (entry = state->ps_hash[state->extract_opcode (opcode)];
20075fd0b74Schristos entry; entry = entry->next)
20175fd0b74Schristos if (entry->opcode->match == (opcode & entry->opcode->mask))
20275fd0b74Schristos return entry->opcode;
20375fd0b74Schristos
20475fd0b74Schristos /* Otherwise look in the main hashtable. */
20575fd0b74Schristos for (entry = state->hash[state->extract_opcode (opcode)];
20675fd0b74Schristos entry; entry = entry->next)
20775fd0b74Schristos if (entry->opcode->match == (opcode & entry->opcode->mask))
20875fd0b74Schristos return entry->opcode;
20975fd0b74Schristos
21075fd0b74Schristos return NULL;
21175fd0b74Schristos }
21275fd0b74Schristos
21375fd0b74Schristos /* There are 32 regular registers, 32 coprocessor registers,
21475fd0b74Schristos and 32 control registers. */
21575fd0b74Schristos #define NUMREGNAMES 32
21675fd0b74Schristos
21775fd0b74Schristos /* Return a pointer to the base of the coprocessor register name array. */
21875fd0b74Schristos static struct nios2_reg *
nios2_coprocessor_regs(void)21975fd0b74Schristos nios2_coprocessor_regs (void)
22075fd0b74Schristos {
22175fd0b74Schristos static struct nios2_reg *cached = NULL;
22275fd0b74Schristos
22375fd0b74Schristos if (!cached)
22475fd0b74Schristos {
22575fd0b74Schristos int i;
22675fd0b74Schristos for (i = NUMREGNAMES; i < nios2_num_regs; i++)
22775fd0b74Schristos if (!strcmp (nios2_regs[i].name, "c0"))
22875fd0b74Schristos {
22975fd0b74Schristos cached = nios2_regs + i;
23075fd0b74Schristos break;
23175fd0b74Schristos }
23275fd0b74Schristos assert (cached);
23375fd0b74Schristos }
23475fd0b74Schristos return cached;
23575fd0b74Schristos }
23675fd0b74Schristos
23775fd0b74Schristos /* Return a pointer to the base of the control register name array. */
23875fd0b74Schristos static struct nios2_reg *
nios2_control_regs(void)23975fd0b74Schristos nios2_control_regs (void)
24075fd0b74Schristos {
24175fd0b74Schristos static struct nios2_reg *cached = NULL;
24275fd0b74Schristos
24375fd0b74Schristos if (!cached)
24475fd0b74Schristos {
24575fd0b74Schristos int i;
24675fd0b74Schristos for (i = NUMREGNAMES; i < nios2_num_regs; i++)
24775fd0b74Schristos if (!strcmp (nios2_regs[i].name, "status"))
24875fd0b74Schristos {
24975fd0b74Schristos cached = nios2_regs + i;
25075fd0b74Schristos break;
25175fd0b74Schristos }
25275fd0b74Schristos assert (cached);
25375fd0b74Schristos }
25475fd0b74Schristos return cached;
25575fd0b74Schristos }
25675fd0b74Schristos
25775fd0b74Schristos /* Helper routine to report internal errors. */
25875fd0b74Schristos static void
bad_opcode(const struct nios2_opcode * op)25975fd0b74Schristos bad_opcode (const struct nios2_opcode *op)
26075fd0b74Schristos {
261ede78133Schristos opcodes_error_handler
262ede78133Schristos /* xgettext:c-format */
263ede78133Schristos (_("internal error: broken opcode descriptor for `%s %s'"),
26475fd0b74Schristos op->name, op->args);
26575fd0b74Schristos abort ();
26675fd0b74Schristos }
26775fd0b74Schristos
26875fd0b74Schristos /* The function nios2_print_insn_arg uses the character pointed
26975fd0b74Schristos to by ARGPTR to determine how it print the next token or separator
27075fd0b74Schristos character in the arguments to an instruction. */
27175fd0b74Schristos static int
nios2_print_insn_arg(const char * argptr,unsigned long opcode,bfd_vma address,disassemble_info * info,const struct nios2_opcode * op)27275fd0b74Schristos nios2_print_insn_arg (const char *argptr,
27375fd0b74Schristos unsigned long opcode, bfd_vma address,
27475fd0b74Schristos disassemble_info *info,
27575fd0b74Schristos const struct nios2_opcode *op)
27675fd0b74Schristos {
27775fd0b74Schristos unsigned long i = 0;
278012573ebSchristos long s = 0;
279*e992f068Schristos int32_t o = 0;
28075fd0b74Schristos struct nios2_reg *reg_base;
28175fd0b74Schristos
28275fd0b74Schristos switch (*argptr)
28375fd0b74Schristos {
28475fd0b74Schristos case ',':
28575fd0b74Schristos case '(':
28675fd0b74Schristos case ')':
28775fd0b74Schristos (*info->fprintf_func) (info->stream, "%c", *argptr);
28875fd0b74Schristos break;
28975fd0b74Schristos
29075fd0b74Schristos case 'c':
29175fd0b74Schristos /* Control register index. */
29275fd0b74Schristos switch (op->format)
29375fd0b74Schristos {
29475fd0b74Schristos case iw_r_type:
29575fd0b74Schristos i = GET_IW_R_IMM5 (opcode);
29675fd0b74Schristos break;
29775fd0b74Schristos case iw_F3X6L5_type:
29875fd0b74Schristos i = GET_IW_F3X6L5_IMM5 (opcode);
29975fd0b74Schristos break;
30075fd0b74Schristos default:
30175fd0b74Schristos bad_opcode (op);
30275fd0b74Schristos }
30375fd0b74Schristos reg_base = nios2_control_regs ();
30475fd0b74Schristos (*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
30575fd0b74Schristos break;
30675fd0b74Schristos
30775fd0b74Schristos case 'd':
30875fd0b74Schristos reg_base = nios2_regs;
30975fd0b74Schristos switch (op->format)
31075fd0b74Schristos {
31175fd0b74Schristos case iw_r_type:
31275fd0b74Schristos i = GET_IW_R_C (opcode);
31375fd0b74Schristos break;
31475fd0b74Schristos case iw_custom_type:
31575fd0b74Schristos i = GET_IW_CUSTOM_C (opcode);
31675fd0b74Schristos if (GET_IW_CUSTOM_READC (opcode) == 0)
31775fd0b74Schristos reg_base = nios2_coprocessor_regs ();
31875fd0b74Schristos break;
31975fd0b74Schristos case iw_F3X6L5_type:
32075fd0b74Schristos case iw_F3X6_type:
32175fd0b74Schristos i = GET_IW_F3X6L5_C (opcode);
32275fd0b74Schristos break;
32375fd0b74Schristos case iw_F3X8_type:
32475fd0b74Schristos i = GET_IW_F3X8_C (opcode);
32575fd0b74Schristos if (GET_IW_F3X8_READC (opcode) == 0)
32675fd0b74Schristos reg_base = nios2_coprocessor_regs ();
32775fd0b74Schristos break;
32875fd0b74Schristos case iw_F2_type:
32975fd0b74Schristos i = GET_IW_F2_B (opcode);
33075fd0b74Schristos break;
33175fd0b74Schristos default:
33275fd0b74Schristos bad_opcode (op);
33375fd0b74Schristos }
33475fd0b74Schristos if (i < NUMREGNAMES)
33575fd0b74Schristos (*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
33675fd0b74Schristos else
33775fd0b74Schristos (*info->fprintf_func) (info->stream, "unknown");
33875fd0b74Schristos break;
33975fd0b74Schristos
34075fd0b74Schristos case 's':
34175fd0b74Schristos reg_base = nios2_regs;
34275fd0b74Schristos switch (op->format)
34375fd0b74Schristos {
34475fd0b74Schristos case iw_r_type:
34575fd0b74Schristos i = GET_IW_R_A (opcode);
34675fd0b74Schristos break;
34775fd0b74Schristos case iw_i_type:
34875fd0b74Schristos i = GET_IW_I_A (opcode);
34975fd0b74Schristos break;
35075fd0b74Schristos case iw_custom_type:
35175fd0b74Schristos i = GET_IW_CUSTOM_A (opcode);
35275fd0b74Schristos if (GET_IW_CUSTOM_READA (opcode) == 0)
35375fd0b74Schristos reg_base = nios2_coprocessor_regs ();
35475fd0b74Schristos break;
35575fd0b74Schristos case iw_F2I16_type:
35675fd0b74Schristos i = GET_IW_F2I16_A (opcode);
35775fd0b74Schristos break;
35875fd0b74Schristos case iw_F2X4I12_type:
35975fd0b74Schristos i = GET_IW_F2X4I12_A (opcode);
36075fd0b74Schristos break;
36175fd0b74Schristos case iw_F1X4I12_type:
36275fd0b74Schristos i = GET_IW_F1X4I12_A (opcode);
36375fd0b74Schristos break;
36475fd0b74Schristos case iw_F1X4L17_type:
36575fd0b74Schristos i = GET_IW_F1X4L17_A (opcode);
36675fd0b74Schristos break;
36775fd0b74Schristos case iw_F3X6L5_type:
36875fd0b74Schristos case iw_F3X6_type:
36975fd0b74Schristos i = GET_IW_F3X6L5_A (opcode);
37075fd0b74Schristos break;
37175fd0b74Schristos case iw_F2X6L10_type:
37275fd0b74Schristos i = GET_IW_F2X6L10_A (opcode);
37375fd0b74Schristos break;
37475fd0b74Schristos case iw_F3X8_type:
37575fd0b74Schristos i = GET_IW_F3X8_A (opcode);
37675fd0b74Schristos if (GET_IW_F3X8_READA (opcode) == 0)
37775fd0b74Schristos reg_base = nios2_coprocessor_regs ();
37875fd0b74Schristos break;
37975fd0b74Schristos case iw_F1X1_type:
38075fd0b74Schristos i = GET_IW_F1X1_A (opcode);
38175fd0b74Schristos break;
38275fd0b74Schristos case iw_F1I5_type:
38375fd0b74Schristos i = 27; /* Implicit stack pointer reference. */
38475fd0b74Schristos break;
38575fd0b74Schristos case iw_F2_type:
38675fd0b74Schristos i = GET_IW_F2_A (opcode);
38775fd0b74Schristos break;
38875fd0b74Schristos default:
38975fd0b74Schristos bad_opcode (op);
39075fd0b74Schristos }
39175fd0b74Schristos if (i < NUMREGNAMES)
39275fd0b74Schristos (*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
39375fd0b74Schristos else
39475fd0b74Schristos (*info->fprintf_func) (info->stream, "unknown");
39575fd0b74Schristos break;
39675fd0b74Schristos
39775fd0b74Schristos case 't':
39875fd0b74Schristos reg_base = nios2_regs;
39975fd0b74Schristos switch (op->format)
40075fd0b74Schristos {
40175fd0b74Schristos case iw_r_type:
40275fd0b74Schristos i = GET_IW_R_B (opcode);
40375fd0b74Schristos break;
40475fd0b74Schristos case iw_i_type:
40575fd0b74Schristos i = GET_IW_I_B (opcode);
40675fd0b74Schristos break;
40775fd0b74Schristos case iw_custom_type:
40875fd0b74Schristos i = GET_IW_CUSTOM_B (opcode);
40975fd0b74Schristos if (GET_IW_CUSTOM_READB (opcode) == 0)
41075fd0b74Schristos reg_base = nios2_coprocessor_regs ();
41175fd0b74Schristos break;
41275fd0b74Schristos case iw_F2I16_type:
41375fd0b74Schristos i = GET_IW_F2I16_B (opcode);
41475fd0b74Schristos break;
41575fd0b74Schristos case iw_F2X4I12_type:
41675fd0b74Schristos i = GET_IW_F2X4I12_B (opcode);
41775fd0b74Schristos break;
41875fd0b74Schristos case iw_F3X6L5_type:
41975fd0b74Schristos case iw_F3X6_type:
42075fd0b74Schristos i = GET_IW_F3X6L5_B (opcode);
42175fd0b74Schristos break;
42275fd0b74Schristos case iw_F2X6L10_type:
42375fd0b74Schristos i = GET_IW_F2X6L10_B (opcode);
42475fd0b74Schristos break;
42575fd0b74Schristos case iw_F3X8_type:
42675fd0b74Schristos i = GET_IW_F3X8_B (opcode);
42775fd0b74Schristos if (GET_IW_F3X8_READB (opcode) == 0)
42875fd0b74Schristos reg_base = nios2_coprocessor_regs ();
42975fd0b74Schristos break;
43075fd0b74Schristos case iw_F1I5_type:
43175fd0b74Schristos i = GET_IW_F1I5_B (opcode);
43275fd0b74Schristos break;
43375fd0b74Schristos case iw_F2_type:
43475fd0b74Schristos i = GET_IW_F2_B (opcode);
43575fd0b74Schristos break;
43675fd0b74Schristos case iw_T1X1I6_type:
43775fd0b74Schristos i = 0;
43875fd0b74Schristos break;
43975fd0b74Schristos default:
44075fd0b74Schristos bad_opcode (op);
44175fd0b74Schristos }
44275fd0b74Schristos if (i < NUMREGNAMES)
44375fd0b74Schristos (*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
44475fd0b74Schristos else
44575fd0b74Schristos (*info->fprintf_func) (info->stream, "unknown");
44675fd0b74Schristos break;
44775fd0b74Schristos
44875fd0b74Schristos case 'D':
44975fd0b74Schristos switch (op->format)
45075fd0b74Schristos {
45175fd0b74Schristos case iw_T1I7_type:
45275fd0b74Schristos i = GET_IW_T1I7_A3 (opcode);
45375fd0b74Schristos break;
45475fd0b74Schristos case iw_T2X1L3_type:
45575fd0b74Schristos i = GET_IW_T2X1L3_B3 (opcode);
45675fd0b74Schristos break;
45775fd0b74Schristos case iw_T2X1I3_type:
45875fd0b74Schristos i = GET_IW_T2X1I3_B3 (opcode);
45975fd0b74Schristos break;
46075fd0b74Schristos case iw_T3X1_type:
46175fd0b74Schristos i = GET_IW_T3X1_C3 (opcode);
46275fd0b74Schristos break;
46375fd0b74Schristos case iw_T2X3_type:
46475fd0b74Schristos if (op->num_args == 3)
46575fd0b74Schristos i = GET_IW_T2X3_A3 (opcode);
46675fd0b74Schristos else
46775fd0b74Schristos i = GET_IW_T2X3_B3 (opcode);
46875fd0b74Schristos break;
46975fd0b74Schristos default:
47075fd0b74Schristos bad_opcode (op);
47175fd0b74Schristos }
47275fd0b74Schristos i = nios2_r2_reg3_mappings[i];
47375fd0b74Schristos (*info->fprintf_func) (info->stream, "%s", nios2_regs[i].name);
47475fd0b74Schristos break;
47575fd0b74Schristos
47675fd0b74Schristos case 'M':
47775fd0b74Schristos /* 6-bit unsigned immediate with no shift. */
47875fd0b74Schristos switch (op->format)
47975fd0b74Schristos {
48075fd0b74Schristos case iw_T1X1I6_type:
48175fd0b74Schristos i = GET_IW_T1X1I6_IMM6 (opcode);
48275fd0b74Schristos break;
48375fd0b74Schristos default:
48475fd0b74Schristos bad_opcode (op);
48575fd0b74Schristos }
48675fd0b74Schristos (*info->fprintf_func) (info->stream, "%ld", i);
48775fd0b74Schristos break;
48875fd0b74Schristos
48975fd0b74Schristos case 'N':
49075fd0b74Schristos /* 6-bit unsigned immediate with 2-bit shift. */
49175fd0b74Schristos switch (op->format)
49275fd0b74Schristos {
49375fd0b74Schristos case iw_T1X1I6_type:
49475fd0b74Schristos i = GET_IW_T1X1I6_IMM6 (opcode) << 2;
49575fd0b74Schristos break;
49675fd0b74Schristos default:
49775fd0b74Schristos bad_opcode (op);
49875fd0b74Schristos }
49975fd0b74Schristos (*info->fprintf_func) (info->stream, "%ld", i);
50075fd0b74Schristos break;
50175fd0b74Schristos
50275fd0b74Schristos case 'S':
50375fd0b74Schristos switch (op->format)
50475fd0b74Schristos {
50575fd0b74Schristos case iw_T1I7_type:
50675fd0b74Schristos i = GET_IW_T1I7_A3 (opcode);
50775fd0b74Schristos break;
50875fd0b74Schristos case iw_T2I4_type:
50975fd0b74Schristos i = GET_IW_T2I4_A3 (opcode);
51075fd0b74Schristos break;
51175fd0b74Schristos case iw_T2X1L3_type:
51275fd0b74Schristos i = GET_IW_T2X1L3_A3 (opcode);
51375fd0b74Schristos break;
51475fd0b74Schristos case iw_T2X1I3_type:
51575fd0b74Schristos i = GET_IW_T2X1I3_A3 (opcode);
51675fd0b74Schristos break;
51775fd0b74Schristos case iw_T3X1_type:
51875fd0b74Schristos i = GET_IW_T3X1_A3 (opcode);
51975fd0b74Schristos break;
52075fd0b74Schristos case iw_T2X3_type:
52175fd0b74Schristos i = GET_IW_T2X3_A3 (opcode);
52275fd0b74Schristos break;
52375fd0b74Schristos case iw_T1X1I6_type:
52475fd0b74Schristos i = GET_IW_T1X1I6_A3 (opcode);
52575fd0b74Schristos break;
52675fd0b74Schristos default:
52775fd0b74Schristos bad_opcode (op);
52875fd0b74Schristos }
52975fd0b74Schristos i = nios2_r2_reg3_mappings[i];
53075fd0b74Schristos (*info->fprintf_func) (info->stream, "%s", nios2_regs[i].name);
53175fd0b74Schristos break;
53275fd0b74Schristos
53375fd0b74Schristos case 'T':
53475fd0b74Schristos switch (op->format)
53575fd0b74Schristos {
53675fd0b74Schristos case iw_T2I4_type:
53775fd0b74Schristos i = GET_IW_T2I4_B3 (opcode);
53875fd0b74Schristos break;
53975fd0b74Schristos case iw_T3X1_type:
54075fd0b74Schristos i = GET_IW_T3X1_B3 (opcode);
54175fd0b74Schristos break;
54275fd0b74Schristos case iw_T2X3_type:
54375fd0b74Schristos i = GET_IW_T2X3_B3 (opcode);
54475fd0b74Schristos break;
54575fd0b74Schristos default:
54675fd0b74Schristos bad_opcode (op);
54775fd0b74Schristos }
54875fd0b74Schristos i = nios2_r2_reg3_mappings[i];
54975fd0b74Schristos (*info->fprintf_func) (info->stream, "%s", nios2_regs[i].name);
55075fd0b74Schristos break;
55175fd0b74Schristos
55275fd0b74Schristos case 'i':
55375fd0b74Schristos /* 16-bit signed immediate. */
55475fd0b74Schristos switch (op->format)
55575fd0b74Schristos {
55675fd0b74Schristos case iw_i_type:
557*e992f068Schristos s = ((int32_t) ((GET_IW_I_IMM16 (opcode) & 0xffff) ^ 0x8000)
558*e992f068Schristos - 0x8000);
55975fd0b74Schristos break;
56075fd0b74Schristos case iw_F2I16_type:
561*e992f068Schristos s = ((int32_t) ((GET_IW_F2I16_IMM16 (opcode) & 0xffff) ^ 0x8000)
562*e992f068Schristos - 0x8000);
56375fd0b74Schristos break;
56475fd0b74Schristos default:
56575fd0b74Schristos bad_opcode (op);
56675fd0b74Schristos }
567012573ebSchristos (*info->fprintf_func) (info->stream, "%ld", s);
56875fd0b74Schristos break;
56975fd0b74Schristos
57075fd0b74Schristos case 'I':
57175fd0b74Schristos /* 12-bit signed immediate. */
57275fd0b74Schristos switch (op->format)
57375fd0b74Schristos {
57475fd0b74Schristos case iw_F2X4I12_type:
575*e992f068Schristos s = ((int32_t) ((GET_IW_F2X4I12_IMM12 (opcode) & 0xfff) ^ 0x800)
576*e992f068Schristos - 0x800);
57775fd0b74Schristos break;
57875fd0b74Schristos case iw_F1X4I12_type:
579*e992f068Schristos s = ((int32_t) ((GET_IW_F1X4I12_IMM12 (opcode) & 0xfff) ^ 0x800)
580*e992f068Schristos - 0x800);
58175fd0b74Schristos break;
58275fd0b74Schristos default:
58375fd0b74Schristos bad_opcode (op);
58475fd0b74Schristos }
585012573ebSchristos (*info->fprintf_func) (info->stream, "%ld", s);
58675fd0b74Schristos break;
58775fd0b74Schristos
58875fd0b74Schristos case 'u':
58975fd0b74Schristos /* 16-bit unsigned immediate. */
59075fd0b74Schristos switch (op->format)
59175fd0b74Schristos {
59275fd0b74Schristos case iw_i_type:
59375fd0b74Schristos i = GET_IW_I_IMM16 (opcode);
59475fd0b74Schristos break;
59575fd0b74Schristos case iw_F2I16_type:
59675fd0b74Schristos i = GET_IW_F2I16_IMM16 (opcode);
59775fd0b74Schristos break;
59875fd0b74Schristos default:
59975fd0b74Schristos bad_opcode (op);
60075fd0b74Schristos }
60175fd0b74Schristos (*info->fprintf_func) (info->stream, "%ld", i);
60275fd0b74Schristos break;
60375fd0b74Schristos
60475fd0b74Schristos case 'U':
60575fd0b74Schristos /* 7-bit unsigned immediate with 2-bit shift. */
60675fd0b74Schristos switch (op->format)
60775fd0b74Schristos {
60875fd0b74Schristos case iw_T1I7_type:
60975fd0b74Schristos i = GET_IW_T1I7_IMM7 (opcode) << 2;
61075fd0b74Schristos break;
61175fd0b74Schristos case iw_X1I7_type:
61275fd0b74Schristos i = GET_IW_X1I7_IMM7 (opcode) << 2;
61375fd0b74Schristos break;
61475fd0b74Schristos default:
61575fd0b74Schristos bad_opcode (op);
61675fd0b74Schristos }
61775fd0b74Schristos (*info->fprintf_func) (info->stream, "%ld", i);
61875fd0b74Schristos break;
61975fd0b74Schristos
62075fd0b74Schristos case 'V':
62175fd0b74Schristos /* 5-bit unsigned immediate with 2-bit shift. */
62275fd0b74Schristos switch (op->format)
62375fd0b74Schristos {
62475fd0b74Schristos case iw_F1I5_type:
62575fd0b74Schristos i = GET_IW_F1I5_IMM5 (opcode) << 2;
62675fd0b74Schristos break;
62775fd0b74Schristos default:
62875fd0b74Schristos bad_opcode (op);
62975fd0b74Schristos }
63075fd0b74Schristos (*info->fprintf_func) (info->stream, "%ld", i);
63175fd0b74Schristos break;
63275fd0b74Schristos
63375fd0b74Schristos case 'W':
63475fd0b74Schristos /* 4-bit unsigned immediate with 2-bit shift. */
63575fd0b74Schristos switch (op->format)
63675fd0b74Schristos {
63775fd0b74Schristos case iw_T2I4_type:
63875fd0b74Schristos i = GET_IW_T2I4_IMM4 (opcode) << 2;
63975fd0b74Schristos break;
64075fd0b74Schristos case iw_L5I4X1_type:
64175fd0b74Schristos i = GET_IW_L5I4X1_IMM4 (opcode) << 2;
64275fd0b74Schristos break;
64375fd0b74Schristos default:
64475fd0b74Schristos bad_opcode (op);
64575fd0b74Schristos }
64675fd0b74Schristos (*info->fprintf_func) (info->stream, "%ld", i);
64775fd0b74Schristos break;
64875fd0b74Schristos
64975fd0b74Schristos case 'X':
65075fd0b74Schristos /* 4-bit unsigned immediate with 1-bit shift. */
65175fd0b74Schristos switch (op->format)
65275fd0b74Schristos {
65375fd0b74Schristos case iw_T2I4_type:
65475fd0b74Schristos i = GET_IW_T2I4_IMM4 (opcode) << 1;
65575fd0b74Schristos break;
65675fd0b74Schristos default:
65775fd0b74Schristos bad_opcode (op);
65875fd0b74Schristos }
65975fd0b74Schristos (*info->fprintf_func) (info->stream, "%ld", i);
66075fd0b74Schristos break;
66175fd0b74Schristos
66275fd0b74Schristos case 'Y':
66375fd0b74Schristos /* 4-bit unsigned immediate without shift. */
66475fd0b74Schristos switch (op->format)
66575fd0b74Schristos {
66675fd0b74Schristos case iw_T2I4_type:
66775fd0b74Schristos i = GET_IW_T2I4_IMM4 (opcode);
66875fd0b74Schristos break;
66975fd0b74Schristos default:
67075fd0b74Schristos bad_opcode (op);
67175fd0b74Schristos }
67275fd0b74Schristos (*info->fprintf_func) (info->stream, "%ld", i);
67375fd0b74Schristos break;
67475fd0b74Schristos
67575fd0b74Schristos case 'o':
67675fd0b74Schristos /* 16-bit signed immediate address offset. */
67775fd0b74Schristos switch (op->format)
67875fd0b74Schristos {
67975fd0b74Schristos case iw_i_type:
680012573ebSchristos o = ((GET_IW_I_IMM16 (opcode) & 0xffff) ^ 0x8000) - 0x8000;
68175fd0b74Schristos break;
68275fd0b74Schristos case iw_F2I16_type:
683012573ebSchristos o = ((GET_IW_F2I16_IMM16 (opcode) & 0xffff) ^ 0x8000) - 0x8000;
68475fd0b74Schristos break;
68575fd0b74Schristos default:
68675fd0b74Schristos bad_opcode (op);
68775fd0b74Schristos }
688012573ebSchristos address = address + 4 + o;
68975fd0b74Schristos (*info->print_address_func) (address, info);
69075fd0b74Schristos break;
69175fd0b74Schristos
69275fd0b74Schristos case 'O':
69375fd0b74Schristos /* 10-bit signed address offset with 1-bit shift. */
69475fd0b74Schristos switch (op->format)
69575fd0b74Schristos {
69675fd0b74Schristos case iw_I10_type:
697*e992f068Schristos o = (((GET_IW_I10_IMM10 (opcode) & 0x3ff) ^ 0x200) - 0x200) * 2;
69875fd0b74Schristos break;
69975fd0b74Schristos default:
70075fd0b74Schristos bad_opcode (op);
70175fd0b74Schristos }
702012573ebSchristos address = address + 2 + o;
70375fd0b74Schristos (*info->print_address_func) (address, info);
70475fd0b74Schristos break;
70575fd0b74Schristos
70675fd0b74Schristos case 'P':
70775fd0b74Schristos /* 7-bit signed address offset with 1-bit shift. */
70875fd0b74Schristos switch (op->format)
70975fd0b74Schristos {
71075fd0b74Schristos case iw_T1I7_type:
711*e992f068Schristos o = (((GET_IW_T1I7_IMM7 (opcode) & 0x7f) ^ 0x40) - 0x40) * 2;
71275fd0b74Schristos break;
71375fd0b74Schristos default:
71475fd0b74Schristos bad_opcode (op);
71575fd0b74Schristos }
716012573ebSchristos address = address + 2 + o;
71775fd0b74Schristos (*info->print_address_func) (address, info);
71875fd0b74Schristos break;
71975fd0b74Schristos
72075fd0b74Schristos case 'j':
72175fd0b74Schristos /* 5-bit unsigned immediate. */
72275fd0b74Schristos switch (op->format)
72375fd0b74Schristos {
72475fd0b74Schristos case iw_r_type:
72575fd0b74Schristos i = GET_IW_R_IMM5 (opcode);
72675fd0b74Schristos break;
72775fd0b74Schristos case iw_F3X6L5_type:
72875fd0b74Schristos i = GET_IW_F3X6L5_IMM5 (opcode);
72975fd0b74Schristos break;
73075fd0b74Schristos case iw_F2X6L10_type:
73175fd0b74Schristos i = GET_IW_F2X6L10_MSB (opcode);
73275fd0b74Schristos break;
73375fd0b74Schristos case iw_X2L5_type:
73475fd0b74Schristos i = GET_IW_X2L5_IMM5 (opcode);
73575fd0b74Schristos break;
73675fd0b74Schristos default:
73775fd0b74Schristos bad_opcode (op);
73875fd0b74Schristos }
73975fd0b74Schristos (*info->fprintf_func) (info->stream, "%ld", i);
74075fd0b74Schristos break;
74175fd0b74Schristos
74275fd0b74Schristos case 'k':
74375fd0b74Schristos /* Second 5-bit unsigned immediate field. */
74475fd0b74Schristos switch (op->format)
74575fd0b74Schristos {
74675fd0b74Schristos case iw_F2X6L10_type:
74775fd0b74Schristos i = GET_IW_F2X6L10_LSB (opcode);
74875fd0b74Schristos break;
74975fd0b74Schristos default:
75075fd0b74Schristos bad_opcode (op);
75175fd0b74Schristos }
75275fd0b74Schristos (*info->fprintf_func) (info->stream, "%ld", i);
75375fd0b74Schristos break;
75475fd0b74Schristos
75575fd0b74Schristos case 'l':
75675fd0b74Schristos /* 8-bit unsigned immediate. */
75775fd0b74Schristos switch (op->format)
75875fd0b74Schristos {
75975fd0b74Schristos case iw_custom_type:
76075fd0b74Schristos i = GET_IW_CUSTOM_N (opcode);
76175fd0b74Schristos break;
76275fd0b74Schristos case iw_F3X8_type:
76375fd0b74Schristos i = GET_IW_F3X8_N (opcode);
76475fd0b74Schristos break;
76575fd0b74Schristos default:
76675fd0b74Schristos bad_opcode (op);
76775fd0b74Schristos }
76875fd0b74Schristos (*info->fprintf_func) (info->stream, "%lu", i);
76975fd0b74Schristos break;
77075fd0b74Schristos
77175fd0b74Schristos case 'm':
77275fd0b74Schristos /* 26-bit unsigned immediate. */
77375fd0b74Schristos switch (op->format)
77475fd0b74Schristos {
77575fd0b74Schristos case iw_j_type:
77675fd0b74Schristos i = GET_IW_J_IMM26 (opcode);
77775fd0b74Schristos break;
77875fd0b74Schristos case iw_L26_type:
77975fd0b74Schristos i = GET_IW_L26_IMM26 (opcode);
78075fd0b74Schristos break;
78175fd0b74Schristos default:
78275fd0b74Schristos bad_opcode (op);
78375fd0b74Schristos }
78475fd0b74Schristos /* This translates to an address because it's only used in call
78575fd0b74Schristos instructions. */
78675fd0b74Schristos address = (address & 0xf0000000) | (i << 2);
78775fd0b74Schristos (*info->print_address_func) (address, info);
78875fd0b74Schristos break;
78975fd0b74Schristos
79075fd0b74Schristos case 'e':
79175fd0b74Schristos /* Encoded enumeration for addi.n/subi.n. */
79275fd0b74Schristos switch (op->format)
79375fd0b74Schristos {
79475fd0b74Schristos case iw_T2X1I3_type:
79575fd0b74Schristos i = nios2_r2_asi_n_mappings[GET_IW_T2X1I3_IMM3 (opcode)];
79675fd0b74Schristos break;
79775fd0b74Schristos default:
79875fd0b74Schristos bad_opcode (op);
79975fd0b74Schristos }
80075fd0b74Schristos (*info->fprintf_func) (info->stream, "%lu", i);
80175fd0b74Schristos break;
80275fd0b74Schristos
80375fd0b74Schristos case 'f':
80475fd0b74Schristos /* Encoded enumeration for slli.n/srli.n. */
80575fd0b74Schristos switch (op->format)
80675fd0b74Schristos {
80775fd0b74Schristos case iw_T2X1L3_type:
80875fd0b74Schristos i = nios2_r2_shi_n_mappings[GET_IW_T2X1I3_IMM3 (opcode)];
80975fd0b74Schristos break;
81075fd0b74Schristos default:
81175fd0b74Schristos bad_opcode (op);
81275fd0b74Schristos }
81375fd0b74Schristos (*info->fprintf_func) (info->stream, "%lu", i);
81475fd0b74Schristos break;
81575fd0b74Schristos
81675fd0b74Schristos case 'g':
81775fd0b74Schristos /* Encoded enumeration for andi.n. */
81875fd0b74Schristos switch (op->format)
81975fd0b74Schristos {
82075fd0b74Schristos case iw_T2I4_type:
82175fd0b74Schristos i = nios2_r2_andi_n_mappings[GET_IW_T2I4_IMM4 (opcode)];
82275fd0b74Schristos break;
82375fd0b74Schristos default:
82475fd0b74Schristos bad_opcode (op);
82575fd0b74Schristos }
82675fd0b74Schristos (*info->fprintf_func) (info->stream, "%lu", i);
82775fd0b74Schristos break;
82875fd0b74Schristos
82975fd0b74Schristos case 'h':
83075fd0b74Schristos /* Encoded enumeration for movi.n. */
83175fd0b74Schristos switch (op->format)
83275fd0b74Schristos {
83375fd0b74Schristos case iw_T1I7_type:
83475fd0b74Schristos i = GET_IW_T1I7_IMM7 (opcode);
83575fd0b74Schristos if (i == 125)
83675fd0b74Schristos i = 0xff;
83775fd0b74Schristos else if (i == 126)
83875fd0b74Schristos i = -2;
83975fd0b74Schristos else if (i == 127)
84075fd0b74Schristos i = -1;
84175fd0b74Schristos break;
84275fd0b74Schristos default:
84375fd0b74Schristos bad_opcode (op);
84475fd0b74Schristos }
84575fd0b74Schristos (*info->fprintf_func) (info->stream, "%ld", i);
84675fd0b74Schristos break;
84775fd0b74Schristos
84875fd0b74Schristos case 'R':
84975fd0b74Schristos {
85075fd0b74Schristos unsigned long reglist = 0;
85175fd0b74Schristos int dir = 1;
85275fd0b74Schristos int k, t;
85375fd0b74Schristos
85475fd0b74Schristos switch (op->format)
85575fd0b74Schristos {
85675fd0b74Schristos case iw_F1X4L17_type:
85775fd0b74Schristos /* Encoding for ldwm/stwm. */
85875fd0b74Schristos i = GET_IW_F1X4L17_REGMASK (opcode);
85975fd0b74Schristos if (GET_IW_F1X4L17_RS (opcode))
86075fd0b74Schristos {
86175fd0b74Schristos reglist = ((i << 14) & 0x00ffc000);
86275fd0b74Schristos if (i & (1 << 10))
86375fd0b74Schristos reglist |= (1 << 28);
86475fd0b74Schristos if (i & (1 << 11))
865012573ebSchristos reglist |= (1u << 31);
86675fd0b74Schristos }
86775fd0b74Schristos else
86875fd0b74Schristos reglist = i << 2;
86975fd0b74Schristos dir = GET_IW_F1X4L17_REGMASK (opcode) ? 1 : -1;
87075fd0b74Schristos break;
87175fd0b74Schristos
87275fd0b74Schristos case iw_L5I4X1_type:
87375fd0b74Schristos /* Encoding for push.n/pop.n. */
874012573ebSchristos reglist |= (1u << 31);
87575fd0b74Schristos if (GET_IW_L5I4X1_FP (opcode))
87675fd0b74Schristos reglist |= (1 << 28);
87775fd0b74Schristos if (GET_IW_L5I4X1_CS (opcode))
87875fd0b74Schristos {
87975fd0b74Schristos int val = GET_IW_L5I4X1_REGRANGE (opcode);
88075fd0b74Schristos reglist |= nios2_r2_reg_range_mappings[val];
88175fd0b74Schristos }
88275fd0b74Schristos dir = (op->match == MATCH_R2_POP_N ? 1 : -1);
88375fd0b74Schristos break;
88475fd0b74Schristos
88575fd0b74Schristos default:
88675fd0b74Schristos bad_opcode (op);
88775fd0b74Schristos }
88875fd0b74Schristos
88975fd0b74Schristos t = 0;
89075fd0b74Schristos (*info->fprintf_func) (info->stream, "{");
89175fd0b74Schristos for (k = (dir == 1 ? 0 : 31);
89275fd0b74Schristos (dir == 1 && k < 32) || (dir == -1 && k >= 0);
89375fd0b74Schristos k += dir)
894012573ebSchristos if (reglist & (1u << k))
89575fd0b74Schristos {
89675fd0b74Schristos if (t)
89775fd0b74Schristos (*info->fprintf_func) (info->stream, ",");
89875fd0b74Schristos else
89975fd0b74Schristos t++;
90075fd0b74Schristos (*info->fprintf_func) (info->stream, "%s", nios2_regs[k].name);
90175fd0b74Schristos }
90275fd0b74Schristos (*info->fprintf_func) (info->stream, "}");
90375fd0b74Schristos break;
90475fd0b74Schristos }
90575fd0b74Schristos
90675fd0b74Schristos case 'B':
90775fd0b74Schristos /* Base register and options for ldwm/stwm. */
90875fd0b74Schristos switch (op->format)
90975fd0b74Schristos {
91075fd0b74Schristos case iw_F1X4L17_type:
91175fd0b74Schristos if (GET_IW_F1X4L17_ID (opcode) == 0)
91275fd0b74Schristos (*info->fprintf_func) (info->stream, "--");
91375fd0b74Schristos
91475fd0b74Schristos i = GET_IW_F1X4I12_A (opcode);
91575fd0b74Schristos (*info->fprintf_func) (info->stream, "(%s)",
91675fd0b74Schristos nios2_builtin_regs[i].name);
91775fd0b74Schristos
91875fd0b74Schristos if (GET_IW_F1X4L17_ID (opcode))
91975fd0b74Schristos (*info->fprintf_func) (info->stream, "++");
92075fd0b74Schristos if (GET_IW_F1X4L17_WB (opcode))
92175fd0b74Schristos (*info->fprintf_func) (info->stream, ",writeback");
92275fd0b74Schristos if (GET_IW_F1X4L17_PC (opcode))
92375fd0b74Schristos (*info->fprintf_func) (info->stream, ",ret");
92475fd0b74Schristos break;
92575fd0b74Schristos default:
92675fd0b74Schristos bad_opcode (op);
92775fd0b74Schristos }
92875fd0b74Schristos break;
92975fd0b74Schristos
93075fd0b74Schristos default:
93175fd0b74Schristos (*info->fprintf_func) (info->stream, "unknown");
93275fd0b74Schristos break;
93375fd0b74Schristos }
93475fd0b74Schristos return 0;
93575fd0b74Schristos }
93675fd0b74Schristos
93775fd0b74Schristos /* nios2_disassemble does all the work of disassembling a Nios II
93875fd0b74Schristos instruction opcode. */
93975fd0b74Schristos static int
nios2_disassemble(bfd_vma address,unsigned long opcode,disassemble_info * info)94075fd0b74Schristos nios2_disassemble (bfd_vma address, unsigned long opcode,
94175fd0b74Schristos disassemble_info *info)
94275fd0b74Schristos {
94375fd0b74Schristos const struct nios2_opcode *op;
94475fd0b74Schristos
94575fd0b74Schristos info->bytes_per_line = INSNLEN;
94675fd0b74Schristos info->bytes_per_chunk = INSNLEN;
94775fd0b74Schristos info->display_endian = info->endian;
94875fd0b74Schristos info->insn_info_valid = 1;
94975fd0b74Schristos info->branch_delay_insns = 0;
95075fd0b74Schristos info->data_size = 0;
95175fd0b74Schristos info->insn_type = dis_nonbranch;
95275fd0b74Schristos info->target = 0;
95375fd0b74Schristos info->target2 = 0;
95475fd0b74Schristos
95575fd0b74Schristos /* Find the major opcode and use this to disassemble
95675fd0b74Schristos the instruction and its arguments. */
95775fd0b74Schristos op = nios2_find_opcode_hash (opcode, info->mach);
95875fd0b74Schristos
95975fd0b74Schristos if (op != NULL)
96075fd0b74Schristos {
96175fd0b74Schristos const char *argstr = op->args;
96275fd0b74Schristos (*info->fprintf_func) (info->stream, "%s", op->name);
96375fd0b74Schristos if (argstr != NULL && *argstr != '\0')
96475fd0b74Schristos {
96575fd0b74Schristos (*info->fprintf_func) (info->stream, "\t");
96675fd0b74Schristos while (*argstr != '\0')
96775fd0b74Schristos {
96875fd0b74Schristos nios2_print_insn_arg (argstr, opcode, address, info, op);
96975fd0b74Schristos ++argstr;
97075fd0b74Schristos }
97175fd0b74Schristos }
97275fd0b74Schristos /* Tell the caller how far to advance the program counter. */
97375fd0b74Schristos info->bytes_per_chunk = op->size;
97475fd0b74Schristos return op->size;
97575fd0b74Schristos }
97675fd0b74Schristos else
97775fd0b74Schristos {
97875fd0b74Schristos /* Handle undefined instructions. */
97975fd0b74Schristos info->insn_type = dis_noninsn;
98075fd0b74Schristos (*info->fprintf_func) (info->stream, "0x%lx", opcode);
98175fd0b74Schristos return INSNLEN;
98275fd0b74Schristos }
98375fd0b74Schristos }
98475fd0b74Schristos
98575fd0b74Schristos
98675fd0b74Schristos /* print_insn_nios2 is the main disassemble function for Nios II.
98775fd0b74Schristos The function diassembler(abfd) (source in disassemble.c) returns a
98875fd0b74Schristos pointer to this either print_insn_big_nios2 or
98975fd0b74Schristos print_insn_little_nios2, which in turn call this function when the
99075fd0b74Schristos bfd machine type is Nios II. print_insn_nios2 reads the
99175fd0b74Schristos instruction word at the address given, and prints the disassembled
99275fd0b74Schristos instruction on the stream info->stream using info->fprintf_func. */
99375fd0b74Schristos
99475fd0b74Schristos static int
print_insn_nios2(bfd_vma address,disassemble_info * info,enum bfd_endian endianness)99575fd0b74Schristos print_insn_nios2 (bfd_vma address, disassemble_info *info,
99675fd0b74Schristos enum bfd_endian endianness)
99775fd0b74Schristos {
99875fd0b74Schristos bfd_byte buffer[INSNLEN];
99975fd0b74Schristos int status;
100075fd0b74Schristos
100175fd0b74Schristos status = (*info->read_memory_func) (address, buffer, INSNLEN, info);
100275fd0b74Schristos if (status == 0)
100375fd0b74Schristos {
100475fd0b74Schristos unsigned long insn;
100575fd0b74Schristos if (endianness == BFD_ENDIAN_BIG)
100675fd0b74Schristos insn = (unsigned long) bfd_getb32 (buffer);
100775fd0b74Schristos else
100875fd0b74Schristos insn = (unsigned long) bfd_getl32 (buffer);
100975fd0b74Schristos return nios2_disassemble (address, insn, info);
101075fd0b74Schristos }
101175fd0b74Schristos
101275fd0b74Schristos /* We might have a 16-bit R2 instruction at the end of memory. Try that. */
101375fd0b74Schristos if (info->mach == bfd_mach_nios2r2)
101475fd0b74Schristos {
101575fd0b74Schristos status = (*info->read_memory_func) (address, buffer, 2, info);
101675fd0b74Schristos if (status == 0)
101775fd0b74Schristos {
101875fd0b74Schristos unsigned long insn;
101975fd0b74Schristos if (endianness == BFD_ENDIAN_BIG)
102075fd0b74Schristos insn = (unsigned long) bfd_getb16 (buffer);
102175fd0b74Schristos else
102275fd0b74Schristos insn = (unsigned long) bfd_getl16 (buffer);
102375fd0b74Schristos return nios2_disassemble (address, insn, info);
102475fd0b74Schristos }
102575fd0b74Schristos }
102675fd0b74Schristos
102775fd0b74Schristos /* If we got here, we couldn't read anything. */
102875fd0b74Schristos (*info->memory_error_func) (status, address, info);
102975fd0b74Schristos return -1;
103075fd0b74Schristos }
103175fd0b74Schristos
103275fd0b74Schristos /* These two functions are the main entry points, accessed from
103375fd0b74Schristos disassemble.c. */
103475fd0b74Schristos int
print_insn_big_nios2(bfd_vma address,disassemble_info * info)103575fd0b74Schristos print_insn_big_nios2 (bfd_vma address, disassemble_info *info)
103675fd0b74Schristos {
103775fd0b74Schristos return print_insn_nios2 (address, info, BFD_ENDIAN_BIG);
103875fd0b74Schristos }
103975fd0b74Schristos
104075fd0b74Schristos int
print_insn_little_nios2(bfd_vma address,disassemble_info * info)104175fd0b74Schristos print_insn_little_nios2 (bfd_vma address, disassemble_info *info)
104275fd0b74Schristos {
104375fd0b74Schristos return print_insn_nios2 (address, info, BFD_ENDIAN_LITTLE);
104475fd0b74Schristos }
1045