1 /**
2  * @file
3  * @brief ARM64 GCC specific floating point register macros
4  */
5 
6 /*
7  * Copyright (c) 2021 BayLibre SAS
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #ifndef _FLOAT_REGS_ARM64_GCC_H
13 #define _FLOAT_REGS_ARM64_GCC_H
14 
15 #include <zephyr/toolchain.h>
16 #include "float_context.h"
17 
18 /**
19  *
20  * @brief Load all floating point registers
21  *
22  * This function loads ALL floating point registers pointed to by @a regs.
23  * It is expected that a subsequent call to _store_all_float_registers()
24  * will be issued to dump the floating point registers to memory.
25  *
26  * The format/organization of 'struct fp_register_set'; the generic C test
27  * code (main.c) merely treat the register set as an array of bytes.
28  *
29  * The only requirement is that the arch specific implementations of
30  * _load_all_float_registers() and _store_all_float_registers() agree
31  * on the format.
32  *
33  */
_load_all_float_registers(struct fp_register_set * regs)34 static inline void _load_all_float_registers(struct fp_register_set *regs)
35 {
36 	__asm__ volatile (
37 	"ldp	q0,  q1,  [x0, #(16 *  0)]\n\t"
38 	"ldp	q2,  q3,  [x0, #(16 *  2)]\n\t"
39 	"ldp	q4,  q5,  [x0, #(16 *  4)]\n\t"
40 	"ldp	q6,  q7,  [x0, #(16 *  6)]\n\t"
41 	"ldp	q8,  q9,  [x0, #(16 *  8)]\n\t"
42 	"ldp	q10, q11, [x0, #(16 * 10)]\n\t"
43 	"ldp	q12, q13, [x0, #(16 * 12)]\n\t"
44 	"ldp	q14, q15, [x0, #(16 * 14)]\n\t"
45 	"ldp	q16, q17, [x0, #(16 * 16)]\n\t"
46 	"ldp	q18, q19, [x0, #(16 * 18)]\n\t"
47 	"ldp	q20, q21, [x0, #(16 * 20)]\n\t"
48 	"ldp	q22, q23, [x0, #(16 * 22)]\n\t"
49 	"ldp	q24, q25, [x0, #(16 * 24)]\n\t"
50 	"ldp	q26, q27, [x0, #(16 * 26)]\n\t"
51 	"ldp	q28, q29, [x0, #(16 * 28)]\n\t"
52 	"ldp	q30, q31, [x0, #(16 * 30)]"
53 	:
54 	: "r" (regs)
55 	);
56 }
57 
58 /**
59  *
60  * @brief Dump all floating point registers to memory
61  *
62  * This function stores ALL floating point registers to the memory buffer
63  * specified by @a regs. It is expected that a previous invocation of
64  * _load_all_float_registers() occurred to load all the floating point
65  * registers from a memory buffer.
66  *
67  */
68 
_store_all_float_registers(struct fp_register_set * regs)69 static inline void _store_all_float_registers(struct fp_register_set *regs)
70 {
71 	__asm__ volatile (
72 	"stp	q0,  q1,  [x0, #(16 *  0)]\n\t"
73 	"stp	q2,  q3,  [x0, #(16 *  2)]\n\t"
74 	"stp	q4,  q5,  [x0, #(16 *  4)]\n\t"
75 	"stp	q6,  q7,  [x0, #(16 *  6)]\n\t"
76 	"stp	q8,  q9,  [x0, #(16 *  8)]\n\t"
77 	"stp	q10, q11, [x0, #(16 * 10)]\n\t"
78 	"stp	q12, q13, [x0, #(16 * 12)]\n\t"
79 	"stp	q14, q15, [x0, #(16 * 14)]\n\t"
80 	"stp	q16, q17, [x0, #(16 * 16)]\n\t"
81 	"stp	q18, q19, [x0, #(16 * 18)]\n\t"
82 	"stp	q20, q21, [x0, #(16 * 20)]\n\t"
83 	"stp	q22, q23, [x0, #(16 * 22)]\n\t"
84 	"stp	q24, q25, [x0, #(16 * 24)]\n\t"
85 	"stp	q26, q27, [x0, #(16 * 26)]\n\t"
86 	"stp	q28, q29, [x0, #(16 * 28)]\n\t"
87 	"stp	q30, q31, [x0, #(16 * 30)]"
88 	:
89 	: "r" (regs)
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(
108 						struct fp_register_set *regs)
109 {
110 	_load_all_float_registers(regs);
111 	_store_all_float_registers(regs);
112 }
113 #endif /* _FLOAT_REGS_ARM64_GCC_H */
114