/* Target-dependent code for the Texas Instruments MSP430 for GDB, the
   GNU debugger.

   Copyright (C) 2012-2022 Free Software Foundation, Inc.

   Contributed by Red Hat, 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/>.  */

#include "defs.h"
#include "arch-utils.h"
#include "prologue-value.h"
#include "target.h"
#include "regcache.h"
#include "dis-asm.h"
#include "gdbtypes.h"
#include "frame.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "value.h"
#include "gdbcore.h"
#include "dwarf2/frame.h"
#include "reggroups.h"
#include "gdbarch.h"

#include "elf/msp430.h"
#include "opcode/msp430-decode.h"
#include "elf-bfd.h"

/* Register Numbers.  */

enum
{
  MSP430_PC_RAW_REGNUM,
  MSP430_SP_RAW_REGNUM,
  MSP430_SR_RAW_REGNUM,
  MSP430_CG_RAW_REGNUM,
  MSP430_R4_RAW_REGNUM,
  MSP430_R5_RAW_REGNUM,
  MSP430_R6_RAW_REGNUM,
  MSP430_R7_RAW_REGNUM,
  MSP430_R8_RAW_REGNUM,
  MSP430_R9_RAW_REGNUM,
  MSP430_R10_RAW_REGNUM,
  MSP430_R11_RAW_REGNUM,
  MSP430_R12_RAW_REGNUM,
  MSP430_R13_RAW_REGNUM,
  MSP430_R14_RAW_REGNUM,
  MSP430_R15_RAW_REGNUM,

  MSP430_NUM_REGS,

  MSP430_PC_REGNUM = MSP430_NUM_REGS,
  MSP430_SP_REGNUM,
  MSP430_SR_REGNUM,
  MSP430_CG_REGNUM,
  MSP430_R4_REGNUM,
  MSP430_R5_REGNUM,
  MSP430_R6_REGNUM,
  MSP430_R7_REGNUM,
  MSP430_R8_REGNUM,
  MSP430_R9_REGNUM,
  MSP430_R10_REGNUM,
  MSP430_R11_REGNUM,
  MSP430_R12_REGNUM,
  MSP430_R13_REGNUM,
  MSP430_R14_REGNUM,
  MSP430_R15_REGNUM,

  MSP430_NUM_TOTAL_REGS,
  MSP430_NUM_PSEUDO_REGS = MSP430_NUM_TOTAL_REGS - MSP430_NUM_REGS
};

enum
{
  /* TI MSP430 Architecture.  */
  MSP_ISA_MSP430,

  /* TI MSP430X Architecture.  */
  MSP_ISA_MSP430X
};

enum
{
  /* The small code model limits code addresses to 16 bits.  */
  MSP_SMALL_CODE_MODEL,

  /* The large code model uses 20 bit addresses for function
     pointers.  These are stored in memory using four bytes (32 bits).  */
  MSP_LARGE_CODE_MODEL
};

/* Architecture specific data.  */

struct msp430_gdbarch_tdep : gdbarch_tdep_base
{
  /* The ELF header flags specify the multilib used.  */
  int elf_flags = 0;

  /* One of MSP_ISA_MSP430 or MSP_ISA_MSP430X.  */
  int isa = 0;

  /* One of MSP_SMALL_CODE_MODEL or MSP_LARGE_CODE_MODEL.  If, at
     some point, we support different data models too, we'll probably
     structure things so that we can combine values using logical
     "or".  */
  int code_model = 0;
};

/* This structure holds the results of a prologue analysis.  */

struct msp430_prologue
{
  /* The offset from the frame base to the stack pointer --- always
     zero or negative.

     Calling this a "size" is a bit misleading, but given that the
     stack grows downwards, using offsets for everything keeps one
     from going completely sign-crazy: you never change anything's
     sign for an ADD instruction; always change the second operand's
     sign for a SUB instruction; and everything takes care of
     itself.  */
  int frame_size;

  /* Non-zero if this function has initialized the frame pointer from
     the stack pointer, zero otherwise.  */
  int has_frame_ptr;

