/* Tracing support for CGEN-based simulators.
   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
   Contributed by Cygnus Support.

This file is part of GDB, the GNU debugger.

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
the Free Software Foundation; either version 2, or (at your option)
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

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.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#include <errno.h>
#include "dis-asm.h"
#include "bfd.h"
#include "sim-main.h"
#include "sim-fpu.h"

#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))

#ifndef SIZE_INSTRUCTION
#define SIZE_INSTRUCTION 16
#endif

#ifndef SIZE_LOCATION
#define SIZE_LOCATION 20
#endif

#ifndef SIZE_PC
#define SIZE_PC 6
#endif

#ifndef SIZE_LINE_NUMBER
#define SIZE_LINE_NUMBER 4
#endif

#ifndef SIZE_CYCLE_COUNT
#define SIZE_CYCLE_COUNT 2
#endif

#ifndef SIZE_TOTAL_CYCLE_COUNT
#define SIZE_TOTAL_CYCLE_COUNT 9
#endif

#ifndef SIZE_TRACE_BUF
#define SIZE_TRACE_BUF 1024
#endif

/* 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.
   This also handles the queueing of trace results, TRACE_RESULT may be
   called multiple times for one insn.  */
static char trace_buf[SIZE_TRACE_BUF];
/* If NULL, output to stdout directly.  */
static char *bufptr;

/* Non-zero if this is the first insn in a set of parallel insns.  */
static int first_insn_p;

/* For communication between trace_insn and trace_result.  */
static int printed_result_p;

/* Insn and its extracted fields.
   Set by trace_insn, used by trace_insn_fini.
   ??? Move to SIM_CPU to support heterogeneous multi-cpu case.  */
static const struct cgen_insn *current_insn;
static const struct argbuf *current_abuf;

void
trace_insn_init (SIM_CPU *cpu, int first_p)
{
  bufptr = trace_buf;
  *bufptr = 0;
  first_insn_p = first_p;

  /* Set to NULL so trace_insn_fini can know if trace_insn was called.  */
  current_insn = NULL;
  current_abuf = NULL;
}

void
trace_insn_fini (SIM_CPU *cpu, const struct argbuf *abuf, int last_p)
{
  SIM_DESC sd = CPU_STATE (cpu);

  /* Was insn traced?  It might not be if trace ranges are in effect.  */
  if (current_insn == NULL)
    return;

  /* The first thing printed is current and total cycle counts.  */

  if (PROFILE_MODEL_P (cpu)
      && ARGBUF_PROFILE_P (current_abuf))
    {
      unsigned long total = PROFILE_MODEL_TOTAL_CYCLES (CPU_PROFILE_DATA (cpu));
      unsigned long this_insn = PROFILE_MODEL_CUR_INSN_CYCLES (CPU_PROFILE_DATA (cpu));

      if (last_p)
	{
	  trace_printf (sd, cpu, "%-*ld %-*ld ",
			SIZE_CYCLE_COUNT, this_insn,
			SIZE_TOTAL_CYCLE_COUNT, total);
	}
      else
	{
	  trace_printf (sd, cpu, "%-*ld %-*s ",
			SIZE_CYCLE_COUNT, this_insn,
			SIZE_TOTAL_CYCLE_COUNT, "---");
	}
    }

  /* Print the disassembled insn.  */

  trace_printf (sd, cpu, "%s", TRACE_PREFIX (CPU_TRACE_DATA (cpu)));

#if 0
  /* Print insn results.  */
  {
    const CGEN_OPINST *opinst = CGEN_INSN_OPERANDS (current_insn);

    if (opinst)
      {
	int i;
	int indices[MAX_OPERAND_INSTANCES];

	/* Fetch the operands used by the insn.  */
	/* FIXME: Add fn ptr to CGEN_CPU_DESC.  */
	CGEN_SYM (get_insn_operands) (CPU_CPU_DESC (cpu), current_insn,
				      0, CGEN_FIELDS_BITSIZE (&insn_fields),
				      indices);

	for (i = 0;
	     CGEN_OPINST_TYPE (opinst) != CGEN_OPINST_END;
	     ++i, ++opinst)
	  {
	    if (CGEN_OPINST_TYPE (opinst) == CGEN_OPINST_OUTPUT)
	      trace_result (cpu, current_insn, opinst, indices[i]);
	  }
      }
  }
#endif

  /* Print anything else requested.  */

  if (*trace_buf)
    trace_printf (sd, cpu, " %s\n", trace_buf);
  else
    trace_printf (sd, cpu, "\n");
}

