* bfd.c (bfd_preserve_save): Don't zero BFD_IN_MEMORY.
[binutils.git] / opcodes / sh64-dis.c
blob10c0f3102e8c54416be459bb9b34ee136be797bf
1 /* Disassemble SH64 instructions.
2 Copyright (C) 2000, 2001 Free Software Foundation, Inc.
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 #include <stdio.h>
20 #include "dis-asm.h"
21 #include "sysdep.h"
22 #include "sh64-opc.h"
23 #include "libiberty.h"
25 /* We need to refer to the ELF header structure. */
26 #include "elf-bfd.h"
27 #include "elf/sh.h"
29 #define ELF_MODE32_CODE_LABEL_P(SYM) \
30 (((elf_symbol_type *) (SYM))->internal_elf_sym.st_other & STO_SH5_ISA32)
32 #define SAVED_MOVI_R(INFO) \
33 (((struct sh64_disassemble_info *) ((INFO)->private_data))->address_reg)
35 #define SAVED_MOVI_IMM(INFO) \
36 (((struct sh64_disassemble_info *) ((INFO)->private_data))->built_address)
38 struct sh64_disassemble_info
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;
45 /* This is the range decriptor for the current address. It is kept
46 around for the next call. */
47 sh64_elf_crange crange;
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;
56 static void initialize_shmedia_opcode_mask_table PARAMS ((void));
57 static int print_insn_shmedia PARAMS ((bfd_vma, disassemble_info *));
58 static const char *creg_name PARAMS ((int));
59 static boolean init_sh64_disasm_info PARAMS ((struct disassemble_info *));
60 static enum sh64_elf_cr_type sh64_get_contents_type_disasm
61 PARAMS ((bfd_vma, struct disassemble_info *));
63 /* Initialize the SH64 opcode mask table for each instruction in SHmedia
64 mode. */
66 static void
67 initialize_shmedia_opcode_mask_table ()
69 int n_opc;
70 int n;
72 /* Calculate number of opcodes. */
73 for (n_opc = 0; shmedia_table[n_opc].name != NULL; n_opc++)
76 shmedia_opcode_mask_table
77 = xmalloc (sizeof (shmedia_opcode_mask_table[0]) * n_opc);
79 for (n = 0; n < n_opc; n++)
81 int i;
83 unsigned long mask = 0;
85 for (i = 0; shmedia_table[n].arg[i] != A_NONE; i++)
87 int offset = shmedia_table[n].nibbles[i];
88 int length;
90 switch (shmedia_table[n].arg[i])
92 case A_GREG_M:
93 case A_GREG_N:
94 case A_GREG_D:
95 case A_CREG_K:
96 case A_CREG_J:
97 case A_FREG_G:
98 case A_FREG_H:
99 case A_FREG_F:
100 case A_DREG_G:
101 case A_DREG_H:
102 case A_DREG_F:
103 case A_FMREG_G:
104 case A_FMREG_H:
105 case A_FMREG_F:
106 case A_FPREG_G:
107 case A_FPREG_H:
108 case A_FPREG_F:
109 case A_FVREG_G:
110 case A_FVREG_H:
111 case A_FVREG_F:
112 case A_REUSE_PREV:
113 length = 6;
114 break;
116 case A_TREG_A:
117 case A_TREG_B:
118 length = 3;
119 break;
121 case A_IMMM:
122 abort ();
123 break;
125 case A_IMMU5:
126 length = 5;
127 break;
129 case A_IMMS6:
130 case A_IMMU6:
131 case A_IMMS6BY32:
132 length = 6;
133 break;
135 case A_IMMS10:
136 case A_IMMS10BY1:
137 case A_IMMS10BY2:
138 case A_IMMS10BY4:
139 case A_IMMS10BY8:
140 length = 10;
141 break;
143 case A_IMMU16:
144 case A_IMMS16:
145 case A_PCIMMS16BY4:
146 case A_PCIMMS16BY4_PT:
147 length = 16;
148 break;
150 default:
151 abort ();
152 length = 0;
153 break;
156 if (length != 0)
157 mask |= (0xffffffff >> (32 - length)) << offset;
159 shmedia_opcode_mask_table[n] = 0xffffffff & ~mask;
163 /* Get a predefined control-register-name, or return NULL. */
165 const char *
166 creg_name (cregno)
167 int cregno;
169 const shmedia_creg_info *cregp;
171 /* If control register usage is common enough, change this to search a
172 hash-table. */
173 for (cregp = shmedia_creg_table; cregp->name != NULL; cregp++)
175 if (cregp->cregno == cregno)
176 return cregp->name;
179 return NULL;
182 /* Main function to disassemble SHmedia instructions. */
184 static int
185 print_insn_shmedia (memaddr, info)
186 bfd_vma memaddr;
187 struct disassemble_info *info;
189 fprintf_ftype fprintf_fn = info->fprintf_func;
190 void *stream = info->stream;
192 unsigned char insn[4];
193 unsigned long instruction;
194 int status;
195 int n;
196 const shmedia_opcode_info *op;
197 int i;
198 unsigned int r = 0;
199 long imm = 0;
200 bfd_vma disp_pc_addr;
202 status = info->read_memory_func (memaddr, insn, 4, info);
204 /* If we can't read four bytes, something is wrong. Display any data we
205 can get as .byte:s. */
206 if (status != 0)
208 int i;
210 for (i = 0; i < 3; i++)
212 status = info->read_memory_func (memaddr + i, insn, 1, info);
213 if (status != 0)
214 break;
215 (*fprintf_fn) (stream, "%s0x%02x",
216 i == 0 ? ".byte " : ", ",
217 insn[0]);
220 return i ? i : -1;
223 /* Rearrange the bytes to make up an instruction. */
224 if (info->endian == BFD_ENDIAN_LITTLE)
225 instruction = bfd_getl32 (insn);
226 else
227 instruction = bfd_getb32 (insn);
229 /* FIXME: Searching could be implemented using a hash on relevant
230 fields. */
231 for (n = 0, op = shmedia_table;
232 op->name != NULL
233 && ((instruction & shmedia_opcode_mask_table[n]) != op->opcode_base);
234 n++, op++)
237 /* FIXME: We should also check register number constraints. */
238 if (op->name == NULL)
240 fprintf_fn (stream, ".long 0x%08x", instruction);
241 return 4;
244 fprintf_fn (stream, "%s\t", op->name);
246 for (i = 0; i < 3 && op->arg[i] != A_NONE; i++)
248 unsigned long temp = instruction >> op->nibbles[i];
249 int by_number = 0;
251 if (i > 0 && op->arg[i] != A_REUSE_PREV)
252 fprintf_fn (stream, ",");
254 switch (op->arg[i])
256 case A_REUSE_PREV:
257 continue;
259 case A_GREG_M:
260 case A_GREG_N:
261 case A_GREG_D:
262 r = temp & 0x3f;
263 fprintf_fn (stream, "r%d", r);
264 break;
266 case A_FVREG_F:
267 case A_FVREG_G:
268 case A_FVREG_H:
269 r = temp & 0x3f;
270 fprintf_fn (stream, "fv%d", r);
271 break;
273 case A_FPREG_F:
274 case A_FPREG_G:
275 case A_FPREG_H:
276 r = temp & 0x3f;
277 fprintf_fn (stream, "fp%d", r);
278 break;
280 case A_FMREG_F:
281 case A_FMREG_G:
282 case A_FMREG_H:
283 r = temp & 0x3f;
284 fprintf_fn (stream, "mtrx%d", r);
285 break;
287 case A_CREG_K:
288 case A_CREG_J:
290 const char *name;
291 r = temp & 0x3f;
293 name = creg_name (r);
295 if (name != NULL)
296 fprintf_fn (stream, "%s", name);
297 else
298 fprintf_fn (stream, "cr%d", r);
300 break;
302 case A_FREG_G:
303 case A_FREG_H:
304 case A_FREG_F:
305 r = temp & 0x3f;
306 fprintf_fn (stream, "fr%d", r);
307 break;
309 case A_DREG_G:
310 case A_DREG_H:
311 case A_DREG_F:
312 r = temp & 0x3f;
313 fprintf_fn (stream, "dr%d", r);
314 break;
316 case A_TREG_A:
317 case A_TREG_B:
318 r = temp & 0x7;
319 fprintf_fn (stream, "tr%d", r);
320 break;
322 /* A signed 6-bit number. */
323 case A_IMMS6:
324 imm = temp & 0x3f;
325 if (imm & (unsigned long) 0x20)
326 imm |= ~(unsigned long) 0x3f;
327 fprintf_fn (stream, "%d", imm);
328 break;
330 /* A signed 6-bit number, multiplied by 32 when used. */
331 case A_IMMS6BY32:
332 imm = temp & 0x3f;
333 if (imm & (unsigned long) 0x20)
334 imm |= ~(unsigned long) 0x3f;
335 fprintf_fn (stream, "%d", imm * 32);
336 break;
338 /* A signed 10-bit number, multiplied by 8 when used. */
339 case A_IMMS10BY8:
340 by_number++;
341 /* Fall through. */
343 /* A signed 10-bit number, multiplied by 4 when used. */
344 case A_IMMS10BY4:
345 by_number++;
346 /* Fall through. */
348 /* A signed 10-bit number, multiplied by 2 when used. */
349 case A_IMMS10BY2:
350 by_number++;
351 /* Fall through. */
353 /* A signed 10-bit number. */
354 case A_IMMS10:
355 case A_IMMS10BY1:
356 imm = temp & 0x3ff;
357 if (imm & (unsigned long) 0x200)
358 imm |= ~(unsigned long) 0x3ff;
359 imm <<= by_number;
360 fprintf_fn (stream, "%d", imm);
361 break;
363 /* A signed 16-bit number. */
364 case A_IMMS16:
365 imm = temp & 0xffff;
366 if (imm & (unsigned long) 0x8000)
367 imm |= ~((unsigned long) 0xffff);
368 fprintf_fn (stream, "%d", imm);
369 break;
371 /* A PC-relative signed 16-bit number, multiplied by 4 when
372 used. */
373 case A_PCIMMS16BY4:
374 imm = temp & 0xffff; /* 16 bits */
375 if (imm & (unsigned long) 0x8000)
376 imm |= ~(unsigned long) 0xffff;
377 imm <<= 2;
378 disp_pc_addr = (bfd_vma) imm + memaddr;
379 (*info->print_address_func) (disp_pc_addr, info);
380 break;
382 /* An unsigned 5-bit number. */
383 case A_IMMU5:
384 imm = temp & 0x1f;
385 fprintf_fn (stream, "%d", imm);
386 break;
388 /* An unsigned 6-bit number. */
389 case A_IMMU6:
390 imm = temp & 0x3f;
391 fprintf_fn (stream, "%d", imm);
392 break;
394 /* An unsigned 16-bit number. */
395 case A_IMMU16:
396 imm = temp & 0xffff;
397 fprintf_fn (stream, "%d", imm);
398 break;
400 default:
401 abort ();
402 break;
406 /* FIXME: Looks like 32-bit values only are handled.
407 FIXME: PC-relative numbers aren't handled correctly. */
408 if (op->opcode_base == (unsigned long) SHMEDIA_SHORI_OPC
409 && SAVED_MOVI_R (info) == r)
411 asection *section = info->section;
413 /* Most callers do not set the section field correctly yet. Revert
414 to getting the section from symbols, if any. */
415 if (section == NULL
416 && info->symbols != NULL
417 && bfd_asymbol_flavour (info->symbols[0]) == bfd_target_elf_flavour
418 && ! bfd_is_und_section (bfd_get_section (info->symbols[0]))
419 && ! bfd_is_abs_section (bfd_get_section (info->symbols[0])))
420 section = bfd_get_section (info->symbols[0]);
422 /* Only guess addresses when the contents of this section is fully
423 relocated. Otherwise, the value will be zero or perhaps even
424 bogus. */
425 if (section == NULL
426 || section->owner == NULL
427 || elf_elfheader (section->owner)->e_type == ET_EXEC)
429 bfd_signed_vma shori_addr;
431 shori_addr = SAVED_MOVI_IMM (info) << 16;
432 shori_addr |= imm;
434 fprintf_fn (stream, "\t! 0x");
435 (*info->print_address_func) (shori_addr, info);
439 if (op->opcode_base == SHMEDIA_MOVI_OPC)
441 SAVED_MOVI_IMM (info) = imm;
442 SAVED_MOVI_R (info) = r;
444 else
446 SAVED_MOVI_IMM (info) = 0;
447 SAVED_MOVI_R (info) = 255;
450 return 4;
453 /* Check the type of contents about to be disassembled. This is like
454 sh64_get_contents_type (which may be called from here), except that it
455 takes the same arguments as print_insn_* and does what can be done if
456 no section is available. */
458 static enum sh64_elf_cr_type
459 sh64_get_contents_type_disasm (memaddr, info)
460 bfd_vma memaddr;
461 struct disassemble_info *info;
463 struct sh64_disassemble_info *sh64_infop = info->private_data;
465 /* Perhaps we have a region from a previous probe and it still counts
466 for this address? */
467 if (sh64_infop->crange.cr_type != CRT_NONE
468 && memaddr >= sh64_infop->crange.cr_addr
469 && memaddr < sh64_infop->crange.cr_addr + sh64_infop->crange.cr_size)
470 return sh64_infop->crange.cr_type;
472 /* If we have a section, try and use it. */
473 if (info->section
474 && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour)
476 enum sh64_elf_cr_type cr_type
477 = sh64_get_contents_type (info->section, memaddr,
478 &sh64_infop->crange);
480 if (cr_type != CRT_NONE)
481 return cr_type;
484 /* If we have symbols, we can try and get at a section from *that*. */
485 if (info->symbols != NULL
486 && bfd_asymbol_flavour (info->symbols[0]) == bfd_target_elf_flavour
487 && ! bfd_is_und_section (bfd_get_section (info->symbols[0]))
488 && ! bfd_is_abs_section (bfd_get_section (info->symbols[0])))
490 enum sh64_elf_cr_type cr_type
491 = sh64_get_contents_type (bfd_get_section (info->symbols[0]),
492 memaddr, &sh64_infop->crange);
494 if (cr_type != CRT_NONE)
495 return cr_type;
498 /* We can make a reasonable guess based on the st_other field of a
499 symbol; for a BranchTarget this is marked as STO_SH5_ISA32 and then
500 it's most probably code there. */
501 if (info->symbols
502 && bfd_asymbol_flavour (info->symbols[0]) == bfd_target_elf_flavour
503 && elf_symbol_from (bfd_asymbol_bfd (info->symbols[0]),
504 info->symbols[0])->internal_elf_sym.st_other
505 == STO_SH5_ISA32)
506 return CRT_SH5_ISA32;
508 /* If all else fails, guess this is code and guess on the low bit set. */
509 return (memaddr & 1) == 1 ? CRT_SH5_ISA32 : CRT_SH5_ISA16;
512 /* Initialize static and dynamic disassembly state. */
514 static boolean
515 init_sh64_disasm_info (info)
516 struct disassemble_info *info;
518 struct sh64_disassemble_info *sh64_infop
519 = calloc (sizeof (*sh64_infop), 1);
521 if (sh64_infop == NULL)
522 return false;
524 info->private_data = sh64_infop;
526 SAVED_MOVI_IMM (info) = 0;
527 SAVED_MOVI_R (info) = 255;
529 if (shmedia_opcode_mask_table == NULL)
530 initialize_shmedia_opcode_mask_table ();
532 return true;
535 /* Main entry to disassemble SHmedia instructions, given an endian set in
536 INFO. Note that the simulator uses this as the main entry and does not
537 use any of the functions further below. */
539 int
540 print_insn_sh64x_media (memaddr, info)
541 bfd_vma memaddr;
542 struct disassemble_info *info;
544 if (info->private_data == NULL && ! init_sh64_disasm_info (info))
545 return -1;
547 /* Make reasonable output. */
548 info->bytes_per_line = 4;
549 info->bytes_per_chunk = 4;
551 return print_insn_shmedia (memaddr, info);
554 /* Main entry to disassemble SHmedia insns.
555 If we see an SHcompact instruction, return -2. */
557 int
558 print_insn_sh64 (memaddr, info)
559 bfd_vma memaddr;
560 struct disassemble_info *info;
562 enum bfd_endian endian = info->endian;
563 enum sh64_elf_cr_type cr_type;
565 if (info->private_data == NULL && ! init_sh64_disasm_info (info))
566 return -1;
568 cr_type = sh64_get_contents_type_disasm (memaddr, info);
569 if (cr_type != CRT_SH5_ISA16)
571 int length = 4 - (memaddr % 4);
572 info->display_endian = endian;
574 /* If we got an uneven address to indicate SHmedia, adjust it. */
575 if (cr_type == CRT_SH5_ISA32 && length == 3)
576 memaddr--, length = 4;
578 /* Only disassemble on four-byte boundaries. Addresses that are not
579 a multiple of four can happen after a data region. */
580 if (cr_type == CRT_SH5_ISA32 && length == 4)
581 return print_insn_sh64x_media (memaddr, info);
583 /* We get CRT_DATA *only* for data regions in a mixed-contents
584 section. For sections with data only, we get indication of one
585 of the ISA:s. You may think that we shouldn't disassemble
586 section with only data if we can figure that out. However, the
587 disassembly function is by default not called for data-only
588 sections, so if the user explicitly specified disassembly of a
589 data section, that's what we should do. */
590 if (cr_type == CRT_DATA || length != 4)
592 int status;
593 unsigned char data[4];
594 struct sh64_disassemble_info *sh64_infop = info->private_data;
596 if (length == 4
597 && sh64_infop->crange.cr_type != CRT_NONE
598 && memaddr >= sh64_infop->crange.cr_addr
599 && memaddr < (sh64_infop->crange.cr_addr
600 + sh64_infop->crange.cr_size))
601 length
602 = (sh64_infop->crange.cr_addr
603 + sh64_infop->crange.cr_size - memaddr);
605 status
606 = (*info->read_memory_func) (memaddr, data,
607 length >= 4 ? 4 : length, info);
609 if (status == 0 && length >= 4)
611 (*info->fprintf_func) (info->stream, ".long 0x%08lx",
612 endian == BFD_ENDIAN_BIG
613 ? (long) (bfd_getb32 (data))
614 : (long) (bfd_getl32 (data)));
615 return 4;
617 else
619 int i;
621 for (i = 0; i < length; i++)
623 status = info->read_memory_func (memaddr + i, data, 1, info);
624 if (status != 0)
625 break;
626 (*info->fprintf_func) (info->stream, "%s0x%02x",
627 i == 0 ? ".byte " : ", ",
628 data[0]);
631 return i ? i : -1;
636 /* SH1 .. SH4 instruction, let caller handle it. */
637 return -2;