/* Target-dependent code for the S12Z, for the GDB.
   Copyright (C) 2018-2020 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 3 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, see <http://www.gnu.org/licenses/>.  */

/* Much of this file is shamelessly copied from or1k-tdep.c and others.  */

#include "defs.h"

#include "arch-utils.h"
#include "dwarf2-frame.h"
#include "gdbsupport/errors.h"
#include "frame-unwind.h"
#include "gdbcore.h"
#include "gdbcmd.h"
#include "inferior.h"
#include "opcode/s12z.h"
#include "trad-frame.h"
#include "remote.h"
#include "opcodes/s12z-opc.h"

/* Two of the registers included in S12Z_N_REGISTERS are
   the CCH and CCL "registers" which are just views into
   the CCW register.  */
#define N_PHYSICAL_REGISTERS (S12Z_N_REGISTERS - 2)


/*  A permutation of all the physical registers.   Indexing this array
    with an integer from gdb's internal representation will return the
    register enum.  */
static const int reg_perm[N_PHYSICAL_REGISTERS] =
  {
   REG_D0,
   REG_D1,
   REG_D2,
   REG_D3,
   REG_D4,
   REG_D5,
   REG_D6,
   REG_D7,
   REG_X,
   REG_Y,
   REG_S,
   REG_P,
   REG_CCW
  };

/*  The inverse of the above permutation.  Indexing this
    array with a register enum (e.g. REG_D2) will return the register
    number in gdb's internal representation.  */
static const int inv_reg_perm[N_PHYSICAL_REGISTERS] =
  {
   2, 3, 4, 5,      /* d2, d3, d4, d5 */
   0, 1,            /* d0, d1 */
   6, 7,            /* d6, d7 */
   8, 9, 10, 11, 12 /* x, y, s, p, ccw */
  };

/*  Return the name of the register REGNUM.  */
static const char *
s12z_register_name (struct gdbarch *gdbarch, int regnum)
{
  /*  Registers is declared in opcodes/s12z.h.   */
  return registers[reg_perm[regnum]].name;
}

static CORE_ADDR
s12z_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR start_pc = 0;

  if (find_pc_partial_function (pc, NULL, &start_pc, NULL))
    {
      CORE_ADDR prologue_end = skip_prologue_using_sal (gdbarch, pc);

      if (prologue_end != 0)
        return prologue_end;
    }

  warning (_("%s Failed to find end of prologue PC = %08x"),
	   __FUNCTION__, (unsigned int) pc);

  return pc;
}

static struct type *
s12z_register_type (struct gdbarch *gdbarch, int reg_nr)
{
  switch (registers[reg_perm[reg_nr]].bytes)
    {
    case 1:
      return builtin_type (gdbarch)->builtin_uint8;
    case 2:
      return builtin_type (gdbarch)->builtin_uint16;
    case 3:
      return builtin_type (gdbarch)->builtin_uint24;
    case 4:
      return builtin_type (gdbarch)->builtin_uint32;
    default:
      return builtin_type (gdbarch)->builtin_uint32;
    }
  return builtin_type (gdbarch)->builtin_int0;
}


static int
s12z_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int num)
{
  switch (num)
    {
    case 15:      return REG_S;
    case 7:       return REG_X;
    case 8:       return REG_Y;
    case 42:      return REG_D0;
    case 43:      return REG_D1;
    case 44:      return REG_D2;
    case 45:      return REG_D3;
    case 46:      return REG_D4;
    case 47:      return REG_D5;
    case 48:      return REG_D6;
    case 49:      return REG_D7;
    }
  return -1;
}


/* Support functions for frame handling.  */

/* Copy of gdb_buffered_insn_length_fprintf from disasm.c.  */

static int ATTRIBUTE_PRINTF (2, 3)
s12z_fprintf_disasm (void *stream, const char *format, ...)
{
  return 0;
}

static struct disassemble_info
s12z_disassemble_info (struct gdbarch *gdbarch)
{
  struct disassemble_info di;
  init_disassemble_info (&di, &null_stream, s12z_fprintf_disasm);
  di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
  di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
  di.endian = gdbarch_byte_order (gdbarch);
  di.read_memory_func = [](bfd_vma memaddr, gdb_byte *myaddr,
			   unsigned int len, struct disassemble_info *info)
    {
      return target_read_code (memaddr, myaddr, len);
    };
  return di;
}


