X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=gdb%2Farm-tdep.h;h=7abfcd7615d2ba9ff8454c48be71ad4167a27e9c;hb=0963b4bd458eab010b3b19c9ffd8eb790f2cd06c;hp=a8f15148364ca1e48c30a5d10713c1f0c8bf4e1e;hpb=2ee563b53258d390d7446e90a67f465d504ae44c;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h index a8f1514836..7abfcd7615 100644 --- a/gdb/arm-tdep.h +++ b/gdb/arm-tdep.h @@ -1,11 +1,12 @@ /* Common target dependent code for GDB on ARM systems. - Copyright 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,23 +15,22 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ -#include "osabi.h" +#ifndef ARM_TDEP_H +#define ARM_TDEP_H -/* Register numbers of various important registers. Note that some of - these values are "real" register numbers, and correspond to the - general registers of the machine, and some are "phony" register - numbers which are too large to be actual register numbers as far as - the user is concerned but do serve to get the desired values when - passed to read_register. */ +/* Forward declarations. */ +struct gdbarch; +struct regset; + +/* Register numbers of various important registers. */ 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 */ @@ -39,6 +39,22 @@ enum gdb_regnum { ARM_F7_REGNUM = 23, /* last floating point register */ ARM_FPS_REGNUM = 24, /* floating point status register */ ARM_PS_REGNUM = 25, /* Contains processor status */ + ARM_WR0_REGNUM, /* WMMX data registers. */ + ARM_WR15_REGNUM = ARM_WR0_REGNUM + 15, + ARM_WC0_REGNUM, /* WMMX control registers. */ + ARM_WCSSF_REGNUM = ARM_WC0_REGNUM + 2, + ARM_WCASF_REGNUM = ARM_WC0_REGNUM + 3, + ARM_WC7_REGNUM = ARM_WC0_REGNUM + 7, + 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, + + /* Other useful registers. */ ARM_FP_REGNUM = 11, /* Frame register in ARM code, if used. */ THUMB_FP_REGNUM = 7, /* Frame register in Thumb code, if used. */ ARM_NUM_ARG_REGS = 4, @@ -47,32 +63,16 @@ enum gdb_regnum { ARM_LAST_FP_ARG_REGNUM = ARM_F3_REGNUM }; -/* Used in target-specific code when we need to know the size of the - largest type of register we need to handle. */ -#define ARM_MAX_REGISTER_RAW_SIZE 12 -#define ARM_MAX_REGISTER_VIRTUAL_SIZE 8 - /* Size of integer registers. */ -#define INT_REGISTER_RAW_SIZE 4 -#define INT_REGISTER_VIRTUAL_SIZE 4 +#define INT_REGISTER_SIZE 4 /* Say how long FP registers are. Used for documentation purposes and code readability in this header. IEEE extended doubles are 80 bits. DWORD aligned they use 96 bits. */ -#define FP_REGISTER_RAW_SIZE 12 - -/* GCC doesn't support long doubles (extended IEEE values). The FP - register virtual size is therefore 64 bits. Used for documentation - purposes and code readability in this header. */ -#define FP_REGISTER_VIRTUAL_SIZE 8 - -/* 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 +#define FP_REGISTER_SIZE 12 /* Number of machine registers. The only define actually required - is NUM_REGS. The other definitions are used for documentation + is gdbarch_num_regs. The other definitions are used for documentation purposes and code readability. */ /* For 26 bit ARM code, a fake copy of the PC is placed in register 25 (PS) (and called PS for processor status) so the status bits can be cleared @@ -106,51 +106,217 @@ enum gdb_regnum { #define FLAG_C 0x20000000 #define FLAG_V 0x10000000 +#define CPSR_T 0x20 + +#define XPSR_T 0x01000000 + /* 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 functions are passed in floating-point registers. - In addition to the traditional models, VFP adds two more. */ + In addition to the traditional models, VFP adds two more. + + If you update this enum, don't forget to update fp_model_strings in + arm-tdep.c. */ enum arm_float_model { - ARM_FLOAT_SOFT, - ARM_FLOAT_FPA, - ARM_FLOAT_SOFT_VFP, - ARM_FLOAT_VFP + ARM_FLOAT_AUTO, /* Automatic detection. Do not set in tdep. */ + ARM_FLOAT_SOFT_FPA, /* Traditional soft-float (mixed-endian on LE ARM). */ + ARM_FLOAT_FPA, /* FPA co-processor. GCC calling convention. */ + ARM_FLOAT_SOFT_VFP, /* Soft-float with pure-endian doubles. */ + ARM_FLOAT_VFP, /* Full VFP calling convention. */ + ARM_FLOAT_LAST /* Keep at end. */ +}; + +/* ABI used by the inferior. */ +enum arm_abi_kind +{ + ARM_ABI_AUTO, + ARM_ABI_APCS, + ARM_ABI_AAPCS, + ARM_ABI_LAST +}; + +/* Convention for returning structures. */ + +enum struct_return +{ + pcc_struct_return, /* Return "short" structures in memory. */ + reg_struct_return /* Return "short" structures in registers. */ }; /* Target-dependent structure in gdbarch. */ struct gdbarch_tdep { - enum gdb_osabi osabi; /* OS/ABI of inferior. */ + /* The ABI for this architecture. It should never be set to + ARM_ABI_AUTO. */ + enum arm_abi_kind arm_abi; 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? */ + + int is_m; /* Does the target follow the "M" profile. */ 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. */ - int jb_pc; /* Offset to PC value in jump buffer. + /* 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. */ size_t jb_elt_size; /* And the size of each entry in the buf. */ + + /* Convention for returning structures. */ + enum struct_return struct_return; + + /* 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; + + /* Return the expected next PC if FRAME is stopped at a syscall + instruction. */ + CORE_ADDR (*syscall_next_pc) (struct frame_info *frame); +}; + +/* 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 *); +int arm_frame_is_thumb (struct frame_info *frame); + +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 *); -/* Prototypes for internal interfaces needed by more than one MD file. */ -int arm_pc_is_thumb_dummy (CORE_ADDR); +/* Functions exported from armbsd-tdep.h. */ -int arm_pc_is_thumb (CORE_ADDR); +/* Return the appropriate register set for the core section identified + by SECT_NAME and SECT_SIZE. */ -CORE_ADDR thumb_get_next_pc (CORE_ADDR); +extern const struct regset * + armbsd_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, size_t sect_size); -CORE_ADDR arm_get_next_pc (CORE_ADDR); +#endif /* arm-tdep.h */