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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [sim/] [common/] [cgen-trace.c] - Diff between revs 1182 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 1182 Rev 1765
/* Tracing support for CGEN-based simulators.
/* Tracing support for CGEN-based simulators.
   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
   Contributed by Cygnus Support.
   Contributed by Cygnus Support.
 
 
This file is part of GDB, the GNU debugger.
This file is part of GDB, the GNU debugger.
 
 
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, or (at your option)
the Free Software Foundation; either version 2, or (at your option)
any later version.
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 along
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 
#include <errno.h>
#include <errno.h>
#include "dis-asm.h"
#include "dis-asm.h"
#include "bfd.h"
#include "bfd.h"
#include "sim-main.h"
#include "sim-main.h"
#include "sim-fpu.h"
#include "sim-fpu.h"
 
 
#undef min
#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#define min(a,b) ((a) < (b) ? (a) : (b))
 
 
#ifndef SIZE_INSTRUCTION
#ifndef SIZE_INSTRUCTION
#define SIZE_INSTRUCTION 16
#define SIZE_INSTRUCTION 16
#endif
#endif
 
 
#ifndef SIZE_LOCATION
#ifndef SIZE_LOCATION
#define SIZE_LOCATION 20
#define SIZE_LOCATION 20
#endif
#endif
 
 
#ifndef SIZE_PC
#ifndef SIZE_PC
#define SIZE_PC 6
#define SIZE_PC 6
#endif
#endif
 
 
#ifndef SIZE_LINE_NUMBER
#ifndef SIZE_LINE_NUMBER
#define SIZE_LINE_NUMBER 4
#define SIZE_LINE_NUMBER 4
#endif
#endif
 
 
#ifndef SIZE_CYCLE_COUNT
#ifndef SIZE_CYCLE_COUNT
#define SIZE_CYCLE_COUNT 2
#define SIZE_CYCLE_COUNT 2
#endif
#endif
 
 
#ifndef SIZE_TOTAL_CYCLE_COUNT
#ifndef SIZE_TOTAL_CYCLE_COUNT
#define SIZE_TOTAL_CYCLE_COUNT 9
#define SIZE_TOTAL_CYCLE_COUNT 9
#endif
#endif
 
 
#ifndef SIZE_TRACE_BUF
#ifndef SIZE_TRACE_BUF
#define SIZE_TRACE_BUF 1024
#define SIZE_TRACE_BUF 1024
#endif
#endif
 
 
/* Text is queued in TRACE_BUF because we want to output the insn's cycle
/* Text is queued in TRACE_BUF because we want to output the insn's cycle
   count first but that isn't known until after the insn has executed.
   count first but that isn't known until after the insn has executed.
   This also handles the queueing of trace results, TRACE_RESULT may be
   This also handles the queueing of trace results, TRACE_RESULT may be
   called multiple times for one insn.  */
   called multiple times for one insn.  */
static char trace_buf[SIZE_TRACE_BUF];
static char trace_buf[SIZE_TRACE_BUF];
/* If NULL, output to stdout directly.  */
/* If NULL, output to stdout directly.  */
static char *bufptr;
static char *bufptr;
 
 
/* Non-zero if this is the first insn in a set of parallel insns.  */
/* Non-zero if this is the first insn in a set of parallel insns.  */
static int first_insn_p;
static int first_insn_p;
 
 
/* For communication between trace_insn and trace_result.  */
/* For communication between trace_insn and trace_result.  */
static int printed_result_p;
static int printed_result_p;
 
 
/* Insn and its extracted fields.
/* Insn and its extracted fields.
   Set by trace_insn, used by trace_insn_fini.
   Set by trace_insn, used by trace_insn_fini.
   ??? Move to SIM_CPU to support heterogeneous multi-cpu case.  */
   ??? Move to SIM_CPU to support heterogeneous multi-cpu case.  */
