1 /// -*- mode: asm; asm-comment-char: ?/ -*-
3 /// Register dump and debugging for 32-bit ARM
5 /// (c) 2019 Straylight/Edgeware
8 ///----- Licensing notice ---------------------------------------------------
10 /// This file is part of Catacomb.
12 /// Catacomb is free software: you can redistribute it and/or modify it
13 /// under the terms of the GNU Library General Public License as published
14 /// by the Free Software Foundation; either version 2 of the License, or
15 /// (at your option) any later version.
17 /// Catacomb is distributed in the hope that it will be useful, but
18 /// WITHOUT ANY WARRANTY; without even the implied warranty of
19 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 /// Library General Public License for more details.
22 /// You should have received a copy of the GNU Library General Public
23 /// License along with Catacomb. If not, write to the Free Software
24 /// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
27 ///--------------------------------------------------------------------------
31 #include "asm-common.h"
39 ///--------------------------------------------------------------------------
44 // On entry, r13 should point to `REGDUMP_GPSIZE' bytes of
45 // word-aligned storage to be the general-purpose save area, with r12
46 // and r14 already saved. On exit, the initial registers are saved
47 // in this space, and modified: r4 points to the general-purpose save
48 // area, r6 holds the focus address (possibly already saved), r0
49 // contains the number of bytes required in the extended save area,
50 // and other general-purpose registers are clobbered or used to
51 // communicate with `regdump_xtsave' below. Doing anything other
52 // than lowering the stack pointer and calling `regdump_xtsave' is
55 // Save the easy registers.
59 // Determine the previous stack pointer and save it.
60 add r0, r4, #REGDUMP_GPSIZE
63 // Clear the magic Thumb-state bit from the return address.
67 // Load the focus address and save it as r6.
68 ldr r6, [r4, #4*REGIX_ADDR]
70 // Determine the extended save area size.
73 leaext r12, regdump__flags
76 addne r0, r0, #REGDUMP_FPSIZE_D16
78 addne r0, r0, #REGDUMP_FPSIZE_D32 - REGDUMP_FPSIZE_D16
87 // On entry, r4 points to a general-purpose save area, established by
88 // `regdump_gpsave'. On exit, the general-purpose registers (other
89 // than r13 and r14) are restored to their original values.
91 // Restore the processor flags.
92 ldr r0, [r4, #4*REGIX_CPSR]
95 // Load the easy registers.
105 // On entry, r13 points to an extended save area, of size determined
106 // by `regdump_gpsave' above. On exit, the save area is filled in
107 // and a handy map placed at its base.
109 // Set up the map/extended save area pointer.
113 // Start by filling in the easy part of the map.
114 str r4, [r5, #regmap_gp]
116 // Fetch the flags explaining what to do.
118 leaext r12, regdump__flags
121 // Figure out whether there are VFP/NEON registers.
124 addne r3, r5, #regmap_size
125 str r3, [r5, #regmap_fp]
128 // Get the FP status register.
132 // At least the first 16.
135 // Maybe the other 16 too.
137 vstmiane r3!, {d16-d31}
146 // On entry, r5 points to a register-save map. On exit, the extended
147 // registers are restored from the save area, r4 (pointing to the
148 // general-purpose save area) is preserved, and the other general
149 // registers are clobbered.
151 // Fetch the flags explaining what to do.
153 leaext r12, regdump__flags
156 // Figure out if there are VFP/NEON registers.
159 ldr r3, [r5, #regmap_fp]
161 // Load the FP status register.
165 // Load the first 16 registers.
168 // And maybe the other 16.
170 vldmiane r3!, {d16-d31}
177 ///----- That's all, folks --------------------------------------------------