OSDN Git Service

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