void
trace_insn (SIM_CPU *cpu, const struct cgen_insn *opcode,
	    const struct argbuf *abuf, IADDR pc)
{
  char disasm_buf[50];

  printed_result_p = 0;
  current_insn = opcode;
  current_abuf = abuf;

  if (CGEN_INSN_VIRTUAL_P (opcode))
    {
      trace_prefix (CPU_STATE (cpu), cpu, NULL_CIA, pc, 0,
		    NULL, 0, CGEN_INSN_NAME (opcode));
      return;
    }

  CPU_DISASSEMBLER (cpu) (cpu, opcode, abuf, pc, disasm_buf);
  trace_prefix (CPU_STATE (cpu), cpu, NULL_CIA, pc, TRACE_LINENUM_P (cpu),
		NULL, 0,
		"%s%-*s",
		first_insn_p ? " " : "|",
		SIZE_INSTRUCTION, disasm_buf);
}

void
trace_extract (SIM_CPU *cpu, IADDR pc, char *name, ...)
{
  va_list args;
  int printed_one_p = 0;
  char *fmt;

  va_start (args, name);

  trace_printf (CPU_STATE (cpu), cpu, "Extract: 0x%.*lx: %s ",
		SIZE_PC, pc, name);

  do {
    int type,ival;

    fmt = va_arg (args, char *);

    if (fmt)
      {
	if (printed_one_p)
	  trace_printf (CPU_STATE (cpu), cpu, ", ");
	printed_one_p = 1;
	type = va_arg (args, int);
	switch (type)
	  {
	  case 'x' :
	    ival = va_arg (args, int);
	    trace_printf (CPU_STATE (cpu), cpu, fmt, ival);
	    break;
	  default :
	    abort ();
	  }
      }
  } while (fmt);

  va_end (args);
  trace_printf (CPU_STATE (cpu), cpu, "\n");
}

void
trace_result (SIM_CPU *cpu, char *name, int type, ...)
{
  va_list args;

  va_start (args, type);
  if (printed_result_p)
    cgen_trace_printf (cpu, ", ");

  switch (type)
    {
    case 'x' :
    default :
      cgen_trace_printf (cpu, "%s <- 0x%x", name, va_arg (args, int));
      break;
    case 'f':
      {
	DI di;
	sim_fpu f;

	/* this is separated from previous line for sunos cc */
	di = va_arg (args, DI);
	sim_fpu_64to (&f, di);

	cgen_trace_printf (cpu, "%s <- ", name);
	sim_fpu_printn_fpu (&f, (sim_fpu_print_func *) cgen_trace_printf, 4, cpu);
	break;
      }
    case 'D' :
      {
	DI di;
	/* this is separated from previous line for sunos cc */
	di = va_arg (args, DI);
	cgen_trace_printf (cpu, "%s <- 0x%x%08x", name,
			   GETHIDI(di), GETLODI (di));
	break;
      }
    }

  printed_result_p = 1;
  va_end (args);
}

/* Print trace output to BUFPTR if active, otherwise print normally.
   This is only for tracing semantic code.  */

void
cgen_trace_printf (SIM_CPU *cpu, char *fmt, ...)
{
  va_list args;

  va_start (args, fmt);

  if (bufptr == NULL)
    {
      if (TRACE_FILE (CPU_TRACE_DATA (cpu)) == NULL)
	(* STATE_CALLBACK (CPU_STATE (cpu))->evprintf_filtered)
	  (STATE_CALLBACK (CPU_STATE (cpu)), fmt, args);
      else
	vfprintf (TRACE_FILE (CPU_TRACE_DATA (cpu)), fmt, args);
    }
  else
    {
      vsprintf (bufptr, fmt, args);
      bufptr += strlen (bufptr);
      /* ??? Need version of SIM_ASSERT that is always enabled.  */
      if (bufptr - trace_buf > SIZE_TRACE_BUF)
	abort ();
    }

  va_end (args);
}

/* Disassembly support.  */

/* sprintf to a "stream" */

int
sim_disasm_sprintf VPARAMS ((SFILE *f, const char *format, ...))
{
#ifndef __STDC__
  SFILE *f;
  const char *format;
#endif
  int n;
  va_list args;

  VA_START (args, format);
#ifndef __STDC__
  f = va_arg (args, SFILE *);
  format = va_arg (args, char *);
#endif
  vsprintf (f->current, format, args);
  f->current += n = strlen (f->current);
  va_end (args);
  return n;
}

