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