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