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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [opcodes/] [tic54x-dis.c] - Diff between revs 578 and 1765

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

Rev 578 Rev 1765
/* Disassembly routines for TMS320C54X architecture
/* Disassembly routines for TMS320C54X architecture
   Copyright 1999, 2000 Free Software Foundation, Inc.
   Copyright 1999, 2000 Free Software Foundation, Inc.
   Contributed by Timothy Wall (twall@cygnus.com)
   Contributed by Timothy Wall (twall@cygnus.com)
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public 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 program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.  */
   02111-1307, 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"
 
 
typedef struct _instruction {
typedef struct _instruction {
  int parallel;
  int parallel;
  template *tm;
  template *tm;
  partemplate *ptm;
  partemplate *ptm;
} instruction;
} instruction;
 
 
static int get_insn_size PARAMS ((unsigned short, instruction *));
static int get_insn_size PARAMS ((unsigned short, instruction *));
static int get_instruction PARAMS ((disassemble_info *, bfd_vma,
static int get_instruction PARAMS ((disassemble_info *, bfd_vma,
                                    unsigned short, instruction *));
                                    unsigned short, instruction *));
static int print_instruction PARAMS ((disassemble_info *, bfd_vma,
static int print_instruction PARAMS ((disassemble_info *, bfd_vma,
                                      unsigned short, char *,
                                      unsigned short, char *,
                                      enum optype [], int, int));
                                      enum optype [], int, int));
static int print_parallel_instruction PARAMS ((disassemble_info *, bfd_vma,
static int print_parallel_instruction PARAMS ((disassemble_info *, bfd_vma,
                                               unsigned short, partemplate *,
                                               unsigned short, partemplate *,
                                               int));
                                               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(memaddr, info)
print_insn_tic54x(memaddr, info)
  bfd_vma memaddr;
  bfd_vma memaddr;
  disassemble_info *info;
  disassemble_info *info;
{
{
  bfd_byte opbuf[2];
  bfd_byte opbuf[2];
  unsigned short opcode;
  unsigned short opcode;
  int status, size;
  int status, size;
  instruction insn;
  instruction insn;
 
 
  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);
  if (!get_instruction (info, memaddr, opcode, &insn))
  if (!get_instruction (info, memaddr, opcode, &insn))
      return -1;
      return -1;
 
 
  size = get_insn_size (opcode, &insn);
  size = get_insn_size (opcode, &insn);
  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 (insn.parallel)
  if (insn.parallel)
  {
  {
    if (!print_parallel_instruction (info, memaddr, opcode, insn.ptm, size))
    if (!print_parallel_instruction (info, memaddr, opcode, insn.ptm, size))
      return -1;
      return -1;
  }
  }
  else
  else
  {
  {
    if (!print_instruction (info, memaddr, opcode,
    if (!print_instruction (info, memaddr, opcode,
                            (char *)insn.tm->name,
                            (char *)insn.tm->name,
                            insn.tm->operand_types,
                            insn.tm->operand_types,
                            size, (insn.tm->flags & FL_EXT)))
                            size, (insn.tm->flags & FL_EXT)))
      return -1;
      return -1;
  }
  }
 
 
  return size*2;
  return size*2;
}
}
 
 
static int
static int
has_lkaddr(opcode, tm)
has_lkaddr(opcode, tm)
  unsigned short opcode;
  unsigned short opcode;
  template *tm;
  template *tm;
{
{
  return IS_LKADDR(opcode) &&
  return IS_LKADDR(opcode) &&
    (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);
}
}
 
 
/* 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 */
static int
static int
get_instruction (info, addr, opcode, insn)
get_instruction (info, addr, opcode, insn)
  disassemble_info *info;
  disassemble_info *info;
  bfd_vma addr;
  bfd_vma addr;
  unsigned short opcode;
  unsigned short opcode;
  instruction *insn;
  instruction *insn;
{
{
  template * tm;
  template * tm;
  partemplate * ptm;
  partemplate * ptm;
 
 
  insn->parallel = 0;
  insn->parallel = 0;
  for (tm = (template *)tic54x_optab; tm->name; tm++)
  for (tm = (template *)tic54x_optab; tm->name; tm++)
  {
  {
    if (tm->opcode == (opcode & tm->mask))
    if (tm->opcode == (opcode & 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(opcode, tm);
          bfd_vma addr2 = addr + 1 + has_lkaddr(opcode, tm);
          int status = (*info->read_memory_func)(addr2, opbuf, 2, info);
          int status = (*info->read_memory_func)(addr2, opbuf, 2, info);
          if (status == 0)
          if (status == 0)
            {
            {
              unsigned short opcode2 = bfd_getl16(opbuf);
              unsigned short opcode2 = bfd_getl16(opbuf);
              if (tm->opcode2 == (opcode2 & tm->mask2))
              if (tm->opcode2 == (opcode2 & tm->mask2))
                {
                {
                  insn->tm = tm;
                  insn->tm = tm;
                  return 1;
                  return 1;
                }
                }
            }
            }
        }
        }
      else
      else
        {
        {
          insn->tm = tm;
          insn->tm = tm;
          return 1;
          return 1;
        }
        }
    }
    }
  }
  }
  for (ptm = (partemplate *)tic54x_paroptab; ptm->name; ptm++)
  for (ptm = (partemplate *)tic54x_paroptab; ptm->name; ptm++)
  {
  {
    if (ptm->opcode == (opcode & ptm->mask))
    if (ptm->opcode == (opcode & ptm->mask))
    {
    {
      insn->parallel = 1;
      insn->parallel = 1;
      insn->ptm = ptm;
      insn->ptm = ptm;
      return 1;
      return 1;
    }
    }
  }
  }
 
 
  insn->tm = (template *)&tic54x_unknown_opcode;
  insn->tm = (template *)&tic54x_unknown_opcode;
  return 1;
  return 1;
}
}
 
 
static int
static int
get_insn_size (opcode, insn)
get_insn_size (opcode, insn)
  unsigned short opcode;
  unsigned short opcode;
  instruction *insn;
  instruction *insn;
{
{
  int size;
  int size;
 
 
  if (insn->parallel)
  if (insn->parallel)
    {
    {
      /* only non-parallel instructions support lk addressing */
      /* only non-parallel instructions support lk addressing */
      size = insn->ptm->words;
      size = insn->ptm->words;
    }
    }
  else
  else
    {
    {
      size = insn->tm->words + has_lkaddr(opcode, insn->tm);
      size = insn->tm->words + has_lkaddr(opcode, insn->tm);
    }
    }
 
 
  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;
  char *tm_name;
  char *tm_name;
  enum optype tm_operands[];
  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, lkaddr;
  unsigned long opcode2, lkaddr;
  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;
  partemplate *ptm;
  partemplate *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;
  disassemble_info *info;
  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;
  disassemble_info *info;
  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;
  disassemble_info *info;
  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, "0x??%02x", (int)(opcode & 0x7F));
  return sprintf (buf, "0x??%02x", (int)(opcode & 0x7F));
}
}
 
 
static int
static int
sprint_mmr (info, buf, mmr)
sprint_mmr (info, buf, mmr)
  disassemble_info *info;
  disassemble_info *info;
  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;
  disassemble_info *info;
  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;
  disassemble_info *info;
  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.