/* A struct (based on mem_read_abstraction_base) to read memory
   through the disassemble_info API.  */
struct mem_read_abstraction
{
  struct mem_read_abstraction_base base; /* The parent struct.  */
  bfd_vma memaddr;                  /* Where to read from.  */
  struct disassemble_info* info;  /* The disassembler  to use for reading.  */
};

/* Advance the reader by one byte.  */
static void
advance (struct mem_read_abstraction_base *b)
{
  struct mem_read_abstraction *mra = (struct mem_read_abstraction *) b;
  mra->memaddr++;
}

/* Return the current position of the reader.  */
static bfd_vma
posn (struct mem_read_abstraction_base *b)
{
  struct mem_read_abstraction *mra = (struct mem_read_abstraction *) b;
  return mra->memaddr;
}

/* Read the N bytes at OFFSET  using B.  The bytes read are stored in BYTES.
   It is the caller's responsibility to ensure that this is of at least N
   in size.  */
static int
abstract_read_memory (struct mem_read_abstraction_base *b,
		      int offset,
		      size_t n, bfd_byte *bytes)
{
  struct mem_read_abstraction *mra = (struct mem_read_abstraction *) b;

  int status =
    (*mra->info->read_memory_func) (mra->memaddr + offset,
				    bytes, n, mra->info);

  if (status != 0)
    {
      (*mra->info->memory_error_func) (status, mra->memaddr, mra->info);
      return -1;
    }

  return 0;
}


/* Return the stack adjustment caused by a push or pull instruction.  */
static int
push_pull_get_stack_adjustment (int n_operands,
				struct operand *const *operands)
{
  int stack_adjustment = 0;
  gdb_assert (n_operands > 0);
  if (operands[0]->cl == OPND_CL_REGISTER_ALL)
    stack_adjustment = 26;  /* All the regs are involved.  */
  else if (operands[0]->cl == OPND_CL_REGISTER_ALL16)
    stack_adjustment = 4 * 2; /* All four 16 bit regs are involved.  */
  else
    for (int i = 0; i < n_operands; ++i)
      {
	if (operands[i]->cl != OPND_CL_REGISTER)
	  continue; /* I don't think this can ever happen.  */
	const struct register_operand *op
	  = (const struct register_operand *) operands[i];
	switch (op->reg)
	  {
	  case REG_X:
	  case REG_Y:
	    stack_adjustment += 3;
	    break;
	  case REG_D7:
	  case REG_D6:
	    stack_adjustment += 4;
	    break;
	  case REG_D2:
	  case REG_D3:
	  case REG_D4:
	  case REG_D5:
	    stack_adjustment += 2;
	    break;
	  case REG_D0:
	  case REG_D1:
	  case REG_CCL:
	  case REG_CCH:
	    stack_adjustment += 1;
	    break;
	  default:
	    gdb_assert_not_reached ("Invalid register in push/pull operation.");
	    break;
	  }
      }
  return stack_adjustment;
}

/* Initialize a prologue cache.  */

