This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
Re: ARM and virtual/raw registers
- From: Richard Earnshaw <rearnsha at arm dot com>
- To: Andrew Cagney <ac131313 at cygnus dot com>
- Cc: Richard dot Earnshaw at arm dot com, gdb at sources dot redhat dot com
- Date: Sun, 12 May 2002 15:10:32 +0100
- Subject: Re: ARM and virtual/raw registers
- Organization: ARM Ltd.
- Reply-to: Richard dot Earnshaw at arm dot com
> Even consider making everything a pseudo so that you know exactly what
> you have at any stage.
>
Hmm, I think this is effectively what I have. See the code below (which is
very much a work-in-progress..., so don't even expect it to compile ;-)
> > I can make my arm_register_read function correctly remap the register
> > numbers, but then I run into the problem that REGISTER_RAW_SIZE is used
> > both above and below the regcache.
>
> I don't understand why this is a problem. I think a register (pseudo or
> raw) should have only one size (c.f. my register_size() patch).
However, in this situation,
pseudo_rengo("r0") != regcache_regno("r0"), yet we effectively have
REGSITER_RAW_SIZE (pseudo_regno ("r0"))
and
REGISTER_RAW_SIZE (regcache_regno ("r0"))
R.
Index: arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.60
diff -p -r1.60 arm-tdep.c
*** arm-tdep.c 9 May 2002 18:07:00 -0000 1.60
--- arm-tdep.c 12 May 2002 14:08:37 -0000
*************** static const char * const arm_abi_names[
*** 113,133 ****
/* Number of different reg name sets (options). */
static int num_flavor_options;
! /* We have more registers than the disassembler as gdb can print the value
! of special registers as well.
! The general register names are overwritten by whatever is being used by
! the disassembler at the moment. We also adjust the case of cpsr and fps. */
!
! /* Initial value: Register names used in ARM's ISA documentation. */
! static char * arm_register_name_strings[] =
! {"r0", "r1", "r2", "r3", /* 0 1 2 3 */
! "r4", "r5", "r6", "r7", /* 4 5 6 7 */
! "r8", "r9", "r10", "r11", /* 8 9 10 11 */
! "r12", "sp", "lr", "pc", /* 12 13 14 15 */
! "f0", "f1", "f2", "f3", /* 16 17 18 19 */
! "f4", "f5", "f6", "f7", /* 20 21 22 23 */
! "fps", "cpsr" }; /* 24 25 */
! static char **arm_register_names = arm_register_name_strings;
/* Valid register name flavors. */
static const char **valid_flavors;
--- 113,275 ----
/* Number of different reg name sets (options). */
static int num_flavor_options;
! /* We have more registers than the disassembler as gdb can print the
! value of special registers as well. It can also display the
! contents of banked registers if these are available from the
! inferior.
!
! Depending on the architecture, ARM processors have up to 31 integer
! registers, but these are banked so that only 16 are visible at any
! one time. The layout of the table is complicated by the fact that
! the ordering must match that used by the compiler to generate
! stabs/dwarf entries, so we put the banked registers first, even
! though we implement some of them as pseudos (mapping onto the
! correct bank entry for the current mode). A debug record entry may
! contain:
!
! 0-15 for the integer registers r0-r15,
! 16-23 for the FPA registers f0-f7,
! 32-63 for the VFP registers s0-s31.
!
! Which leaves a gap of 8 registers in the numbering space: we put
! the cpsr, spsr (x5), fpsr and fpcr registers in this space, though
! not all of these will always be available. None of these registers
! will have debug table entries. [XXX-rwe 20020511 At least, I don't
! think so].
!
! The general register names are overwritten by whatever is being
! used by the disassembler at the moment. We also adjust the case of
! cpsr and fps.
!
! Note, the ordering of registers in the regcache is entirely
! different, since we don't want the pseudo registers in that. The
! mapping tables follow. */
!
!
! struct register_info
! {
! const char *name,
! enum arm_phys_reg regcache,
! enum arm_reg_class regclass
! };
!
! static struct register_info arm_register_info[] =
! {
! { "r0", ARM_PHYS_R0, ARM_REGCLASS_INT },
! { "r1", ARM_PHYS_R1, ARM_REGCLASS_INT },
! { "r2", ARM_PHYS_R2, ARM_REGCLASS_INT },
! { "r3", ARM_PHYS_R3, ARM_REGCLASS_INT },
! { "r4", ARM_PHYS_R4, ARM_REGCLASS_INT },
! { "r5", ARM_PHYS_R5, ARM_REGCLASS_INT },
! { "r6", ARM_PHYS_R6, ARM_REGCLASS_INT },
! { "r7", ARM_PHYS_R7, ARM_REGCLASS_INT },
! /* Pseudos mapping to banked registers. */
! { "r8", ARM_PHYS_NONE, ARM_REGCLASS_INT },
! { "r9", ARM_PHYS_NONE, ARM_REGCLASS_INT },
! { "r10", ARM_PHYS_NONE, ARM_REGCLASS_INT },
! { "r11", ARM_PHYS_NONE, ARM_REGCLASS_INT },
! { "r12", ARM_PHYS_NONE, ARM_REGCLASS_INT },
! { "sp", ARM_PHYS_NONE, ARM_REGCLASS_INT },
! { "lr", ARM_PHYS_NONE, ARM_REGCLASS_INT },
! { "pc", ARM_PHYS_NONE, ARM_REGCLASS_INT },
! /* FPA registers. */
! { "f0", ARM_PHYS_F0, ARM_REGCLASS_FPA },
! { "f1", ARM_PHYS_F1, ARM_REGCLASS_FPA },
! { "f2", ARM_PHYS_F2, ARM_REGCLASS_FPA },
! { "f3", ARM_PHYS_F3, ARM_REGCLASS_FPA },
! { "f4", ARM_PHYS_F4, ARM_REGCLASS_FPA },
! { "f5", ARM_PHYS_F5, ARM_REGCLASS_FPA },
! { "f6", ARM_PHYS_F6, ARM_REGCLASS_FPA },
! { "f7", ARM_PHYS_F7, ARM_REGCLASS_FPA },
! /* PSR type registers (in unused space). */
! { "cpsr", ARM_PHYS_NONE, ARM_REGCLASS_PSR },
! { "spsr_svc", ARM_PHYS_SPSR_SVC, ARM_REGCLASS_PSR },
! { "spsr_abt", ARM_PHYS_SPSR_ABT, ARM_REGCLASS_PSR },
! { "spsr_und", ARM_PHYS_SPSR_UND, ARM_REGCLASS_PSR },
! { "spsr_irq", ARM_PHYS_SPSR_IRQ, ARM_REGCLASS_PSR },
! { "spsr_fiq", ARM_PHYS_SPSR_FIQ, ARM_REGCLASS_PSR },
! { "fpsr", ARM_PHYS_FPSR, ARM_REGCLASS_FPA_FPSR },
! { "fpcr", ARM_PHYS_FPCR, ARM_REGCLASS_FPA_FPCR },
! /* Single precision VFP registers. */
! { "s0", ARM_PHYS_S0, ARM_REGCLASS_VFP_SP },
! { "s1", ARM_PHYS_S1, ARM_REGCLASS_VFP_SP },
! { "s2", ARM_PHYS_S2, ARM_REGCLASS_VFP_SP },
! { "s3", ARM_PHYS_S3, ARM_REGCLASS_VFP_SP },
! { "s4", ARM_PHYS_S4, ARM_REGCLASS_VFP_SP },
! { "s5", ARM_PHYS_S5, ARM_REGCLASS_VFP_SP },
! { "s6", ARM_PHYS_S6, ARM_REGCLASS_VFP_SP },
! { "s7", ARM_PHYS_S7, ARM_REGCLASS_VFP_SP },
! { "s8", ARM_PHYS_S8, ARM_REGCLASS_VFP_SP },
! { "s9", ARM_PHYS_S9, ARM_REGCLASS_VFP_SP },
! { "s10", ARM_PHYS_S10, ARM_REGCLASS_VFP_SP },
! { "s11", ARM_PHYS_S11, ARM_REGCLASS_VFP_SP },
! { "s12", ARM_PHYS_S12, ARM_REGCLASS_VFP_SP },
! { "s13", ARM_PHYS_S13, ARM_REGCLASS_VFP_SP },
! { "s14", ARM_PHYS_S14, ARM_REGCLASS_VFP_SP },
! { "s15", ARM_PHYS_S15, ARM_REGCLASS_VFP_SP },
! { "s16", ARM_PHYS_S16, ARM_REGCLASS_VFP_SP },
! { "s17", ARM_PHYS_S17, ARM_REGCLASS_VFP_SP },
! { "s18", ARM_PHYS_S18, ARM_REGCLASS_VFP_SP },
! { "s19", ARM_PHYS_S19, ARM_REGCLASS_VFP_SP },
! { "s20", ARM_PHYS_S20, ARM_REGCLASS_VFP_SP },
! { "s21", ARM_PHYS_S21, ARM_REGCLASS_VFP_SP },
! { "s22", ARM_PHYS_S22, ARM_REGCLASS_VFP_SP },
! { "s23", ARM_PHYS_S23, ARM_REGCLASS_VFP_SP },
! { "s24", ARM_PHYS_S24, ARM_REGCLASS_VFP_SP },
! { "s25", ARM_PHYS_S25, ARM_REGCLASS_VFP_SP },
! { "s26", ARM_PHYS_S26, ARM_REGCLASS_VFP_SP },
! { "s27", ARM_PHYS_S27, ARM_REGCLASS_VFP_SP },
! { "s28", ARM_PHYS_S28, ARM_REGCLASS_VFP_SP },
! { "s29", ARM_PHYS_S29, ARM_REGCLASS_VFP_SP },
! { "s30", ARM_PHYS_S30, ARM_REGCLASS_VFP_SP },
! { "s31", ARM_PHYS_S31, ARM_REGCLASS_VFP_SP },
! /* Double precision pseudo views of the above. */
! { "d0", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! { "d1", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! { "d2", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! { "d3", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! { "d4", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! { "d5", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! { "d6", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! { "d7", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! { "d8", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! { "d9", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! { "d10", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! { "d11", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! { "d12", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! { "d13", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! { "d14", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! { "d15", ARM_PHYS_NONE, ARM_REGCLASS_VFP_DP },
! /* VFP status registers. */
! { "fpsid" ARM_PHYS_FPSID, ARM_REGCLASS_VFP_FPSID },
! { "fpscr", ARM_PHYS_FPSCR, ARM_REGCLASS_VFP_FPSCR },
! { "fpexc", ARM_PHYS_FPEXC, ARM_REGCLASS_VFP_FPEXC },
! /* Banked registers. */
! { "r8_usr", ARM_PHYS_R8_USR, ARM_REGCLASS_INT },
! { "r9_usr", ARM_PHYS_R9_USR, ARM_REGCLASS_INT },
! { "r10_usr", ARM_PHYS_R10_USR, ARM_REGCLASS_INT },
! { "r11_usr", ARM_PHYS_R11_USR, ARM_REGCLASS_INT },
! { "r12_usr", ARM_PHYS_R12_USR, ARM_REGCLASS_INT },
! { "r13_usr", ARM_PHYS_R13_USR, ARM_REGCLASS_INT },
! { "r14_usr", ARM_PHYS_R14_USR, ARM_REGCLASS_INT },
! { "r15_raw", ARM_PHYS_R15, ARM_REGCLASS_INT },
! { "r13_svc", ARM_PHYS_R13_SVC, ARM_REGCLASS_INT },
! { "r14_svc", ARM_PHYS_R14_SVC, ARM_REGCLASS_INT },
! { "r13_abt", ARM_PHYS_R13_ABT, ARM_REGCLASS_INT },
! { "r14_abt", ARM_PHYS_R14_ABT, ARM_REGCLASS_INT },
! { "r13_und", ARM_PHYS_R13_UND, ARM_REGCLASS_INT },
! { "r14_und", ARM_PHYS_R14_UND, ARM_REGCLASS_INT },
! { "r13_irq", ARM_PHYS_R13_IRQ, ARM_REGCLASS_INT },
! { "r14_irq", ARM_PHYS_R14_IRQ, ARM_REGCLASS_INT },
! { "r8_fiq", ARM_PHYS_R8_FIQ, ARM_REGCLASS_INT },
! { "r9_fiq", ARM_PHYS_R9_FIQ, ARM_REGCLASS_INT },
! { "r10_fiq", ARM_PHYS_R10_FIQ, ARM_REGCLASS_INT },
! { "r11_fiq", ARM_PHYS_R11_FIQ, ARM_REGCLASS_INT },
! { "r12_fiq", ARM_PHYS_R12_FIQ, ARM_REGCLASS_INT },
! { "r13_fiq", ARM_PHYS_R13_FIQ, ARM_REGCLASS_INT },
! { "r14_fiq", ARM_PHYS_R14_FIQ, ARM_REGCLASS_INT },
! { "spsr" ARM_PHYS_NONE, ARM_REGCLASS_PSR },
! };
/* Valid register name flavors. */
static const char **valid_flavors;
*************** arm_print_float_info (void)
*** 1596,1627 ****
static struct type *
arm_register_type (int regnum)
{
! if (regnum >= ARM_F0_REGNUM && regnum < ARM_F0_REGNUM + NUM_FREGS)
{
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
return builtin_type_arm_ext_big;
else
return builtin_type_arm_ext_littlebyte_bigword;
- }
- else
- return builtin_type_int32;
- }
! /* Index within `registers' of the first byte of the space for
! register N. */
! static int
! arm_register_byte (int regnum)
! {
! if (regnum < ARM_F0_REGNUM)
! return regnum * INT_REGISTER_RAW_SIZE;
! else if (regnum < ARM_PS_REGNUM)
! return (NUM_GREGS * INT_REGISTER_RAW_SIZE
! + (regnum - ARM_F0_REGNUM) * FP_REGISTER_RAW_SIZE);
! else
! return (NUM_GREGS * INT_REGISTER_RAW_SIZE
! + NUM_FREGS * FP_REGISTER_RAW_SIZE
! + (regnum - ARM_FPS_REGNUM) * STATUS_REGISTER_SIZE);
}
/* Number of bytes of storage in the actual machine representation for
--- 1738,1766 ----
static struct type *
arm_register_type (int regnum)
{
! switch (arm_register_info[regnum].class)
{
+ case ARM_REGCLASS_FPA:
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
return builtin_type_arm_ext_big;
else
return builtin_type_arm_ext_littlebyte_bigword;
! case ARM_REGCLASS_VFP_SP:
! if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
! return builtin_type_ieee_double_big;
! else
! return builtin_type_ieee_double_little;
! case ARM_REGCLASS_VFP_DP:
! if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
! return builtin_type_ieee_single_big;
! else
! return builtin_type_ieee_single_little;
!
! default:
! return builtin_type int32;
! }
}
/* Number of bytes of storage in the actual machine representation for
*************** arm_register_byte (int regnum)
*** 1629,1657 ****
12 bytes in length. */
static int
! arm_register_raw_size (int regnum)
{
! if (regnum < ARM_F0_REGNUM)
! return INT_REGISTER_RAW_SIZE;
! else if (regnum < ARM_FPS_REGNUM)
! return FP_REGISTER_RAW_SIZE;
! else
! return STATUS_REGISTER_SIZE;
}
! /* Number of bytes of storage in a program's representation
! for register N. */
static int
! arm_register_virtual_size (int regnum)
{
! if (regnum < ARM_F0_REGNUM)
! return INT_REGISTER_VIRTUAL_SIZE;
! else if (regnum < ARM_FPS_REGNUM)
! return FP_REGISTER_VIRTUAL_SIZE;
! else
! return STATUS_REGISTER_SIZE;
}
/* NOTE: cagney/2001-08-20: Both convert_from_extended() and
convert_to_extended() use floatformat_arm_ext_littlebyte_bigword.
--- 1768,1949 ----
12 bytes in length. */
static int
! arm_register_size (int regnum)
{
! switch (arm_register_info[regnum].class)
! {
! case ARM_REGCLASS_INT:
! return INT_REGISTER_SIZE;
! case ARM_REGCLASS_FPA:
! return FPA_REGISTER_SIZE;
! case ARM_REGCLASS_VFP_SP:
! return VFP_SP_REGISTER_SIZE;
! case ARM_REGCLASS_VFP_DP:
! return VFP_DP_REGISTER_SIZE;
! default:
! return STATUS_REGISTER_SIZE;
! }
}
! /* Index within the regcache of the first byte of the space for
! register N.
! NOTE: calling this with regnum == ARM_PHYS_NUM_REGS will give the
! size of the regcache. */
!
static int
! arm_register_byte (int regnum)
{
! static int *reg_offsets = 0;
!
! if (reg_offsets == 0)
! {
! int i;
! int offset = 0;
!
! reg_offset = (int *) xmalloc ((1 + ARM_PHYS_NUM_REGS) * sizeof (int));
!
! for (i = 0; i <= ARM_PHYS_NUM_REGS; i++)
! {
! reg_offset[i] = offset;
! offset += arm_register_size (i);
! }
! }
!
! return reg_offset[i];
! }
!
! /* Construct a pseudo register. */
! static void
! arm_pseudo_register_read (struct gdbarch *gdbarch, int regno, char *buffer)
! {
! switch (arm_register_info[regno].regclass)
! {
! case ARM_REGCLASS_INT:
! switch (read_register (ARM_PS_REGNUM) & PSR_MODE_MASK)
! {
! case MODE_FIQ32:
! case MODE_FIQ26:
! regcache_read (ARM_PHYS_R8_FIQ + (regno - ARM_R8_REGNUM), buffer);
! break;
!
! case MODE_IRQ32:
! case MODE_IRQ26:
! if (regno == ARM_SP_REGNUM || regno == ARM_LR_REGNUM)
! {
! regcache_read (ARM_PHYS_R13_IRQ + (regno - ARM_SP_REGNUM),
! buffer);
! break;
! }
! /* Fall through. */
!
! case MODE_SVC32:
! case MODE_SVC26:
! if (regno == ARM_SP_REGNUM || regno == ARM_LR_REGNUM)
! {
! regcache_read (ARM_PHYS_R13_SVC + (regno - ARM_SP_REGNUM),
! buffer);
! break;
! }
! /* Fall through. */
!
! case MODE_ABT:
! if (regno == ARM_SP_REGNUM || regno == ARM_LR_REGNUM)
! {
! regcache_read (ARM_PHYS_R13_ABT + (regno - ARM_SP_REGNUM),
! buffer);
! break;
! }
! /* Fall through. */
!
! case MODE_UND:
! if (regno == ARM_SP_REGNUM || regno == ARM_LR_REGNUM)
! {
! regcache_read (ARM_PHYS_R13_UND + (regno - ARM_SP_REGNUM),
! buffer);
! break;
! }
! /* Fall through. */
!
! default: /* Everything else reads from the user bank.
! regcache_read (ARM_PHYS_R8_USR + (regno - ARM_R8_REGNUM), buffer);
! break;
!
! }
! break;
!
! case ARM_REGCLASS_PSR:
! /* Two cases to handle here. The CPSR and the SPSR.
! The CPSR will either be in the physical register, or part of the
! PC. We look at the APCS mode to determine which.
!
! The SPSR may not exist if the current mode is not privilaged (or it
! is System mode). To determine that we need to look at the CPSR. */
! if (regno == ARM_PS_REGNUM) /* CPSR. */
! {
! if (arm_apcs_32)
! regcache_read (ARM_PHYS_CPSR, buffer);
! else
! {
! LONGEST cpsr_bits;
!
! regcache_read (ARM_PHYS_R15, buffer);
! cpsr_bits
! = (extract_unsigned_integer (buffer, STATUS_REGISTER_SIZE)
! & APCS_26_PS_MASK);
!
! store_signed_integer (buffer, STATUS_REGISTER_SIZE, cpsr_bits);
! }
! }
! else
! {
! gdb_assert (regnum == ARM_SPSR_REGNUM);
!
! switch (read_register (ARM_PS_REGNUM) & PSR_MODE_MASK)
! {
! case MODE_FIQ32:
! regcache_read (ARM_PHYS_SPSR_FIQ, buffer);
! break;
! case MODE_IRQ32:
! regcache_read (ARM_PHYS_SPSR_IRQ, buffer);
! break;
! case MODE_SVC32:
! regcache_read (ARM_PHYS_SPSR_SVC, buffer);
! break;
! case MODE_ABT:
! regcache_read (ARM_PHYS_SPSR_ABT, buffer);
! break;
! case MODE_UND:
! regcache_read (ARM_PHYS_SPSR_UND, buffer);
! break;
! default:
! store_signed_integer (buffer, STATUS_REGISTER_SIZE, (LONGEST) 0);
! break;
! }
! }
! break;
!
! case ARM_REGCLASS_VFP_DP:
! /* XXX Fixme: suppor these pseudos. */
! break;
!
! default:
! internal_error
! (__FILE__, __LINE__,
! "arm_pseudo_register_read: Invalid class for pseudo register %s",
! REGISTER_NAME(regno));
! }
}
+ /* Read a register, either directly from the regcache, or by constructing
+ it from other registers. */
+ static void
+ arm_register_read (struct gdbarch *gdbarch, int regno, char *buffer)
+ {
+ if (arm_register_info[regno].regcache != ARM_PHYS_NONE)
+ regcache_read (regno, buffer);
+ else
+ arm_pseudo_register_read (gdbarch, regno, buffer);
+ }
/* NOTE: cagney/2001-08-20: Both convert_from_extended() and
convert_to_extended() use floatformat_arm_ext_littlebyte_bigword.
*************** set_disassembly_flavor_sfunc (char *args
*** 2475,2481 ****
static char *
arm_register_name (int i)
{
! return arm_register_names[i];
}
static void
--- 2767,2773 ----
static char *
arm_register_name (int i)
{
! return arm_register_info[i].name;
}
static void
*************** arm_gdbarch_init (struct gdbarch_info in
*** 3014,3028 ****
set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);
set_gdbarch_pc_regnum (gdbarch, ARM_PC_REGNUM);
set_gdbarch_register_byte (gdbarch, arm_register_byte);
! set_gdbarch_register_bytes (gdbarch,
! (NUM_GREGS * INT_REGISTER_RAW_SIZE
! + NUM_FREGS * FP_REGISTER_RAW_SIZE
! + NUM_SREGS * STATUS_REGISTER_SIZE));
! set_gdbarch_num_regs (gdbarch, NUM_GREGS + NUM_FREGS + NUM_SREGS);
! set_gdbarch_register_raw_size (gdbarch, arm_register_raw_size);
! set_gdbarch_register_virtual_size (gdbarch, arm_register_virtual_size);
! set_gdbarch_max_register_raw_size (gdbarch, FP_REGISTER_RAW_SIZE);
! set_gdbarch_max_register_virtual_size (gdbarch, FP_REGISTER_VIRTUAL_SIZE);
set_gdbarch_register_virtual_type (gdbarch, arm_register_type);
/* Integer registers are 4 bytes. */
--- 3306,3317 ----
set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);
set_gdbarch_pc_regnum (gdbarch, ARM_PC_REGNUM);
set_gdbarch_register_byte (gdbarch, arm_register_byte);
! set_gdbarch_register_bytes (gdbarch, arm_register_byte(ARM_PHYS_NUM_REGS));
! set_gdbarch_num_regs (gdbarch, ARM_PHYS_NUM_REGS);
! set_gdbarch_register_raw_size (gdbarch, arm_register_size);
! set_gdbarch_register_virtual_size (gdbarch, arm_register_size);
! set_gdbarch_max_register_raw_size (gdbarch, ARM_MAX_REGISTER_SIZE);
! set_gdbarch_max_register_virtual_size (gdbarch, ARM_MAX_REGISTER_SIZE);
set_gdbarch_register_virtual_type (gdbarch, arm_register_type);
/* Integer registers are 4 bytes. */
Index: arm-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.h,v
retrieving revision 1.8
diff -p -r1.8 arm-tdep.h
*** arm-tdep.h 7 May 2002 12:58:51 -0000 1.8
--- arm-tdep.h 12 May 2002 14:08:37 -0000
***************
*** 28,33 ****
--- 28,34 ----
enum gdb_regnum {
ARM_A1_REGNUM = 0, /* first integer-like argument */
ARM_A4_REGNUM = 3, /* last integer-like argument */
+ ARM_R8_REGNUM = 8, /* First banked register */
ARM_AP_REGNUM = 11,
ARM_SP_REGNUM = 13, /* Contains address of top of stack */
ARM_LR_REGNUM = 14, /* address to return to from a function call */
*************** enum gdb_regnum {
*** 35,42 ****
ARM_F0_REGNUM = 16, /* first floating point register */
ARM_F3_REGNUM = 19, /* last floating point argument register */
ARM_F7_REGNUM = 23, /* last floating point register */
! ARM_FPS_REGNUM = 24, /* floating point status register */
! ARM_PS_REGNUM = 25, /* Contains processor status */
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,
--- 36,43 ----
ARM_F0_REGNUM = 16, /* first floating point register */
ARM_F3_REGNUM = 19, /* last floating point argument register */
ARM_F7_REGNUM = 23, /* last floating point register */
! ARM_PS_REGNUM = 24, /* Contains processor status */
! ARM_FPS_REGNUM = 31, /* floating point status register */
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,
*************** enum gdb_regnum {
*** 45,86 ****
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
! /* 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
- /* Number of machine registers. The only define actually required
- is 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
- from the PC (register 15). For 32 bit ARM code, a copy of CPSR is placed
- in PS. */
- #define NUM_FREGS 8 /* Number of floating point registers. */
- #define NUM_SREGS 2 /* Number of status registers. */
- #define NUM_GREGS 16 /* Number of general purpose registers. */
-
-
/* Instruction condition field values. */
#define INST_EQ 0x0
#define INST_NE 0x1
--- 46,125 ----
ARM_LAST_FP_ARG_REGNUM = ARM_F3_REGNUM
};
+ /* Indecees of the registers in the regcache. Note that this effectively
+ determines the order of these registers in the cache. arm_regcache_read
+ will perform a mapping between these and the virtual index so that debug
+ formats like stabs will see the registers in the right place. */
+ enum arm_phys_reg {
+ ARM_PHYS_NONE= -1,
+
+ ARM_PHYS_R0 = 0, ARM_PHYS_R1, ARM_PHYS_R2, ARM_PHYS_R3,
+ ARM_PHYS_R4, ARM_PHYS_R5, ARM_PHYS_R6, ARM_PHYS_R7,
+
+ ARM_PHYS_R8_USR, ARM_PHYS_R9_USR, ARM_PHYS_R10_USR, ARM_PHYS_R11_USR,
+ ARM_PHYS_R12_USR, ARM_PHYS_R13_USR, ARM_PHYS_R14_USR, ARM_PHYS_R15,
+
+ ARM_PHYS_R13_SVC, ARM_PHYS_R14_SVC, ARM_PHYS_SPSR_SVC,
+ ARM_PHYS_R13_ABT, ARM_PHYS_R14_ABT, ARM_PHYS_SPSR_ABT,
+ ARM_PHYS_R13_UND, ARM_PHYS_R14_UND, ARM_PHYS_SPSR_UND,
+ ARM_PHYS_R13_IRQ, ARM_PHYS_R14_IRQ, ARM_PHYS_SPSR_IRQ,
+
+ ARM_PHYS_R8_FIQ, ARM_PHYS_R9_FIQ, ARM_PHYS_R10_FIQ, ARM_PHYS_R11_FIQ,
+ ARM_PHYS_R12_FIQ, ARM_PHYS_R13_FIQ, ARM_PHYS_R14_FIQ, ARM_PHYS_SPSR_FIQ,
+
+ ARM_PHYS_CPSR,
+
+ ARM_PHYS_F0, ARM_PHYS_F1, ARM_PHYS_F2, ARM_PHYS_F3,
+ ARM_PHYS_F4, ARM_PHYS_F5, ARM_PHYS_F6, ARM_PHYS_F7,
+
+ ARM_PHYS_FPSR, ARM_PHYS_FPCR,
+
+ ARM_PHYS_S0, ARM_PHYS_S1, ARM_PHYS_S2, ARM_PHYS_S3,
+ ARM_PHYS_S4, ARM_PHYS_S5, ARM_PHYS_S6, ARM_PHYS_S7,
+ ARM_PHYS_S8, ARM_PHYS_S9, ARM_PHYS_S10, ARM_PHYS_S11,
+ ARM_PHYS_S12, ARM_PHYS_S13, ARM_PHYS_S14, ARM_PHYS_S15,
+ ARM_PHYS_S16, ARM_PHYS_S17, ARM_PHYS_S18, ARM_PHYS_S19,
+ ARM_PHYS_S20, ARM_PHYS_S21, ARM_PHYS_S22, ARM_PHYS_S23,
+ ARM_PHYS_S24, ARM_PHYS_S25, ARM_PHYS_S26, ARM_PHYS_S27,
+ ARM_PHYS_S28, ARM_PHYS_S29, ARM_PHYS_S30, ARM_PHYS_S31,
+
+ ARM_PHYS_FPSID, ARM_PHYS_FPSCR, ARM_PHYS_FPEXC,
+
+ /* Keep last. */
+ ARM_PHYS_NUM_REGS
+ };
+
+ enum arm_reg_class
+ {
+ ARM_REGCLASS_INT, ARM_REGCLASS_PSR,
+
+ ARM_REGCLASS_FPA, ARM_REGCLASS_FPA_FPSR, ARM_REGCLASS_FPA_FPCR,
+
+ ARM_REGCLASS_VFP_SP, ARM_REGCLASS_VFP_DP, ARM_REGCLASS_VFP_FPSID,
+ ARM_REGCLASS_VFP_FPSCR, ARM_REGCLASS_VFP_FPEXC
+ };
+
/* 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_SIZE FPA_REGISTER_SIZE
/* Size of integer registers. */
! #define INT_REGISTER_SIZE 4
! /* Say how long FPA 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 FPA_REGISTER_SIZE 12
! /* Size of VFP SP and DP registers. */
! #define VFP_SP_REGISTER_SIZE 4
! #define VFP_DP_REGISTER_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
/* Instruction condition field values. */
#define INST_EQ 0x0
#define INST_NE 0x1
*************** enum gdb_regnum {
*** 103,108 ****
--- 142,165 ----
#define FLAG_Z 0x40000000
#define FLAG_C 0x20000000
#define FLAG_V 0x10000000
+
+ #define PSR_MODE_MASK 0x00000011
+
+ #define MODE_USR32 0x00000010
+ #define MODE_FIQ32 0x00000011
+ #define MODE_IRQ32 0x00000012
+ #define MODE_SVC32 0x00000013
+ #define MODE_ABT 0x00000017
+ #define MODE_UND 0x0000001b
+ #define MODE_SYS 0x0000001f
+ #define MODE_USR26 0x00000000
+ #define MODE_FIQ26 0x00000001
+ #define MODE_IRQ26 0x00000002
+ #define MODE_SVC26 0x00000003
+
+ #define APCS_26_PC_MASK 0x03fffffc
+ #define APCS_26_PS_MASK (~APCS_26_PC_MASK)
+
/* ABI variants that we know about. If you add to this enum, please
update the table of names in tm-arm.c. */