  /* If has_frame_ptr is non-zero, this is the offset from the frame
     base to where the frame pointer points.  This is always zero or
     negative.  */
  int frame_ptr_offset;

  /* The address of the first instruction at which the frame has been
     set up and the arguments are where the debug info says they are
     --- as best as we can tell.  */
  CORE_ADDR prologue_end;

  /* reg_offset[R] is the offset from the CFA at which register R is
     saved, or 1 if register R has not been saved.  (Real values are
     always zero or negative.)  */
  int reg_offset[MSP430_NUM_TOTAL_REGS];
};

/* Implement the "register_type" gdbarch method.  */

static struct type *
msp430_register_type (struct gdbarch *gdbarch, int reg_nr)
{
  if (reg_nr < MSP430_NUM_REGS)
    return builtin_type (gdbarch)->builtin_uint32;
  else if (reg_nr == MSP430_PC_REGNUM)
    return builtin_type (gdbarch)->builtin_func_ptr;
  else
    return builtin_type (gdbarch)->builtin_uint16;
}

/* Implement another version of the "register_type" gdbarch method
   for msp430x.  */

static struct type *
msp430x_register_type (struct gdbarch *gdbarch, int reg_nr)
{
  if (reg_nr < MSP430_NUM_REGS)
    return builtin_type (gdbarch)->builtin_uint32;
  else if (reg_nr == MSP430_PC_REGNUM)
    return builtin_type (gdbarch)->builtin_func_ptr;
  else
    return builtin_type (gdbarch)->builtin_uint32;
}

/* Implement the "register_name" gdbarch method.  */

static const char *
msp430_register_name (struct gdbarch *gdbarch, int regnr)
{
  static const char *const reg_names[] = {
    /* Raw registers.  */
    "", "", "", "", "", "", "", "",
    "", "", "", "", "", "", "", "",
    /* Pseudo registers.  */
    "pc", "sp", "sr", "cg", "r4", "r5", "r6", "r7",
    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
  };

  gdb_static_assert (ARRAY_SIZE (reg_names) == (MSP430_NUM_REGS
						+ MSP430_NUM_PSEUDO_REGS));
  return reg_names[regnr];
}

/* Implement the "register_reggroup_p" gdbarch method.  */

static int
msp430_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
			    const struct reggroup *group)
{
  if (group == all_reggroup)
    return 1;

  /* All other registers are saved and restored.  */
  if (group == save_reggroup || group == restore_reggroup)
    return (MSP430_NUM_REGS <= regnum && regnum < MSP430_NUM_TOTAL_REGS);

  return group == general_reggroup;
}

/* Implement the "pseudo_register_read" gdbarch method.  */

static enum register_status
msp430_pseudo_register_read (struct gdbarch *gdbarch,
			     readable_regcache *regcache,
			     int regnum, gdb_byte *buffer)
{
  if (MSP430_NUM_REGS <= regnum && regnum < MSP430_NUM_TOTAL_REGS)
    {
      enum register_status status;
      ULONGEST val;
      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
      int regsize = register_size (gdbarch, regnum);
      int raw_regnum = regnum - MSP430_NUM_REGS;

      status = regcache->raw_read (raw_regnum, &val);
      if (status == REG_VALID)
	store_unsigned_integer (buffer, regsize, byte_order, val);

      return status;
    }
  else
    gdb_assert_not_reached ("invalid pseudo register number");
}

/* Implement the "pseudo_register_write" gdbarch method.  */

static void
msp430_pseudo_register_write (struct gdbarch *gdbarch,
			      struct regcache *regcache,
			      int regnum, const gdb_byte *buffer)
{
  if (MSP430_NUM_REGS <= regnum && regnum < MSP430_NUM_TOTAL_REGS)

    {
      ULONGEST val;
      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
      int regsize = register_size (gdbarch, regnum);
      int raw_regnum = regnum - MSP430_NUM_REGS;

      val = extract_unsigned_integer (buffer, regsize, byte_order);
      regcache_raw_write_unsigned (regcache, raw_regnum, val);

    }
  else
    gdb_assert_not_reached ("invalid pseudo register number");
}

/* Implement the `register_sim_regno' gdbarch method.  */

