source: rtems/cpukit/score/cpu/arm/arm-context-validate.S @ 8ae37323

4.115
Last change on this file since 8ae37323 was 8ae37323, checked in by Sebastian Huber <sebastian.huber@…>, on 08/10/14 at 16:36:30

arm: Add support for FPv4-SP floating point unit

This floating point unit is available in Cortex-M4 processors and
defined by ARMv7-M. This adds basic support for other VFP-D16 variants.

  • Property mode set to 100644
File size: 5.7 KB
Line 
1/*
2 * Copyright (c) 2013-2014 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <rtems/asm.h>
20#include <rtems/score/cpu.h>
21
22#define FRAME_OFFSET_R4 0
23#define FRAME_OFFSET_R5 4
24#define FRAME_OFFSET_R6 8
25#define FRAME_OFFSET_R7 12
26#define FRAME_OFFSET_R8 16
27#define FRAME_OFFSET_R9 20
28#define FRAME_OFFSET_R10 24
29#define FRAME_OFFSET_R11 28
30#define FRAME_OFFSET_LR 32
31
32#ifdef ARM_MULTILIB_VFP
33  #define FRAME_OFFSET_D8 40
34  #define FRAME_OFFSET_D9 48
35  #define FRAME_OFFSET_D10 56
36  #define FRAME_OFFSET_D11 64
37  #define FRAME_OFFSET_D12 72
38  #define FRAME_OFFSET_D13 80
39  #define FRAME_OFFSET_D14 88
40  #define FRAME_OFFSET_D15 96
41
42  #define FRAME_SIZE (FRAME_OFFSET_D15 + 8)
43#else
44  #define FRAME_SIZE (FRAME_OFFSET_LR + 4)
45#endif
46
47        .section        .text
48
49FUNCTION_THUMB_ENTRY(_CPU_Context_validate)
50
51        /* Save */
52
53        sub     sp, sp, #FRAME_SIZE
54
55        mov     r1, r4
56        str     r1, [sp, #FRAME_OFFSET_R4]
57        mov     r1, r5
58        str     r1, [sp, #FRAME_OFFSET_R5]
59        mov     r1, r6
60        str     r1, [sp, #FRAME_OFFSET_R6]
61        mov     r1, r7
62        str     r1, [sp, #FRAME_OFFSET_R7]
63        mov     r1, r8
64        str     r1, [sp, #FRAME_OFFSET_R8]
65        mov     r1, r9
66        str     r1, [sp, #FRAME_OFFSET_R9]
67        mov     r1, r10
68        str     r1, [sp, #FRAME_OFFSET_R10]
69        mov     r1, r11
70        str     r1, [sp, #FRAME_OFFSET_R11]
71        mov     r1, lr
72        str     r1, [sp, #FRAME_OFFSET_LR]
73
74#ifdef ARM_MULTILIB_VFP
75        vstr    d8, [sp, #FRAME_OFFSET_D8]
76        vstr    d9, [sp, #FRAME_OFFSET_D9]
77        vstr    d10, [sp, #FRAME_OFFSET_D10]
78        vstr    d11, [sp, #FRAME_OFFSET_D11]
79        vstr    d12, [sp, #FRAME_OFFSET_D12]
80        vstr    d13, [sp, #FRAME_OFFSET_D13]
81        vstr    d14, [sp, #FRAME_OFFSET_D14]
82        vstr    d15, [sp, #FRAME_OFFSET_D15]
83#endif
84
85        /* Fill */
86
87        /* R1 is used for temporary values */
88        mov     r1, r0
89
90        /* R2 contains the stack pointer */
91        mov     r2, sp
92
93.macro fill_register reg
94        add     r1, r1, #1
95        mov     \reg, r1
96.endm
97
98
99#ifdef ARM_MULTILIB_VFP
100        /* R3 contains the FPSCR */
101        vmrs    r3, FPSCR
102        movs    r4, #0x001f
103#ifdef ARM_MULTILIB_ARCH_V7M
104        movt    r4, #0xf000
105#else
106        movt    r4, #0xf800
107#endif
108        bic     r3, r3, r4
109        and     r4, r4, r0
110        orr     r3, r3, r4
111        vmsr    FPSCR, r3
112#else
113        fill_register   r3
114#endif
115
116        fill_register   r4
117        fill_register   r5
118        fill_register   r6
119        fill_register   r7
120        fill_register   r8
121        fill_register   r9
122        fill_register   r10
123        fill_register   r11
124        fill_register   r12
125        fill_register   lr
126
127#ifdef ARM_MULTILIB_VFP
128.macro fill_vfp_register reg
129        add     r1, r1, #1
130        vmov    \reg, r1, r1
131.endm
132
133        fill_vfp_register       d0
134        fill_vfp_register       d1
135        fill_vfp_register       d2
136        fill_vfp_register       d3
137        fill_vfp_register       d4
138        fill_vfp_register       d5
139        fill_vfp_register       d6
140        fill_vfp_register       d7
141        fill_vfp_register       d8
142        fill_vfp_register       d9
143        fill_vfp_register       d10
144        fill_vfp_register       d11
145        fill_vfp_register       d12
146        fill_vfp_register       d13
147        fill_vfp_register       d14
148        fill_vfp_register       d15
149#ifdef ARM_MULTILIB_VFP_D32
150        fill_vfp_register       d16
151        fill_vfp_register       d17
152        fill_vfp_register       d18
153        fill_vfp_register       d19
154        fill_vfp_register       d20
155        fill_vfp_register       d21
156        fill_vfp_register       d22
157        fill_vfp_register       d23
158        fill_vfp_register       d24
159        fill_vfp_register       d25
160        fill_vfp_register       d26
161        fill_vfp_register       d27
162        fill_vfp_register       d28
163        fill_vfp_register       d29
164        fill_vfp_register       d30
165        fill_vfp_register       d31
166#endif /* ARM_MULTILIB_VFP_D32 */
167#endif /* ARM_MULTILIB_VFP */
168
169        /* Check */
170check:
171
172.macro check_register reg
173        add     r1, r1, #1
174        cmp     \reg, r1
175        bne     restore
176.endm
177
178        cmp     r2, sp
179        bne     restore
180
181        mov     r1, r0
182
183#ifndef ARM_MULTILIB_VFP
184        check_register  r3
185#endif
186
187        check_register  r4
188        check_register  r5
189        check_register  r6
190        check_register  r7
191        check_register  r8
192        check_register  r9
193        check_register  r10
194        check_register  r11
195        check_register  r12
196        check_register  lr
197
198#ifdef ARM_MULTILIB_VFP
199        b       check_vfp
200#endif
201
202        b       check
203
204        /* Restore */
205restore:
206
207        ldr     r1, [sp, #FRAME_OFFSET_R4]
208        mov     r4, r1
209        ldr     r1, [sp, #FRAME_OFFSET_R5]
210        mov     r5, r1
211        ldr     r1, [sp, #FRAME_OFFSET_R6]
212        mov     r6, r1
213        ldr     r1, [sp, #FRAME_OFFSET_R7]
214        mov     r7, r1
215        ldr     r1, [sp, #FRAME_OFFSET_R8]
216        mov     r8, r1
217        ldr     r1, [sp, #FRAME_OFFSET_R9]
218        mov     r9, r1
219        ldr     r1, [sp, #FRAME_OFFSET_R10]
220        mov     r10, r1
221        ldr     r1, [sp, #FRAME_OFFSET_R11]
222        mov     r11, r1
223        ldr     r1, [sp, #FRAME_OFFSET_LR]
224        mov     lr, r1
225
226#ifdef ARM_MULTILIB_VFP
227        vldr    d8, [sp, #FRAME_OFFSET_D8]
228        vldr    d9, [sp, #FRAME_OFFSET_D9]
229        vldr    d10, [sp, #FRAME_OFFSET_D10]
230        vldr    d11, [sp, #FRAME_OFFSET_D11]
231        vldr    d12, [sp, #FRAME_OFFSET_D12]
232        vldr    d13, [sp, #FRAME_OFFSET_D13]
233        vldr    d14, [sp, #FRAME_OFFSET_D14]
234        vldr    d15, [sp, #FRAME_OFFSET_D15]
235#endif
236
237        add     sp, sp, #FRAME_SIZE
238
239        bx      lr
240
241FUNCTION_END(_CPU_Context_validate)
242
243#ifdef ARM_MULTILIB_VFP
244check_vfp:
245
246.macro check_vfp_register reg
247        add     r1, r1, #1
248        vmov    r4, r5, \reg
249        cmp     r4, r5
250        bne     1f
251        cmp     r1, r4
252        bne     1f
253        b       2f
2541:
255        b       restore
2562:
257.endm
258
259        vmrs    r4, FPSCR
260        cmp     r4, r3
261        bne     restore
262
263        check_vfp_register      d0
264        check_vfp_register      d1
265        check_vfp_register      d2
266        check_vfp_register      d3
267        check_vfp_register      d4
268        check_vfp_register      d5
269        check_vfp_register      d6
270        check_vfp_register      d7
271        check_vfp_register      d8
272        check_vfp_register      d9
273        check_vfp_register      d10
274        check_vfp_register      d11
275        check_vfp_register      d12
276        check_vfp_register      d13
277        check_vfp_register      d14
278        check_vfp_register      d15
279#ifdef ARM_MULTILIB_VFP_D32
280        check_vfp_register      d16
281        check_vfp_register      d17
282        check_vfp_register      d18
283        check_vfp_register      d19
284        check_vfp_register      d20
285        check_vfp_register      d21
286        check_vfp_register      d22
287        check_vfp_register      d23
288        check_vfp_register      d24
289        check_vfp_register      d25
290        check_vfp_register      d26
291        check_vfp_register      d27
292        check_vfp_register      d28
293        check_vfp_register      d29
294        check_vfp_register      d30
295        check_vfp_register      d31
296#endif /* ARM_MULTILIB_VFP_D32 */
297
298        /* Restore r4 and r5 */
299        mov     r1, r0
300        fill_register   r4
301        fill_register   r5
302
303        b       check
304#endif /* ARM_MULTILIB_VFP */
Note: See TracBrowser for help on using the repository browser.