/* ARC target-dependent stuff.
   Copyright 1995, 1996, 1999, 2000, 2001 Free Software Foundation, Inc.

   This file is part of GDB.

   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 of the License, 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 "defs.h"
#include "frame.h"
#include "inferior.h"
#include "gdbcore.h"
#include "target.h"
#include "floatformat.h"
#include "symtab.h"
#include "gdbcmd.h"
#include "regcache.h"

/* Local functions */

static int arc_set_cpu_type (char *str);

/* Current CPU, set with the "set cpu" command.  */
static int arc_bfd_mach_type;
char *arc_cpu_type;
char *tmp_arc_cpu_type;

/* Table of cpu names.  */
struct
  {
    char *name;
    int value;
  }
arc_cpu_type_table[] =
{
  { "arc5", bfd_mach_arc_5 },
  { "arc6", bfd_mach_arc_6 },
  { "arc7", bfd_mach_arc_7 },
  { "arc8", bfd_mach_arc_8 },
  {  NULL,  0 }
};

/* Used by simulator.  */
int display_pipeline_p;
int cpu_timer;
/* This one must have the same type as used in the emulator.
   It's currently an enum so this should be ok for now.  */
int debug_pipeline_p;

#define ARC_CALL_SAVED_REG(r) ((r) >= 16 && (r) < 24)

#define OPMASK	0xf8000000

/* Instruction field accessor macros.
   See the Programmer's Reference Manual.  */
#define X_OP(i) (((i) >> 27) & 0x1f)
#define X_A(i) (((i) >> 21) & 0x3f)
#define X_B(i) (((i) >> 15) & 0x3f)
#define X_C(i) (((i) >> 9) & 0x3f)
#define X_D(i) ((((i) & 0x1ff) ^ 0x100) - 0x100)
#define X_L(i) (((((i) >> 5) & 0x3ffffc) ^ 0x200000) - 0x200000)
#define X_N(i) (((i) >> 5) & 3)
#define X_Q(i) ((i) & 0x1f)

/* Return non-zero if X is a short immediate data indicator.  */
#define SHIMM_P(x) ((x) == 61 || (x) == 63)

/* Return non-zero if X is a "long" (32 bit) immediate data indicator.  */
#define LIMM_P(x) ((x) == 62)

/* Build a simple instruction.  */
#define BUILD_INSN(op, a, b, c, d) \
  ((((op) & 31) << 27) \
   | (((a) & 63) << 21) \
   | (((b) & 63) << 15) \
   | (((c) & 63) << 9) \
   | ((d) & 511))

/* Codestream stuff.  */
static void codestream_read (unsigned int *, int);
static void codestream_seek (CORE_ADDR);
static unsigned int codestream_fill (int);

#define CODESTREAM_BUFSIZ 16
static CORE_ADDR codestream_next_addr;
static CORE_ADDR codestream_addr;
/* FIXME assumes sizeof (int) == 32? */
static unsigned int codestream_buf[CODESTREAM_BUFSIZ];
static int codestream_off;
static int codestream_cnt;

#define codestream_tell() \
  (codestream_addr + codestream_off * sizeof (codestream_buf[0]))
#define codestream_peek() \
  (codestream_cnt == 0 \
   ? codestream_fill (1) \
   : codestream_buf[codestream_off])
#define codestream_get() \
  (codestream_cnt-- == 0 \
   ? codestream_fill (0) \
   : codestream_buf[codestream_off++])

static unsigned int
codestream_fill (int peek_flag)
{
  codestream_addr = codestream_next_addr;
  codestream_next_addr += CODESTREAM_BUFSIZ * sizeof (codestream_buf[0]);
  codestream_off = 0;
  codestream_cnt = CODESTREAM_BUFSIZ;
  read_memory (codestream_addr, (char *) codestream_buf,
	       CODESTREAM_BUFSIZ * sizeof (codestream_buf[0]));
  /* FIXME: check return code?  */


  /* Handle byte order differences -> convert to host byte ordering.  */
  {
    int i;
    for (i = 0; i < CODESTREAM_BUFSIZ; i++)
      codestream_buf[i] =
	extract_unsigned_integer (&codestream_buf[i],
				  sizeof (codestream_buf[i]));
  }

  if (peek_flag)
    return codestream_peek ();
  else
    return codestream_get ();
}

