/* ARC target-dependent stuff.
   Copyright (C) 1995, 1997 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"

/* 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[] = {
  { "base", bfd_mach_arc_base },
  { 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 PARAMS ((unsigned int *, int));
static void codestream_seek PARAMS ((CORE_ADDR));
static unsigned int codestream_fill PARAMS ((int));

#define CODESTREAM_BUFSIZ 16 
static CORE_ADDR codestream_next_addr;
static CORE_ADDR codestream_addr;
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 (peek_flag)
    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.  */
  if (HOST_BYTE_ORDER != TARGET_BYTE_ORDER)
    {
      register unsigned int i, j, n = sizeof (codestream_buf[0]);
      register char tmp, *p;
      for (i = 0, p = (char *) codestream_buf; i < CODESTREAM_BUFSIZ;
	   ++i, p += n)
	for (j = 0; j < n / 2; ++j)
	  tmp = p[j], p[j] = p[n - 1 - j], p[n - 1 - j] = tmp;
    }
  
  if (peek_flag)
    return codestream_peek ();
  else
    return codestream_get ();
}

static void
codestream_seek (place)
    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 (buf, count)
     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 (pc)
     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 (pc)
     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 (pc, frameless_p)
     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 ();
}

/* 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 (frame)
     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 (fip, fsrp)
     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
push_dummy_frame ()
{
  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
pop_frame ()
{
  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 (insn, pc, target)
     unsigned long insn;
     CORE_ADDR pc, *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 (ignore, insert_breakpoints_p)
     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);
    }
}

#ifdef GET_LONGJMP_TARGET
/* 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(pc)
     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 (vma, info)
     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 (current_mach,
					     current_endian == BIG_ENDIAN);
    }

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

void
arc_set_cpu_type_command (args, from_tty)
     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 = strsave (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 = strsave (arc_cpu_type);
    }
}

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

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

int
arc_set_cpu_type (str)
     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 ()
{
  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);
  c->function.cfunc = arc_set_cpu_type_command;
  c = add_show_from_set (c, &showlist);
  c->function.cfunc = arc_show_cpu_type_command;

  /* We have to use strsave here because the `set' command frees it before
     setting a new value.  */
  tmp_arc_cpu_type = strsave (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;
}