static int
msp430_register_sim_regno (struct gdbarch *gdbarch, int regnum)
{
  gdb_assert (regnum < MSP430_NUM_REGS);

  /* So long as regnum is in [0, RL78_NUM_REGS), it's valid.  We
     just want to override the default here which disallows register
     numbers which have no names.  */
  return regnum;
}

constexpr gdb_byte msp430_break_insn[] = { 0x43, 0x43 };

typedef BP_MANIPULATION (msp430_break_insn) msp430_breakpoint;

/* Define a "handle" struct for fetching the next opcode.  */

struct msp430_get_opcode_byte_handle
{
  CORE_ADDR pc;
};

/* Fetch a byte on behalf of the opcode decoder.  HANDLE contains
   the memory address of the next byte to fetch.  If successful,
   the address in the handle is updated and the byte fetched is
   returned as the value of the function.  If not successful, -1
   is returned.  */

static int
msp430_get_opcode_byte (void *handle)
{
  struct msp430_get_opcode_byte_handle *opcdata
    = (struct msp430_get_opcode_byte_handle *) handle;
  int status;
  gdb_byte byte;

  status = target_read_memory (opcdata->pc, &byte, 1);
  if (status == 0)
    {
      opcdata->pc += 1;
      return byte;
    }
  else
    return -1;
}

/* Function for finding saved registers in a 'struct pv_area'; this
   function is passed to pv_area::scan.

   If VALUE is a saved register, ADDR says it was saved at a constant
   offset from the frame base, and SIZE indicates that the whole
   register was saved, record its offset.  */

static void
check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size, pv_t value)
{
  struct msp430_prologue *result = (struct msp430_prologue *) result_untyped;

  if (value.kind == pvk_register
      && value.k == 0
      && pv_is_register (addr, MSP430_SP_REGNUM)
      && size == register_size (target_gdbarch (), value.reg))
    result->reg_offset[value.reg] = addr.k;
}

/* Analyze a prologue starting at START_PC, going no further than
   LIMIT_PC.  Fill in RESULT as appropriate.  */

static void
msp430_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc,
			 CORE_ADDR limit_pc, struct msp430_prologue *result)
{
  CORE_ADDR pc, next_pc;
  int rn;
  pv_t reg[MSP430_NUM_TOTAL_REGS];
  CORE_ADDR after_last_frame_setup_insn = start_pc;
  msp430_gdbarch_tdep *tdep = gdbarch_tdep<msp430_gdbarch_tdep> (gdbarch);
  int code_model = tdep->code_model;
  int sz;

  memset (result, 0, sizeof (*result));

  for (rn = 0; rn < MSP430_NUM_TOTAL_REGS; rn++)
    {
      reg[rn] = pv_register (rn, 0);
      result->reg_offset[rn] = 1;
    }

  pv_area stack (MSP430_SP_REGNUM, gdbarch_addr_bit (gdbarch));

  /* The call instruction has saved the return address on the stack.  */
  sz = code_model == MSP_LARGE_CODE_MODEL ? 4 : 2;
  reg[MSP430_SP_REGNUM] = pv_add_constant (reg[MSP430_SP_REGNUM], -sz);
  stack.store (reg[MSP430_SP_REGNUM], sz, reg[MSP430_PC_REGNUM]);

  pc = start_pc;
  while (pc < limit_pc)
    {
      int bytes_read;
      struct msp430_get_opcode_byte_handle opcode_handle;
      MSP430_Opcode_Decoded opc;

      opcode_handle.pc = pc;
      bytes_read = msp430_decode_opcode (pc, &opc, msp430_get_opcode_byte,
					 &opcode_handle);
      next_pc = pc + bytes_read;

      if (opc.id == MSO_push && opc.op[0].type == MSP430_Operand_Register)
	{
	  int rsrc = opc.op[0].reg;

	  reg[MSP430_SP_REGNUM] = pv_add_constant (reg[MSP430_SP_REGNUM], -2);
	  stack.store (reg[MSP430_SP_REGNUM], 2, reg[rsrc]);
	  after_last_frame_setup_insn = next_pc;
	}
      else if (opc.id == MSO_push	/* PUSHM  */
	       && opc.op[0].type == MSP430_Operand_None
	       && opc.op[1].type == MSP430_Operand_Register)
	{
	  int rsrc = opc.op[1].reg;
	  int count = opc.repeats + 1;
	  int size = opc.size == 16 ? 2 : 4;

	  while (count > 0)
	    {
	      reg[MSP430_SP_REGNUM]
		= pv_add_constant (reg[MSP430_SP_REGNUM], -size);
	      stack.store (reg[MSP430_SP_REGNUM], size, reg[rsrc]);
	      rsrc--;
	      count--;
	    }
	  after_last_frame_setup_insn = next_pc;
	}
      else if (opc.id == MSO_sub
	       && opc.op[0].type == MSP430_Operand_Register
	       && opc.op[0].reg == MSR_SP
	       && opc.op[1].type == MSP430_Operand_Immediate)
	{
	  int addend = opc.op[1].addend;

	  reg[MSP430_SP_REGNUM] = pv_add_constant (reg[MSP430_SP_REGNUM],
						   -addend);
	  after_last_frame_setup_insn = next_pc;
	}
      else if (opc.id == MSO_mov
	       && opc.op[0].type == MSP430_Operand_Immediate
	       && 12 <= opc.op[0].reg && opc.op[0].reg <= 15)
	after_last_frame_setup_insn = next_pc;
      else
	{
	  /* Terminate the prologue scan.  */
	  break;
	}

      pc = next_pc;
    }

  /* Is the frame size (offset, really) a known constant?  */
  if (pv_is_register (reg[MSP430_SP_REGNUM], MSP430_SP_REGNUM))
    result->frame_size = reg[MSP430_SP_REGNUM].k;

  /* Record where all the registers were saved.  */
  stack.scan (check_for_saved, result);

  result->prologue_end = after_last_frame_setup_insn;
}

