progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / base / regdump-arm.S
CommitLineData
4bc8424a
MW
1/// -*- mode: asm; asm-comment-char: ?/ -*-
2///
3/// Register dump and debugging for 32-bit ARM
4///
5/// (c) 2019 Straylight/Edgeware
6///
7
8///----- Licensing notice ---------------------------------------------------
9///
10/// This file is part of Catacomb.
11///
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.
16///
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.
21///
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,
25/// USA.
26
27///--------------------------------------------------------------------------
28/// Preliminaries.
29
30#include "config.h"
31#include "asm-common.h"
32#include "regdump.h"
33
34 .arch armv7-a
35 .fpu neon
36
37 .text
38
39///--------------------------------------------------------------------------
40/// Main code.
41
42FUNC(regdump_gpsave)
43 endprologue
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
53 // not recommended.
54
55 // Save the easy registers.
56 stmia r13, {r0-r11}
57 mov r4, r13
58
59 // Determine the previous stack pointer and save it.
60 add r0, r4, #REGDUMP_GPSIZE
61 str r0, [r4, #13*4]
62
6a3d653c 63 // Clear the magic Thumb-state bit from the return address.
4bc8424a 64 bic r1, r14, #1
4bc8424a
MW
65 str r1, [r13, #15*4]
66
67 // Load the focus address and save it as r6.
68 ldr r6, [r4, #4*REGIX_ADDR]
69
70 // Determine the extended save area size.
71 ldgot
72 mov r0, #8 + 8
73 leaext r12, regdump__flags
74 ldr r12, [r12]
75 tst r12, #REGF_VFP
76 addne r0, r0, #REGDUMP_FPSIZE_D16
77 tstne r12, #REGF_D32
78 addne r0, r0, #REGDUMP_FPSIZE_D32 - REGDUMP_FPSIZE_D16
79
80 // Done.
81 bx r14
82
83ENDFUNC
84
85FUNC(regdump_gprstr)
86 endprologue
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.
90
91 // Restore the processor flags.
92 ldr r0, [r4, #4*REGIX_CPSR]
93 msr cpsr_fs, r0
94
95 // Load the easy registers.
96 ldmia r4, {r0-r12}
97
98 // Done.
99 bx r14
100
101ENDFUNC
102
103FUNC(regdump_xtsave)
104 endprologue
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
c85d1829
MW
107 // and a handy map placed at its base, and r5 is left pointing to the
108 // reigster map.
4bc8424a
MW
109
110 // Set up the map/extended save area pointer.
111 add r5, r13, #7
112 bic r5, r5, #7
113
114 // Start by filling in the easy part of the map.
115 str r4, [r5, #regmap_gp]
116
117 // Fetch the flags explaining what to do.
118 ldgot
119 leaext r12, regdump__flags
120 ldr r12, [r12]
121
122 // Figure out whether there are VFP/NEON registers.
123 tst r12, #REGF_VFP
124 moveq r3, #0
125 addne r3, r5, #regmap_size
126 str r3, [r5, #regmap_fp]
127 beq 9f
128
129 // Get the FP status register.
130 vmrs r0, fpscr
131 str r0, [r3], #8
132
133 // At least the first 16.
134 vstmia r3!, {d0-d15}
135
136 // Maybe the other 16 too.
137 tst r12, #REGF_D32
138 vstmiane r3!, {d16-d31}
139
140 // Done.
1419: bx r14
142
143ENDFUNC
144
145FUNC(regdump_xtrstr)
146 endprologue
147 // On entry, r5 points to a register-save map. On exit, the extended
148 // registers are restored from the save area, r4 (pointing to the
149 // general-purpose save area) is preserved, and the other general
150 // registers are clobbered.
151
152 // Fetch the flags explaining what to do.
153 ldgot
154 leaext r12, regdump__flags
155 ldr r12, [r12]
156
157 // Figure out if there are VFP/NEON registers.
158 tst r12, #REGF_VFP
159 beq 9f
160 ldr r3, [r5, #regmap_fp]
161
162 // Load the FP status register.
163 ldr r0, [r3], #8
164 vmsr fpscr, r0
165
166 // Load the first 16 registers.
167 vldmia r3!, {d0-d15}
168
169 // And maybe the other 16.
170 tst r12, #REGF_D32
171 vldmiane r3!, {d16-d31}
172
173 // Done.
1749: bx r14
175
176ENDFUNC
177
178///----- That's all, folks --------------------------------------------------