opcodes: Fix definition of "in rd,imm16" opcode.
[deliverable/binutils-gdb.git] / opcodes / sh64-dis.c
1 /* Disassemble SH64 instructions.
2 Copyright (C) 2000, 2001 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
25 /* We need to refer to the ELF header structure. */
26 #include "elf-bfd.h"
27 #include "elf/sh.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 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 *));
62
63 /* Initialize the SH64 opcode mask table for each instruction in SHmedia
64 mode. */
65
66 static void
67 initialize_shmedia_opcode_mask_table ()
68 {
69 int n_opc;
70 int n;
71
72 /* Calculate number of opcodes. */
73 for (n_opc = 0; shmedia_table[n_opc].name != NULL; n_opc++)
74 ;
75
76 shmedia_opcode_mask_table
77 = xmalloc (sizeof (shmedia_opcode_mask_table[0]) * n_opc);
78
79 for (n = 0; n < n_opc; n++)
80 {
81 int i;
82
83 unsigned long mask = 0;
84
85 for (i = 0; shmedia_table[n].arg[i] != A_NONE; i++)
86 {
87 int offset = shmedia_table[n].nibbles[i];
88 int length;
89
90 switch (shmedia_table[n].arg[i])
91 {
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;
115
116 case A_TREG_A:
117 case A_TREG_B:
118 length = 3;
119 break;
120
121 case A_IMMM:
122 abort ();
123 break;
124
125 case A_IMMU5:
126 length = 5;
127 break;
128
129 case A_IMMS6:
130 case A_IMMU6:
131 case A_IMMS6BY32:
132 length = 6;
133 break;
134
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;
142
143 case A_IMMU16:
144 case A_IMMS16:
145 case A_PCIMMS16BY4:
146 case A_PCIMMS16BY4_PT:
147 length = 16;
148 break;
149
150 default:
151 abort ();
152 length = 0;
153 break;
154 }
155
156 if (length != 0)
157 mask |= (0xffffffff >> (32 - length)) << offset;
158 }
159 shmedia_opcode_mask_table[n] = 0xffffffff & ~mask;
160 }
161 }
162
163 /* Get a predefined control-register-name, or return NULL. */
164
165 const char *
166 creg_name (cregno)
167 int cregno;
168 {
169 const shmedia_creg_info *cregp;
170
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++)
174 {
175 if (cregp->cregno == cregno)
176 return cregp->name;
177 }
178
179 return NULL;
180 }
181
182 /* Main function to disassemble SHmedia instructions. */
183
184 static int
185 print_insn_shmedia (memaddr, info)
186 bfd_vma memaddr;
187 struct disassemble_info *info;
188 {
189 fprintf_ftype fprintf_fn = info->fprintf_func;
190 void *stream = info->stream;
191
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;
201
202 status = info->read_memory_func (memaddr, insn, 4, info);
203
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)
207 {
208 int i;
209
210 for (i = 0; i < 3; i++)
211 {
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]);
218 }
219
220 return i ? i : -1;
221 }
222
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);
228
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++)
235 ;
236
237 /* FIXME: We should also check register number constraints. */
238 if (op->name == NULL)
239 {
240 fprintf_fn (stream, ".long 0x%08x", instruction);
241 return 4;
242 }
243
244 fprintf_fn (stream, "%s\t", op->name);
245
246 for (i = 0; i < 3 && op->arg[i] != A_NONE; i++)
247 {
248 unsigned long temp = instruction >> op->nibbles[i];
249 int by_number = 0;
250
251 if (i > 0 && op->arg[i] != A_REUSE_PREV)
252 fprintf_fn (stream, ",");
253
254 switch (op->arg[i])
255 {
256 case A_REUSE_PREV:
257 continue;
258
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;
265
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;
272
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;
279
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;
286
287 case A_CREG_K:
288 case A_CREG_J:
289 {
290 const char *name;
291 r = temp & 0x3f;
292
293 name = creg_name (r);
294
295 if (name != NULL)
296 fprintf_fn (stream, "%s", name);
297 else
298 fprintf_fn (stream, "cr%d", r);
299 }
300 break;
301
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;
308
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;
315
316 case A_TREG_A:
317 case A_TREG_B:
318 r = temp & 0x7;
319 fprintf_fn (stream, "tr%d", r);
320 break;
321
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;
329
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;
337
338 /* A signed 10-bit number, multiplied by 8 when used. */
339 case A_IMMS10BY8:
340 by_number++;
341 /* Fall through. */
342
343 /* A signed 10-bit number, multiplied by 4 when used. */
344 case A_IMMS10BY4:
345 by_number++;
346 /* Fall through. */
347
348 /* A signed 10-bit number, multiplied by 2 when used. */
349 case A_IMMS10BY2:
350 by_number++;
351 /* Fall through. */
352
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;
362
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;
370
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;
381
382 /* An unsigned 5-bit number. */
383 case A_IMMU5:
384 imm = temp & 0x1f;
385 fprintf_fn (stream, "%d", imm);
386 break;
387
388 /* An unsigned 6-bit number. */
389 case A_IMMU6:
390 imm = temp & 0x3f;
391 fprintf_fn (stream, "%d", imm);
392 break;
393
394 /* An unsigned 16-bit number. */
395 case A_IMMU16:
396 imm = temp & 0xffff;
397 fprintf_fn (stream, "%d", imm);
398 break;
399
400 default:
401 abort ();
402 break;
403 }
404 }
405
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)
410 {
411 asection *section = info->section;
412
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]);
421
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)
428 {
429 bfd_signed_vma shori_addr;
430
431 shori_addr = SAVED_MOVI_IMM (info) << 16;
432 shori_addr |= imm;
433
434 fprintf_fn (stream, "\t! 0x");
435 (*info->print_address_func) (shori_addr, info);
436 }
437 }
438
439 if (op->opcode_base == SHMEDIA_MOVI_OPC)
440 {
441 SAVED_MOVI_IMM (info) = imm;
442 SAVED_MOVI_R (info) = r;
443 }
444 else
445 {
446 SAVED_MOVI_IMM (info) = 0;
447 SAVED_MOVI_R (info) = 255;
448 }
449
450 return 4;
451 }
452
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. */
457
458 static enum sh64_elf_cr_type
459 sh64_get_contents_type_disasm (memaddr, info)
460 bfd_vma memaddr;
461 struct disassemble_info *info;
462 {
463 struct sh64_disassemble_info *sh64_infop = info->private_data;
464
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;
471
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)
475 {
476 enum sh64_elf_cr_type cr_type
477 = sh64_get_contents_type (info->section, memaddr,
478 &sh64_infop->crange);
479
480 if (cr_type != CRT_NONE)
481 return cr_type;
482 }
483
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])))
489 {
490 enum sh64_elf_cr_type cr_type
491 = sh64_get_contents_type (bfd_get_section (info->symbols[0]),
492 memaddr, &sh64_infop->crange);
493
494 if (cr_type != CRT_NONE)
495 return cr_type;
496 }
497
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;
507
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;
510 }
511
512 /* Initialize static and dynamic disassembly state. */
513
514 static boolean
515 init_sh64_disasm_info (info)
516 struct disassemble_info *info;
517 {
518 struct sh64_disassemble_info *sh64_infop
519 = calloc (sizeof (*sh64_infop), 1);
520
521 if (sh64_infop == NULL)
522 return false;
523
524 info->private_data = sh64_infop;
525
526 SAVED_MOVI_IMM (info) = 0;
527 SAVED_MOVI_R (info) = 255;
528
529 if (shmedia_opcode_mask_table == NULL)
530 initialize_shmedia_opcode_mask_table ();
531
532 return true;
533 }
534
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. */
538
539 int
540 print_insn_sh64x_media (memaddr, info)
541 bfd_vma memaddr;
542 struct disassemble_info *info;
543 {
544 if (info->private_data == NULL && ! init_sh64_disasm_info (info))
545 return -1;
546
547 /* Make reasonable output. */
548 info->bytes_per_line = 4;
549 info->bytes_per_chunk = 4;
550
551 return print_insn_shmedia (memaddr, info);
552 }
553
554 /* Main entry to disassemble SHmedia insns.
555 If we see an SHcompact instruction, return -2. */
556
557 int
558 print_insn_sh64 (memaddr, info)
559 bfd_vma memaddr;
560 struct disassemble_info *info;
561 {
562 enum bfd_endian endian = info->endian;
563 enum sh64_elf_cr_type cr_type;
564
565 if (info->private_data == NULL && ! init_sh64_disasm_info (info))
566 return -1;
567
568 cr_type = sh64_get_contents_type_disasm (memaddr, info);
569 if (cr_type != CRT_SH5_ISA16)
570 {
571 int length = 4 - (memaddr % 4);
572 info->display_endian = endian;
573
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;
577
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);
582
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)
591 {
592 int status;
593 unsigned char data[4];
594 struct sh64_disassemble_info *sh64_infop = info->private_data;
595
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);
604
605 status
606 = (*info->read_memory_func) (memaddr, data,
607 length >= 4 ? 4 : length, info);
608
609 if (status == 0 && length >= 4)
610 {
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;
616 }
617 else
618 {
619 int i;
620
621 for (i = 0; i < length; i++)
622 {
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]);
629 }
630
631 return i ? i : -1;
632 }
633 }
634 }
635
636 /* SH1 .. SH4 instruction, let caller handle it. */
637 return -2;
638 }
This page took 0.115469 seconds and 4 git commands to generate.