static const struct cgen_insn *current_insn;
static const struct cgen_insn *current_insn;
static const struct argbuf *current_abuf;
static const struct argbuf *current_abuf;
 
 
void
void
trace_insn_init (SIM_CPU *cpu, int first_p)
trace_insn_init (SIM_CPU *cpu, int first_p)
{
{
  bufptr = trace_buf;
  bufptr = trace_buf;
  *bufptr = 0;
  *bufptr = 0;
  first_insn_p = first_p;
  first_insn_p = first_p;
 
 
  /* Set to NULL so trace_insn_fini can know if trace_insn was called.  */
  /* Set to NULL so trace_insn_fini can know if trace_insn was called.  */
  current_insn = NULL;
  current_insn = NULL;
  current_abuf = NULL;
  current_abuf = NULL;
}
}
 
 
void
void
trace_insn_fini (SIM_CPU *cpu, const struct argbuf *abuf, int last_p)
trace_insn_fini (SIM_CPU *cpu, const struct argbuf *abuf, int last_p)
{
{
  SIM_DESC sd = CPU_STATE (cpu);
  SIM_DESC sd = CPU_STATE (cpu);
 
 
  /* Was insn traced?  It might not be if trace ranges are in effect.  */
  /* Was insn traced?  It might not be if trace ranges are in effect.  */
  if (current_insn == NULL)
  if (current_insn == NULL)
    return;
    return;
 
 
  /* The first thing printed is current and total cycle counts.  */
  /* The first thing printed is current and total cycle counts.  */
 
 
  if (PROFILE_MODEL_P (cpu)
  if (PROFILE_MODEL_P (cpu)
      && ARGBUF_PROFILE_P (current_abuf))
      && ARGBUF_PROFILE_P (current_abuf))
    {
    {
      unsigned long total = PROFILE_MODEL_TOTAL_CYCLES (CPU_PROFILE_DATA (cpu));
      unsigned long total = PROFILE_MODEL_TOTAL_CYCLES (CPU_PROFILE_DATA (cpu));
      unsigned long this_insn = PROFILE_MODEL_CUR_INSN_CYCLES (CPU_PROFILE_DATA (cpu));
      unsigned long this_insn = PROFILE_MODEL_CUR_INSN_CYCLES (CPU_PROFILE_DATA (cpu));
 
 
      if (last_p)
      if (last_p)
        {
        {
          trace_printf (sd, cpu, "%-*ld %-*ld ",
          trace_printf (sd, cpu, "%-*ld %-*ld ",
                        SIZE_CYCLE_COUNT, this_insn,
                        SIZE_CYCLE_COUNT, this_insn,
                        SIZE_TOTAL_CYCLE_COUNT, total);
                        SIZE_TOTAL_CYCLE_COUNT, total);
        }
        }
      else
      else
        {
        {
          trace_printf (sd, cpu, "%-*ld %-*s ",
          trace_printf (sd, cpu, "%-*ld %-*s ",
                        SIZE_CYCLE_COUNT, this_insn,
                        SIZE_CYCLE_COUNT, this_insn,
                        SIZE_TOTAL_CYCLE_COUNT, "---");
                        SIZE_TOTAL_CYCLE_COUNT, "---");
        }
        }
    }
    }
 
 
  /* Print the disassembled insn.  */
  /* Print the disassembled insn.  */
 
 
  trace_printf (sd, cpu, "%s", TRACE_PREFIX (CPU_TRACE_DATA (cpu)));
  trace_printf (sd, cpu, "%s", TRACE_PREFIX (CPU_TRACE_DATA (cpu)));
 
 
#if 0
#if 0
  /* Print insn results.  */
  /* Print insn results.  */
  {
  {
    const CGEN_OPINST *opinst = CGEN_INSN_OPERANDS (current_insn);
    const CGEN_OPINST *opinst = CGEN_INSN_OPERANDS (current_insn);
 
 
    if (opinst)
    if (opinst)
      {
      {
        int i;
        int i;
        int indices[MAX_OPERAND_INSTANCES];
        int indices[MAX_OPERAND_INSTANCES];
 
 
        /* Fetch the operands used by the insn.  */
        /* Fetch the operands used by the insn.  */
        /* FIXME: Add fn ptr to CGEN_CPU_DESC.  */
        /* FIXME: Add fn ptr to CGEN_CPU_DESC.  */
        CGEN_SYM (get_insn_operands) (CPU_CPU_DESC (cpu), current_insn,
        CGEN_SYM (get_insn_operands) (CPU_CPU_DESC (cpu), current_insn,
                                      0, CGEN_FIELDS_BITSIZE (&insn_fields),
                                      0, CGEN_FIELDS_BITSIZE (&insn_fields),
                                      indices);
                                      indices);
 
 
        for (i = 0;
        for (i = 0;
             CGEN_OPINST_TYPE (opinst) != CGEN_OPINST_END;
             CGEN_OPINST_TYPE (opinst) != CGEN_OPINST_END;
             ++i, ++opinst)
             ++i, ++opinst)
          {
          {
            if (CGEN_OPINST_TYPE (opinst) == CGEN_OPINST_OUTPUT)
            if (CGEN_OPINST_TYPE (opinst) == CGEN_OPINST_OUTPUT)
              trace_result (cpu, current_insn, opinst, indices[i]);
              trace_result (cpu, current_insn, opinst, indices[i]);
          }
          }
      }
      }
  }
  }
#endif
#endif
 
 
  /* Print anything else requested.  */
  /* Print anything else requested.  */
 
 
  if (*trace_buf)
  if (*trace_buf)
    trace_printf (sd, cpu, " %s\n", trace_buf);
    trace_printf (sd, cpu, " %s\n", trace_buf);
  else
  else
    trace_printf (sd, cpu, "\n");
    trace_printf (sd, cpu, "\n");
}
}
 
 
void
void
trace_insn (SIM_CPU *cpu, const struct cgen_insn *opcode,
trace_insn (SIM_CPU *cpu, const struct cgen_insn *opcode,
            const struct argbuf *abuf, IADDR pc)
            const struct argbuf *abuf, IADDR pc)
{
{
  char disasm_buf[50];
  char disasm_buf[50];
 
 
  printed_result_p = 0;
  printed_result_p = 0;
  current_insn = opcode;
  current_insn = opcode;
  current_abuf = abuf;
  current_abuf = abuf;
 
 
  if (CGEN_INSN_VIRTUAL_P (opcode))
  if (CGEN_INSN_VIRTUAL_P (opcode))
    {
    {
      trace_prefix (CPU_STATE (cpu), cpu, NULL_CIA, pc, 0,
      trace_prefix (CPU_STATE (cpu), cpu, NULL_CIA, pc, 0,
                    NULL, 0, CGEN_INSN_NAME (opcode));
                    NULL, 0, CGEN_INSN_NAME (opcode));
      return;
      return;
    }
    }
 
 
  CPU_DISASSEMBLER (cpu) (cpu, opcode, abuf, pc, disasm_buf);
  CPU_DISASSEMBLER (cpu) (cpu, opcode, abuf, pc, disasm_buf);
  trace_prefix (CPU_STATE (cpu), cpu, NULL_CIA, pc, TRACE_LINENUM_P (cpu),
  trace_prefix (CPU_STATE (cpu), cpu, NULL_CIA, pc, TRACE_LINENUM_P (cpu),
                NULL, 0,
                NULL, 0,
                "%s%-*s",
                "%s%-*s",
                first_insn_p ? " " : "|",
                first_insn_p ? " " : "|",
                SIZE_INSTRUCTION, disasm_buf);
                SIZE_INSTRUCTION, disasm_buf);
}
}
 
 
void
void
trace_extract (SIM_CPU *cpu, IADDR pc, char *name, ...)
trace_extract (SIM_CPU *cpu, IADDR pc, char *name, ...)
{
{
  va_list args;
  va_list args;
  int printed_one_p = 0;
  int printed_one_p = 0;
  char *fmt;
  char *fmt;
 
 
  va_start (args, name);
  va_start (args, name);
 
 
  trace_printf (CPU_STATE (cpu), cpu, "Extract: 0x%.*lx: %s ",
  trace_printf (CPU_STATE (cpu), cpu, "Extract: 0x%.*lx: %s ",
                SIZE_PC, pc, name);
                SIZE_PC, pc, name);
 
 
  do {
  do {
    int type,ival;
    int type,ival;
 
 
    fmt = va_arg (args, char *);
    fmt = va_arg (args, char *);
 
 
    if (fmt)
    if (fmt)
      {
      {
        if (printed_one_p)
        if (printed_one_p)
          trace_printf (CPU_STATE (cpu), cpu, ", ");
          trace_printf (CPU_STATE (cpu), cpu, ", ");
        printed_one_p = 1;
        printed_one_p = 1;
        type = va_arg (args, int);
        type = va_arg (args, int);
        switch (type)
        switch (type)
          {
          {
          case 'x' :
          case 'x' :
            ival = va_arg (args, int);
            ival = va_arg (args, int);
            trace_printf (CPU_STATE (cpu), cpu, fmt, ival);
            trace_printf (CPU_STATE (cpu), cpu, fmt, ival);
            break;
            break;
          default :
          default :
            abort ();
            abort ();
          }
          }
      }
      }
  } while (fmt);
  } while (fmt);
 
 
  va_end (args);
  va_end (args);
  trace_printf (CPU_STATE (cpu), cpu, "\n");
  trace_printf (CPU_STATE (cpu), cpu, "\n");
}
}
 
 
void
void
trace_result (SIM_CPU *cpu, char *name, int type, ...)
trace_result (SIM_CPU *cpu, char *name, int type, ...)
{
{
  va_list args;
  va_list args;
 
 
  va_start (args, type);
  va_start (args, type);
  if (printed_result_p)
  if (printed_result_p)
    cgen_trace_printf (cpu, ", ");
    cgen_trace_printf (cpu, ", ");
 
 
  switch (type)
  switch (type)
    {
    {
    case 'x' :
    case 'x' :
    default :
    default :
      cgen_trace_printf (cpu, "%s <- 0x%x", name, va_arg (args, int));
      cgen_trace_printf (cpu, "%s <- 0x%x", name, va_arg (args, int));
      break;
      break;
    case 'f':
    case 'f':
      {
      {
        DI di;
        DI di;
        sim_fpu f;
        sim_fpu f;
 
 
        /* this is separated from previous line for sunos cc */
        /* this is separated from previous line for sunos cc */
        di = va_arg (args, DI);
        di = va_arg (args, DI);
        sim_fpu_64to (&f, di);
        sim_fpu_64to (&f, di);
 
 
        cgen_trace_printf (cpu, "%s <- ", name);
        cgen_trace_printf (cpu, "%s <- ", name);
        sim_fpu_printn_fpu (&f, (sim_fpu_print_func *) cgen_trace_printf, 4, cpu);
        sim_fpu_printn_fpu (&f, (sim_fpu_print_func *) cgen_trace_printf, 4, cpu);
        break;
        break;
      }
      }
    case 'D' :
    case 'D' :
      {
      {
        DI di;
        DI di;
        /* this is separated from previous line for sunos cc */
        /* this is separated from previous line for sunos cc */
        di = va_arg (args, DI);
        di = va_arg (args, DI);
        cgen_trace_printf (cpu, "%s <- 0x%x%08x", name,
        cgen_trace_printf (cpu, "%s <- 0x%x%08x", name,
                           GETHIDI(di), GETLODI (di));
                           GETHIDI(di), GETLODI (di));
        break;
        break;
      }
      }
    }
    }
 
 
  printed_result_p = 1;
  printed_result_p = 1;
  va_end (args);
  va_end (args);
}
}
 
 
/* Print trace output to BUFPTR if active, otherwise print normally.
/* Print trace output to BUFPTR if active, otherwise print normally.
   This is only for tracing semantic code.  */
   This is only for tracing semantic code.  */
 
 