/* Memory read support for an opcodes disassembler.  */

int
sim_disasm_read_memory (bfd_vma memaddr, bfd_byte *myaddr, unsigned int length,
			struct disassemble_info *info)
{
  SIM_CPU *cpu = (SIM_CPU *) info->application_data;
  SIM_DESC sd = CPU_STATE (cpu);
  unsigned length_read;

  length_read = sim_core_read_buffer (sd, cpu, read_map, myaddr, memaddr,
				      length);
  if (length_read != length)
    return EIO;
  return 0;
}

/* Memory error support for an opcodes disassembler.  */

void
sim_disasm_perror_memory (int status, bfd_vma memaddr,
			  struct disassemble_info *info)
{
  if (status != EIO)
    /* Can't happen.  */
    info->fprintf_func (info->stream, "Unknown error %d.", status);
  else
    /* Actually, address between memaddr and memaddr + len was
       out of bounds.  */
    info->fprintf_func (info->stream,
			"Address 0x%x is out of bounds.",
			(int) memaddr);
}

/* Disassemble using the CGEN opcode table.
   ??? While executing an instruction, the insn has been decoded and all its
   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
   extracted fields will be used.  */

void
sim_cgen_disassemble_insn (SIM_CPU *cpu, const CGEN_INSN *insn,
			   const ARGBUF *abuf, IADDR pc, char *buf)
{
  unsigned int length;
  unsigned int base_length;
  unsigned long insn_value;
  struct disassemble_info disasm_info;
  SFILE sfile;
  union {
    unsigned8 bytes[CGEN_MAX_INSN_SIZE];
    unsigned16 shorts[8];
    unsigned32 words[4];
  } insn_buf;
  SIM_DESC sd = CPU_STATE (cpu);
  CGEN_CPU_DESC cd = CPU_CPU_DESC (cpu);
  CGEN_EXTRACT_INFO ex_info;
  CGEN_FIELDS *fields = alloca (CGEN_CPU_SIZEOF_FIELDS (cd));
  int insn_bit_length = CGEN_INSN_BITSIZE (insn);
  int insn_length = insn_bit_length / 8;

  sfile.buffer = sfile.current = buf;
  INIT_DISASSEMBLE_INFO (disasm_info, (FILE *) &sfile,
			 (fprintf_ftype) sim_disasm_sprintf);
  disasm_info.endian =
    (bfd_big_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_BIG
     : bfd_little_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_LITTLE
     : BFD_ENDIAN_UNKNOWN);

  length = sim_core_read_buffer (sd, cpu, read_map, &insn_buf, pc,
				 insn_length);

  if (length != insn_length)
  {
    sim_io_error (sd, "unable to read address %x", pc);
  }

  /* If the entire insn will fit into an integer, then do it. Otherwise, just
     use the bits of the base_insn.  */
  if (insn_bit_length <= 32)
    base_length = insn_bit_length;
  else
    base_length = min (cd->base_insn_bitsize, insn_bit_length);
  switch (base_length)
    {
    case 0 : return; /* fake insn, typically "compile" (aka "invalid") */
    case 8 : insn_value = insn_buf.bytes[0]; break;
    case 16 : insn_value = T2H_2 (insn_buf.shorts[0]); break;
    case 32 : insn_value = T2H_4 (insn_buf.words[0]); break;
    default: abort ();
    }

  disasm_info.buffer_vma = pc;
  disasm_info.buffer = insn_buf.bytes;
  disasm_info.buffer_length = length;

  ex_info.dis_info = (PTR) &disasm_info;
  ex_info.valid = (1 << length) - 1;
  ex_info.insn_bytes = insn_buf.bytes;

  length = (*CGEN_EXTRACT_FN (cd, insn)) (cd, insn, &ex_info, insn_value, fields, pc);
  /* Result of extract fn is in bits.  */
  /* ??? This assumes that each instruction has a fixed length (and thus
     for insns with multiple versions of variable lengths they would each
     have their own table entry).  */
  if (length == insn_bit_length)
    {
      (*CGEN_PRINT_FN (cd, insn)) (cd, &disasm_info, insn, fields, pc, length);
    }
  else
    {
      /* This shouldn't happen, but aborting is too drastic.  */
      strcpy (buf, "***unknown***");
    }
}
