/* Common target dependent code for GDB on ARM systems.
- Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GDB.
ARM_A1_REGNUM = 0, /* first integer-like argument */
ARM_A4_REGNUM = 3, /* last integer-like argument */
ARM_AP_REGNUM = 11,
+ ARM_IP_REGNUM = 12,
ARM_SP_REGNUM = 13, /* Contains address of top of stack */
ARM_LR_REGNUM = 14, /* address to return to from a function call */
ARM_PC_REGNUM = 15, /* Contains program counter */
ARM_WCGR0_REGNUM, /* WMMX general purpose registers. */
ARM_WCGR3_REGNUM = ARM_WCGR0_REGNUM + 3,
ARM_WCGR7_REGNUM = ARM_WCGR0_REGNUM + 7,
+ ARM_D0_REGNUM, /* VFP double-precision registers. */
+ ARM_D31_REGNUM = ARM_D0_REGNUM + 31,
ARM_NUM_REGS,
bits. DWORD aligned they use 96 bits. */
#define FP_REGISTER_SIZE 12
-/* Status registers are the same size as general purpose registers.
- Used for documentation purposes and code readability in this
- header. */
-#define STATUS_REGISTER_SIZE 4
-
/* Number of machine registers. The only define actually required
is gdbarch_num_regs. The other definitions are used for documentation
purposes and code readability. */
#define FLAG_C 0x20000000
#define FLAG_V 0x10000000
+#define CPSR_T 0x20
+
/* Type of floating-point code in use by inferior. There are really 3 models
that are traditionally supported (plus the endianness issue), but gcc can
only generate 2 of those. The third is APCS_FLOAT, where arguments to
enum arm_float_model fp_model; /* Floating point calling conventions. */
int have_fpa_registers; /* Does the target report the FPA registers? */
+ int have_vfp_registers; /* Does the target report the VFP registers? */
+ int have_vfp_pseudos; /* Are we synthesizing the single precision
+ VFP registers? */
+ int have_neon_pseudos; /* Are we synthesizing the quad precision
+ NEON registers? Requires
+ have_vfp_pseudos. */
+ int have_neon; /* Do we have a NEON unit? */
CORE_ADDR lowest_pc; /* Lowest address at which instructions
will appear. */
/* Cached core file helpers. */
struct regset *gregset, *fpregset;
+
+ /* ISA-specific data types. */
+ struct type *arm_ext_type;
+ struct type *neon_double_type;
+ struct type *neon_quad_type;
};
+/* Structures used for displaced stepping. */
+/* The maximum number of temporaries available for displaced instructions. */
+#define DISPLACED_TEMPS 16
+/* The maximum number of modified instructions generated for one single-stepped
+ instruction, including the breakpoint (usually at the end of the instruction
+ sequence) and any scratch words, etc. */
+#define DISPLACED_MODIFIED_INSNS 8
+
+struct displaced_step_closure
+{
+ ULONGEST tmp[DISPLACED_TEMPS];
+ int rd;
+ int wrote_to_pc;
+ union
+ {
+ struct
+ {
+ int xfersize;
+ int rn; /* Writeback register. */
+ unsigned int immed : 1; /* Offset is immediate. */
+ unsigned int writeback : 1; /* Perform base-register writeback. */
+ unsigned int restore_r4 : 1; /* Used r4 as scratch. */
+ } ldst;
+
+ struct
+ {
+ unsigned long dest;
+ unsigned int link : 1;
+ unsigned int exchange : 1;
+ unsigned int cond : 4;
+ } branch;
+
+ struct
+ {
+ unsigned int regmask;
+ int rn;
+ CORE_ADDR xfer_addr;
+ unsigned int load : 1;
+ unsigned int user : 1;
+ unsigned int increment : 1;
+ unsigned int before : 1;
+ unsigned int writeback : 1;
+ unsigned int cond : 4;
+ } block;
+
+ struct
+ {
+ unsigned int immed : 1;
+ } preload;
+
+ struct
+ {
+ /* If non-NULL, override generic SVC handling (e.g. for a particular
+ OS). */
+ int (*copy_svc_os) (struct gdbarch *gdbarch, uint32_t insn, CORE_ADDR to,
+ struct regcache *regs,
+ struct displaced_step_closure *dsc);
+ } svc;
+ } u;
+ unsigned long modinsn[DISPLACED_MODIFIED_INSNS];
+ int numinsns;
+ CORE_ADDR insn_addr;
+ CORE_ADDR scratch_base;
+ void (*cleanup) (struct gdbarch *, struct regcache *,
+ struct displaced_step_closure *);
+};
-#ifndef LOWEST_PC
-#define LOWEST_PC (gdbarch_tdep (current_gdbarch)->lowest_pc)
-#endif
+/* Values for the WRITE_PC argument to displaced_write_reg. If the register
+ write may write to the PC, specifies the way the CPSR T bit, etc. is
+ modified by the instruction. */
+
+enum pc_write_style
+{
+ BRANCH_WRITE_PC,
+ BX_WRITE_PC,
+ LOAD_WRITE_PC,
+ ALU_WRITE_PC,
+ CANNOT_WRITE_PC
+};
+
+extern void
+ arm_process_displaced_insn (struct gdbarch *gdbarch, uint32_t insn,
+ CORE_ADDR from, CORE_ADDR to,
+ struct regcache *regs,
+ struct displaced_step_closure *dsc);
+extern void
+ arm_displaced_init_closure (struct gdbarch *gdbarch, CORE_ADDR from,
+ CORE_ADDR to, struct displaced_step_closure *dsc);
+extern ULONGEST
+ displaced_read_reg (struct regcache *regs, CORE_ADDR from, int regno);
+extern void
+ displaced_write_reg (struct regcache *regs,
+ struct displaced_step_closure *dsc, int regno,
+ ULONGEST val, enum pc_write_style write_pc);
CORE_ADDR arm_skip_stub (struct frame_info *, CORE_ADDR);
CORE_ADDR arm_get_next_pc (struct frame_info *, CORE_ADDR);
int arm_software_single_step (struct frame_info *);
+extern struct displaced_step_closure *
+ arm_displaced_step_copy_insn (struct gdbarch *, CORE_ADDR, CORE_ADDR,
+ struct regcache *);
+extern void arm_displaced_step_fixup (struct gdbarch *,
+ struct displaced_step_closure *,
+ CORE_ADDR, CORE_ADDR, struct regcache *);
+
/* Functions exported from armbsd-tdep.h. */
/* Return the appropriate register set for the core section identified