void
void
cgen_trace_printf (SIM_CPU *cpu, char *fmt, ...)
cgen_trace_printf (SIM_CPU *cpu, char *fmt, ...)
{
{
  va_list args;
  va_list args;
 
 
  va_start (args, fmt);
  va_start (args, fmt);
 
 
  if (bufptr == NULL)
  if (bufptr == NULL)
    {
    {
      if (TRACE_FILE (CPU_TRACE_DATA (cpu)) == NULL)
      if (TRACE_FILE (CPU_TRACE_DATA (cpu)) == NULL)
        (* STATE_CALLBACK (CPU_STATE (cpu))->evprintf_filtered)
        (* STATE_CALLBACK (CPU_STATE (cpu))->evprintf_filtered)
          (STATE_CALLBACK (CPU_STATE (cpu)), fmt, args);
          (STATE_CALLBACK (CPU_STATE (cpu)), fmt, args);
      else
      else
        vfprintf (TRACE_FILE (CPU_TRACE_DATA (cpu)), fmt, args);
        vfprintf (TRACE_FILE (CPU_TRACE_DATA (cpu)), fmt, args);
    }
    }
  else
  else
    {
    {
      vsprintf (bufptr, fmt, args);
      vsprintf (bufptr, fmt, args);
      bufptr += strlen (bufptr);
      bufptr += strlen (bufptr);
      /* ??? Need version of SIM_ASSERT that is always enabled.  */
      /* ??? Need version of SIM_ASSERT that is always enabled.  */
      if (bufptr - trace_buf > SIZE_TRACE_BUF)
      if (bufptr - trace_buf > SIZE_TRACE_BUF)
        abort ();
        abort ();
    }
    }
 
 
  va_end (args);
  va_end (args);
}
}


