-/* Target-dependent code for the Acorn Risc Machine, for GDB, the GNU Debugger.
- Copyright (C) 1988, 1989, 1991, 1992, 1993, 1995, 1996, 1998
+/* Target-dependent code for the Acorn Risc Machine (ARM).
+ Copyright (C) 1988, 1989, 1991, 1992, 1993, 1995-1999
Free Software Foundation, Inc.
This file is part of GDB.
return (TYPE_LENGTH (type) > 4);
}
+int
+arm_frame_chain_valid (chain, thisframe)
+ CORE_ADDR chain;
+ struct frame_info *thisframe;
+{
+#define LOWEST_PC 0x20 /* the first 0x20 bytes are the trap vectors. */
+ return (chain != 0 && (FRAME_SAVED_PC (thisframe) >= LOWEST_PC));
+}
+
/* Set to true if the 32-bit mode is in use. */
int arm_apcs_32 = 1;
{
/* Get address of the stmfd in the prologue of the callee; the saved
PC is the address of the stmfd + 12. */
- prologue_start = (read_memory_integer (fi->frame, 4) & 0x03fffffc) - 12;
+ prologue_start = ADDR_BITS_REMOVE(read_memory_integer (fi->frame, 4)) - 12;
prologue_end = prologue_start + 40; /* FIXME: should be big enough */
}
{
struct frame_info *frame = get_current_frame();
int regnum;
+ CORE_ADDR old_SP;
+ old_SP = read_register (frame->framereg);
for (regnum = 0; regnum < NUM_REGS; regnum++)
if (frame->fsr.regs[regnum] != 0)
write_register (regnum,
read_memory_integer (frame->fsr.regs[regnum], 4));
write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
- write_register (SP_REGNUM, read_register (frame->framereg));
+ write_register (SP_REGNUM, old_SP);
flush_cached_frames ();
}
print_fpu_flags (status);
}
+static char *original_register_names[] =
+{ "a1", "a2", "a3", "a4", /* 0 1 2 3 */
+ "v1", "v2", "v3", "v4", /* 4 5 6 7 */
+ "v5", "v6", "sl", "fp", /* 8 9 10 11 */
+ "ip", "sp", "lr", "pc", /* 12 13 14 15 */
+ "f0", "f1", "f2", "f3", /* 16 17 18 19 */
+ "f4", "f5", "f6", "f7", /* 20 21 22 23 */
+ "fps","ps" } /* 24 25 */;
+
+/* These names are the ones which gcc emits, and
+ I find them less confusing. Toggle between them
+ using the `othernames' command. */
+static char *additional_register_names[] =
+{ "r0", "r1", "r2", "r3", /* 0 1 2 3 */
+ "r4", "r5", "r6", "r7", /* 4 5 6 7 */
+ "r8", "r9", "sl", "fp", /* 8 9 10 11 */
+ "ip", "sp", "lr", "pc", /* 12 13 14 15 */
+ "f0", "f1", "f2", "f3", /* 16 17 18 19 */
+ "f4", "f5", "f6", "f7", /* 20 21 22 23 */
+ "fps","ps" } /* 24 25 */;
+
+char **arm_register_names = original_register_names;
+
+
static void
arm_othernames ()
{
static int toggle;
- static char *original[] = ORIGINAL_REGISTER_NAMES;
- static char *extra_crispy[] = ADDITIONAL_REGISTER_NAMES;
-
- memcpy (reg_names, toggle ? extra_crispy : original, sizeof(original));
+ arm_register_names = (toggle
+ ? additional_register_names
+ : original_register_names);
toggle = !toggle;
}
return print_insn_little_arm (memaddr, info);
}
+/* Sequence of bytes for breakpoint instruction. */
+#define ARM_LE_BREAKPOINT {0xFE,0xDE,0xFF,0xE7} /* Recognized illegal opcodes */
+#define ARM_BE_BREAKPOINT {0xE7,0xFF,0xDE,0xFE}
+#define THUMB_LE_BREAKPOINT {0xfe,0xdf}
+#define THUMB_BE_BREAKPOINT {0xdf,0xfe}
+
+/* The following has been superseded by BREAKPOINT_FOR_PC, but
+ is defined merely to keep mem-break.c happy. */
+#define LITTLE_BREAKPOINT ARM_LE_BREAKPOINT
+#define BIG_BREAKPOINT ARM_BE_BREAKPOINT
+
/* This function implements the BREAKPOINT_FROM_PC macro. It uses the program
counter value to determine whether a 16- or 32-bit breakpoint should be
used. It returns a pointer to a string of bytes that encode a breakpoint