static void
codestream_seek (CORE_ADDR place)
{
  codestream_next_addr = place / CODESTREAM_BUFSIZ;
  codestream_next_addr *= CODESTREAM_BUFSIZ;
  codestream_cnt = 0;
  codestream_fill (1);
  while (codestream_tell () != place)
    codestream_get ();
}

/* This function is currently unused but leave in for now.  */

static void
codestream_read (unsigned int *buf, int count)
{
  unsigned int *p;
  int i;
  p = buf;
  for (i = 0; i < count; i++)
    *p++ = codestream_get ();
}

/* Set up prologue scanning and return the first insn.  */

static unsigned int
setup_prologue_scan (CORE_ADDR pc)
{
  unsigned int insn;

  codestream_seek (pc);
  insn = codestream_get ();

  return insn;
}

/*
 * Find & return amount a local space allocated, and advance codestream to
 * first register push (if any).
 * If entry sequence doesn't make sense, return -1, and leave 
 * codestream pointer random.
 */

static long
arc_get_frame_setup (CORE_ADDR pc)
{
  unsigned int insn;
  /* Size of frame or -1 if unrecognizable prologue.  */
  int frame_size = -1;
  /* An initial "sub sp,sp,N" may or may not be for a stdarg fn.  */
  int maybe_stdarg_decr = -1;

  insn = setup_prologue_scan (pc);

  /* The authority for what appears here is the home-grown ABI.
     The most recent version is 1.2.  */

  /* First insn may be "sub sp,sp,N" if stdarg fn.  */
  if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
      == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0))
    {
      maybe_stdarg_decr = X_D (insn);
      insn = codestream_get ();
    }

  if ((insn & BUILD_INSN (-1, 0, -1, -1, -1))	/* st blink,[sp,4] */
      == BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4))
    {
      insn = codestream_get ();
      /* Frame may not be necessary, even though blink is saved.
         At least this is something we recognize.  */
      frame_size = 0;
    }

  if ((insn & BUILD_INSN (-1, 0, -1, -1, -1))	/* st fp,[sp] */
      == BUILD_INSN (2, 0, SP_REGNUM, FP_REGNUM, 0))
    {
      insn = codestream_get ();
      if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
	  != BUILD_INSN (12, FP_REGNUM, SP_REGNUM, SP_REGNUM, 0))
	return -1;

      /* Check for stack adjustment sub sp,sp,N.  */
      insn = codestream_peek ();
      if ((insn & BUILD_INSN (-1, -1, -1, 0, 0))
	  == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, 0, 0))
	{
	  if (LIMM_P (X_C (insn)))
	    frame_size = codestream_get ();
	  else if (SHIMM_P (X_C (insn)))
	    frame_size = X_D (insn);
	  else
	    return -1;
	  if (frame_size < 0)
	    return -1;

	  codestream_get ();

	  /* This sequence is used to get the address of the return
	     buffer for a function that returns a structure.  */
	  insn = codestream_peek ();
	  if ((insn & OPMASK) == 0x60000000)
	    codestream_get ();
	}
      /* Frameless fn.  */
      else
	{
	  frame_size = 0;
	}
    }

  /* If we found a "sub sp,sp,N" and nothing else, it may or may not be a
     stdarg fn.  The stdarg decrement is not treated as part of the frame size,
     so we have a dilemma: what do we return?  For now, if we get a
     "sub sp,sp,N" and nothing else assume this isn't a stdarg fn.  One way
     to fix this completely would be to add a bit to the function descriptor
     that says the function is a stdarg function.  */

  if (frame_size < 0 && maybe_stdarg_decr > 0)
    return maybe_stdarg_decr;
  return frame_size;
}

