Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | /** * @file * @brief Intel x86 GCC specific floating point register macros */ /* * Copyright (c) 2015, Wind River Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 */ #ifndef _FLOAT_REGS_X86_GCC_H #define _FLOAT_REGS_X86_GCC_H #if !defined(__GNUC__) || !defined(CONFIG_ISA_IA32) #error __FILE__ goes only with x86 GCC #endif #include <toolchain.h> #include "float_context.h" /** * * @brief Load all floating point registers * * This function loads ALL floating point registers pointed to by @a regs. * It is expected that a subsequent call to _store_all_float_registers() * will be issued to dump the floating point registers to memory. * * The format/organization of 'struct fp_register_set'; the generic C test * code (main.c) merely treat the register set as an array of bytes. * * The only requirement is that the arch specific implementations of * _load_all_float_registers(), _store_all_float_registers() and * _load_then_store_all_float_registers() agree on the format. * * @return N/A */ static inline void _load_all_float_registers(struct fp_register_set *regs) { __asm__ volatile ( "movdqu 0(%0), %%xmm0\n\t;" "movdqu 16(%0), %%xmm1\n\t;" "movdqu 32(%0), %%xmm2\n\t;" "movdqu 48(%0), %%xmm3\n\t;" "movdqu 64(%0), %%xmm4\n\t;" "movdqu 80(%0), %%xmm5\n\t;" "movdqu 96(%0), %%xmm6\n\t;" "movdqu 112(%0), %%xmm7\n\t;" "fldt 128(%0)\n\t;" "fldt 138(%0)\n\t;" "fldt 148(%0)\n\t;" "fldt 158(%0)\n\t;" "fldt 168(%0)\n\t;" "fldt 178(%0)\n\t;" "fldt 188(%0)\n\t;" "fldt 198(%0)\n\t;" : : "r" (regs) ); } /** * * @brief Load then dump all float registers to memory * * This function loads ALL floating point registers from the memory buffer * specified by @a regs, and then stores them back to that buffer. * * This routine is called by a high priority thread prior to calling a primitive * that pends and triggers a co-operative context switch to a low priority * thread. Because the kernel doesn't save floating point context for * co-operative context switches, the x87 FPU register stack must be put back * in an empty state before the switch occurs in case the next task to perform * floating point operations was also co-operatively switched out and simply * inherits the existing x87 FPU state (expecting the stack to be empty). * * @return N/A */ static inline void _load_then_store_all_float_registers(struct fp_register_set *regs) { __asm__ volatile ( "movdqu 0(%0), %%xmm0\n\t;" "movdqu 16(%0), %%xmm1\n\t;" "movdqu 32(%0), %%xmm2\n\t;" "movdqu 48(%0), %%xmm3\n\t;" "movdqu 64(%0), %%xmm4\n\t;" "movdqu 80(%0), %%xmm5\n\t;" "movdqu 96(%0), %%xmm6\n\t;" "movdqu 112(%0), %%xmm7\n\t;" "fldt 128(%0)\n\t;" "fldt 138(%0)\n\t;" "fldt 148(%0)\n\t;" "fldt 158(%0)\n\t;" "fldt 168(%0)\n\t;" "fldt 178(%0)\n\t;" "fldt 188(%0)\n\t;" "fldt 198(%0)\n\t;" /* pop the x87 FPU registers back to memory */ "fstpt 198(%0)\n\t;" "fstpt 188(%0)\n\t;" "fstpt 178(%0)\n\t;" "fstpt 168(%0)\n\t;" "fstpt 158(%0)\n\t;" "fstpt 148(%0)\n\t;" "fstpt 138(%0)\n\t;" "fstpt 128(%0)\n\t;" : : "r" (regs) ); } /** * * @brief Dump all floating point registers to memory * * This function stores ALL floating point registers to the memory buffer * specified by @a regs. It is expected that a previous invocation of * _load_all_float_registers() occurred to load all the floating point * registers from a memory buffer. * * @return N/A */ static inline void _store_all_float_registers(struct fp_register_set *regs) { __asm__ volatile ( "movdqu %%xmm0, 0(%0)\n\t;" "movdqu %%xmm1, 16(%0)\n\t;" "movdqu %%xmm2, 32(%0)\n\t;" "movdqu %%xmm3, 48(%0)\n\t;" "movdqu %%xmm4, 64(%0)\n\t;" "movdqu %%xmm5, 80(%0)\n\t;" "movdqu %%xmm6, 96(%0)\n\t;" "movdqu %%xmm7, 112(%0)\n\t;" "fstpt 198(%0)\n\t;" "fstpt 188(%0)\n\t;" "fstpt 178(%0)\n\t;" "fstpt 168(%0)\n\t;" "fstpt 158(%0)\n\t;" "fstpt 148(%0)\n\t;" "fstpt 138(%0)\n\t;" "fstpt 128(%0)\n\t;" : : "r" (regs) : "memory" ); } #endif /* _FLOAT_REGS_X86_GCC_H */ |