1 /** 2 * @file 3 * @brief common definitions for the FPU sharing test application 4 */ 5 6 /* 7 * Copyright (c) 2011-2014 Wind River Systems, Inc. 8 * 9 * SPDX-License-Identifier: Apache-2.0 10 */ 11 12 #ifndef _FLOATCONTEXT_H 13 #define _FLOATCONTEXT_H 14 15 /* 16 * Each architecture must define the following structures (which may be empty): 17 * 'struct fp_volatile_register_set' 18 * 'struct fp_non_volatile_register_set' 19 * 20 * Each architecture must also define the following macros: 21 * SIZEOF_FP_VOLATILE_REGISTER_SET 22 * SIZEOF_FP_NON_VOLATILE_REGISTER_SET 23 * Those macros are used as sizeof(<an empty structure>) is compiler specific; 24 * that is, it may evaluate to a non-zero value. 25 * 26 * Each architecture shall also have custom implementations of: 27 * _load_all_float_registers() 28 * _load_then_store_all_float_registers() 29 * _store_all_float_registers() 30 */ 31 32 #if defined(CONFIG_X86) 33 34 #define FP_OPTION 0 35 36 /* 37 * In the future, the struct definitions may need to be refined based on the 38 * specific IA-32 processor, but for now only the Pentium4 is supported: 39 * 40 * 8 x 80 bit floating point registers (ST[0] -> ST[7]) 41 * 8 x 128 bit XMM registers (XMM[0] -> XMM[7]) 42 * 43 * All these registers are considered volatile across a function invocation. 44 */ 45 46 struct fp_register { 47 unsigned char reg[10]; 48 }; 49 50 struct xmm_register { 51 unsigned char reg[16]; 52 }; 53 54 struct fp_volatile_register_set { 55 struct xmm_register xmm[8]; /* XMM[0] -> XMM[7] */ 56 struct fp_register st[8]; /* ST[0] -> ST[7] */ 57 }; 58 59 struct fp_non_volatile_register_set { 60 /* No non-volatile floating point registers */ 61 }; 62 63 #define SIZEOF_FP_VOLATILE_REGISTER_SET sizeof(struct fp_volatile_register_set) 64 #define SIZEOF_FP_NON_VOLATILE_REGISTER_SET 0 65 66 #elif defined(CONFIG_ARM) 67 68 #if defined(CONFIG_VFP_FEATURE_REGS_S64_D32) 69 70 struct fp_volatile_register_set { 71 double regs[16]; /* d0..d15 */ 72 }; 73 74 struct fp_non_volatile_register_set { 75 double regs[16]; /*d16..d31 */ 76 }; 77 78 #elif defined(CONFIG_ARMV7_M_ARMV8_M_FP) || defined(CONFIG_ARMV7_R_FP) \ 79 || defined(CONFIG_VFP_FEATURE_REGS_S32_D16) 80 81 #define FP_OPTION 0 82 83 /* 84 * Registers s0..s15 are volatile and do not 85 * need to be preserved across function calls. 86 */ 87 struct fp_volatile_register_set { 88 float s[16]; 89 }; 90 91 /* 92 * Registers s16..s31 are non-volatile and 93 * need to be preserved across function calls. 94 */ 95 struct fp_non_volatile_register_set { 96 float s[16]; 97 }; 98 99 #else 100 101 struct fp_volatile_register_set { 102 /* No volatile floating point registers */ 103 }; 104 105 struct fp_non_volatile_register_set { 106 /* No non-volatile floating point registers */ 107 }; 108 109 #endif 110 111 #define SIZEOF_FP_VOLATILE_REGISTER_SET \ 112 sizeof(struct fp_volatile_register_set) 113 #define SIZEOF_FP_NON_VOLATILE_REGISTER_SET \ 114 sizeof(struct fp_non_volatile_register_set) 115 116 #elif defined(CONFIG_ARM64) 117 118 struct fp_volatile_register_set { 119 __int128 regs[16]; /* q0..q15 */ 120 }; 121 122 struct fp_non_volatile_register_set { 123 __int128 regs[16]; /* q16..q31 */ 124 }; 125 126 #define SIZEOF_FP_VOLATILE_REGISTER_SET \ 127 sizeof(struct fp_volatile_register_set) 128 #define SIZEOF_FP_NON_VOLATILE_REGISTER_SET \ 129 sizeof(struct fp_non_volatile_register_set) 130 131 #elif defined(CONFIG_ISA_ARCV2) 132 133 struct fp_volatile_register_set { 134 #ifdef CONFIG_FP_FPU_DA 135 uint32_t dpfp2h; 136 uint32_t dpfp2l; 137 uint32_t dpfp1h; 138 uint32_t dpfp1l; 139 #endif 140 }; 141 142 struct fp_non_volatile_register_set { 143 /* No non-volatile floating point registers */ 144 }; 145 146 #define SIZEOF_FP_VOLATILE_REGISTER_SET sizeof(struct fp_volatile_register_set) 147 #define SIZEOF_FP_NON_VOLATILE_REGISTER_SET 0 148 149 #elif defined(CONFIG_RISCV) 150 151 struct fp_volatile_register_set { 152 #ifdef CONFIG_CPU_HAS_FPU_DOUBLE_PRECISION 153 uint64_t fp[32]; 154 #else 155 uint32_t fp[32]; 156 #endif 157 }; 158 159 struct fp_non_volatile_register_set { 160 /* No non-volatile floating point registers */ 161 }; 162 163 #define SIZEOF_FP_VOLATILE_REGISTER_SET sizeof(struct fp_volatile_register_set) 164 #define SIZEOF_FP_NON_VOLATILE_REGISTER_SET 0 165 166 #elif defined(CONFIG_SPARC) 167 168 struct fp_volatile_register_set { 169 double d[16]; 170 }; 171 172 struct fp_non_volatile_register_set { 173 }; 174 175 #define SIZEOF_FP_VOLATILE_REGISTER_SET sizeof(struct fp_volatile_register_set) 176 #define SIZEOF_FP_NON_VOLATILE_REGISTER_SET 0 177 178 #elif defined(CONFIG_XTENSA) 179 180 struct fp_volatile_register_set { 181 /* No volatile floating point registers */ 182 }; 183 184 struct fp_non_volatile_register_set { 185 uint32_t reg[18]; /* FR register file consists of 18 registers of 32 bits */ 186 }; 187 188 #define SIZEOF_FP_VOLATILE_REGISTER_SET 0 189 #define SIZEOF_FP_NON_VOLATILE_REGISTER_SET sizeof(struct fp_non_volatile_register_set) 190 191 #else 192 193 #error "Architecture must provide the following definitions:\n" 194 "\t'struct fp_volatile_registers'\n" 195 "\t'struct fp_non_volatile_registers'\n" 196 "\t'SIZEOF_FP_VOLATILE_REGISTER_SET'\n" 197 "\t'SIZEOF_FP_NON_VOLATILE_REGISTER_SET'\n" 198 #endif /* CONFIG_X86 */ 199 200 /* the set of ALL floating point registers */ 201 202 struct fp_register_set { 203 struct fp_volatile_register_set fp_volatile; 204 struct fp_non_volatile_register_set fp_non_volatile; 205 }; 206 207 #define SIZEOF_FP_REGISTER_SET \ 208 (SIZEOF_FP_VOLATILE_REGISTER_SET + SIZEOF_FP_NON_VOLATILE_REGISTER_SET) 209 210 /* 211 * The following constants define the initial byte value used by the background 212 * task, and the thread when loading up the floating point registers. 213 */ 214 215 #define MAIN_FLOAT_REG_CHECK_BYTE ((unsigned char)0xe5) 216 #define FIBER_FLOAT_REG_CHECK_BYTE ((unsigned char)0xf9) 217 218 #endif /* _FLOATCONTEXT_H */ 219