83
83
#if defined(__GNUC__)
85
FXSAVE_ES1(uint8 *save)
87
__asm__ __volatile__ ("fxsave %0\n" : "=m" (*save) : : "memory");
91
FXRSTOR_ES1(const uint8 *load)
93
__asm__ __volatile__ ("fxrstor %0\n" : : "m" (*load) : "memory");
97
FXRSTOR_AMD_ES0(const uint8 *load)
85
FXSAVE_ES1(void *save)
87
__asm__ __volatile__ ("fxsave %0\n" : "=m" (*(uint8 *)save) : : "memory");
91
FXRSTOR_ES1(const void *load)
93
__asm__ __volatile__ ("fxrstor %0\n"
94
: : "m" (*(const uint8 *)load) : "memory");
98
FXRSTOR_AMD_ES0(const void *load)
101
102
__asm__ __volatile__
102
103
("fnstsw %%ax \n" // Grab x87 ES bit
103
104
"bt $7,%%ax \n" // Test ES bit
109
110
// x87 exception pointers.
112
: "m" (dummy), "m" (*load)
113
: "m" (dummy), "m" (*(const uint8 *)load)
113
114
: "ax", "memory");
115
116
#endif /* __GNUC__ */
120
* save/restore GSSE/SIMD/MMX fpu state
122
* The pointer passed in must be 64-byte aligned.
123
* See above comment for more information.
125
#if defined(__GNUC__) && (defined(VMM) || defined(VMKERNEL) || defined(FROBOS))
128
XSAVE_ES1(void *save, uint64 mask)
130
#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
131
__asm__ __volatile__ (
132
".byte 0x0f, 0xae, 0x21 \n"
134
: "c" ((uint8 *)save), "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
137
__asm__ __volatile__ (
139
: "=m" (*(uint8 *)save)
140
: "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
146
XSAVEOPT_ES1(void *save, uint64 mask)
148
__asm__ __volatile__ (
149
".byte 0x0f, 0xae, 0x31 \n"
151
: "c" ((uint8 *)save), "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
156
XRSTOR_ES1(const void *load, uint64 mask)
158
#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
159
__asm__ __volatile__ (
160
".byte 0x0f, 0xae, 0x29 \n"
162
: "c" ((const uint8 *)load),
163
"a" ((uint32)mask), "d" ((uint32)(mask >> 32))
166
__asm__ __volatile__ (
169
: "m" (*(const uint8 *)load),
170
"a" ((uint32)mask), "d" ((uint32)(mask >> 32))
176
XRSTOR_AMD_ES0(const void *load, uint64 mask)
181
("fnstsw %%ax \n" // Grab x87 ES bit
182
"bt $7,%%ax \n" // Test ES bit
183
"jnc 1f \n" // Jump if ES=0
184
"fnclex \n" // ES=1. Clear it so fild doesn't trap
186
"ffree %%st(7) \n" // Clear tag bit - avoid poss. stack overflow
187
"fildl %0 \n" // Dummy Load from "safe address" changes all
188
// x87 exception pointers.
189
"mov %%ebx, %%eax \n"
190
#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
191
".byte 0x0f, 0xae, 0x29 \n"
193
: "m" (dummy), "c" ((const uint8 *)load),
194
"b" ((uint32)mask), "d" ((uint32)(mask >> 32))
198
: "m" (dummy), "m" (*(const uint8 *)load),
199
"b" ((uint32)mask), "d" ((uint32)(mask >> 32))
203
#endif /* __GNUC__ */
118
206
*-----------------------------------------------------------------------------
428
516
"shrdl %%edx, %%eax\n\t" // result = hi(p2):hi(p1):lo(p1) >> shift
429
517
"shrdl %1, %%edx\n"
431
: "=A" (result), "=&r" (tmp1), "=&r" (tmp2)
519
: "=A" (result), "=&r" (tmp1), "=&rm" (tmp2)
432
520
: "0" (multiplicand), "rm" (multiplier), "c" (shift)