OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [opcodes/] [z8k-dis.c] - Diff between revs 827 and 840

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 827 Rev 840
/* Disassemble z8000 code.
/* Disassemble z8000 code.
   Copyright 1992, 1993, 1998, 2000, 2001, 2002, 2003, 2005, 2007
   Copyright 1992, 1993, 1998, 2000, 2001, 2002, 2003, 2005, 2007
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
 
 
   This file is part of the GNU opcodes library.
   This file is part of the GNU opcodes library.
 
 
   This library is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   the Free Software Foundation; either version 3, or (at your option)
   any later version.
   any later version.
 
 
   It is distributed in the hope that it will be useful, but WITHOUT
   It is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   License for more details.
   License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this file; see the file COPYING.  If not, write to the
   along with this file; see the file COPYING.  If not, write to the
   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */
   MA 02110-1301, USA.  */
 
 
#include "sysdep.h"
#include "sysdep.h"
#include "dis-asm.h"
#include "dis-asm.h"
 
 
#define DEFINE_TABLE
#define DEFINE_TABLE
#include "z8k-opc.h"
#include "z8k-opc.h"
 
 
#include <setjmp.h>
#include <setjmp.h>
 
 
typedef struct
typedef struct
{
{
  /* These are all indexed by nibble number (i.e only every other entry
  /* These are all indexed by nibble number (i.e only every other entry
     of bytes is used, and every 4th entry of words).  */
     of bytes is used, and every 4th entry of words).  */
  unsigned char nibbles[24];
  unsigned char nibbles[24];
  unsigned char bytes[24];
  unsigned char bytes[24];
  unsigned short words[24];
  unsigned short words[24];
 
 
  /* Nibble number of first word not yet fetched.  */
  /* Nibble number of first word not yet fetched.  */
  int max_fetched;
  int max_fetched;
  bfd_vma insn_start;
  bfd_vma insn_start;
  jmp_buf bailout;
  jmp_buf bailout;
 
 
  int tabl_index;
  int tabl_index;
  char instr_asmsrc[80];
  char instr_asmsrc[80];
  unsigned long arg_reg[0x0f];
  unsigned long arg_reg[0x0f];
  unsigned long immediate;
  unsigned long immediate;
  unsigned long displacement;
  unsigned long displacement;
  unsigned long address;
  unsigned long address;
  unsigned long cond_code;
  unsigned long cond_code;
  unsigned long ctrl_code;
  unsigned long ctrl_code;
  unsigned long flags;
  unsigned long flags;
  unsigned long interrupts;
  unsigned long interrupts;
}
}
instr_data_s;
instr_data_s;
 
 
/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
   on error.  */
   on error.  */
#define FETCH_DATA(info, nibble) \
#define FETCH_DATA(info, nibble) \
  ((nibble) < ((instr_data_s *) (info->private_data))->max_fetched \
  ((nibble) < ((instr_data_s *) (info->private_data))->max_fetched \
   ? 1 : fetch_data ((info), (nibble)))
   ? 1 : fetch_data ((info), (nibble)))
 
 
static int
static int
fetch_data (struct disassemble_info *info, int nibble)
fetch_data (struct disassemble_info *info, int nibble)
{
{
  unsigned char mybuf[20];
  unsigned char mybuf[20];
  int status;
  int status;
  instr_data_s *priv = (instr_data_s *) info->private_data;
  instr_data_s *priv = (instr_data_s *) info->private_data;
 
 
  if ((nibble % 4) != 0)
  if ((nibble % 4) != 0)
    abort ();
    abort ();
 
 
  status = (*info->read_memory_func) (priv->insn_start,
  status = (*info->read_memory_func) (priv->insn_start,
                                      (bfd_byte *) mybuf,
                                      (bfd_byte *) mybuf,
                                      nibble / 2,
                                      nibble / 2,
                                      info);
                                      info);
  if (status != 0)
  if (status != 0)
    {
    {
      (*info->memory_error_func) (status, priv->insn_start, info);
      (*info->memory_error_func) (status, priv->insn_start, info);
      longjmp (priv->bailout, 1);
      longjmp (priv->bailout, 1);
    }
    }
 
 
  {
  {
    int i;
    int i;
    unsigned char *p = mybuf;
    unsigned char *p = mybuf;
 
 
    for (i = 0; i < nibble;)
    for (i = 0; i < nibble;)
      {
      {
        priv->words[i] = (p[0] << 8) | p[1];
        priv->words[i] = (p[0] << 8) | p[1];
 
 
        priv->bytes[i] = *p;
        priv->bytes[i] = *p;
        priv->nibbles[i++] = *p >> 4;
        priv->nibbles[i++] = *p >> 4;
        priv->nibbles[i++] = *p & 0xf;
        priv->nibbles[i++] = *p & 0xf;
 
 
        ++p;
        ++p;
        priv->bytes[i] = *p;
        priv->bytes[i] = *p;
        priv->nibbles[i++] = *p >> 4;
        priv->nibbles[i++] = *p >> 4;
        priv->nibbles[i++] = *p & 0xf;
        priv->nibbles[i++] = *p & 0xf;
 
 
        ++p;
        ++p;
      }
      }
  }
  }
  priv->max_fetched = nibble;
  priv->max_fetched = nibble;
  return 1;
  return 1;
}
}
 
 
static char *codes[16] =
static char *codes[16] =
  {
  {
    "f",
    "f",
    "lt",
    "lt",
    "le",
    "le",
    "ule",
    "ule",
    "ov/pe",
    "ov/pe",
    "mi",
    "mi",
    "eq",
    "eq",
    "c/ult",
    "c/ult",
    "t",
    "t",
    "ge",
    "ge",
    "gt",
    "gt",
    "ugt",
    "ugt",
    "nov/po",
    "nov/po",
    "pl",
    "pl",
    "ne",
    "ne",
    "nc/uge"
    "nc/uge"
  };
  };
 
 
