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" (&regs->fp_volatile), "r" (&regs->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" (&regs->fp_volatile), "r" (&regs->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" (&regs->fp_volatile), "r" (&regs->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" (&regs->fp_volatile), "r" (&regs->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