/* Implement the "skip_prologue" gdbarch method.  */

static CORE_ADDR
msp430_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  const char *name;
  CORE_ADDR func_addr, func_end;
  struct msp430_prologue p;

  /* Try to find the extent of the function that contains PC.  */
  if (!find_pc_partial_function (pc, &name, &func_addr, &func_end))
    return pc;

  msp430_analyze_prologue (gdbarch, pc, func_end, &p);
  return p.prologue_end;
}

/* Given a frame described by THIS_FRAME, decode the prologue of its
   associated function if there is not cache entry as specified by
   THIS_PROLOGUE_CACHE.  Save the decoded prologue in the cache and
   return that struct as the value of this function.  */

static struct msp430_prologue *
msp430_analyze_frame_prologue (frame_info_ptr this_frame,
			       void **this_prologue_cache)
{
  if (!*this_prologue_cache)
    {
      CORE_ADDR func_start, stop_addr;

      *this_prologue_cache = FRAME_OBSTACK_ZALLOC (struct msp430_prologue);

      func_start = get_frame_func (this_frame);
      stop_addr = get_frame_pc (this_frame);

      /* If we couldn't find any function containing the PC, then
	 just initialize the prologue cache, but don't do anything.  */
      if (!func_start)
	stop_addr = func_start;

      msp430_analyze_prologue (get_frame_arch (this_frame), func_start,
			       stop_addr,
			       (struct msp430_prologue *) *this_prologue_cache);
    }

  return (struct msp430_prologue *) *this_prologue_cache;
}

/* Given a frame and a prologue cache, return this frame's base.  */

static CORE_ADDR
msp430_frame_base (frame_info_ptr this_frame, void **this_prologue_cache)
{
  struct msp430_prologue *p
    = msp430_analyze_frame_prologue (this_frame, this_prologue_cache);
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, MSP430_SP_REGNUM);

  return sp - p->frame_size;
}

/* Implement the "frame_this_id" method for unwinding frames.  */

static void
msp430_this_id (frame_info_ptr this_frame,
		void **this_prologue_cache, struct frame_id *this_id)
{
  *this_id = frame_id_build (msp430_frame_base (this_frame,
						this_prologue_cache),
			     get_frame_func (this_frame));
}