static char *ctrl_names[8] =
static char *ctrl_names[8] =
  {
  {
    "<invld>",
    "<invld>",
    "flags",
    "flags",
    "fcw",
    "fcw",
    "refresh",
    "refresh",
    "psapseg",
    "psapseg",
    "psapoff",
    "psapoff",
    "nspseg",
    "nspseg",
    "nspoff"
    "nspoff"
  };
  };
 
 
static int seg_length;
static int seg_length;
int z8k_lookup_instr (unsigned char *, disassemble_info *);
int z8k_lookup_instr (unsigned char *, disassemble_info *);
static void output_instr (instr_data_s *, unsigned long, disassemble_info *);
static void output_instr (instr_data_s *, unsigned long, disassemble_info *);
static void unpack_instr (instr_data_s *, int, disassemble_info *);
static void unpack_instr (instr_data_s *, int, disassemble_info *);
static void unparse_instr (instr_data_s *, int);
static void unparse_instr (instr_data_s *, int);
 
 
static int
static int
print_insn_z8k (bfd_vma addr, disassemble_info *info, int is_segmented)
print_insn_z8k (bfd_vma addr, disassemble_info *info, int is_segmented)
{
{
  instr_data_s instr_data;
  instr_data_s instr_data;
 
 
  info->private_data = (PTR) &instr_data;
  info->private_data = (PTR) &instr_data;
  instr_data.max_fetched = 0;
  instr_data.max_fetched = 0;
  instr_data.insn_start = addr;
  instr_data.insn_start = addr;
  if (setjmp (instr_data.bailout) != 0)
  if (setjmp (instr_data.bailout) != 0)
    /* Error return.  */
    /* Error return.  */
    return -1;
    return -1;
 
 
  info->bytes_per_chunk = 2;
  info->bytes_per_chunk = 2;
  info->bytes_per_line = 6;
  info->bytes_per_line = 6;
  info->display_endian = BFD_ENDIAN_BIG;
  info->display_endian = BFD_ENDIAN_BIG;
 
 
  instr_data.tabl_index = z8k_lookup_instr (instr_data.nibbles, info);
  instr_data.tabl_index = z8k_lookup_instr (instr_data.nibbles, info);
  if (instr_data.tabl_index >= 0)
  if (instr_data.tabl_index >= 0)
    {
    {
      unpack_instr (&instr_data, is_segmented, info);
      unpack_instr (&instr_data, is_segmented, info);
      unparse_instr (&instr_data, is_segmented);
      unparse_instr (&instr_data, is_segmented);
      output_instr (&instr_data, addr, info);
      output_instr (&instr_data, addr, info);
      return z8k_table[instr_data.tabl_index].length + seg_length;
      return z8k_table[instr_data.tabl_index].length + seg_length;
    }
    }
  else
  else
    {
    {
      FETCH_DATA (info, 4);
      FETCH_DATA (info, 4);
      (*info->fprintf_func) (info->stream, ".word %02x%02x",
      (*info->fprintf_func) (info->stream, ".word %02x%02x",
                             instr_data.bytes[0], instr_data.bytes[2]);
                             instr_data.bytes[0], instr_data.bytes[2]);
      return 2;
      return 2;
    }
    }
}
}
 
 
int
int
print_insn_z8001 (bfd_vma addr, disassemble_info *info)
print_insn_z8001 (bfd_vma addr, disassemble_info *info)
{
{
  return print_insn_z8k (addr, info, 1);
  return print_insn_z8k (addr, info, 1);
}
}
 
 
int
int
print_insn_z8002 (bfd_vma addr, disassemble_info *info)
print_insn_z8002 (bfd_vma addr, disassemble_info *info)
{
{
  return print_insn_z8k (addr, info, 0);
  return print_insn_z8k (addr, info, 0);
}
}
 
 
int
int
z8k_lookup_instr (unsigned char *nibbles, disassemble_info *info)
z8k_lookup_instr (unsigned char *nibbles, disassemble_info *info)
{
{
  int nibl_index, tabl_index;
  int nibl_index, tabl_index;
  int nibl_matched;
  int nibl_matched;
  int need_fetch = 0;
  int need_fetch = 0;
  unsigned short instr_nibl;
  unsigned short instr_nibl;
  unsigned short tabl_datum, datum_class, datum_value;
  unsigned short tabl_datum, datum_class, datum_value;
 
 
  nibl_matched = 0;
  nibl_matched = 0;
  tabl_index = 0;
  tabl_index = 0;
  FETCH_DATA (info, 4);
  FETCH_DATA (info, 4);
  while (!nibl_matched && z8k_table[tabl_index].name)
  while (!nibl_matched && z8k_table[tabl_index].name)
    {
    {
      nibl_matched = 1;
      nibl_matched = 1;
      for (nibl_index = 0;
      for (nibl_index = 0;
           nibl_index < z8k_table[tabl_index].length * 2 && nibl_matched;
           nibl_index < z8k_table[tabl_index].length * 2 && nibl_matched;
           nibl_index++)
           nibl_index++)
        {
        {
          if ((nibl_index % 4) == 0)
          if ((nibl_index % 4) == 0)
            {
            {
              /* Fetch data only if it isn't already there.  */
              /* Fetch data only if it isn't already there.  */
              if (nibl_index >= 4 || (nibl_index < 4 && need_fetch))
              if (nibl_index >= 4 || (nibl_index < 4 && need_fetch))
                FETCH_DATA (info, nibl_index + 4);   /* Fetch one word at a time.  */
                FETCH_DATA (info, nibl_index + 4);   /* Fetch one word at a time.  */
              if (nibl_index < 4)
              if (nibl_index < 4)
                need_fetch = 0;
                need_fetch = 0;
              else
              else
                need_fetch = 1;
                need_fetch = 1;
            }
            }
          instr_nibl = nibbles[nibl_index];
          instr_nibl = nibbles[nibl_index];
 
 
          tabl_datum = z8k_table[tabl_index].byte_info[nibl_index];
          tabl_datum = z8k_table[tabl_index].byte_info[nibl_index];
          datum_class = tabl_datum & CLASS_MASK;
          datum_class = tabl_datum & CLASS_MASK;
          datum_value = ~CLASS_MASK & tabl_datum;
          datum_value = ~CLASS_MASK & tabl_datum;
 
 
          switch (datum_class)
          switch (datum_class)
            {
            {
            case CLASS_BIT:
            case CLASS_BIT:
              if (datum_value != instr_nibl)
              if (datum_value != instr_nibl)
                nibl_matched = 0;
                nibl_matched = 0;
              break;
              break;
            case CLASS_IGNORE:
            case CLASS_IGNORE:
              break;
              break;
            case CLASS_00II:
            case CLASS_00II:
              if (!((~instr_nibl) & 0x4))
              if (!((~instr_nibl) & 0x4))
                nibl_matched = 0;
                nibl_matched = 0;
              break;
              break;
            case CLASS_01II:
            case CLASS_01II:
              if (!(instr_nibl & 0x4))
              if (!(instr_nibl & 0x4))
                nibl_matched = 0;
                nibl_matched = 0;
              break;
              break;
            case CLASS_0CCC:
            case CLASS_0CCC:
              if (!((~instr_nibl) & 0x8))
              if (!((~instr_nibl) & 0x8))
                nibl_matched = 0;
                nibl_matched = 0;
              break;
              break;
            case CLASS_1CCC:
            case CLASS_1CCC:
              if (!(instr_nibl & 0x8))
              if (!(instr_nibl & 0x8))
                nibl_matched = 0;
                nibl_matched = 0;
              break;
              break;
            case CLASS_0DISP7:
            case CLASS_0DISP7:
              if (!((~instr_nibl) & 0x8))
              if (!((~instr_nibl) & 0x8))
                nibl_matched = 0;
                nibl_matched = 0;
              nibl_index += 1;
              nibl_index += 1;
              break;
              break;
            case CLASS_1DISP7:
            case CLASS_1DISP7:
              if (!(instr_nibl & 0x8))
              if (!(instr_nibl & 0x8))
                nibl_matched = 0;
                nibl_matched = 0;
              nibl_index += 1;
              nibl_index += 1;
              break;
              break;
            case CLASS_REGN0:
            case CLASS_REGN0:
              if (instr_nibl == 0)
              if (instr_nibl == 0)
                nibl_matched = 0;
                nibl_matched = 0;
              break;
              break;
            case CLASS_BIT_1OR2:
            case CLASS_BIT_1OR2:
              if ((instr_nibl | 0x2) != (datum_value | 0x2))
              if ((instr_nibl | 0x2) != (datum_value | 0x2))
                nibl_matched = 0;
                nibl_matched = 0;
              break;
              break;
            default:
            default:
              break;
              break;
            }
            }
        }
        }
 
 
      if (nibl_matched)
      if (nibl_matched)
        return tabl_index;
        return tabl_index;
 
 
      tabl_index++;
      tabl_index++;
    }
    }
  return -1;
  return -1;
}
}
 
 
static void
static void
output_instr (instr_data_s *instr_data,
output_instr (instr_data_s *instr_data,
              unsigned long addr ATTRIBUTE_UNUSED,
              unsigned long addr ATTRIBUTE_UNUSED,
              disassemble_info *info)
              disassemble_info *info)
{
{
  int num_bytes;
  int num_bytes;
  char out_str[100];
  char out_str[100];
 
 
  out_str[0] = 0;
  out_str[0] = 0;
 
 
  num_bytes = (z8k_table[instr_data->tabl_index].length + seg_length) * 2;
  num_bytes = (z8k_table[instr_data->tabl_index].length + seg_length) * 2;
  FETCH_DATA (info, num_bytes);
  FETCH_DATA (info, num_bytes);
 
 
  strcat (out_str, instr_data->instr_asmsrc);
  strcat (out_str, instr_data->instr_asmsrc);
 
 
  (*info->fprintf_func) (info->stream, "%s", out_str);
  (*info->fprintf_func) (info->stream, "%s", out_str);
}
}
 
 
static void
static void
unpack_instr (instr_data_s *instr_data, int is_segmented, disassemble_info *info)
unpack_instr (instr_data_s *instr_data, int is_segmented, disassemble_info *info)
{
{
  int nibl_count, loop;
  int nibl_count, loop;
  unsigned short instr_nibl, instr_byte, instr_word;
  unsigned short instr_nibl, instr_byte, instr_word;
  long instr_long;
  long instr_long;
  unsigned int tabl_datum, datum_class;
  unsigned int tabl_datum, datum_class;
  unsigned short datum_value;
  unsigned short datum_value;
 
 
  nibl_count = 0;
  nibl_count = 0;
  loop = 0;
  loop = 0;
  seg_length = 0;
  seg_length = 0;
 
 
  while (z8k_table[instr_data->tabl_index].byte_info[loop] != 0)
  while (z8k_table[instr_data->tabl_index].byte_info[loop] != 0)
    {
    {
      FETCH_DATA (info, nibl_count + 4 - (nibl_count % 4));
      FETCH_DATA (info, nibl_count + 4 - (nibl_count % 4));
      instr_nibl = instr_data->nibbles[nibl_count];
      instr_nibl = instr_data->nibbles[nibl_count];
      instr_byte = instr_data->bytes[nibl_count & ~1];
      instr_byte = instr_data->bytes[nibl_count & ~1];
      instr_word = instr_data->words[nibl_count & ~3];
      instr_word = instr_data->words[nibl_count & ~3];
 
 
      tabl_datum = z8k_table[instr_data->tabl_index].byte_info[loop];
      tabl_datum = z8k_table[instr_data->tabl_index].byte_info[loop];
      datum_class = tabl_datum & CLASS_MASK;
      datum_class = tabl_datum & CLASS_MASK;
      datum_value = tabl_datum & ~CLASS_MASK;
      datum_value = tabl_datum & ~CLASS_MASK;
 
 
      switch (datum_class)
      switch (datum_class)
        {
        {
        case CLASS_DISP:
        case CLASS_DISP:
          switch (datum_value)
          switch (datum_value)
            {
            {
            case ARG_DISP16:
            case ARG_DISP16:
              instr_data->displacement = instr_data->insn_start + 4
              instr_data->displacement = instr_data->insn_start + 4
                + (signed short) (instr_word & 0xffff);
                + (signed short) (instr_word & 0xffff);
              nibl_count += 3;
              nibl_count += 3;
              break;
              break;
            case ARG_DISP12:
            case ARG_DISP12:
              if (instr_word & 0x800)
              if (instr_word & 0x800)
                /* Negative 12 bit displacement.  */
                /* Negative 12 bit displacement.  */
                instr_data->displacement = instr_data->insn_start + 2
                instr_data->displacement = instr_data->insn_start + 2
                  - (signed short) ((instr_word & 0xfff) | 0xf000) * 2;
                  - (signed short) ((instr_word & 0xfff) | 0xf000) * 2;
              else
              else
                instr_data->displacement = instr_data->insn_start + 2
                instr_data->displacement = instr_data->insn_start + 2
                  - (instr_word & 0x0fff) * 2;
                  - (instr_word & 0x0fff) * 2;
 
 
              nibl_count += 2;
              nibl_count += 2;
              break;
              break;
            default:
            default:
              break;
              break;
            }
            }
          break;
          break;
        case CLASS_IMM:
        case CLASS_IMM:
          switch (datum_value)
          switch (datum_value)
            {
            {
            case ARG_IMM4:
            case ARG_IMM4:
              instr_data->immediate = instr_nibl;
              instr_data->immediate = instr_nibl;
              break;
              break;
            case ARG_NIM4:
            case ARG_NIM4:
              instr_data->immediate = (- instr_nibl) & 0xf;
              instr_data->immediate = (- instr_nibl) & 0xf;
              break;
              break;
            case ARG_NIM8:
            case ARG_NIM8:
              instr_data->immediate = (- instr_byte) & 0xff;
              instr_data->immediate = (- instr_byte) & 0xff;
              nibl_count += 1;
              nibl_count += 1;
              break;
              break;
            case ARG_IMM8:
            case ARG_IMM8:
              instr_data->immediate = instr_byte;
              instr_data->immediate = instr_byte;
              nibl_count += 1;
              nibl_count += 1;
              break;
              break;
            case ARG_IMM16:
            case ARG_IMM16:
              instr_data->immediate = instr_word;
              instr_data->immediate = instr_word;
              nibl_count += 3;
              nibl_count += 3;
              break;
              break;
            case ARG_IMM32:
            case ARG_IMM32:
              FETCH_DATA (info, nibl_count + 8);
              FETCH_DATA (info, nibl_count + 8);
              instr_long = (instr_data->words[nibl_count] << 16)
              instr_long = (instr_data->words[nibl_count] << 16)
                | (instr_data->words[nibl_count + 4]);
                | (instr_data->words[nibl_count + 4]);
              instr_data->immediate = instr_long;
              instr_data->immediate = instr_long;
              nibl_count += 7;
              nibl_count += 7;
              break;
              break;
            case ARG_IMMN:
            case ARG_IMMN:
              instr_data->immediate = instr_nibl - 1;
              instr_data->immediate = instr_nibl - 1;
              break;
              break;
            case ARG_IMM4M1:
            case ARG_IMM4M1:
              instr_data->immediate = instr_nibl + 1;
              instr_data->immediate = instr_nibl + 1;
              break;
              break;
            case ARG_IMM_1:
            case ARG_IMM_1:
              instr_data->immediate = 1;
              instr_data->immediate = 1;
              break;
              break;
            case ARG_IMM_2:
            case ARG_IMM_2:
              instr_data->immediate = 2;
              instr_data->immediate = 2;
              break;
              break;
            case ARG_IMM2:
            case ARG_IMM2:
              instr_data->immediate = instr_nibl & 0x3;
              instr_data->immediate = instr_nibl & 0x3;
              break;
              break;
            default:
            default:
              break;
              break;
            }
            }
          break;
          break;
        case CLASS_CC:
        case CLASS_CC:
          instr_data->cond_code = instr_nibl;
          instr_data->cond_code = instr_nibl;
          break;
          break;
        case CLASS_ADDRESS:
        case CLASS_ADDRESS:
          if (is_segmented)
          if (is_segmented)
            {
            {
              if (instr_nibl & 0x8)
              if (instr_nibl & 0x8)
                {
                {
                  FETCH_DATA (info, nibl_count + 8);
                  FETCH_DATA (info, nibl_count + 8);
                  instr_long = (instr_data->words[nibl_count] << 16)
                  instr_long = (instr_data->words[nibl_count] << 16)
                    | (instr_data->words[nibl_count + 4]);
                    | (instr_data->words[nibl_count + 4]);
                  instr_data->address = ((instr_word & 0x7f00) << 16)
                  instr_data->address = ((instr_word & 0x7f00) << 16)
                    + (instr_long & 0xffff);
                    + (instr_long & 0xffff);
                  nibl_count += 7;
                  nibl_count += 7;
                  seg_length = 2;
                  seg_length = 2;
                }
                }
              else
              else
                {
                {
                  instr_data->address = ((instr_word & 0x7f00) << 16)
                  instr_data->address = ((instr_word & 0x7f00) << 16)
                    + (instr_word & 0x00ff);
                    + (instr_word & 0x00ff);
                  nibl_count += 3;
                  nibl_count += 3;
                }
                }
            }
            }
          else
          else
            {
            {
              instr_data->address = instr_word;
              instr_data->address = instr_word;
              nibl_count += 3;
              nibl_count += 3;
            }
            }
          break;
          break;
        case CLASS_0CCC:
        case CLASS_0CCC:
        case CLASS_1CCC:
        case CLASS_1CCC:
          instr_data->ctrl_code = instr_nibl & 0x7;
          instr_data->ctrl_code = instr_nibl & 0x7;
          break;
          break;
        case CLASS_0DISP7:
        case CLASS_0DISP7:
          instr_data->displacement =
          instr_data->displacement =
            instr_data->insn_start + 2 - (instr_byte & 0x7f) * 2;
            instr_data->insn_start + 2 - (instr_byte & 0x7f) * 2;
          nibl_count += 1;
          nibl_count += 1;
          break;
          break;
        case CLASS_1DISP7:
        case CLASS_1DISP7:
          instr_data->displacement =
          instr_data->displacement =
            instr_data->insn_start + 2 - (instr_byte & 0x7f) * 2;
            instr_data->insn_start + 2 - (instr_byte & 0x7f) * 2;
          nibl_count += 1;
          nibl_count += 1;
          break;
          break;
        case CLASS_01II:
        case CLASS_01II:
          instr_data->interrupts = instr_nibl & 0x3;
          instr_data->interrupts = instr_nibl & 0x3;
          break;
          break;
        case CLASS_00II:
        case CLASS_00II:
          instr_data->interrupts = instr_nibl & 0x3;
          instr_data->interrupts = instr_nibl & 0x3;
          break;
          break;
        case CLASS_IGNORE:
        case CLASS_IGNORE:
        case CLASS_BIT:
        case CLASS_BIT:
          instr_data->ctrl_code = instr_nibl & 0x7;
          instr_data->ctrl_code = instr_nibl & 0x7;
          break;
          break;
        case CLASS_FLAGS:
        case CLASS_FLAGS:
          instr_data->flags = instr_nibl;
          instr_data->flags = instr_nibl;
          break;
          break;
        case CLASS_REG:
        case CLASS_REG:
          instr_data->arg_reg[datum_value] = instr_nibl;
          instr_data->arg_reg[datum_value] = instr_nibl;
          break;
          break;
        case CLASS_REGN0:
        case CLASS_REGN0:
          instr_data->arg_reg[datum_value] = instr_nibl;
          instr_data->arg_reg[datum_value] = instr_nibl;
          break;
          break;
        case CLASS_DISP8:
        case CLASS_DISP8:
          instr_data->displacement =
          instr_data->displacement =
            instr_data->insn_start + 2 + (signed char) instr_byte * 2;
            instr_data->insn_start + 2 + (signed char) instr_byte * 2;
          nibl_count += 1;
          nibl_count += 1;
          break;
          break;
        case CLASS_BIT_1OR2:
        case CLASS_BIT_1OR2:
          instr_data->immediate = ((instr_nibl >> 1) & 0x1) + 1;
          instr_data->immediate = ((instr_nibl >> 1) & 0x1) + 1;
          nibl_count += 1;
          nibl_count += 1;
          break;
          break;
        default:
        default:
          abort ();
          abort ();
          break;
          break;
        }
        }
 
 
      loop += 1;
      loop += 1;
      nibl_count += 1;
      nibl_count += 1;
    }
    }
}
}
 
 
static void
static void
print_intr(char *tmp_str, unsigned long interrupts)
print_intr(char *tmp_str, unsigned long interrupts)
{
{
  int comma = 0;
  int comma = 0;
 
 
  *tmp_str = 0;
  *tmp_str = 0;
  if (! (interrupts & 2))
  if (! (interrupts & 2))
    {
    {
      strcat (tmp_str, "vi");
      strcat (tmp_str, "vi");
      comma = 1;
      comma = 1;
    }
    }
  if (! (interrupts & 1))
  if (! (interrupts & 1))
    {
    {
      if (comma) strcat (tmp_str, ",");
      if (comma) strcat (tmp_str, ",");
      strcat (tmp_str, "nvi");
      strcat (tmp_str, "nvi");
    }
    }
}
}
 
 
static void
static void
print_flags(char *tmp_str, unsigned long flags)
print_flags(char *tmp_str, unsigned long flags)
{
{
  int comma = 0;
  int comma = 0;
 
 
  *tmp_str = 0;
  *tmp_str = 0;
  if (flags & 8)
  if (flags & 8)
    {
    {
      strcat (tmp_str, "c");
      strcat (tmp_str, "c");
      comma = 1;
      comma = 1;
    }
    }
  if (flags & 4)
  if (flags & 4)
    {
    {
      if (comma) strcat (tmp_str, ",");
      if (comma) strcat (tmp_str, ",");
      strcat (tmp_str, "z");
      strcat (tmp_str, "z");
      comma = 1;
      comma = 1;
    }
    }
  if (flags & 2)
  if (flags & 2)
    {
    {
      if (comma) strcat (tmp_str, ",");
      if (comma) strcat (tmp_str, ",");
      strcat (tmp_str, "s");
      strcat (tmp_str, "s");
      comma = 1;
      comma = 1;
    }
    }
  if (flags & 1)
  if (flags & 1)
    {
    {
      if (comma) strcat (tmp_str, ",");
      if (comma) strcat (tmp_str, ",");
      strcat (tmp_str, "p");
      strcat (tmp_str, "p");
    }
    }
}
}
 
 
static void
static void
unparse_instr (instr_data_s *instr_data, int is_segmented)
unparse_instr (instr_data_s *instr_data, int is_segmented)
{
{
  unsigned short datum_value;
  unsigned short datum_value;
  unsigned int tabl_datum, datum_class;
  unsigned int tabl_datum, datum_class;
  int loop, loop_limit;
  int loop, loop_limit;
  char out_str[80], tmp_str[25];
  char out_str[80], tmp_str[25];
 
 
  sprintf (out_str, "%s\t", z8k_table[instr_data->tabl_index].name);
  sprintf (out_str, "%s\t", z8k_table[instr_data->tabl_index].name);
 
 
  loop_limit = z8k_table[instr_data->tabl_index].noperands;
  loop_limit = z8k_table[instr_data->tabl_index].noperands;
  for (loop = 0; loop < loop_limit; loop++)
  for (loop = 0; loop < loop_limit; loop++)
    {
    {
      if (loop)
      if (loop)
        strcat (out_str, ",");
        strcat (out_str, ",");
 
 
      tabl_datum = z8k_table[instr_data->tabl_index].arg_info[loop];
      tabl_datum = z8k_table[instr_data->tabl_index].arg_info[loop];
      datum_class = tabl_datum & CLASS_MASK;
      datum_class = tabl_datum & CLASS_MASK;
      datum_value = tabl_datum & ~CLASS_MASK;
      datum_value = tabl_datum & ~CLASS_MASK;
 
 
      switch (datum_class)
      switch (datum_class)
        {
        {
        case CLASS_X:
        case CLASS_X:
          sprintf (tmp_str, "0x%0lx(r%ld)", instr_data->address,
          sprintf (tmp_str, "0x%0lx(r%ld)", instr_data->address,
                   instr_data->arg_reg[datum_value]);
                   instr_data->arg_reg[datum_value]);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        case CLASS_BA:
        case CLASS_BA:
          if (is_segmented)
          if (is_segmented)
            sprintf (tmp_str, "rr%ld(#0x%lx)", instr_data->arg_reg[datum_value],
            sprintf (tmp_str, "rr%ld(#0x%lx)", instr_data->arg_reg[datum_value],
                     instr_data->immediate);
                     instr_data->immediate);
          else
          else
            sprintf (tmp_str, "r%ld(#0x%lx)", instr_data->arg_reg[datum_value],
            sprintf (tmp_str, "r%ld(#0x%lx)", instr_data->arg_reg[datum_value],
                     instr_data->immediate);
                     instr_data->immediate);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        case CLASS_BX:
        case CLASS_BX:
          if (is_segmented)
          if (is_segmented)
            sprintf (tmp_str, "rr%ld(r%ld)", instr_data->arg_reg[datum_value],
            sprintf (tmp_str, "rr%ld(r%ld)", instr_data->arg_reg[datum_value],
                     instr_data->arg_reg[ARG_RX]);
                     instr_data->arg_reg[ARG_RX]);
          else
          else
            sprintf (tmp_str, "r%ld(r%ld)", instr_data->arg_reg[datum_value],
            sprintf (tmp_str, "r%ld(r%ld)", instr_data->arg_reg[datum_value],
                     instr_data->arg_reg[ARG_RX]);
                     instr_data->arg_reg[ARG_RX]);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        case CLASS_DISP:
        case CLASS_DISP:
          sprintf (tmp_str, "0x%0lx", instr_data->displacement);
          sprintf (tmp_str, "0x%0lx", instr_data->displacement);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        case CLASS_IMM:
        case CLASS_IMM:
          if (datum_value == ARG_IMM2)  /* True with EI/DI instructions only.  */
          if (datum_value == ARG_IMM2)  /* True with EI/DI instructions only.  */
            {
            {
              print_intr (tmp_str, instr_data->interrupts);
              print_intr (tmp_str, instr_data->interrupts);
              strcat (out_str, tmp_str);
              strcat (out_str, tmp_str);
              break;
              break;
            }
            }
          sprintf (tmp_str, "#0x%0lx", instr_data->immediate);
          sprintf (tmp_str, "#0x%0lx", instr_data->immediate);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        case CLASS_CC:
        case CLASS_CC:
          sprintf (tmp_str, "%s", codes[instr_data->cond_code]);
          sprintf (tmp_str, "%s", codes[instr_data->cond_code]);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        case CLASS_CTRL:
        case CLASS_CTRL:
          sprintf (tmp_str, "%s", ctrl_names[instr_data->ctrl_code]);
          sprintf (tmp_str, "%s", ctrl_names[instr_data->ctrl_code]);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        case CLASS_DA:
        case CLASS_DA:
        case CLASS_ADDRESS:
        case CLASS_ADDRESS:
          sprintf (tmp_str, "0x%0lx", instr_data->address);
          sprintf (tmp_str, "0x%0lx", instr_data->address);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        case CLASS_IR:
        case CLASS_IR:
          if (is_segmented)
          if (is_segmented)
            sprintf (tmp_str, "@rr%ld", instr_data->arg_reg[datum_value]);
            sprintf (tmp_str, "@rr%ld", instr_data->arg_reg[datum_value]);
          else
          else
            sprintf (tmp_str, "@r%ld", instr_data->arg_reg[datum_value]);
            sprintf (tmp_str, "@r%ld", instr_data->arg_reg[datum_value]);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        case CLASS_IRO:
        case CLASS_IRO:
          sprintf (tmp_str, "@r%ld", instr_data->arg_reg[datum_value]);
          sprintf (tmp_str, "@r%ld", instr_data->arg_reg[datum_value]);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        case CLASS_FLAGS:
        case CLASS_FLAGS:
          print_flags(tmp_str, instr_data->flags);
          print_flags(tmp_str, instr_data->flags);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        case CLASS_REG_BYTE:
        case CLASS_REG_BYTE:
          if (instr_data->arg_reg[datum_value] >= 0x8)
          if (instr_data->arg_reg[datum_value] >= 0x8)
            sprintf (tmp_str, "rl%ld",
            sprintf (tmp_str, "rl%ld",
                     instr_data->arg_reg[datum_value] - 0x8);
                     instr_data->arg_reg[datum_value] - 0x8);
          else
          else
            sprintf (tmp_str, "rh%ld", instr_data->arg_reg[datum_value]);
            sprintf (tmp_str, "rh%ld", instr_data->arg_reg[datum_value]);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        case CLASS_REG_WORD:
        case CLASS_REG_WORD:
          sprintf (tmp_str, "r%ld", instr_data->arg_reg[datum_value]);
          sprintf (tmp_str, "r%ld", instr_data->arg_reg[datum_value]);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        case CLASS_REG_QUAD:
        case CLASS_REG_QUAD:
          sprintf (tmp_str, "rq%ld", instr_data->arg_reg[datum_value]);
          sprintf (tmp_str, "rq%ld", instr_data->arg_reg[datum_value]);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        case CLASS_REG_LONG:
        case CLASS_REG_LONG:
          sprintf (tmp_str, "rr%ld", instr_data->arg_reg[datum_value]);
          sprintf (tmp_str, "rr%ld", instr_data->arg_reg[datum_value]);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        case CLASS_PR:
        case CLASS_PR:
          if (is_segmented)
          if (is_segmented)
            sprintf (tmp_str, "rr%ld", instr_data->arg_reg[datum_value]);
            sprintf (tmp_str, "rr%ld", instr_data->arg_reg[datum_value]);
          else
          else
            sprintf (tmp_str, "r%ld", instr_data->arg_reg[datum_value]);
            sprintf (tmp_str, "r%ld", instr_data->arg_reg[datum_value]);
          strcat (out_str, tmp_str);
          strcat (out_str, tmp_str);
          break;
          break;
        default:
        default:
          abort ();
          abort ();
          break;
          break;
        }
        }
    }
    }
 
 
  strcpy (instr_data->instr_asmsrc, out_str);
  strcpy (instr_data->instr_asmsrc, out_str);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.