/* Given a pc value, skip it forward past the function prologue by
   disassembling instructions that appear to be a prologue.

   If FRAMELESS_P is set, we are only testing to see if the function
   is frameless.  If it is a frameless function, return PC unchanged.
   This allows a quicker answer.  */

CORE_ADDR
arc_skip_prologue (CORE_ADDR pc, int frameless_p)
{
  unsigned int insn;
  int i, frame_size;

  if ((frame_size = arc_get_frame_setup (pc)) < 0)
    return (pc);

  if (frameless_p)
    return frame_size == 0 ? pc : codestream_tell ();

  /* Skip over register saves.  */
  for (i = 0; i < 8; i++)
    {
      insn = codestream_peek ();
      if ((insn & BUILD_INSN (-1, 0, -1, 0, 0))
	  != BUILD_INSN (2, 0, SP_REGNUM, 0, 0))
	break;			/* not st insn */
      if (!ARC_CALL_SAVED_REG (X_C (insn)))
	break;
      codestream_get ();
    }

  return codestream_tell ();
}

/* Is the prologue at PC frameless?  */

int
arc_prologue_frameless_p (CORE_ADDR pc)
{
  return (pc == arc_skip_prologue (pc, 1));
}

/* Return the return address for a frame.
   This is used to implement FRAME_SAVED_PC.
   This is taken from frameless_look_for_prologue.  */

CORE_ADDR
arc_frame_saved_pc (struct frame_info *frame)
{
  CORE_ADDR func_start;
  unsigned int insn;

  func_start = get_pc_function_start (frame->pc) + FUNCTION_START_OFFSET;
  if (func_start == 0)
    {
      /* Best guess.  */
      return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame) + 4, 4));
    }

  /* The authority for what appears here is the home-grown ABI.
     The most recent version is 1.2.  */

  insn = setup_prologue_scan (func_start);

  /* First insn may be "sub sp,sp,N" if stdarg fn.  */
  if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
      == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0))
    insn = codestream_get ();

  /* If the next insn is "st blink,[sp,4]" we can get blink from there.
     Otherwise this is a leaf function and we can use blink.  Note that
     this still allows for the case where a leaf function saves/clobbers/
     restores blink.  */

  if ((insn & BUILD_INSN (-1, 0, -1, -1, -1))	/* st blink,[sp,4] */
      != BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4))
    return ARC_PC_TO_REAL_ADDRESS (read_register (BLINK_REGNUM));
  else
    return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame) + 4, 4));
}

/*
 * Parse the first few instructions of the function to see
 * what registers were stored.
 *
 * The startup sequence can be at the start of the function.
 * 'st blink,[sp+4], st fp,[sp], mov fp,sp' 
 *
 * Local space is allocated just below by sub sp,sp,nnn.
 * Next, the registers used by this function are stored (as offsets from sp).
 */

void
frame_find_saved_regs (struct frame_info *fip, struct frame_saved_regs *fsrp)
{
  long locals;
  unsigned int insn;
  CORE_ADDR dummy_bottom;
  CORE_ADDR adr;
  int i, regnum, offset;

  memset (fsrp, 0, sizeof *fsrp);

  /* If frame is the end of a dummy, compute where the beginning would be.  */
  dummy_bottom = fip->frame - 4 - REGISTER_BYTES - CALL_DUMMY_LENGTH;

  /* Check if the PC is in the stack, in a dummy frame.  */
  if (dummy_bottom <= fip->pc && fip->pc <= fip->frame)
    {
      /* all regs were saved by push_call_dummy () */
      adr = fip->frame;
      for (i = 0; i < NUM_REGS; i++)
	{
	  adr -= REGISTER_RAW_SIZE (i);
	  fsrp->regs[i] = adr;
	}
      return;
    }

  locals = arc_get_frame_setup (get_pc_function_start (fip->pc));

  if (locals >= 0)
    {
      /* Set `adr' to the value of `sp'.  */
      adr = fip->frame - locals;
      for (i = 0; i < 8; i++)
	{
	  insn = codestream_get ();
	  if ((insn & BUILD_INSN (-1, 0, -1, 0, 0))
	      != BUILD_INSN (2, 0, SP_REGNUM, 0, 0))
	    break;
	  regnum = X_C (insn);
	  offset = X_D (insn);
	  fsrp->regs[regnum] = adr + offset;
	}
    }

  fsrp->regs[PC_REGNUM] = fip->frame + 4;
  fsrp->regs[FP_REGNUM] = fip->frame;
}