/* Disassembly support.  */
/* Disassembly support.  */
 
 
/* sprintf to a "stream" */
/* sprintf to a "stream" */
 
 
int
int
sim_disasm_sprintf VPARAMS ((SFILE *f, const char *format, ...))
sim_disasm_sprintf VPARAMS ((SFILE *f, const char *format, ...))
{
{
#ifndef __STDC__
#ifndef __STDC__
  SFILE *f;
  SFILE *f;
  const char *format;
  const char *format;
#endif
#endif
  int n;
  int n;
  va_list args;
  va_list args;
 
 
  VA_START (args, format);
  VA_START (args, format);
#ifndef __STDC__
#ifndef __STDC__
  f = va_arg (args, SFILE *);
  f = va_arg (args, SFILE *);
  format = va_arg (args, char *);
  format = va_arg (args, char *);
#endif
#endif
  vsprintf (f->current, format, args);
  vsprintf (f->current, format, args);
  f->current += n = strlen (f->current);
  f->current += n = strlen (f->current);
  va_end (args);
  va_end (args);
  return n;
  return n;
}
}
 
 
/* Memory read support for an opcodes disassembler.  */
/* Memory read support for an opcodes disassembler.  */
 
 
int
int
sim_disasm_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
sim_disasm_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
                        struct disassemble_info *info)
                        struct disassemble_info *info)
{
{
  SIM_CPU *cpu = (SIM_CPU *) info->application_data;
  SIM_CPU *cpu = (SIM_CPU *) info->application_data;
  SIM_DESC sd = CPU_STATE (cpu);
  SIM_DESC sd = CPU_STATE (cpu);
  int length_read;
  int length_read;
 
 
  length_read = sim_core_read_buffer (sd, cpu, read_map, myaddr, memaddr,
  length_read = sim_core_read_buffer (sd, cpu, read_map, myaddr, memaddr,
                                      length);
                                      length);
  if (length_read != length)
  if (length_read != length)
    return EIO;
    return EIO;
  return 0;
  return 0;
}
}
 
 
/* Memory error support for an opcodes disassembler.  */
/* Memory error support for an opcodes disassembler.  */
 
 
void
void
sim_disasm_perror_memory (int status, bfd_vma memaddr,
sim_disasm_perror_memory (int status, bfd_vma memaddr,
                          struct disassemble_info *info)
                          struct disassemble_info *info)
{
{
  if (status != EIO)
  if (status != EIO)
    /* Can't happen.  */
    /* Can't happen.  */
    info->fprintf_func (info->stream, "Unknown error %d.", status);
    info->fprintf_func (info->stream, "Unknown error %d.", status);
  else
  else
    /* Actually, address between memaddr and memaddr + len was
    /* Actually, address between memaddr and memaddr + len was
       out of bounds.  */
       out of bounds.  */
    info->fprintf_func (info->stream,
    info->fprintf_func (info->stream,
                        "Address 0x%x is out of bounds.",
                        "Address 0x%x is out of bounds.",
                        (int) memaddr);
                        (int) memaddr);
}
}
 
 
/* Disassemble using the CGEN opcode table.
/* Disassemble using the CGEN opcode table.
   ??? While executing an instruction, the insn has been decoded and all its
   ??? While executing an instruction, the insn has been decoded and all its
   fields have been extracted.  It is certainly possible to do the disassembly
   fields have been extracted.  It is certainly possible to do the disassembly
   with that data.  This seems simpler, but maybe in the future the already
   with that data.  This seems simpler, but maybe in the future the already
   extracted fields will be used.  */
   extracted fields will be used.  */
 
 
