~ubuntu-branches/ubuntu/quantal/open-vm-tools/quantal-201210021442

« back to all changes in this revision

Viewing changes to lib/include/vm_basic_asm_x86_64.h

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2011-03-31 14:20:05 UTC
  • mfrom: (1.4.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110331142005-3n9red91p7ogkweo
Tags: 2011.03.28-387002-0ubuntu1
* Merge latest upstream git tag.  This has the unlocked_ioctl change
  needed to fix dkms build failures (LP: #727342)
* Changes in debian/rules:
  - work around a bug in toolbox/Makefile, where install-exec-hook is
    not happening.  This needs to get fixed the right way.
  - don't install 'vmware-user' which seems to no longer exist
  - move /etc/xdg into open-vm-toolbox (which should be done using .install)
* debian/open-vm-tools.init: add 'modprobe [-r] vmblock'. (LP: #332323)
* debian/rules and debian/open-vm-toolbox.lintian-overrides:
  - Make vmware-user-suid-wrapper suid-root (LP: #332323)

Show diffs side-by-side

added added

removed removed

Lines of Context:
72
72
#endif // _MSC_VER
73
73
 
74
74
/*
 
75
 * GET_CURRENT_RIP
 
76
 *
 
77
 * Return an approximation of the current instruction pointer. For example for a
 
78
 * function call
 
79
 * foo.c
 
80
 * L123: Foo(GET_CURRENT_RIP())
 
81
 *
 
82
 * The return value from GET_CURRENT_RIP will point a debugger to L123.
 
83
 */
 
84
#if defined(__GNUC__)
 
85
#define GET_CURRENT_RIP() ({                                                   \
 
86
      void *__rip;                                                             \
 
87
      asm("lea 0(%%rip), %0;\n\t"                                              \
 
88
         : "=r" (__rip));                                                      \
 
89
      __rip;                                                                   \
 
90
})
 
91
#endif
 
92
 
 
93
/*
75
94
 * FXSAVE/FXRSTOR
76
95
 *     save/restore SIMD/MMX fpu state
77
96
 *
95
114
#if defined(__GNUC__)
96
115
 
97
116
static INLINE void 
98
 
FXSAVE_ES1(uint8 *save)
99
 
{
100
 
   __asm__ __volatile__ ("fxsaveq %0  \n" : "=m" (*save) : : "memory");
101
 
}
102
 
 
103
 
static INLINE void 
104
 
FXSAVE_COMPAT_ES1(uint8 *save)
105
 
{
106
 
   __asm__ __volatile__ ("fxsave %0  \n" : "=m" (*save) : : "memory");
107
 
}
108
 
 
109
 
static INLINE void 
110
 
FXRSTOR_ES1(const uint8 *load)
111
 
{
112
 
   __asm__ __volatile__ ("fxrstorq %0 \n" : : "m" (*load) : "memory");
113
 
}
114
 
 
115
 
static INLINE void 
116
 
FXRSTOR_COMPAT_ES1(const uint8 *load)
117
 
{
118
 
   __asm__ __volatile__ ("fxrstor %0 \n" : : "m" (*load) : "memory");
119
 
}
120
 
 
121
 
static INLINE void 
122
 
FXRSTOR_AMD_ES0(const uint8 *load)
 
117
FXSAVE_ES1(void *save)
 
118
{
 
119
   __asm__ __volatile__ ("fxsaveq %0  \n" : "=m" (*(uint8 *)save) : : "memory");
 
120
}
 
121
 
 
122
static INLINE void 
 
123
FXSAVE_COMPAT_ES1(void *save)
 
124
{
 
125
   __asm__ __volatile__ ("fxsave %0  \n" : "=m" (*(uint8 *)save) : : "memory");
 
126
}
 
127
 
 
128
static INLINE void 
 
129
FXRSTOR_ES1(const void *load)
 
130
{
 
131
   __asm__ __volatile__ ("fxrstorq %0 \n"
 
132
                         : : "m" (*(const uint8 *)load) : "memory");
 
133
}
 
134
 
 
135
static INLINE void 
 
136
FXRSTOR_COMPAT_ES1(const void *load)
 
137
{
 
138
   __asm__ __volatile__ ("fxrstor %0 \n"
 
139
                         : : "m" (*(const uint8 *)load) : "memory");
 
140
}
 
141
 
 
142
static INLINE void 
 
143
FXRSTOR_AMD_ES0(const void *load)
123
144
{
124
145
   uint64 dummy = 0;
125
 
      
 
146
 
126
147
   __asm__ __volatile__ 
127
148
       ("fnstsw  %%ax    \n"     // Grab x87 ES bit
128
149
        "bt      $7,%%ax \n"     // Test ES bit
134
155
                                 // x87 exception pointers.
135
156
        "fxrstorq %1 \n"
136
157
        :
137
 
        : "m" (dummy), "m" (*load)
 
158
        : "m" (dummy), "m" (*(const uint8 *)load)
138
159
        : "ax", "memory");
139
160
}
140
161
 
141
162
#endif /* __GNUC__ */
142
163
 
 
164
/*
 
165
 * XSAVE/XRSTOR
 
166
 *     save/restore GSSE/SIMD/MMX fpu state
 
167
 *
 
168
 * The pointer passed in must be 64-byte aligned.
 
169
 * See above comment for more information.
 
170
 */
 
171
#if defined(__GNUC__) && (defined(VMM) || defined(VMKERNEL) || defined(FROBOS))
 
172
 
 
173
static INLINE void 
 
174
XSAVE_ES1(void *save, uint64 mask)
 
175
{
 
176
#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
 
177
   __asm__ __volatile__ (
 
178
        ".byte 0x48, 0x0f, 0xae, 0x21 \n"
 
179
        :
 
180
        : "c" ((uint8 *)save), "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
 
181
        : "memory");
 
182
#else
 
183
   __asm__ __volatile__ (
 
184
        "xsaveq %0 \n"
 
185
        : "=m" (*(uint8 *)save)
 
186
        : "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
 
187
        : "memory");
 
188
#endif
 
189
}
 
190
 
 
191
static INLINE void 
 
192
XSAVE_COMPAT_ES1(void *save, uint64 mask)
 
193
{
 
194
#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
 
195
   __asm__ __volatile__ (
 
196
        ".byte 0x0f, 0xae, 0x21 \n"
 
197
        :
 
198
        : "c" ((uint8 *)save), "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
 
199
        : "memory");
 
200
#else
 
201
   __asm__ __volatile__ (
 
202
        "xsave %0 \n"
 
203
        : "=m" (*(uint8 *)save)
 
204
        : "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
 
205
        : "memory");
 
206
#endif
 
207
}
 
208
 
 
209
static INLINE void 
 
210
XSAVEOPT_ES1(void *save, uint64 mask)
 
211
{
 
212
   __asm__ __volatile__ (
 
213
        ".byte 0x48, 0x0f, 0xae, 0x31 \n"
 
214
        :
 
215
        : "c" ((uint8 *)save), "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
 
216
        : "memory");
 
217
}
 
218
 
 
219
static INLINE void 
 
220
XRSTOR_ES1(const void *load, uint64 mask)
 
221
{
 
222
#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
 
223
   __asm__ __volatile__ (
 
224
        ".byte 0x48, 0x0f, 0xae, 0x29 \n"
 
225
        :
 
226
        : "c" ((const uint8 *)load),
 
227
          "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
 
228
        : "memory");
 
229
#else
 
230
   __asm__ __volatile__ (
 
231
        "xrstorq %0 \n"
 
232
        :
 
233
        : "m" (*(const uint8 *)load),
 
234
          "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
 
235
        : "memory");
 
236
#endif
 
237
}
 
238
 
 
239
static INLINE void 
 
240
XRSTOR_COMPAT_ES1(const void *load, uint64 mask)
 
241
{
 
242
#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
 
243
   __asm__ __volatile__ (
 
244
        ".byte 0x0f, 0xae, 0x29 \n"
 
245
        :
 
246
        : "c" ((const uint8 *)load),
 
247
          "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
 
248
        : "memory");
 
249
#else
 
250
   __asm__ __volatile__ (
 
251
        "xrstor %0 \n"
 
252
        :
 
253
        : "m" (*(const uint8 *)load),
 
254
          "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
 
255
        : "memory");
 
256
#endif
 
257
}
 
258
 
 
259
static INLINE void 
 
260
XRSTOR_AMD_ES0(const void *load, uint64 mask)
 
261
{
 
262
   uint64 dummy = 0;
 
263
 
 
264
   __asm__ __volatile__ 
 
265
       ("fnstsw  %%ax    \n"     // Grab x87 ES bit
 
266
        "bt      $7,%%ax \n"     // Test ES bit
 
267
        "jnc     1f      \n"     // Jump if ES=0
 
268
        "fnclex          \n"     // ES=1. Clear it so fild doesn't trap
 
269
        "1:              \n"
 
270
        "ffree   %%st(7) \n"     // Clear tag bit - avoid poss. stack overflow
 
271
        "fildl   %0      \n"     // Dummy Load from "safe address" changes all
 
272
                                 // x87 exception pointers.
 
273
        "mov %%ebx, %%eax \n"
 
274
#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
 
275
        ".byte 0x48, 0x0f, 0xae, 0x29 \n"
 
276
        :
 
277
        : "m" (dummy), "c" ((const uint8 *)load),
 
278
          "b" ((uint32)mask), "d" ((uint32)(mask >> 32))
 
279
#else
 
280
        "xrstorq %1 \n"
 
281
        :
 
282
        : "m" (dummy), "m" (*(const uint8 *)load),
 
283
          "b" ((uint32)mask), "d" ((uint32)(mask >> 32))
 
284
#endif
 
285
        : "eax", "memory");
 
286
}
 
287
 
 
288
#endif /* __GNUC__ */
 
289
 
143
290
 
144
291
/*
145
292
 *-----------------------------------------------------------------------------
146
293
 *
147
 
 * Mul64x3264 --
 
294
 * Mul64x6464 --
148
295
 *
149
296
 *    Unsigned integer by fixed point multiplication:
150
297
 *       result = multiplicand * multiplier >> shift
151
298
 * 
152
299
 *       Unsigned 64-bit integer multiplicand.
153
 
 *       Unsigned 32-bit fixed point multiplier, represented as
 
300
 *       Unsigned 64-bit fixed point multiplier, represented as
154
301
 *         multiplier >> shift, where shift < 64.
155
302
 *       Unsigned 64-bit integer product.
156
303
 *
168
315
#if defined(__GNUC__)
169
316
 
170
317
static INLINE uint64
171
 
Mul64x3264(uint64 multiplicand,
172
 
           uint32 multiplier,
 
318
Mul64x6464(uint64 multiplicand,
 
319
           uint64 multiplier,
173
320
           uint32 shift)
174
321
{
175
322
   uint64 result, dummy;
176
 
   const uint64 multiplier64 = multiplier;
177
323
 
178
324
   __asm__("mulq    %3      \n\t"
179
325
           "shrdq   %1, %0  \n\t"
180
326
           : "=a" (result),
181
327
             "=d" (dummy)
182
 
           : "0"  (multiplier64),
 
328
           : "0"  (multiplier),
183
329
             "rm" (multiplicand),
184
330
         "c"  (shift)
185
331
           : "cc");
189
335
#elif defined(_MSC_VER)
190
336
 
191
337
static INLINE uint64
192
 
Mul64x3264(uint64 multiplicand, uint32 multiplier, uint32 shift)
 
338
Mul64x6464(uint64 multiplicand, uint64 multiplier, uint32 shift)
193
339
{
194
340
   uint64 tmplo, tmphi;
195
341
   tmplo = _umul128(multiplicand, multiplier, &tmphi);
201
347
/*
202
348
 *-----------------------------------------------------------------------------
203
349
 *
204
 
 * Muls64x32s64 --
 
350
 * Muls64x64s64 --
205
351
 *
206
352
 *    Signed integer by fixed point multiplication:
207
353
 *       result = multiplicand * multiplier >> shift
208
354
 * 
209
355
 *       Signed 64-bit integer multiplicand.
210
 
 *       Unsigned 32-bit fixed point multiplier, represented as
 
356
 *       Unsigned 64-bit fixed point multiplier, represented as
211
357
 *         multiplier >> shift, where shift < 64.
212
358
 *       Signed 64-bit integer product.
213
359
 *
229
375
#if defined(__GNUC__)
230
376
 
231
377
static inline int64
232
 
Muls64x32s64(int64 multiplicand, uint32 multiplier, uint32 shift)
 
378
Muls64x64s64(int64 multiplicand, int64 multiplier, uint32 shift)
233
379
{
234
380
   int64 result, dummy;
235
 
   const int64 multiplier64 = multiplier;
236
381
 
237
382
   __asm__("imulq   %3      \n\t"
238
383
       "shrdq   %1, %0  \n\t"
239
384
       : "=a" (result),
240
385
         "=d" (dummy)
241
 
       : "0"  (multiplier64),
 
386
       : "0"  (multiplier),
242
387
         "rm" (multiplicand),
243
388
         "c"  (shift)
244
389
       : "cc");
248
393
#elif defined(_MSC_VER)
249
394
 
250
395
static INLINE int64
251
 
Muls64x32s64(int64 multiplicand, uint32 multiplier, uint32 shift)
 
396
Muls64x64s64(int64 multiplicand, int64 multiplier, uint32 shift)
252
397
{
253
398
   int64 tmplo, tmphi;
 
399
 
254
400
   tmplo = _mul128(multiplicand, multiplier, &tmphi);
255
401
   return __shiftright128(tmplo, tmphi, (uint8) shift);
256
402
}
257
403
 
258
404
#endif
259
405
 
 
406
/*
 
407
 *-----------------------------------------------------------------------------
 
408
 *
 
409
 * Mul64x3264 --
 
410
 *
 
411
 *    Unsigned integer by fixed point multiplication:
 
412
 *       result = multiplicand * multiplier >> shift
 
413
 * 
 
414
 *       Unsigned 64-bit integer multiplicand.
 
415
 *       Unsigned 32-bit fixed point multiplier, represented as
 
416
 *         multiplier >> shift, where shift < 64.
 
417
 *       Unsigned 64-bit integer product.
 
418
 *
 
419
 * Implementation:
 
420
 *    Multiply 64x64 bits to yield a full 128-bit product.
 
421
 *    Shift result in RDX:RAX right by "shift".
 
422
 *    Return the low-order 64 bits of the above.
 
423
 *
 
424
 * Result:
 
425
 *    Return the low-order 64 bits of ((multiplicand * multiplier) >> shift)
 
426
 *
 
427
 *-----------------------------------------------------------------------------
 
428
 */
 
429
 
 
430
static INLINE uint64
 
431
Mul64x3264(uint64 multiplicand, uint32 multiplier, uint32 shift)
 
432
{
 
433
   return Mul64x6464(multiplicand, multiplier, shift);
 
434
}
 
435
 
 
436
/*
 
437
 *-----------------------------------------------------------------------------
 
438
 *
 
439
 * Muls64x32s64 --
 
440
 *
 
441
 *    Signed integer by fixed point multiplication:
 
442
 *       result = (multiplicand * multiplier) >> shift
 
443
 * 
 
444
 *       Signed 64-bit integer multiplicand.
 
445
 *       Unsigned 32-bit fixed point multiplier, represented as
 
446
 *         multiplier >> shift, where shift < 64.
 
447
 *       Signed 64-bit integer product.
 
448
 *
 
449
 * Implementation:
 
450
 *    Multiply 64x64 bits to yield a full 128-bit product.
 
451
 *    Shift result in RDX:RAX right by "shift".
 
452
 *    Return the low-order 64 bits of the above.
 
453
 *
 
454
 * Result:
 
455
 *    Return the low-order 64 bits of ((multiplicand * multiplier) >> shift)
 
456
 *
 
457
 *-----------------------------------------------------------------------------
 
458
 */
 
459
 
 
460
static INLINE int64
 
461
Muls64x32s64(int64 multiplicand, uint32 multiplier, uint32 shift)
 
462
{
 
463
   return Muls64x64s64(multiplicand, multiplier, shift);
 
464
}
 
465
 
260
466
 
261
467
#if defined(__GNUC__)
262
468