void
arc_push_dummy_frame (void)
{
  CORE_ADDR sp = read_register (SP_REGNUM);
  int regnum;
  char regbuf[MAX_REGISTER_RAW_SIZE];

  read_register_gen (PC_REGNUM, regbuf);
  write_memory (sp + 4, regbuf, REGISTER_SIZE);
  read_register_gen (FP_REGNUM, regbuf);
  write_memory (sp, regbuf, REGISTER_SIZE);
  write_register (FP_REGNUM, sp);
  for (regnum = 0; regnum < NUM_REGS; regnum++)
    {
      read_register_gen (regnum, regbuf);
      sp = push_bytes (sp, regbuf, REGISTER_RAW_SIZE (regnum));
    }
  sp += (2 * REGISTER_SIZE);
  write_register (SP_REGNUM, sp);
}

void
arc_pop_frame (void)
{
  struct frame_info *frame = get_current_frame ();
  CORE_ADDR fp;
  int regnum;
  struct frame_saved_regs fsr;
  char regbuf[MAX_REGISTER_RAW_SIZE];

  fp = FRAME_FP (frame);
  get_frame_saved_regs (frame, &fsr);
  for (regnum = 0; regnum < NUM_REGS; regnum++)
    {
      CORE_ADDR adr;
      adr = fsr.regs[regnum];
      if (adr)
	{
	  read_memory (adr, regbuf, REGISTER_RAW_SIZE (regnum));
	  write_register_bytes (REGISTER_BYTE (regnum), regbuf,
				REGISTER_RAW_SIZE (regnum));
	}
    }
  write_register (FP_REGNUM, read_memory_integer (fp, 4));
  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
  write_register (SP_REGNUM, fp + 8);
  flush_cached_frames ();
}

/* Simulate single-step.  */

typedef enum
{
  NORMAL4,			/* a normal 4 byte insn */
  NORMAL8,			/* a normal 8 byte insn */
  BRANCH4,			/* a 4 byte branch insn, including ones without delay slots */
  BRANCH8,			/* an 8 byte branch insn, including ones with delay slots */
}
insn_type;

/* Return the type of INSN and store in TARGET the destination address of a
   branch if this is one.  */
/* ??? Need to verify all cases are properly handled.  */

