1/* Disassemble SH64 instructions.
2   Copyright (C) 2000-2017 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 "sysdep.h"
22#include <stdio.h>
23#include "dis-asm.h"
24#include "sh64-opc.h"
25#include "libiberty.h"
26/* We need to refer to the ELF header structure.  */
27#include "elf-bfd.h"
28#include "elf/sh.h"
29#include "elf32-sh64.h"
30
31#define ELF_MODE32_CODE_LABEL_P(SYM) \
32 (((elf_symbol_type *) (SYM))->internal_elf_sym.st_other & STO_SH5_ISA32)
33
34#define SAVED_MOVI_R(INFO) \
35 (((struct sh64_disassemble_info *) ((INFO)->private_data))->address_reg)
36
37#define SAVED_MOVI_IMM(INFO) \
38 (((struct sh64_disassemble_info *) ((INFO)->private_data))->built_address)
39
40struct sh64_disassemble_info
41 {
42   /* When we see a MOVI, we save the register and the value, and merge a
43      subsequent SHORI and display the address, if there is one.  */
44   unsigned int address_reg;
45   bfd_signed_vma built_address;
46
47   /* This is the range decriptor for the current address.  It is kept
48      around for the next call.  */
49   sh64_elf_crange crange;
50 };
51
52/* Each item in the table is a mask to indicate which bits to be set
53   to determine an instruction's operator.
54   The index is as same as the instruction in the opcode table.
55   Note that some archs have this as a field in the opcode table.  */
56static unsigned long *shmedia_opcode_mask_table;
57
58/* Initialize the SH64 opcode mask table for each instruction in SHmedia
59   mode.  */
60
61static void
62initialize_shmedia_opcode_mask_table (void)
63{
64  int n_opc;
65  int n;
66
67  /* Calculate number of opcodes.  */
68  for (n_opc = 0; shmedia_table[n_opc].name != NULL; n_opc++)
69    ;
70
71  shmedia_opcode_mask_table
72    = xmalloc (sizeof (shmedia_opcode_mask_table[0]) * n_opc);
73
74  for (n = 0; n < n_opc; n++)
75    {
76      int i;
77
78      unsigned long mask = 0;
79
80      for (i = 0; shmedia_table[n].arg[i] != A_NONE; i++)
81	{
82	  int offset = shmedia_table[n].nibbles[i];
83	  int length;
84
85	  switch (shmedia_table[n].arg[i])
86	    {
87	    case A_GREG_M:
88	    case A_GREG_N:
89	    case A_GREG_D:
90	    case A_CREG_K:
91	    case A_CREG_J:
92	    case A_FREG_G:
93	    case A_FREG_H:
94	    case A_FREG_F:
95	    case A_DREG_G:
96	    case A_DREG_H:
97	    case A_DREG_F:
98	    case A_FMREG_G:
99	    case A_FMREG_H:
100	    case A_FMREG_F:
101	    case A_FPREG_G:
102	    case A_FPREG_H:
103	    case A_FPREG_F:
104	    case A_FVREG_G:
105	    case A_FVREG_H:
106	    case A_FVREG_F:
107	    case A_REUSE_PREV:
108	      length = 6;
109	      break;
110
111	    case A_TREG_A:
112	    case A_TREG_B:
113	      length = 3;
114	      break;
115
116	    case A_IMMM:
117	      abort ();
118	      break;
119
120	    case A_IMMU5:
121	      length = 5;
122	      break;
123
124	    case A_IMMS6:
125	    case A_IMMU6:
126	    case A_IMMS6BY32:
127	      length = 6;
128	      break;
129
130	    case A_IMMS10:
131	    case A_IMMS10BY1:
132	    case A_IMMS10BY2:
133	    case A_IMMS10BY4:
134	    case A_IMMS10BY8:
135	      length = 10;
136	      break;
137
138	    case A_IMMU16:
139	    case A_IMMS16:
140	    case A_PCIMMS16BY4:
141	    case A_PCIMMS16BY4_PT:
142	      length = 16;
143	      break;
144
145	    default:
146	      abort ();
147	      length = 0;
148	      break;
149	    }
150
151	  if (length != 0)
152	    mask |= (0xffffffff >> (32 - length)) << offset;
153	}
154      shmedia_opcode_mask_table[n] = 0xffffffff & ~mask;
155    }
156}
157
158/* Get a predefined control-register-name, or return NULL.  */
159
160static const char *
161creg_name (int cregno)
162{
163  const shmedia_creg_info *cregp;
164
165  /* If control register usage is common enough, change this to search a
166     hash-table.  */
167  for (cregp = shmedia_creg_table; cregp->name != NULL; cregp++)
168    if (cregp->cregno == cregno)
169      return cregp->name;
170
171  return NULL;
172}
173
174/* Main function to disassemble SHmedia instructions.  */
175
176static int
177print_insn_shmedia (bfd_vma memaddr, struct disassemble_info *info)
178{
179  fprintf_ftype fprintf_fn = info->fprintf_func;
180  void *stream = info->stream;
181  unsigned char insn[4];
182  unsigned long instruction;
183  int status;
184  int n;
185  const shmedia_opcode_info *op;
186  int i;
187  unsigned int r = 0;
188  long imm = 0;
189  bfd_vma disp_pc_addr;
190
191  status = info->read_memory_func (memaddr, insn, 4, info);
192
193  /* If we can't read four bytes, something is wrong.  Display any data we
194     can get as .byte:s.  */
195  if (status != 0)
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%08lx", 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, "%ld", 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, "%ld", 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, "%ld", 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, "%ld", 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, "%ld", imm);
374	  break;
375
376	  /* An unsigned 6-bit number.  */
377	case A_IMMU6:
378	  imm = temp & 0x3f;
379	  fprintf_fn (stream, "%ld", imm);
380	  break;
381
382	  /* An unsigned 16-bit number.  */
383	case A_IMMU16:
384	  imm = temp & 0xffff;
385	  fprintf_fn (stream, "%ld", 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
446static enum sh64_elf_cr_type
447sh64_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
500static bfd_boolean
501init_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
524int
525print_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
540int
541print_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}
620