/* Implement the "frame_prev_register" method for unwinding frames.  */

static struct value *
msp430_prev_register (frame_info_ptr this_frame,
		      void **this_prologue_cache, int regnum)
{
  struct msp430_prologue *p
    = msp430_analyze_frame_prologue (this_frame, this_prologue_cache);
  CORE_ADDR frame_base = msp430_frame_base (this_frame, this_prologue_cache);

  if (regnum == MSP430_SP_REGNUM)
    return frame_unwind_got_constant (this_frame, regnum, frame_base);

  /* If prologue analysis says we saved this register somewhere,
     return a description of the stack slot holding it.  */
  else if (p->reg_offset[regnum] != 1)
    {
      struct value *rv = frame_unwind_got_memory (this_frame, regnum,
						  frame_base +
						  p->reg_offset[regnum]);

      if (regnum == MSP430_PC_REGNUM)
	{
	  ULONGEST pc = value_as_long (rv);

	  return frame_unwind_got_constant (this_frame, regnum, pc);
	}
      return rv;
    }

  /* Otherwise, presume we haven't changed the value of this
     register, and get it from the next frame.  */
  else
    return frame_unwind_got_register (this_frame, regnum, regnum);
}

static const struct frame_unwind msp430_unwind = {
  "msp430 prologue",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  msp430_this_id,
  msp430_prev_register,
  NULL,
  default_frame_sniffer
};

/* Implement the "dwarf2_reg_to_regnum" gdbarch method.  */

static int
msp430_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
  if (reg >= 0 && reg < MSP430_NUM_REGS)
    return reg + MSP430_NUM_REGS;
  return -1;
}

/* Implement the "return_value" gdbarch method.  */

static enum return_value_convention
msp430_return_value (struct gdbarch *gdbarch,
		     struct value *function,
		     struct type *valtype,
		     struct regcache *regcache,
		     gdb_byte *readbuf, const gdb_byte *writebuf)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  LONGEST valtype_len = valtype->length ();
  msp430_gdbarch_tdep *tdep = gdbarch_tdep<msp430_gdbarch_tdep> (gdbarch);
  int code_model = tdep->code_model;

  if (valtype->length () > 8
      || valtype->code () == TYPE_CODE_STRUCT
      || valtype->code () == TYPE_CODE_UNION)
    return RETURN_VALUE_STRUCT_CONVENTION;

  if (readbuf)
    {
      ULONGEST u;
      int argreg = MSP430_R12_REGNUM;
      int offset = 0;

      while (valtype_len > 0)
	{
	  int size = 2;

	  if (code_model == MSP_LARGE_CODE_MODEL
	      && valtype->code () == TYPE_CODE_PTR)
	    {
	      size = 4;
	    }

	  regcache_cooked_read_unsigned (regcache, argreg, &u);
	  store_unsigned_integer (readbuf + offset, size, byte_order, u);
	  valtype_len -= size;
	  offset += size;
	  argreg++;
	}
    }

  if (writebuf)
    {
      ULONGEST u;
      int argreg = MSP430_R12_REGNUM;
      int offset = 0;

      while (valtype_len > 0)
	{
	  int size = 2;

	  if (code_model == MSP_LARGE_CODE_MODEL
	      && valtype->code () == TYPE_CODE_PTR)
	    {
	      size = 4;
	    }

	  u = extract_unsigned_integer (writebuf + offset, size, byte_order);
	  regcache_cooked_write_unsigned (regcache, argreg, u);
	  valtype_len -= size;
	  offset += size;
	  argreg++;
	}
    }

  return RETURN_VALUE_REGISTER_CONVENTION;
}


/* Implement the "frame_align" gdbarch method.  */

static CORE_ADDR
msp430_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
{
  return align_down (sp, 2);
}

/* Implement the "push_dummy_call" gdbarch method.  */

