gdb/sparc-tdep.c - gdb
Global variables defined
Functions defined
Macros defined
Source code
- #include "defs.h"
- #include "arch-utils.h"
- #include "dis-asm.h"
- #include "dwarf2-frame.h"
- #include "floatformat.h"
- #include "frame.h"
- #include "frame-base.h"
- #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"
- #include "value.h"
- #include "sparc-tdep.h"
- #include "sparc-ravenscar-thread.h"
- struct regset;
- #define floatformats_sparc_quad floatformats_ia64_quad
- #undef BIAS
- #define BIAS 2047
- #define X_OP(i) (((i) >> 30) & 0x3)
- #define X_RD(i) (((i) >> 25) & 0x1f)
- #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)
- #define X_RS1(i) (((i) >> 14) & 0x1f)
- #define X_RS2(i) ((i) & 0x1f)
- #define X_I(i) (((i) >> 13) & 1)
- #define X_DISP22(i) ((X_IMM22 (i) ^ 0x200000) - 0x200000)
- #define X_DISP19(i) ((((i) & 0x7ffff) ^ 0x40000) - 0x40000)
- #define X_DISP10(i) ((((((i) >> 11) && 0x300) | (((i) >> 5) & 0xff)) ^ 0x200) - 0x200)
- #define X_SIMM13(i) ((((i) & 0x1fff) ^ 0x1000) - 0x1000)
- #define X_RETTURN(i) ((X_OP (i) == 0x2) && (X_OP3 (i) == 0x39))
- unsigned long
- sparc_fetch_instruction (CORE_ADDR pc)
- {
- gdb_byte buf[4];
- unsigned long insn;
- int i;
-
- if (target_read_memory (pc, buf, sizeof (buf)))
- return 0;
- insn = 0;
- for (i = 0; i < sizeof (buf); i++)
- insn = (insn << 8) | buf[i];
- return insn;
- }
- static int
- sparc_is_unimp_insn (CORE_ADDR pc)
- {
- const unsigned long insn = sparc_fetch_instruction (pc);
- return ((insn & 0xc1c00000) == 0);
- }
- int
- sparc_is_annulled_branch_insn (CORE_ADDR pc)
- {
-
- const unsigned long insn = sparc_fetch_instruction (pc);
- const unsigned op2 = X_OP2 (insn);
- if ((X_OP (insn) == 0)
- && ((op2 == 1) || (op2 == 2) || (op2 == 5) || (op2 == 6)
- || ((op2 == 3) && ((insn & 0x10000000) == 0))))
- return X_A (insn);
- else
- return 0;
- }
- ULONGEST
- sparc_fetch_wcookie (struct gdbarch *gdbarch)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct target_ops *ops = ¤t_target;
- gdb_byte buf[8];
- int len;
- len = target_read (ops, TARGET_OBJECT_WCOOKIE, NULL, buf, 0, 8);
- if (len == -1)
- return 0;
-
- gdb_assert (len == 4 || len == 8);
- return extract_unsigned_integer (buf, len, byte_order);
- }
- static int
- sparc_integral_or_pointer_p (const struct type *type)
- {
- int len = TYPE_LENGTH (type);
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_INT:
- case TYPE_CODE_BOOL:
- case TYPE_CODE_CHAR:
- case TYPE_CODE_ENUM:
- case TYPE_CODE_RANGE:
-
- return (len == 1 || len == 2 || len == 4 || len == 8);
- case TYPE_CODE_PTR:
- case TYPE_CODE_REF:
-
- return (len == 4 || len == 8);
- default:
- break;
- }
- return 0;
- }
- static int
- sparc_floating_p (const struct type *type)
- {
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_FLT:
- {
- int len = TYPE_LENGTH (type);
- return (len == 4 || len == 8 || len == 16);
- }
- default:
- break;
- }
- return 0;
- }
- static int
- sparc_complex_floating_p (const struct type *type)
- {
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_COMPLEX:
- {
- int len = TYPE_LENGTH (type);
- return (len == 8 || len == 16 || len == 32);
- }
- default:
- break;
- }
- return 0;
- }
- static int
- sparc_structure_or_union_p (const struct type *type)
- {
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_STRUCT:
- case TYPE_CODE_UNION:
- case TYPE_CODE_ARRAY:
- return 1;
- default:
- break;
- }
- return 0;
- }
- static const char *sparc32_register_names[] =
- {
- "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
- "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
- "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
- "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
- "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr"
- };
- #define SPARC32_NUM_REGS ARRAY_SIZE (sparc32_register_names)
- static const char *sparc32_pseudo_register_names[] =
- {
- "d0", "d2", "d4", "d6", "d8", "d10", "d12", "d14",
- "d16", "d18", "d20", "d22", "d24", "d26", "d28", "d30"
- };
- #define SPARC32_NUM_PSEUDO_REGS ARRAY_SIZE (sparc32_pseudo_register_names)
- static const char *
- sparc32_register_name (struct gdbarch *gdbarch, int regnum)
- {
- if (regnum >= 0 && regnum < SPARC32_NUM_REGS)
- return sparc32_register_names[regnum];
- if (regnum < SPARC32_NUM_REGS + SPARC32_NUM_PSEUDO_REGS)
- return sparc32_pseudo_register_names[regnum - SPARC32_NUM_REGS];
- return NULL;
- }
- static struct type *
- sparc_psr_type (struct gdbarch *gdbarch)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (!tdep->sparc_psr_type)
- {
- struct type *type;
- type = arch_flags_type (gdbarch, "builtin_type_sparc_psr", 4);
- append_flags_type_flag (type, 5, "ET");
- append_flags_type_flag (type, 6, "PS");
- append_flags_type_flag (type, 7, "S");
- append_flags_type_flag (type, 12, "EF");
- append_flags_type_flag (type, 13, "EC");
- tdep->sparc_psr_type = type;
- }
- return tdep->sparc_psr_type;
- }
- static struct type *
- sparc_fsr_type (struct gdbarch *gdbarch)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (!tdep->sparc_fsr_type)
- {
- struct type *type;
- type = arch_flags_type (gdbarch, "builtin_type_sparc_fsr", 4);
- append_flags_type_flag (type, 0, "NXA");
- append_flags_type_flag (type, 1, "DZA");
- append_flags_type_flag (type, 2, "UFA");
- append_flags_type_flag (type, 3, "OFA");
- append_flags_type_flag (type, 4, "NVA");
- append_flags_type_flag (type, 5, "NXC");
- append_flags_type_flag (type, 6, "DZC");
- append_flags_type_flag (type, 7, "UFC");
- append_flags_type_flag (type, 8, "OFC");
- append_flags_type_flag (type, 9, "NVC");
- append_flags_type_flag (type, 22, "NS");
- append_flags_type_flag (type, 23, "NXM");
- append_flags_type_flag (type, 24, "DZM");
- append_flags_type_flag (type, 25, "UFM");
- append_flags_type_flag (type, 26, "OFM");
- append_flags_type_flag (type, 27, "NVM");
- tdep->sparc_fsr_type = type;
- }
- return tdep->sparc_fsr_type;
- }
- static struct type *
- sparc32_register_type (struct gdbarch *gdbarch, int regnum)
- {
- if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
- return builtin_type (gdbarch)->builtin_float;
- if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM)
- return builtin_type (gdbarch)->builtin_double;
- if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM)
- return builtin_type (gdbarch)->builtin_data_ptr;
- if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM)
- return builtin_type (gdbarch)->builtin_func_ptr;
- if (regnum == SPARC32_PSR_REGNUM)
- return sparc_psr_type (gdbarch);
- if (regnum == SPARC32_FSR_REGNUM)
- return sparc_fsr_type (gdbarch);
- return builtin_type (gdbarch)->builtin_int32;
- }
- static enum register_status
- sparc32_pseudo_register_read (struct gdbarch *gdbarch,
- struct regcache *regcache,
- int regnum, gdb_byte *buf)
- {
- enum register_status status;
- gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM);
- regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM);
- status = regcache_raw_read (regcache, regnum, buf);
- if (status == REG_VALID)
- status = regcache_raw_read (regcache, regnum + 1, buf + 4);
- return status;
- }
- static void
- sparc32_pseudo_register_write (struct gdbarch *gdbarch,
- struct regcache *regcache,
- int regnum, const gdb_byte *buf)
- {
- gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM);
- regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM);
- regcache_raw_write (regcache, regnum, buf);
- regcache_raw_write (regcache, regnum + 1, buf + 4);
- }
- int
- sparc_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
- {
-
- unsigned int insn = sparc_fetch_instruction (pc - 4);
- return X_RETTURN (insn);
- }
- static CORE_ADDR
- sparc32_frame_align (struct gdbarch *gdbarch, CORE_ADDR address)
- {
-
- return address & ~0x7;
- }
- static CORE_ADDR
- sparc32_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
- CORE_ADDR funcaddr,
- struct value **args, int nargs,
- struct type *value_type,
- CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
- struct regcache *regcache)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- *bp_addr = sp - 4;
- *real_pc = funcaddr;
- if (using_struct_return (gdbarch, NULL, value_type))
- {
- gdb_byte buf[4];
-
- store_unsigned_integer (buf, 4, byte_order,
- TYPE_LENGTH (value_type) & 0x1fff);
- write_memory (sp - 8, buf, 4);
- return sp - 8;
- }
- return sp - 4;
- }
- static CORE_ADDR
- sparc32_store_arguments (struct regcache *regcache, int nargs,
- struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-
- int num_elements = 0;
- int element = 0;
- int i;
- for (i = 0; i < nargs; i++)
- {
- struct type *type = value_type (args[i]);
- int len = TYPE_LENGTH (type);
- if (sparc_structure_or_union_p (type)
- || (sparc_floating_p (type) && len == 16)
- || sparc_complex_floating_p (type))
- {
-
- sp -= len;
-
- sp &= ~0x7;
- write_memory (sp, value_contents (args[i]), len);
- args[i] = value_from_pointer (lookup_pointer_type (type), sp);
- num_elements++;
- }
- else if (sparc_floating_p (type))
- {
-
- gdb_assert (len == 4 || len == 8);
- num_elements += (len / 4);
- }
- else
- {
-
- gdb_assert (sparc_integral_or_pointer_p (type));
- if (len < 4)
- args[i] = value_cast (builtin_type (gdbarch)->builtin_int32,
- args[i]);
- num_elements += ((len + 3) / 4);
- }
- }
-
- sp -= max (6, num_elements) * 4;
-
- sp -= 4;
-
- sp &= ~0x7;
- for (i = 0; i < nargs; i++)
- {
- const bfd_byte *valbuf = value_contents (args[i]);
- struct type *type = value_type (args[i]);
- int len = TYPE_LENGTH (type);
- gdb_assert (len == 4 || len == 8);
- if (element < 6)
- {
- int regnum = SPARC_O0_REGNUM + element;
- regcache_cooked_write (regcache, regnum, valbuf);
- if (len > 4 && element < 5)
- regcache_cooked_write (regcache, regnum + 1, valbuf + 4);
- }
-
- write_memory (sp + 4 + element * 4, valbuf, len);
- element += len / 4;
- }
- gdb_assert (element == num_elements);
- if (struct_return)
- {
- gdb_byte buf[4];
- store_unsigned_integer (buf, 4, byte_order, struct_addr);
- write_memory (sp, buf, 4);
- }
- return sp;
- }
- static CORE_ADDR
- sparc32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
- struct regcache *regcache, CORE_ADDR bp_addr,
- int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
- {
- CORE_ADDR call_pc = (struct_return ? (bp_addr - 12) : (bp_addr - 8));
-
- regcache_cooked_write_unsigned (regcache, SPARC_O7_REGNUM, call_pc);
-
- sp = sparc32_store_arguments (regcache, nargs, args, sp,
- struct_return, struct_addr);
-
- sp -= 16 * 4;
-
- gdb_assert (sp % 8 == 0);
-
- regcache_cooked_write_unsigned (regcache, SPARC_SP_REGNUM, sp);
- return sp;
- }
- static const gdb_byte *
- sparc_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len)
- {
- static const gdb_byte break_insn[] = { 0x91, 0xd0, 0x20, 0x01 };
- *len = sizeof (break_insn);
- return break_insn;
- }
- static struct sparc_frame_cache *
- sparc_alloc_frame_cache (void)
- {
- struct sparc_frame_cache *cache;
- cache = FRAME_OBSTACK_ZALLOC (struct sparc_frame_cache);
-
- cache->base = 0;
- cache->pc = 0;
-
- cache->frameless_p = 1;
- cache->frame_offset = 0;
- cache->saved_regs_mask = 0;
- cache->copied_regs_mask = 0;
- cache->struct_return_p = 0;
- return cache;
- }
- static CORE_ADDR
- sparc_skip_stack_check (const CORE_ADDR start_pc)
- {
- CORE_ADDR pc = start_pc;
- unsigned long insn;
- int offset_stack_checking_sequence = 0;
- int probing_loop = 0;
-
-
- insn = sparc_fetch_instruction (pc);
- pc = pc + 4;
- if (!(X_OP (insn) == 0 && X_OP2 (insn) == 0x4 && X_RD (insn) == 1))
- return start_pc;
-
- insn = sparc_fetch_instruction (pc);
- pc = pc + 4;
- if (X_OP (insn) == 0 && X_OP2 (insn) == 0x4 && X_RD (insn) == 4)
- {
- probing_loop = 1;
- insn = sparc_fetch_instruction (pc);
- pc = pc + 4;
- }
-
- if (!(X_OP (insn) == 2 && X_OP3 (insn) == 0x4 && !X_I(insn)
- && X_RD (insn) == 1 && X_RS1 (insn) == 14 && X_RS2 (insn) == 1))
- return start_pc;
- insn = sparc_fetch_instruction (pc);
- pc = pc + 4;
-
- if (X_OP (insn) == 0 && X_OP2 (insn) == 0x4 && X_RD (insn) == 4)
- {
- probing_loop = 1;
- insn = sparc_fetch_instruction (pc);
- pc = pc + 4;
- }
-
-
- if (X_OP (insn) == 3 && X_OP3(insn) == 0x4 && X_I(insn)
- && X_RS1 (insn) == 1 && X_RD (insn) == 0)
- {
-
- return pc;
- }
-
-
- else if (X_OP (insn) == 3 && X_OP3(insn) == 0x4 && !X_I(insn)
- && X_RS1 (insn) == 1 && X_RD (insn) == 0)
- {
- while (1)
- {
-
- insn = sparc_fetch_instruction (pc);
- pc = pc + 4;
- if (!(X_OP (insn) == 2 && X_OP3(insn) == 0 && X_I(insn)
- && X_RS1 (insn) == 1 && X_RD (insn) == 1))
- break;
-
- insn = sparc_fetch_instruction (pc);
- pc = pc + 4;
- if (!(X_OP (insn) == 3 && X_OP3(insn) == 0x4 && !X_I(insn)
- && X_RD (insn) == 0 && X_RS1 (insn) == 1))
- return start_pc;
- }
-
- if (!(X_OP (insn) == 3 && X_OP3(insn) == 0x4 && X_I(insn)
- && X_RS1 (insn) == 1 && X_RD (insn) == 0))
- return start_pc;
-
- return pc;
- }
-
- if (probing_loop)
- {
-
- if (!(X_OP (insn) == 2 && X_OP3 (insn) == 0x4 && !X_I(insn)
- && X_RD (insn) == 4 && X_RS1 (insn) == 1 && X_RS2 (insn) == 4))
- return start_pc;
-
- insn = sparc_fetch_instruction (pc);
- pc = pc + 4;
- if (!(X_OP (insn) == 2 && X_OP3 (insn) == 0x14 && !X_I(insn)
- && X_RD (insn) == 0 && X_RS1 (insn) == 1 && X_RS2 (insn) == 4))
- return start_pc;
-
- insn = sparc_fetch_instruction (pc);
- pc = pc + 4;
- if (!(X_OP (insn) == 0 && X_COND (insn) == 0x1))
- return start_pc;
-
- insn = sparc_fetch_instruction (pc);
- pc = pc + 4;
- if (!(X_OP (insn) == 2 && X_OP3(insn) == 0 && X_I(insn)
- && X_RS1 (insn) == 1 && X_RD (insn) == 1))
- return start_pc;
-
- insn = sparc_fetch_instruction (pc);
- pc = pc + 4;
- if (!(X_OP (insn) == 0 && X_COND (insn) == 0x8))
- return start_pc;
-
- insn = sparc_fetch_instruction (pc);
- pc = pc + 4;
- if (!(X_OP (insn) == 3 && X_OP3(insn) == 0x4
- && X_RD (insn) == 0 && X_RS1 (insn) == 1
- && (!X_I(insn) || X_SIMM13 (insn) == 0)))
- return start_pc;
-
-
- insn = sparc_fetch_instruction (pc);
- pc = pc + 4;
- if (!(X_OP (insn) == 3 && X_OP3(insn) == 0x4 && X_I(insn)
- && X_RS1 (insn) == 4 && X_RD (insn) == 0))
- return pc - 4;
- else
- return pc;
- }
-
- return start_pc;
- }
- void
- sparc_record_save_insn (struct sparc_frame_cache *cache)
- {
-
- cache->frameless_p = 0;
-
- cache->frame_offset = 0;
-
- cache->saved_regs_mask = 0xffff;
-
- cache->copied_regs_mask = 0xff;
- }
- CORE_ADDR
- sparc_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
- CORE_ADDR current_pc, struct sparc_frame_cache *cache)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- unsigned long insn;
- int offset = 0;
- int dest = -1;
- pc = sparc_skip_stack_check (pc);
- if (current_pc <= pc)
- return current_pc;
-
- if (tdep->plt_entry_size > 0 && in_plt_section (current_pc))
- pc = current_pc - ((current_pc - pc) % tdep->plt_entry_size);
- insn = sparc_fetch_instruction (pc);
-
- while (X_OP (insn) == 3
- && (X_OP3 (insn) == 0x4
- || X_OP3 (insn) == 0x7
- || X_OP3 (insn) == 0xe)
- && X_RS1 (insn) == SPARC_SP_REGNUM)
- {
- int regnum = X_RD (insn);
-
- if (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM
- && ((X_I (insn)
- && X_SIMM13 (insn) == (X_OP3 (insn) == 0xe
- ? (regnum - SPARC_L0_REGNUM) * 8 + BIAS
- : (regnum - SPARC_L0_REGNUM) * 4))
- || (!X_I (insn) && regnum == SPARC_L0_REGNUM)))
- {
- cache->saved_regs_mask |= (1 << (regnum - SPARC_L0_REGNUM));
- if (X_OP3 (insn) == 0x7)
- cache->saved_regs_mask |= (1 << (regnum + 1 - SPARC_L0_REGNUM));
- }
- offset += 4;
- insn = sparc_fetch_instruction (pc + offset);
- }
-
- if (X_OP (insn) == 0 && X_OP2 (insn) == 0x04)
- {
- dest = X_RD (insn);
- offset += 4;
- insn = sparc_fetch_instruction (pc + offset);
- }
-
- if (X_OP (insn) == 2 && X_I (insn)
- && (X_RD (insn) == 1 || X_RD (insn) == dest))
- {
- offset += 4;
- insn = sparc_fetch_instruction (pc + offset);
- }
-
- if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3c)
- {
- sparc_record_save_insn (cache);
- offset += 4;
- return pc + offset;
- }
-
- if (X_OP (insn) == 2
- && (X_OP3 (insn) == 0 || X_OP3 (insn) == 0x4)
- && X_RS1 (insn) == SPARC_SP_REGNUM
- && X_RD (insn) == SPARC_SP_REGNUM)
- {
- if (X_I (insn))
- {
- cache->frame_offset = X_SIMM13 (insn);
- if (X_OP3 (insn) == 0)
- cache->frame_offset = -cache->frame_offset;
- }
- offset += 4;
- insn = sparc_fetch_instruction (pc + offset);
-
- if (X_OP (insn) == 2
- && (X_OP3 (insn) == 0 || X_OP3 (insn) == 0x4)
- && X_RS1 (insn) == SPARC_SP_REGNUM
- && X_RD (insn) == SPARC_FP_REGNUM)
- {
- cache->frameless_p = 0;
- cache->frame_offset = 0;
-
- cache->copied_regs_mask |= 0x40;
- offset += 4;
- insn = sparc_fetch_instruction (pc + offset);
- }
-
- if (X_OP (insn) == 2
- && X_OP3 (insn) == 0x2
- && !X_I (insn)
- && X_RS1 (insn) == SPARC_G0_REGNUM
- && X_RS2 (insn) == SPARC_O7_REGNUM
- && X_RD (insn) == SPARC_I7_REGNUM)
- {
- cache->copied_regs_mask |= 0x80;
- offset += 4;
- }
- return pc + offset;
- }
- return pc;
- }
- static CORE_ADDR
- sparc_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- return frame_unwind_register_unsigned (this_frame, tdep->pc_regnum);
- }
- static CORE_ADDR
- sparc32_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
- {
- struct symtab_and_line sal;
- CORE_ADDR func_start, func_end;
- struct sparc_frame_cache cache;
-
- if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end))
- {
- sal = find_pc_line (func_start, 0);
- if (sal.end < func_end
- && start_pc <= sal.end)
- return sal.end;
- }
- start_pc = sparc_analyze_prologue (gdbarch, start_pc, 0xffffffffUL, &cache);
-
- while (1)
- {
- unsigned long insn = sparc_fetch_instruction (start_pc);
-
- if (X_OP (insn) == 3 && (X_OP3 (insn) & 0x3c) == 0x04
- && X_I (insn) && X_RS1 (insn) == SPARC_FP_REGNUM)
- {
- int regnum = X_RD (insn);
-
- if (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O5_REGNUM
- && !(cache.copied_regs_mask & (1 << (regnum - SPARC_O0_REGNUM)))
- && X_SIMM13 (insn) == 68 + (regnum - SPARC_O0_REGNUM) * 4)
- {
- start_pc += 4;
- continue;
- }
-
- if (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I5_REGNUM
- && (cache.copied_regs_mask & (1 << (regnum - SPARC_I0_REGNUM)))
- && X_SIMM13 (insn) == 68 + (regnum - SPARC_I0_REGNUM) * 4)
- {
- start_pc += 4;
- continue;
- }
- }
- break;
- }
- return start_pc;
- }
- struct sparc_frame_cache *
- sparc_frame_cache (struct frame_info *this_frame, void **this_cache)
- {
- struct sparc_frame_cache *cache;
- if (*this_cache)
- return *this_cache;
- cache = sparc_alloc_frame_cache ();
- *this_cache = cache;
- cache->pc = get_frame_func (this_frame);
- if (cache->pc != 0)
- sparc_analyze_prologue (get_frame_arch (this_frame), cache->pc,
- get_frame_pc (this_frame), cache);
- if (cache->frameless_p)
- {
-
- cache->base =
- get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
- }
- else
- {
-
- cache->base =
- get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
- }
- cache->base += cache->frame_offset;
- if (cache->base & 1)
- cache->base += BIAS;
- return cache;
- }
- static int
- sparc32_struct_return_from_sym (struct symbol *sym)
- {
- struct type *type = check_typedef (SYMBOL_TYPE (sym));
- enum type_code code = TYPE_CODE (type);
- if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD)
- {
- type = check_typedef (TYPE_TARGET_TYPE (type));
- if (sparc_structure_or_union_p (type)
- || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16))
- return 1;
- }
- return 0;
- }
- struct sparc_frame_cache *
- sparc32_frame_cache (struct frame_info *this_frame, void **this_cache)
- {
- struct sparc_frame_cache *cache;
- struct symbol *sym;
- if (*this_cache)
- return *this_cache;
- cache = sparc_frame_cache (this_frame, this_cache);
- sym = find_pc_function (cache->pc);
- if (sym)
- {
- cache->struct_return_p = sparc32_struct_return_from_sym (sym);
- }
- else
- {
-
- CORE_ADDR pc;
- int regnum =
- (cache->copied_regs_mask & 0x80) ? SPARC_I7_REGNUM : SPARC_O7_REGNUM;
- pc = get_frame_register_unsigned (this_frame, regnum) + 8;
- if (sparc_is_unimp_insn (pc))
- cache->struct_return_p = 1;
- }
- return cache;
- }
- static void
- sparc32_frame_this_id (struct frame_info *this_frame, void **this_cache,
- struct frame_id *this_id)
- {
- struct sparc_frame_cache *cache =
- sparc32_frame_cache (this_frame, this_cache);
-
- if (cache->base == 0)
- return;
- (*this_id) = frame_id_build (cache->base, cache->pc);
- }
- static struct value *
- sparc32_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct sparc_frame_cache *cache =
- sparc32_frame_cache (this_frame, this_cache);
- if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM)
- {
- CORE_ADDR pc = (regnum == SPARC32_NPC_REGNUM) ? 4 : 0;
-
- if (cache->struct_return_p)
- pc += 4;
- regnum =
- (cache->copied_regs_mask & 0x80) ? SPARC_I7_REGNUM : SPARC_O7_REGNUM;
- pc += get_frame_register_unsigned (this_frame, regnum) + 8;
- return frame_unwind_got_constant (this_frame, regnum, pc);
- }
-
- {
- ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
- if (wcookie != 0 && !cache->frameless_p && regnum == SPARC_I7_REGNUM)
- {
- CORE_ADDR addr = cache->base + (regnum - SPARC_L0_REGNUM) * 4;
- ULONGEST i7;
-
- i7 = get_frame_memory_unsigned (this_frame, addr, 4);
- return frame_unwind_got_constant (this_frame, regnum, i7 ^ wcookie);
- }
- }
-
- if (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM
- && (cache->saved_regs_mask & (1 << (regnum - SPARC_L0_REGNUM))))
- {
- CORE_ADDR addr = cache->base + (regnum - SPARC_L0_REGNUM) * 4;
- return frame_unwind_got_memory (this_frame, regnum, addr);
- }
-
- if (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM
- && (cache->copied_regs_mask & (1 << (regnum - SPARC_O0_REGNUM))))
- regnum += (SPARC_I0_REGNUM - SPARC_O0_REGNUM);
- return frame_unwind_got_register (this_frame, regnum, regnum);
- }
- static const struct frame_unwind sparc32_frame_unwind =
- {
- NORMAL_FRAME,
- default_frame_unwind_stop_reason,
- sparc32_frame_this_id,
- sparc32_frame_prev_register,
- NULL,
- default_frame_sniffer
- };
- static CORE_ADDR
- sparc32_frame_base_address (struct frame_info *this_frame, void **this_cache)
- {
- struct sparc_frame_cache *cache =
- sparc32_frame_cache (this_frame, this_cache);
- return cache->base;
- }
- static const struct frame_base sparc32_frame_base =
- {
- &sparc32_frame_unwind,
- sparc32_frame_base_address,
- sparc32_frame_base_address,
- sparc32_frame_base_address
- };
- static struct frame_id
- sparc_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
- {
- CORE_ADDR sp;
- sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
- if (sp & 1)
- sp += BIAS;
- return frame_id_build (sp, get_frame_pc (this_frame));
- }
- static void
- sparc32_extract_return_value (struct type *type, struct regcache *regcache,
- gdb_byte *valbuf)
- {
- int len = TYPE_LENGTH (type);
- gdb_byte buf[32];
- gdb_assert (!sparc_structure_or_union_p (type));
- gdb_assert (!(sparc_floating_p (type) && len == 16));
- if (sparc_floating_p (type) || sparc_complex_floating_p (type))
- {
-
- regcache_cooked_read (regcache, SPARC_F0_REGNUM, buf);
- if (len > 4)
- regcache_cooked_read (regcache, SPARC_F1_REGNUM, buf + 4);
- if (len > 8)
- {
- regcache_cooked_read (regcache, SPARC_F2_REGNUM, buf + 8);
- regcache_cooked_read (regcache, SPARC_F3_REGNUM, buf + 12);
- }
- if (len > 16)
- {
- regcache_cooked_read (regcache, SPARC_F4_REGNUM, buf + 16);
- regcache_cooked_read (regcache, SPARC_F5_REGNUM, buf + 20);
- regcache_cooked_read (regcache, SPARC_F6_REGNUM, buf + 24);
- regcache_cooked_read (regcache, SPARC_F7_REGNUM, buf + 28);
- }
- memcpy (valbuf, buf, len);
- }
- else
- {
-
- gdb_assert (sparc_integral_or_pointer_p (type));
- regcache_cooked_read (regcache, SPARC_O0_REGNUM, buf);
- if (len > 4)
- {
- regcache_cooked_read (regcache, SPARC_O1_REGNUM, buf + 4);
- gdb_assert (len == 8);
- memcpy (valbuf, buf, 8);
- }
- else
- {
-
- memcpy (valbuf, buf + 4 - len, len);
- }
- }
- }
- static void
- sparc32_store_return_value (struct type *type, struct regcache *regcache,
- const gdb_byte *valbuf)
- {
- int len = TYPE_LENGTH (type);
- gdb_byte buf[8];
- gdb_assert (!sparc_structure_or_union_p (type));
- gdb_assert (!(sparc_floating_p (type) && len == 16));
- gdb_assert (len <= 8);
- if (sparc_floating_p (type) || sparc_complex_floating_p (type))
- {
-
- memcpy (buf, valbuf, len);
- regcache_cooked_write (regcache, SPARC_F0_REGNUM, buf);
- if (len > 4)
- regcache_cooked_write (regcache, SPARC_F1_REGNUM, buf + 4);
- if (len > 8)
- {
- regcache_cooked_write (regcache, SPARC_F2_REGNUM, buf + 8);
- regcache_cooked_write (regcache, SPARC_F3_REGNUM, buf + 12);
- }
- if (len > 16)
- {
- regcache_cooked_write (regcache, SPARC_F4_REGNUM, buf + 16);
- regcache_cooked_write (regcache, SPARC_F5_REGNUM, buf + 20);
- regcache_cooked_write (regcache, SPARC_F6_REGNUM, buf + 24);
- regcache_cooked_write (regcache, SPARC_F7_REGNUM, buf + 28);
- }
- }
- else
- {
-
- gdb_assert (sparc_integral_or_pointer_p (type));
- if (len > 4)
- {
- gdb_assert (len == 8);
- memcpy (buf, valbuf, 8);
- regcache_cooked_write (regcache, SPARC_O1_REGNUM, buf + 4);
- }
- else
- {
-
- memcpy (buf + 4 - len, valbuf, len);
- }
- regcache_cooked_write (regcache, SPARC_O0_REGNUM, buf);
- }
- }
- static enum return_value_convention
- sparc32_return_value (struct gdbarch *gdbarch, struct value *function,
- struct type *type, struct regcache *regcache,
- gdb_byte *readbuf, const gdb_byte *writebuf)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-
- if (sparc_structure_or_union_p (type)
- || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16))
- {
- ULONGEST sp;
- CORE_ADDR addr;
- if (readbuf)
- {
- regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
- addr = read_memory_unsigned_integer (sp + 64, 4, byte_order);
- read_memory (addr, readbuf, TYPE_LENGTH (type));
- }
- if (writebuf)
- {
- regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
- addr = read_memory_unsigned_integer (sp + 64, 4, byte_order);
- write_memory (addr, writebuf, TYPE_LENGTH (type));
- }
- return RETURN_VALUE_ABI_PRESERVES_ADDRESS;
- }
- if (readbuf)
- sparc32_extract_return_value (type, regcache, readbuf);
- if (writebuf)
- sparc32_store_return_value (type, regcache, writebuf);
- return RETURN_VALUE_REGISTER_CONVENTION;
- }
- static int
- sparc32_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
- {
- return (sparc_structure_or_union_p (type)
- || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16)
- || sparc_complex_floating_p (type));
- }
- static int
- sparc32_dwarf2_struct_return_p (struct frame_info *this_frame)
- {
- CORE_ADDR pc = get_frame_address_in_block (this_frame);
- struct symbol *sym = find_pc_function (pc);
- if (sym)
- return sparc32_struct_return_from_sym (sym);
- return 0;
- }
- static void
- sparc32_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
- struct dwarf2_frame_state_reg *reg,
- struct frame_info *this_frame)
- {
- int off;
- switch (regnum)
- {
- case SPARC_G0_REGNUM:
-
- reg->how = DWARF2_FRAME_REG_SAME_VALUE;
- break;
- case SPARC_SP_REGNUM:
- reg->how = DWARF2_FRAME_REG_CFA;
- break;
- case SPARC32_PC_REGNUM:
- case SPARC32_NPC_REGNUM:
- reg->how = DWARF2_FRAME_REG_RA_OFFSET;
- off = 8;
- if (sparc32_dwarf2_struct_return_p (this_frame))
- off += 4;
- if (regnum == SPARC32_NPC_REGNUM)
- off += 4;
- reg->loc.offset = off;
- break;
- }
- }
- static CORE_ADDR
- sparc_analyze_control_transfer (struct frame_info *frame,
- CORE_ADDR pc, CORE_ADDR *npc)
- {
- unsigned long insn = sparc_fetch_instruction (pc);
- int conditional_p = X_COND (insn) & 0x7;
- int branch_p = 0, fused_p = 0;
- long offset = 0;
- if (X_OP (insn) == 0 && X_OP2 (insn) == 3)
- {
- if ((insn & 0x10000000) == 0)
- {
-
- branch_p = 1;
- conditional_p = 1;
- }
- else
- {
-
- branch_p = 1;
- fused_p = 1;
- offset = 4 * X_DISP10 (insn);
- }
- }
- else if (X_OP (insn) == 0 && X_OP2 (insn) == 6)
- {
-
- branch_p = 1;
- offset = 4 * X_DISP22 (insn);
- }
- else if (X_OP (insn) == 0 && X_OP2 (insn) == 5)
- {
-
- branch_p = 1;
- offset = 4 * X_DISP19 (insn);
- }
- else if (X_OP (insn) == 0 && X_OP2 (insn) == 2)
- {
-
- branch_p = 1;
- offset = 4 * X_DISP22 (insn);
- }
- else if (X_OP (insn) == 0 && X_OP2 (insn) == 1)
- {
-
- branch_p = 1;
- offset = 4 * X_DISP19 (insn);
- }
- else if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3a)
- {
-
- return gdbarch_tdep (get_frame_arch (frame))->step_trap (frame, insn);
- }
- FIXME
- if (branch_p)
- {
- if (fused_p)
- {
-
- gdb_assert (offset != 0);
- return pc + offset;
- }
- else if (conditional_p)
- {
-
- return (X_A (insn) ? *npc + 4 : 0);
- }
- else
- {
-
- if (X_COND (insn) == 0x0)
- pc = *npc, offset = 4;
- if (X_A (insn))
- *npc = 0;
- return pc + offset;
- }
- }
- return 0;
- }
- static CORE_ADDR
- sparc_step_trap (struct frame_info *frame, unsigned long insn)
- {
- return 0;
- }
- int
- sparc_software_single_step (struct frame_info *frame)
- {
- struct gdbarch *arch = get_frame_arch (frame);
- struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
- struct address_space *aspace = get_frame_address_space (frame);
- CORE_ADDR npc, nnpc;
- CORE_ADDR pc, orig_npc;
- pc = get_frame_register_unsigned (frame, tdep->pc_regnum);
- orig_npc = npc = get_frame_register_unsigned (frame, tdep->npc_regnum);
-
- nnpc = sparc_analyze_control_transfer (frame, pc, &npc);
- if (npc != 0)
- insert_single_step_breakpoint (arch, aspace, npc);
- if (nnpc != 0)
- insert_single_step_breakpoint (arch, aspace, nnpc);
-
- gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0);
- gdb_assert (nnpc != npc || orig_npc == 0);
- return 1;
- }
- static void
- sparc_write_pc (struct regcache *regcache, CORE_ADDR pc)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
- regcache_cooked_write_unsigned (regcache, tdep->pc_regnum, pc);
- regcache_cooked_write_unsigned (regcache, tdep->npc_regnum, pc + 4);
- }
- static void
- sparc_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- cb (".reg", tdep->sizeof_gregset, tdep->gregset, NULL, cb_data);
- cb (".reg2", tdep->sizeof_fpregset, tdep->fpregset, NULL, cb_data);
- }
- static struct gdbarch *
- sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
- {
- struct gdbarch_tdep *tdep;
- struct gdbarch *gdbarch;
-
- arches = gdbarch_list_lookup_by_info (arches, &info);
- if (arches != NULL)
- return arches->gdbarch;
-
- tdep = XCNEW (struct gdbarch_tdep);
- gdbarch = gdbarch_alloc (&info, tdep);
- tdep->pc_regnum = SPARC32_PC_REGNUM;
- tdep->npc_regnum = SPARC32_NPC_REGNUM;
- tdep->step_trap = sparc_step_trap;
- set_gdbarch_long_double_bit (gdbarch, 128);
- set_gdbarch_long_double_format (gdbarch, floatformats_sparc_quad);
- set_gdbarch_num_regs (gdbarch, SPARC32_NUM_REGS);
- set_gdbarch_register_name (gdbarch, sparc32_register_name);
- set_gdbarch_register_type (gdbarch, sparc32_register_type);
- set_gdbarch_num_pseudo_regs (gdbarch, SPARC32_NUM_PSEUDO_REGS);
- set_gdbarch_pseudo_register_read (gdbarch, sparc32_pseudo_register_read);
- set_gdbarch_pseudo_register_write (gdbarch, sparc32_pseudo_register_write);
-
- set_gdbarch_sp_regnum (gdbarch, SPARC_SP_REGNUM);
- set_gdbarch_pc_regnum (gdbarch, SPARC32_PC_REGNUM);
- set_gdbarch_fp0_regnum (gdbarch, SPARC_F0_REGNUM);
-
- set_gdbarch_frame_align (gdbarch, sparc32_frame_align);
- set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
- set_gdbarch_push_dummy_code (gdbarch, sparc32_push_dummy_code);
- set_gdbarch_push_dummy_call (gdbarch, sparc32_push_dummy_call);
- set_gdbarch_return_value (gdbarch, sparc32_return_value);
- set_gdbarch_stabs_argument_has_addr
- (gdbarch, sparc32_stabs_argument_has_addr);
- set_gdbarch_skip_prologue (gdbarch, sparc32_skip_prologue);
-
- set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_breakpoint_from_pc (gdbarch, sparc_breakpoint_from_pc);
- 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_write_pc (gdbarch, sparc_write_pc);
- set_gdbarch_dummy_id (gdbarch, sparc_dummy_id);
- set_gdbarch_unwind_pc (gdbarch, sparc_unwind_pc);
- frame_base_set_default (gdbarch, &sparc32_frame_base);
-
- dwarf2_frame_set_init_reg (gdbarch, sparc32_dwarf2_frame_init_reg);
- FIXME
-
- gdbarch_init_osabi (info, gdbarch);
- frame_unwind_append_unwinder (gdbarch, &sparc32_frame_unwind);
-
- if (tdep->gregset)
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, sparc_iterate_over_regset_sections);
- register_sparc_ravenscar_ops (gdbarch);
- return gdbarch;
- }
- void
- sparc_supply_rwindow (struct regcache *regcache, CORE_ADDR sp, int regnum)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- int offset = 0;
- gdb_byte buf[8];
- int i;
- if (sp & 1)
- {
-
- sp += BIAS;
- for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- {
- target_read_memory (sp + ((i - SPARC_L0_REGNUM) * 8), buf, 8);
-
- if (i == SPARC_I7_REGNUM)
- {
- ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
- ULONGEST i7;
- i7 = extract_unsigned_integer (buf + offset, 8, byte_order);
- store_unsigned_integer (buf + offset, 8, byte_order,
- i7 ^ wcookie);
- }
- regcache_raw_supply (regcache, i, buf);
- }
- }
- }
- else
- {
-
- sp &= 0xffffffffUL;
-
- if (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 64)
- {
- memset (buf, 0, 4);
- offset = 4;
- }
- for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- {
- target_read_memory (sp + ((i - SPARC_L0_REGNUM) * 4),
- buf + offset, 4);
-
- if (i == SPARC_I7_REGNUM)
- {
- ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
- ULONGEST i7;
- i7 = extract_unsigned_integer (buf + offset, 4, byte_order);
- store_unsigned_integer (buf + offset, 4, byte_order,
- i7 ^ wcookie);
- }
- regcache_raw_supply (regcache, i, buf);
- }
- }
- }
- }
- void
- sparc_collect_rwindow (const struct regcache *regcache,
- CORE_ADDR sp, int regnum)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- int offset = 0;
- gdb_byte buf[8];
- int i;
- if (sp & 1)
- {
-
- sp += BIAS;
- for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
- {
- if (regnum == -1 || regnum == SPARC_SP_REGNUM || regnum == i)
- {
- regcache_raw_collect (regcache, i, buf);
-
- if (i == SPARC_I7_REGNUM)
- {
- ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
- ULONGEST i7;
- i7 = extract_unsigned_integer (buf + offset, 8, byte_order);
- store_unsigned_integer (buf, 8, byte_order, i7 ^ wcookie);
- }
- target_write_memory (sp + ((i - SPARC_L0_REGNUM) * 8), buf, 8);
- }
- }
- }
- else
- {
-
- sp &= 0xffffffffUL;
-
- if (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 64)
- offset = 4;
- for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
- {
- if (regnum == -1 || regnum == SPARC_SP_REGNUM || regnum == i)
- {
- regcache_raw_collect (regcache, i, buf);
-
- if (i == SPARC_I7_REGNUM)
- {
- ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
- ULONGEST i7;
- i7 = extract_unsigned_integer (buf + offset, 4, byte_order);
- store_unsigned_integer (buf + offset, 4, byte_order,
- i7 ^ wcookie);
- }
- target_write_memory (sp + ((i - SPARC_L0_REGNUM) * 4),
- buf + offset, 4);
- }
- }
- }
- }
- void
- sparc32_supply_gregset (const struct sparc_gregmap *gregmap,
- struct regcache *regcache,
- int regnum, const void *gregs)
- {
- const gdb_byte *regs = gregs;
- gdb_byte zero[4] = { 0 };
- int i;
- if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
- regcache_raw_supply (regcache, SPARC32_PSR_REGNUM,
- regs + gregmap->r_psr_offset);
- if (regnum == SPARC32_PC_REGNUM || regnum == -1)
- regcache_raw_supply (regcache, SPARC32_PC_REGNUM,
- regs + gregmap->r_pc_offset);
- if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
- regcache_raw_supply (regcache, SPARC32_NPC_REGNUM,
- regs + gregmap->r_npc_offset);
- if (regnum == SPARC32_Y_REGNUM || regnum == -1)
- regcache_raw_supply (regcache, SPARC32_Y_REGNUM,
- regs + gregmap->r_y_offset);
- if (regnum == SPARC_G0_REGNUM || regnum == -1)
- regcache_raw_supply (regcache, SPARC_G0_REGNUM, &zero);
- if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
- {
- int offset = gregmap->r_g1_offset;
- for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_supply (regcache, i, regs + offset);
- offset += 4;
- }
- }
- if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1)
- {
-
- if (gregmap->r_l0_offset == -1)
- {
- ULONGEST sp;
- regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
- sparc_supply_rwindow (regcache, sp, regnum);
- }
- else
- {
- int offset = gregmap->r_l0_offset;
- for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_supply (regcache, i, regs + offset);
- offset += 4;
- }
- }
- }
- }
- void
- sparc32_collect_gregset (const struct sparc_gregmap *gregmap,
- const struct regcache *regcache,
- int regnum, void *gregs)
- {
- gdb_byte *regs = gregs;
- int i;
- if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
- regcache_raw_collect (regcache, SPARC32_PSR_REGNUM,
- regs + gregmap->r_psr_offset);
- if (regnum == SPARC32_PC_REGNUM || regnum == -1)
- regcache_raw_collect (regcache, SPARC32_PC_REGNUM,
- regs + gregmap->r_pc_offset);
- if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
- regcache_raw_collect (regcache, SPARC32_NPC_REGNUM,
- regs + gregmap->r_npc_offset);
- if (regnum == SPARC32_Y_REGNUM || regnum == -1)
- regcache_raw_collect (regcache, SPARC32_Y_REGNUM,
- regs + gregmap->r_y_offset);
- if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
- {
- int offset = gregmap->r_g1_offset;
-
- for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_collect (regcache, i, regs + offset);
- offset += 4;
- }
- }
- if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1)
- {
-
- if (gregmap->r_l0_offset != -1)
- {
- int offset = gregmap->r_l0_offset;
- for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_collect (regcache, i, regs + offset);
- offset += 4;
- }
- }
- }
- }
- void
- sparc32_supply_fpregset (const struct sparc_fpregmap *fpregmap,
- struct regcache *regcache,
- int regnum, const void *fpregs)
- {
- const gdb_byte *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 + fpregmap->r_f0_offset + (i * 4));
- }
- if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
- regcache_raw_supply (regcache, SPARC32_FSR_REGNUM,
- regs + fpregmap->r_fsr_offset);
- }
- void
- sparc32_collect_fpregset (const struct sparc_fpregmap *fpregmap,
- const struct regcache *regcache,
- int regnum, void *fpregs)
- {
- gdb_byte *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 + fpregmap->r_f0_offset + (i * 4));
- }
- if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
- regcache_raw_collect (regcache, SPARC32_FSR_REGNUM,
- regs + fpregmap->r_fsr_offset);
- }
- const struct sparc_gregmap sparc32_sunos4_gregmap =
- {
- 0 * 4,
- 1 * 4,
- 2 * 4,
- 3 * 4,
- -1,
- -1,
- 4 * 4,
- -1
- };
- const struct sparc_fpregmap sparc32_sunos4_fpregmap =
- {
- 0 * 4,
- 33 * 4,
- };
- const struct sparc_fpregmap sparc32_bsd_fpregmap =
- {
- 0 * 4,
- 32 * 4,
- };
- void _initialize_sparc_tdep (void);
- void
- _initialize_sparc_tdep (void)
- {
- register_gdbarch_init (bfd_arch_sparc, sparc32_gdbarch_init);
- }