static struct trad_frame_cache *
s12z_frame_cache (struct frame_info *this_frame, void **prologue_cache)
{
  struct trad_frame_cache *info;

  CORE_ADDR this_sp;
  CORE_ADDR this_sp_for_id;

  CORE_ADDR start_addr;
  CORE_ADDR end_addr;

  /* Nothing to do if we already have this info.  */
  if (NULL != *prologue_cache)
    return (struct trad_frame_cache *) *prologue_cache;

  /* Get a new prologue cache and populate it with default values.  */
  info = trad_frame_cache_zalloc (this_frame);
  *prologue_cache = info;

  /* Find the start address of this function (which is a normal frame, even
     if the next frame is the sentinel frame) and the end of its prologue.  */
  CORE_ADDR this_pc = get_frame_pc (this_frame);
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  find_pc_partial_function (this_pc, NULL, &start_addr, NULL);

  /* Get the stack pointer if we have one (if there's no process executing
     yet we won't have a frame.  */
  this_sp = (NULL == this_frame) ? 0 :
    get_frame_register_unsigned (this_frame, REG_S);

  /* Return early if GDB couldn't find the function.  */
  if (start_addr == 0)
    {
      warning (_("Couldn't find function including address %s SP is %s"),
               paddress (gdbarch, this_pc),
               paddress (gdbarch, this_sp));

      /* JPB: 28-Apr-11.  This is a temporary patch, to get round GDB
	 crashing right at the beginning.  Build the frame ID as best we
	 can.  */
      trad_frame_set_id (info, frame_id_build (this_sp, this_pc));

      return info;
    }

  /* The default frame base of this frame (for ID purposes only - frame
     base is an overloaded term) is its stack pointer.  For now we use the
     value of the SP register in this frame.  However if the PC is in the
     prologue of this frame, before the SP has been set up, then the value
     will actually be that of the prev frame, and we'll need to adjust it
     later.  */
  trad_frame_set_this_base (info, this_sp);
  this_sp_for_id = this_sp;

  /* We should only examine code that is in the prologue.  This is all code
     up to (but not including) end_addr.  We should only populate the cache
     while the address is up to (but not including) the PC or end_addr,
     whichever is first.  */
  end_addr = s12z_skip_prologue (gdbarch, start_addr);

  /* All the following analysis only occurs if we are in the prologue and
     have executed the code.  Check we have a sane prologue size, and if
     zero we are frameless and can give up here.  */
  if (end_addr < start_addr)
    error (_("end addr %s is less than start addr %s"),
	   paddress (gdbarch, end_addr), paddress (gdbarch, start_addr));

  CORE_ADDR addr = start_addr; /* Where we have got to?  */
  int frame_size = 0;
  int saved_frame_size = 0;

  struct disassemble_info di = s12z_disassemble_info (gdbarch);


  struct mem_read_abstraction mra;
  mra.base.read = (int (*)(mem_read_abstraction_base*,
			   int, size_t, bfd_byte*)) abstract_read_memory;
  mra.base.advance = advance ;
  mra.base.posn = posn;
  mra.info = &di;

  while (this_pc > addr)
    {
      enum optr optr = OP_INVALID;
      short osize;
      int n_operands = 0;
      struct operand *operands[6];
      mra.memaddr = addr;
      int n_bytes =
	decode_s12z (&optr, &osize, &n_operands, operands,
		     (mem_read_abstraction_base *) &mra);

      switch (optr)
	{
	case OP_tbNE:
	case OP_tbPL:
	case OP_tbMI:
	case OP_tbGT:
	case OP_tbLE:
	case OP_dbNE:
	case OP_dbEQ:
	case OP_dbPL:
	case OP_dbMI:
	case OP_dbGT:
	case OP_dbLE:
	  /* Conditional Branches.   If any of these are encountered, then
	     it is likely that a RTS will terminate it.  So we need to save
	     the frame size so it can be restored.  */
	  saved_frame_size = frame_size;
	  break;
	case OP_rts:
	  /* Restore the frame size from a previously saved value.  */
	  frame_size = saved_frame_size;
	  break;
	case OP_push:
	  frame_size += push_pull_get_stack_adjustment (n_operands, operands);
	  break;
	case OP_pull:
	  frame_size -= push_pull_get_stack_adjustment (n_operands, operands);
	  break;
	case OP_lea:
	  if (operands[0]->cl == OPND_CL_REGISTER)
	    {
	      int reg = ((struct register_operand *) (operands[0]))->reg;
	      if ((reg == REG_S) && (operands[1]->cl == OPND_CL_MEMORY))
		{
		  const struct memory_operand *mo
		    = (const struct memory_operand * ) operands[1];
		  if (mo->n_regs == 1 && !mo->indirect
		      && mo->regs[0] == REG_S
		      && mo->mutation == OPND_RM_NONE)
		    {
		      /* LEA S, (xxx, S) -- Decrement the stack.   This is
			 almost certainly the start of a frame.  */
		      int simm = (signed char)  mo->base_offset;
		      frame_size -= simm;
		    }
		}
	    }
	  break;
	default:
	  break;
	}
      addr += n_bytes;
      for (int o = 0; o < n_operands; ++o)
	free (operands[o]);
    }

  /* If the PC has not actually got to this point, then the frame
     base will be wrong, and we adjust it. */
  if (this_pc < addr)
    {
      /* Only do if executing.  */
      if (0 != this_sp)
        {
          this_sp_for_id = this_sp - frame_size;
          trad_frame_set_this_base (info, this_sp_for_id);
        }
      trad_frame_set_reg_value (info, REG_S, this_sp + 3);
      trad_frame_set_reg_addr (info, REG_P, this_sp);
    }
  else
    {
      gdb_assert (this_sp == this_sp_for_id);
      /* The stack pointer of the prev frame is frame_size greater
         than the stack pointer of this frame plus one address
         size (caused by the JSR or BSR).  */
      trad_frame_set_reg_value (info, REG_S,
                                this_sp + frame_size + 3);
      trad_frame_set_reg_addr (info, REG_P, this_sp + frame_size);
    }


  /* Build the frame ID.  */
  trad_frame_set_id (info, frame_id_build (this_sp_for_id, start_addr));

  return info;
}

