1 /**
2 * @file
3 * @brief ARM GCC specific floating point register macros
4 */
5
6 /*
7 * Copyright (c) 2016, Wind River Systems, Inc.
8 *
9 * SPDX-License-Identifier: Apache-2.0
10 */
11
12 #ifndef _FLOAT_REGS_ARM_GCC_H
13 #define _FLOAT_REGS_ARM_GCC_H
14
15 #include <zephyr/toolchain.h>
16 #include "float_context.h"
17
18 #if defined(CONFIG_VFP_FEATURE_REGS_S64_D32)
19
_load_all_float_registers(struct fp_register_set * regs)20 static inline void _load_all_float_registers(struct fp_register_set *regs)
21 {
22 __asm__ volatile (
23 "vldmia %0, {d0-d15};\n\t"
24 "vldmia %1, {d16-d31};\n\t"
25 : : "r" (®s->fp_volatile), "r" (®s->fp_non_volatile)
26 );
27 }
28
_store_all_float_registers(struct fp_register_set * regs)29 static inline void _store_all_float_registers(struct fp_register_set *regs)
30 {
31 __asm__ volatile (
32 "vstmia %0, {d0-d15};\n\t"
33 "vstmia %1, {d16-d31};\n\t"
34 : : "r" (®s->fp_volatile), "r" (®s->fp_non_volatile)
35 : "memory"
36 );
37 }
38
_load_then_store_all_float_registers(struct fp_register_set * regs)39 static inline void _load_then_store_all_float_registers(struct fp_register_set *regs)
40 {
41 _load_all_float_registers(regs);
42 _store_all_float_registers(regs);
43 }
44
45 #else
46
47 /**
48 *
49 * @brief Load all floating point registers
50 *
51 * This function loads ALL floating point registers pointed to by @a regs.
52 * It is expected that a subsequent call to _store_all_float_registers()
53 * will be issued to dump the floating point registers to memory.
54 *
55 * The format/organization of 'struct fp_register_set'; the generic C test
56 * code (main.c) merely treat the register set as an array of bytes.
57 *
58 * The only requirement is that the arch specific implementations of
59 * _load_all_float_registers() and _store_all_float_registers() agree
60 * on the format.
61 *
62 */
63
_load_all_float_registers(struct fp_register_set * regs)64 static inline void _load_all_float_registers(struct fp_register_set *regs)
65 {
66 __asm__ volatile (
67 "vldmia %0, {s0-s15};\n\t"
68 "vldmia %1, {s16-s31};\n\t"
69 : : "r" (®s->fp_volatile), "r" (®s->fp_non_volatile)
70 );
71 }
72
73 /**
74 *
75 * @brief Dump all floating point registers to memory
76 *
77 * This function stores ALL floating point registers to the memory buffer
78 * specified by @a regs. It is expected that a previous invocation of
79 * _load_all_float_registers() occurred to load all the floating point
80 * registers from a memory buffer.
81 *
82 */
83
_store_all_float_registers(struct fp_register_set * regs)84 static inline void _store_all_float_registers(struct fp_register_set *regs)
85 {
86 __asm__ volatile (
87 "vstmia %0, {s0-s15};\n\t"
88 "vstmia %1, {s16-s31};\n\t"
89 : : "r" (®s->fp_volatile), "r" (®s->fp_non_volatile)
90 : "memory"
91 );
92 }
93
94 /**
95 *
96 * @brief Load then dump all float registers to memory
97 *
98 * This function loads ALL floating point registers from the memory buffer
99 * specified by @a regs, and then stores them back to that buffer.
100 *
101 * This routine is called by a high priority thread prior to calling a primitive
102 * that pends and triggers a co-operative context switch to a low priority
103 * thread.
104 *
105 */
106
_load_then_store_all_float_registers(struct fp_register_set * regs)107 static inline void _load_then_store_all_float_registers(struct fp_register_set
108 *regs)
109 {
110 _load_all_float_registers(regs);
111 _store_all_float_registers(regs);
112 }
113
114 #endif
115
116 #endif /* _FLOAT_REGS_ARM_GCC_H */
117