mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-27 09:38:57 +00:00
* Makefile.in (ALLDEPFILES): Remove sparc-linux-nat.c and
sparcl-tdep.c. Add sparc-linux-tdep.c, sparc-sol2-nat.c, sparc-sol2-tdep.c, sparc-sol2-nat.c, sparc-sol2-tdep.c, sparc64-linux-nat.c, sparc64-linux-tdep.c, sparc64-nat.c, sparc64-sol2-tdep.c, sparc64-tdep.c, sparc64fbsd-nat.c, sparc64fbsd-tdep.c, sparcnbsd-nat.c, sparcnbsd-tdep.c. (sparc_nat_h): New variable. (sparcbsd_nat_h, sparcnbsd_tdep_h): Remove variables. (tm-sun4os4.h): Remove dependency. (sparcbsd-nat.o, sparc-linux-nat.o): Remove dependencies. (sparc64fbsd-nat.o, sparc64fbsd-tdep.o, sparc64nbsd-nat.o, sparc64-tdep.o, sparc-nat.o, sparcnbsd-nat.o, sparcnbsd-tdep.o, sparc-tdep.o): Update dependencies. (sparc-linux-tdep.o, sparc-sol2-nat.o, sparc-sol2-tdep.o, sparc64-linux-nat.o, sparc64-linux-tdep.o, sparc64-nat.o, sparc64-sol2-tdep.o, sparc64-tdep.o, sparc64nbsd-tdep.o): New dependencies. * configure.host: Remove existing sparc-*-lynxos*, sparc-*-solaris*, sparc-*-sunos4*, sparc-*-sunos5*, sparc-*-*, ultrasparc-*-freebsd, sparcv9-*-freebsd, sparc64-*-linux*, sparcv9-*-* and sparc64-*-* triplets. Add new sparc64-*-linux*, sparc-*-solaris2*, sparcv9-*-solaris2* and sparc64-*-solaris2* triplets. * configure.tgt: Remove exitsing sparc-*-aout*, sparc-*-coff*, sparc-*-elf*, sparc*-lynxos*, sparc-*-solars2*, sparc-*-sunos4*, sparc-*-sunos5*, sparc-*-vxworks*, sparc64-*linux*, sparc64-*-*, sparcv9-*-* and commented out sparc64-*-solars2* triplets. Add new sparc-*-solaris2.[0-6], sparc-*-solaris2.[0-6].*, sparc64-*-linux, sparc-*-solaris2*, sparcv9-*-solaris*, sparc64-*-solaris2* and sparc64-*-* triplets. * sparc64-tdep.c: Update copyright year. Include "inferior.h", "symtab.h" and "objfiles.h". (BIAS): Remove define. (X_OP, X_RD, X_A, X_COND, X_OP2, X_IMM22, X_OP3, X_I, X_DISP22) (X_DISP19): Remove macros. (sparc_fetch_instruction): Remove function. (struct gdbarch_tdep): Remove definition. (SPARC64_NUM_REGS, SPARC64_NUM_PSEUDO_REGS): Use ARRAY_SIZE. (sparc_breakpoint_from_pc): Remove function. (struct sparc64_frame_cache): Remove definition. (sparc64_alloc_frame_cache, sparc64_analyze_prologue, sparc64_unwind_pc): Remove functions. (sparc64_skip_prologue): Use `struct sparc_frame_cache' instead of `struct sparc64_frame_cache. Call sparc_analyze_prologue instead of sparc64_analyze_prologue. Mark constant as ULL instead of UL. (sparc64_frame_cache): Change return type to `struct sparc_frame_cache *'. Simply call sparc_frame_cache. (sparc64_frame_this_id, sparc64_frame_prev_register, sparc64_frame_base_address): Use `struct sparc_frame_cache' instead of `struct sparc64_frame_cache. (sparc_unwind_dummy_id, sparc_extract_struct_value_address, sparc_analyze_control_transfer, sparc_software_single_step, sparc64_gdbarch_init, sparc_supply_rwindow, sparc_fill_rwindow, _initialize_sparc64_tdep): Remove functions. (TSTATE_CWP, TSTATE_ICC, TSTATE_XCC): New macros. (PSR_S, PSR_ICC, PSR_VERS, PSR_IMPL, PSR_V8PLUS, PSR_XCC): New macros. (sparc64_supply_gregset, sparc64_collect_gregset, sparc64_supply_fpregset, sparc64_collect_fpregset): New functions. (sparc64_init_abi): New function. * sparc64-tdep.h: Update copyright year. Fix typo in multiple inclusion guard. Include "sparc-tdep.h". (BIAS): Define. (r_tstate_offset, r_fprs_offset): New defines. (enum sparc_regnum): Remove defenition. (enum sparc64_regnum): Reformat. (sparc_supply_rwindow, sparc_fill_rwindow): Remove prototypes. (sparc64_init_abi, sparc64_supply_gregset, sparc64_collect_gregset, sparc64_supply_fpregset, sparc64_collect_fpregset): New prototypes. (sparc64_sol2_gregset, sparc64nbsd_gregset, sparc64fbsd_gregset): Add extern declarations. (sparc64_sol2_init_abi): New prototype. (sparc64fbsd_supply_reg, sparc64fbsd_fill_reg) (sparc64fbsd_supply_fpreg, sparc64fbsd_fill_fpreg): Remove prototypes. * sparc64fbsd-nat.c: Include "sparc-nat.h", don't include "sparnbsd-nat.h". (sparc64fbsd_reg_supplies_p, sparc64fbsd_fpreg_supplies_p): Remove functions. (_initialize_sparc64fbsd_nat): Remove initialization of sparcbsd_supply_reg, sparcbsd_fill_reg, sparcbsd_supply_fpreg, sparcbsd_fill_fpreg, sparcbsd_reg_supplies_p, sparcbsd_fpreg_supplies_p. Initialize sparc_gregset. * sparc64fbsd-tdep.c: Update copyright year. Include "frame.h", "frame-unwind.h", "trad-frame.h" and "gdb_assert.h". (sparc64fbsd_r_global_offset, sparc64fbsd_r_out_offset) (sparc64fbsd_r_fprs_offset, sparc64fbsd_r_tnpc_offset) (sparc64fbsd_r_tpc_offset, sparc64fbsd_r_tstate_offset) (sparc64fbsd_r_y_offset): Remove variables. (sparc64fbsd_sizeof_struct_reg, sparc64fbsd_sizeof_struct_fpreg): Make static and const. (sparc64fbsd_supply_reg, sparc64fbsd_fill_reg) (sparc64fbsd_supply_fpreg, sparc64fbsd_fill_fpreg): Remove functions. (sparc64fbsd_gregset): New variable. (fetch_core_registers): Replace calls to sparc64fbsd_supply_reg and sparc64fbsd_supply_fpreg with calls to sparc64_supply_gregset and sparc64_supply_fpregset. (sparc64fbsd_pc_in_sigtramp, sparc64fbsd_sigtramp_frame_cache) (sparc64fbsd_sigtramp_frame_this_id) (sparc64fbsd_sigtramp_frame_prev_register): New functions. (sparc64fbsd_sigtramp_frame_unwind): New variable. (sparc64fbsd_sigtramp_frame_sniffer): New function. (sparc64fbsd_init_abi): Set pc_in_sigtramp, append sparc64fbsd_sigtramp_frame_sniffer. Call sparc64_init_abi. * sparcnbsd-tdep.c: Update copyright year. Include "floatformat.h", "frame.h", "frame-unwind.h", "symtab.h", "trad-frame.h" and "gdb_assert.h", don't include "target.h", "value.h" and "sparcnbsd-tdep.h". (REG32_OFFSET_PSR, REG32_OFFSET_PC, REG32_OFFSET_NPC) (REG32_OFFSET_Y, REG32_OFFSET_GLOBAL, REG32_OFFSET_OUT) (REG64_OFFSET_TSTATE, REG64_OFFSET_PC, REG64_OFFSET_NPC) (REG64_OFFSET_Y, REG64_OFFSET_GLOBAL, REG64_OFFSET_OUT): Remove defines. (sparcnbsd_gregset): New variable. (sparcnbsd_supply_reg32, sparcnbsd_supply_reg64) (sparcnbsd_fill_reg32, sparcnbsd_fill_reg64) (sparcnbsd_supply_fpreg32, sparcnbsd_supply_fpreg64) (sparcnbsd_fill_reg32, sparcnbsd_fill_reg64): Remove functions. (sparc32nbsd_sigtramp_start, sparc32nbsd_sigtramp_end): New variables. (sparc32nbsd_pc_in_sigtramp, sparc32nbsd_sigcontext_frame_cache) (sparc32nbsd_sigcontext_frame_this_id) (sparc32nbsd_sigcontext_frame_prev_register): New functions. (sparc32nbsd_sigcontext_frame_unwind): New variable. (sparc32nbsd_sigtramp_frame_sniffer): New function. (sparcnbsd_get_longjmp_target_32, sparcnbsd_get_longjmp_target_64): Remove functions. (sparcnbsd_aout_in_solib_call_trampoline): Rewrite. (sparcnbsd_init_abi_common, sparcnbsd_init_aout, sparcnbsd_init_elf): Remove. (sparcnbsd_init_abi, sparcnbsd_aout_init_abi) (sparcnbsd_elf_init_abi): New functions. (_initialize_sparcnbsd_tdep): New prototype. (_initialize_sparnbsd_tdep): Update. * config/sparc/fbsd.mh (NATDEPFILES): Remove sparcbsd-nat.o and corelow.o. Add sparc64-nat.o and sparc-nat.o. * config/sparc/fbsd.mt (TDEPFILES): Add sparc-tdep.o and corelow.o. * config/sparc/linux.mh: Update comment. (XM_FILE, HOST_IPC): Remove variables. (NATDEPFILES): Add sparc-sol2-nat.o and core-regset.o. Remove sparc-linux-nat.o. * config/sparc/linux.mt: Update comment. (TDEPFILES): Add sparc-sol2-tdep.o and sparc-linux-tdep.o. * config/sparc/nbsd.mt: Reformat. * config/sparc/nbsd64.mh: Update comment. (NATDEPFILES): Add sparc-nat.o. * config/sparc/nbsd64.mt: Update comment. (TDEPFILES): Add sparc64-tdep.o and sparc64nbsd-tdep.o. (TM_FILE): Set to tm-nbsd.h. * config/sparc/nbsdelf.mh: Update comment. (NATDEPFILES): Add sparc-nat.o. (XM_FILE): Delete. * config/sparc/nbsdaout.mh: Update comment. (NATDEPFILES): Add sparc-nat.o (XM_FILE): Delete. * config/sparc/nm-linux.h: Update copyright year. Don't include "config/nm-svr4.h" and "solib.h". Add protection against multiple inclusion. (KERNEL_U_SIZE): Remove define. (kernel_u_size): Remove prototype. (PTRACE_ARG3_TYPE, PTRACE_XFER_TYPE): Define. * config/sparc/nm-nbsd.h: Update copyright. Don't include "regcache.h". (CHILD_PREPARE_TO_STORE): Remove define. * config/sparc/nm-nbsdaout.h: Tweak some comments. * sparc-nat.c, sparc-tdep.c, sparc-tdep.h, sparc64nbsd-nat.c, sparcnbsd-nat.c: Rewrite files. * config/sparc/tm-linux.h, config/sparc/tm-nbsd.h: Rewrite files. * sparc-linux-nat.c, sparcbsd-nat.c, sparcbsd-nat.h, sparcnbsd-tdep.h: Remove files. * config/sparc/nm-sparclynx.h, config/sparc/nm-sun4os4.h, config/sparc/nm-sun4sol2.h, config/sparc/sp64.mt, config/sparc/sp64linux.mt, config/sparc/sp64sol2.mt, config/sparc/sparc-em.mt, config/sparc/sparclynx.mh, config/sparc/sparclynx.mt, config/sparc/sun4os4.mh, config/sparc/sun4os4.mt, config/sparc/sun4sol2.mh, config/sparc/sun4sol2.mt, config/sparc/tm-sp64.h, config/sparc/tm-sp64linux.h, config/sparc/tm-sparc.h, config/sparc/tm-sparclynx.h, config/sparc/tm-spc-em.h, config/sparc/tm-sun4os4.h, config/sparc/tm-sun4sol2.h, config/sparc/tm-vxsparc.h, config/sparc/vxsparc.mt, config/sparc/xm-linux.h, config/sparc/xm-sun4sol2.h: Remove files. * sparc-linux-tdep.c, sparc-nat.h, sparc-sol2-nat.c, sparc-sol2-tdep.c, sparc64-linux-nat.c, sparc64-linux-t dep.c, sparc64-nat.c, sparc64-sol2-tdep.c, sparc64nbsd-tdep.c: New files. * config/sparc/linux64.mh, config/sparc/linux64.mt, config/sparc/nm-sol2.h, config/sparc/sol2-64.mt, config/sparc/sol2.mh, config/sparc/sol2.mt, config/sparc/sparc.mt, config/sparc/sparc64.mt, config/sparc/tm-sol2.h: New files.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/* Target-dependent code for UltraSPARC.
|
||||
|
||||
Copyright 2003 Free Software Foundation, Inc.
|
||||
Copyright 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
#include "frame-unwind.h"
|
||||
#include "gdbcore.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "inferior.h"
|
||||
#include "symtab.h"
|
||||
#include "objfiles.h"
|
||||
#include "osabi.h"
|
||||
#include "regcache.h"
|
||||
#include "target.h"
|
||||
@@ -45,41 +48,6 @@
|
||||
/* Please use the sparc32_-prefix for 32-bit specific code, the
|
||||
sparc64_-prefix for 64-bit specific code and the sparc_-prefix for
|
||||
code can handle both. */
|
||||
|
||||
/* The stack pointer is offset from the stack frame by a BIAS of 2047
|
||||
(0x7ff) for 64-bit code. BIAS is likely to be defined on SPARC
|
||||
hosts, so undefine it first. */
|
||||
#undef BIAS
|
||||
#define BIAS 2047
|
||||
|
||||
/* Macros to extract fields from SPARC instructions. */
|
||||
#define X_OP(i) (((i) >> 30) & 0x3)
|
||||
#define X_A(i) (((i) >> 29) & 1)
|
||||
#define X_COND(i) (((i) >> 25) & 0xf)
|
||||
#define X_OP2(i) (((i) >> 22) & 0x7)
|
||||
#define X_IMM22(i) ((i) & 0x3fffff)
|
||||
#define X_OP3(i) (((i) >> 19) & 0x3f)
|
||||
/* Sign extension macros. */
|
||||
#define X_DISP22(i) ((X_IMM22 (i) ^ 0x200000) - 0x200000)
|
||||
#define X_DISP19(i) ((((i) & 0x7ffff) ^ 0x40000) - 0x40000)
|
||||
|
||||
/* Fetch the instruction at PC. Instructions are always big-endian
|
||||
even if the processor operates in little-endian mode. */
|
||||
|
||||
static unsigned long
|
||||
sparc_fetch_instruction (CORE_ADDR pc)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
unsigned long insn;
|
||||
int i;
|
||||
|
||||
read_memory (pc, buf, sizeof (buf));
|
||||
|
||||
insn = 0;
|
||||
for (i = 0; i < sizeof (buf); i++)
|
||||
insn = (insn << 8) | buf[i];
|
||||
return insn;
|
||||
}
|
||||
|
||||
/* The functions on this page are intended to be used to classify
|
||||
function arguments. */
|
||||
@@ -163,14 +131,6 @@ sparc64_structure_or_union_p (const struct type *type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* UltraSPARC architecture specific information. */
|
||||
|
||||
struct gdbarch_tdep
|
||||
{
|
||||
/* Offset of saved PC in jmp_buf. */
|
||||
int jb_pc_offset;
|
||||
};
|
||||
|
||||
/* Register information. */
|
||||
|
||||
struct sparc64_register_info
|
||||
@@ -283,8 +243,7 @@ static struct sparc64_register_info sparc64_register_info[] =
|
||||
};
|
||||
|
||||
/* Total number of registers. */
|
||||
#define SPARC64_NUM_REGS \
|
||||
(sizeof (sparc64_register_info) / sizeof (sparc64_register_info[0]))
|
||||
#define SPARC64_NUM_REGS ARRAY_SIZE (sparc64_register_info)
|
||||
|
||||
/* We provide the aliases %d0..%d62 and %q0..%q60 for the floating
|
||||
registers as "psuedo" registers. */
|
||||
@@ -348,9 +307,7 @@ static struct sparc64_register_info sparc64_pseudo_register_info[] =
|
||||
};
|
||||
|
||||
/* Total number of pseudo registers. */
|
||||
#define SPARC64_NUM_PSEUDO_REGS \
|
||||
(sizeof (sparc64_pseudo_register_info) \
|
||||
/ sizeof (sparc64_pseudo_register_info[0]))
|
||||
#define SPARC64_NUM_PSEUDO_REGS ARRAY_SIZE (sparc64_pseudo_register_info)
|
||||
|
||||
/* Return the name of register REGNUM. */
|
||||
|
||||
@@ -499,79 +456,8 @@ sparc64_pseudo_register_write (struct gdbarch *gdbarch,
|
||||
regcache_raw_write_unsigned (regcache, SPARC64_STATE_REGNUM, state);
|
||||
}
|
||||
}
|
||||
|
||||
/* Use the program counter to determine the contents and size of a
|
||||
breakpoint instruction. Return a pointer to a string of bytes that
|
||||
encode a breakpoint instruction, store the length of the string in
|
||||
*LEN and optionally adjust *PC to point to the correct memory
|
||||
location for inserting the breakpoint. */
|
||||
|
||||
static const unsigned char *
|
||||
sparc_breakpoint_from_pc (CORE_ADDR *pc, int *len)
|
||||
{
|
||||
static unsigned char break_insn[] = { 0x91, 0xd0, 0x20, 0x01 };
|
||||
|
||||
*len = sizeof (break_insn);
|
||||
return break_insn;
|
||||
}
|
||||
|
||||
|
||||
struct sparc64_frame_cache
|
||||
{
|
||||
/* Base address. */
|
||||
CORE_ADDR base;
|
||||
CORE_ADDR pc;
|
||||
|
||||
/* Do we have a frame? */
|
||||
int frameless_p;
|
||||
};
|
||||
|
||||
/* Allocate and initialize a frame cache. */
|
||||
|
||||
static struct sparc64_frame_cache *
|
||||
sparc64_alloc_frame_cache (void)
|
||||
{
|
||||
struct sparc64_frame_cache *cache;
|
||||
int i;
|
||||
|
||||
cache = FRAME_OBSTACK_ZALLOC (struct sparc64_frame_cache);
|
||||
|
||||
/* Base address. */
|
||||
cache->base = 0;
|
||||
cache->pc = 0;
|
||||
|
||||
/* Frameless until proven otherwise. */
|
||||
cache->frameless_p = 1;
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
sparc64_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
|
||||
struct sparc64_frame_cache *cache)
|
||||
{
|
||||
unsigned long insn;
|
||||
|
||||
if (current_pc <= pc)
|
||||
return current_pc;
|
||||
|
||||
/* Check whether the function starts with a SAVE instruction. */
|
||||
insn = sparc_fetch_instruction (pc);
|
||||
if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3c)
|
||||
{
|
||||
cache->frameless_p = 0;
|
||||
return pc + 4;
|
||||
}
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
sparc64_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
|
||||
{
|
||||
return frame_unwind_register_unsigned (next_frame, SPARC64_PC_REGNUM);
|
||||
}
|
||||
|
||||
/* Return PC of first real instruction of the function starting at
|
||||
START_PC. */
|
||||
|
||||
@@ -580,7 +466,7 @@ sparc64_skip_prologue (CORE_ADDR start_pc)
|
||||
{
|
||||
struct symtab_and_line sal;
|
||||
CORE_ADDR func_start, func_end;
|
||||
struct sparc64_frame_cache cache;
|
||||
struct sparc_frame_cache cache;
|
||||
|
||||
/* This is the preferred method, find the end of the prologue by
|
||||
using the debugging information. */
|
||||
@@ -593,50 +479,22 @@ sparc64_skip_prologue (CORE_ADDR start_pc)
|
||||
return sal.end;
|
||||
}
|
||||
|
||||
return sparc64_analyze_prologue (start_pc, 0xffffffffffffffffUL, &cache);
|
||||
return sparc_analyze_prologue (start_pc, 0xffffffffffffffffULL, &cache);
|
||||
}
|
||||
|
||||
/* Normal frames. */
|
||||
|
||||
static struct sparc64_frame_cache *
|
||||
static struct sparc_frame_cache *
|
||||
sparc64_frame_cache (struct frame_info *next_frame, void **this_cache)
|
||||
{
|
||||
struct sparc64_frame_cache *cache;
|
||||
|
||||
if (*this_cache)
|
||||
return *this_cache;
|
||||
|
||||
cache = sparc64_alloc_frame_cache ();
|
||||
*this_cache = cache;
|
||||
|
||||
/* In priciple, for normal frames, %fp (%i6) holds the frame
|
||||
pointer, which holds the base address for the current stack
|
||||
frame. */
|
||||
|
||||
cache->base = frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM);
|
||||
if (cache->base == 0)
|
||||
return cache;
|
||||
|
||||
cache->pc = frame_func_unwind (next_frame);
|
||||
if (cache->pc != 0)
|
||||
sparc64_analyze_prologue (cache->pc, frame_pc_unwind (next_frame), cache);
|
||||
|
||||
if (cache->frameless_p)
|
||||
{
|
||||
/* We didn't find a valid frame, which means that CACHE->base
|
||||
currently holds the frame pointer for our calling frame. */
|
||||
cache->base = frame_unwind_register_unsigned (next_frame,
|
||||
SPARC_SP_REGNUM);
|
||||
}
|
||||
|
||||
return cache;
|
||||
return sparc_frame_cache (next_frame, this_cache);
|
||||
}
|
||||
|
||||
static void
|
||||
sparc64_frame_this_id (struct frame_info *next_frame, void **this_cache,
|
||||
struct frame_id *this_id)
|
||||
{
|
||||
struct sparc64_frame_cache *cache =
|
||||
struct sparc_frame_cache *cache =
|
||||
sparc64_frame_cache (next_frame, this_cache);
|
||||
|
||||
/* This marks the outermost frame. */
|
||||
@@ -652,7 +510,7 @@ sparc64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
|
||||
enum lval_type *lvalp, CORE_ADDR *addrp,
|
||||
int *realnump, void *valuep)
|
||||
{
|
||||
struct sparc64_frame_cache *cache =
|
||||
struct sparc_frame_cache *cache =
|
||||
sparc64_frame_cache (next_frame, this_cache);
|
||||
|
||||
if (regnum == SPARC64_PC_REGNUM || regnum == SPARC64_NPC_REGNUM)
|
||||
@@ -718,7 +576,7 @@ sparc64_frame_sniffer (struct frame_info *next_frame)
|
||||
static CORE_ADDR
|
||||
sparc64_frame_base_address (struct frame_info *next_frame, void **this_cache)
|
||||
{
|
||||
struct sparc64_frame_cache *cache =
|
||||
struct sparc_frame_cache *cache =
|
||||
sparc64_frame_cache (next_frame, this_cache);
|
||||
|
||||
/* ??? Should we take BIAS into account here? */
|
||||
@@ -732,15 +590,6 @@ static const struct frame_base sparc64_frame_base =
|
||||
sparc64_frame_base_address,
|
||||
sparc64_frame_base_address
|
||||
};
|
||||
|
||||
static struct frame_id
|
||||
sparc_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
|
||||
{
|
||||
CORE_ADDR sp;
|
||||
|
||||
sp = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM);
|
||||
return frame_id_build (sp, frame_pc_unwind (next_frame));
|
||||
}
|
||||
|
||||
/* Check whether TYPE must be 16-byte aligned. */
|
||||
|
||||
@@ -1193,19 +1042,6 @@ sparc64_store_return_value (struct type *type, struct regcache *regcache,
|
||||
}
|
||||
}
|
||||
|
||||
/* Extract from REGCACHE, which contains the (raw) register state, the
|
||||
address in which a function should return its structure value, as a
|
||||
CORE_ADDR. */
|
||||
|
||||
static CORE_ADDR
|
||||
sparc_extract_struct_value_address (struct regcache *regcache)
|
||||
{
|
||||
ULONGEST addr;
|
||||
|
||||
regcache_cooked_read_unsigned (regcache, SPARC_O0_REGNUM, &addr);
|
||||
return addr;
|
||||
}
|
||||
|
||||
static int
|
||||
sparc64_use_struct_convention (int gcc_p, struct type *type)
|
||||
{
|
||||
@@ -1213,138 +1049,20 @@ sparc64_use_struct_convention (int gcc_p, struct type *type)
|
||||
registers. */
|
||||
return (TYPE_LENGTH (type) > 32);
|
||||
}
|
||||
|
||||
|
||||
/* The SPARC Architecture doesn't have hardware single-step support,
|
||||
and most operating systems don't implement it either, so we provide
|
||||
software single-step mechanism. */
|
||||
|
||||
static CORE_ADDR
|
||||
sparc_analyze_control_transfer (CORE_ADDR pc, CORE_ADDR *npc)
|
||||
{
|
||||
unsigned long insn = sparc_fetch_instruction (pc);
|
||||
int conditional_p = X_COND (insn) & 0x7;
|
||||
int branch_p = 0;
|
||||
long offset = 0; /* Must be signed for sign-extend. */
|
||||
|
||||
if (X_OP (insn) == 0 && X_OP2 (insn) == 3 && (insn & 0x1000000) == 0)
|
||||
{
|
||||
/* Branch on Integer Register with Prediction (BPr). */
|
||||
branch_p = 1;
|
||||
conditional_p = 1;
|
||||
}
|
||||
else if (X_OP (insn) == 0 && X_OP2 (insn) == 6)
|
||||
{
|
||||
/* Branch on Floating-Point Condition Codes (FBfcc). */
|
||||
branch_p = 1;
|
||||
offset = 4 * X_DISP22 (insn);
|
||||
}
|
||||
else if (X_OP (insn) == 0 && X_OP2 (insn) == 5)
|
||||
{
|
||||
/* Branch on Floating-Point Condition Codes with Prediction
|
||||
(FBPfcc). */
|
||||
branch_p = 1;
|
||||
offset = 4 * X_DISP19 (insn);
|
||||
}
|
||||
else if (X_OP (insn) == 0 && X_OP2 (insn) == 2)
|
||||
{
|
||||
/* Branch on Integer Condition Codes (Bicc). */
|
||||
branch_p = 1;
|
||||
offset = 4 * X_DISP22 (insn);
|
||||
}
|
||||
else if (X_OP (insn) == 0 && X_OP2 (insn) == 1)
|
||||
{
|
||||
/* Branch on Integer Condition Codes with Prediction (BPcc). */
|
||||
branch_p = 1;
|
||||
offset = 4 * X_DISP19 (insn);
|
||||
}
|
||||
|
||||
/* FIXME: Handle DONE and RETRY instructions. */
|
||||
|
||||
/* FIXME: Handle the Trap instruction. */
|
||||
|
||||
if (branch_p)
|
||||
{
|
||||
if (conditional_p)
|
||||
{
|
||||
/* For conditional branches, return nPC + 4 iff the annul
|
||||
bit is 1. */
|
||||
return (X_A (insn) ? *npc + 4 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For unconditional branches, return the target if its
|
||||
specified condition is "always" and return nPC + 4 if the
|
||||
condition is "never". If the annul bit is 1, set *NPC to
|
||||
zero. */
|
||||
if (X_COND (insn) == 0x0)
|
||||
pc = *npc, offset = 4;
|
||||
if (X_A (insn))
|
||||
*npc = 0;
|
||||
|
||||
gdb_assert (offset != 0);
|
||||
return pc + offset;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
|
||||
sparc64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
static CORE_ADDR npc, nnpc;
|
||||
static char npc_save[4], nnpc_save[4];
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
if (insert_breakpoints_p)
|
||||
{
|
||||
CORE_ADDR pc;
|
||||
|
||||
pc = sparc_address_from_register (SPARC64_PC_REGNUM);
|
||||
npc = sparc_address_from_register (SPARC64_NPC_REGNUM);
|
||||
|
||||
/* Analyze the instruction at PC. */
|
||||
nnpc = sparc_analyze_control_transfer (pc, &npc);
|
||||
if (npc != 0)
|
||||
target_insert_breakpoint (npc, npc_save);
|
||||
if (nnpc != 0)
|
||||
target_insert_breakpoint (nnpc, nnpc_save);
|
||||
|
||||
/* Assert that we have set at least one breakpoint. */
|
||||
gdb_assert (npc != 0 || nnpc != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (npc != 0)
|
||||
target_remove_breakpoint (npc, npc_save);
|
||||
if (nnpc != 0)
|
||||
target_remove_breakpoint (nnpc, nnpc_save);
|
||||
|
||||
npc = 0;
|
||||
nnpc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static struct gdbarch *
|
||||
sparc64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
{
|
||||
struct gdbarch_tdep *tdep;
|
||||
struct gdbarch *gdbarch;
|
||||
|
||||
/* If there is already a candidate, use it. */
|
||||
arches = gdbarch_list_lookup_by_info (arches, &info);
|
||||
if (arches != NULL)
|
||||
return arches->gdbarch;
|
||||
|
||||
/* Allocate space for the new architecture. */
|
||||
tdep = XMALLOC (struct gdbarch_tdep);
|
||||
gdbarch = gdbarch_alloc (&info, tdep);
|
||||
tdep->pc_regnum = SPARC64_PC_REGNUM;
|
||||
tdep->npc_regnum = SPARC64_NPC_REGNUM;
|
||||
|
||||
/* This is what all the fuss is about. */
|
||||
set_gdbarch_long_bit (gdbarch, 64);
|
||||
set_gdbarch_long_long_bit (gdbarch, 64);
|
||||
set_gdbarch_ptr_bit (gdbarch, 64);
|
||||
set_gdbarch_long_double_bit (gdbarch, 128);
|
||||
|
||||
set_gdbarch_num_regs (gdbarch, SPARC64_NUM_REGS);
|
||||
set_gdbarch_register_name (gdbarch, sparc64_register_name);
|
||||
@@ -1354,147 +1072,329 @@ sparc64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
set_gdbarch_pseudo_register_write (gdbarch, sparc64_pseudo_register_write);
|
||||
|
||||
/* Register numbers of various important registers. */
|
||||
set_gdbarch_sp_regnum (gdbarch, SPARC_SP_REGNUM); /* %sp */
|
||||
set_gdbarch_pc_regnum (gdbarch, SPARC64_PC_REGNUM); /* %pc */
|
||||
set_gdbarch_deprecated_npc_regnum (gdbarch, SPARC64_NPC_REGNUM);
|
||||
set_gdbarch_fp0_regnum (gdbarch, SPARC_F0_REGNUM); /* %f0 */
|
||||
|
||||
/* Call dummy code. */
|
||||
set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
|
||||
set_gdbarch_push_dummy_code (gdbarch, NULL);
|
||||
set_gdbarch_push_dummy_call (gdbarch, sparc64_push_dummy_call);
|
||||
|
||||
set_gdbarch_extract_return_value (gdbarch, sparc64_extract_return_value);
|
||||
set_gdbarch_store_return_value (gdbarch, sparc64_store_return_value);
|
||||
set_gdbarch_extract_struct_value_address
|
||||
(gdbarch, sparc_extract_struct_value_address);
|
||||
set_gdbarch_use_struct_convention (gdbarch, sparc64_use_struct_convention);
|
||||
set_gdbarch_return_value_on_stack
|
||||
(gdbarch, generic_return_value_on_stack_not);
|
||||
set_gdbarch_stabs_argument_has_addr
|
||||
(gdbarch, default_stabs_argument_has_addr);
|
||||
|
||||
set_gdbarch_skip_prologue (gdbarch, sparc64_skip_prologue);
|
||||
|
||||
/* Stack grows downward. */
|
||||
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
|
||||
|
||||
set_gdbarch_breakpoint_from_pc (gdbarch, sparc_breakpoint_from_pc);
|
||||
set_gdbarch_decr_pc_after_break (gdbarch, 0);
|
||||
set_gdbarch_function_start_offset (gdbarch, 0);
|
||||
|
||||
set_gdbarch_frame_args_skip (gdbarch, 8);
|
||||
|
||||
set_gdbarch_print_insn (gdbarch, print_insn_sparc);
|
||||
|
||||
set_gdbarch_software_single_step (gdbarch, sparc_software_single_step);
|
||||
|
||||
set_gdbarch_unwind_dummy_id (gdbarch, sparc_unwind_dummy_id);
|
||||
|
||||
set_gdbarch_unwind_pc (gdbarch, sparc64_unwind_pc);
|
||||
|
||||
frame_base_set_default (gdbarch, &sparc64_frame_base);
|
||||
|
||||
/* Hook in ABI-specific overrides, if they have been registered. */
|
||||
gdbarch_init_osabi (info, gdbarch);
|
||||
|
||||
frame_unwind_append_sniffer (gdbarch, sparc64_frame_sniffer);
|
||||
|
||||
return gdbarch;
|
||||
frame_base_set_default (gdbarch, &sparc64_frame_base);
|
||||
}
|
||||
|
||||
/* Helper functions for dealing with register windows. */
|
||||
|
||||
/* Helper functions for dealing with register sets. */
|
||||
|
||||
#define TSTATE_CWP 0x000000000000001fULL
|
||||
#define TSTATE_ICC 0x0000000f00000000ULL
|
||||
#define TSTATE_XCC 0x000000f000000000ULL
|
||||
|
||||
#define PSR_S 0x00000080
|
||||
#define PSR_ICC 0x00f00000
|
||||
#define PSR_VERS 0x0f000000
|
||||
#define PSR_IMPL 0xf0000000
|
||||
#define PSR_V8PLUS 0xff000000
|
||||
#define PSR_XCC 0x000f0000
|
||||
|
||||
void
|
||||
sparc_supply_rwindow (CORE_ADDR sp, int regnum)
|
||||
sparc64_supply_gregset (const struct sparc_gregset *gregset,
|
||||
struct regcache *regcache,
|
||||
int regnum, const void *gregs)
|
||||
{
|
||||
int offset = 0;
|
||||
char buf[8];
|
||||
int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32);
|
||||
const char *regs = gregs;
|
||||
int i;
|
||||
|
||||
if (sp & 1)
|
||||
if (sparc32)
|
||||
{
|
||||
/* Registers are 64-bit. */
|
||||
sp += BIAS;
|
||||
|
||||
for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
|
||||
if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
|
||||
{
|
||||
if (regnum == i || regnum == -1)
|
||||
{
|
||||
target_read_memory (sp + ((i - SPARC_L0_REGNUM) * 8), buf, 8);
|
||||
supply_register (i, buf);
|
||||
}
|
||||
int offset = gregset->r_tstate_offset;
|
||||
ULONGEST tstate, psr;
|
||||
char buf[4];
|
||||
|
||||
tstate = extract_unsigned_integer (regs + offset, 8);
|
||||
psr = ((tstate & TSTATE_CWP) | PSR_S | ((tstate & TSTATE_ICC) >> 12)
|
||||
| ((tstate & TSTATE_XCC) >> 20) | PSR_V8PLUS);
|
||||
store_unsigned_integer (buf, 4, psr);
|
||||
regcache_raw_supply (regcache, SPARC32_PSR_REGNUM, buf);
|
||||
}
|
||||
|
||||
if (regnum == SPARC32_PC_REGNUM || regnum == -1)
|
||||
regcache_raw_supply (regcache, SPARC32_PC_REGNUM,
|
||||
regs + gregset->r_pc_offset + 4);
|
||||
|
||||
if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
|
||||
regcache_raw_supply (regcache, SPARC32_NPC_REGNUM,
|
||||
regs + gregset->r_npc_offset + 4);
|
||||
|
||||
if (regnum == SPARC32_Y_REGNUM || regnum == -1)
|
||||
{
|
||||
int offset = gregset->r_y_offset + 8 - gregset->r_y_size;
|
||||
regcache_raw_supply (regcache, SPARC32_Y_REGNUM, regs + offset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Registers are 32-bit. Toss any sign-extension of the stack
|
||||
pointer. */
|
||||
sp &= 0xffffffffUL;
|
||||
if (regnum == SPARC64_STATE_REGNUM || regnum == -1)
|
||||
regcache_raw_supply (regcache, SPARC64_STATE_REGNUM,
|
||||
regs + gregset->r_tstate_offset);
|
||||
|
||||
/* Clear out the top half of the temporary buffer, and put the
|
||||
register value in the bottom half if we're in 64-bit mode. */
|
||||
if (gdbarch_ptr_bit (current_gdbarch) == 64)
|
||||
if (regnum == SPARC64_PC_REGNUM || regnum == -1)
|
||||
regcache_raw_supply (regcache, SPARC64_PC_REGNUM,
|
||||
regs + gregset->r_pc_offset);
|
||||
|
||||
if (regnum == SPARC64_NPC_REGNUM || regnum == -1)
|
||||
regcache_raw_supply (regcache, SPARC64_NPC_REGNUM,
|
||||
regs + gregset->r_npc_offset);
|
||||
|
||||
if (regnum == SPARC64_Y_REGNUM || regnum == -1)
|
||||
{
|
||||
memset (buf, 0, 4);
|
||||
offset = 4;
|
||||
char buf[8];
|
||||
|
||||
memset (buf, 0, 8);
|
||||
memcpy (buf + 8 - gregset->r_y_size,
|
||||
regs + gregset->r_y_offset, gregset->r_y_size);
|
||||
regcache_raw_supply (regcache, SPARC64_Y_REGNUM, buf);
|
||||
}
|
||||
|
||||
for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
|
||||
if ((regnum == SPARC64_FPRS_REGNUM || regnum == -1)
|
||||
&& gregset->r_fprs_offset != -1)
|
||||
regcache_raw_supply (regcache, SPARC64_FPRS_REGNUM,
|
||||
regs + gregset->r_fprs_offset);
|
||||
}
|
||||
|
||||
if (regnum == SPARC_G0_REGNUM || regnum == -1)
|
||||
regcache_raw_supply (regcache, SPARC_G0_REGNUM, NULL);
|
||||
|
||||
if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
|
||||
{
|
||||
int offset = gregset->r_g1_offset;
|
||||
|
||||
if (sparc32)
|
||||
offset += 4;
|
||||
|
||||
for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
|
||||
{
|
||||
if (regnum == i || regnum == -1)
|
||||
regcache_raw_supply (regcache, i, regs + offset);
|
||||
offset += 8;
|
||||
}
|
||||
}
|
||||
|
||||
if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1)
|
||||
{
|
||||
/* Not all of the register set variants include Locals and
|
||||
Inputs. For those that don't, we read them off the stack. */
|
||||
if (gregset->r_l0_offset == -1)
|
||||
{
|
||||
ULONGEST sp;
|
||||
|
||||
regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
|
||||
sparc_supply_rwindow (regcache, sp, regnum);
|
||||
}
|
||||
else
|
||||
{
|
||||
int offset = gregset->r_l0_offset;
|
||||
|
||||
if (sparc32)
|
||||
offset += 4;
|
||||
|
||||
for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
|
||||
{
|
||||
target_read_memory (sp + ((i - SPARC_L0_REGNUM) * 4),
|
||||
buf + offset, 4);
|
||||
supply_register (i, buf);
|
||||
if (regnum == i || regnum == -1)
|
||||
regcache_raw_supply (regcache, i, regs + offset);
|
||||
offset += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sparc_fill_rwindow (CORE_ADDR sp, int regnum)
|
||||
sparc64_collect_gregset (const struct sparc_gregset *gregset,
|
||||
const struct regcache *regcache,
|
||||
int regnum, void *gregs)
|
||||
{
|
||||
int offset = 0;
|
||||
char buf[8];
|
||||
int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32);
|
||||
char *regs = gregs;
|
||||
int i;
|
||||
|
||||
if (sp & 1)
|
||||
if (sparc32)
|
||||
{
|
||||
/* Registers are 64-bit. */
|
||||
sp += BIAS;
|
||||
|
||||
for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
|
||||
if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
|
||||
{
|
||||
if (regnum == -1 || regnum == SPARC_SP_REGNUM || regnum == i)
|
||||
{
|
||||
regcache_collect (i, buf);
|
||||
target_write_memory (sp + ((i - SPARC_L0_REGNUM) * 8), buf, 8);
|
||||
}
|
||||
int offset = gregset->r_tstate_offset;
|
||||
ULONGEST tstate, psr;
|
||||
char buf[8];
|
||||
|
||||
tstate = extract_unsigned_integer (regs + offset, 8);
|
||||
regcache_raw_collect (regcache, SPARC32_PSR_REGNUM, buf);
|
||||
psr = extract_unsigned_integer (buf, 4);
|
||||
tstate |= (psr & PSR_ICC) << 12;
|
||||
if ((psr & (PSR_VERS | PSR_IMPL)) == PSR_V8PLUS)
|
||||
tstate |= (psr & PSR_XCC) << 20;
|
||||
store_unsigned_integer (buf, 8, tstate);
|
||||
memcpy (regs + offset, buf, 8);
|
||||
}
|
||||
|
||||
if (regnum == SPARC32_PC_REGNUM || regnum == -1)
|
||||
regcache_raw_collect (regcache, SPARC32_PC_REGNUM,
|
||||
regs + gregset->r_pc_offset + 4);
|
||||
|
||||
if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
|
||||
regcache_raw_collect (regcache, SPARC32_NPC_REGNUM,
|
||||
regs + gregset->r_npc_offset + 4);
|
||||
|
||||
if (regnum == SPARC32_Y_REGNUM || regnum == -1)
|
||||
{
|
||||
int offset = gregset->r_y_offset + 8 - gregset->r_y_size;
|
||||
regcache_raw_collect (regcache, SPARC32_Y_REGNUM, regs + offset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Registers are 32-bit. Toss any sign-extension of the stack
|
||||
pointer. */
|
||||
sp &= 0xffffffffUL;
|
||||
if (regnum == SPARC64_STATE_REGNUM || regnum == -1)
|
||||
regcache_raw_collect (regcache, SPARC64_STATE_REGNUM,
|
||||
regs + gregset->r_tstate_offset);
|
||||
|
||||
/* Only use the bottom half if we're in 64-bit mode. */
|
||||
if (gdbarch_ptr_bit (current_gdbarch) == 64)
|
||||
offset = 4;
|
||||
if (regnum == SPARC64_PC_REGNUM || regnum == -1)
|
||||
regcache_raw_collect (regcache, SPARC64_PC_REGNUM,
|
||||
regs + gregset->r_pc_offset);
|
||||
|
||||
for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
|
||||
if (regnum == SPARC64_NPC_REGNUM || regnum == -1)
|
||||
regcache_raw_collect (regcache, SPARC64_NPC_REGNUM,
|
||||
regs + gregset->r_npc_offset);
|
||||
|
||||
if (regnum == SPARC64_Y_REGNUM || regnum == -1)
|
||||
{
|
||||
if (regnum == -1 || regnum == SPARC_SP_REGNUM || regnum == i)
|
||||
char buf[8];
|
||||
|
||||
regcache_raw_collect (regcache, SPARC64_Y_REGNUM, buf);
|
||||
memcpy (regs + gregset->r_y_offset,
|
||||
buf + 8 - gregset->r_y_size, gregset->r_y_size);
|
||||
}
|
||||
|
||||
if ((regnum == SPARC64_FPRS_REGNUM || regnum == -1)
|
||||
&& gregset->r_fprs_offset != -1)
|
||||
regcache_raw_collect (regcache, SPARC64_FPRS_REGNUM,
|
||||
regs + gregset->r_fprs_offset);
|
||||
|
||||
}
|
||||
|
||||
if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
|
||||
{
|
||||
int offset = gregset->r_g1_offset;
|
||||
|
||||
if (sparc32)
|
||||
offset += 4;
|
||||
|
||||
/* %g0 is always zero. */
|
||||
for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
|
||||
{
|
||||
if (regnum == i || regnum == -1)
|
||||
regcache_raw_collect (regcache, i, regs + offset);
|
||||
offset += 8;
|
||||
}
|
||||
}
|
||||
|
||||
if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1)
|
||||
{
|
||||
/* Not all of the register set variants include Locals and
|
||||
Inputs. For those that don't, we read them off the stack. */
|
||||
if (gregset->r_l0_offset != -1)
|
||||
{
|
||||
int offset = gregset->r_l0_offset;
|
||||
|
||||
if (sparc32)
|
||||
offset += 4;
|
||||
|
||||
for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
|
||||
{
|
||||
regcache_collect (i, buf);
|
||||
target_write_memory (sp + ((i - SPARC_L0_REGNUM) * 4),
|
||||
buf + offset, 4);
|
||||
if (regnum == i || regnum == -1)
|
||||
regcache_raw_collect (regcache, i, regs + offset);
|
||||
offset += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
void _initialize_sparc64_tdep (void);
|
||||
|
||||
void
|
||||
_initialize_sparc64_tdep (void)
|
||||
sparc64_supply_fpregset (struct regcache *regcache,
|
||||
int regnum, const void *fpregs)
|
||||
{
|
||||
register_gdbarch_init (bfd_arch_sparc, sparc64_gdbarch_init);
|
||||
int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32);
|
||||
const char *regs = fpregs;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1)
|
||||
regcache_raw_supply (regcache, SPARC_F0_REGNUM + i, regs + (i * 4));
|
||||
}
|
||||
|
||||
if (sparc32)
|
||||
{
|
||||
if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
|
||||
regcache_raw_supply (regcache, SPARC32_FSR_REGNUM,
|
||||
regs + (32 * 4) + (16 * 8) + 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (regnum == (SPARC64_F32_REGNUM + i) || regnum == -1)
|
||||
regcache_raw_supply (regcache, SPARC64_F32_REGNUM + i,
|
||||
regs + (32 * 4) + (i * 8));
|
||||
}
|
||||
|
||||
if (regnum == SPARC64_FSR_REGNUM || regnum == -1)
|
||||
regcache_raw_supply (regcache, SPARC64_FSR_REGNUM,
|
||||
regs + (32 * 4) + (16 * 8));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sparc64_collect_fpregset (const struct regcache *regcache,
|
||||
int regnum, void *fpregs)
|
||||
{
|
||||
int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32);
|
||||
char *regs = fpregs;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1)
|
||||
regcache_raw_collect (regcache, SPARC_F0_REGNUM + i, regs + (i * 4));
|
||||
}
|
||||
|
||||
if (sparc32)
|
||||
{
|
||||
if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
|
||||
regcache_raw_collect (regcache, SPARC32_FSR_REGNUM,
|
||||
regs + (32 * 4) + (16 * 8) + 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (regnum == (SPARC64_F32_REGNUM + i) || regnum == -1)
|
||||
regcache_raw_collect (regcache, SPARC64_F32_REGNUM + i,
|
||||
regs + (32 * 4) + (i * 8));
|
||||
}
|
||||
|
||||
if (regnum == SPARC64_FSR_REGNUM || regnum == -1)
|
||||
regcache_raw_collect (regcache, SPARC64_FSR_REGNUM,
|
||||
regs + (32 * 4) + (16 * 8));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user