/* Implement the this_id function for the stub unwinder.  */
static void
s12z_frame_this_id (struct frame_info *this_frame,
		    void **prologue_cache, struct frame_id *this_id)
{
  struct trad_frame_cache *info = s12z_frame_cache (this_frame,
						    prologue_cache);

  trad_frame_get_id (info, this_id);
}


/* Implement the prev_register function for the stub unwinder.  */
static struct value *
s12z_frame_prev_register (struct frame_info *this_frame,
			  void **prologue_cache, int regnum)
{
  struct trad_frame_cache *info = s12z_frame_cache (this_frame,
						    prologue_cache);

  return trad_frame_get_register (info, this_frame, regnum);
}

/* Data structures for the normal prologue-analysis-based unwinder.  */
static const struct frame_unwind s12z_frame_unwind = {
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  s12z_frame_this_id,
  s12z_frame_prev_register,
  NULL,
  default_frame_sniffer,
  NULL,
};


constexpr gdb_byte s12z_break_insn[] = {0x00};

typedef BP_MANIPULATION (s12z_break_insn) s12z_breakpoint;

struct gdbarch_tdep
{
};

/*  A vector of human readable characters representing the
    bits in the CCW register.  Unused bits are represented as '-'.
    Lowest significant bit comes first.  */
static const char ccw_bits[] =
  {
   'C',  /* Carry  */
   'V',  /* Two's Complement Overflow  */
   'Z',  /* Zero  */
   'N',  /* Negative  */
   'I',  /* Interrupt  */
   '-',
   'X',  /* Non-Maskable Interrupt  */
   'S',  /* STOP Disable  */
   '0',  /*  Interrupt priority level */
   '0',  /*  ditto  */
   '0',  /*  ditto  */
   '-',
   '-',
   '-',
   '-',
   'U'   /* User/Supervisor State.  */
  };

/* Print a human readable representation of the CCW register.
   For example: "u----000SX-Inzvc" corresponds to the value
   0xD0.  */
static void
s12z_print_ccw_info (struct gdbarch *gdbarch,
                     struct ui_file *file,
                     struct frame_info *frame,
                     int reg)
{
  struct value *v = value_of_register (reg, frame);
  const char *name = gdbarch_register_name (gdbarch, reg);
  uint32_t ccw = value_as_long (v);
  fputs_filtered (name, file);
  size_t len = strlen (name);
  const int stop_1 = 15;
  const int stop_2 = 17;
  for (int i = 0; i < stop_1 - len; ++i)
    fputc_filtered (' ', file);
  fprintf_filtered (file, "0x%04x", ccw);
  for (int i = 0; i < stop_2 - len; ++i)
    fputc_filtered (' ', file);
  for (int b = 15; b >= 0; --b)
    {
      if (ccw & (0x1u << b))
        {
          if (ccw_bits[b] == 0)
            fputc_filtered ('1', file);
          else
            fputc_filtered (ccw_bits[b], file);
        }
      else
        fputc_filtered (tolower (ccw_bits[b]), file);
    }
  fputc_filtered ('\n', file);
}

