ppc476 workaround sizing
[platform/upstream/binutils.git] / opcodes / nios2-dis.c
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.
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
38 /* Length of Nios II instruction in bytes.  */
39 #define INSNLEN 4
40
41 /* Data structures used by the opcode hash table.  */
42 typedef struct _nios2_opcode_hash
43 {
44   const struct nios2_opcode *opcode;
45   struct _nios2_opcode_hash *next;
46 } nios2_opcode_hash;
47
48 static bfd_boolean nios2_hash_init = 0;
49 static nios2_opcode_hash *nios2_hash[(OP_MASK_OP) + 1];
50
51 /* Separate hash table for pseudo-ops.  */
52 static nios2_opcode_hash *nios2_ps_hash[(OP_MASK_OP) + 1];
53
54 /* Function to initialize the opcode hash table.  */
55 static void
56 nios2_init_opcode_hash (void)
57 {
58   unsigned int i;
59   register const struct nios2_opcode *op;
60
61   for (i = 0; i <= OP_MASK_OP; ++i)
62     nios2_hash[0] = NULL;
63   for (i = 0; i <= OP_MASK_OP; i++)
64     for (op = nios2_opcodes; op < &nios2_opcodes[NUMOPCODES]; op++)
65       {
66         nios2_opcode_hash *new_hash;
67         nios2_opcode_hash **bucket = NULL;
68
69         if ((op->pinfo & NIOS2_INSN_MACRO) == NIOS2_INSN_MACRO)
70           {
71             if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP)
72                 && (op->pinfo & (NIOS2_INSN_MACRO_MOV | NIOS2_INSN_MACRO_MOVI)
73                     & 0x7fffffff))
74               bucket = &(nios2_ps_hash[i]);
75           }
76         else if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
77           bucket = &(nios2_hash[i]);
78
79         if (bucket)
80           {
81             new_hash =
82               (nios2_opcode_hash *) malloc (sizeof (nios2_opcode_hash));
83             if (new_hash == NULL)
84               {
85                 fprintf (stderr,
86                          "error allocating memory...broken disassembler\n");
87                 abort ();
88               }
89             new_hash->opcode = op;
90             new_hash->next = NULL;
91             while (*bucket)
92               bucket = &((*bucket)->next);
93             *bucket = new_hash;
94           }
95       }
96   nios2_hash_init = 1;
97 #ifdef DEBUG_HASHTABLE
98   for (i = 0; i <= OP_MASK_OP; ++i)
99     {
100       nios2_opcode_hash *tmp_hash = nios2_hash[i];
101       printf ("index: 0x%02X    ops: ", i);
102       while (tmp_hash != NULL)
103         {
104           printf ("%s ", tmp_hash->opcode->name);
105           tmp_hash = tmp_hash->next;
106         }
107       printf ("\n");
108     }
109
110   for (i = 0; i <= OP_MASK_OP; ++i)
111     {
112       nios2_opcode_hash *tmp_hash = nios2_ps_hash[i];
113       printf ("index: 0x%02X    ops: ", i);
114       while (tmp_hash != NULL)
115         {
116           printf ("%s ", tmp_hash->opcode->name);
117           tmp_hash = tmp_hash->next;
118         }
119       printf ("\n");
120     }
121 #endif /* DEBUG_HASHTABLE */
122 }
123
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)
128 {
129   nios2_opcode_hash *entry;
130
131   /* Build a hash table to shorten the search time.  */
132   if (!nios2_hash_init)
133     nios2_init_opcode_hash ();
134
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;
140
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;
146
147   return NULL;
148 }
149
150 /* There are 32 regular registers, 32 coprocessor registers,
151    and 32 control registers.  */
152 #define NUMREGNAMES 32
153
154 /* Return a pointer to the base of the coprocessor register name array.  */
155 static struct nios2_reg *
156 nios2_coprocessor_regs (void)
157 {
158   static struct nios2_reg *cached = NULL;
159   
160   if (!cached)
161     {
162       int i;
163       for (i = NUMREGNAMES; i < nios2_num_regs; i++)
164         if (!strcmp (nios2_regs[i].name, "c0"))
165           {
166             cached = nios2_regs + i;
167             break;
168           }
169       assert (cached);
170     }
171   return cached;
172 }
173
174 /* Return a pointer to the base of the control register name array.  */
175 static struct nios2_reg *
176 nios2_control_regs (void)
177 {
178   static struct nios2_reg *cached = NULL;
179   
180   if (!cached)
181     {
182       int i;
183       for (i = NUMREGNAMES; i < nios2_num_regs; i++)
184         if (!strcmp (nios2_regs[i].name, "status"))
185           {
186             cached = nios2_regs + i;
187             break;
188           }
189       assert (cached);
190     }
191   return cached;
192 }
193
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.  */
197 static int
198 nios2_print_insn_arg (const char *argptr,
199                       unsigned long opcode, bfd_vma address,
200                       disassemble_info *info)
201 {
202   unsigned long i = 0;
203   struct nios2_reg *reg_base;
204
205   switch (*argptr)
206     {
207     case ',':
208     case '(':
209     case ')':
210       (*info->fprintf_func) (info->stream, "%c", *argptr);
211       break;
212     case 'd':
213       i = GET_INSN_FIELD (RRD, opcode);
214
215       if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
216           && GET_INSN_FIELD (CUSTOM_C, opcode) == 0)
217         reg_base = nios2_coprocessor_regs ();
218       else
219         reg_base = nios2_regs;
220
221       if (i < NUMREGNAMES)
222         (*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
223       else
224         (*info->fprintf_func) (info->stream, "unknown");
225       break;
226     case 's':
227       i = GET_INSN_FIELD (RRS, opcode);
228
229       if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
230           && GET_INSN_FIELD (CUSTOM_A, opcode) == 0)
231         reg_base = nios2_coprocessor_regs ();
232       else
233         reg_base = nios2_regs;
234
235       if (i < NUMREGNAMES)
236         (*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
237       else
238         (*info->fprintf_func) (info->stream, "unknown");
239       break;
240     case 't':
241       i = GET_INSN_FIELD (RRT, opcode);
242
243       if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
244           && GET_INSN_FIELD (CUSTOM_B, opcode) == 0)
245         reg_base = nios2_coprocessor_regs ();
246       else
247         reg_base = nios2_regs;
248
249       if (i < NUMREGNAMES)
250         (*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
251       else
252         (*info->fprintf_func) (info->stream, "unknown");
253       break;
254     case 'i':
255       /* 16-bit signed immediate.  */
256       i = (signed) (GET_INSN_FIELD (IMM16, opcode) << 16) >> 16;
257       (*info->fprintf_func) (info->stream, "%ld", i);
258       break;
259     case 'u':
260       /* 16-bit unsigned immediate.  */
261       i = GET_INSN_FIELD (IMM16, opcode);
262       (*info->fprintf_func) (info->stream, "%ld", i);
263       break;
264     case 'o':
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);
269       break;
270     case 'p':
271       /* 5-bit unsigned immediate.  */
272       i = GET_INSN_FIELD (CACHE_OPX, opcode);
273       (*info->fprintf_func) (info->stream, "%ld", i);
274       break;
275     case 'j':
276       /* 5-bit unsigned immediate.  */
277       i = GET_INSN_FIELD (IMM5, opcode);
278       (*info->fprintf_func) (info->stream, "%ld", i);
279       break;
280     case 'l':
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);
285       break;
286     case 'm':
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
290          instructions.  */
291       address = (address & 0xf0000000) | (i << 2);
292       (*info->print_address_func) (address, info);
293       break;
294     case 'c':
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);
299       break;
300     case 'b':
301       i = GET_INSN_FIELD (IMM5, opcode);
302       (*info->fprintf_func) (info->stream, "%ld", i);
303       break;
304     default:
305       (*info->fprintf_func) (info->stream, "unknown");
306       break;
307     }
308   return 0;
309 }
310
311 /* nios2_disassemble does all the work of disassembling a Nios II
312    instruction opcode.  */
313 static int
314 nios2_disassemble (bfd_vma address, unsigned long opcode,
315                    disassemble_info *info)
316 {
317   const struct nios2_opcode *op;
318
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;
324   info->data_size = 0;
325   info->insn_type = dis_nonbranch;
326   info->target = 0;
327   info->target2 = 0;
328
329   /* Find the major opcode and use this to disassemble
330      the instruction and its arguments.  */
331   op = nios2_find_opcode_hash (opcode);
332
333   if (op != NULL)
334     {
335       bfd_boolean is_nop = FALSE;
336       if (op->pinfo == NIOS2_INSN_MACRO_MOV)
337         {
338           /* Check for mov r0, r0 and change to nop.  */
339           int dst, src;
340           dst = GET_INSN_FIELD (RRD, opcode);
341           src = GET_INSN_FIELD (RRS, opcode);
342           if (dst == 0 && src == 0)
343             {
344               (*info->fprintf_func) (info->stream, "nop");
345               is_nop = TRUE;
346             }
347           else
348             (*info->fprintf_func) (info->stream, "%s", op->name);
349         }
350       else
351         (*info->fprintf_func) (info->stream, "%s", op->name);
352
353       if (!is_nop)
354         {
355           const char *argstr = op->args;
356           if (argstr != NULL && *argstr != '\0')
357             {
358               (*info->fprintf_func) (info->stream, "\t");
359               while (*argstr != '\0')
360                 {
361                   nios2_print_insn_arg (argstr, opcode, address, info);
362                   ++argstr;
363                 }
364             }
365         }
366     }
367   else
368     {
369       /* Handle undefined instructions.  */
370       info->insn_type = dis_noninsn;
371       (*info->fprintf_func) (info->stream, "0x%lx", opcode);
372     }
373   /* Tell the caller how far to advance the program counter.  */
374   return INSNLEN;
375 }
376
377
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. */
385
386 static int
387 print_insn_nios2 (bfd_vma address, disassemble_info *info,
388                   enum bfd_endian endianness)
389 {
390   bfd_byte buffer[INSNLEN];
391   int status;
392
393   status = (*info->read_memory_func) (address, buffer, INSNLEN, info);
394   if (status == 0)
395     {
396       unsigned long insn;
397       if (endianness == BFD_ENDIAN_BIG)
398         insn = (unsigned long) bfd_getb32 (buffer);
399       else
400         insn = (unsigned long) bfd_getl32 (buffer);
401       status = nios2_disassemble (address, insn, info);
402     }
403   else
404     {
405       (*info->memory_error_func) (status, address, info);
406       status = -1;
407     }
408   return status;
409 }
410
411 /* These two functions are the main entry points, accessed from
412    disassemble.c.  */
413 int
414 print_insn_big_nios2 (bfd_vma address, disassemble_info *info)
415 {
416   return print_insn_nios2 (address, info, BFD_ENDIAN_BIG);
417 }
418
419 int
420 print_insn_little_nios2 (bfd_vma address, disassemble_info *info)
421 {
422   return print_insn_nios2 (address, info, BFD_ENDIAN_LITTLE);
423 }