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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [opcodes/] [i370-dis.c] - Diff between revs 330 and 816

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

Rev 330 Rev 816
/* i370-dis.c -- Disassemble Instruction 370 (ESA/390) instructions
/* i370-dis.c -- Disassemble Instruction 370 (ESA/390) instructions
   Copyright 1994, 2000, 2003, 2005, 2007  Free Software Foundation, Inc.
   Copyright 1994, 2000, 2003, 2005, 2007  Free Software Foundation, Inc.
   PowerPC version written by Ian Lance Taylor, Cygnus Support
   PowerPC version written by Ian Lance Taylor, Cygnus Support
   Rewritten for i370 ESA/390 support by Linas Vepstas <linas@linas.org>
   Rewritten for i370 ESA/390 support by Linas Vepstas <linas@linas.org>
 
 
   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 Free
   along with this file; see the file COPYING.  If not, write to the Free
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */
   MA 02110-1301, USA.  */
 
 
#include <stdio.h>
#include <stdio.h>
#include "sysdep.h"
#include "sysdep.h"
#include "dis-asm.h"
#include "dis-asm.h"
#include "opcode/i370.h"
#include "opcode/i370.h"
 
 
/* This file provides several disassembler functions, all of which use
/* This file provides several disassembler functions, all of which use
   the disassembler interface defined in dis-asm.h.  */
   the disassembler interface defined in dis-asm.h.  */
 
 