static CORE_ADDR
msp430_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
			struct regcache *regcache, CORE_ADDR bp_addr,
			int nargs, struct value **args, CORE_ADDR sp,
			function_call_return_method return_method,
			CORE_ADDR struct_addr)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int write_pass;
  int sp_off = 0;
  CORE_ADDR cfa;
  msp430_gdbarch_tdep *tdep = gdbarch_tdep<msp430_gdbarch_tdep> (gdbarch);
  int code_model = tdep->code_model;

  struct type *func_type = value_type (function);

  /* Dereference function pointer types.  */
  while (func_type->code () == TYPE_CODE_PTR)
    func_type = func_type->target_type ();

  /* The end result had better be a function or a method.  */
  gdb_assert (func_type->code () == TYPE_CODE_FUNC
	      || func_type->code () == TYPE_CODE_METHOD);

  /* We make two passes; the first does the stack allocation,
     the second actually stores the arguments.  */
  for (write_pass = 0; write_pass <= 1; write_pass++)
    {
      int i;
      int arg_reg = MSP430_R12_REGNUM;
      int args_on_stack = 0;

      if (write_pass)
	sp = align_down (sp - sp_off, 4);
      sp_off = 0;

      if (return_method == return_method_struct)
	{
	  if (write_pass)
	    regcache_cooked_write_unsigned (regcache, arg_reg, struct_addr);
	  arg_reg++;
	}

      /* Push the arguments.  */
      for (i = 0; i < nargs; i++)
	{
	  struct value *arg = args[i];
	  const gdb_byte *arg_bits = value_contents_all (arg).data ();
	  struct type *arg_type = check_typedef (value_type (arg));
	  ULONGEST arg_size = arg_type->length ();
	  int offset;
	  int current_arg_on_stack;
	  gdb_byte struct_addr_buf[4];

	  current_arg_on_stack = 0;

	  if (arg_type->code () == TYPE_CODE_STRUCT
	      || arg_type->code () == TYPE_CODE_UNION)
	    {
	      /* Aggregates of any size are passed by reference.  */
	      store_unsigned_integer (struct_addr_buf, 4, byte_order,
				      value_address (arg));
	      arg_bits = struct_addr_buf;
	      arg_size = (code_model == MSP_LARGE_CODE_MODEL) ? 4 : 2;
	    }
	  else
	    {
	      /* Scalars bigger than 8 bytes such as complex doubles are passed
		 on the stack.  */
	      if (arg_size > 8)
		current_arg_on_stack = 1;
	    }


	  for (offset = 0; offset < arg_size; offset += 2)
	    {
	      /* The condition below prevents 8 byte scalars from being split
		 between registers and memory (stack).  It also prevents other
		 splits once the stack has been written to.  */
	      if (!current_arg_on_stack
		  && (arg_reg
		      + ((arg_size == 8 || args_on_stack)
			 ? ((arg_size - offset) / 2 - 1)
			 : 0) <= MSP430_R15_REGNUM))
		{
		  int size = 2;

		  if (code_model == MSP_LARGE_CODE_MODEL
		      && (arg_type->code () == TYPE_CODE_PTR
			  || TYPE_IS_REFERENCE (arg_type)
			  || arg_type->code () == TYPE_CODE_STRUCT
			  || arg_type->code () == TYPE_CODE_UNION))
		    {
		      /* When using the large memory model, pointer,
			 reference, struct, and union arguments are
			 passed using the entire register.  (As noted
			 earlier, aggregates are always passed by
			 reference.) */
		      if (offset != 0)
			continue;
		      size = 4;
		    }

		  if (write_pass)
		    regcache_cooked_write_unsigned (regcache, arg_reg,
						    extract_unsigned_integer
						    (arg_bits + offset, size,
						     byte_order));

		  arg_reg++;
		}
	      else
		{
		  if (write_pass)
		    write_memory (sp + sp_off, arg_bits + offset, 2);

		  sp_off += 2;
		  args_on_stack = 1;
		  current_arg_on_stack = 1;
		}
	    }
	}
    }

  /* Keep track of the stack address prior to pushing the return address.
     This is the value that we'll return.  */
  cfa = sp;

  /* Push the return address.  */
  {
    int sz = tdep->code_model == MSP_SMALL_CODE_MODEL ? 2 : 4;
    sp = sp - sz;
    write_memory_unsigned_integer (sp, sz, byte_order, bp_addr);
  }

  /* Update the stack pointer.  */
  regcache_cooked_write_unsigned (regcache, MSP430_SP_REGNUM, sp);

  return cfa;
}