static insn_type
get_insn_type (unsigned long insn, CORE_ADDR pc, CORE_ADDR *target)
{
  unsigned long limm;

  switch (insn >> 27)
    {
    case 0:
    case 1:
    case 2:			/* load/store insns */
      if (LIMM_P (X_A (insn))
	  || LIMM_P (X_B (insn))
	  || LIMM_P (X_C (insn)))
	return NORMAL8;
      return NORMAL4;
    case 4:
    case 5:
    case 6:			/* branch insns */
      *target = pc + 4 + X_L (insn);
      /* ??? It isn't clear that this is always the right answer.
         The problem occurs when the next insn is an 8 byte insn.  If the
         branch is conditional there's no worry as there shouldn't be an 8
         byte insn following.  The programmer may be cheating if s/he knows
         the branch will never be taken, but we don't deal with that.
         Note that the programmer is also allowed to play games by putting
         an insn with long immediate data in the delay slot and then duplicate
         the long immediate data at the branch target.  Ugh!  */
      if (X_N (insn) == 0)
	return BRANCH4;
      return BRANCH8;
    case 7:			/* jump insns */
      if (LIMM_P (X_B (insn)))
	{
	  limm = read_memory_integer (pc + 4, 4);
	  *target = ARC_PC_TO_REAL_ADDRESS (limm);
	  return BRANCH8;
	}
      if (SHIMM_P (X_B (insn)))
	*target = ARC_PC_TO_REAL_ADDRESS (X_D (insn));
      else
	*target = ARC_PC_TO_REAL_ADDRESS (read_register (X_B (insn)));
      if (X_Q (insn) == 0 && X_N (insn) == 0)
	return BRANCH4;
      return BRANCH8;
    default:			/* arithmetic insns, etc. */
      if (LIMM_P (X_A (insn))
	  || LIMM_P (X_B (insn))
	  || LIMM_P (X_C (insn)))
	return NORMAL8;
      return NORMAL4;
    }
}

/* single_step() is called just before we want to resume the inferior, if we
   want to single-step it but there is no hardware or kernel single-step
   support.  We find all the possible targets of the coming instruction and
   breakpoint them.

   single_step is also called just after the inferior stops.  If we had
   set up a simulated single-step, we undo our damage.  */

void
arc_software_single_step (enum target_signal ignore,	/* sig but we don't need it */
			  int insert_breakpoints_p)
{
  static CORE_ADDR next_pc, target;
  static int brktrg_p;
  typedef char binsn_quantum[BREAKPOINT_MAX];
  static binsn_quantum break_mem[2];

  if (insert_breakpoints_p)
    {
      insn_type type;
      CORE_ADDR pc;
      unsigned long insn;

      pc = read_register (PC_REGNUM);
      insn = read_memory_integer (pc, 4);
      type = get_insn_type (insn, pc, &target);

      /* Always set a breakpoint for the insn after the branch.  */
      next_pc = pc + ((type == NORMAL8 || type == BRANCH8) ? 8 : 4);
      target_insert_breakpoint (next_pc, break_mem[0]);

      brktrg_p = 0;

      if ((type == BRANCH4 || type == BRANCH8)
      /* Watch out for branches to the following location.
         We just stored a breakpoint there and another call to
         target_insert_breakpoint will think the real insn is the
         breakpoint we just stored there.  */
	  && target != next_pc)
	{
	  brktrg_p = 1;
	  target_insert_breakpoint (target, break_mem[1]);
	}

    }
  else
    {
      /* Remove breakpoints.  */
      target_remove_breakpoint (next_pc, break_mem[0]);

      if (brktrg_p)
	target_remove_breakpoint (target, break_mem[1]);

      /* Fix the pc.  */
      stop_pc -= DECR_PC_AFTER_BREAK;
      write_pc (stop_pc);
    }
}

/* Because of Multi-arch, GET_LONGJMP_TARGET is always defined.  So test
   for a definition of JB_PC.  */
#ifdef JB_PC
/* Figure out where the longjmp will land.  Slurp the args out of the stack.
   We expect the first arg to be a pointer to the jmp_buf structure from which
   we extract the pc (JB_PC) that we will land at.  The pc is copied into PC.
   This routine returns true on success. */

int
get_longjmp_target (CORE_ADDR *pc)
{
  char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
  CORE_ADDR sp, jb_addr;

  sp = read_register (SP_REGNUM);

  if (target_read_memory (sp + SP_ARG0,		/* Offset of first arg on stack */
			  buf,
			  TARGET_PTR_BIT / TARGET_CHAR_BIT))
    return 0;

  jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);

  if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
			  TARGET_PTR_BIT / TARGET_CHAR_BIT))
    return 0;

  *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);

  return 1;
}
#endif /* GET_LONGJMP_TARGET */

