Xenomai  3.1
fptest.h
1 /*
2  * Copyright (C) 2006 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13 
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18 #ifndef _COBALT_ARM64_ASM_UAPI_FPTEST_H
19 #define _COBALT_ARM64_ASM_UAPI_FPTEST_H
20 
21 #define __COBALT_HAVE_FPU 0x1
22 
23 /*
24  * CAUTION: keep this code strictly inlined in macros: we don't want
25  * GCC to apply any callee-saved logic to fpsimd registers in
26  * fp_regs_set() before fp_regs_check() can verify their contents, but
27  * we still want GCC to know about the registers we have clobbered.
28  */
29 
30 #define fp_regs_set(__features, __val) \
31  do { \
32  unsigned long long __e[32]; \
33  unsigned int __i; \
34  \
35  if (__features & __COBALT_HAVE_FPU) { \
36  \
37  for (__i = 0; __i < 32; __i++) \
38  __e[__i] = (__val); \
39  \
40  __asm__ __volatile__("ldp d0, d1, [%0, #8 * 0] \n" \
41  "ldp d2, d3, [%0, #8 * 2] \n" \
42  "ldp d4, d5, [%0, #8 * 4]\n" \
43  "ldp d6, d7, [%0, #8 * 6]\n" \
44  "ldp d8, d9, [%0, #8 * 8]\n" \
45  "ldp d10, d11, [%0, #8 * 10]\n" \
46  "ldp d12, d13, [%0, #8 * 12]\n" \
47  "ldp d14, d15, [%0, #8 * 14]\n" \
48  "ldp d16, d17, [%0, #8 * 16]\n" \
49  "ldp d18, d19, [%0, #8 * 18]\n" \
50  "ldp d20, d21, [%0, #8 * 20]\n" \
51  "ldp d22, d23, [%0, #8 * 22]\n" \
52  "ldp d24, d25, [%0, #8 * 24]\n" \
53  "ldp d26, d27, [%0, #8 * 26]\n" \
54  "ldp d28, d29, [%0, #8 * 28]\n" \
55  "ldp d30, d31, [%0, #8 * 30]\n" \
56  : /* No outputs. */ \
57  : "r"(&__e[0]) \
58  : "d0", "d1", "d2", "d3", "d4", "d5", "d6", \
59  "d7", "d8", "d9", "d10", "d11", "d12", "d13", \
60  "d14", "d15", "d16", "d17", "d18", "d19", \
61  "d20", "d21", "d22", "d23", "d24", "d25", \
62  "d26", "d27", "d28", "d29", "d30", "d31", \
63  "memory"); \
64  } \
65  } while (0)
66 
67 #define fp_regs_check(__features, __val, __report) \
68  ({ \
69  unsigned int __result = (__val), __i; \
70  unsigned long long __e[32]; \
71  \
72  if (__features & __COBALT_HAVE_FPU) { \
73  \
74  __asm__ __volatile__("stp d0, d1, [%0, #8 * 0] \n" \
75  "stp d2, d3, [%0, #8 * 2] \n" \
76  "stp d4, d5, [%0, #8 * 4]\n" \
77  "stp d6, d7, [%0, #8 * 6]\n" \
78  "stp d8, d9, [%0, #8 * 8]\n" \
79  "stp d10, d11, [%0, #8 * 10]\n" \
80  "stp d12, d13, [%0, #8 * 12]\n" \
81  "stp d14, d15, [%0, #8 * 14]\n" \
82  "stp d16, d17, [%0, #8 * 16]\n" \
83  "stp d18, d19, [%0, #8 * 18]\n" \
84  "stp d20, d21, [%0, #8 * 20]\n" \
85  "stp d22, d23, [%0, #8 * 22]\n" \
86  "stp d24, d25, [%0, #8 * 24]\n" \
87  "stp d26, d27, [%0, #8 * 26]\n" \
88  "stp d28, d29, [%0, #8 * 28]\n" \
89  "stp d30, d31, [%0, #8 * 30]\n" \
90  : /* No outputs. */ \
91  : "r"(&__e[0]) \
92  : "memory"); \
93  \
94  for (__i = 0; __i < 32; __i++) \
95  if (__e[__i] != __val) { \
96  __report("d%d: %llu != %u\n", \
97  __i, __e[__i], __val); \
98  __result = __e[__i]; \
99  } \
100  } \
101  \
102  __result; \
103  })
104 
105 #endif /* !_COBALT_ARM64_ASM_UAPI_FPTEST_H */