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