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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [opcodes/] [tic54x-dis.c] - Diff between revs 156 and 816

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

Rev 156 Rev 816
/* Disassembly routines for TMS320C54X architecture
/* Disassembly routines for TMS320C54X architecture
   Copyright 1999, 2000, 2001, 2007 Free Software Foundation, Inc.
   Copyright 1999, 2000, 2001, 2007 Free Software Foundation, Inc.
   Contributed by Timothy Wall (twall@cygnus.com)
   Contributed by Timothy Wall (twall@cygnus.com)
 
 
   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 <errno.h>
#include <errno.h>
#include <math.h>
#include <math.h>
#include <stdlib.h>
#include <stdlib.h>
#include "sysdep.h"
#include "sysdep.h"
#include "dis-asm.h"
#include "dis-asm.h"
#include "opcode/tic54x.h"
#include "opcode/tic54x.h"
#include "coff/tic54x.h"
#include "coff/tic54x.h"
 
 
static int has_lkaddr (unsigned short, const template *);
static int has_lkaddr (unsigned short, const template *);
static int get_insn_size (unsigned short, const template *);
static int get_insn_size (unsigned short, const template *);
static int print_instruction (disassemble_info *, bfd_vma,
static int print_instruction (disassemble_info *, bfd_vma,
                              unsigned short, const char *,
                              unsigned short, const char *,
                              const enum optype [], int, int);
                              const enum optype [], int, int);
static int print_parallel_instruction (disassemble_info *, bfd_vma,
static int print_parallel_instruction (disassemble_info *, bfd_vma,
                                       unsigned short,
                                       unsigned short,
                                       const template *, int);
                                       const template *, int);
static int sprint_dual_address (disassemble_info *,char [],
static int sprint_dual_address (disassemble_info *,char [],
                                unsigned short);
                                unsigned short);
static int sprint_indirect_address (disassemble_info *,char [],
static int sprint_indirect_address (disassemble_info *,char [],
                                    unsigned short);
                                    unsigned short);
static int sprint_direct_address (disassemble_info *,char [],
static int sprint_direct_address (disassemble_info *,char [],
                                  unsigned short);
                                  unsigned short);
static int sprint_mmr (disassemble_info *,char [],int);
static int sprint_mmr (disassemble_info *,char [],int);
static int sprint_condition (disassemble_info *,char *,unsigned short);
static int sprint_condition (disassemble_info *,char *,unsigned short);
static int sprint_cc2 (disassemble_info *,char *,unsigned short);
static int sprint_cc2 (disassemble_info *,char *,unsigned short);
 
 
int
int
print_insn_tic54x (bfd_vma memaddr, disassemble_info *info)
print_insn_tic54x (bfd_vma memaddr, disassemble_info *info)
{
{
  bfd_byte opbuf[2];
  bfd_byte opbuf[2];
  unsigned short opcode;
  unsigned short opcode;
  int status, size;
  int status, size;
  const template* tm;
  const template* tm;
 
 
  status = (*info->read_memory_func) (memaddr, opbuf, 2, info);
  status = (*info->read_memory_func) (memaddr, opbuf, 2, info);
  if (status != 0)
  if (status != 0)
  {
  {
    (*info->memory_error_func) (status, memaddr, info);
    (*info->memory_error_func) (status, memaddr, info);
    return -1;
    return -1;
  }
  }
 
 
  opcode = bfd_getl16 (opbuf);
  opcode = bfd_getl16 (opbuf);
  tm = tic54x_get_insn (info, memaddr, opcode, &size);
  tm = tic54x_get_insn (info, memaddr, opcode, &size);
 
 
  info->bytes_per_line = 2;
  info->bytes_per_line = 2;
  info->bytes_per_chunk = 2;
  info->bytes_per_chunk = 2;
  info->octets_per_byte = 2;
  info->octets_per_byte = 2;
  info->display_endian = BFD_ENDIAN_LITTLE;
  info->display_endian = BFD_ENDIAN_LITTLE;
 
 
  if (tm->flags & FL_PAR)
  if (tm->flags & FL_PAR)
  {
  {
    if (!print_parallel_instruction (info, memaddr, opcode, tm, size))
    if (!print_parallel_instruction (info, memaddr, opcode, tm, size))
      return -1;
      return -1;
  }
  }
  else
  else
  {
  {
    if (!print_instruction (info, memaddr, opcode,
    if (!print_instruction (info, memaddr, opcode,
                            (char *) tm->name,
                            (char *) tm->name,
                            tm->operand_types,
                            tm->operand_types,
                            size, (tm->flags & FL_EXT)))
                            size, (tm->flags & FL_EXT)))
      return -1;
      return -1;
  }
  }
 
 
  return size * 2;
  return size * 2;
}
}
 
 
static int
static int
has_lkaddr (unsigned short memdata, const template *tm)
has_lkaddr (unsigned short memdata, const template *tm)
{
{
  return (IS_LKADDR (memdata)
  return (IS_LKADDR (memdata)
          && (OPTYPE (tm->operand_types[0]) == OP_Smem
          && (OPTYPE (tm->operand_types[0]) == OP_Smem
              || OPTYPE (tm->operand_types[1]) == OP_Smem
              || OPTYPE (tm->operand_types[1]) == OP_Smem
              || OPTYPE (tm->operand_types[2]) == OP_Smem
              || OPTYPE (tm->operand_types[2]) == OP_Smem
              || OPTYPE (tm->operand_types[1]) == OP_Sind
              || OPTYPE (tm->operand_types[1]) == OP_Sind
              || OPTYPE (tm->operand_types[0]) == OP_Lmem
              || OPTYPE (tm->operand_types[0]) == OP_Lmem
              || OPTYPE (tm->operand_types[1]) == OP_Lmem));
              || OPTYPE (tm->operand_types[1]) == OP_Lmem));
}
}
 
 
/* always returns 1 (whether an insn template was found) since we provide an
/* always returns 1 (whether an insn template was found) since we provide an
   "unknown instruction" template */
   "unknown instruction" template */
