* arm-dis.c (print_insn): Fixed search for next
[external/binutils.git] / opcodes / sh64-dis.c
1 /* Disassemble SH64 instructions.
2    Copyright 2000, 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
3
4    This file is part of the GNU opcodes library.
5
6    This library is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10
11    It is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14    License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this file; see the file COPYING.  If not, write to the
18    Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20
21 #include <stdio.h>
22
23 #include "dis-asm.h"
24 #include "sysdep.h"
25 #include "sh64-opc.h"
26 #include "libiberty.h"
27 /* We need to refer to the ELF header structure.  */
28 #include "elf-bfd.h"
29 #include "elf/sh.h"
30 #include "elf32-sh64.h"
31
32 #define ELF_MODE32_CODE_LABEL_P(SYM) \
33  (((elf_symbol_type *) (SYM))->internal_elf_sym.st_other & STO_SH5_ISA32)
34
35 #define SAVED_MOVI_R(INFO) \
36  (((struct sh64_disassemble_info *) ((INFO)->private_data))->address_reg)
37
38 #define SAVED_MOVI_IMM(INFO) \
39  (((struct sh64_disassemble_info *) ((INFO)->private_data))->built_address)
40
41 struct sh64_disassemble_info
42  {
43    /* When we see a MOVI, we save the register and the value, and merge a
44       subsequent SHORI and display the address, if there is one.  */
45    unsigned int address_reg;
46    bfd_signed_vma built_address;
47
48    /* This is the range decriptor for the current address.  It is kept
49       around for the next call.  */
50    sh64_elf_crange crange;
51  };
52
53 /* Each item in the table is a mask to indicate which bits to be set
54    to determine an instruction's operator.
55    The index is as same as the instruction in the opcode table.
56    Note that some archs have this as a field in the opcode table.  */
57 static unsigned long *shmedia_opcode_mask_table;
58
59 /* Initialize the SH64 opcode mask table for each instruction in SHmedia
60    mode.  */
61
62 static void
63 initialize_shmedia_opcode_mask_table (void)
64 {
65   int n_opc;
66   int n;
67
68   /* Calculate number of opcodes.  */
69   for (n_opc = 0; shmedia_table[n_opc].name != NULL; n_opc++)
70     ;
71
72   shmedia_opcode_mask_table
73     = xmalloc (sizeof (shmedia_opcode_mask_table[0]) * n_opc);
74
75   for (n = 0; n < n_opc; n++)
76     {
77       int i;
78
79       unsigned long mask = 0;
80
81       for (i = 0; shmedia_table[n].arg[i] != A_NONE; i++)
82         {
83           int offset = shmedia_table[n].nibbles[i];
84           int length;
85
86           switch (shmedia_table[n].arg[i])
87             {
88             case A_GREG_M:
89             case A_GREG_N:
90             case A_GREG_D:
91             case A_CREG_K:
92             case A_CREG_J:
93             case A_FREG_G:
94             case A_FREG_H:
95             case A_FREG_F:
96             case A_DREG_G:
97             case A_DREG_H:
98             case A_DREG_F:
99             case A_FMREG_G:
100             case A_FMREG_H:
101             case A_FMREG_F:
102             case A_FPREG_G:
103             case A_FPREG_H:
104             case A_FPREG_F:
105             case A_FVREG_G:
106             case A_FVREG_H:
107             case A_FVREG_F:
108             case A_REUSE_PREV:
109               length = 6;
110               break;
111
112             case A_TREG_A:
113             case A_TREG_B:
114               length = 3;
115               break;
116
117             case A_IMMM:
118               abort ();
119               break;
120
121             case A_IMMU5:
122               length = 5;
123               break;
124
125             case A_IMMS6:
126             case A_IMMU6:
127             case A_IMMS6BY32:
128               length = 6;
129               break;
130
131             case A_IMMS10:
132             case A_IMMS10BY1:
133             case A_IMMS10BY2:
134             case A_IMMS10BY4:
135             case A_IMMS10BY8:
136               length = 10;
137               break;
138
139             case A_IMMU16:
140             case A_IMMS16:
141             case A_PCIMMS16BY4:
142             case A_PCIMMS16BY4_PT:
143               length = 16;
144               break;
145
146             default:
147               abort ();
148               length = 0;
149               break;
150             }
151
152           if (length != 0)
153             mask |= (0xffffffff >> (32 - length)) << offset;
154         }
155       shmedia_opcode_mask_table[n] = 0xffffffff & ~mask;
156     }
157 }
158
159 /* Get a predefined control-register-name, or return NULL.  */
160
161 static const char *
162 creg_name (int cregno)
163 {
164   const shmedia_creg_info *cregp;
165
166   /* If control register usage is common enough, change this to search a
167      hash-table.  */
168   for (cregp = shmedia_creg_table; cregp->name != NULL; cregp++)
169     if (cregp->cregno == cregno)
170       return cregp->name;
171
172   return NULL;
173 }
174
175 /* Main function to disassemble SHmedia instructions.  */
176
177 static int
178 print_insn_shmedia (bfd_vma memaddr, struct disassemble_info *info)
179 {
180   fprintf_ftype fprintf_fn = info->fprintf_func;
181   void *stream = info->stream;
182   unsigned char insn[4];
183   unsigned long instruction;
184   int status;
185   int n;
186   const shmedia_opcode_info *op;
187   int i;
188   unsigned int r = 0;
189   long imm = 0;
190   bfd_vma disp_pc_addr;
191
192   status = info->read_memory_func (memaddr, insn, 4, info);
193
194   /* If we can't read four bytes, something is wrong.  Display any data we
195      can get as .byte:s.  */
196   if (status != 0)
197     {
198       for (i = 0; i < 3; i++)
199         {
200           status = info->read_memory_func (memaddr + i, insn, 1, info);
201           if (status != 0)
202             break;
203           (*fprintf_fn) (stream, "%s0x%02x",
204                          i == 0 ? ".byte " : ", ",
205                          insn[0]);
206         }
207
208       return i ? i : -1;
209     }
210
211   /* Rearrange the bytes to make up an instruction.  */
212   if (info->endian == BFD_ENDIAN_LITTLE)
213     instruction = bfd_getl32 (insn);
214   else
215     instruction = bfd_getb32 (insn);
216
217   /* FIXME: Searching could be implemented using a hash on relevant
218      fields.  */
219   for (n = 0, op = shmedia_table;
220        op->name != NULL
221        && ((instruction & shmedia_opcode_mask_table[n]) != op->opcode_base);
222        n++, op++)
223     ;
224
225   /* FIXME: We should also check register number constraints.  */
226   if (op->name == NULL)
227     {
228       fprintf_fn (stream, ".long 0x%08lx", instruction);
229       return 4;
230     }
231
232   fprintf_fn (stream, "%s\t", op->name);
233
234   for (i = 0; i < 3 && op->arg[i] != A_NONE; i++)
235     {
236       unsigned long temp = instruction >> op->nibbles[i];
237       int by_number = 0;
238
239       if (i > 0 && op->arg[i] != A_REUSE_PREV)
240         fprintf_fn (stream, ",");
241
242       switch (op->arg[i])
243         {
244         case A_REUSE_PREV:
245           continue;
246
247         case A_GREG_M:
248         case A_GREG_N:
249         case A_GREG_D:
250           r = temp & 0x3f;
251           fprintf_fn (stream, "r%d", r);
252           break;
253
254         case A_FVREG_F:
255         case A_FVREG_G:
256         case A_FVREG_H:
257           r = temp & 0x3f;
258           fprintf_fn (stream, "fv%d", r);
259           break;
260
261         case A_FPREG_F:
262         case A_FPREG_G:
263         case A_FPREG_H:
264           r = temp & 0x3f;
265           fprintf_fn (stream, "fp%d", r);
266           break;
267
268         case A_FMREG_F:
269         case A_FMREG_G:
270         case A_FMREG_H:
271           r = temp & 0x3f;
272           fprintf_fn (stream, "mtrx%d", r);
273           break;
274
275         case A_CREG_K:
276         case A_CREG_J:
277           {
278             const char *name;
279
280             r = temp & 0x3f;
281
282             name = creg_name (r);
283
284             if (name != NULL)
285               fprintf_fn (stream, "%s", name);
286             else
287               fprintf_fn (stream, "cr%d", r);
288           }
289           break;
290
291         case A_FREG_G:
292         case A_FREG_H:
293         case A_FREG_F:
294           r = temp & 0x3f;
295           fprintf_fn (stream, "fr%d", r);
296           break;
297
298         case A_DREG_G:
299         case A_DREG_H:
300         case A_DREG_F:
301           r = temp & 0x3f;
302           fprintf_fn (stream, "dr%d", r);
303           break;
304
305         case A_TREG_A:
306         case A_TREG_B:
307           r = temp & 0x7;
308           fprintf_fn (stream, "tr%d", r);
309           break;
310
311           /* A signed 6-bit number.  */
312         case A_IMMS6:
313           imm = temp & 0x3f;
314           if (imm & (unsigned long) 0x20)
315             imm |= ~(unsigned long) 0x3f;
316           fprintf_fn (stream, "%ld", imm);
317           break;
318
319           /* A signed 6-bit number, multiplied by 32 when used.  */
320         case A_IMMS6BY32:
321           imm = temp & 0x3f;
322           if (imm & (unsigned long) 0x20)
323             imm |= ~(unsigned long) 0x3f;
324           fprintf_fn (stream, "%ld", imm * 32);
325           break;
326
327           /* A signed 10-bit number, multiplied by 8 when used.  */
328         case A_IMMS10BY8:
329           by_number++;
330           /* Fall through.  */
331
332           /* A signed 10-bit number, multiplied by 4 when used.  */
333         case A_IMMS10BY4:
334           by_number++;
335           /* Fall through.  */
336
337           /* A signed 10-bit number, multiplied by 2 when used.  */
338         case A_IMMS10BY2:
339           by_number++;
340           /* Fall through.  */
341
342           /* A signed 10-bit number.  */
343         case A_IMMS10:
344         case A_IMMS10BY1:
345           imm = temp & 0x3ff;
346           if (imm & (unsigned long) 0x200)
347             imm |= ~(unsigned long) 0x3ff;
348           imm <<= by_number;
349           fprintf_fn (stream, "%ld", imm);
350           break;
351
352           /* A signed 16-bit number.  */
353         case A_IMMS16:
354           imm = temp & 0xffff;
355           if (imm & (unsigned long) 0x8000)
356             imm |= ~((unsigned long) 0xffff);
357           fprintf_fn (stream, "%ld", imm);
358           break;
359
360           /* A PC-relative signed 16-bit number, multiplied by 4 when
361              used.  */
362         case A_PCIMMS16BY4:
363           imm = temp & 0xffff;  /* 16 bits */
364           if (imm & (unsigned long) 0x8000)
365             imm |= ~(unsigned long) 0xffff;
366           imm <<= 2;
367           disp_pc_addr = (bfd_vma) imm + memaddr;
368           (*info->print_address_func) (disp_pc_addr, info);
369           break;
370
371           /* An unsigned 5-bit number.  */
372         case A_IMMU5:
373           imm = temp & 0x1f;
374           fprintf_fn (stream, "%ld", imm);
375           break;
376
377           /* An unsigned 6-bit number.  */
378         case A_IMMU6:
379           imm = temp & 0x3f;
380           fprintf_fn (stream, "%ld", imm);
381           break;
382
383           /* An unsigned 16-bit number.  */
384         case A_IMMU16:
385           imm = temp & 0xffff;
386           fprintf_fn (stream, "%ld", imm);
387           break;
388
389         default:
390           abort ();
391           break;
392         }
393     }
394
395   /* FIXME: Looks like 32-bit values only are handled.
396      FIXME: PC-relative numbers aren't handled correctly.  */
397   if (op->opcode_base == (unsigned long) SHMEDIA_SHORI_OPC
398       && SAVED_MOVI_R (info) == r)
399     {
400       asection *section = info->section;
401
402       /* Most callers do not set the section field correctly yet.  Revert
403          to getting the section from symbols, if any. */
404       if (section == NULL
405           && info->symbols != NULL
406           && bfd_asymbol_flavour (info->symbols[0]) == bfd_target_elf_flavour
407           && ! bfd_is_und_section (bfd_get_section (info->symbols[0]))
408           && ! bfd_is_abs_section (bfd_get_section (info->symbols[0])))
409         section = bfd_get_section (info->symbols[0]);
410
411       /* Only guess addresses when the contents of this section is fully
412          relocated.  Otherwise, the value will be zero or perhaps even
413          bogus.  */
414       if (section == NULL
415           || section->owner == NULL
416           || elf_elfheader (section->owner)->e_type == ET_EXEC)
417         {
418           bfd_signed_vma shori_addr;
419
420           shori_addr = SAVED_MOVI_IMM (info) << 16;
421           shori_addr |= imm;
422
423           fprintf_fn (stream, "\t! 0x");
424           (*info->print_address_func) (shori_addr, info);
425         }
426     }
427
428   if (op->opcode_base == SHMEDIA_MOVI_OPC)
429     {
430       SAVED_MOVI_IMM (info) = imm;
431       SAVED_MOVI_R (info) = r;
432     }
433   else
434     {
435       SAVED_MOVI_IMM (info) = 0;
436       SAVED_MOVI_R (info) = 255;
437     }
438
439   return 4;
440 }
441
442 /* Check the type of contents about to be disassembled.  This is like
443    sh64_get_contents_type (which may be called from here), except that it
444    takes the same arguments as print_insn_* and does what can be done if
445    no section is available.  */
446
447 static enum sh64_elf_cr_type
448 sh64_get_contents_type_disasm (bfd_vma memaddr, struct disassemble_info *info)
449 {
450   struct sh64_disassemble_info *sh64_infop = info->private_data;
451
452   /* Perhaps we have a region from a previous probe and it still counts
453      for this address?  */
454   if (sh64_infop->crange.cr_type != CRT_NONE
455       && memaddr >= sh64_infop->crange.cr_addr
456       && memaddr < sh64_infop->crange.cr_addr + sh64_infop->crange.cr_size)
457     return sh64_infop->crange.cr_type;
458
459   /* If we have a section, try and use it.  */
460   if (info->section
461       && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour)
462     {
463       enum sh64_elf_cr_type cr_type
464         = sh64_get_contents_type (info->section, memaddr,
465                                   &sh64_infop->crange);
466
467       if (cr_type != CRT_NONE)
468         return cr_type;
469     }
470
471   /* If we have symbols, we can try and get at a section from *that*.  */
472   if (info->symbols != NULL
473       && bfd_asymbol_flavour (info->symbols[0]) == bfd_target_elf_flavour
474       && ! bfd_is_und_section (bfd_get_section (info->symbols[0]))
475       && ! bfd_is_abs_section (bfd_get_section (info->symbols[0])))
476     {
477       enum sh64_elf_cr_type cr_type
478         = sh64_get_contents_type (bfd_get_section (info->symbols[0]),
479                                   memaddr, &sh64_infop->crange);
480
481       if (cr_type != CRT_NONE)
482         return cr_type;
483     }
484
485   /* We can make a reasonable guess based on the st_other field of a
486      symbol; for a BranchTarget this is marked as STO_SH5_ISA32 and then
487      it's most probably code there.  */
488   if (info->symbols
489       && bfd_asymbol_flavour (info->symbols[0]) == bfd_target_elf_flavour
490       && elf_symbol_from (bfd_asymbol_bfd (info->symbols[0]),
491                           info->symbols[0])->internal_elf_sym.st_other
492       == STO_SH5_ISA32)
493     return CRT_SH5_ISA32;
494
495   /* If all else fails, guess this is code and guess on the low bit set.  */
496   return (memaddr & 1) == 1 ? CRT_SH5_ISA32 : CRT_SH5_ISA16;
497 }
498
499 /* Initialize static and dynamic disassembly state.  */
500
501 static bfd_boolean
502 init_sh64_disasm_info (struct disassemble_info *info)
503 {
504   struct sh64_disassemble_info *sh64_infop
505     = calloc (sizeof (*sh64_infop), 1);
506
507   if (sh64_infop == NULL)
508     return FALSE;
509
510   info->private_data = sh64_infop;
511
512   SAVED_MOVI_IMM (info) = 0;
513   SAVED_MOVI_R (info) = 255;
514
515   if (shmedia_opcode_mask_table == NULL)
516     initialize_shmedia_opcode_mask_table ();
517
518   return TRUE;
519 }
520
521 /* Main entry to disassemble SHmedia instructions, given an endian set in
522    INFO.  Note that the simulator uses this as the main entry and does not
523    use any of the functions further below.  */
524
525 int
526 print_insn_sh64x_media (bfd_vma memaddr, struct disassemble_info *info)
527 {
528   if (info->private_data == NULL && ! init_sh64_disasm_info (info))
529     return -1;
530
531   /* Make reasonable output.  */
532   info->bytes_per_line = 4;
533   info->bytes_per_chunk = 4;
534
535   return print_insn_shmedia (memaddr, info);
536 }
537
538 /* Main entry to disassemble SHmedia insns.
539    If we see an SHcompact instruction, return -2.  */
540
541 int
542 print_insn_sh64 (bfd_vma memaddr, struct disassemble_info *info)
543 {
544   enum bfd_endian endian = info->endian;
545   enum sh64_elf_cr_type cr_type;
546
547   if (info->private_data == NULL && ! init_sh64_disasm_info (info))
548     return -1;
549
550   cr_type = sh64_get_contents_type_disasm (memaddr, info);
551   if (cr_type != CRT_SH5_ISA16)
552     {
553       int length = 4 - (memaddr % 4);
554       info->display_endian = endian;
555
556       /* If we got an uneven address to indicate SHmedia, adjust it.  */
557       if (cr_type == CRT_SH5_ISA32 && length == 3)
558         memaddr--, length = 4;
559
560       /* Only disassemble on four-byte boundaries.  Addresses that are not
561          a multiple of four can happen after a data region.  */
562       if (cr_type == CRT_SH5_ISA32 && length == 4)
563         return print_insn_sh64x_media (memaddr, info);
564
565       /* We get CRT_DATA *only* for data regions in a mixed-contents
566          section.  For sections with data only, we get indication of one
567          of the ISA:s.  You may think that we shouldn't disassemble
568          section with only data if we can figure that out.  However, the
569          disassembly function is by default not called for data-only
570          sections, so if the user explicitly specified disassembly of a
571          data section, that's what we should do.  */
572       if (cr_type == CRT_DATA || length != 4)
573         {
574           int status;
575           unsigned char data[4];
576           struct sh64_disassemble_info *sh64_infop = info->private_data;
577
578           if (length == 4
579               && sh64_infop->crange.cr_type != CRT_NONE
580               && memaddr >= sh64_infop->crange.cr_addr
581               && memaddr < (sh64_infop->crange.cr_addr
582                             + sh64_infop->crange.cr_size))
583             length
584               = (sh64_infop->crange.cr_addr
585                  + sh64_infop->crange.cr_size - memaddr);
586
587           status
588             = (*info->read_memory_func) (memaddr, data,
589                                          length >= 4 ? 4 : length, info);
590
591           if (status == 0 && length >= 4)
592             {
593               (*info->fprintf_func) (info->stream, ".long 0x%08lx",
594                                      endian == BFD_ENDIAN_BIG
595                                      ? (long) (bfd_getb32 (data))
596                                      : (long) (bfd_getl32 (data)));
597               return 4;
598             }
599           else
600             {
601               int i;
602
603               for (i = 0; i < length; i++)
604                 {
605                   status = info->read_memory_func (memaddr + i, data, 1, info);
606                   if (status != 0)
607                     break;
608                   (*info->fprintf_func) (info->stream, "%s0x%02x",
609                                          i == 0 ? ".byte " : ", ",
610                                          data[0]);
611                 }
612
613               return i ? i : -1;
614             }
615         }
616     }
617
618   /* SH1 .. SH4 instruction, let caller handle it.  */
619   return -2;
620 }