FreeBSD/Linux Kernel Cross Reference
sys/i386/fpu.h
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26
27 /*
28 * HISTORY
29 * $Log: fpu.h,v $
30 * Revision 2.3 92/02/19 15:08:04 elf
31 * Added fwait()
32 * [92/01/19 jvh]
33 *
34 * Revision 2.2 92/01/03 20:05:49 dbg
35 * Created.
36 * [91/12/23 16:32:15 dbg]
37 *
38 */
39
40 #ifndef _I386_FPU_H_
41 #define _I386_FPU_H_
42
43 /*
44 * Macro definitions for routines to manipulate the
45 * floating-point processor.
46 */
47
48 #include <cpus.h>
49 #include <fpe.h>
50 #include <i386/proc_reg.h>
51 #include <i386/thread.h>
52
53 /*
54 * FPU instructions.
55 */
56 #define fninit() \
57 asm volatile("fninit")
58
59 #define fnstcw(control) \
60 asm("fnstcw %0" : "=m" (*(unsigned short *)(control)))
61
62 #define fldcw(control) \
63 asm volatile("fldcw %0" : : "m" (*(unsigned short *) &(control)) )
64
65 #define fnstsw() \
66 ({ \
67 unsigned short _status__; \
68 asm("fnstsw %0" : "=ma" (_status__)); \
69 _status__; \
70 })
71
72 #define fnclex() \
73 asm volatile("fnclex")
74
75 #define fnsave(state) \
76 asm volatile("fnsave %0" : "=m" (*state))
77
78 #define frstor(state) \
79 asm volatile("frstor %0" : : "m" (state))
80
81 #define fwait() \
82 asm("fwait");
83
84 /*
85 * If floating-point instructions are emulated,
86 * we must load the floating-point register selector
87 * when switching to a new thread.
88 */
89 #if FPE
90 extern void disable_fpe();
91 extern void enable_fpe();
92
93 #define fpu_save_context(thread) \
94 { \
95 if (fp_kind == FP_SOFT) \
96 disable_fpe(); \
97 else \
98 set_ts(); \
99 }
100
101 #define fpu_load_context(pcb) \
102 { \
103 register struct i386_fpsave_state *ifps; \
104 if (fp_kind == FP_SOFT && (ifps = pcb->ims.ifps) != 0) \
105 enable_fpe(ifps); \
106 }
107
108 #else /* no FPE */
109
110 #define fpu_load_context(pcb)
111
112 /*
113 * Save thread`s FPU context.
114 * If only one CPU, we just set the task-switched bit,
115 * to keep the new thread from using the coprocessor.
116 * If multiple CPUs, we save the entire state.
117 */
118 #if NCPUS > 1
119 #define fpu_save_context(thread) \
120 { \
121 register struct i386_fpsave_state *ifps; \
122 ifps = (thread)->pcb->ims.ifps; \
123 if (ifps != 0 && !ifps->fp_valid) { \
124 /* registers are in FPU - save to memory */ \
125 ifps->fp_valid = TRUE; \
126 fnsave(&ifps->fp_save_state); \
127 set_ts(); \
128 } \
129 }
130
131 #else /* NCPUS == 1 */
132 #define fpu_save_context(thread) \
133 { \
134 set_ts(); \
135 }
136
137 #endif /* NCPUS == 1 */
138
139 #endif /* no FPE */
140
141 extern int fp_kind;
142
143 #endif /* _I386_FPU_H_ */
Cache object: b4820447ea0e72333826be5274030926
|