const template*
const template*
tic54x_get_insn (disassemble_info *info, bfd_vma addr,
tic54x_get_insn (disassemble_info *info, bfd_vma addr,
                 unsigned short memdata, int *size)
                 unsigned short memdata, int *size)
{
{
  const template *tm = NULL;
  const template *tm = NULL;
 
 
  for (tm = tic54x_optab; tm->name; tm++)
  for (tm = tic54x_optab; tm->name; tm++)
  {
  {
    if (tm->opcode == (memdata & tm->mask))
    if (tm->opcode == (memdata & tm->mask))
    {
    {
      /* a few opcodes span two words */
      /* a few opcodes span two words */
      if (tm->flags & FL_EXT)
      if (tm->flags & FL_EXT)
        {
        {
          /* if lk addressing is used, the second half of the opcode gets
          /* if lk addressing is used, the second half of the opcode gets
             pushed one word later */
             pushed one word later */
          bfd_byte opbuf[2];
          bfd_byte opbuf[2];
          bfd_vma addr2 = addr + 1 + has_lkaddr (memdata, tm);
          bfd_vma addr2 = addr + 1 + has_lkaddr (memdata, tm);
          int status = (*info->read_memory_func) (addr2, opbuf, 2, info);
          int status = (*info->read_memory_func) (addr2, opbuf, 2, info);
          // FIXME handle errors
          // FIXME handle errors
          if (status == 0)
          if (status == 0)
            {
            {
              unsigned short data2 = bfd_getl16 (opbuf);
              unsigned short data2 = bfd_getl16 (opbuf);
              if (tm->opcode2 == (data2 & tm->mask2))
              if (tm->opcode2 == (data2 & tm->mask2))
                {
                {
                  if (size) *size = get_insn_size (memdata, tm);
                  if (size) *size = get_insn_size (memdata, tm);
                  return tm;
                  return tm;
                }
                }
            }
            }
        }
        }
      else
      else
        {
        {
          if (size) *size = get_insn_size (memdata, tm);
          if (size) *size = get_insn_size (memdata, tm);
          return tm;
          return tm;
        }
        }
    }
    }
  }
  }
  for (tm = (template *) tic54x_paroptab; tm->name; tm++)
  for (tm = (template *) tic54x_paroptab; tm->name; tm++)
  {
  {
    if (tm->opcode == (memdata & tm->mask))
    if (tm->opcode == (memdata & tm->mask))
    {
    {
      if (size) *size = get_insn_size (memdata, tm);
      if (size) *size = get_insn_size (memdata, tm);
      return tm;
      return tm;
    }
    }
  }
  }
 
 
  if (size) *size = 1;
  if (size) *size = 1;
  return &tic54x_unknown_opcode;
  return &tic54x_unknown_opcode;
}
}
 
 
static int
static int
get_insn_size (unsigned short memdata, const template *insn)
get_insn_size (unsigned short memdata, const template *insn)
{
{
  int size;
  int size;
 
 
  if (insn->flags & FL_PAR)
  if (insn->flags & FL_PAR)
    {
    {
      /* only non-parallel instructions support lk addressing */
      /* only non-parallel instructions support lk addressing */
      size = insn->words;
      size = insn->words;
    }
    }
  else
  else
    {
    {
      size = insn->words + has_lkaddr (memdata, insn);
      size = insn->words + has_lkaddr (memdata, insn);
    }
    }
 
 
  return size;
  return size;
}
}
 
 
int
int
print_instruction (info, memaddr, opcode, tm_name, tm_operands, size, ext)
print_instruction (info, memaddr, opcode, tm_name, tm_operands, size, ext)
  disassemble_info *info;
  disassemble_info *info;
  bfd_vma memaddr;
  bfd_vma memaddr;
  unsigned short opcode;
  unsigned short opcode;
  const char *tm_name;
  const char *tm_name;
  const enum optype tm_operands[];
  const enum optype tm_operands[];
  int size;
  int size;
  int ext;
  int ext;
{
{
  static int n;
  static int n;
  /* string storage for multiple operands */
  /* string storage for multiple operands */
  char operand[4][64] = { {0},{0},{0},{0}, };
  char operand[4][64] = { {0},{0},{0},{0}, };
  bfd_byte buf[2];
  bfd_byte buf[2];
  unsigned long opcode2 = 0;
  unsigned long opcode2 = 0;
  unsigned long lkaddr = 0;
  unsigned long lkaddr = 0;
  enum optype src = OP_None;
  enum optype src = OP_None;
  enum optype dst = OP_None;
  enum optype dst = OP_None;
  int i, shift;
  int i, shift;
  char *comma = "";
  char *comma = "";
 
 
  info->fprintf_func (info->stream, "%-7s", tm_name);
  info->fprintf_func (info->stream, "%-7s", tm_name);
 
 
  if (size > 1)
  if (size > 1)
    {
    {
      int status = (*info->read_memory_func) (memaddr + 1, buf, 2, info);
      int status = (*info->read_memory_func) (memaddr + 1, buf, 2, info);
      if (status != 0)
      if (status != 0)
        return 0;
        return 0;
      lkaddr = opcode2 = bfd_getl16 (buf);
      lkaddr = opcode2 = bfd_getl16 (buf);
      if (size > 2)
      if (size > 2)
        {
        {
          status = (*info->read_memory_func) (memaddr + 2, buf, 2, info);
          status = (*info->read_memory_func) (memaddr + 2, buf, 2, info);
          if (status != 0)
          if (status != 0)
            return 0;
            return 0;
          opcode2 = bfd_getl16 (buf);
          opcode2 = bfd_getl16 (buf);
        }
        }
    }
    }
 
 
  for (i = 0; i < MAX_OPERANDS && OPTYPE (tm_operands[i]) != OP_None; i++)
  for (i = 0; i < MAX_OPERANDS && OPTYPE (tm_operands[i]) != OP_None; i++)
    {
    {
      char *next_comma = ",";
      char *next_comma = ",";
      int optional = (tm_operands[i] & OPT) != 0;
      int optional = (tm_operands[i] & OPT) != 0;
 
 
      switch (OPTYPE (tm_operands[i]))
      switch (OPTYPE (tm_operands[i]))
        {
        {
        case OP_Xmem:
        case OP_Xmem:
          sprint_dual_address (info, operand[i], XMEM (opcode));
          sprint_dual_address (info, operand[i], XMEM (opcode));
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_Ymem:
        case OP_Ymem:
          sprint_dual_address (info, operand[i], YMEM (opcode));
          sprint_dual_address (info, operand[i], YMEM (opcode));
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_Smem:
        case OP_Smem:
        case OP_Sind:
        case OP_Sind:
        case OP_Lmem:
        case OP_Lmem:
          info->fprintf_func (info->stream, "%s", comma);
          info->fprintf_func (info->stream, "%s", comma);
          if (INDIRECT (opcode))
          if (INDIRECT (opcode))
            {
            {
              if (MOD (opcode) >= 12)
              if (MOD (opcode) >= 12)
                {
                {
                  bfd_vma addr = lkaddr;
                  bfd_vma addr = lkaddr;
                  int arf = ARF (opcode);
                  int arf = ARF (opcode);
                  int mod = MOD (opcode);
                  int mod = MOD (opcode);
                  if (mod == 15)
                  if (mod == 15)
                      info->fprintf_func (info->stream, "*(");
                      info->fprintf_func (info->stream, "*(");
                  else
                  else
                      info->fprintf_func (info->stream, "*%sar%d(",
                      info->fprintf_func (info->stream, "*%sar%d(",
                                          (mod == 13 || mod == 14 ? "+" : ""),
                                          (mod == 13 || mod == 14 ? "+" : ""),
                                          arf);
                                          arf);
                  (*(info->print_address_func)) ((bfd_vma) addr, info);
                  (*(info->print_address_func)) ((bfd_vma) addr, info);
                  info->fprintf_func (info->stream, ")%s",
                  info->fprintf_func (info->stream, ")%s",
                                      mod == 14 ? "%" : "");
                                      mod == 14 ? "%" : "");
                }
                }
              else
              else
                {
                {
                  sprint_indirect_address (info, operand[i], opcode);
                  sprint_indirect_address (info, operand[i], opcode);
                  info->fprintf_func (info->stream, "%s", operand[i]);
                  info->fprintf_func (info->stream, "%s", operand[i]);
                }
                }
            }
            }
          else
          else
          {
          {
            /* FIXME -- use labels (print_address_func) */
            /* FIXME -- use labels (print_address_func) */
            /* in order to do this, we need to guess what DP is */
            /* in order to do this, we need to guess what DP is */
            sprint_direct_address (info, operand[i], opcode);
            sprint_direct_address (info, operand[i], opcode);
            info->fprintf_func (info->stream, "%s", operand[i]);
            info->fprintf_func (info->stream, "%s", operand[i]);
          }
          }
          break;
          break;
        case OP_dmad:
        case OP_dmad:
          info->fprintf_func (info->stream, "%s", comma);
          info->fprintf_func (info->stream, "%s", comma);
          (*(info->print_address_func)) ((bfd_vma) opcode2, info);
          (*(info->print_address_func)) ((bfd_vma) opcode2, info);
          break;
          break;
        case OP_xpmad:
        case OP_xpmad:
          /* upper 7 bits of address are in the opcode */
          /* upper 7 bits of address are in the opcode */
          opcode2 += ((unsigned long) opcode & 0x7F) << 16;
          opcode2 += ((unsigned long) opcode & 0x7F) << 16;
          /* fall through */
          /* fall through */
        case OP_pmad:
        case OP_pmad:
          info->fprintf_func (info->stream, "%s", comma);
          info->fprintf_func (info->stream, "%s", comma);
          (*(info->print_address_func)) ((bfd_vma) opcode2, info);
          (*(info->print_address_func)) ((bfd_vma) opcode2, info);
          break;
          break;
        case OP_MMRX:
        case OP_MMRX:
          sprint_mmr (info, operand[i], MMRX (opcode));
          sprint_mmr (info, operand[i], MMRX (opcode));
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_MMRY:
        case OP_MMRY:
          sprint_mmr (info, operand[i], MMRY (opcode));
          sprint_mmr (info, operand[i], MMRY (opcode));
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_MMR:
        case OP_MMR:
          sprint_mmr (info, operand[i], MMR (opcode));
          sprint_mmr (info, operand[i], MMR (opcode));
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_PA:
        case OP_PA:
          sprintf (operand[i], "pa%d", (unsigned) opcode2);
          sprintf (operand[i], "pa%d", (unsigned) opcode2);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_SRC:
        case OP_SRC:
          src = SRC (ext ? opcode2 : opcode) ? OP_B : OP_A;
          src = SRC (ext ? opcode2 : opcode) ? OP_B : OP_A;
          sprintf (operand[i], (src == OP_B) ? "b" : "a");
          sprintf (operand[i], (src == OP_B) ? "b" : "a");
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_SRC1:
        case OP_SRC1:
          src = SRC1 (ext ? opcode2 : opcode) ? OP_B : OP_A;
          src = SRC1 (ext ? opcode2 : opcode) ? OP_B : OP_A;
          sprintf (operand[i], (src == OP_B) ? "b" : "a");
          sprintf (operand[i], (src == OP_B) ? "b" : "a");
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_RND:
        case OP_RND:
          dst = DST (opcode) ? OP_B : OP_A;
          dst = DST (opcode) ? OP_B : OP_A;
          sprintf (operand[i], (dst == OP_B) ? "a" : "b");
          sprintf (operand[i], (dst == OP_B) ? "a" : "b");
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_DST:
        case OP_DST:
          dst = DST (ext ? opcode2 : opcode) ? OP_B : OP_A;
          dst = DST (ext ? opcode2 : opcode) ? OP_B : OP_A;
          if (!optional || dst != src)
          if (!optional || dst != src)
            {
            {
              sprintf (operand[i], (dst == OP_B) ? "b" : "a");
              sprintf (operand[i], (dst == OP_B) ? "b" : "a");
              info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
              info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
            }
            }
          else
          else
            next_comma = comma;
            next_comma = comma;
          break;
          break;
        case OP_B:
        case OP_B:
          sprintf (operand[i], "b");
          sprintf (operand[i], "b");
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_A:
        case OP_A:
          sprintf (operand[i], "a");
          sprintf (operand[i], "a");
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_ARX:
        case OP_ARX:
          sprintf (operand[i], "ar%d", (int) ARX (opcode));
          sprintf (operand[i], "ar%d", (int) ARX (opcode));
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_SHIFT:
        case OP_SHIFT:
          shift = SHIFT (ext ? opcode2 : opcode);
          shift = SHIFT (ext ? opcode2 : opcode);
          if (!optional || shift != 0)
          if (!optional || shift != 0)
            {
            {
              sprintf (operand[i], "%d", shift);
              sprintf (operand[i], "%d", shift);
              info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
              info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
            }
            }
          else
          else
            next_comma = comma;
            next_comma = comma;
          break;
          break;
        case OP_SHFT:
        case OP_SHFT:
          shift = SHFT (opcode);
          shift = SHFT (opcode);
          if (!optional || shift != 0)
          if (!optional || shift != 0)
            {
            {
              sprintf (operand[i], "%d", (unsigned) shift);
              sprintf (operand[i], "%d", (unsigned) shift);
              info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
              info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
            }
            }
          else
          else
            next_comma = comma;
            next_comma = comma;
          break;
          break;
        case OP_lk:
        case OP_lk:
          sprintf (operand[i], "#%d", (int) (short) opcode2);
          sprintf (operand[i], "#%d", (int) (short) opcode2);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_T:
        case OP_T:
          sprintf (operand[i], "t");
          sprintf (operand[i], "t");
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_TS:
        case OP_TS:
          sprintf (operand[i], "ts");
          sprintf (operand[i], "ts");
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_k8:
        case OP_k8:
          sprintf (operand[i], "%d", (int) ((signed char) (opcode & 0xFF)));
          sprintf (operand[i], "%d", (int) ((signed char) (opcode & 0xFF)));
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_16:
        case OP_16:
          sprintf (operand[i], "16");
          sprintf (operand[i], "16");
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_ASM:
        case OP_ASM:
          sprintf (operand[i], "asm");
          sprintf (operand[i], "asm");
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_BITC:
        case OP_BITC:
          sprintf (operand[i], "%d", (int) (opcode & 0xF));
          sprintf (operand[i], "%d", (int) (opcode & 0xF));
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_CC:
        case OP_CC:
          /* put all CC operands in the same operand */
          /* put all CC operands in the same operand */
          sprint_condition (info, operand[i], opcode);
          sprint_condition (info, operand[i], opcode);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          i = MAX_OPERANDS;
          i = MAX_OPERANDS;
          break;
          break;
        case OP_CC2:
        case OP_CC2:
          sprint_cc2 (info, operand[i], opcode);
          sprint_cc2 (info, operand[i], opcode);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_CC3:
        case OP_CC3:
        {
        {
          const char *code[] = { "eq", "lt", "gt", "neq" };
          const char *code[] = { "eq", "lt", "gt", "neq" };
          sprintf (operand[i], code[CC3 (opcode)]);
          sprintf (operand[i], code[CC3 (opcode)]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        }
        }
        case OP_123:
        case OP_123:
          {
          {
            int code = (opcode >> 8) & 0x3;
            int code = (opcode >> 8) & 0x3;
            sprintf (operand[i], "%d", (code == 0) ? 1 : (code == 2) ? 2 : 3);
            sprintf (operand[i], "%d", (code == 0) ? 1 : (code == 2) ? 2 : 3);
            info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
            info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
            break;
            break;
          }
          }
        case OP_k5:
        case OP_k5:
          sprintf (operand[i], "#%d",
          sprintf (operand[i], "#%d",
                   (int) (((signed char) opcode & 0x1F) << 3) >> 3);
                   (int) (((signed char) opcode & 0x1F) << 3) >> 3);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_k8u:
        case OP_k8u:
          sprintf (operand[i], "#%d", (unsigned) (opcode & 0xFF));
          sprintf (operand[i], "#%d", (unsigned) (opcode & 0xFF));
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_k3:
        case OP_k3:
          sprintf (operand[i], "#%d", (int) (opcode & 0x7));
          sprintf (operand[i], "#%d", (int) (opcode & 0x7));
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_lku:
        case OP_lku:
          sprintf (operand[i], "#%d", (unsigned) opcode2);
          sprintf (operand[i], "#%d", (unsigned) opcode2);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_N:
        case OP_N:
          n = (opcode >> 9) & 0x1;
          n = (opcode >> 9) & 0x1;
          sprintf (operand[i], "st%d", n);
          sprintf (operand[i], "st%d", n);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_SBIT:
        case OP_SBIT:
        {
        {
          const char *status0[] = {
          const char *status0[] = {
            "0", "1", "2", "3", "4", "5", "6", "7", "8",
            "0", "1", "2", "3", "4", "5", "6", "7", "8",
            "ovb", "ova", "c", "tc", "13", "14", "15"
            "ovb", "ova", "c", "tc", "13", "14", "15"
          };
          };
          const char *status1[] = {
          const char *status1[] = {
            "0", "1", "2", "3", "4",
            "0", "1", "2", "3", "4",
            "cmpt", "frct", "c16", "sxm", "ovm", "10",
            "cmpt", "frct", "c16", "sxm", "ovm", "10",
            "intm", "hm", "xf", "cpl", "braf"
            "intm", "hm", "xf", "cpl", "braf"
          };
          };
          sprintf (operand[i], "%s",
          sprintf (operand[i], "%s",
                   n ? status1[SBIT (opcode)] : status0[SBIT (opcode)]);
                   n ? status1[SBIT (opcode)] : status0[SBIT (opcode)]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        }
        }
        case OP_12:
        case OP_12:
          sprintf (operand[i], "%d", (int) ((opcode >> 9) & 1) + 1);
          sprintf (operand[i], "%d", (int) ((opcode >> 9) & 1) + 1);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_TRN:
        case OP_TRN:
          sprintf (operand[i], "trn");
          sprintf (operand[i], "trn");
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_DP:
        case OP_DP:
          sprintf (operand[i], "dp");
          sprintf (operand[i], "dp");
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_k9:
        case OP_k9:
          /* FIXME-- this is DP, print the original address? */
          /* FIXME-- this is DP, print the original address? */
          sprintf (operand[i], "#%d", (int) (opcode & 0x1FF));
          sprintf (operand[i], "#%d", (int) (opcode & 0x1FF));
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_ARP:
        case OP_ARP:
          sprintf (operand[i], "arp");
          sprintf (operand[i], "arp");
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        case OP_031:
        case OP_031:
          sprintf (operand[i], "%d", (int) (opcode & 0x1F));
          sprintf (operand[i], "%d", (int) (opcode & 0x1F));
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        default:
        default:
          sprintf (operand[i], "??? (0x%x)", tm_operands[i]);
          sprintf (operand[i], "??? (0x%x)", tm_operands[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          info->fprintf_func (info->stream, "%s%s", comma, operand[i]);
          break;
          break;
        }
        }
      comma = next_comma;
      comma = next_comma;
    }
    }
  return 1;
  return 1;
}
}
 
 
static int
static int
print_parallel_instruction (info, memaddr, opcode, ptm, size)
print_parallel_instruction (info, memaddr, opcode, ptm, size)
  disassemble_info *info;
  disassemble_info *info;
  bfd_vma memaddr;
  bfd_vma memaddr;
  unsigned short opcode;
  unsigned short opcode;
  const template *ptm;
  const template *ptm;
  int size;
  int size;
{
{
  print_instruction (info, memaddr, opcode,
  print_instruction (info, memaddr, opcode,
                     ptm->name, ptm->operand_types, size, 0);
                     ptm->name, ptm->operand_types, size, 0);
  info->fprintf_func (info->stream, " || ");
  info->fprintf_func (info->stream, " || ");
  return print_instruction (info, memaddr, opcode,
  return print_instruction (info, memaddr, opcode,
                            ptm->parname, ptm->paroperand_types, size, 0);
                            ptm->parname, ptm->paroperand_types, size, 0);
}
}
 
 
static int
static int
sprint_dual_address (info, buf, code)
sprint_dual_address (info, buf, code)
  disassemble_info *info ATTRIBUTE_UNUSED;
  disassemble_info *info ATTRIBUTE_UNUSED;
  char buf[];
  char buf[];
  unsigned short code;
  unsigned short code;
{
{
  const char *formats[] = {
  const char *formats[] = {
    "*ar%d",
    "*ar%d",
    "*ar%d-",
    "*ar%d-",
    "*ar%d+",
    "*ar%d+",
    "*ar%d+0%%",
    "*ar%d+0%%",
  };
  };
  return sprintf (buf, formats[XMOD (code)], XARX (code));
  return sprintf (buf, formats[XMOD (code)], XARX (code));
}
}
 
 
static int
static int
sprint_indirect_address (info, buf, opcode)
sprint_indirect_address (info, buf, opcode)
  disassemble_info *info ATTRIBUTE_UNUSED;
  disassemble_info *info ATTRIBUTE_UNUSED;
  char buf[];
  char buf[];
  unsigned short opcode;
  unsigned short opcode;
{
{
  const char *formats[] = {
  const char *formats[] = {
    "*ar%d",
    "*ar%d",
    "*ar%d-",
    "*ar%d-",
    "*ar%d+",
    "*ar%d+",
    "*+ar%d",
    "*+ar%d",
    "*ar%d-0B",
    "*ar%d-0B",
    "*ar%d-0",
    "*ar%d-0",
    "*ar%d+0",
    "*ar%d+0",
    "*ar%d+0B",
    "*ar%d+0B",
    "*ar%d-%%",
    "*ar%d-%%",
    "*ar%d-0%%",
    "*ar%d-0%%",
    "*ar%d+%%",
    "*ar%d+%%",
    "*ar%d+0%%",
    "*ar%d+0%%",
  };
  };
  return sprintf (buf, formats[MOD (opcode)], ARF (opcode));
  return sprintf (buf, formats[MOD (opcode)], ARF (opcode));
}
}
 
 
static int
static int
sprint_direct_address (info, buf, opcode)
sprint_direct_address (info, buf, opcode)
  disassemble_info *info ATTRIBUTE_UNUSED;
  disassemble_info *info ATTRIBUTE_UNUSED;
  char buf[];
  char buf[];
  unsigned short opcode;
  unsigned short opcode;
{
{
  /* FIXME -- look up relocation if available */
  /* FIXME -- look up relocation if available */
  return sprintf (buf, "DP+0x%02x", (int) (opcode & 0x7F));
  return sprintf (buf, "DP+0x%02x", (int) (opcode & 0x7F));
}
}
 
 
static int
static int
sprint_mmr (info, buf, mmr)
sprint_mmr (info, buf, mmr)
  disassemble_info *info ATTRIBUTE_UNUSED;
  disassemble_info *info ATTRIBUTE_UNUSED;
  char buf[];
  char buf[];
  int mmr;
  int mmr;
{
{
  symbol *reg = (symbol *) mmregs;
  symbol *reg = (symbol *) mmregs;
  while (reg->name != NULL)
  while (reg->name != NULL)
    {
    {
      if (mmr == reg->value)
      if (mmr == reg->value)
        {
        {
          sprintf (buf, "%s", (reg + 1)->name);
          sprintf (buf, "%s", (reg + 1)->name);
          return 1;
          return 1;
        }
        }
      ++reg;
      ++reg;
    }
    }
  sprintf (buf, "MMR(%d)", mmr); /* FIXME -- different targets.  */
  sprintf (buf, "MMR(%d)", mmr); /* FIXME -- different targets.  */
  return 0;
  return 0;
}
}
 
 
static int
static int
sprint_cc2 (info, buf, opcode)
sprint_cc2 (info, buf, opcode)
  disassemble_info *info ATTRIBUTE_UNUSED;
  disassemble_info *info ATTRIBUTE_UNUSED;
  char *buf;
  char *buf;
  unsigned short opcode;
  unsigned short opcode;
{
{
  const char *cc2[] = {
  const char *cc2[] = {
    "??", "??", "ageq", "alt", "aneq", "aeq", "agt", "aleq",
    "??", "??", "ageq", "alt", "aneq", "aeq", "agt", "aleq",
    "??", "??", "bgeq", "blt", "bneq", "beq", "bgt", "bleq",
    "??", "??", "bgeq", "blt", "bneq", "beq", "bgt", "bleq",
  };
  };
  return sprintf (buf, "%s", cc2[opcode & 0xF]);
  return sprintf (buf, "%s", cc2[opcode & 0xF]);
}
}
 
 
static int
static int
sprint_condition (info, buf, opcode)
sprint_condition (info, buf, opcode)
  disassemble_info *info ATTRIBUTE_UNUSED;
  disassemble_info *info ATTRIBUTE_UNUSED;
  char *buf;
  char *buf;
  unsigned short opcode;
  unsigned short opcode;
{
{
  char *start = buf;
  char *start = buf;
  const char *cmp[] = {
  const char *cmp[] = {
      "??", "??", "geq", "lt", "neq", "eq", "gt", "leq"
      "??", "??", "geq", "lt", "neq", "eq", "gt", "leq"
  };
  };
  if (opcode & 0x40)
  if (opcode & 0x40)
    {
    {
      char acc = (opcode & 0x8) ? 'b' : 'a';
      char acc = (opcode & 0x8) ? 'b' : 'a';
      if (opcode & 0x7)
      if (opcode & 0x7)
          buf += sprintf (buf, "%c%s%s", acc, cmp[(opcode & 0x7)],
          buf += sprintf (buf, "%c%s%s", acc, cmp[(opcode & 0x7)],
                          (opcode & 0x20) ? ", " : "");
                          (opcode & 0x20) ? ", " : "");
      if (opcode & 0x20)
      if (opcode & 0x20)
          buf += sprintf (buf, "%c%s", acc, (opcode & 0x10) ? "ov" : "nov");
          buf += sprintf (buf, "%c%s", acc, (opcode & 0x10) ? "ov" : "nov");
    }
    }
  else if (opcode & 0x3F)
  else if (opcode & 0x3F)
    {
    {
      if (opcode & 0x30)
      if (opcode & 0x30)
        buf += sprintf (buf, "%s%s",
        buf += sprintf (buf, "%s%s",
                        ((opcode & 0x30) == 0x30) ? "tc" : "ntc",
                        ((opcode & 0x30) == 0x30) ? "tc" : "ntc",
                        (opcode & 0x0F) ? ", " : "");
                        (opcode & 0x0F) ? ", " : "");
      if (opcode & 0x0C)
      if (opcode & 0x0C)
        buf += sprintf (buf, "%s%s",
        buf += sprintf (buf, "%s%s",
                        ((opcode & 0x0C) == 0x0C) ? "c" : "nc",
                        ((opcode & 0x0C) == 0x0C) ? "c" : "nc",
                        (opcode & 0x03) ? ", " : "");
                        (opcode & 0x03) ? ", " : "");
      if (opcode & 0x03)
      if (opcode & 0x03)
        buf += sprintf (buf, "%s",
        buf += sprintf (buf, "%s",
                        ((opcode & 0x03) == 0x03) ? "bio" : "nbio");
                        ((opcode & 0x03) == 0x03) ? "bio" : "nbio");
    }
    }
  else
  else
    buf += sprintf (buf, "unc");
    buf += sprintf (buf, "unc");
 
 
  return buf - start;
  return buf - start;
}
}
 
 

powered by: WebSVN 2.1.0

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