diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2002-02-08 05:51:04 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@redhat.com> | 2002-02-08 05:51:04 +0000 |
commit | d28847ce8eb6da33e8bc2905fe0b08631360a764 (patch) | |
tree | 473f46355faa44f31d5b66c6843a456c981c5aa0 /opcodes/sh64-dis.c | |
parent | fbca6ad9f37cba55a02e4df8a925b638426ed87e (diff) | |
download | gdb-d28847ce8eb6da33e8bc2905fe0b08631360a764.zip gdb-d28847ce8eb6da33e8bc2905fe0b08631360a764.tar.gz gdb-d28847ce8eb6da33e8bc2905fe0b08631360a764.tar.bz2 |
Contribute sh64-elf.
2001-10-08 Nick Clifton <nickc@cambridge.redhat.com>
* sh64-opc.c: Regenerate.
2001-03-13 DJ Delorie <dj@redhat.com>
* sh64-opc.h: Rename A_RESV_Fx to A_REUSE_PREV so that its
purpose is more obvious.
* sh64-opc.c (shmedia_table): Ditto.
* sh64-dis.c (initialize_shmedia_opcode_mask_table): Ditto.
(print_insn_shmedia): Ditto.
2001-03-12 DJ Delorie <dj@redhat.com>
* sh64-opc.c: Adjust comments to reflect reality: replace bits
3:0 with zeros (not "reserved"), replace "rrrrrr" with
"gggggg" for two-operand floating point opcodes. Remove
"fsina".
2001-01-08 Hans-Peter Nilsson <hpn@cygnus.com>
* sh64-dis.c (print_insn_shmedia) <failing read_memory_func>:
Correct printing of .byte:s. Return number of printed bytes or
-1; never 0.
(print_insn_sh64x) <not CRT_SH5_ISA16>: Ditto. Print as .byte:s
to next four-byte-alignment if insn or data is not aligned.
2001-01-06 Hans-Peter Nilsson <hpn@cygnus.com>
* sh64-dis.c: Update comments and fix comment formatting.
(initialize_shmedia_opcode_mask_table) <case A_IMMM>:
Abort instead of setting length to 0.
(crange_qsort_cmpb, crange_qsort_cmpl, crange_bsearch_cmpb,
crange_bsearch_cmpl, sh64_get_contents_type,
sh64_address_in_cranges): Move to bfd/elf32-sh64.c.
2001-01-05 Hans-Peter Nilsson <hpn@cygnus.com>
* sh64-opc.c: Remove #if 0:d entries for instructions not found in
SH-5/ST50-023-04: fcosa.s, fsrra.s and prefo.
2000-12-30 Hans-Peter Nilsson <hpn@cygnus.com>
* sh64-dis.c (print_insn_shmedia): Display MOVI/SHORI-formed
address with same prefix as SHcompact.
In the disassembler, use a .cranges section for linked executables.
* sh64-dis.c (SAVED_MOVI_R, SAVED_MOVI_IMM): Move to head of file
and update for using structure in info->private_data.
(struct sh64_disassemble_info): New.
(is_shmedia_p): Delete.
(crange_qsort_cmpb): New function.
(crange_qsort_cmpl, crange_bsearch_cmpb): New functions.
(crange_bsearch_cmpl, sh64_address_in_cranges): New functions.
(init_sh64_disasm_info, sh64_get_contents_type_disasm): New functions.
(sh64_get_contents_type, sh64_address_is_shmedia): New functions.
(print_insn_shmedia): Correct displaying of address after MOVI/SHORI
pair. Display addresses for linked executables only.
(print_insn_sh64x_media): Initialize info->private_data by calling
init_sh64_disasm_info.
(print_insn_sh64x): Ditto. Find out type of contents by calling
sh64_contents_type_disasm. Display data regions using ".long" and
".byte" similar to unrecognized opcodes.
2000-12-19 Hans-Peter Nilsson <hpn@cygnus.com>
* sh64-dis.c (is_shmedia_p): Check info->section and look for ISA
information in section flags before considering symbols. Don't
assume an info->mach setting of bfd_mach_sh5 means SHmedia code.
* configure.in (bfd_sh_arch): Check presence of sh64 insns by
matching $target $canon_targets instead of looking at the
now-removed -DINCLUDE_SHMEDIA in $targ_cflags.
* configure: Regenerate.
2000-11-25 Hans-Peter Nilsson <hpn@cygnus.com>
* sh64-opc.c (shmedia_creg_table): New.
* sh64-opc.h (shmedia_creg_info): New type.
(shmedia_creg_table): Declare.
* sh64-dis.c (creg_name): New function.
(print_insn_shmedia): Use it.
* disassemble.c (disassembler) [ARCH_sh, INCLUDE_SHMEDIA]: Map
bfd_mach_sh5 to print_insn_sh64 if big-endian and to
print_insn_sh64l if little-endian.
* sh64-dis.c (print_insn_shmedia): Make r unsigned.
(print_insn_sh64l): New.
(print_insn_sh64x): New.
(print_insn_sh64x_media): New.
(print_insn_sh64): Break out code to print_insn_sh64x and
print_insn_sh64x_media.
2000-11-24 Hans-Peter Nilsson <hpn@cygnus.com>
* sh64-opc.h: New file
* sh64-opc.c: New file
* sh64-dis.c: New file
* Makefile.am: Add sh64 targets.
(HFILES): Add sh64-opc.h.
(CFILES): Add sh64-opc.c and sh64-dis.c.
(ALL_MACHINES): Add sh64 files.
* Makefile.in: Regenerate.
* configure.in: Add support for sh64 to bfd_sh_arch.
* configure: Regenerate.
* disassemble.c [ARCH_all] (INCLUDE_SHMEDIA): Define.
(disassembler) [ARCH_sh, INCLUDE_SHMEDIA]: Map bfd_mach_sh5 to
print_insn_sh64.
* sh-dis.c (print_insn_shx): Handle bfd_mach_sh5 as arch_sh4.
* po/POTFILES.in: Regenerate.
* po/opcodes.pot: Regenerate.
Diffstat (limited to 'opcodes/sh64-dis.c')
-rw-r--r-- | opcodes/sh64-dis.c | 659 |
1 files changed, 659 insertions, 0 deletions
diff --git a/opcodes/sh64-dis.c b/opcodes/sh64-dis.c new file mode 100644 index 0000000..2c76067 --- /dev/null +++ b/opcodes/sh64-dis.c @@ -0,0 +1,659 @@ +/* Disassemble SH64 instructions. + Copyright (C) 2000, 2001 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include <stdio.h> + +#include "dis-asm.h" +#include "sysdep.h" +#include "sh64-opc.h" +#include "libiberty.h" + +/* We need to refer to the ELF header structure. */ +#include "elf-bfd.h" +#include "elf/sh.h" + +#define ELF_MODE32_CODE_LABEL_P(SYM) \ + (((elf_symbol_type *) (SYM))->internal_elf_sym.st_other & STO_SH5_ISA32) + +#define SAVED_MOVI_R(INFO) \ + (((struct sh64_disassemble_info *) ((INFO)->private_data))->address_reg) + +#define SAVED_MOVI_IMM(INFO) \ + (((struct sh64_disassemble_info *) ((INFO)->private_data))->built_address) + +struct sh64_disassemble_info + { + /* When we see a MOVI, we save the register and the value, and merge a + subsequent SHORI and display the address, if there is one. */ + unsigned int address_reg; + bfd_signed_vma built_address; + + /* This is the range decriptor for the current address. It is kept + around for the next call. */ + sh64_elf_crange crange; + }; + +/* Each item in the table is a mask to indicate which bits to be set + to determine an instruction's operator. + The index is as same as the instruction in the opcode table. + Note that some archs have this as a field in the opcode table. */ +static unsigned long *shmedia_opcode_mask_table; + +static void initialize_shmedia_opcode_mask_table PARAMS ((void)); +static int print_insn_shmedia PARAMS ((bfd_vma, disassemble_info *)); +static int print_insn_sh64x + PARAMS ((bfd_vma, disassemble_info *, + int (*) PARAMS ((bfd_vma, struct disassemble_info *)), + enum bfd_endian)); +static const char *creg_name PARAMS ((int)); +static boolean init_sh64_disasm_info PARAMS ((struct disassemble_info *)); +static enum sh64_elf_cr_type sh64_get_contents_type_disasm + PARAMS ((bfd_vma, struct disassemble_info *)); + +/* Initialize the SH64 opcode mask table for each instruction in SHmedia + mode. */ + +static void +initialize_shmedia_opcode_mask_table () +{ + int n_opc; + int n; + + /* Calculate number of opcodes. */ + for (n_opc = 0; shmedia_table[n_opc].name != NULL; n_opc++) + ; + + shmedia_opcode_mask_table + = xmalloc (sizeof (shmedia_opcode_mask_table[0]) * n_opc); + + for (n = 0; n < n_opc; n++) + { + int i; + + unsigned long mask = 0; + + for (i = 0; shmedia_table[n].arg[i] != A_NONE; i++) + { + int offset = shmedia_table[n].nibbles[i]; + int length; + + switch (shmedia_table[n].arg[i]) + { + case A_GREG_M: + case A_GREG_N: + case A_GREG_D: + case A_CREG_K: + case A_CREG_J: + case A_FREG_G: + case A_FREG_H: + case A_FREG_F: + case A_DREG_G: + case A_DREG_H: + case A_DREG_F: + case A_FMREG_G: + case A_FMREG_H: + case A_FMREG_F: + case A_FPREG_G: + case A_FPREG_H: + case A_FPREG_F: + case A_FVREG_G: + case A_FVREG_H: + case A_FVREG_F: + case A_REUSE_PREV: + length = 6; + break; + + case A_TREG_A: + case A_TREG_B: + length = 3; + break; + + case A_IMMM: + abort (); + break; + + case A_IMMU5: + length = 5; + break; + + case A_IMMS6: + case A_IMMU6: + case A_IMMS6BY32: + length = 6; + break; + + case A_IMMS10: + case A_IMMS10BY1: + case A_IMMS10BY2: + case A_IMMS10BY4: + case A_IMMS10BY8: + length = 10; + break; + + case A_IMMU16: + case A_IMMS16: + case A_PCIMMS16BY4: + case A_PCIMMS16BY4_PT: + length = 16; + break; + + default: + abort (); + length = 0; + break; + } + + if (length != 0) + mask |= (0xffffffff >> (32 - length)) << offset; + } + shmedia_opcode_mask_table[n] = 0xffffffff & ~mask; + } +} + +/* Get a predefined control-register-name, or return NULL. */ + +const char * +creg_name (cregno) + int cregno; +{ + const shmedia_creg_info *cregp; + + /* If control register usage is common enough, change this to search a + hash-table. */ + for (cregp = shmedia_creg_table; cregp->name != NULL; cregp++) + { + if (cregp->cregno == cregno) + return cregp->name; + } + + return NULL; +} + +/* Main function to disassemble SHmedia instructions. */ + +static int +print_insn_shmedia (memaddr, info) + bfd_vma memaddr; + struct disassemble_info *info; +{ + fprintf_ftype fprintf_fn = info->fprintf_func; + void *stream = info->stream; + + unsigned char insn[4]; + unsigned long instruction; + int status; + int n; + const shmedia_opcode_info *op; + int i; + unsigned int r = 0; + long imm = 0; + bfd_vma disp_pc_addr; + + status = info->read_memory_func (memaddr, insn, 4, info); + + /* If we can't read four bytes, something is wrong. Display any data we + can get as .byte:s. */ + if (status != 0) + { + int i; + + for (i = 0; i < 3; i++) + { + status = info->read_memory_func (memaddr + i, insn, 1, info); + if (status != 0) + break; + (*fprintf_fn) (stream, "%s0x%02x", + i == 0 ? ".byte " : ", ", + insn[0]); + } + + return i ? i : -1; + } + + /* Rearrange the bytes to make up an instruction. */ + if (info->endian == BFD_ENDIAN_LITTLE) + instruction = bfd_getl32 (insn); + else + instruction = bfd_getb32 (insn); + + /* FIXME: Searching could be implemented using a hash on relevant + fields. */ + for (n = 0, op = shmedia_table; + op->name != NULL + && ((instruction & shmedia_opcode_mask_table[n]) != op->opcode_base); + n++, op++) + ; + + /* FIXME: We should also check register number constraints. */ + if (op->name == NULL) + { + fprintf_fn (stream, ".long 0x%08x", instruction); + return 4; + } + + fprintf_fn (stream, "%s\t", op->name); + + for (i = 0; i < 3 && op->arg[i] != A_NONE; i++) + { + unsigned long temp = instruction >> op->nibbles[i]; + int by_number = 0; + + if (i > 0 && op->arg[i] != A_REUSE_PREV) + fprintf_fn (stream, ","); + + switch (op->arg[i]) + { + case A_REUSE_PREV: + continue; + + case A_GREG_M: + case A_GREG_N: + case A_GREG_D: + r = temp & 0x3f; + fprintf_fn (stream, "r%d", r); + break; + + case A_FVREG_F: + case A_FVREG_G: + case A_FVREG_H: + r = temp & 0x3f; + fprintf_fn (stream, "fv%d", r); + break; + + case A_FPREG_F: + case A_FPREG_G: + case A_FPREG_H: + r = temp & 0x3f; + fprintf_fn (stream, "fp%d", r); + break; + + case A_FMREG_F: + case A_FMREG_G: + case A_FMREG_H: + r = temp & 0x3f; + fprintf_fn (stream, "mtrx%d", r); + break; + + case A_CREG_K: + case A_CREG_J: + { + const char *name; + r = temp & 0x3f; + + name = creg_name (r); + + if (name != NULL) + fprintf_fn (stream, "%s", name); + else + fprintf_fn (stream, "cr%d", r); + } + break; + + case A_FREG_G: + case A_FREG_H: + case A_FREG_F: + r = temp & 0x3f; + fprintf_fn (stream, "fr%d", r); + break; + + case A_DREG_G: + case A_DREG_H: + case A_DREG_F: + r = temp & 0x3f; + fprintf_fn (stream, "dr%d", r); + break; + + case A_TREG_A: + case A_TREG_B: + r = temp & 0x7; + fprintf_fn (stream, "tr%d", r); + break; + + /* A signed 6-bit number. */ + case A_IMMS6: + imm = temp & 0x3f; + if (imm & (unsigned long) 0x20) + imm |= ~(unsigned long) 0x3f; + fprintf_fn (stream, "%d", imm); + break; + + /* A signed 6-bit number, multiplied by 32 when used. */ + case A_IMMS6BY32: + imm = temp & 0x3f; + if (imm & (unsigned long) 0x20) + imm |= ~(unsigned long) 0x3f; + fprintf_fn (stream, "%d", imm * 32); + break; + + /* A signed 10-bit number, multiplied by 8 when used. */ + case A_IMMS10BY8: + by_number++; + /* Fall through. */ + + /* A signed 10-bit number, multiplied by 4 when used. */ + case A_IMMS10BY4: + by_number++; + /* Fall through. */ + + /* A signed 10-bit number, multiplied by 2 when used. */ + case A_IMMS10BY2: + by_number++; + /* Fall through. */ + + /* A signed 10-bit number. */ + case A_IMMS10: + case A_IMMS10BY1: + imm = temp & 0x3ff; + if (imm & (unsigned long) 0x200) + imm |= ~(unsigned long) 0x3ff; + imm <<= by_number; + fprintf_fn (stream, "%d", imm); + break; + + /* A signed 16-bit number. */ + case A_IMMS16: + imm = temp & 0xffff; + if (imm & (unsigned long) 0x8000) + imm |= ~((unsigned long) 0xffff); + fprintf_fn (stream, "%d", imm); + break; + + /* A PC-relative signed 16-bit number, multiplied by 4 when + used. */ + case A_PCIMMS16BY4: + imm = temp & 0xffff; /* 16 bits */ + if (imm & (unsigned long) 0x8000) + imm |= ~(unsigned long) 0xffff; + imm <<= 2; + disp_pc_addr = (bfd_vma) imm + memaddr; + (*info->print_address_func) (disp_pc_addr, info); + break; + + /* An unsigned 5-bit number. */ + case A_IMMU5: + imm = temp & 0x1f; + fprintf_fn (stream, "%d", imm); + break; + + /* An unsigned 6-bit number. */ + case A_IMMU6: + imm = temp & 0x3f; + fprintf_fn (stream, "%d", imm); + break; + + /* An unsigned 16-bit number. */ + case A_IMMU16: + imm = temp & 0xffff; + fprintf_fn (stream, "%d", imm); + break; + + default: + abort (); + break; + } + } + + /* FIXME: Looks like 32-bit values only are handled. + FIXME: PC-relative numbers aren't handled correctly. */ + if (op->opcode_base == (unsigned long) SHMEDIA_SHORI_OPC + && SAVED_MOVI_R (info) == r) + { + asection *section = info->section; + + /* Most callers do not set the section field correctly yet. Revert + to getting the section from symbols, if any. */ + if (section == NULL + && info->symbols != NULL + && bfd_asymbol_flavour (info->symbols[0]) == bfd_target_elf_flavour + && ! bfd_is_und_section (bfd_get_section (info->symbols[0])) + && ! bfd_is_abs_section (bfd_get_section (info->symbols[0]))) + section = bfd_get_section (info->symbols[0]); + + /* Only guess addresses when the contents of this section is fully + relocated. Otherwise, the value will be zero or perhaps even + bogus. */ + if (section == NULL + || section->owner == NULL + || elf_elfheader (section->owner)->e_type == ET_EXEC) + { + bfd_signed_vma shori_addr; + + shori_addr = SAVED_MOVI_IMM (info) << 16; + shori_addr |= imm; + + fprintf_fn (stream, "\t! 0x"); + (*info->print_address_func) (shori_addr, info); + } + } + + if (op->opcode_base == SHMEDIA_MOVI_OPC) + { + SAVED_MOVI_IMM (info) = imm; + SAVED_MOVI_R (info) = r; + } + else + { + SAVED_MOVI_IMM (info) = 0; + SAVED_MOVI_R (info) = 255; + } + + return 4; +} + +/* Check the type of contents about to be disassembled. This is like + sh64_get_contents_type (which may be called from here), except that it + takes the same arguments as print_insn_* and does what can be done if + no section is available. */ + +static enum sh64_elf_cr_type +sh64_get_contents_type_disasm (memaddr, info) + bfd_vma memaddr; + struct disassemble_info *info; +{ + struct sh64_disassemble_info *sh64_infop = info->private_data; + + /* Perhaps we have a region from a previous probe and it still counts + for this address? */ + if (sh64_infop->crange.cr_type != CRT_NONE + && memaddr >= sh64_infop->crange.cr_addr + && memaddr < sh64_infop->crange.cr_addr + sh64_infop->crange.cr_size) + return sh64_infop->crange.cr_type; + + /* If we have a section, try and use it. */ + if (info->section + && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour) + { + enum sh64_elf_cr_type cr_type + = sh64_get_contents_type (info->section, memaddr, + &sh64_infop->crange); + + if (cr_type != CRT_NONE) + return cr_type; + } + + /* If we have symbols, we can try and get at a section from *that*. */ + if (info->symbols != NULL + && bfd_asymbol_flavour (info->symbols[0]) == bfd_target_elf_flavour + && ! bfd_is_und_section (bfd_get_section (info->symbols[0])) + && ! bfd_is_abs_section (bfd_get_section (info->symbols[0]))) + { + enum sh64_elf_cr_type cr_type + = sh64_get_contents_type (bfd_get_section (info->symbols[0]), + memaddr, &sh64_infop->crange); + + if (cr_type != CRT_NONE) + return cr_type; + } + + /* We can make a reasonable guess based on the st_other field of a + symbol; for a BranchTarget this is marked as STO_SH5_ISA32 and then + it's most probably code there. */ + if (info->symbols + && bfd_asymbol_flavour (info->symbols[0]) == bfd_target_elf_flavour + && elf_symbol_from (bfd_asymbol_bfd (info->symbols[0]), + info->symbols[0])->internal_elf_sym.st_other + == STO_SH5_ISA32) + return CRT_SH5_ISA32; + + /* If all else fails, guess this is code and guess on the low bit set. */ + return (memaddr & 1) == 1 ? CRT_SH5_ISA32 : CRT_SH5_ISA16; +} + +/* Initialize static and dynamic disassembly state. */ + +static boolean +init_sh64_disasm_info (info) + struct disassemble_info *info; +{ + struct sh64_disassemble_info *sh64_infop + = calloc (sizeof (*sh64_infop), 1); + + if (sh64_infop == NULL) + return false; + + info->private_data = sh64_infop; + + SAVED_MOVI_IMM (info) = 0; + SAVED_MOVI_R (info) = 255; + + if (shmedia_opcode_mask_table == NULL) + initialize_shmedia_opcode_mask_table (); + + return true; +} + +/* Main entry to disassemble SHmedia instructions, given an endian set in + INFO. Note that the simulator uses this as the main entry and does not + use any of the functions further below. */ + +int +print_insn_sh64x_media (memaddr, info) + bfd_vma memaddr; + struct disassemble_info *info; +{ + if (info->private_data == NULL && ! init_sh64_disasm_info (info)) + return -1; + + /* Make reasonable output. */ + info->bytes_per_line = 4; + info->bytes_per_chunk = 4; + + return print_insn_shmedia (memaddr, info); +} + +/* Main entry to disassemble SHcompact or SHmedia insns. */ + +static int +print_insn_sh64x (memaddr, info, pfun_compact, endian) + bfd_vma memaddr; + struct disassemble_info *info; + int (*pfun_compact) PARAMS ((bfd_vma, struct disassemble_info *)); + enum bfd_endian endian; +{ + enum sh64_elf_cr_type cr_type; + + if (info->private_data == NULL && ! init_sh64_disasm_info (info)) + return -1; + + cr_type = sh64_get_contents_type_disasm (memaddr, info); + if (cr_type != CRT_SH5_ISA16) + { + int length = 4 - (memaddr % 4); + info->display_endian = endian; + + /* Only disassemble on four-byte boundaries. Addresses that are not + a multiple of four can happen after a data region. */ + if (cr_type == CRT_SH5_ISA32 && length == 4) + return print_insn_sh64x_media (memaddr, info); + + /* We get CRT_DATA *only* for data regions in a mixed-contents + section. For sections with data only, we get indication of one + of the ISA:s. You may think that we shouldn't disassemble + section with only data if we can figure that out. However, the + disassembly function is by default not called for data-only + sections, so if the user explicitly specified disassembly of a + data section, that's what we should do. */ + if (cr_type == CRT_DATA || length != 4) + { + int status; + unsigned char data[4]; + struct sh64_disassemble_info *sh64_infop = info->private_data; + + if (length == 4 + && sh64_infop->crange.cr_type != CRT_NONE + && memaddr >= sh64_infop->crange.cr_addr + && memaddr < (sh64_infop->crange.cr_addr + + sh64_infop->crange.cr_size)) + length + = (sh64_infop->crange.cr_addr + + sh64_infop->crange.cr_size - memaddr); + + status + = (*info->read_memory_func) (memaddr, data, + length >= 4 ? 4 : length, info); + + if (status == 0 && length >= 4) + { + (*info->fprintf_func) (info->stream, ".long 0x%08lx", + endian == BFD_ENDIAN_BIG + ? (long) (bfd_getb32 (data)) + : (long) (bfd_getl32 (data))); + return 4; + } + else + { + int i; + + for (i = 0; i < length; i++) + { + status = info->read_memory_func (memaddr + i, data, 1, info); + if (status != 0) + break; + (*info->fprintf_func) (info->stream, "%s0x%02x", + i == 0 ? ".byte " : ", ", + data[0]); + } + + return i ? i : -1; + } + } + } + + return (*pfun_compact) (memaddr, info); +} + +/* Main entry to disassemble SHcompact or SHmedia insns, big endian. */ + +int +print_insn_sh64 (memaddr, info) + bfd_vma memaddr; + struct disassemble_info *info; +{ + return + print_insn_sh64x (memaddr, info, print_insn_sh, BFD_ENDIAN_BIG); +} + +/* Main entry to disassemble SHcompact or SHmedia insns, little endian. */ + +int +print_insn_sh64l (memaddr, info) + bfd_vma memaddr; + struct disassemble_info *info; +{ + return + print_insn_sh64x (memaddr, info, print_insn_shl, BFD_ENDIAN_LITTLE); +} |