/* Target dependent code for CRIS, for GDB, the GNU debugger.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2022 Free Software Foundation, Inc.
Contributed by Axis Communications AB.
Written by Hendrik Ruijter, Stefan Andersson, and Orjan Friberg.
#include "frame-unwind.h"
#include "frame-base.h"
#include "trad-frame.h"
-#include "dwarf2-frame.h"
+#include "dwarf2/frame.h"
#include "symtab.h"
#include "inferior.h"
#include "gdbtypes.h"
#include "osabi.h"
#include "arch-utils.h"
#include "regcache.h"
+#include "regset.h"
#include "objfiles.h"
static unsigned int usr_cmd_cris_version;
/* Indicates whether to trust the above variable. */
-static int usr_cmd_cris_version_valid = 0;
+static bool usr_cmd_cris_version_valid = false;
static const char cris_mode_normal[] = "normal";
static const char cris_mode_guru[] = "guru";
static const char *usr_cmd_cris_mode = cris_mode_normal;
/* Whether to make use of Dwarf-2 CFI (default on). */
-static int usr_cmd_cris_dwarf2_cfi = 1;
+static bool usr_cmd_cris_dwarf2_cfi = true;
/* Sigtramp identification code copied from i386-linux-tdep.c. */
CORE_ADDR pc = get_frame_pc (this_frame);
gdb_byte buf[SIGTRAMP_LEN];
- if (!safe_frame_unwind_memory (this_frame, pc, buf, SIGTRAMP_LEN))
+ if (!safe_frame_unwind_memory (this_frame, pc, buf))
return 0;
if (((buf[1] << 8) + buf[0]) != SIGTRAMP_INSN0)
return 0;
pc -= SIGTRAMP_OFFSET1;
- if (!safe_frame_unwind_memory (this_frame, pc, buf, SIGTRAMP_LEN))
+ if (!safe_frame_unwind_memory (this_frame, pc, buf))
return 0;
}
CORE_ADDR pc = get_frame_pc (this_frame);
gdb_byte buf[SIGTRAMP_LEN];
- if (!safe_frame_unwind_memory (this_frame, pc, buf, SIGTRAMP_LEN))
+ if (!safe_frame_unwind_memory (this_frame, pc, buf))
return 0;
if (((buf[1] << 8) + buf[0]) != SIGTRAMP_INSN0)
return 0;
pc -= SIGTRAMP_OFFSET1;
- if (!safe_frame_unwind_memory (this_frame, pc, buf, SIGTRAMP_LEN))
+ if (!safe_frame_unwind_memory (this_frame, pc, buf))
return 0;
}
int leaf_function;
/* Table indicating the location of each and every register. */
- struct trad_frame_saved_reg *saved_regs;
+ trad_frame_saved_reg *saved_regs;
};
static struct cris_unwind_cache *
void **this_cache)
{
struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ cris_gdbarch_tdep *tdep = (cris_gdbarch_tdep *) gdbarch_tdep (gdbarch);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct cris_unwind_cache *info;
CORE_ADDR addr;
/* R0 to R13 are stored in reverse order at offset (2 * 4) in
struct pt_regs. */
for (i = 0; i <= 13; i++)
- info->saved_regs[i].addr = addr + ((15 - i) * 4);
+ info->saved_regs[i].set_addr (addr + ((15 - i) * 4));
- info->saved_regs[MOF_REGNUM].addr = addr + (16 * 4);
- info->saved_regs[DCCR_REGNUM].addr = addr + (17 * 4);
- info->saved_regs[SRP_REGNUM].addr = addr + (18 * 4);
+ info->saved_regs[MOF_REGNUM].set_addr (addr + (16 * 4));
+ info->saved_regs[DCCR_REGNUM].set_addr (addr + (17 * 4));
+ info->saved_regs[SRP_REGNUM].set_addr (addr + (18 * 4));
/* Note: IRP is off by 2 at this point. There's no point in correcting
it though since that will mean that the backtrace will show a PC
different from what is shown when stopped. */
- info->saved_regs[IRP_REGNUM].addr = addr + (19 * 4);
+ info->saved_regs[IRP_REGNUM].set_addr (addr + (19 * 4));
info->saved_regs[gdbarch_pc_regnum (gdbarch)]
= info->saved_regs[IRP_REGNUM];
- info->saved_regs[gdbarch_sp_regnum (gdbarch)].addr = addr + (24 * 4);
+ info->saved_regs[gdbarch_sp_regnum (gdbarch)].set_addr (addr + (24 * 4));
}
else
{
/* R0 to R13 are stored in order at offset (1 * 4) in
struct pt_regs. */
for (i = 0; i <= 13; i++)
- info->saved_regs[i].addr = addr + ((i + 1) * 4);
-
- info->saved_regs[ACR_REGNUM].addr = addr + (15 * 4);
- info->saved_regs[SRS_REGNUM].addr = addr + (16 * 4);
- info->saved_regs[MOF_REGNUM].addr = addr + (17 * 4);
- info->saved_regs[SPC_REGNUM].addr = addr + (18 * 4);
- info->saved_regs[CCS_REGNUM].addr = addr + (19 * 4);
- info->saved_regs[SRP_REGNUM].addr = addr + (20 * 4);
- info->saved_regs[ERP_REGNUM].addr = addr + (21 * 4);
- info->saved_regs[EXS_REGNUM].addr = addr + (22 * 4);
- info->saved_regs[EDA_REGNUM].addr = addr + (23 * 4);
+ info->saved_regs[i].set_addr (addr + ((i + 1) * 4));
+
+ info->saved_regs[ACR_REGNUM].set_addr (addr + (15 * 4));
+ info->saved_regs[SRS_REGNUM].set_addr (addr + (16 * 4));
+ info->saved_regs[MOF_REGNUM].set_addr (addr + (17 * 4));
+ info->saved_regs[SPC_REGNUM].set_addr (addr + (18 * 4));
+ info->saved_regs[CCS_REGNUM].set_addr (addr + (19 * 4));
+ info->saved_regs[SRP_REGNUM].set_addr (addr + (20 * 4));
+ info->saved_regs[ERP_REGNUM].set_addr (addr + (21 * 4));
+ info->saved_regs[EXS_REGNUM].set_addr (addr + (22 * 4));
+ info->saved_regs[EDA_REGNUM].set_addr (addr + (23 * 4));
/* FIXME: If ERP is in a delay slot at this point then the PC will
be wrong at this point. This problem manifests itself in the
info->saved_regs[gdbarch_pc_regnum (gdbarch)]
= info->saved_regs[ERP_REGNUM];
- info->saved_regs[gdbarch_sp_regnum (gdbarch)].addr
- = addr + (25 * 4);
+ info->saved_regs[gdbarch_sp_regnum (gdbarch)].set_addr (addr + (25 * 4));
}
return info;
static void
cris_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache,
- struct frame_id *this_id)
+ struct frame_id *this_id)
{
struct cris_unwind_cache *cache =
cris_sigtramp_frame_unwind_cache (this_frame, this_cache);
void **this_cache, int regnum);
static struct value *
cris_sigtramp_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
+ void **this_cache, int regnum)
{
/* Make sure we've initialized the cache. */
cris_sigtramp_frame_unwind_cache (this_frame, this_cache);
static const struct frame_unwind cris_sigtramp_frame_unwind =
{
+ "cris sigtramp",
SIGTRAMP_FRAME,
default_frame_unwind_stop_reason,
cris_sigtramp_frame_this_id,
crisv32_single_step_through_delay (struct gdbarch *gdbarch,
struct frame_info *this_frame)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ cris_gdbarch_tdep *tdep = (cris_gdbarch_tdep *) gdbarch_tdep (gdbarch);
ULONGEST erp;
int ret = 0;
/* Functions for opcodes. The general form of the ETRAX 16-bit instruction:
Bit 15 - 12 Operand2
11 - 10 Mode
- 9 - 6 Opcode
- 5 - 4 Size
- 3 - 0 Operand1 */
+ 9 - 6 Opcode
+ 5 - 4 Size
+ 3 - 0 Operand1 */
static int
cris_get_operand2 (unsigned short insn)
inst_env_type *);
static struct gdbarch *cris_gdbarch_init (struct gdbarch_info,
- struct gdbarch_list *);
+ struct gdbarch_list *);
static void cris_dump_tdep (struct gdbarch *, struct ui_file *);
-static void set_cris_version (char *ignore_args, int from_tty,
+static void set_cris_version (const char *ignore_args, int from_tty,
struct cmd_list_element *c);
-static void set_cris_mode (char *ignore_args, int from_tty,
+static void set_cris_mode (const char *ignore_args, int from_tty,
struct cmd_list_element *c);
-static void set_cris_dwarf2_cfi (char *ignore_args, int from_tty,
+static void set_cris_dwarf2_cfi (const char *ignore_args, int from_tty,
struct cmd_list_element *c);
static CORE_ADDR cris_scan_prologue (CORE_ADDR pc,
struct frame_info *this_frame,
struct cris_unwind_cache *info);
-static CORE_ADDR cris_unwind_pc (struct gdbarch *gdbarch,
- struct frame_info *next_frame);
-
-static CORE_ADDR cris_unwind_sp (struct gdbarch *gdbarch,
- struct frame_info *next_frame);
-
/* When arguments must be pushed onto the stack, they go on in reverse
order. The below implements a FILO (stack) to do this.
Copied from d10v-tdep.c. */
void **this_prologue_cache)
{
struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ cris_gdbarch_tdep *tdep = (cris_gdbarch_tdep *) gdbarch_tdep (gdbarch);
struct cris_unwind_cache *info;
if ((*this_prologue_cache))
return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
}
-/* Assuming THIS_FRAME is a dummy, return the frame ID of that dummy
- frame. The frame ID's base needs to match the TOS value saved by
- save_dummy_frame_tos(), and the PC match the dummy frame's breakpoint. */
-
-static struct frame_id
-cris_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
- CORE_ADDR sp;
- sp = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
- return frame_id_build (sp, get_frame_pc (this_frame));
-}
-
static CORE_ADDR
cris_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
{
static CORE_ADDR
cris_push_dummy_code (struct gdbarch *gdbarch,
- CORE_ADDR sp, CORE_ADDR funaddr,
- struct value **args, int nargs,
- struct type *value_type,
- CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
+ CORE_ADDR sp, CORE_ADDR funaddr,
+ struct value **args, int nargs,
+ struct type *value_type,
+ CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
struct regcache *regcache)
{
/* Allocate space sufficient for a breakpoint. */
cris_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)
+ function_call_return_method return_method,
+ CORE_ADDR struct_addr)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- int stack_offset;
int argreg;
int argnum;
- /* The function's arguments and memory allocated by gdb for the arguments to
- point at reside in separate areas on the stack.
- Both frame pointers grow toward higher addresses. */
- CORE_ADDR fp_arg;
- CORE_ADDR fp_mem;
-
struct stack_item *si = NULL;
/* Push the return address. */
/* Are we returning a value using a structure return or a normal value
return? struct_addr is the address of the reserved space for the return
structure to be written on the stack. */
- if (struct_return)
- {
- regcache_cooked_write_unsigned (regcache, STR_REGNUM, struct_addr);
- }
+ if (return_method == return_method_struct)
+ regcache_cooked_write_unsigned (regcache, STR_REGNUM, struct_addr);
/* Now load as many as possible of the first arguments into registers,
and push the rest onto the stack. */
argreg = ARG1_REGNUM;
- stack_offset = 0;
for (argnum = 0; argnum < nargs; argnum++)
{
int i;
len = TYPE_LENGTH (value_type (args[argnum]));
- val = value_contents (args[argnum]);
+ val = value_contents (args[argnum]).data ();
/* How may registers worth of storage do we need for this argument? */
reg_demand = (len / 4) + (len % 4 != 0 ? 1 : 0);
-
+
if (len <= (2 * 4) && (argreg + reg_demand - 1 <= ARG4_REGNUM))
- {
- /* Data passed by value. Fits in available register(s). */
- for (i = 0; i < reg_demand; i++)
- {
- regcache_cooked_write (regcache, argreg, val);
- argreg++;
- val += 4;
- }
- }
+ {
+ /* Data passed by value. Fits in available register(s). */
+ for (i = 0; i < reg_demand; i++)
+ {
+ regcache->cooked_write (argreg, val);
+ argreg++;
+ val += 4;
+ }
+ }
else if (len <= (2 * 4) && argreg <= ARG4_REGNUM)
- {
- /* Data passed by value. Does not fit in available register(s).
- Use the register(s) first, then the stack. */
- for (i = 0; i < reg_demand; i++)
- {
- if (argreg <= ARG4_REGNUM)
- {
- regcache_cooked_write (regcache, argreg, val);
- argreg++;
- val += 4;
- }
- else
- {
+ {
+ /* Data passed by value. Does not fit in available register(s).
+ Use the register(s) first, then the stack. */
+ for (i = 0; i < reg_demand; i++)
+ {
+ if (argreg <= ARG4_REGNUM)
+ {
+ regcache->cooked_write (argreg, val);
+ argreg++;
+ val += 4;
+ }
+ else
+ {
/* Push item for later so that pushed arguments
come in the right order. */
si = push_stack_item (si, val, 4);
- val += 4;
- }
- }
- }
+ val += 4;
+ }
+ }
+ }
else if (len > (2 * 4))
- {
+ {
/* Data passed by reference. Push copy of data onto stack
and pass pointer to this copy as argument. */
sp = (sp - len) & ~3;
store_unsigned_integer (buf, 4, byte_order, sp);
si = push_stack_item (si, buf, 4);
}
- }
+ }
else
- {
- /* Data passed by value. No available registers. Put it on
- the stack. */
+ {
+ /* Data passed by value. No available registers. Put it on
+ the stack. */
si = push_stack_item (si, val, len);
- }
+ }
}
while (si)
static const struct frame_unwind cris_frame_unwind =
{
+ "cris prologue",
NORMAL_FRAME,
default_frame_unwind_stop_reason,
cris_frame_this_id,
unsigned short insn_next;
int regno;
- /* Is there a push fp? */
- int have_fp;
-
/* Number of byte on stack used for local variables and movem. */
int val;
insn = read_memory_unsigned_integer (pc, 2, byte_order);
pc += 2;
if (insn == 0xE1FC)
- {
- /* push <reg> 32 bit instruction. */
- insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
- pc += 2;
- regno = cris_get_operand2 (insn_next);
+ {
+ /* push <reg> 32 bit instruction. */
+ insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
+ pc += 2;
+ regno = cris_get_operand2 (insn_next);
if (info)
{
info->sp_offset += 4;
}
- /* This check, meant to recognize srp, used to be regno ==
- (SRP_REGNUM - NUM_GENREGS), but that covers r11 also. */
- if (insn_next == 0xBE7E)
- {
+ /* This check, meant to recognize srp, used to be regno ==
+ (SRP_REGNUM - NUM_GENREGS), but that covers r11 also. */
+ if (insn_next == 0xBE7E)
+ {
if (info)
{
info->leaf_function = 0;
}
- }
+ }
else if (insn_next == 0x8FEE)
- {
+ {
/* push $r8 */
if (info)
{
info->r8_offset = info->sp_offset;
}
- }
- }
+ }
+ }
else if (insn == 0x866E)
- {
- /* move.d sp,r8 */
+ {
+ /* move.d sp,r8 */
if (info)
{
info->uses_frame = 1;
}
- continue;
- }
+ continue;
+ }
else if (cris_get_operand2 (insn) == gdbarch_sp_regnum (gdbarch)
- && cris_get_mode (insn) == 0x0000
- && cris_get_opcode (insn) == 0x000A)
- {
- /* subq <val>,sp */
+ && cris_get_mode (insn) == 0x0000
+ && cris_get_opcode (insn) == 0x000A)
+ {
+ /* subq <val>,sp */
if (info)
{
info->sp_offset += cris_get_quick_value (insn);
}
- }
+ }
else if (cris_get_mode (insn) == 0x0002
- && cris_get_opcode (insn) == 0x000F
- && cris_get_size (insn) == 0x0003
- && cris_get_operand1 (insn) == gdbarch_sp_regnum (gdbarch))
- {
- /* movem r<regsave>,[sp] */
- regsave = cris_get_operand2 (insn);
- }
+ && cris_get_opcode (insn) == 0x000F
+ && cris_get_size (insn) == 0x0003
+ && cris_get_operand1 (insn) == gdbarch_sp_regnum (gdbarch))
+ {
+ /* movem r<regsave>,[sp] */
+ regsave = cris_get_operand2 (insn);
+ }
else if (cris_get_operand2 (insn) == gdbarch_sp_regnum (gdbarch)
- && ((insn & 0x0F00) >> 8) == 0x0001
- && (cris_get_signed_offset (insn) < 0))
- {
- /* Immediate byte offset addressing prefix word with sp as base
- register. Used for CRIS v8 i.e. ETRAX 100 and newer if <val>
- is between 64 and 128.
- movem r<regsave>,[sp=sp-<val>] */
+ && ((insn & 0x0F00) >> 8) == 0x0001
+ && (cris_get_signed_offset (insn) < 0))
+ {
+ /* Immediate byte offset addressing prefix word with sp as base
+ register. Used for CRIS v8 i.e. ETRAX 100 and newer if <val>
+ is between 64 and 128.
+ movem r<regsave>,[sp=sp-<val>] */
if (info)
{
info->sp_offset += -cris_get_signed_offset (insn);
}
insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
- pc += 2;
- if (cris_get_mode (insn_next) == PREFIX_ASSIGN_MODE
- && cris_get_opcode (insn_next) == 0x000F
- && cris_get_size (insn_next) == 0x0003
- && cris_get_operand1 (insn_next) == gdbarch_sp_regnum
+ pc += 2;
+ if (cris_get_mode (insn_next) == PREFIX_ASSIGN_MODE
+ && cris_get_opcode (insn_next) == 0x000F
+ && cris_get_size (insn_next) == 0x0003
+ && cris_get_operand1 (insn_next) == gdbarch_sp_regnum
(gdbarch))
- {
- regsave = cris_get_operand2 (insn_next);
- }
- else
- {
- /* The prologue ended before the limit was reached. */
- pc -= 4;
- break;
- }
- }
+ {
+ regsave = cris_get_operand2 (insn_next);
+ }
+ else
+ {
+ /* The prologue ended before the limit was reached. */
+ pc -= 4;
+ break;
+ }
+ }
else if (cris_get_mode (insn) == 0x0001
- && cris_get_opcode (insn) == 0x0009
- && cris_get_size (insn) == 0x0002)
- {
- /* move.d r<10..13>,r<0..15> */
- source_register = cris_get_operand1 (insn);
-
- /* FIXME? In the glibc solibs, the prologue might contain something
- like (this example taken from relocate_doit):
- move.d $pc,$r0
- sub.d 0xfffef426,$r0
- which isn't covered by the source_register check below. Question
- is whether to add a check for this combo, or make better use of
- the limit variable instead. */
- if (source_register < ARG1_REGNUM || source_register > ARG4_REGNUM)
- {
- /* The prologue ended before the limit was reached. */
- pc -= 2;
- break;
- }
- }
+ && cris_get_opcode (insn) == 0x0009
+ && cris_get_size (insn) == 0x0002)
+ {
+ /* move.d r<10..13>,r<0..15> */
+ source_register = cris_get_operand1 (insn);
+
+ /* FIXME? In the glibc solibs, the prologue might contain something
+ like (this example taken from relocate_doit):
+ move.d $pc,$r0
+ sub.d 0xfffef426,$r0
+ which isn't covered by the source_register check below. Question
+ is whether to add a check for this combo, or make better use of
+ the limit variable instead. */
+ if (source_register < ARG1_REGNUM || source_register > ARG4_REGNUM)
+ {
+ /* The prologue ended before the limit was reached. */
+ pc -= 2;
+ break;
+ }
+ }
else if (cris_get_operand2 (insn) == CRIS_FP_REGNUM
- /* The size is a fixed-size. */
- && ((insn & 0x0F00) >> 8) == 0x0001
- /* A negative offset. */
- && (cris_get_signed_offset (insn) < 0))
- {
- /* move.S rZ,[r8-U] (?) */
- insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
- pc += 2;
- regno = cris_get_operand2 (insn_next);
- if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch))
- && cris_get_mode (insn_next) == PREFIX_OFFSET_MODE
- && cris_get_opcode (insn_next) == 0x000F)
- {
- /* move.S rZ,[r8-U] */
- continue;
- }
- else
- {
- /* The prologue ended before the limit was reached. */
- pc -= 4;
- break;
- }
- }
+ /* The size is a fixed-size. */
+ && ((insn & 0x0F00) >> 8) == 0x0001
+ /* A negative offset. */
+ && (cris_get_signed_offset (insn) < 0))
+ {
+ /* move.S rZ,[r8-U] (?) */
+ insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
+ pc += 2;
+ regno = cris_get_operand2 (insn_next);
+ if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch))
+ && cris_get_mode (insn_next) == PREFIX_OFFSET_MODE
+ && cris_get_opcode (insn_next) == 0x000F)
+ {
+ /* move.S rZ,[r8-U] */
+ continue;
+ }
+ else
+ {
+ /* The prologue ended before the limit was reached. */
+ pc -= 4;
+ break;
+ }
+ }
else if (cris_get_operand2 (insn) == CRIS_FP_REGNUM
- /* The size is a fixed-size. */
- && ((insn & 0x0F00) >> 8) == 0x0001
- /* A positive offset. */
- && (cris_get_signed_offset (insn) > 0))
- {
- /* move.S [r8+U],rZ (?) */
+ /* The size is a fixed-size. */
+ && ((insn & 0x0F00) >> 8) == 0x0001
+ /* A positive offset. */
+ && (cris_get_signed_offset (insn) > 0))
+ {
+ /* move.S [r8+U],rZ (?) */
insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
- pc += 2;
- regno = cris_get_operand2 (insn_next);
- if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch))
- && cris_get_mode (insn_next) == PREFIX_OFFSET_MODE
- && cris_get_opcode (insn_next) == 0x0009
- && cris_get_operand1 (insn_next) == regno)
- {
- /* move.S [r8+U],rZ */
- continue;
- }
- else
- {
- /* The prologue ended before the limit was reached. */
- pc -= 4;
- break;
- }
- }
+ pc += 2;
+ regno = cris_get_operand2 (insn_next);
+ if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch))
+ && cris_get_mode (insn_next) == PREFIX_OFFSET_MODE
+ && cris_get_opcode (insn_next) == 0x0009
+ && cris_get_operand1 (insn_next) == regno)
+ {
+ /* move.S [r8+U],rZ */
+ continue;
+ }
+ else
+ {
+ /* The prologue ended before the limit was reached. */
+ pc -= 4;
+ break;
+ }
+ }
else
- {
- /* The prologue ended before the limit was reached. */
- pc -= 2;
- break;
- }
+ {
+ /* The prologue ended before the limit was reached. */
+ pc -= 2;
+ break;
+ }
}
/* We only want to know the end of the prologue when this_frame and info
{
ULONGEST this_base;
/* The SP was moved to the FP. This indicates that a new frame
- was created. Get THIS frame's FP value by unwinding it from
- the next frame. */
+ was created. Get THIS frame's FP value by unwinding it from
+ the next frame. */
this_base = get_frame_register_unsigned (this_frame, CRIS_FP_REGNUM);
info->base = this_base;
- info->saved_regs[CRIS_FP_REGNUM].addr = info->base;
+ info->saved_regs[CRIS_FP_REGNUM].set_addr (info->base);
/* The FP points at the last saved register. Adjust the FP back
- to before the first saved register giving the SP. */
+ to before the first saved register giving the SP. */
info->prev_sp = info->base + info->r8_offset;
}
else
{
ULONGEST this_base;
/* Assume that the FP is this frame's SP but with that pushed
- stack space added back. */
+ stack space added back. */
this_base = get_frame_register_unsigned (this_frame,
gdbarch_sp_regnum (gdbarch));
info->base = this_base;
for (regno = regsave; regno >= 0; regno--)
{
- info->saved_regs[regno].addr = info->base + info->r8_offset - val;
+ info->saved_regs[regno].set_addr (info->base + info->r8_offset - val);
val -= 4;
}
/* The previous frame's SP needed to be computed. Save the computed
value. */
- trad_frame_set_value (info->saved_regs,
- gdbarch_sp_regnum (gdbarch), info->prev_sp);
+ info->saved_regs[gdbarch_sp_regnum (gdbarch)].set_value (info->prev_sp);
if (!info->leaf_function)
{
if (info->r8_offset == 0)
{
/* R8 not pushed yet. */
- info->saved_regs[SRP_REGNUM].addr = info->base;
+ info->saved_regs[SRP_REGNUM].set_addr (info->base);
}
else
{
/* R8 pushed, but SP may or may not be moved to R8 yet. */
- info->saved_regs[SRP_REGNUM].addr = info->base + 4;
+ info->saved_regs[SRP_REGNUM].set_addr (info->base + 4);
}
}
static CORE_ADDR
cris_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ cris_gdbarch_tdep *tdep = (cris_gdbarch_tdep *) gdbarch_tdep (gdbarch);
CORE_ADDR func_addr, func_end;
struct symtab_and_line sal;
CORE_ADDR pc_after_prologue;
return pc_after_prologue;
}
-static CORE_ADDR
-cris_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
- ULONGEST pc;
- pc = frame_unwind_register_unsigned (next_frame,
- gdbarch_pc_regnum (gdbarch));
- return pc;
-}
+/* Implement the breakpoint_kind_from_pc gdbarch method. */
-static CORE_ADDR
-cris_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+static int
+cris_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
- ULONGEST sp;
- sp = frame_unwind_register_unsigned (next_frame,
- gdbarch_sp_regnum (gdbarch));
- return sp;
+ return 2;
}
-/* Use the program counter to determine the contents and size of a breakpoint
- instruction. It returns a pointer to a string of bytes that encode a
- breakpoint instruction, stores the length of the string to *lenptr, and
- adjusts pcptr (if necessary) to point to the actual memory location where
- the breakpoint should be inserted. */
+/* Implement the sw_breakpoint_from_kind gdbarch method. */
-static const unsigned char *
-cris_breakpoint_from_pc (struct gdbarch *gdbarch,
- CORE_ADDR *pcptr, int *lenptr)
+static const gdb_byte *
+cris_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ cris_gdbarch_tdep *tdep = (cris_gdbarch_tdep *) gdbarch_tdep (gdbarch);
static unsigned char break8_insn[] = {0x38, 0xe9};
static unsigned char break15_insn[] = {0x3f, 0xe9};
- *lenptr = 2;
+
+ *size = kind;
if (tdep->cris_mode == cris_mode_guru)
return break15_insn;
cris_spec_reg_applicable (struct gdbarch *gdbarch,
struct cris_spec_reg spec_reg)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ cris_gdbarch_tdep *tdep = (cris_gdbarch_tdep *) gdbarch_tdep (gdbarch);
unsigned int version = tdep->cris_version;
switch (spec_reg.applicable_version)
/* Indeterminate/obsolete. */
return 0;
case cris_ver_v0_3:
- return (version >= 0 && version <= 3);
+ return in_inclusive_range (version, 0U, 3U);
case cris_ver_v3p:
return (version >= 3);
case cris_ver_v8:
- return (version == 8 || version == 9);
+ return in_inclusive_range (version, 8U, 9U);
case cris_ver_v8p:
return (version >= 8);
case cris_ver_v0_10:
- return (version >= 0 && version <= 10);
+ return in_inclusive_range (version, 0U, 10U);
case cris_ver_v3_10:
- return (version >= 3 && version <= 10);
+ return in_inclusive_range (version, 3U, 10U);
case cris_ver_v8_10:
- return (version >= 8 && version <= 10);
+ return in_inclusive_range (version, 8U, 10U);
case cris_ver_v10:
return (version == 10);
case cris_ver_v10p:
static int
cris_register_size (struct gdbarch *gdbarch, int regno)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int i;
int spec_regno;
else if (regno >= NUM_GENREGS && regno < (NUM_GENREGS + NUM_SPECREGS))
{
/* Special register (R16 - R31). cris_spec_regs is zero-based.
- Adjust regno accordingly. */
+ Adjust regno accordingly. */
spec_regno = regno - NUM_GENREGS;
for (i = 0; cris_spec_regs[i].name != NULL; i++)
- {
- if (cris_spec_regs[i].number == spec_regno
- && cris_spec_reg_applicable (gdbarch, cris_spec_regs[i]))
- /* Go with the first applicable register. */
- return cris_spec_regs[i].reg_size;
- }
+ {
+ if (cris_spec_regs[i].number == spec_regno
+ && cris_spec_reg_applicable (gdbarch, cris_spec_regs[i]))
+ /* Go with the first applicable register. */
+ return cris_spec_regs[i].reg_size;
+ }
/* Special register not applicable to this CRIS version. */
return 0;
}
cris_cannot_fetch_register (struct gdbarch *gdbarch, int regno)
{
return ((regno < 0 || regno >= gdbarch_num_regs (gdbarch))
- || (cris_register_size (gdbarch, regno) == 0));
+ || (cris_register_size (gdbarch, regno) == 0));
}
/* Nonzero if regno should not be written to the target, for various
crisv32_cannot_fetch_register (struct gdbarch *gdbarch, int regno)
{
return ((regno < 0 || regno >= gdbarch_num_regs (gdbarch))
- || (cris_register_size (gdbarch, regno) == 0));
+ || (cris_register_size (gdbarch, regno) == 0));
}
/* Nonzero if regno should not be written to the target, for various
cris_store_return_value (struct type *type, struct regcache *regcache,
const gdb_byte *valbuf)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST val;
int len = TYPE_LENGTH (type);
static const char *
cris_register_name (struct gdbarch *gdbarch, int regno)
{
- static char *cris_genreg_names[] =
+ static const char *cris_genreg_names[] =
{ "r0", "r1", "r2", "r3", \
"r4", "r5", "r6", "r7", \
"r8", "r9", "r10", "r11", \
static const char *
crisv32_register_name (struct gdbarch *gdbarch, int regno)
{
- static char *crisv32_genreg_names[] =
+ static const char *crisv32_genreg_names[] =
{ "r0", "r1", "r2", "r3", \
"r4", "r5", "r6", "r7", \
"r8", "r9", "r10", "r11", \
"r12", "r13", "sp", "acr"
};
- static char *crisv32_sreg_names[] =
+ static const char *crisv32_sreg_names[] =
{ "s0", "s1", "s2", "s3", \
"s4", "s5", "s6", "s7", \
"s8", "s9", "s10", "s11", \
static void
cris_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
- struct dwarf2_frame_state_reg *reg,
+ struct dwarf2_frame_state_reg *reg,
struct frame_info *this_frame)
{
/* The return address column. */
cris_extract_return_value (struct type *type, struct regcache *regcache,
gdb_byte *valbuf)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST val;
int len = TYPE_LENGTH (type);
struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf)
{
- if (TYPE_CODE (type) == TYPE_CODE_STRUCT
- || TYPE_CODE (type) == TYPE_CODE_UNION
+ if (type->code () == TYPE_CODE_STRUCT
+ || type->code () == TYPE_CODE_UNION
|| TYPE_LENGTH (type) > 8)
/* Structs, unions, and anything larger than 8 bytes (2 registers)
goes on the stack. */
static int
constraint (unsigned int insn, const char *inst_args,
- inst_env_type *inst_env)
+ inst_env_type *inst_env)
{
int retval = 0;
int tmp, i;
switch (*s)
{
case 'm':
- if ((insn & 0x30) == 0x30)
- return -1;
- break;
-
+ if ((insn & 0x30) == 0x30)
+ return -1;
+ break;
+
case 'S':
- /* A prefix operand. */
- if (inst_env->prefix_found)
- break;
- else
- return -1;
+ /* A prefix operand. */
+ if (inst_env->prefix_found)
+ break;
+ else
+ return -1;
case 'B':
- /* A "push" prefix. (This check was REMOVED by san 970921.) Check for
- valid "push" size. In case of special register, it may be != 4. */
- if (inst_env->prefix_found)
- break;
- else
- return -1;
+ /* A "push" prefix. (This check was REMOVED by san 970921.) Check for
+ valid "push" size. In case of special register, it may be != 4. */
+ if (inst_env->prefix_found)
+ break;
+ else
+ return -1;
case 'D':
- retval = (((insn >> 0xC) & 0xF) == (insn & 0xF));
- if (!retval)
- return -1;
- else
- retval += 4;
- break;
+ retval = (((insn >> 0xC) & 0xF) == (insn & 0xF));
+ if (!retval)
+ return -1;
+ else
+ retval += 4;
+ break;
case 'P':
- tmp = (insn >> 0xC) & 0xF;
-
- for (i = 0; cris_spec_regs[i].name != NULL; i++)
- {
- /* Since we match four bits, we will give a value of
- 4 - 1 = 3 in a match. If there is a corresponding
- exact match of a special register in another pattern, it
- will get a value of 4, which will be higher. This should
- be correct in that an exact pattern would match better that
- a general pattern.
- Note that there is a reason for not returning zero; the
- pattern for "clear" is partly matched in the bit-pattern
- (the two lower bits must be zero), while the bit-pattern
- for a move from a special register is matched in the
- register constraint.
- This also means we will will have a race condition if
- there is a partly match in three bits in the bit pattern. */
- if (tmp == cris_spec_regs[i].number)
- {
- retval += 3;
- break;
- }
- }
-
- if (cris_spec_regs[i].name == NULL)
- return -1;
- break;
+ tmp = (insn >> 0xC) & 0xF;
+
+ for (i = 0; cris_spec_regs[i].name != NULL; i++)
+ {
+ /* Since we match four bits, we will give a value of
+ 4 - 1 = 3 in a match. If there is a corresponding
+ exact match of a special register in another pattern, it
+ will get a value of 4, which will be higher. This should
+ be correct in that an exact pattern would match better that
+ a general pattern.
+ Note that there is a reason for not returning zero; the
+ pattern for "clear" is partly matched in the bit-pattern
+ (the two lower bits must be zero), while the bit-pattern
+ for a move from a special register is matched in the
+ register constraint.
+ This also means we will will have a race condition if
+ there is a partly match in three bits in the bit pattern. */
+ if (tmp == cris_spec_regs[i].number)
+ {
+ retval += 3;
+ break;
+ }
+ }
+
+ if (cris_spec_regs[i].name == NULL)
+ return -1;
+ break;
}
return retval;
}
for (i = 0; cris_opcodes[i].name != NULL; i++)
{
if (((cris_opcodes[i].match & insn) == cris_opcodes[i].match)
- && ((cris_opcodes[i].lose & insn) == 0)
+ && ((cris_opcodes[i].lose & insn) == 0)
/* Only CRISv10 instructions, please. */
&& (cris_opcodes[i].applicable_version != cris_ver_v32p))
- {
- level_of_match = constraint (insn, cris_opcodes[i].args, inst_env);
- if (level_of_match >= 0)
- {
- level_of_match +=
- number_of_bits (cris_opcodes[i].match | cris_opcodes[i].lose);
- if (level_of_match > max_level_of_match)
- {
- max_matched = i;
- max_level_of_match = level_of_match;
- if (level_of_match == 16)
- {
- /* All bits matched, cannot find better. */
- break;
- }
- }
- }
- }
+ {
+ level_of_match = constraint (insn, cris_opcodes[i].args, inst_env);
+ if (level_of_match >= 0)
+ {
+ level_of_match +=
+ number_of_bits (cris_opcodes[i].match | cris_opcodes[i].lose);
+ if (level_of_match > max_level_of_match)
+ {
+ max_matched = i;
+ max_level_of_match = level_of_match;
+ if (level_of_match == 16)
+ {
+ /* All bits matched, cannot find better. */
+ break;
+ }
+ }
+ }
+ }
}
return max_matched;
}
actually an internal error. */
static int
-find_step_target (struct frame_info *frame, inst_env_type *inst_env)
+find_step_target (struct regcache *regcache, inst_env_type *inst_env)
{
int i;
int offset;
unsigned short insn;
- struct gdbarch *gdbarch = get_frame_arch (frame);
+ struct gdbarch *gdbarch = regcache->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
/* Create a local register image and set the initial state. */
for (i = 0; i < NUM_GENREGS; i++)
{
inst_env->reg[i] =
- (unsigned long) get_frame_register_unsigned (frame, i);
+ (unsigned long) regcache_raw_get_unsigned (regcache, i);
}
offset = NUM_GENREGS;
for (i = 0; i < NUM_SPECREGS; i++)
{
inst_env->preg[i] =
- (unsigned long) get_frame_register_unsigned (frame, offset + i);
+ (unsigned long) regcache_raw_get_unsigned (regcache, offset + i);
}
inst_env->branch_found = 0;
inst_env->slot_needed = 0;
(inst_env->reg[gdbarch_pc_regnum (gdbarch)], 2, byte_order);
/* If the instruction is not in a delay slot the new content of the
- PC is [PC] + 2. If the instruction is in a delay slot it is not
- that simple. Since a instruction in a delay slot cannot change
- the content of the PC, it does not matter what value PC will have.
- Just make sure it is a valid instruction. */
+ PC is [PC] + 2. If the instruction is in a delay slot it is not
+ that simple. Since a instruction in a delay slot cannot change
+ the content of the PC, it does not matter what value PC will have.
+ Just make sure it is a valid instruction. */
if (!inst_env->delay_slot_pc_active)
- {
- inst_env->reg[gdbarch_pc_regnum (gdbarch)] += 2;
- }
+ {
+ inst_env->reg[gdbarch_pc_regnum (gdbarch)] += 2;
+ }
else
- {
- inst_env->delay_slot_pc_active = 0;
- inst_env->reg[gdbarch_pc_regnum (gdbarch)]
+ {
+ inst_env->delay_slot_pc_active = 0;
+ inst_env->reg[gdbarch_pc_regnum (gdbarch)]
= inst_env->delay_slot_pc;
- }
+ }
/* Analyse the present instruction. */
i = find_cris_op (insn, inst_env);
if (i == -1)
- {
- inst_env->invalid = 1;
- }
+ {
+ inst_env->invalid = 1;
+ }
else
- {
- cris_gdb_func (gdbarch, cris_opcodes[i].op, insn, inst_env);
- }
+ {
+ cris_gdb_func (gdbarch, cris_opcodes[i].op, insn, inst_env);
+ }
} while (!inst_env->invalid
- && (inst_env->prefix_found || inst_env->xflag_found
- || inst_env->slot_needed));
+ && (inst_env->prefix_found || inst_env->xflag_found
+ || inst_env->slot_needed));
return i;
}
digs through the opcodes in order to find all possible targets.
Either one ordinary target or two targets for branches may be found. */
-static int
-cris_software_single_step (struct frame_info *frame)
+static std::vector<CORE_ADDR>
+cris_software_single_step (struct regcache *regcache)
{
- struct gdbarch *gdbarch = get_frame_arch (frame);
- struct address_space *aspace = get_frame_address_space (frame);
+ struct gdbarch *gdbarch = regcache->arch ();
inst_env_type inst_env;
+ std::vector<CORE_ADDR> next_pcs;
/* Analyse the present instruction environment and insert
breakpoints. */
- int status = find_step_target (frame, &inst_env);
+ int status = find_step_target (regcache, &inst_env);
if (status == -1)
{
/* Could not find a target. Things are likely to go downhill
else
{
/* Insert at most two breakpoints. One for the next PC content
- and possibly another one for a branch, jump, etc. */
+ and possibly another one for a branch, jump, etc. */
CORE_ADDR next_pc
= (CORE_ADDR) inst_env.reg[gdbarch_pc_regnum (gdbarch)];
- insert_single_step_breakpoint (gdbarch, aspace, next_pc);
+
+ next_pcs.push_back (next_pc);
if (inst_env.branch_found
&& (CORE_ADDR) inst_env.branch_break_address != next_pc)
{
CORE_ADDR branch_target_address
= (CORE_ADDR) inst_env.branch_break_address;
- insert_single_step_breakpoint (gdbarch,
- aspace, branch_target_address);
+
+ next_pcs.push_back (branch_target_address);
}
}
- return 1;
+ return next_pcs;
}
/* Calculates the prefix value for quick offset addressing mode. */
inst_env->reg[cris_get_operand1 (inst)] += 1;
/* The PC must be word aligned, so increase the PC with one
- word even if the size is byte. */
+ word even if the size is byte. */
if (cris_get_operand1 (inst) == REG_PC)
- {
- inst_env->reg[REG_PC] += 1;
- }
+ {
+ inst_env->reg[REG_PC] += 1;
+ }
}
else if (size == INST_WORD_SIZE)
{
/* It's invalid to change to the PC if we are in a delay slot. */
if (inst_env->slot_needed)
- {
- inst_env->invalid = 1;
- return;
- }
+ {
+ inst_env->invalid = 1;
+ return;
+ }
value = (long) inst_env->reg[REG_PC];
/* The value of abs (SIGNED_DWORD_MASK) is SIGNED_DWORD_MASK. */
if (value != SIGNED_DWORD_MASK)
- {
- value = -value;
- inst_env->reg[REG_PC] = (long) value;
- }
+ {
+ value = -value;
+ inst_env->reg[REG_PC] = (long) value;
+ }
}
inst_env->slot_needed = 0;
{
/* It's invalid to change the PC in a delay slot. */
if (inst_env->slot_needed)
- {
- inst_env->invalid = 1;
- return;
- }
+ {
+ inst_env->invalid = 1;
+ return;
+ }
/* Get the number of bits to shift. */
shift_steps
= cris_get_asr_shift_steps (inst_env->reg[cris_get_operand1 (inst)]);
/* Find out how many bits the operation should apply to. */
if (cris_get_size (inst) == INST_BYTE_SIZE)
- {
- if (value & SIGNED_BYTE_MASK)
- {
- signed_extend_mask = 0xFF;
- signed_extend_mask = signed_extend_mask >> shift_steps;
- signed_extend_mask = ~signed_extend_mask;
- }
- value = value >> shift_steps;
- value |= signed_extend_mask;
- value &= 0xFF;
- inst_env->reg[REG_PC] &= 0xFFFFFF00;
- inst_env->reg[REG_PC] |= value;
- }
+ {
+ if (value & SIGNED_BYTE_MASK)
+ {
+ signed_extend_mask = 0xFF;
+ signed_extend_mask = signed_extend_mask >> shift_steps;
+ signed_extend_mask = ~signed_extend_mask;
+ }
+ value = value >> shift_steps;
+ value |= signed_extend_mask;
+ value &= 0xFF;
+ inst_env->reg[REG_PC] &= 0xFFFFFF00;
+ inst_env->reg[REG_PC] |= value;
+ }
else if (cris_get_size (inst) == INST_WORD_SIZE)
- {
- if (value & SIGNED_WORD_MASK)
- {
- signed_extend_mask = 0xFFFF;
- signed_extend_mask = signed_extend_mask >> shift_steps;
- signed_extend_mask = ~signed_extend_mask;
- }
- value = value >> shift_steps;
- value |= signed_extend_mask;
- value &= 0xFFFF;
- inst_env->reg[REG_PC] &= 0xFFFF0000;
- inst_env->reg[REG_PC] |= value;
- }
+ {
+ if (value & SIGNED_WORD_MASK)
+ {
+ signed_extend_mask = 0xFFFF;
+ signed_extend_mask = signed_extend_mask >> shift_steps;
+ signed_extend_mask = ~signed_extend_mask;
+ }
+ value = value >> shift_steps;
+ value |= signed_extend_mask;
+ value &= 0xFFFF;
+ inst_env->reg[REG_PC] &= 0xFFFF0000;
+ inst_env->reg[REG_PC] |= value;
+ }
else if (cris_get_size (inst) == INST_DWORD_SIZE)
- {
- if (value & SIGNED_DWORD_MASK)
- {
- signed_extend_mask = 0xFFFFFFFF;
- signed_extend_mask = signed_extend_mask >> shift_steps;
- signed_extend_mask = ~signed_extend_mask;
- }
- value = value >> shift_steps;
- value |= signed_extend_mask;
- inst_env->reg[REG_PC] = value;
- }
+ {
+ if (value & SIGNED_DWORD_MASK)
+ {
+ signed_extend_mask = 0xFFFFFFFF;
+ signed_extend_mask = signed_extend_mask >> shift_steps;
+ signed_extend_mask = ~signed_extend_mask;
+ }
+ value = value >> shift_steps;
+ value |= signed_extend_mask;
+ inst_env->reg[REG_PC] = value;
+ }
}
inst_env->slot_needed = 0;
inst_env->prefix_found = 0;
/* It's invalid to change the PC in a delay slot. */
if (inst_env->slot_needed)
- {
- inst_env->invalid = 1;
- return;
- }
+ {
+ inst_env->invalid = 1;
+ return;
+ }
/* The shift size is given as a 5 bit quick value, i.e. we don't
- want the sign bit of the quick value. */
+ want the sign bit of the quick value. */
shift_steps = cris_get_asr_shift_steps (inst);
value = inst_env->reg[REG_PC];
if (value & SIGNED_DWORD_MASK)
- {
- signed_extend_mask = 0xFFFFFFFF;
- signed_extend_mask = signed_extend_mask >> shift_steps;
- signed_extend_mask = ~signed_extend_mask;
- }
+ {
+ signed_extend_mask = 0xFFFFFFFF;
+ signed_extend_mask = signed_extend_mask >> shift_steps;
+ signed_extend_mask = ~signed_extend_mask;
+ }
value = value >> shift_steps;
value |= signed_extend_mask;
inst_env->reg[REG_PC] = value;
{
/* It's invalid to change the PC in a delay slot. */
if (inst_env->slot_needed)
- {
- inst_env->invalid = 1;
- return;
- }
+ {
+ inst_env->invalid = 1;
+ return;
+ }
process_autoincrement (cris_get_size (inst), inst, inst_env);
}
inst_env->slot_needed = 0;
/* The instruction will clear the instruction's size bits. */
int clear_size = cris_get_clear_size (inst);
if (clear_size == INST_BYTE_SIZE)
- {
- inst_env->delay_slot_pc = inst_env->reg[REG_PC] & 0xFFFFFF00;
- }
+ {
+ inst_env->delay_slot_pc = inst_env->reg[REG_PC] & 0xFFFFFF00;
+ }
if (clear_size == INST_WORD_SIZE)
- {
- inst_env->delay_slot_pc = inst_env->reg[REG_PC] & 0xFFFF0000;
- }
+ {
+ inst_env->delay_slot_pc = inst_env->reg[REG_PC] & 0xFFFF0000;
+ }
if (clear_size == INST_DWORD_SIZE)
- {
- inst_env->delay_slot_pc = 0x0;
- }
+ {
+ inst_env->delay_slot_pc = 0x0;
+ }
/* The jump will be delayed with one delay slot. So we need a delay
- slot. */
+ slot. */
inst_env->slot_needed = 1;
inst_env->delay_slot_pc_active = 1;
}
if (inst_env->prefix_found)
{
/* The only way the PC can change is if this instruction is in
- assign addressing mode. */
+ assign addressing mode. */
check_assign (inst, inst_env);
}
/* Indirect mode can't change the PC so just check if the mode is
{
/* Check if we have a prefix. */
if (inst_env->prefix_found)
- {
- check_assign (inst, inst_env);
-
- /* Get the new value for the PC. */
- newpc =
- read_memory_unsigned_integer ((CORE_ADDR) inst_env->prefix_value,
- 4, inst_env->byte_order);
- }
+ {
+ check_assign (inst, inst_env);
+
+ /* Get the new value for the PC. */
+ newpc =
+ read_memory_unsigned_integer ((CORE_ADDR) inst_env->prefix_value,
+ 4, inst_env->byte_order);
+ }
else
- {
- /* Get the new value for the PC. */
- address = (CORE_ADDR) inst_env->reg[cris_get_operand1 (inst)];
- newpc = read_memory_unsigned_integer (address,
+ {
+ /* Get the new value for the PC. */
+ address = (CORE_ADDR) inst_env->reg[cris_get_operand1 (inst)];
+ newpc = read_memory_unsigned_integer (address,
4, inst_env->byte_order);
- /* Check if we should increment a register. */
- if (cris_get_mode (inst) == AUTOINC_MODE)
- {
- inst_env->reg[cris_get_operand1 (inst)] += 4;
- }
- }
+ /* Check if we should increment a register. */
+ if (cris_get_mode (inst) == AUTOINC_MODE)
+ {
+ inst_env->reg[cris_get_operand1 (inst)] += 4;
+ }
+ }
inst_env->reg[REG_PC] = newpc;
}
inst_env->slot_needed = 0;
if (inst_env->prefix_found)
{
/* The instruction has a prefix that means we are only interested if
- the instruction is in assign mode. */
+ the instruction is in assign mode. */
if (cris_get_mode (inst) == PREFIX_ASSIGN_MODE)
- {
- /* The prefix handles the problem if we are in a delay slot. */
- if (cris_get_operand1 (inst) == REG_PC)
- {
- /* Just take care of the assign. */
- check_assign (inst, inst_env);
- }
- }
+ {
+ /* The prefix handles the problem if we are in a delay slot. */
+ if (cris_get_operand1 (inst) == REG_PC)
+ {
+ /* Just take care of the assign. */
+ check_assign (inst, inst_env);
+ }
+ }
}
else if (cris_get_mode (inst) == AUTOINC_MODE)
{
/* The instruction doesn't have a prefix, the only case left that we
- are interested in is the autoincrement mode. */
+ are interested in is the autoincrement mode. */
if (cris_get_operand1 (inst) == REG_PC)
- {
- /* If the PC is to be incremented it's invalid to be in a
- delay slot. */
- if (inst_env->slot_needed)
- {
- inst_env->invalid = 1;
- return;
- }
-
- /* The increment depends on the size of the special register. */
- if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 1)
- {
- process_autoincrement (INST_BYTE_SIZE, inst, inst_env);
- }
- else if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 2)
- {
- process_autoincrement (INST_WORD_SIZE, inst, inst_env);
- }
- else
- {
- process_autoincrement (INST_DWORD_SIZE, inst, inst_env);
- }
- }
+ {
+ /* If the PC is to be incremented it's invalid to be in a
+ delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* The increment depends on the size of the special register. */
+ if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 1)
+ {
+ process_autoincrement (INST_BYTE_SIZE, inst, inst_env);
+ }
+ else if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 2)
+ {
+ process_autoincrement (INST_WORD_SIZE, inst, inst_env);
+ }
+ else
+ {
+ process_autoincrement (INST_DWORD_SIZE, inst, inst_env);
+ }
+ }
}
inst_env->slot_needed = 0;
inst_env->prefix_found = 0;
if (inst_env->prefix_found)
{
/* The instruction has a prefix that means we are only interested if
- the instruction is in assign mode. */
+ the instruction is in assign mode. */
if (cris_get_mode (inst) == PREFIX_ASSIGN_MODE)
- {
- /* The prefix handles the problem if we are in a delay slot. */
- if (cris_get_operand1 (inst) == REG_PC)
- {
- /* Just take care of the assign. */
- check_assign (inst, inst_env);
- }
- }
+ {
+ /* The prefix handles the problem if we are in a delay slot. */
+ if (cris_get_operand1 (inst) == REG_PC)
+ {
+ /* Just take care of the assign. */
+ check_assign (inst, inst_env);
+ }
+ }
}
/* The instruction doesn't have a prefix, the only case left that we
are interested in is the autoincrement mode. */
else if (cris_get_mode (inst) == AUTOINC_MODE)
{
if (cris_get_operand1 (inst) == REG_PC)
- {
- /* If the PC is to be incremented it's invalid to be in a
- delay slot. */
- if (inst_env->slot_needed)
- {
- inst_env->invalid = 1;
- return;
- }
-
- /* The increment depends on the size of the special register. */
- if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 1)
- {
- process_autoincrement (INST_BYTE_SIZE, inst, inst_env);
- }
- else if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 2)
- {
- process_autoincrement (INST_WORD_SIZE, inst, inst_env);
- }
- else
- {
- process_autoincrement (INST_DWORD_SIZE, inst, inst_env);
- }
- }
+ {
+ /* If the PC is to be incremented it's invalid to be in a
+ delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* The increment depends on the size of the special register. */
+ if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 1)
+ {
+ process_autoincrement (INST_BYTE_SIZE, inst, inst_env);
+ }
+ else if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 2)
+ {
+ process_autoincrement (INST_WORD_SIZE, inst, inst_env);
+ }
+ else
+ {
+ process_autoincrement (INST_DWORD_SIZE, inst, inst_env);
+ }
+ }
}
inst_env->slot_needed = 0;
inst_env->prefix_found = 0;
{
/* It's invalid to change the PC in a delay slot. */
if (inst_env->slot_needed)
- {
- inst_env->invalid = 1;
- return;
- }
+ {
+ inst_env->invalid = 1;
+ return;
+ }
/* The destination is the PC, the jump will have a delay slot. */
inst_env->delay_slot_pc = inst_env->preg[cris_get_operand2 (inst)];
inst_env->slot_needed = 1;
if (inst_env->prefix_found)
{
/* The prefix handles the problem if we are in a delay slot. Is the
- MOVEM instruction going to change the PC? */
+ MOVEM instruction going to change the PC? */
if (cris_get_operand2 (inst) >= REG_PC)
- {
- inst_env->reg[REG_PC] =
- read_memory_unsigned_integer (inst_env->prefix_value,
+ {
+ inst_env->reg[REG_PC] =
+ read_memory_unsigned_integer (inst_env->prefix_value,
4, inst_env->byte_order);
- }
+ }
/* The assign value is the value after the increment. Normally, the
- assign value is the value before the increment. */
+ assign value is the value before the increment. */
if ((cris_get_operand1 (inst) == REG_PC)
- && (cris_get_mode (inst) == PREFIX_ASSIGN_MODE))
- {
- inst_env->reg[REG_PC] = inst_env->prefix_value;
- inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
- }
+ && (cris_get_mode (inst) == PREFIX_ASSIGN_MODE))
+ {
+ inst_env->reg[REG_PC] = inst_env->prefix_value;
+ inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
+ }
}
else
{
/* Is the MOVEM instruction going to change the PC? */
if (cris_get_operand2 (inst) == REG_PC)
- {
- /* It's invalid to change the PC in a delay slot. */
- if (inst_env->slot_needed)
- {
- inst_env->invalid = 1;
- return;
- }
- inst_env->reg[REG_PC] =
- read_memory_unsigned_integer (inst_env->reg[cris_get_operand1 (inst)],
- 4, inst_env->byte_order);
- }
+ {
+ /* It's invalid to change the PC in a delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ inst_env->reg[REG_PC] =
+ read_memory_unsigned_integer (inst_env->reg[cris_get_operand1 (inst)],
+ 4, inst_env->byte_order);
+ }
/* The increment is not depending on the size, instead it's depending
- on the number of registers loaded from memory. */
+ on the number of registers loaded from memory. */
if ((cris_get_operand1 (inst) == REG_PC)
&& (cris_get_mode (inst) == AUTOINC_MODE))
- {
- /* It's invalid to change the PC in a delay slot. */
- if (inst_env->slot_needed)
- {
- inst_env->invalid = 1;
- return;
- }
- inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
- }
+ {
+ /* It's invalid to change the PC in a delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
+ }
}
inst_env->slot_needed = 0;
inst_env->prefix_found = 0;
if (inst_env->prefix_found)
{
/* The assign value is the value after the increment. Normally, the
- assign value is the value before the increment. */
+ assign value is the value before the increment. */
if ((cris_get_operand1 (inst) == REG_PC)
- && (cris_get_mode (inst) == PREFIX_ASSIGN_MODE))
- {
- /* The prefix handles the problem if we are in a delay slot. */
- inst_env->reg[REG_PC] = inst_env->prefix_value;
- inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
- }
+ && (cris_get_mode (inst) == PREFIX_ASSIGN_MODE))
+ {
+ /* The prefix handles the problem if we are in a delay slot. */
+ inst_env->reg[REG_PC] = inst_env->prefix_value;
+ inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
+ }
}
else
{
/* The increment is not depending on the size, instead it's depending
- on the number of registers loaded to memory. */
+ on the number of registers loaded to memory. */
if ((cris_get_operand1 (inst) == REG_PC)
&& (cris_get_mode (inst) == AUTOINC_MODE))
- {
- /* It's invalid to change the PC in a delay slot. */
- if (inst_env->slot_needed)
- {
- inst_env->invalid = 1;
- return;
- }
- inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
- }
+ {
+ /* It's invalid to change the PC in a delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
+ }
}
inst_env->slot_needed = 0;
inst_env->prefix_found = 0;
inst_env->disable_interrupt = 0;
}
-/* Handles the intructions that's not yet implemented, by setting
+/* Handles the instructions that's not yet implemented, by setting
inst_env->invalid to true. */
static void
{
/* It's invalid to change the PC in a delay slot. */
if (inst_env->slot_needed)
- {
- inst_env->invalid = 1;
- return;
- }
+ {
+ inst_env->invalid = 1;
+ return;
+ }
inst_env->reg[REG_PC] ^= inst_env->reg[cris_get_operand1 (inst)];
}
inst_env->slot_needed = 0;
static void
add_sub_cmp_and_or_move_action (unsigned short inst, inst_env_type *inst_env,
- unsigned long source1, unsigned long source2)
+ unsigned long source1, unsigned long source2)
{
unsigned long pc_mask;
unsigned long operation_mask;
value &= 0xFFFF;
/* Check if the instruction is signed extend. If so, check if value has
- the sign bit on. */
+ the sign bit on. */
if (cris_is_signed_extend_bit_on (*inst) && (value & SIGNED_WORD_MASK))
- {
- value |= SIGNED_WORD_EXTEND_MASK;
- }
+ {
+ value |= SIGNED_WORD_EXTEND_MASK;
+ }
}
else
{
value &= 0xFF;
/* Check if the instruction is signed extend. If so, check if value has
- the sign bit on. */
+ the sign bit on. */
if (cris_is_signed_extend_bit_on (*inst) && (value & SIGNED_BYTE_MASK))
- {
- value |= SIGNED_BYTE_EXTEND_MASK;
- }
+ {
+ value |= SIGNED_BYTE_EXTEND_MASK;
+ }
}
/* The size should now be dword. */
cris_set_size_to_dword (inst);
static void
reg_mode_add_sub_cmp_and_or_move_op (unsigned short inst,
- inst_env_type *inst_env)
+ inst_env_type *inst_env)
{
unsigned long operand1;
unsigned long operand2;
if (cris_get_operand2 (inst) == REG_PC)
{
if (inst_env->slot_needed)
- {
- inst_env->invalid = 1;
- return;
- }
+ {
+ inst_env->invalid = 1;
+ return;
+ }
/* The instruction has the PC as its target register. */
operand1 = inst_env->reg[cris_get_operand1 (inst)];
operand2 = inst_env->reg[REG_PC];
/* Check if it's a extend, signed or zero instruction. */
if (cris_get_opcode (inst) < 4)
- {
- operand1 = do_sign_or_zero_extend (operand1, &inst);
- }
+ {
+ operand1 = do_sign_or_zero_extend (operand1, &inst);
+ }
/* Calculate the PC value after the instruction, i.e. where the
- breakpoint should be. The order of the udw_operands is vital. */
+ breakpoint should be. The order of the udw_operands is vital. */
add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand1);
}
inst_env->slot_needed = 0;
static void
handle_prefix_assign_mode_for_aritm_op (unsigned short inst,
- inst_env_type *inst_env)
+ inst_env_type *inst_env)
{
unsigned long operand2;
unsigned long operand3;
inst_env->byte_order);
/* Calculate the PC value after the instruction, i.e. where the
- breakpoint should be. The order of the udw_operands is vital. */
+ breakpoint should be. The order of the udw_operands is vital. */
add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand3);
}
inst_env->slot_needed = 0;
static void
three_operand_add_sub_cmp_and_or_op (unsigned short inst,
- inst_env_type *inst_env)
+ inst_env_type *inst_env)
{
unsigned long operand2;
unsigned long operand3;
inst_env->byte_order);
/* Calculate the PC value after the instruction, i.e. where the
- breakpoint should be. */
+ breakpoint should be. */
add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand3);
}
inst_env->slot_needed = 0;
static void
handle_prefix_index_mode_for_aritm_op (unsigned short inst,
- inst_env_type *inst_env)
+ inst_env_type *inst_env)
{
if (cris_get_operand1 (inst) != cris_get_operand2 (inst))
{
/* If the instruction is MOVE it's invalid. If the instruction is ADD,
- SUB, AND or OR something weird is going on (if everything works these
- instructions should end up in the three operand version). */
+ SUB, AND or OR something weird is going on (if everything works these
+ instructions should end up in the three operand version). */
inst_env->invalid = 1;
return;
}
else
{
/* three_operand_add_sub_cmp_and_or does the same as we should do here
- so use it. */
+ so use it. */
three_operand_add_sub_cmp_and_or_op (inst, inst_env);
}
inst_env->slot_needed = 0;
static void
handle_inc_and_index_mode_for_aritm_op (unsigned short inst,
- inst_env_type *inst_env)
+ inst_env_type *inst_env)
{
unsigned long operand1;
unsigned long operand2;
if (cris_get_operand2 (inst) == REG_PC)
{
/* Must be done here, get_data_from_address may change the size
- field. */
+ field. */
size = cris_get_size (inst);
operand2 = inst_env->reg[REG_PC];
operand3 = get_data_from_address (&inst, operand1, inst_env->byte_order);
/* Calculate the PC value after the instruction, i.e. where the
- breakpoint should be. The order of the udw_operands is vital. */
+ breakpoint should be. The order of the udw_operands is vital. */
add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand3);
}
/* If this is an autoincrement addressing mode, check if the increment
size = cris_get_size (inst);
/* If it's an extend instruction we don't want the signed extend bit,
- because it influences the size. */
+ because it influences the size. */
if (cris_get_opcode (inst) < 4)
- {
- size &= ~SIGNED_EXTEND_BIT_MASK;
- }
+ {
+ size &= ~SIGNED_EXTEND_BIT_MASK;
+ }
process_autoincrement (size, inst, inst_env);
}
inst_env->slot_needed = 0;
static void
none_reg_mode_add_sub_cmp_and_or_move_op (unsigned short inst,
- inst_env_type *inst_env)
+ inst_env_type *inst_env)
{
if (inst_env->prefix_found)
{
if (cris_get_mode (inst) == PREFIX_INDEX_MODE)
- {
- handle_prefix_index_mode_for_aritm_op (inst, inst_env);
- }
+ {
+ handle_prefix_index_mode_for_aritm_op (inst, inst_env);
+ }
else if (cris_get_mode (inst) == PREFIX_ASSIGN_MODE)
- {
- handle_prefix_assign_mode_for_aritm_op (inst, inst_env);
- }
+ {
+ handle_prefix_assign_mode_for_aritm_op (inst, inst_env);
+ }
else
- {
- /* The mode is invalid for a prefixed base instruction. */
- inst_env->invalid = 1;
- return;
- }
+ {
+ /* The mode is invalid for a prefixed base instruction. */
+ inst_env->invalid = 1;
+ return;
+ }
}
else
{
if (cris_get_operand2 (inst) == REG_PC)
{
if (inst_env->slot_needed)
- {
- inst_env->invalid = 1;
- return;
- }
+ {
+ inst_env->invalid = 1;
+ return;
+ }
operand1 = cris_get_quick_value (inst);
operand2 = inst_env->reg[REG_PC];
cris_set_size_to_dword (&inst);
/* Calculate the PC value after the instruction, i.e. where the
- breakpoint should be. */
+ breakpoint should be. */
add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand1);
}
inst_env->slot_needed = 0;
if (cris_get_operand2 (inst) == REG_PC)
{
if (inst_env->slot_needed)
- {
- inst_env->invalid = 1;
- return;
- }
+ {
+ inst_env->invalid = 1;
+ return;
+ }
/* The instruction has the PC as its target register. */
operand1 = cris_get_quick_value (inst);
operand2 = inst_env->reg[REG_PC];
/* The quick value is signed, so check if we must do a signed extend. */
if (operand1 & SIGNED_QUICK_VALUE_MASK)
- {
- /* sign extend */
- operand1 |= SIGNED_QUICK_VALUE_EXTEND_MASK;
- }
+ {
+ /* sign extend */
+ operand1 |= SIGNED_QUICK_VALUE_EXTEND_MASK;
+ }
/* The size should now be dword. */
cris_set_size_to_dword (&inst);
/* Calculate the PC value after the instruction, i.e. where the
- breakpoint should be. */
+ breakpoint should be. */
add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand1);
}
inst_env->slot_needed = 0;
}
}
-/* This wrapper is to avoid cris_get_assembler being called before
- exec_bfd has been set. */
-
-static int
-cris_delayed_get_disassembler (bfd_vma addr, struct disassemble_info *info)
-{
- int (*print_insn) (bfd_vma addr, struct disassemble_info *info);
- /* FIXME: cagney/2003-08-27: It should be possible to select a CRIS
- disassembler, even when there is no BFD. Does something like
- "gdb; target remote; disassmeble *0x123" work? */
- gdb_assert (exec_bfd != NULL);
- print_insn = cris_get_disassembler (exec_bfd);
- gdb_assert (print_insn != NULL);
- return print_insn (addr, info);
-}
-
/* Originally from <asm/elf.h>. */
typedef unsigned char cris_elf_greg_t[4];
/* Unpack a cris_elf_gregset_t into GDB's register cache. */
static void
-cris_supply_gregset (struct regcache *regcache, cris_elf_gregset_t *gregsetp)
+cris_supply_gregset (const struct regset *regset, struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ struct gdbarch *gdbarch = regcache->arch ();
+ cris_gdbarch_tdep *tdep = (cris_gdbarch_tdep *) gdbarch_tdep (gdbarch);
int i;
- cris_elf_greg_t *regp = *gregsetp;
+ const cris_elf_greg_t *regp = static_cast<const cris_elf_greg_t *>(gregs);
+
+ if (len != sizeof (cris_elf_gregset_t)
+ && len != sizeof (crisv32_elf_gregset_t))
+ warning (_("wrong size gregset struct in core file"));
+ gdb_assert (len >= sizeof (crisv32_elf_gregset_t));
/* The kernel dumps all 32 registers as unsigned longs, but supply_register
knows about the actual size of each register so that's no problem. */
for (i = 0; i < NUM_GENREGS + NUM_SPECREGS; i++)
{
- regcache_raw_supply (regcache, i, (char *)®p[i]);
+ if (regnum == -1 || regnum == i)
+ regcache->raw_supply (i, (char *)®p[i]);
}
- if (tdep->cris_version == 32)
+ if (tdep->cris_version == 32 && (regnum == -1 || regnum == ERP_REGNUM))
{
/* Needed to set pseudo-register PC for CRISv32. */
/* FIXME: If ERP is in a delay slot at this point then the PC will
be wrong. Issue a warning to alert the user. */
- regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch),
- (char *)®p[ERP_REGNUM]);
+ regcache->raw_supply (gdbarch_pc_regnum (gdbarch),
+ (char *)®p[ERP_REGNUM]);
if (*(char *)®p[ERP_REGNUM] & 0x1)
fprintf_unfiltered (gdb_stderr, "Warning: PC in delay slot\n");
}
}
-/* Use a local version of this function to get the correct types for
- regsets, until multi-arch core support is ready. */
+static const struct regset cris_regset = {
+ nullptr,
+ cris_supply_gregset,
+ /* We don't need a collect function because we only use this for core files
+ (via iterate_over_regset_sections). */
+ nullptr,
+ REGSET_VARIABLE_SIZE
+};
-static void
-fetch_core_registers (struct regcache *regcache,
- char *core_reg_sect, unsigned core_reg_size,
- int which, CORE_ADDR reg_addr)
+static void cris_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
{
- cris_elf_gregset_t gregset;
-
- switch (which)
- {
- case 0:
- if (core_reg_size != sizeof (cris_elf_gregset_t)
- && core_reg_size != sizeof (crisv32_elf_gregset_t))
- {
- warning (_("wrong size gregset struct in core file"));
- }
- else
- {
- memcpy (&gregset, core_reg_sect, sizeof (gregset));
- cris_supply_gregset (regcache, &gregset);
- }
-
- default:
- /* We've covered all the kinds of registers we know about here,
- so this must be something we wouldn't know what to do with
- anyway. Just ignore it. */
- break;
- }
+ cb (".reg", sizeof (crisv32_elf_gregset_t), sizeof (crisv32_elf_gregset_t),
+ &cris_regset, NULL, cb_data);
}
-static struct core_fns cris_elf_core_fns =
-{
- bfd_target_elf_flavour, /* core_flavour */
- default_check_format, /* check_format */
- default_core_sniffer, /* core_sniffer */
- fetch_core_registers, /* core_read_registers */
- NULL /* next */
-};
-
-extern initialize_file_ftype _initialize_cris_tdep; /* -Wmissing-prototypes */
-
+void _initialize_cris_tdep ();
void
-_initialize_cris_tdep (void)
+_initialize_cris_tdep ()
{
- struct cmd_list_element *c;
-
gdbarch_register (bfd_arch_cris, cris_gdbarch_init, cris_dump_tdep);
/* CRIS-specific user-commands. */
NULL, /* FIXME: i18n: Usage of Dwarf-2 CFI
for CRIS is %d. */
&setlist, &showlist);
-
- deprecated_add_core_fns (&cris_elf_core_fns);
}
/* Prints out all target specific values. */
static void
cris_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ cris_gdbarch_tdep *tdep = (cris_gdbarch_tdep *) gdbarch_tdep (gdbarch);
if (tdep != NULL)
{
- fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_version = %i\n",
- tdep->cris_version);
- fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_mode = %s\n",
- tdep->cris_mode);
- fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_dwarf2_cfi = %i\n",
- tdep->cris_dwarf2_cfi);
+ fprintf_filtered (file, "cris_dump_tdep: tdep->cris_version = %i\n",
+ tdep->cris_version);
+ fprintf_filtered (file, "cris_dump_tdep: tdep->cris_mode = %s\n",
+ tdep->cris_mode);
+ fprintf_filtered (file, "cris_dump_tdep: tdep->cris_dwarf2_cfi = %i\n",
+ tdep->cris_dwarf2_cfi);
}
}
static void
-set_cris_version (char *ignore_args, int from_tty,
+set_cris_version (const char *ignore_args, int from_tty,
struct cmd_list_element *c)
{
struct gdbarch_info info;
usr_cmd_cris_version_valid = 1;
/* Update the current architecture, if needed. */
- gdbarch_info_init (&info);
if (!gdbarch_update_p (info))
internal_error (__FILE__, __LINE__,
_("cris_gdbarch_update: failed to update architecture."));
}
static void
-set_cris_mode (char *ignore_args, int from_tty,
+set_cris_mode (const char *ignore_args, int from_tty,
struct cmd_list_element *c)
{
struct gdbarch_info info;
/* Update the current architecture, if needed. */
- gdbarch_info_init (&info);
if (!gdbarch_update_p (info))
internal_error (__FILE__, __LINE__,
"cris_gdbarch_update: failed to update architecture.");
}
static void
-set_cris_dwarf2_cfi (char *ignore_args, int from_tty,
+set_cris_dwarf2_cfi (const char *ignore_args, int from_tty,
struct cmd_list_element *c)
{
struct gdbarch_info info;
/* Update the current architecture, if needed. */
- gdbarch_info_init (&info);
if (!gdbarch_update_p (info))
internal_error (__FILE__, __LINE__,
_("cris_gdbarch_update: failed to update architecture."));
cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
struct gdbarch *gdbarch;
- struct gdbarch_tdep *tdep;
unsigned int cris_version;
if (usr_cmd_cris_version_valid)
arches != NULL;
arches = gdbarch_list_lookup_by_info (arches->next, &info))
{
- if ((gdbarch_tdep (arches->gdbarch)->cris_version
- == usr_cmd_cris_version)
- && (gdbarch_tdep (arches->gdbarch)->cris_mode
- == usr_cmd_cris_mode)
- && (gdbarch_tdep (arches->gdbarch)->cris_dwarf2_cfi
- == usr_cmd_cris_dwarf2_cfi))
- return arches->gdbarch;
+ cris_gdbarch_tdep *tdep
+ = (cris_gdbarch_tdep *) gdbarch_tdep (arches->gdbarch);
+
+ if (tdep->cris_version == usr_cmd_cris_version
+ && tdep->cris_mode == usr_cmd_cris_mode
+ && tdep->cris_dwarf2_cfi == usr_cmd_cris_dwarf2_cfi)
+ return arches->gdbarch;
}
/* No matching architecture was found. Create a new one. */
- tdep = XNEW (struct gdbarch_tdep);
+ cris_gdbarch_tdep *tdep = new cris_gdbarch_tdep;
+ info.byte_order = BFD_ENDIAN_LITTLE;
gdbarch = gdbarch_alloc (&info, tdep);
tdep->cris_version = usr_cmd_cris_version;
tdep->cris_mode = usr_cmd_cris_mode;
tdep->cris_dwarf2_cfi = usr_cmd_cris_dwarf2_cfi;
- /* INIT shall ensure that the INFO.BYTE_ORDER is non-zero. */
- switch (info.byte_order)
- {
- case BFD_ENDIAN_LITTLE:
- /* Ok. */
- break;
-
- case BFD_ENDIAN_BIG:
- internal_error (__FILE__, __LINE__,
- _("cris_gdbarch_init: big endian byte order in info"));
- break;
-
- default:
- internal_error (__FILE__, __LINE__,
- _("cris_gdbarch_init: unknown byte order in info"));
- }
-
set_gdbarch_return_value (gdbarch, cris_return_value);
-
set_gdbarch_sp_regnum (gdbarch, 14);
/* Length of ordinary registers used in push_word and a few other
case 8:
case 9:
/* Old versions; not supported. */
- internal_error (__FILE__, __LINE__,
- _("cris_gdbarch_init: unsupported CRIS version"));
- break;
+ return 0;
case 10:
case 11:
/* CRIS v10 and v11, a.k.a. ETRAX 100LX. In addition to ETRAX 100,
- P7 (32 bits), and P15 (32 bits) have been implemented. */
+ P7 (32 bits), and P15 (32 bits) have been implemented. */
set_gdbarch_pc_regnum (gdbarch, 15);
set_gdbarch_register_type (gdbarch, cris_register_type);
/* There are 32 registers (some of which may not be implemented). */
break;
default:
- internal_error (__FILE__, __LINE__,
- _("cris_gdbarch_init: unknown CRIS version"));
+ /* Unknown version. */
+ return 0;
}
/* Dummy frame functions (shared between CRISv10 and CRISv32 since they
/* The stack grows downward. */
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_breakpoint_from_pc (gdbarch, cris_breakpoint_from_pc);
+ set_gdbarch_breakpoint_kind_from_pc (gdbarch, cris_breakpoint_kind_from_pc);
+ set_gdbarch_sw_breakpoint_from_kind (gdbarch, cris_sw_breakpoint_from_kind);
+ set_gdbarch_iterate_over_regset_sections (gdbarch, cris_iterate_over_regset_sections);
- set_gdbarch_unwind_pc (gdbarch, cris_unwind_pc);
- set_gdbarch_unwind_sp (gdbarch, cris_unwind_sp);
- set_gdbarch_dummy_id (gdbarch, cris_dummy_id);
-
if (tdep->cris_dwarf2_cfi == 1)
{
/* Hook in the Dwarf-2 frame sniffer. */
/* Hook in ABI-specific overrides, if they have been registered. */
gdbarch_init_osabi (info, gdbarch);
- /* FIXME: cagney/2003-08-27: It should be possible to select a CRIS
- disassembler, even when there is no BFD. Does something like
- "gdb; target remote; disassmeble *0x123" work? */
- set_gdbarch_print_insn (gdbarch, cris_delayed_get_disassembler);
-
return gdbarch;
}