summaryrefslogtreecommitdiff
path: root/opcodes/h8500-dis.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-12-23 14:38:46 +0000
committer <>2015-05-26 15:48:41 +0000
commit5500a97a2ad1735db5b35bc51cfb825c1f4c38df (patch)
treecc6e777c26142b88456ff03a672e1cb69215fc32 /opcodes/h8500-dis.c
downloadbinutils-tarball-5500a97a2ad1735db5b35bc51cfb825c1f4c38df.tar.gz
Imported from /home/lorry/working-area/delta_binutils-tarball/binutils-2.25.tar.bz2.HEADbinutils-2.25master
Diffstat (limited to 'opcodes/h8500-dis.c')
-rw-r--r--opcodes/h8500-dis.c325
1 files changed, 325 insertions, 0 deletions
diff --git a/opcodes/h8500-dis.c b/opcodes/h8500-dis.c
new file mode 100644
index 0000000..caa3020
--- /dev/null
+++ b/opcodes/h8500-dis.c
@@ -0,0 +1,325 @@
+/* Disassemble h8500 instructions.
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
+
+ This file is part of the GNU opcodes library.
+
+ This library 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 3, or (at your option)
+ any later version.
+
+ It 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., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include <stdio.h>
+
+#define DISASSEMBLER_TABLE
+#define DEFINE_TABLE
+
+#include "h8500-opc.h"
+#include "dis-asm.h"
+#include "opintl.h"
+
+/* Maximum length of an instruction. */
+#define MAXLEN 8
+
+#include <setjmp.h>
+
+struct private
+{
+ /* Points to first byte not fetched. */
+ bfd_byte *max_fetched;
+ bfd_byte the_buffer[MAXLEN];
+ bfd_vma insn_start;
+ OPCODES_SIGJMP_BUF bailout;
+};
+
+/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
+ to ADDR (exclusive) are valid. Returns 1 for success, longjmps
+ on error. */
+#define FETCH_DATA(info, addr) \
+ ((addr) <= ((struct private *)(info->private_data))->max_fetched \
+ ? 1 : fetch_data ((info), (addr)))
+
+static int
+fetch_data (struct disassemble_info *info, bfd_byte *addr)
+{
+ int status;
+ struct private *priv = (struct private *) info->private_data;
+ bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
+
+ status = (*info->read_memory_func) (start,
+ priv->max_fetched,
+ addr - priv->max_fetched,
+ info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, start, info);
+ OPCODES_SIGLONGJMP (priv->bailout, 1);
+ }
+ else
+ priv->max_fetched = addr;
+ return 1;
+}
+
+static char *crname[] = { "sr", "ccr", "*", "br", "ep", "dp", "*", "tp" };
+
+int
+print_insn_h8500 (bfd_vma addr, disassemble_info *info)
+{
+ const h8500_opcode_info *opcode;
+ void *stream = info->stream;
+ fprintf_ftype func = info->fprintf_func;
+ struct private priv;
+ bfd_byte *buffer = priv.the_buffer;
+
+ info->private_data = (PTR) & priv;
+ priv.max_fetched = priv.the_buffer;
+ priv.insn_start = addr;
+ if (OPCODES_SIGSETJMP (priv.bailout) != 0)
+ /* Error return. */
+ return -1;
+
+ /* Run down the table to find the one which matches. */
+ for (opcode = h8500_table; opcode->name; opcode++)
+ {
+ int byte;
+ int rn = 0;
+ int rd = 0;
+ int rs = 0;
+ int disp = 0;
+ int abs_val = 0;
+ int imm = 0;
+ int pcrel = 0;
+ int qim = 0;
+ int i;
+ int cr = 0;
+
+ for (byte = 0; byte < opcode->length; byte++)
+ {
+ FETCH_DATA (info, buffer + byte + 1);
+ if ((buffer[byte] & opcode->bytes[byte].mask)
+ != (opcode->bytes[byte].contents))
+ goto next;
+
+ else
+ {
+ /* Extract any info parts. */
+ switch (opcode->bytes[byte].insert)
+ {
+ case 0:
+ case FP:
+ break;
+ default:
+ /* xgettext:c-format */
+ func (stream, _("can't cope with insert %d\n"),
+ opcode->bytes[byte].insert);
+ break;
+ case RN:
+ rn = buffer[byte] & 0x7;
+ break;
+ case RS:
+ rs = buffer[byte] & 0x7;
+ break;
+ case CRB:
+ cr = buffer[byte] & 0x7;
+ if (cr == 0)
+ goto next;
+ break;
+ case CRW:
+ cr = buffer[byte] & 0x7;
+ if (cr != 0)
+ goto next;
+ break;
+ case DISP16:
+ FETCH_DATA (info, buffer + byte + 2);
+ disp = (buffer[byte] << 8) | (buffer[byte + 1]);
+ break;
+ case FPIND_D8:
+ case DISP8:
+ disp = ((char) (buffer[byte]));
+ break;
+ case RD:
+ case RDIND:
+ rd = buffer[byte] & 0x7;
+ break;
+ case ABS24:
+ FETCH_DATA (info, buffer + byte + 3);
+ abs_val =
+ (buffer[byte] << 16)
+ | (buffer[byte + 1] << 8)
+ | (buffer[byte + 2]);
+ break;
+ case ABS16:
+ FETCH_DATA (info, buffer + byte + 2);
+ abs_val = (buffer[byte] << 8) | (buffer[byte + 1]);
+ break;
+ case ABS8:
+ abs_val = (buffer[byte]);
+ break;
+ case IMM16:
+ FETCH_DATA (info, buffer + byte + 2);
+ imm = (buffer[byte] << 8) | (buffer[byte + 1]);
+ break;
+ case IMM4:
+ imm = (buffer[byte]) & 0xf;
+ break;
+ case IMM8:
+ case RLIST:
+ imm = (buffer[byte]);
+ break;
+ case PCREL16:
+ FETCH_DATA (info, buffer + byte + 2);
+ pcrel = (buffer[byte] << 8) | (buffer[byte + 1]);
+ break;
+ case PCREL8:
+ pcrel = (buffer[byte]);
+ break;
+ case QIM:
+ switch (buffer[byte] & 0x7)
+ {
+ case 0:
+ qim = 1;
+ break;
+ case 1:
+ qim = 2;
+ break;
+ case 4:
+ qim = -1;
+ break;
+ case 5:
+ qim = -2;
+ break;
+ }
+ break;
+
+ }
+ }
+ }
+ /* We get here when all the masks have passed so we can output
+ the operands. */
+ FETCH_DATA (info, buffer + opcode->length);
+ (func) (stream, "%s\t", opcode->name);
+ for (i = 0; i < opcode->nargs; i++)
+ {
+ if (i)
+ (func) (stream, ",");
+ switch (opcode->arg_type[i])
+ {
+ case FP:
+ func (stream, "fp");
+ break;
+ case RNIND_D16:
+ func (stream, "@(0x%x:16,r%d)", disp, rn);
+ break;
+ case RNIND_D8:
+ func (stream, "@(0x%x:8 (%d),r%d)", disp & 0xff, disp, rn);
+ break;
+ case RDIND_D16:
+ func (stream, "@(0x%x:16,r%d)", disp, rd);
+ break;
+ case RDIND_D8:
+ func (stream, "@(0x%x:8 (%d), r%d)", disp & 0xff, disp, rd);
+ break;
+ case FPIND_D8:
+ func (stream, "@(0x%x:8 (%d), fp)", disp & 0xff, disp);
+ break;
+ case CRB:
+ case CRW:
+ func (stream, "%s", crname[cr]);
+ break;
+ case RN:
+ func (stream, "r%d", rn);
+ break;
+ case RD:
+ func (stream, "r%d", rd);
+ break;
+ case RS:
+ func (stream, "r%d", rs);
+ break;
+ case RNDEC:
+ func (stream, "@-r%d", rn);
+ break;
+ case RNINC:
+ func (stream, "@r%d+", rn);
+ break;
+ case RNIND:
+ func (stream, "@r%d", rn);
+ break;
+ case RDIND:
+ func (stream, "@r%d", rd);
+ break;
+ case SPINC:
+ func (stream, "@sp+");
+ break;
+ case SPDEC:
+ func (stream, "@-sp");
+ break;
+ case ABS24:
+ func (stream, "@0x%0x:24", abs_val);
+ break;
+ case ABS16:
+ func (stream, "@0x%0x:16", abs_val & 0xffff);
+ break;
+ case ABS8:
+ func (stream, "@0x%0x:8", abs_val & 0xff);
+ break;
+ case IMM16:
+ func (stream, "#0x%0x:16", imm & 0xffff);
+ break;
+ case RLIST:
+ {
+ int j;
+ int nc = 0;
+
+ func (stream, "(");
+ for (j = 0; j < 8; j++)
+ {
+ if (imm & (1 << j))
+ {
+ func (stream, "r%d", j);
+ if (nc)
+ func (stream, ",");
+ nc = 1;
+ }
+ }
+ func (stream, ")");
+ }
+ break;
+ case IMM8:
+ func (stream, "#0x%0x:8", imm & 0xff);
+ break;
+ case PCREL16:
+ func (stream, "0x%0x:16",
+ (int)(pcrel + addr + opcode->length) & 0xffff);
+ break;
+ case PCREL8:
+ func (stream, "#0x%0x:8",
+ (int)((char) pcrel + addr + opcode->length) & 0xffff);
+ break;
+ case QIM:
+ func (stream, "#%d:q", qim);
+ break;
+ case IMM4:
+ func (stream, "#%d:4", imm);
+ break;
+ }
+ }
+ return opcode->length;
+ next:
+ ;
+ }
+
+ /* Couldn't understand anything. */
+ /* xgettext:c-format */
+ func (stream, _("%02x\t\t*unknown*"), buffer[0]);
+ return 1;
+}