/* Disassemble one instruction.  */

static int
arc_print_insn (bfd_vma vma, disassemble_info *info)
{
  static int current_mach;
  static int current_endian;
  static disassembler_ftype current_disasm;

  if (current_disasm == NULL
      || arc_bfd_mach_type != current_mach
      || TARGET_BYTE_ORDER != current_endian)
    {
      current_mach = arc_bfd_mach_type;
      current_endian = TARGET_BYTE_ORDER;
      current_disasm = arc_get_disassembler (NULL);
    }

  return (*current_disasm) (vma, info);
}

/* Command to set cpu type.  */

void
arc_set_cpu_type_command (char *args, int from_tty)
{
  int i;

  if (tmp_arc_cpu_type == NULL || *tmp_arc_cpu_type == '\0')
    {
      printf_unfiltered ("The known ARC cpu types are as follows:\n");
      for (i = 0; arc_cpu_type_table[i].name != NULL; ++i)
	printf_unfiltered ("%s\n", arc_cpu_type_table[i].name);

      /* Restore the value.  */
      tmp_arc_cpu_type = xstrdup (arc_cpu_type);

      return;
    }

  if (!arc_set_cpu_type (tmp_arc_cpu_type))
    {
      error ("Unknown cpu type `%s'.", tmp_arc_cpu_type);
      /* Restore its value.  */
      tmp_arc_cpu_type = xstrdup (arc_cpu_type);
    }
}

static void
arc_show_cpu_type_command (char *args, int from_tty)
{
}

/* Modify the actual cpu type.
   Result is a boolean indicating success.  */

static int
arc_set_cpu_type (char *str)
{
  int i, j;

  if (str == NULL)
    return 0;

  for (i = 0; arc_cpu_type_table[i].name != NULL; ++i)
    {
      if (strcasecmp (str, arc_cpu_type_table[i].name) == 0)
	{
	  arc_cpu_type = str;
	  arc_bfd_mach_type = arc_cpu_type_table[i].value;
	  return 1;
	}
    }

  return 0;
}

void
_initialize_arc_tdep (void)
{
  struct cmd_list_element *c;

  c = add_set_cmd ("cpu", class_support, var_string_noescape,
		   (char *) &tmp_arc_cpu_type,
		   "Set the type of ARC cpu in use.\n\
This command has two purposes.  In a multi-cpu system it lets one\n\
change the cpu being debugged.  It also gives one access to\n\
cpu-type-specific registers and recognize cpu-type-specific instructions.\
",
		   &setlist);
  set_cmd_cfunc (c, arc_set_cpu_type_command);
  c = add_show_from_set (c, &showlist);
  set_cmd_cfunc (c, arc_show_cpu_type_command);

  /* We have to use xstrdup() here because the `set' command frees it
     before setting a new value.  */
  tmp_arc_cpu_type = xstrdup (DEFAULT_ARC_CPU_TYPE);
  arc_set_cpu_type (tmp_arc_cpu_type);

  c = add_set_cmd ("displaypipeline", class_support, var_zinteger,
		   (char *) &display_pipeline_p,
		   "Set pipeline display (simulator only).\n\
When enabled, the state of the pipeline after each cycle is displayed.",
		   &setlist);
  c = add_show_from_set (c, &showlist);

  c = add_set_cmd ("debugpipeline", class_support, var_zinteger,
		   (char *) &debug_pipeline_p,
		   "Set pipeline debug display (simulator only).\n\
When enabled, debugging information about the pipeline is displayed.",
		   &setlist);
  c = add_show_from_set (c, &showlist);

  c = add_set_cmd ("cputimer", class_support, var_zinteger,
		   (char *) &cpu_timer,
		   "Set maximum cycle count (simulator only).\n\
Control will return to gdb if the timer expires.\n\
A negative value disables the timer.",
		   &setlist);
  c = add_show_from_set (c, &showlist);

  tm_print_insn = arc_print_insn;
}
