This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Support functions for splitting PC and PSR on 26-bit ARMs


The following patch is intended to provide standard functions to allow ARM
targets of GDB to split R15 on 26-bit ARM machines into the PC and PSR
used on newer ARMs.  This effectively re-implements code in
arm-linux-nat.c (fetch_register, fetch_regs, store_register, store_regs),
but better.

The forthcoming NetBSD/arm target will use this code.  If all the other
26-bit ARM targets (only ARM Linux now, I think) do so, then we can
probably get rid of arm_apcs_32 and infer the processor mode from the PSR.

ChangeLog entry:

2001-10-29  Ben Harris  <bjh21@netbsd.org>

	* arm-tdep.h, config/arm/tm-arm.h [ARM_26BIT_R15]
	(arm_supply_26bit_r15, arm_read_26bit_r15): New functions

Patch (based on NetBSD-current GDB 5.0.  I don't think the trunk is very
different):

Index: arm-tdep.c
===================================================================
RCS file: /cvsroot/gnusrc/gnu/dist/toolchain/gdb/arm-tdep.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- arm-tdep.c	2001/10/22 21:09:47	1.6
+++ arm-tdep.c	2001/10/29 20:37:59	1.7
@@ -278,6 +278,49 @@
     return (val & 0xfffffffc);
 }

+#ifdef ARM_26BIT_R15
+#define R15_PC		0x03fffffc
+#define R15_PSR_DIRECT	0xf0000003 /* Bits in the same places in R15 & PSR */
+#define R15_IF		0x0c000000 /* Bits which must be shifted... */
+#define PSR_IF		0x000000c0
+#define IF_SHIFT	20	   /* ... by this much */
+
+/* Functions to unpack and pack R15 on 26-bit ARMs.  Within GDB, R15
+   is always stored with the program counter in PC_REGNUM, and the
+   flags in PS_REGNUM.  PS_REGNUM has the I and F flags in their
+   32-bit positions.  Targets can use these functions to convert
+   between this format and the format used on 26-bit processors, where
+   the PC and PSR are packed into R15. */
+
+void
+arm_supply_26bit_r15 (char *val)
+{
+  ULONGEST r15, pc, psr;
+  char rawpc[4], rawpsr[4];
+
+  r15 = extract_unsigned_integer (val, 4);
+
+  pc = r15 & R15_PC;
+  store_unsigned_integer (rawpc, 4, pc);
+  supply_register (PC_REGNUM, rawpc);
+
+  psr = (r15 & R15_PSR_DIRECT) | ((r15 & R15_IF) >> IF_SHIFT);
+  store_unsigned_integer (rawpsr, 4, psr);
+  supply_register (PS_REGNUM, rawpsr);
+}
+
+void
+arm_read_26bit_r15 (char *myaddr)
+{
+  ULONGEST r15, pc, psr;
+
+  pc = read_register (PC_REGNUM);
+  psr = read_register (PS_REGNUM);
+  r15 = pc | (psr & R15_PSR_DIRECT) | ((psr & PSR_IF) << IF_SHIFT);
+  store_unsigned_integer (myaddr, r15, 4);
+}
+#endif
+
 CORE_ADDR
 arm_saved_pc_after_call (struct frame_info *frame)
 {
Index: config/arm/tm-arm.h
===================================================================
RCS file: /cvsroot/gnusrc/gnu/dist/toolchain/gdb/config/arm/tm-arm.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- config/arm/tm-arm.h	2001/10/22 19:07:10	1.3
+++ config/arm/tm-arm.h	2001/10/29 20:38:00	1.4
@@ -47,6 +47,12 @@

 #define ADDR_BITS_REMOVE(val)	(arm_addr_bits_remove (val))

+#ifdef ARM_26BIT_R15
+/* Functions to unpack and pack R15 on 26-bit ARMs. */
+void arm_supply_26bit_r15 (char *);
+void arm_read_26bit_r15 (char *);
+#endif
+
 /* Offset from address of function to start of its code.  Zero on most
    machines.  */


-- 
Ben Harris                                                   <bjh21@netbsd.org>
Portmaster, NetBSD/arm26               <URL:http://www.netbsd.org/Ports/arm26/>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]