/* In order to keep code size small, the compiler may create epilogue
   code through which more than one function epilogue is routed.  I.e.
   the epilogue and return may just be a branch to some common piece of
   code which is responsible for tearing down the frame and performing
   the return.  These epilog (label) names will have the common prefix
   defined here.  */

static const char msp430_epilog_name_prefix[] = "__mspabi_func_epilog_";

/* Implement the "in_return_stub" gdbarch method.  */

static int
msp430_in_return_stub (struct gdbarch *gdbarch, CORE_ADDR pc,
		       const char *name)
{
  return (name != NULL
	  && startswith (name, msp430_epilog_name_prefix));
}

/* Implement the "skip_trampoline_code" gdbarch method.  */
static CORE_ADDR
msp430_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
{
  struct bound_minimal_symbol bms;
  const char *stub_name;
  struct gdbarch *gdbarch = get_frame_arch (frame);

  bms = lookup_minimal_symbol_by_pc (pc);
  if (!bms.minsym)
    return pc;

  stub_name = bms.minsym->linkage_name ();

  msp430_gdbarch_tdep *tdep = gdbarch_tdep<msp430_gdbarch_tdep> (gdbarch);
  if (tdep->code_model == MSP_SMALL_CODE_MODEL
      && msp430_in_return_stub (gdbarch, pc, stub_name))
    {
      CORE_ADDR sp = get_frame_register_unsigned (frame, MSP430_SP_REGNUM);

      return read_memory_integer
	(sp + 2 * (stub_name[strlen (msp430_epilog_name_prefix)] - '0'),
	 2, gdbarch_byte_order (gdbarch));
    }

  return pc;
}

/* Allocate and initialize a gdbarch object.  */

