2010-04-12 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
[deliverable/binutils-gdb.git] / gdb / arm-tdep.h
index 5fa8b62d3828055d7e0c765c9f95164435387a1b..b6283efb91c0110c876202ca5990a05765a3501c 100644 (file)
@@ -1,5 +1,6 @@
 /* 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, 2010
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -29,6 +30,7 @@ enum gdb_regnum {
   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 */
@@ -46,6 +48,9 @@ enum gdb_regnum {
   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_FPSCR_REGNUM,
 
   ARM_NUM_REGS,
 
@@ -66,11 +71,6 @@ enum gdb_regnum {
    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.  */
@@ -106,6 +106,8 @@ enum gdb_regnum {
 #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
@@ -153,15 +155,29 @@ struct gdbarch_tdep
   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.  */
 
   const char *arm_breakpoint;  /* Breakpoint pattern for an ARM insn.  */
   int arm_breakpoint_size;     /* And its size.  */
-  const char *thumb_breakpoint;        /* Breakpoint pattern for an ARM insn.  */
+  const char *thumb_breakpoint;        /* Breakpoint pattern for a Thumb insn.  */
   int thumb_breakpoint_size;   /* And its size.  */
 
+  /* If the Thumb breakpoint is an undefined instruction (which is
+     affected by IT blocks) rather than a BKPT instruction (which is
+     not), then we need a 32-bit Thumb breakpoint to preserve the
+     instruction count in IT blocks.  */
+  const char *thumb2_breakpoint;
+  int thumb2_breakpoint_size;
+
   int jb_pc;                   /* Offset to PC value in jump buffer. 
                                   If this is negative, longjmp support
                                   will be disabled.  */
@@ -172,17 +188,120 @@ struct gdbarch_tdep
 
   /* 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 *);
 };
 
+/* 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
+};
 
-#ifndef LOWEST_PC
-#define LOWEST_PC (gdbarch_tdep (current_gdbarch)->lowest_pc)
-#endif
+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
This page took 0.02778 seconds and 4 git commands to generate.