void
void
sim_cgen_disassemble_insn (SIM_CPU *cpu, const CGEN_INSN *insn,
sim_cgen_disassemble_insn (SIM_CPU *cpu, const CGEN_INSN *insn,
                           const ARGBUF *abuf, IADDR pc, char *buf)
                           const ARGBUF *abuf, IADDR pc, char *buf)
{
{
  unsigned int length;
  unsigned int length;
  unsigned int base_length;
  unsigned int base_length;
  unsigned long insn_value;
  unsigned long insn_value;
  struct disassemble_info disasm_info;
  struct disassemble_info disasm_info;
  SFILE sfile;
  SFILE sfile;
  union {
  union {
    unsigned8 bytes[CGEN_MAX_INSN_SIZE];
    unsigned8 bytes[CGEN_MAX_INSN_SIZE];
    unsigned16 shorts[8];
    unsigned16 shorts[8];
    unsigned32 words[4];
    unsigned32 words[4];
  } insn_buf;
  } insn_buf;
  SIM_DESC sd = CPU_STATE (cpu);
  SIM_DESC sd = CPU_STATE (cpu);
  CGEN_CPU_DESC cd = CPU_CPU_DESC (cpu);
  CGEN_CPU_DESC cd = CPU_CPU_DESC (cpu);
  CGEN_EXTRACT_INFO ex_info;
  CGEN_EXTRACT_INFO ex_info;
  CGEN_FIELDS *fields = alloca (CGEN_CPU_SIZEOF_FIELDS (cd));
  CGEN_FIELDS *fields = alloca (CGEN_CPU_SIZEOF_FIELDS (cd));
  int insn_bit_length = CGEN_INSN_BITSIZE (insn);
  int insn_bit_length = CGEN_INSN_BITSIZE (insn);
  int insn_length = insn_bit_length / 8;
  int insn_length = insn_bit_length / 8;
 
 
  sfile.buffer = sfile.current = buf;
  sfile.buffer = sfile.current = buf;
  INIT_DISASSEMBLE_INFO (disasm_info, (FILE *) &sfile,
  INIT_DISASSEMBLE_INFO (disasm_info, (FILE *) &sfile,
                         (fprintf_ftype) sim_disasm_sprintf);
                         (fprintf_ftype) sim_disasm_sprintf);
  disasm_info.endian =
  disasm_info.endian =
    (bfd_big_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_BIG
    (bfd_big_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_BIG
     : bfd_little_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_LITTLE
     : bfd_little_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_LITTLE
     : BFD_ENDIAN_UNKNOWN);
     : BFD_ENDIAN_UNKNOWN);
 
 
  length = sim_core_read_buffer (sd, cpu, read_map, &insn_buf, pc,
  length = sim_core_read_buffer (sd, cpu, read_map, &insn_buf, pc,
                                 insn_length);
                                 insn_length);
 
 
  if (length != insn_length)
  if (length != insn_length)
  {
  {
    sim_io_error (sd, "unable to read address %x", pc);
    sim_io_error (sd, "unable to read address %x", pc);
  }
  }
 
 
  /* If the entire insn will fit into an integer, then do it. Otherwise, just
  /* If the entire insn will fit into an integer, then do it. Otherwise, just
     use the bits of the base_insn.  */
     use the bits of the base_insn.  */
  if (insn_bit_length <= 32)
  if (insn_bit_length <= 32)
    base_length = insn_bit_length;
    base_length = insn_bit_length;
  else
  else
    base_length = min (cd->base_insn_bitsize, insn_bit_length);
    base_length = min (cd->base_insn_bitsize, insn_bit_length);
  switch (base_length)
  switch (base_length)
    {
    {
    case 0 : return; /* fake insn, typically "compile" (aka "invalid") */
    case 0 : return; /* fake insn, typically "compile" (aka "invalid") */
    case 8 : insn_value = insn_buf.bytes[0]; break;
    case 8 : insn_value = insn_buf.bytes[0]; break;
    case 16 : insn_value = T2H_2 (insn_buf.shorts[0]); break;
    case 16 : insn_value = T2H_2 (insn_buf.shorts[0]); break;
    case 32 : insn_value = T2H_4 (insn_buf.words[0]); break;
    case 32 : insn_value = T2H_4 (insn_buf.words[0]); break;
    default: abort ();
    default: abort ();
    }
    }
 
 
  disasm_info.buffer_vma = pc;
  disasm_info.buffer_vma = pc;
  disasm_info.buffer = insn_buf.bytes;
  disasm_info.buffer = insn_buf.bytes;
  disasm_info.buffer_length = length;
  disasm_info.buffer_length = length;
 
 
  ex_info.dis_info = (PTR) &disasm_info;
  ex_info.dis_info = (PTR) &disasm_info;
  ex_info.valid = (1 << length) - 1;
  ex_info.valid = (1 << length) - 1;
  ex_info.insn_bytes = insn_buf.bytes;
  ex_info.insn_bytes = insn_buf.bytes;
 
 
  length = (*CGEN_EXTRACT_FN (cd, insn)) (cd, insn, &ex_info, insn_value, fields, pc);
  length = (*CGEN_EXTRACT_FN (cd, insn)) (cd, insn, &ex_info, insn_value, fields, pc);
  /* Result of extract fn is in bits.  */
  /* Result of extract fn is in bits.  */
  /* ??? This assumes that each instruction has a fixed length (and thus
  /* ??? This assumes that each instruction has a fixed length (and thus
     for insns with multiple versions of variable lengths they would each
     for insns with multiple versions of variable lengths they would each
     have their own table entry).  */
     have their own table entry).  */
  if (length == insn_bit_length)
  if (length == insn_bit_length)
    {
    {
      (*CGEN_PRINT_FN (cd, insn)) (cd, &disasm_info, insn, fields, pc, length);
      (*CGEN_PRINT_FN (cd, insn)) (cd, &disasm_info, insn, fields, pc, length);
    }
    }
  else
  else
    {
    {
      /* This shouldn't happen, but aborting is too drastic.  */
      /* This shouldn't happen, but aborting is too drastic.  */
      strcpy (buf, "***unknown***");
      strcpy (buf, "***unknown***");
    }
    }
}
}
 
 

powered by: WebSVN 2.1.0

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