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. */