/* Builtin frame register, for GDB, the GNU debugger.

   Copyright (C) 2002, 2005, 2007, 2008, 2009, 2010
   Free Software Foundation, Inc.

   Contributed by Red Hat.

   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 "user-regs.h"
#include "frame.h"
#include "gdbtypes.h"
#include "value.h"
#include "gdb_string.h"


static struct value *
value_of_builtin_frame_fp_reg (struct frame_info *frame, const void *baton)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  if (gdbarch_deprecated_fp_regnum (gdbarch) >= 0)
    /* NOTE: cagney/2003-04-24: Since the mere presence of "fp" in the
       register name table overrides this built-in $fp register, there
       is no real reason for this gdbarch_deprecated_fp_regnum trickery here.
       An architecture wanting to implement "$fp" as alias for a raw
       register can do so by adding "fp" to register name table (mind
       you, doing this is probably a dangerous thing).  */
    return value_of_register (gdbarch_deprecated_fp_regnum (gdbarch),
			      frame);
  else
    {
      struct type *data_ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
      struct value *val = allocate_value (data_ptr_type);
      gdb_byte *buf = value_contents_raw (val);
      if (frame == NULL)
	memset (buf, 0, TYPE_LENGTH (value_type (val)));
      else
	gdbarch_address_to_pointer (gdbarch, data_ptr_type,
				    buf, get_frame_base_address (frame));
      return val;
    }
}

static struct value *
value_of_builtin_frame_pc_reg (struct frame_info *frame, const void *baton)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  if (gdbarch_pc_regnum (gdbarch) >= 0)
    return value_of_register (gdbarch_pc_regnum (gdbarch), frame);
  else
    {
      struct type *func_ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
      struct value *val = allocate_value (func_ptr_type);
      gdb_byte *buf = value_contents_raw (val);
      if (frame == NULL)
	memset (buf, 0, TYPE_LENGTH (value_type (val)));
      else
	gdbarch_address_to_pointer (gdbarch, func_ptr_type,
				    buf, get_frame_pc (frame));
      return val;
    }
}

static struct value *
value_of_builtin_frame_sp_reg (struct frame_info *frame, const void *baton)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  if (gdbarch_sp_regnum (gdbarch) >= 0)
    return value_of_register (gdbarch_sp_regnum (gdbarch), frame);
  error (_("Standard register ``$sp'' is not available for this target"));
}

static struct value *
value_of_builtin_frame_ps_reg (struct frame_info *frame, const void *baton)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  if (gdbarch_ps_regnum (gdbarch) >= 0)
    return value_of_register (gdbarch_ps_regnum (gdbarch), frame);
  error (_("Standard register ``$ps'' is not available for this target"));
}

extern initialize_file_ftype _initialize_frame_reg; /* -Wmissing-prototypes */

void
_initialize_frame_reg (void)
{
  /* Frame based $fp, $pc, $sp and $ps.  These only come into play
     when the target does not define its own version of these
     registers.  */
  user_reg_add_builtin ("fp", value_of_builtin_frame_fp_reg, NULL);
  user_reg_add_builtin ("pc", value_of_builtin_frame_pc_reg, NULL);
  user_reg_add_builtin ("sp", value_of_builtin_frame_sp_reg, NULL);
  user_reg_add_builtin ("ps", value_of_builtin_frame_ps_reg, NULL);
}