static void
s12z_print_registers_info (struct gdbarch *gdbarch,
			    struct ui_file *file,
			    struct frame_info *frame,
			    int regnum, int print_all)
{
  const int numregs = (gdbarch_num_regs (gdbarch)
		       + gdbarch_num_pseudo_regs (gdbarch));

  if (regnum == -1)
    {
      for (int reg = 0; reg < numregs; reg++)
        {
          if (REG_CCW == reg_perm[reg])
            {
              s12z_print_ccw_info (gdbarch, file, frame, reg);
              continue;
            }
          default_print_registers_info (gdbarch, file, frame, reg, print_all);
        }
    }
  else if (REG_CCW == reg_perm[regnum])
    s12z_print_ccw_info (gdbarch, file, frame, regnum);
  else
    default_print_registers_info (gdbarch, file, frame, regnum, print_all);
}




static void
s12z_extract_return_value (struct type *type, struct regcache *regcache,
                              void *valbuf)
{
  int reg = -1;

  switch (TYPE_LENGTH (type))
    {
    case 0:   /* Nothing to do */
      return;

    case 1:
      reg = REG_D0;
      break;

    case 2:
      reg = REG_D2;
      break;

    case 3:
      reg = REG_X;
      break;

    case 4:
      reg = REG_D6;
      break;

    default:
      error (_("bad size for return value"));
      return;
    }

  regcache->cooked_read (inv_reg_perm[reg], (gdb_byte *) valbuf);
}

static enum return_value_convention
s12z_return_value (struct gdbarch *gdbarch, struct value *function,
                   struct type *type, struct regcache *regcache,
                   gdb_byte *readbuf, const gdb_byte *writebuf)
{
  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
      || TYPE_CODE (type) == TYPE_CODE_UNION
      || TYPE_CODE (type) == TYPE_CODE_ARRAY
      || TYPE_LENGTH (type) > 4)
    return RETURN_VALUE_STRUCT_CONVENTION;

  if (readbuf)
    s12z_extract_return_value (type, regcache, readbuf);

  return RETURN_VALUE_REGISTER_CONVENTION;
}


static void
show_bdccsr_command (const char *args, int from_tty)
{
  struct string_file output;
  target_rcmd ("bdccsr", &output);

  printf_unfiltered ("The current BDCCSR value is %s\n", output.string().c_str());
}

static struct gdbarch *
s12z_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch_tdep *tdep = XNEW (struct gdbarch_tdep);
  struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);

  add_cmd ("bdccsr", class_support, show_bdccsr_command,
	   _("Show the current value of the microcontroller's BDCCSR."),
           &maintenanceinfolist);

  /* Target data types.  */
  set_gdbarch_short_bit (gdbarch, 16);
  set_gdbarch_int_bit (gdbarch, 16);
  set_gdbarch_long_bit (gdbarch, 32);
  set_gdbarch_long_long_bit (gdbarch, 32);
  set_gdbarch_ptr_bit (gdbarch, 24);
  set_gdbarch_addr_bit (gdbarch, 24);
  set_gdbarch_char_signed (gdbarch, 0);

  set_gdbarch_ps_regnum (gdbarch, REG_CCW);
  set_gdbarch_pc_regnum (gdbarch, REG_P);
  set_gdbarch_sp_regnum (gdbarch, REG_S);


  set_gdbarch_print_registers_info (gdbarch, s12z_print_registers_info);

  set_gdbarch_breakpoint_kind_from_pc (gdbarch,
				       s12z_breakpoint::kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch,
				       s12z_breakpoint::bp_from_kind);

  set_gdbarch_num_regs (gdbarch, N_PHYSICAL_REGISTERS);
  set_gdbarch_register_name (gdbarch, s12z_register_name);
  set_gdbarch_skip_prologue (gdbarch, s12z_skip_prologue);
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, s12z_dwarf_reg_to_regnum);

  set_gdbarch_register_type (gdbarch, s12z_register_type);

  frame_unwind_append_unwinder (gdbarch, &s12z_frame_unwind);
  /* Currently, the only known producer for this architecture, produces buggy
     dwarf CFI.   So don't append a dwarf unwinder until the situation is
     better understood.  */

  set_gdbarch_return_value (gdbarch, s12z_return_value);

  return gdbarch;
}

void
_initialize_s12z_tdep (void)
{
  gdbarch_register (bfd_arch_s12z, s12z_gdbarch_init, NULL);
}