static struct gdbarch *
msp430_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch *gdbarch;
  int elf_flags, isa, code_model;

  /* Extract the elf_flags if available.  */
  if (info.abfd != NULL
      && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
    elf_flags = elf_elfheader (info.abfd)->e_flags;
  else
    elf_flags = 0;

  if (info.abfd != NULL)
    switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_PROC,
				      OFBA_MSPABI_Tag_ISA))
      {
      case 1:
	isa = MSP_ISA_MSP430;
	code_model = MSP_SMALL_CODE_MODEL;
	break;
      case 2:
	isa = MSP_ISA_MSP430X;
	switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_PROC,
					  OFBA_MSPABI_Tag_Code_Model))
	  {
	  case 1:
	    code_model = MSP_SMALL_CODE_MODEL;
	    break;
	  case 2:
	    code_model = MSP_LARGE_CODE_MODEL;
	    break;
	  default:
	    internal_error (_("Unknown msp430x code memory model"));
	    break;
	  }
	break;
      case 0:
	/* This can happen when loading a previously dumped data structure.
	   Use the ISA and code model from the current architecture, provided
	   it's compatible.  */
	{
	  struct gdbarch *ca = get_current_arch ();
	  if (ca && gdbarch_bfd_arch_info (ca)->arch == bfd_arch_msp430)
	    {
	      msp430_gdbarch_tdep *ca_tdep
		= gdbarch_tdep<msp430_gdbarch_tdep> (ca);

	      elf_flags = ca_tdep->elf_flags;
	      isa = ca_tdep->isa;
	      code_model = ca_tdep->code_model;
	      break;
	    }
	}
	/* Fall through.  */
      default:
	error (_("Unknown msp430 isa"));
	break;
      }
  else
    {
      isa = MSP_ISA_MSP430;
      code_model = MSP_SMALL_CODE_MODEL;
    }


  /* Try to find the architecture in the list of already defined
     architectures.  */
  for (arches = gdbarch_list_lookup_by_info (arches, &info);
       arches != NULL;
       arches = gdbarch_list_lookup_by_info (arches->next, &info))
    {
      msp430_gdbarch_tdep *candidate_tdep
	= gdbarch_tdep<msp430_gdbarch_tdep> (arches->gdbarch);

      if (candidate_tdep->elf_flags != elf_flags
	  || candidate_tdep->isa != isa
	  || candidate_tdep->code_model != code_model)
	continue;

      return arches->gdbarch;
    }

  /* None found, create a new architecture from the information
     provided.  */
  msp430_gdbarch_tdep *tdep = new msp430_gdbarch_tdep;
  gdbarch = gdbarch_alloc (&info, tdep);
  tdep->elf_flags = elf_flags;
  tdep->isa = isa;
  tdep->code_model = code_model;

  /* Registers.  */
  set_gdbarch_num_regs (gdbarch, MSP430_NUM_REGS);
  set_gdbarch_num_pseudo_regs (gdbarch, MSP430_NUM_PSEUDO_REGS);
  set_gdbarch_register_name (gdbarch, msp430_register_name);
  if (isa == MSP_ISA_MSP430)
    set_gdbarch_register_type (gdbarch, msp430_register_type);
  else
    set_gdbarch_register_type (gdbarch, msp430x_register_type);
  set_gdbarch_pc_regnum (gdbarch, MSP430_PC_REGNUM);
  set_gdbarch_sp_regnum (gdbarch, MSP430_SP_REGNUM);
  set_gdbarch_register_reggroup_p (gdbarch, msp430_register_reggroup_p);
  set_gdbarch_pseudo_register_read (gdbarch, msp430_pseudo_register_read);
  set_gdbarch_pseudo_register_write (gdbarch, msp430_pseudo_register_write);
  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, msp430_dwarf2_reg_to_regnum);
  set_gdbarch_register_sim_regno (gdbarch, msp430_register_sim_regno);

  /* Data types.  */
  set_gdbarch_char_signed (gdbarch, 0);
  set_gdbarch_short_bit (gdbarch, 16);
  set_gdbarch_int_bit (gdbarch, 16);
  set_gdbarch_long_bit (gdbarch, 32);
  set_gdbarch_long_long_bit (gdbarch, 64);
  if (code_model == MSP_SMALL_CODE_MODEL)
    {
      set_gdbarch_ptr_bit (gdbarch, 16);
      set_gdbarch_addr_bit (gdbarch, 16);
    }
  else				/* MSP_LARGE_CODE_MODEL */
    {
      set_gdbarch_ptr_bit (gdbarch, 32);
      set_gdbarch_addr_bit (gdbarch, 32);
    }
  set_gdbarch_dwarf2_addr_size (gdbarch, 4);
  set_gdbarch_float_bit (gdbarch, 32);
  set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
  set_gdbarch_double_bit (gdbarch, 64);
  set_gdbarch_long_double_bit (gdbarch, 64);
  set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
  set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);

  /* Breakpoints.  */
  set_gdbarch_breakpoint_kind_from_pc (gdbarch,
				       msp430_breakpoint::kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch,
				       msp430_breakpoint::bp_from_kind);
  set_gdbarch_decr_pc_after_break (gdbarch, 1);

  /* Frames, prologues, etc.  */
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  set_gdbarch_skip_prologue (gdbarch, msp430_skip_prologue);
  set_gdbarch_frame_align (gdbarch, msp430_frame_align);
  dwarf2_append_unwinders (gdbarch);
  frame_unwind_append_unwinder (gdbarch, &msp430_unwind);

  /* Dummy frames, return values.  */
  set_gdbarch_push_dummy_call (gdbarch, msp430_push_dummy_call);
  set_gdbarch_return_value (gdbarch, msp430_return_value);

  /* Trampolines.  */
  set_gdbarch_in_solib_return_trampoline (gdbarch, msp430_in_return_stub);
  set_gdbarch_skip_trampoline_code (gdbarch, msp430_skip_trampoline_code);

  /* Virtual tables.  */
  set_gdbarch_vbit_in_delta (gdbarch, 0);

  return gdbarch;
}

/* Register the initialization routine.  */

void _initialize_msp430_tdep ();
void
_initialize_msp430_tdep ()
{
  gdbarch_register (bfd_arch_msp430, msp430_gdbarch_init);
}