int
int
print_insn_i370 (bfd_vma memaddr, struct disassemble_info *info)
print_insn_i370 (bfd_vma memaddr, struct disassemble_info *info)
{
{
  bfd_byte buffer[8];
  bfd_byte buffer[8];
  int status;
  int status;
  i370_insn_t insn;
  i370_insn_t insn;
  const struct i370_opcode *opcode;
  const struct i370_opcode *opcode;
  const struct i370_opcode *opcode_end;
  const struct i370_opcode *opcode_end;
 
 
  status = (*info->read_memory_func) (memaddr, buffer, 6, info);
  status = (*info->read_memory_func) (memaddr, buffer, 6, 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;
    }
    }
 
 
  /* Cast the bytes into the insn (in a host-endian indep way).  */
  /* Cast the bytes into the insn (in a host-endian indep way).  */
  insn.i[0] = (buffer[0] << 24) & 0xff000000;
  insn.i[0] = (buffer[0] << 24) & 0xff000000;
  insn.i[0] |= (buffer[1] << 16) & 0xff0000;
  insn.i[0] |= (buffer[1] << 16) & 0xff0000;
  insn.i[0] |= (buffer[2] << 8) & 0xff00;
  insn.i[0] |= (buffer[2] << 8) & 0xff00;
  insn.i[0] |= buffer[3]  & 0xff;
  insn.i[0] |= buffer[3]  & 0xff;
  insn.i[1] = (buffer[4] << 24) & 0xff000000;
  insn.i[1] = (buffer[4] << 24) & 0xff000000;
  insn.i[1] |= (buffer[5] << 16) & 0xff0000;
  insn.i[1] |= (buffer[5] << 16) & 0xff0000;
 
 
  /* Find the first match in the opcode table.  We could speed this up
  /* Find the first match in the opcode table.  We could speed this up
     a bit by doing a binary search on the major opcode.  */
     a bit by doing a binary search on the major opcode.  */
  opcode_end = i370_opcodes + i370_num_opcodes;
  opcode_end = i370_opcodes + i370_num_opcodes;
  for (opcode = i370_opcodes; opcode < opcode_end; opcode++)
  for (opcode = i370_opcodes; opcode < opcode_end; opcode++)
    {
    {
      const unsigned char *opindex;
      const unsigned char *opindex;
      const struct i370_operand *operand;
      const struct i370_operand *operand;
      i370_insn_t masked;
      i370_insn_t masked;
      int invalid;
      int invalid;
 
 
      /* Mask off operands, and look for a match ... */
      /* Mask off operands, and look for a match ... */
      masked = insn;
      masked = insn;
      if (2 == opcode->len)
      if (2 == opcode->len)
        {
        {
          masked.i[0] >>= 16;
          masked.i[0] >>= 16;
          masked.i[0] &= 0xffff;
          masked.i[0] &= 0xffff;
        }
        }
      masked.i[0] &= opcode->mask.i[0];
      masked.i[0] &= opcode->mask.i[0];
      if (masked.i[0] != opcode->opcode.i[0])
      if (masked.i[0] != opcode->opcode.i[0])
        continue;
        continue;
 
 
      if (6 == opcode->len)
      if (6 == opcode->len)
        {
        {
          masked.i[1] &= opcode->mask.i[1];
          masked.i[1] &= opcode->mask.i[1];
          if (masked.i[1] != opcode->opcode.i[1])
          if (masked.i[1] != opcode->opcode.i[1])
            continue;
            continue;
        }
        }
 
 
      /* Found a match.  adjust a tad.  */
      /* Found a match.  adjust a tad.  */
      if (2 == opcode->len)
      if (2 == opcode->len)
        {
        {
          insn.i[0] >>= 16;
          insn.i[0] >>= 16;
          insn.i[0] &= 0xffff;
          insn.i[0] &= 0xffff;
        }
        }
 
 
      /* Make two passes over the operands.  First see if any of them
      /* Make two passes over the operands.  First see if any of them
         have extraction functions, and, if they do, make sure the
         have extraction functions, and, if they do, make sure the
         instruction is valid.  */
         instruction is valid.  */
      invalid = 0;
      invalid = 0;
      for (opindex = opcode->operands; *opindex != 0; opindex++)
      for (opindex = opcode->operands; *opindex != 0; opindex++)
        {
        {
          operand = i370_operands + *opindex;
          operand = i370_operands + *opindex;
          if (operand->extract)
          if (operand->extract)
            (*operand->extract) (insn, &invalid);
            (*operand->extract) (insn, &invalid);
        }
        }
      if (invalid)
      if (invalid)
        continue;
        continue;
 
 
      /* The instruction is valid.  */
      /* The instruction is valid.  */
      (*info->fprintf_func) (info->stream, "%s", opcode->name);
      (*info->fprintf_func) (info->stream, "%s", opcode->name);
      if (opcode->operands[0] != 0)
      if (opcode->operands[0] != 0)
        (*info->fprintf_func) (info->stream, "\t");
        (*info->fprintf_func) (info->stream, "\t");
 
 
      /* Now extract and print the operands.  */
      /* Now extract and print the operands.  */
      for (opindex = opcode->operands; *opindex != 0; opindex++)
      for (opindex = opcode->operands; *opindex != 0; opindex++)
        {
        {
          long value;
          long value;
 
 
          operand = i370_operands + *opindex;
          operand = i370_operands + *opindex;
 
 
          /* Extract the value from the instruction.  */
          /* Extract the value from the instruction.  */
          if (operand->extract)
          if (operand->extract)
            value = (*operand->extract) (insn, (int *) NULL);
            value = (*operand->extract) (insn, (int *) NULL);
          else
          else
            value = (insn.i[0] >> operand->shift) & ((1 << operand->bits) - 1);
            value = (insn.i[0] >> operand->shift) & ((1 << operand->bits) - 1);
 
 
          /* Print the operand as directed by the flags.  */
          /* Print the operand as directed by the flags.  */
          if ((operand->flags & I370_OPERAND_OPTIONAL) != 0)
          if ((operand->flags & I370_OPERAND_OPTIONAL) != 0)
            {
            {
              if (value)
              if (value)
                (*info->fprintf_func) (info->stream, "(r%ld)", value);
                (*info->fprintf_func) (info->stream, "(r%ld)", value);
            }
            }
          else if ((operand->flags & I370_OPERAND_SBASE) != 0)
          else if ((operand->flags & I370_OPERAND_SBASE) != 0)
            {
            {
              (*info->fprintf_func) (info->stream, "(r%ld)", value);
              (*info->fprintf_func) (info->stream, "(r%ld)", value);
            }
            }
          else if ((operand->flags & I370_OPERAND_INDEX) != 0)
          else if ((operand->flags & I370_OPERAND_INDEX) != 0)
            {
            {
              if (value)
              if (value)
                (*info->fprintf_func) (info->stream, "(r%ld,", value);
                (*info->fprintf_func) (info->stream, "(r%ld,", value);
              else
              else
                (*info->fprintf_func) (info->stream, "(,");
                (*info->fprintf_func) (info->stream, "(,");
            }
            }
          else if ((operand->flags & I370_OPERAND_LENGTH) != 0)
          else if ((operand->flags & I370_OPERAND_LENGTH) != 0)
            {
            {
              (*info->fprintf_func) (info->stream, "(%ld,", value);
              (*info->fprintf_func) (info->stream, "(%ld,", value);
            }
            }
          else if ((operand->flags & I370_OPERAND_BASE) != 0)
          else if ((operand->flags & I370_OPERAND_BASE) != 0)
            (*info->fprintf_func) (info->stream, "r%ld)", value);
            (*info->fprintf_func) (info->stream, "r%ld)", value);
          else if ((operand->flags & I370_OPERAND_GPR) != 0)
          else if ((operand->flags & I370_OPERAND_GPR) != 0)
            (*info->fprintf_func) (info->stream, "r%ld,", value);
            (*info->fprintf_func) (info->stream, "r%ld,", value);
          else if ((operand->flags & I370_OPERAND_FPR) != 0)
          else if ((operand->flags & I370_OPERAND_FPR) != 0)
            (*info->fprintf_func) (info->stream, "f%ld,", value);
            (*info->fprintf_func) (info->stream, "f%ld,", value);
          else if ((operand->flags & I370_OPERAND_RELATIVE) != 0)
          else if ((operand->flags & I370_OPERAND_RELATIVE) != 0)
            (*info->fprintf_func) (info->stream, "%ld", value);
            (*info->fprintf_func) (info->stream, "%ld", value);
          else
          else
            (*info->fprintf_func) (info->stream, " %ld, ", value);
            (*info->fprintf_func) (info->stream, " %ld, ", value);
        }
        }
 
 
      return opcode->len;
      return opcode->len;
    }
    }
 
 
  /* We could not find a match.  */
  /* We could not find a match.  */
  (*info->fprintf_func) (info->stream, ".short 0x%02x%02x", buffer[0], buffer[1]);
  (*info->fprintf_func) (info->stream, ".short 0x%02x%02x", buffer[0], buffer[1]);
 
 
  return 2;
  return 2;
}
}
 
 

powered by: WebSVN 2.1.0

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