/* 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, int length,
			struct disassemble_info *info)
{
  SIM_CPU *cpu = (SIM_CPU *) info->application_data;
  SIM_DESC sd = CPU_STATE (cpu);
  int 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***");
    }
}
