]> git.cworth.org Git - apitrace/blob - thirdparty/directxtex/XNAMath/xnamathconvert.inl
thirdparty/directxtex: Import DirectXTex library.
[apitrace] / thirdparty / directxtex / XNAMath / xnamathconvert.inl
1 /************************************************************************
2 *                                                                       *
3 * xnamathconvert.inl -- SIMD C++ Math library for Windows and Xbox 360  *
4 *                       Conversion, loading, and storing functions      *
5 *                                                                       *
6 * Copyright (c) Microsoft Corp. All rights reserved.                    *
7 *                                                                       *
8 ************************************************************************/
9
10 #if defined(_MSC_VER) && (_MSC_VER > 1000)
11 #pragma once
12 #endif
13
14 #ifndef __XNAMATHCONVERT_INL__
15 #define __XNAMATHCONVERT_INL__
16
17 #define XM_PACK_FACTOR                  (FLOAT)(1 << 22)
18 #define XM_UNPACK_FACTOR_UNSIGNED       (FLOAT)(1 << 23)
19 #define XM_UNPACK_FACTOR_SIGNED         XM_PACK_FACTOR
20
21 #define XM_UNPACK_UNSIGNEDN_OFFSET(BitsX, BitsY, BitsZ, BitsW) \
22                                         {-XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsX)) - 1), \
23                                          -XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsY)) - 1), \
24                                          -XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsZ)) - 1), \
25                                          -XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsW)) - 1)}
26
27 #define XM_UNPACK_UNSIGNEDN_SCALE(BitsX, BitsY, BitsZ, BitsW) \
28                                         {XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsX)) - 1), \
29                                          XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsY)) - 1), \
30                                          XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsZ)) - 1), \
31                                          XM_UNPACK_FACTOR_UNSIGNED / (FLOAT)((1 << (BitsW)) - 1)}
32
33 #define XM_UNPACK_SIGNEDN_SCALE(BitsX, BitsY, BitsZ, BitsW) \
34                                         {-XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsX) - 1)) - 1), \
35                                          -XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsY) - 1)) - 1), \
36                                          -XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsZ) - 1)) - 1), \
37                                          -XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsW) - 1)) - 1)}
38
39 //#define XM_UNPACK_SIGNEDN_OFFSET(BitsX, BitsY, BitsZ, BitsW) \
40 //                                        {-XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsX) - 1)) - 1) * 3.0f, \
41 //                                         -XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsY) - 1)) - 1) * 3.0f, \
42 //                                         -XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsZ) - 1)) - 1) * 3.0f, \
43 //                                         -XM_UNPACK_FACTOR_SIGNED / (FLOAT)((1 << ((BitsW) - 1)) - 1) * 3.0f}
44
45 #define XM_PACK_UNSIGNEDN_SCALE(BitsX, BitsY, BitsZ, BitsW) \
46                                         {-(FLOAT)((1 << (BitsX)) - 1) / XM_PACK_FACTOR, \
47                                          -(FLOAT)((1 << (BitsY)) - 1) / XM_PACK_FACTOR, \
48                                          -(FLOAT)((1 << (BitsZ)) - 1) / XM_PACK_FACTOR, \
49                                          -(FLOAT)((1 << (BitsW)) - 1) / XM_PACK_FACTOR}
50
51 #define XM_PACK_SIGNEDN_SCALE(BitsX, BitsY, BitsZ, BitsW) \
52                                         {-(FLOAT)((1 << ((BitsX) - 1)) - 1) / XM_PACK_FACTOR, \
53                                          -(FLOAT)((1 << ((BitsY) - 1)) - 1) / XM_PACK_FACTOR, \
54                                          -(FLOAT)((1 << ((BitsZ) - 1)) - 1) / XM_PACK_FACTOR, \
55                                          -(FLOAT)((1 << ((BitsW) - 1)) - 1) / XM_PACK_FACTOR}
56
57 #define XM_PACK_OFFSET                  XMVectorSplatConstant(3, 0)
58 //#define XM_UNPACK_OFFSET                XM_PACK_OFFSET
59
60 /****************************************************************************
61  *
62  * Data conversion
63  *
64  ****************************************************************************/
65
66 //------------------------------------------------------------------------------
67
68 XMFINLINE FLOAT XMConvertHalfToFloat
69 (
70     HALF Value
71 )
72 {
73 #if defined(_XM_NO_INTRINSICS_) || defined(_XM_SSE_INTRINSICS_)
74
75     UINT Mantissa;
76     UINT Exponent;
77     UINT Result;
78
79     Mantissa = (UINT)(Value & 0x03FF);
80
81     if ((Value & 0x7C00) != 0)  // The value is normalized
82     {
83         Exponent = (UINT)((Value >> 10) & 0x1F);
84     }
85     else if (Mantissa != 0)     // The value is denormalized
86     {
87         // Normalize the value in the resulting float
88         Exponent = 1;
89
90         do
91         {
92             Exponent--;
93             Mantissa <<= 1;
94         } while ((Mantissa & 0x0400) == 0);
95
96         Mantissa &= 0x03FF;
97     }
98     else                        // The value is zero
99     {
100         Exponent = (UINT)-112;
101     }
102
103     Result = ((Value & 0x8000) << 16) | // Sign
104              ((Exponent + 112) << 23) | // Exponent
105              (Mantissa << 13);          // Mantissa
106
107     return *(FLOAT*)&Result;
108
109 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
110 #endif
111 }
112
113 //------------------------------------------------------------------------------
114
115 XMINLINE FLOAT* XMConvertHalfToFloatStream
116 (
117     FLOAT*      pOutputStream, 
118     size_t      OutputStride, 
119     CONST HALF* pInputStream, 
120     size_t      InputStride, 
121     size_t      HalfCount
122 )
123 {
124 #if defined(_XM_NO_INTRINSICS_) || defined(_XM_SSE_INTRINSICS_)
125
126     size_t  i;
127     CONST BYTE* pHalf = (CONST BYTE*)pInputStream;
128     BYTE* pFloat = (BYTE*)pOutputStream;
129
130     XMASSERT(pOutputStream);
131     XMASSERT(pInputStream);
132
133     for (i = 0; i < HalfCount; i++)
134     {
135         *(FLOAT*)pFloat = XMConvertHalfToFloat(*(const HALF*)pHalf);
136         pHalf += InputStride;
137         pFloat += OutputStride; 
138     }
139
140     return pOutputStream;
141
142 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
143 #endif // _XM_VMX128_INTRINSICS_
144 }
145
146 //------------------------------------------------------------------------------
147
148 XMFINLINE HALF XMConvertFloatToHalf
149 (
150     FLOAT Value
151 )
152 {
153 #if defined(_XM_NO_INTRINSICS_) || defined(_XM_SSE_INTRINSICS_)
154     UINT Result;
155
156     UINT IValue = ((UINT *)(&Value))[0];
157     UINT Sign = (IValue & 0x80000000U) >> 16U;
158     IValue = IValue & 0x7FFFFFFFU;      // Hack off the sign
159
160     if (IValue > 0x47FFEFFFU)
161     {
162         // The number is too large to be represented as a half.  Saturate to infinity.
163         Result = 0x7FFFU;
164     }
165     else
166     {
167         if (IValue < 0x38800000U)
168         {
169             // The number is too small to be represented as a normalized half.
170             // Convert it to a denormalized value.
171             UINT Shift = 113U - (IValue >> 23U);
172             IValue = (0x800000U | (IValue & 0x7FFFFFU)) >> Shift;
173         }
174         else
175         {
176             // Rebias the exponent to represent the value as a normalized half.
177             IValue += 0xC8000000U;
178         }
179
180         Result = ((IValue + 0x0FFFU + ((IValue >> 13U) & 1U)) >> 13U)&0x7FFFU; 
181     }
182     return (HALF)(Result|Sign);
183
184 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
185 #endif
186 }
187
188 //------------------------------------------------------------------------------
189
190 XMINLINE HALF* XMConvertFloatToHalfStream
191 (
192     HALF*        pOutputStream, 
193     size_t       OutputStride, 
194     CONST FLOAT* pInputStream, 
195     size_t       InputStride, 
196     size_t       FloatCount
197 )
198 {
199 #if defined(_XM_NO_INTRINSICS_) || defined(_XM_SSE_INTRINSICS_)
200
201     size_t  i;
202     BYTE* pFloat = (BYTE*)pInputStream;
203     BYTE* pHalf = (BYTE*)pOutputStream;
204
205     XMASSERT(pOutputStream);
206     XMASSERT(pInputStream);
207
208     for (i = 0; i < FloatCount; i++)
209     {
210         *(HALF*)pHalf = XMConvertFloatToHalf(*(FLOAT*)pFloat);
211         pFloat += InputStride; 
212         pHalf += OutputStride;
213     }
214     return pOutputStream;
215 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
216 #endif // _XM_VMX128_INTRINSICS_
217 }
218
219 //------------------------------------------------------------------------------
220
221 #if defined(_XM_NO_INTRINSICS_) || defined(_XM_SSE_INTRINSICS_)
222 // For VMX128, these routines are all defines in the main header
223
224 #pragma warning(push)
225 #pragma warning(disable:4701) // Prevent warnings about 'Result' potentially being used without having been initialized
226
227 XMINLINE XMVECTOR XMConvertVectorIntToFloat
228 (
229     FXMVECTOR VInt,
230     UINT     DivExponent
231 )
232 {
233 #if defined(_XM_NO_INTRINSICS_)
234     UINT ElementIndex;
235     FLOAT fScale;
236     XMVECTOR Result;
237     XMASSERT(DivExponent<32);
238     fScale = 1.0f / (FLOAT)(1U << DivExponent);
239     ElementIndex = 0;
240     do {
241         INT iTemp = (INT)VInt.vector4_u32[ElementIndex];
242         Result.vector4_f32[ElementIndex] = ((FLOAT)iTemp) * fScale;
243     } while (++ElementIndex<4);
244     return Result;
245 #else // _XM_SSE_INTRINSICS_
246     XMASSERT(DivExponent<32);
247     // Convert to floats
248     XMVECTOR vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&VInt)[0]);
249     // Convert DivExponent into 1.0f/(1<<DivExponent)
250     UINT uScale = 0x3F800000U - (DivExponent << 23);
251     // Splat the scalar value
252     __m128i vScale = _mm_set1_epi32(uScale);
253     vResult = _mm_mul_ps(vResult,reinterpret_cast<const __m128 *>(&vScale)[0]);
254     return vResult;
255 #endif
256 }
257
258 //------------------------------------------------------------------------------
259
260 XMINLINE XMVECTOR XMConvertVectorFloatToInt
261 (
262     FXMVECTOR VFloat,
263     UINT     MulExponent
264 )
265 {
266 #if defined(_XM_NO_INTRINSICS_)
267     UINT ElementIndex;
268     XMVECTOR Result;
269     FLOAT fScale;
270     XMASSERT(MulExponent<32);
271     // Get the scalar factor.
272     fScale = (FLOAT)(1U << MulExponent);
273     ElementIndex = 0;
274     do {
275         INT iResult;
276         FLOAT fTemp = VFloat.vector4_f32[ElementIndex]*fScale;
277         if (fTemp <= -(65536.0f*32768.0f)) {
278             iResult = (-0x7FFFFFFF)-1;
279         } else if (fTemp > (65536.0f*32768.0f)-128.0f) {
280             iResult = 0x7FFFFFFF;
281         } else {
282             iResult = (INT)fTemp;
283         }
284         Result.vector4_u32[ElementIndex] = (UINT)iResult;
285     } while (++ElementIndex<4);
286     return Result;
287 #else // _XM_SSE_INTRINSICS_
288     XMASSERT(MulExponent<32);
289     XMVECTOR vResult = _mm_set_ps1((FLOAT)(1U << MulExponent));
290     vResult = _mm_mul_ps(vResult,VFloat);
291     // In case of positive overflow, detect it
292     XMVECTOR vOverflow = _mm_cmpgt_ps(vResult,g_XMMaxInt);
293     // Float to int conversion
294     __m128i vResulti = _mm_cvttps_epi32(vResult);
295     // If there was positive overflow, set to 0x7FFFFFFF
296     vResult = _mm_and_ps(vOverflow,g_XMAbsMask);
297     vOverflow = _mm_andnot_ps(vOverflow,reinterpret_cast<const __m128 *>(&vResulti)[0]);
298     vOverflow = _mm_or_ps(vOverflow,vResult);
299     return vOverflow;
300 #endif
301 }
302
303 //------------------------------------------------------------------------------
304
305 XMINLINE XMVECTOR XMConvertVectorUIntToFloat
306 (
307     FXMVECTOR VUInt,
308     UINT      DivExponent
309 )
310 {
311 #if defined(_XM_NO_INTRINSICS_)
312     UINT ElementIndex;
313     FLOAT fScale;
314     XMVECTOR Result;
315     XMASSERT(DivExponent<32);
316     fScale = 1.0f / (FLOAT)(1U << DivExponent);
317     ElementIndex = 0;
318     do {
319         Result.vector4_f32[ElementIndex] = (FLOAT)VUInt.vector4_u32[ElementIndex] * fScale;
320     } while (++ElementIndex<4);
321     return Result;
322 #else // _XM_SSE_INTRINSICS_
323     XMASSERT(DivExponent<32);
324     // For the values that are higher than 0x7FFFFFFF, a fixup is needed
325     // Determine which ones need the fix.
326     XMVECTOR vMask = _mm_and_ps(VUInt,g_XMNegativeZero);
327     // Force all values positive
328     XMVECTOR vResult = _mm_xor_ps(VUInt,vMask);
329     // Convert to floats
330     vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vResult)[0]);
331     // Convert 0x80000000 -> 0xFFFFFFFF
332     __m128i iMask = _mm_srai_epi32(reinterpret_cast<const __m128i *>(&vMask)[0],31);
333     // For only the ones that are too big, add the fixup
334     vMask = _mm_and_ps(reinterpret_cast<const __m128 *>(&iMask)[0],g_XMFixUnsigned);
335     vResult = _mm_add_ps(vResult,vMask);
336     // Convert DivExponent into 1.0f/(1<<DivExponent)
337     UINT uScale = 0x3F800000U - (DivExponent << 23);
338     // Splat
339     iMask = _mm_set1_epi32(uScale);
340     vResult = _mm_mul_ps(vResult,reinterpret_cast<const __m128 *>(&iMask)[0]);
341     return vResult;
342 #endif
343 }
344
345 //------------------------------------------------------------------------------
346
347 XMINLINE XMVECTOR XMConvertVectorFloatToUInt
348 (
349     FXMVECTOR VFloat,
350     UINT      MulExponent
351 )
352 {
353 #if defined(_XM_NO_INTRINSICS_)
354     UINT ElementIndex;
355     XMVECTOR Result;
356     FLOAT fScale;
357     XMASSERT(MulExponent<32);
358     // Get the scalar factor.
359     fScale = (FLOAT)(1U << MulExponent);
360     ElementIndex = 0;
361     do {
362         UINT uResult;
363         FLOAT fTemp = VFloat.vector4_f32[ElementIndex]*fScale;
364         if (fTemp <= 0.0f) {
365             uResult = 0;
366         } else if (fTemp >= (65536.0f*65536.0f)) {
367             uResult = 0xFFFFFFFFU;
368         } else {
369             uResult = (UINT)fTemp;
370         }
371         Result.vector4_u32[ElementIndex] = uResult;
372     } while (++ElementIndex<4);
373     return Result;
374 #else // _XM_SSE_INTRINSICS_
375     XMASSERT(MulExponent<32);
376     XMVECTOR vResult = _mm_set_ps1(static_cast<float>(1U << MulExponent));
377     vResult = _mm_mul_ps(vResult,VFloat);
378     // Clamp to >=0
379     vResult = _mm_max_ps(vResult,g_XMZero);
380     // Any numbers that are too big, set to 0xFFFFFFFFU
381     XMVECTOR vOverflow = _mm_cmpgt_ps(vResult,g_XMMaxUInt);
382     XMVECTOR vValue = g_XMUnsignedFix;
383     // Too large for a signed integer?
384     XMVECTOR vMask = _mm_cmpge_ps(vResult,vValue);
385     // Zero for number's lower than 0x80000000, 32768.0f*65536.0f otherwise
386     vValue = _mm_and_ps(vValue,vMask);
387     // Perform fixup only on numbers too large (Keeps low bit precision)
388     vResult = _mm_sub_ps(vResult,vValue);
389     __m128i vResulti = _mm_cvttps_epi32(vResult);
390     // Convert from signed to unsigned pnly if greater than 0x80000000
391     vMask = _mm_and_ps(vMask,g_XMNegativeZero);
392     vResult = _mm_xor_ps(reinterpret_cast<const __m128 *>(&vResulti)[0],vMask);
393     // On those that are too large, set to 0xFFFFFFFF
394     vResult = _mm_or_ps(vResult,vOverflow);
395     return vResult;
396 #endif
397 }
398
399 #pragma warning(pop)
400
401 #endif // _XM_NO_INTRINSICS_ || _XM_SSE_INTRINSICS_
402
403 /****************************************************************************
404  *
405  * Vector and matrix load operations
406  *
407  ****************************************************************************/
408
409 //------------------------------------------------------------------------------
410
411 XMFINLINE XMVECTOR XMLoadInt(CONST UINT* pSource)
412 {
413 #if defined(_XM_NO_INTRINSICS_)
414
415     XMVECTOR V;
416     XMASSERT(pSource);
417     XMASSERT(((UINT_PTR)pSource & 3) == 0);
418
419     V.vector4_u32[0] = *pSource;
420
421     return V;
422
423 #elif defined(_XM_SSE_INTRINSICS_)
424     XMASSERT(pSource);
425     XMASSERT(((UINT_PTR)pSource & 3) == 0);
426
427     return _mm_load_ss( (const float*)pSource );
428 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
429 #endif // _XM_VMX128_INTRINSICS_
430 }
431
432 //------------------------------------------------------------------------------
433
434 XMFINLINE XMVECTOR XMLoadFloat(CONST FLOAT* pSource)
435 {
436 #if defined(_XM_NO_INTRINSICS_)
437
438     XMVECTOR V;
439     XMASSERT(pSource);
440     XMASSERT(((UINT_PTR)pSource & 3) == 0);
441
442     V.vector4_f32[0] = *pSource;
443
444     return V;
445
446 #elif defined(_XM_SSE_INTRINSICS_)
447     XMASSERT(pSource);
448     XMASSERT(((UINT_PTR)pSource & 3) == 0);
449
450     return _mm_load_ss( pSource );
451 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
452 #endif // _XM_VMX128_INTRINSICS_
453 }
454
455 //------------------------------------------------------------------------------
456
457 XMFINLINE XMVECTOR XMLoadInt2
458 (
459     CONST UINT* pSource
460 )
461 {
462 #if defined(_XM_NO_INTRINSICS_)
463
464     XMVECTOR V;
465
466     XMASSERT(pSource);
467
468     V.vector4_u32[0] = pSource[0];
469     V.vector4_u32[1] = pSource[1];
470
471     return V;
472 #elif defined(_XM_SSE_INTRINSICS_)
473
474     XMASSERT(pSource);
475
476     __m128 x = _mm_load_ss( (const float*)pSource );
477     __m128 y = _mm_load_ss( (const float*)(pSource+1) );
478     return _mm_unpacklo_ps( x, y );
479 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
480 #endif // _XM_VMX128_INTRINSICS_
481 }
482
483 //------------------------------------------------------------------------------
484
485 XMFINLINE XMVECTOR XMLoadSInt2
486 (
487     CONST XMINT2* pSource
488 )
489 {
490 #if defined(_XM_NO_INTRINSICS_)
491     XMVECTOR V;
492     XMASSERT(pSource);
493
494     V.vector4_f32[0] = (float)pSource->x;
495     V.vector4_f32[1] = (float)pSource->y;
496     return V;
497
498 #elif defined(_XM_SSE_INTRINSICS_)
499     XMASSERT(pSource);
500
501     __m128 x = _mm_load_ss( (const float*)&pSource->x );
502     __m128 y = _mm_load_ss( (const float*)&pSource->y );
503     __m128 V = _mm_unpacklo_ps( x, y );
504     return _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&V)[0]);
505 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
506 #endif // _XM_VMX128_INTRINSICS_
507 }
508
509 //------------------------------------------------------------------------------
510
511 XMFINLINE XMVECTOR XMLoadUInt2
512 (
513     CONST XMUINT2* pSource
514 )
515 {
516 #if defined(_XM_NO_INTRINSICS_)
517     XMVECTOR V;
518     XMASSERT(pSource);
519
520     V.vector4_f32[0] = (float)pSource->x;
521     V.vector4_f32[1] = (float)pSource->y;
522     return V;
523
524 #elif defined(_XM_SSE_INTRINSICS_)
525     XMASSERT(pSource);
526
527     __m128 x = _mm_load_ss( (const float*)&pSource->x );
528     __m128 y = _mm_load_ss( (const float*)&pSource->y );
529     __m128 V = _mm_unpacklo_ps( x, y );
530     // For the values that are higher than 0x7FFFFFFF, a fixup is needed
531     // Determine which ones need the fix.
532     XMVECTOR vMask = _mm_and_ps(V,g_XMNegativeZero);
533     // Force all values positive
534     XMVECTOR vResult = _mm_xor_ps(V,vMask);
535     // Convert to floats
536     vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vResult)[0]);
537     // Convert 0x80000000 -> 0xFFFFFFFF
538     __m128i iMask = _mm_srai_epi32(reinterpret_cast<const __m128i *>(&vMask)[0],31);
539     // For only the ones that are too big, add the fixup
540     vMask = _mm_and_ps(reinterpret_cast<const __m128 *>(&iMask)[0],g_XMFixUnsigned);
541     vResult = _mm_add_ps(vResult,vMask);
542     return vResult;
543 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
544 #endif // _XM_VMX128_INTRINSICS_
545 }
546
547 //------------------------------------------------------------------------------
548
549 XMFINLINE XMVECTOR XMLoadInt2A
550 (
551     CONST UINT* pSource
552 )
553 {
554 #if defined(_XM_NO_INTRINSICS_)
555
556     XMVECTOR V;
557
558     XMASSERT(pSource);
559     XMASSERT(((UINT_PTR)pSource & 0xF) == 0);
560
561     V.vector4_u32[0] = pSource[0];
562     V.vector4_u32[1] = pSource[1];
563
564     return V;
565
566 #elif defined(_XM_SSE_INTRINSICS_)
567
568     XMASSERT(pSource);
569     XMASSERT(((UINT_PTR)pSource & 0xF) == 0);
570
571     __m128i V = _mm_loadl_epi64( (const __m128i*)pSource );
572     return reinterpret_cast<__m128 *>(&V)[0];
573
574 #else // _XM_VMX128_INTRINSICS_
575 #endif // _XM_VMX128_INTRINSICS_
576 }
577
578 //------------------------------------------------------------------------------
579
580 XMFINLINE XMVECTOR XMLoadFloat2
581 (
582     CONST XMFLOAT2* pSource
583 )
584 {
585 #if defined(_XM_NO_INTRINSICS_)
586     XMVECTOR V;
587     XMASSERT(pSource);
588
589     ((UINT *)(&V.vector4_f32[0]))[0] = ((const UINT *)(&pSource->x))[0];
590     ((UINT *)(&V.vector4_f32[1]))[0] = ((const UINT *)(&pSource->y))[0];
591     return V;
592 #elif defined(_XM_SSE_INTRINSICS_)
593     XMASSERT(pSource);
594
595     __m128 x = _mm_load_ss( &pSource->x );
596     __m128 y = _mm_load_ss( &pSource->y );
597     return _mm_unpacklo_ps( x, y );
598 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
599 #endif // _XM_VMX128_INTRINSICS_
600 }
601
602 //------------------------------------------------------------------------------
603
604 XMFINLINE XMVECTOR XMLoadFloat2A
605 (
606     CONST XMFLOAT2A* pSource
607 )
608 {
609 #if defined(_XM_NO_INTRINSICS_)
610
611     XMVECTOR V;
612
613     XMASSERT(pSource);
614     XMASSERT(((UINT_PTR)pSource & 0xF) == 0);
615
616     V.vector4_f32[0] = pSource->x;
617     V.vector4_f32[1] = pSource->y;
618
619     return V;
620
621 #elif defined(_XM_SSE_INTRINSICS_)
622     XMASSERT(pSource);
623     XMASSERT(((UINT_PTR)pSource & 0xF) == 0);
624
625     __m128i V = _mm_loadl_epi64( (const __m128i*)pSource );
626     return reinterpret_cast<__m128 *>(&V)[0];
627 #else // _XM_VMX128_INTRINSICS_
628 #endif // _XM_VMX128_INTRINSICS_
629 }
630     
631 //------------------------------------------------------------------------------
632
633 XMFINLINE XMVECTOR XMLoadHalf2
634 (
635     CONST XMHALF2* pSource
636 )
637 {
638 #if defined(_XM_NO_INTRINSICS_)
639     XMASSERT(pSource);
640     {
641     XMVECTOR vResult = {
642         XMConvertHalfToFloat(pSource->x),
643         XMConvertHalfToFloat(pSource->y),
644         0.0f,
645         0.0f
646     };
647     return vResult;
648     }
649 #elif defined(_XM_SSE_INTRINSICS_)
650     XMASSERT(pSource);
651     XMVECTOR vResult = {
652         XMConvertHalfToFloat(pSource->x),
653         XMConvertHalfToFloat(pSource->y),
654         0.0f,
655         0.0f
656     };
657     return vResult;
658
659 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
660 #endif // _XM_VMX128_INTRINSICS_
661 }
662
663 //------------------------------------------------------------------------------
664
665 XMFINLINE XMVECTOR XMLoadShortN2
666 (
667     CONST XMSHORTN2* pSource
668 )
669 {
670 #if defined(_XM_NO_INTRINSICS_)
671     XMASSERT(pSource);
672     {
673     XMVECTOR vResult = {
674         (pSource->x == -32768) ? -1.f : ((FLOAT)pSource->x * (1.0f/32767.0f)),
675         (pSource->y == -32768) ? -1.f : ((FLOAT)pSource->y * (1.0f/32767.0f)),
676         0.0f,
677         0.0f
678     };
679     return vResult;
680     }
681
682 #elif defined(_XM_SSE_INTRINSICS_)
683     XMASSERT(pSource);
684     // Splat the two shorts in all four entries (WORD alignment okay,
685     // DWORD alignment preferred)
686     __m128 vTemp = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->x));
687     // Mask x&0xFFFF, y&0xFFFF0000,z&0,w&0
688     vTemp = _mm_and_ps(vTemp,g_XMMaskX16Y16);
689     // x needs to be sign extended
690     vTemp = _mm_xor_ps(vTemp,g_XMFlipX16Y16);
691     // Convert to floating point numbers
692     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
693     // x - 0x8000 to undo the signed order.
694     vTemp = _mm_add_ps(vTemp,g_XMFixX16Y16);
695     // Convert -1.0f - 1.0f
696     vTemp = _mm_mul_ps(vTemp,g_XMNormalizeX16Y16);
697     // Clamp result (for case of -32768)
698     return _mm_max_ps( vTemp, g_XMNegativeOne );
699 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
700 #endif // _XM_VMX128_INTRINSICS_
701 }
702
703 //------------------------------------------------------------------------------
704
705 XMFINLINE XMVECTOR XMLoadShort2
706 (
707     CONST XMSHORT2* pSource
708 )
709 {
710 #if defined(_XM_NO_INTRINSICS_)
711
712     XMVECTOR V;
713
714     XMASSERT(pSource);
715
716     V.vector4_f32[0] = (FLOAT)pSource->x;
717     V.vector4_f32[1] = (FLOAT)pSource->y;
718
719     return V;
720
721 #elif defined(_XM_SSE_INTRINSICS_)
722     XMASSERT(pSource);
723     // Splat the two shorts in all four entries (WORD alignment okay,
724     // DWORD alignment preferred)
725     __m128 vTemp = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->x));
726     // Mask x&0xFFFF, y&0xFFFF0000,z&0,w&0
727     vTemp = _mm_and_ps(vTemp,g_XMMaskX16Y16);
728     // x needs to be sign extended
729     vTemp = _mm_xor_ps(vTemp,g_XMFlipX16Y16);
730     // Convert to floating point numbers
731     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
732     // x - 0x8000 to undo the signed order.
733     vTemp = _mm_add_ps(vTemp,g_XMFixX16Y16);
734     // Y is 65536 too large
735     return _mm_mul_ps(vTemp,g_XMFixupY16);
736 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
737 #endif // _XM_VMX128_INTRINSICS_
738 }
739
740 //------------------------------------------------------------------------------
741
742 XMFINLINE XMVECTOR XMLoadUShortN2
743 (
744     CONST XMUSHORTN2* pSource
745 )
746 {
747 #if defined(_XM_NO_INTRINSICS_)
748
749     XMVECTOR V;
750
751     XMASSERT(pSource);
752
753     V.vector4_f32[0] = (FLOAT)pSource->x / 65535.0f;
754     V.vector4_f32[1] = (FLOAT)pSource->y / 65535.0f;
755
756     return V;
757
758 #elif defined(_XM_SSE_INTRINSICS_)
759     static const XMVECTORF32 FixupY16 = {1.0f/65535.0f,1.0f/(65535.0f*65536.0f),0.0f,0.0f};
760     static const XMVECTORF32 FixaddY16 = {0,32768.0f*65536.0f,0,0};
761     XMASSERT(pSource);
762     // Splat the two shorts in all four entries (WORD alignment okay,
763     // DWORD alignment preferred)
764     __m128 vTemp = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->x));
765     // Mask x&0xFFFF, y&0xFFFF0000,z&0,w&0
766     vTemp = _mm_and_ps(vTemp,g_XMMaskX16Y16);
767     // y needs to be sign flipped
768     vTemp = _mm_xor_ps(vTemp,g_XMFlipY);
769     // Convert to floating point numbers
770     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
771     // y + 0x8000 to undo the signed order.
772     vTemp = _mm_add_ps(vTemp,FixaddY16);
773     // Y is 65536 times too large
774     vTemp = _mm_mul_ps(vTemp,FixupY16);
775     return vTemp;
776 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
777 #endif // _XM_VMX128_INTRINSICS_
778 }
779
780 //------------------------------------------------------------------------------
781
782 XMFINLINE XMVECTOR XMLoadUShort2
783 (
784     CONST XMUSHORT2* pSource
785 )
786 {
787 #if defined(_XM_NO_INTRINSICS_)
788
789     XMVECTOR V;
790
791     XMASSERT(pSource);
792
793     V.vector4_f32[0] = (FLOAT)pSource->x;
794     V.vector4_f32[1] = (FLOAT)pSource->y;
795
796     return V;
797
798 #elif defined(_XM_SSE_INTRINSICS_)
799     static const XMVECTORF32 FixaddY16 = {0,32768.0f,0,0};
800     XMASSERT(pSource);
801     // Splat the two shorts in all four entries (WORD alignment okay,
802     // DWORD alignment preferred)
803     __m128 vTemp = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->x));
804     // Mask x&0xFFFF, y&0xFFFF0000,z&0,w&0
805     vTemp = _mm_and_ps(vTemp,g_XMMaskX16Y16);
806     // y needs to be sign flipped
807     vTemp = _mm_xor_ps(vTemp,g_XMFlipY);
808     // Convert to floating point numbers
809     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
810     // Y is 65536 times too large
811     vTemp = _mm_mul_ps(vTemp,g_XMFixupY16);
812     // y + 0x8000 to undo the signed order.
813     vTemp = _mm_add_ps(vTemp,FixaddY16);
814     return vTemp;
815 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
816 #endif // _XM_VMX128_INTRINSICS_
817 }
818
819 //------------------------------------------------------------------------------
820
821 XMFINLINE XMVECTOR XMLoadByteN2
822 (
823     CONST XMBYTEN2* pSource
824 )
825 {
826     XMASSERT(pSource);
827     {
828     XMVECTOR vResult = {
829         (pSource->x == -128) ? -1.f : ((FLOAT)pSource->x * (1.0f/127.0f)),
830         (pSource->y == -128) ? -1.f : ((FLOAT)pSource->y * (1.0f/127.0f)),
831         0.0f,
832         0.0f
833     };
834     return vResult;
835     }
836 }
837
838 //------------------------------------------------------------------------------
839
840 XMFINLINE XMVECTOR XMLoadByte2
841 (
842     CONST XMBYTE2* pSource
843 )
844 {
845     XMASSERT(pSource);
846     {
847     XMVECTOR vResult = {
848         (FLOAT)pSource->x,
849         (FLOAT)pSource->y,
850         0.0f,
851         0.0f
852     };
853     return vResult;
854     }
855 }
856
857 //------------------------------------------------------------------------------
858
859 XMFINLINE XMVECTOR XMLoadUByteN2
860 (
861     CONST XMUBYTEN2* pSource
862 )
863 {
864     XMASSERT(pSource);
865     {
866     XMVECTOR vResult = {
867         (FLOAT)pSource->x * (1.0f/255.0f),
868         (FLOAT)pSource->y * (1.0f/255.0f),
869         0.0f,
870         0.0f
871     };
872     return vResult;
873     }
874 }
875
876 //------------------------------------------------------------------------------
877
878 XMFINLINE XMVECTOR XMLoadUByte2
879 (
880     CONST XMUBYTE2* pSource
881 )
882 {
883     XMASSERT(pSource);
884     {
885     XMVECTOR vResult = {
886         (FLOAT)pSource->x,
887         (FLOAT)pSource->y,
888         0.0f,
889         0.0f
890     };
891     return vResult;
892     }
893 }
894
895 //------------------------------------------------------------------------------
896
897 XMFINLINE XMVECTOR XMLoadInt3
898 (
899     CONST UINT* pSource
900 )
901 {
902 #if defined(_XM_NO_INTRINSICS_)
903
904     XMVECTOR V;
905
906     XMASSERT(pSource);
907
908     V.vector4_u32[0] = pSource[0];
909     V.vector4_u32[1] = pSource[1];
910     V.vector4_u32[2] = pSource[2];
911
912     return V;
913
914 #elif defined(_XM_SSE_INTRINSICS_)
915     XMASSERT(pSource);
916
917 #ifdef _XM_ISVS2005_
918     __m128i V = _mm_set_epi32( 0, *(pSource+2), *(pSource+1), *pSource );
919     return reinterpret_cast<__m128 *>(&V)[0];
920 #else
921     __m128 x = _mm_load_ss( (const float*)pSource );
922     __m128 y = _mm_load_ss( (const float*)(pSource+1) );
923     __m128 z = _mm_load_ss( (const float*)(pSource+2) );
924     __m128 xy = _mm_unpacklo_ps( x, y );
925     return _mm_movelh_ps( xy, z );
926 #endif // !_XM_ISVS2005_
927 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
928 #endif // _XM_VMX128_INTRINSICS_
929 }
930
931 //------------------------------------------------------------------------------
932
933 XMFINLINE XMVECTOR XMLoadSInt3
934 (
935     CONST XMINT3* pSource
936 )
937 {
938 #if defined(_XM_NO_INTRINSICS_)
939     XMVECTOR V;
940     XMASSERT(pSource);
941
942 #ifdef _XBOX_VER
943     V = XMLoadInt3( (const UINT*)pSource );
944     return XMConvertVectorIntToFloat( V, 0 );
945 #else
946     V.vector4_f32[0] = (float)pSource->x;
947     V.vector4_f32[1] = (float)pSource->y;
948     V.vector4_f32[2] = (float)pSource->z;
949     return V;
950 #endif
951
952 #elif defined(_XM_SSE_INTRINSICS_)
953     XMASSERT(pSource);
954
955 #ifdef _XM_ISVS2005_
956     __m128i V = _mm_set_epi32( 0, pSource->z, pSource->y, pSource->x );
957     return _mm_cvtepi32_ps(V);
958 #else
959     __m128 x = _mm_load_ss( (const float*)&pSource->x );
960     __m128 y = _mm_load_ss( (const float*)&pSource->y );
961     __m128 z = _mm_load_ss( (const float*)&pSource->z );
962     __m128 xy = _mm_unpacklo_ps( x, y );
963     __m128 V = _mm_movelh_ps( xy, z );
964     return _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&V)[0]);
965 #endif // !_XM_ISVS2005_
966 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
967 #endif // _XM_VMX128_INTRINSICS_
968 }
969
970 //------------------------------------------------------------------------------
971
972 XMFINLINE XMVECTOR XMLoadUInt3
973 (
974     CONST XMUINT3* pSource
975 )
976 {
977 #if defined(_XM_NO_INTRINSICS_)
978     XMVECTOR V;
979     XMASSERT(pSource);
980
981     V.vector4_f32[0] = (float)pSource->x;
982     V.vector4_f32[1] = (float)pSource->y;
983     V.vector4_f32[2] = (float)pSource->z;
984     return V;
985
986 #elif defined(_XM_SSE_INTRINSICS_)
987     XMASSERT(pSource);
988
989 #ifdef _XM_ISVS2005_
990     __m128i V = _mm_set_epi32( 0, pSource->z, pSource->y, pSource->x );
991     // For the values that are higher than 0x7FFFFFFF, a fixup is needed
992     // Determine which ones need the fix.
993     XMVECTOR vMask = _mm_and_ps(reinterpret_cast<const __m128 *>(&V)[0],g_XMNegativeZero);
994     // Force all values positive
995     XMVECTOR vResult = _mm_xor_ps(reinterpret_cast<const __m128 *>(&V)[0],vMask);
996 #else
997     __m128 x = _mm_load_ss( (const float*)&pSource->x );
998     __m128 y = _mm_load_ss( (const float*)&pSource->y );
999     __m128 z = _mm_load_ss( (const float*)&pSource->z );
1000     __m128 xy = _mm_unpacklo_ps( x, y );
1001     __m128 V = _mm_movelh_ps( xy, z );
1002     // For the values that are higher than 0x7FFFFFFF, a fixup is needed
1003     // Determine which ones need the fix.
1004     XMVECTOR vMask = _mm_and_ps(V,g_XMNegativeZero);
1005     // Force all values positive
1006     XMVECTOR vResult = _mm_xor_ps(V,vMask);
1007 #endif // !_XM_ISVS2005_
1008     // Convert to floats
1009     vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vResult)[0]);
1010     // Convert 0x80000000 -> 0xFFFFFFFF
1011     __m128i iMask = _mm_srai_epi32(reinterpret_cast<const __m128i *>(&vMask)[0],31);
1012     // For only the ones that are too big, add the fixup
1013     vMask = _mm_and_ps(reinterpret_cast<const __m128 *>(&iMask)[0],g_XMFixUnsigned);
1014     vResult = _mm_add_ps(vResult,vMask);
1015     return vResult; 
1016
1017 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
1018 #endif // _XM_VMX128_INTRINSICS_
1019 }
1020
1021 //------------------------------------------------------------------------------
1022
1023 XMFINLINE XMVECTOR XMLoadInt3A
1024 (
1025     CONST UINT* pSource
1026 )
1027 {
1028 #if defined(_XM_NO_INTRINSICS_)
1029
1030     XMVECTOR V;
1031
1032     XMASSERT(pSource);
1033     XMASSERT(((UINT_PTR)pSource & 0xF) == 0);
1034
1035     V.vector4_u32[0] = pSource[0];
1036     V.vector4_u32[1] = pSource[1];
1037     V.vector4_u32[2] = pSource[2];
1038
1039     return V;
1040
1041 #elif defined(_XM_SSE_INTRINSICS_)
1042     XMASSERT(pSource);
1043
1044     // Reads an extra integer that is 'undefined'
1045
1046     __m128i V = _mm_load_si128( (const __m128i*)pSource );
1047     return reinterpret_cast<__m128 *>(&V)[0];
1048 #else // _XM_VMX128_INTRINSICS_
1049 #endif // _XM_VMX128_INTRINSICS_
1050 }
1051
1052 //------------------------------------------------------------------------------
1053
1054 XMFINLINE XMVECTOR XMLoadFloat3
1055 (
1056     CONST XMFLOAT3* pSource
1057 )
1058 {
1059 #if defined(_XM_NO_INTRINSICS_)
1060     XMVECTOR V;
1061     XMASSERT(pSource);
1062
1063     ((UINT *)(&V.vector4_f32[0]))[0] = ((const UINT *)(&pSource->x))[0];
1064     ((UINT *)(&V.vector4_f32[1]))[0] = ((const UINT *)(&pSource->y))[0];
1065     ((UINT *)(&V.vector4_f32[2]))[0] = ((const UINT *)(&pSource->z))[0];
1066     return V;
1067 #elif defined(_XM_SSE_INTRINSICS_)
1068     XMASSERT(pSource);
1069
1070 #ifdef _XM_ISVS2005_
1071     // This reads 1 floats past the memory that should be ignored.
1072     // Need to continue to do this for VS 2005 due to compiler issue but prefer new method
1073     // to avoid triggering issues with memory debug tools (like AV)
1074     return _mm_loadu_ps( &pSource->x );
1075 #else
1076     __m128 x = _mm_load_ss( &pSource->x );
1077     __m128 y = _mm_load_ss( &pSource->y );
1078     __m128 z = _mm_load_ss( &pSource->z );
1079     __m128 xy = _mm_unpacklo_ps( x, y );
1080     return _mm_movelh_ps( xy, z );
1081 #endif // !_XM_ISVS2005_
1082 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
1083 #endif // _XM_VMX128_INTRINSICS_
1084 }
1085
1086 //------------------------------------------------------------------------------
1087
1088 XMFINLINE XMVECTOR XMLoadFloat3A
1089 (
1090     CONST XMFLOAT3A* pSource
1091 )
1092 {
1093 #if defined(_XM_NO_INTRINSICS_)
1094
1095     XMVECTOR V;
1096
1097     XMASSERT(pSource);
1098     XMASSERT(((UINT_PTR)pSource & 0xF) == 0);
1099
1100     V.vector4_f32[0] = pSource->x;
1101     V.vector4_f32[1] = pSource->y;
1102     V.vector4_f32[2] = pSource->z;
1103
1104     return V;
1105
1106 #elif defined(_XM_SSE_INTRINSICS_)
1107     XMASSERT(pSource);
1108     XMASSERT(((UINT_PTR)pSource & 0xF) == 0);
1109
1110     // This reads 1 floats past the memory that should be ignored.
1111     return _mm_load_ps( &pSource->x );
1112 #else // _XM_VMX128_INTRINSICS_
1113 #endif // _XM_VMX128_INTRINSICS_
1114 }
1115
1116 //------------------------------------------------------------------------------
1117
1118 XMFINLINE XMVECTOR XMLoadUHenDN3
1119 (
1120     CONST XMUHENDN3* pSource
1121 )
1122 {
1123 #if defined(_XM_NO_INTRINSICS_)
1124
1125     XMVECTOR          V;
1126     UINT              Element;
1127
1128     XMASSERT(pSource);
1129
1130     Element = pSource->v & 0x7FF;
1131     V.vector4_f32[0] = (FLOAT)Element / 2047.0f;
1132     Element = (pSource->v >> 11) & 0x7FF;
1133     V.vector4_f32[1] = (FLOAT)Element / 2047.0f;
1134     Element = (pSource->v >> 22) & 0x3FF;
1135     V.vector4_f32[2] = (FLOAT)Element / 1023.0f;
1136
1137     return V;
1138
1139 #elif defined(_XM_SSE_INTRINSICS_)
1140     static const XMVECTORF32 UHenDN3Mul = {1.0f/2047.0f,1.0f/(2047.0f*2048.0f),1.0f/(1023.0f*2048.0f*2048.0f),0};
1141     XMASSERT(pSource);
1142     // Get the 32 bit value and splat it
1143     XMVECTOR vResult = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
1144     // Mask off x, y and z
1145     vResult = _mm_and_ps(vResult,g_XMMaskHenD3);
1146     // Convert x and y to unsigned
1147     vResult = _mm_xor_ps(vResult,g_XMFlipZ);
1148     // Convert to float
1149     vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vResult)[0]);
1150     // Convert x and y back to signed
1151     vResult = _mm_add_ps(vResult,g_XMAddUHenD3);
1152     // Normalize x,y and z to -1.0f-1.0f
1153     vResult = _mm_mul_ps(vResult,UHenDN3Mul);
1154     return vResult;
1155 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
1156 #endif // _XM_VMX128_INTRINSICS_
1157 }
1158
1159 //------------------------------------------------------------------------------
1160
1161 XMFINLINE XMVECTOR XMLoadUHenD3
1162 (
1163     CONST XMUHEND3* pSource
1164 )
1165 {
1166 #if defined(_XM_NO_INTRINSICS_)
1167
1168     XMVECTOR          V;
1169     UINT              Element;
1170
1171     XMASSERT(pSource);
1172
1173     Element = pSource->v & 0x7FF;
1174     V.vector4_f32[0] = (FLOAT)Element;
1175     Element = (pSource->v >> 11) & 0x7FF;
1176     V.vector4_f32[1] = (FLOAT)Element;
1177     Element = (pSource->v >> 22) & 0x3FF;
1178     V.vector4_f32[2] = (FLOAT)Element;
1179
1180     return V;
1181
1182 #elif defined(_XM_SSE_INTRINSICS_)
1183     XMASSERT(pSource);
1184     // Get the 32 bit value and splat it
1185     XMVECTOR vResult = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
1186     // Mask off x, y and z
1187     vResult = _mm_and_ps(vResult,g_XMMaskHenD3);
1188     // Convert x and y to unsigned
1189     vResult = _mm_xor_ps(vResult,g_XMFlipZ);
1190     // Convert to float
1191     vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vResult)[0]);
1192     // Convert x and y back to signed
1193     vResult = _mm_add_ps(vResult,g_XMAddUHenD3);
1194     // Normalize x and y to -1024-1023.0f and z to -512-511.0f
1195     vResult = _mm_mul_ps(vResult,g_XMMulHenD3);
1196     return vResult;
1197 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
1198 #endif // _XM_VMX128_INTRINSICS_
1199 }
1200
1201 //------------------------------------------------------------------------------
1202
1203 XMFINLINE XMVECTOR XMLoadHenDN3
1204 (
1205     CONST XMHENDN3* pSource
1206 )
1207 {
1208 #if defined(_XM_NO_INTRINSICS_)
1209
1210     XMVECTOR          V;
1211     UINT              Element;
1212     static CONST UINT SignExtendXY[] = {0x00000000, 0xFFFFF800};
1213     static CONST UINT SignExtendZ[] = {0x00000000, 0xFFFFFC00};
1214
1215     XMASSERT(pSource);
1216     XMASSERT((pSource->v & 0x7FF) != 0x400);
1217     XMASSERT(((pSource->v >> 11) & 0x7FF) != 0x400);
1218     XMASSERT(((pSource->v >> 22) & 0x3FF) != 0x200);
1219
1220     Element = pSource->v & 0x7FF;
1221     V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtendXY[Element >> 10]) / 1023.0f;
1222     Element = (pSource->v >> 11) & 0x7FF;
1223     V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtendXY[Element >> 10]) / 1023.0f;
1224     Element = (pSource->v >> 22) & 0x3FF;
1225     V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtendZ[Element >> 9]) / 511.0f;
1226
1227     return V;
1228
1229 #elif defined(_XM_SSE_INTRINSICS_)
1230     static const XMVECTORF32 HenDN3Mul = {1.0f/1023.0f,1.0f/(1023.0f*2048.0f),1.0f/(511.0f*2048.0f*2048.0f),0};
1231     XMASSERT(pSource);
1232     XMASSERT((pSource->v & 0x7FF) != 0x400);
1233     XMASSERT(((pSource->v >> 11) & 0x7FF) != 0x400);
1234     XMASSERT(((pSource->v >> 22) & 0x3FF) != 0x200);
1235     // Get the 32 bit value and splat it
1236     XMVECTOR vResult = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
1237     // Mask off x, y and z
1238     vResult = _mm_and_ps(vResult,g_XMMaskHenD3);
1239     // Convert x and y to unsigned
1240     vResult = _mm_xor_ps(vResult,g_XMXorHenD3);
1241     // Convert to float
1242     vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vResult)[0]);
1243     // Convert x and y back to signed
1244     vResult = _mm_add_ps(vResult,g_XMAddHenD3);
1245     // Normalize x,y and z to -1.0f-1.0f
1246     vResult = _mm_mul_ps(vResult,HenDN3Mul);
1247     return vResult;
1248 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
1249 #endif // _XM_VMX128_INTRINSICS_
1250 }
1251
1252 //------------------------------------------------------------------------------
1253
1254 XMFINLINE XMVECTOR XMLoadHenD3
1255 (
1256     CONST XMHEND3* pSource
1257 )
1258 {
1259 #if defined(_XM_NO_INTRINSICS_)
1260
1261     XMVECTOR          V;
1262     UINT              Element;
1263     static CONST UINT SignExtendXY[] = {0x00000000, 0xFFFFF800};
1264     static CONST UINT SignExtendZ[] = {0x00000000, 0xFFFFFC00};
1265
1266     XMASSERT(pSource);
1267     XMASSERT((pSource->v & 0x7FF) != 0x400);
1268     XMASSERT(((pSource->v >> 11) & 0x7FF) != 0x400);
1269     XMASSERT(((pSource->v >> 22) & 0x3FF) != 0x200);
1270
1271     Element = pSource->v & 0x7FF;
1272     V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtendXY[Element >> 10]);
1273     Element = (pSource->v >> 11) & 0x7FF;
1274     V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtendXY[Element >> 10]);
1275     Element = (pSource->v >> 22) & 0x3FF;
1276     V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtendZ[Element >> 9]);
1277
1278     return V;
1279
1280 #elif defined(_XM_SSE_INTRINSICS_)
1281     XMASSERT(pSource);
1282     XMASSERT((pSource->v & 0x7FF) != 0x400);
1283     XMASSERT(((pSource->v >> 11) & 0x7FF) != 0x400);
1284     XMASSERT(((pSource->v >> 22) & 0x3FF) != 0x200);
1285     // Get the 32 bit value and splat it
1286     XMVECTOR vResult = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
1287     // Mask off x, y and z
1288     vResult = _mm_and_ps(vResult,g_XMMaskHenD3);
1289     // Convert x and y to unsigned
1290     vResult = _mm_xor_ps(vResult,g_XMXorHenD3);
1291     // Convert to float
1292     vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vResult)[0]);
1293     // Convert x and y back to signed
1294     vResult = _mm_add_ps(vResult,g_XMAddHenD3);
1295     // Normalize x and y to -1024-1023.0f and z to -512-511.0f
1296     vResult = _mm_mul_ps(vResult,g_XMMulHenD3);
1297     return vResult;
1298 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
1299 #endif // _XM_VMX128_INTRINSICS_
1300 }
1301
1302 //------------------------------------------------------------------------------
1303
1304 XMFINLINE XMVECTOR XMLoadUDHenN3
1305 (
1306     CONST XMUDHENN3* pSource
1307 )
1308 {
1309 #if defined(_XM_NO_INTRINSICS_)
1310
1311     XMVECTOR          V;
1312     UINT              Element;
1313
1314     XMASSERT(pSource);
1315
1316     Element = pSource->v & 0x3FF;
1317     V.vector4_f32[0] = (FLOAT)Element / 1023.0f;
1318     Element = (pSource->v >> 10) & 0x7FF;
1319     V.vector4_f32[1] = (FLOAT)Element / 2047.0f;
1320     Element = (pSource->v >> 21) & 0x7FF;
1321     V.vector4_f32[2] = (FLOAT)Element / 2047.0f;
1322
1323     return V;
1324
1325 #elif defined(_XM_SSE_INTRINSICS_)
1326     static const XMVECTORF32 UDHenN3Mul = {1.0f/1023.0f,1.0f/(2047.0f*1024.0f),1.0f/(2047.0f*1024.0f*2048.0f),0};
1327     XMASSERT(pSource);
1328     // Get the 32 bit value and splat it
1329     XMVECTOR vResult = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
1330     // Mask off x, y and z
1331     vResult = _mm_and_ps(vResult,g_XMMaskDHen3);
1332     // Convert x and y to unsigned
1333     vResult = _mm_xor_ps(vResult,g_XMFlipZ);
1334     // Convert to float
1335     vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vResult)[0]);
1336     // Convert x and y back to signed
1337     vResult = _mm_add_ps(vResult,g_XMAddUHenD3);
1338     // Normalize x,y and z to -1.0f-1.0f
1339     vResult = _mm_mul_ps(vResult,UDHenN3Mul);
1340     return vResult;
1341 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
1342 #endif // _XM_VMX128_INTRINSICS_
1343 }
1344
1345 //------------------------------------------------------------------------------
1346
1347 XMFINLINE XMVECTOR XMLoadUDHen3
1348 (
1349     CONST XMUDHEN3* pSource
1350 )
1351 {
1352 #if defined(_XM_NO_INTRINSICS_)
1353
1354     XMVECTOR          V;
1355     UINT              Element;
1356
1357     XMASSERT(pSource);
1358
1359     Element = pSource->v & 0x3FF;
1360     V.vector4_f32[0] = (FLOAT)Element;
1361     Element = (pSource->v >> 10) & 0x7FF;
1362     V.vector4_f32[1] = (FLOAT)Element;
1363     Element = (pSource->v >> 21) & 0x7FF;
1364     V.vector4_f32[2] = (FLOAT)Element;
1365
1366     return V;
1367
1368 #elif defined(_XM_SSE_INTRINSICS_)
1369     XMASSERT(pSource);
1370     // Get the 32 bit value and splat it
1371     XMVECTOR vResult = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
1372     // Mask off x, y and z
1373     vResult = _mm_and_ps(vResult,g_XMMaskDHen3);
1374     // Convert x and y to unsigned
1375     vResult = _mm_xor_ps(vResult,g_XMFlipZ);
1376     // Convert to float
1377     vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vResult)[0]);
1378     // Convert x and y back to signed
1379     vResult = _mm_add_ps(vResult,g_XMAddUHenD3);
1380     // Normalize x to 0-1023.0f and y and z to 0-2047.0f
1381     vResult = _mm_mul_ps(vResult,g_XMMulDHen3);
1382     return vResult;
1383 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
1384 #endif // _XM_VMX128_INTRINSICS_
1385 }
1386
1387 //------------------------------------------------------------------------------
1388
1389 XMFINLINE XMVECTOR XMLoadDHenN3
1390 (
1391     CONST XMDHENN3* pSource
1392 )
1393 {
1394 #if defined(_XM_NO_INTRINSICS_)
1395
1396     XMVECTOR          V;
1397     UINT              Element;
1398     static CONST UINT SignExtendX[] = {0x00000000, 0xFFFFFC00};
1399     static CONST UINT SignExtendYZ[] = {0x00000000, 0xFFFFF800};
1400
1401     XMASSERT(pSource);
1402     XMASSERT((pSource->v & 0x3FF) != 0x200);
1403     XMASSERT(((pSource->v >> 10) & 0x7FF) != 0x400);
1404     XMASSERT(((pSource->v >> 21) & 0x7FF) != 0x400);
1405
1406     Element = pSource->v & 0x3FF;
1407     V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtendX[Element >> 9]) / 511.0f;
1408     Element = (pSource->v >> 10) & 0x7FF;
1409     V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtendYZ[Element >> 10]) / 1023.0f;
1410     Element = (pSource->v >> 21) & 0x7FF;
1411     V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtendYZ[Element >> 10]) / 1023.0f;
1412
1413     return V;
1414
1415 #elif defined(_XM_SSE_INTRINSICS_)
1416     static const XMVECTORF32 DHenN3Mul = {1.0f/511.0f,1.0f/(1023.0f*1024.0f),1.0f/(1023.0f*1024.0f*2048.0f),0};
1417     XMASSERT(pSource);
1418     XMASSERT((pSource->v & 0x3FF) != 0x200);
1419     XMASSERT(((pSource->v >> 10) & 0x7FF) != 0x400);
1420     XMASSERT(((pSource->v >> 21) & 0x7FF) != 0x400);
1421     // Get the 32 bit value and splat it
1422     XMVECTOR vResult = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
1423     // Mask off x, y and z
1424     vResult = _mm_and_ps(vResult,g_XMMaskDHen3);
1425     // Convert x and y to unsigned
1426     vResult = _mm_xor_ps(vResult,g_XMXorDHen3);
1427     // Convert to float
1428     vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vResult)[0]);
1429     // Convert x and y back to signed
1430     vResult = _mm_add_ps(vResult,g_XMAddDHen3);
1431     // Normalize x,y and z to -1.0f-1.0f
1432     vResult = _mm_mul_ps(vResult,DHenN3Mul);
1433     return vResult;
1434 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
1435 #endif // _XM_VMX128_INTRINSICS_
1436 }
1437
1438 //------------------------------------------------------------------------------
1439
1440 XMFINLINE XMVECTOR XMLoadDHen3
1441 (
1442     CONST XMDHEN3* pSource
1443 )
1444 {
1445 #if defined(_XM_NO_INTRINSICS_)
1446
1447     XMVECTOR          V;
1448     UINT              Element;
1449     static CONST UINT SignExtendX[] = {0x00000000, 0xFFFFFC00};
1450     static CONST UINT SignExtendYZ[] = {0x00000000, 0xFFFFF800};
1451
1452     XMASSERT(pSource);
1453     XMASSERT((pSource->v & 0x3FF) != 0x200);
1454     XMASSERT(((pSource->v >> 10) & 0x7FF) != 0x400);
1455     XMASSERT(((pSource->v >> 21) & 0x7FF) != 0x400);
1456
1457     Element = pSource->v & 0x3FF;
1458     V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtendX[Element >> 9]);
1459     Element = (pSource->v >> 10) & 0x7FF;
1460     V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtendYZ[Element >> 10]);
1461     Element = (pSource->v >> 21) & 0x7FF;
1462     V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtendYZ[Element >> 10]);
1463
1464     return V;
1465
1466 #elif defined(_XM_SSE_INTRINSICS_)
1467     XMASSERT(pSource);
1468     XMASSERT((pSource->v & 0x3FF) != 0x200);
1469     XMASSERT(((pSource->v >> 10) & 0x7FF) != 0x400);
1470     XMASSERT(((pSource->v >> 21) & 0x7FF) != 0x400);
1471     // Get the 32 bit value and splat it
1472     XMVECTOR vResult = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
1473     // Mask off x, y and z
1474     vResult = _mm_and_ps(vResult,g_XMMaskDHen3);
1475     // Convert x and y to unsigned
1476     vResult = _mm_xor_ps(vResult,g_XMXorDHen3);
1477     // Convert to float
1478     vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vResult)[0]);
1479     // Convert x and y back to signed
1480     vResult = _mm_add_ps(vResult,g_XMAddDHen3);
1481     // Normalize x to -210-511.0f and y and z to -1024-1023.0f
1482     vResult = _mm_mul_ps(vResult,g_XMMulDHen3);
1483     return vResult;
1484 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
1485 #endif // _XM_VMX128_INTRINSICS_
1486 }
1487
1488 //------------------------------------------------------------------------------
1489
1490 XMFINLINE XMVECTOR XMLoadU565
1491 (
1492     CONST XMU565* pSource
1493 )
1494 {
1495 #if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
1496     static const XMVECTORI32 U565And = {0x1F,0x3F<<5,0x1F<<11,0};
1497     static const XMVECTORF32 U565Mul = {1.0f,1.0f/32.0f,1.0f/2048.f,0};
1498     XMASSERT(pSource);
1499     // Get the 32 bit value and splat it
1500     XMVECTOR vResult = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
1501     // Mask off x, y and z
1502     vResult = _mm_and_ps(vResult,U565And);
1503     // Convert to float
1504     vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vResult)[0]);
1505     // Normalize x, y, and z
1506     vResult = _mm_mul_ps(vResult,U565Mul);
1507     return vResult;
1508 #else
1509     XMVECTOR          V;
1510     UINT              Element;
1511
1512     XMASSERT(pSource);
1513
1514     Element = pSource->v & 0x1F;
1515     V.vector4_f32[0] = (FLOAT)Element;
1516     Element = (pSource->v >> 5) & 0x3F;
1517     V.vector4_f32[1] = (FLOAT)Element;
1518     Element = (pSource->v >> 11) & 0x1F;
1519     V.vector4_f32[2] = (FLOAT)Element;
1520
1521     return V;
1522 #endif // !_XM_SSE_INTRINSICS_
1523 }
1524
1525 //------------------------------------------------------------------------------
1526
1527 XMFINLINE XMVECTOR XMLoadFloat3PK
1528 (
1529     CONST XMFLOAT3PK* pSource
1530 )
1531 {
1532     _DECLSPEC_ALIGN_16_ UINT Result[4];
1533     UINT Mantissa;
1534     UINT Exponent;
1535
1536     XMASSERT(pSource);
1537
1538     // X Channel (6-bit mantissa)
1539     Mantissa = pSource->xm;
1540
1541     if ( pSource->xe == 0x1f ) // INF or NAN
1542     {
1543         Result[0] = 0x7f800000 | (pSource->xm << 17);
1544     }
1545     else
1546     {
1547         if ( pSource->xe != 0 ) // The value is normalized
1548         {
1549             Exponent = pSource->xe;
1550         }
1551         else if (Mantissa != 0) // The value is denormalized
1552         {
1553             // Normalize the value in the resulting float
1554             Exponent = 1;
1555     
1556             do
1557             {
1558                 Exponent--;
1559                 Mantissa <<= 1;
1560             } while ((Mantissa & 0x40) == 0);
1561     
1562             Mantissa &= 0x3F;
1563         }
1564         else // The value is zero
1565         {
1566             Exponent = (UINT)-112;
1567         }
1568     
1569         Result[0] = ((Exponent + 112) << 23) | (Mantissa << 17);
1570     }
1571
1572     // Y Channel (6-bit mantissa)
1573     Mantissa = pSource->ym;
1574
1575     if ( pSource->ye == 0x1f ) // INF or NAN
1576     {
1577         Result[1] = 0x7f800000 | (pSource->ym << 17);
1578     }
1579     else
1580     {
1581         if ( pSource->ye != 0 ) // The value is normalized
1582         {
1583             Exponent = pSource->ye;
1584         }
1585         else if (Mantissa != 0) // The value is denormalized
1586         {
1587             // Normalize the value in the resulting float
1588             Exponent = 1;
1589     
1590             do
1591             {
1592                 Exponent--;
1593                 Mantissa <<= 1;
1594             } while ((Mantissa & 0x40) == 0);
1595     
1596             Mantissa &= 0x3F;
1597         }
1598         else // The value is zero
1599         {
1600             Exponent = (UINT)-112;
1601         }
1602     
1603         Result[1] = ((Exponent + 112) << 23) | (Mantissa << 17);
1604     }
1605
1606     // Z Channel (5-bit mantissa)
1607     Mantissa = pSource->zm;
1608
1609     if ( pSource->ze == 0x1f ) // INF or NAN
1610     {
1611         Result[2] = 0x7f800000 | (pSource->zm << 17);
1612     }
1613     else
1614     {
1615         if ( pSource->ze != 0 ) // The value is normalized
1616         {
1617             Exponent = pSource->ze;
1618         }
1619         else if (Mantissa != 0) // The value is denormalized
1620         {
1621             // Normalize the value in the resulting float
1622             Exponent = 1;
1623     
1624             do
1625             {
1626                 Exponent--;
1627                 Mantissa <<= 1;
1628             } while ((Mantissa & 0x20) == 0);
1629     
1630             Mantissa &= 0x1F;
1631         }
1632         else // The value is zero
1633         {
1634             Exponent = (UINT)-112;
1635         }
1636
1637         Result[2] = ((Exponent + 112) << 23) | (Mantissa << 18);
1638     }
1639
1640     return XMLoadFloat3A( (const XMFLOAT3A*)&Result );
1641 }
1642
1643 //------------------------------------------------------------------------------
1644
1645 XMFINLINE XMVECTOR XMLoadFloat3SE
1646 (
1647     CONST XMFLOAT3SE* pSource
1648 )
1649 {
1650     _DECLSPEC_ALIGN_16_ UINT Result[4];
1651     UINT Mantissa;
1652     UINT Exponent, ExpBits;
1653
1654     XMASSERT(pSource);
1655
1656     if ( pSource->e == 0x1f ) // INF or NAN
1657     {
1658         Result[0] = 0x7f800000 | (pSource->xm << 14);
1659         Result[1] = 0x7f800000 | (pSource->ym << 14);
1660         Result[2] = 0x7f800000 | (pSource->zm << 14);
1661     }
1662     else if ( pSource->e != 0 ) // The values are all normalized
1663     {
1664         Exponent = pSource->e;
1665
1666         ExpBits = (Exponent + 112) << 23;
1667
1668         Mantissa = pSource->xm;
1669         Result[0] = ExpBits | (Mantissa << 14);
1670
1671         Mantissa = pSource->ym;
1672         Result[1] = ExpBits | (Mantissa << 14);
1673
1674         Mantissa = pSource->zm;
1675         Result[2] = ExpBits | (Mantissa << 14);
1676     }
1677     else
1678     {
1679         // X Channel
1680         Mantissa = pSource->xm;
1681
1682         if (Mantissa != 0) // The value is denormalized
1683         {
1684             // Normalize the value in the resulting float
1685             Exponent = 1;
1686
1687             do
1688             {
1689                 Exponent--;
1690                 Mantissa <<= 1;
1691             } while ((Mantissa & 0x200) == 0);
1692
1693             Mantissa &= 0x1FF;
1694         }
1695         else // The value is zero
1696         {
1697             Exponent = (UINT)-112;
1698         }
1699
1700         Result[0] = ((Exponent + 112) << 23) | (Mantissa << 14);
1701
1702         // Y Channel
1703         Mantissa = pSource->ym;
1704
1705         if (Mantissa != 0) // The value is denormalized
1706         {
1707             // Normalize the value in the resulting float
1708             Exponent = 1;
1709
1710             do
1711             {
1712                 Exponent--;
1713                 Mantissa <<= 1;
1714             } while ((Mantissa & 0x200) == 0);
1715
1716             Mantissa &= 0x1FF;
1717         }
1718         else // The value is zero
1719         {
1720             Exponent = (UINT)-112;
1721         }
1722
1723         Result[1] = ((Exponent + 112) << 23) | (Mantissa << 14);
1724
1725         // Z Channel
1726         Mantissa = pSource->zm;
1727
1728         if (Mantissa != 0) // The value is denormalized
1729         {
1730             // Normalize the value in the resulting float
1731             Exponent = 1;
1732
1733             do
1734             {
1735                 Exponent--;
1736                 Mantissa <<= 1;
1737             } while ((Mantissa & 0x200) == 0);
1738
1739             Mantissa &= 0x1FF;
1740         }
1741         else // The value is zero
1742         {
1743             Exponent = (UINT)-112;
1744         }
1745
1746         Result[2] = ((Exponent + 112) << 23) | (Mantissa << 14);
1747     }
1748
1749     return XMLoadFloat3A( (const XMFLOAT3A*)&Result );
1750 }
1751
1752 //------------------------------------------------------------------------------
1753
1754 XMFINLINE XMVECTOR XMLoadInt4
1755 (
1756     CONST UINT* pSource
1757 )
1758 {
1759 #if defined(_XM_NO_INTRINSICS_)
1760
1761     XMVECTOR V;
1762
1763     XMASSERT(pSource);
1764
1765     V.vector4_u32[0] = pSource[0];
1766     V.vector4_u32[1] = pSource[1];
1767     V.vector4_u32[2] = pSource[2];
1768     V.vector4_u32[3] = pSource[3];
1769
1770     return V;
1771
1772 #elif defined(_XM_SSE_INTRINSICS_)
1773
1774     XMASSERT(pSource);
1775
1776     __m128i V = _mm_loadu_si128( (const __m128i*)pSource );
1777     return reinterpret_cast<__m128 *>(&V)[0];
1778
1779 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
1780 #endif // _XM_VMX128_INTRINSICS_
1781 }
1782
1783 //------------------------------------------------------------------------------
1784
1785 XMFINLINE XMVECTOR XMLoadSInt4
1786 (
1787     CONST XMINT4* pSource
1788 )
1789 {
1790 #if defined(_XM_NO_INTRINSICS_)
1791     XMVECTOR V;
1792     XMASSERT(pSource);
1793
1794 #ifdef _XBOX_VER
1795     V = XMLoadInt4( (const UINT*)pSource );
1796     return XMConvertVectorIntToFloat( V, 0 );
1797 #else
1798     V.vector4_f32[0] = (float)pSource->x;
1799     V.vector4_f32[1] = (float)pSource->y;
1800     V.vector4_f32[2] = (float)pSource->z;
1801     V.vector4_f32[3] = (float)pSource->w;
1802     return V;
1803 #endif
1804
1805 #elif defined(_XM_SSE_INTRINSICS_)
1806     XMASSERT(pSource);
1807     __m128i V = _mm_loadu_si128( (const __m128i*)pSource );
1808     return _mm_cvtepi32_ps(V);
1809 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
1810 #endif // _XM_VMX128_INTRINSICS_
1811 }
1812
1813 //------------------------------------------------------------------------------
1814
1815 XMFINLINE XMVECTOR XMLoadUInt4
1816 (
1817     CONST XMUINT4* pSource
1818 )
1819 {
1820 #if defined(_XM_NO_INTRINSICS_)
1821     XMVECTOR V;
1822     XMASSERT(pSource);
1823
1824     V.vector4_f32[0] = (float)pSource->x;
1825     V.vector4_f32[1] = (float)pSource->y;
1826     V.vector4_f32[2] = (float)pSource->z;
1827     V.vector4_f32[3] = (float)pSource->w;
1828     return V;
1829
1830 #elif defined(_XM_SSE_INTRINSICS_)
1831     XMASSERT(pSource);
1832     __m128i V = _mm_loadu_si128( (const __m128i*)pSource );
1833     // For the values that are higher than 0x7FFFFFFF, a fixup is needed
1834     // Determine which ones need the fix.
1835     XMVECTOR vMask = _mm_and_ps(reinterpret_cast<const __m128 *>(&V)[0],g_XMNegativeZero);
1836     // Force all values positive
1837     XMVECTOR vResult = _mm_xor_ps(reinterpret_cast<const __m128 *>(&V)[0],vMask);
1838     // Convert to floats
1839     vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vResult)[0]);
1840     // Convert 0x80000000 -> 0xFFFFFFFF
1841     __m128i iMask = _mm_srai_epi32(reinterpret_cast<const __m128i *>(&vMask)[0],31);
1842     // For only the ones that are too big, add the fixup
1843     vMask = _mm_and_ps(reinterpret_cast<const __m128 *>(&iMask)[0],g_XMFixUnsigned);
1844     vResult = _mm_add_ps(vResult,vMask);
1845     return vResult;
1846 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
1847 #endif // _XM_VMX128_INTRINSICS_
1848 }
1849
1850 //------------------------------------------------------------------------------
1851
1852 XMFINLINE XMVECTOR XMLoadInt4A
1853 (
1854     CONST UINT* pSource
1855 )
1856 {
1857 #if defined(_XM_NO_INTRINSICS_)
1858
1859     XMVECTOR V;
1860
1861     XMASSERT(pSource);
1862     XMASSERT(((UINT_PTR)pSource & 0xF) == 0);
1863
1864     V.vector4_u32[0] = pSource[0];
1865     V.vector4_u32[1] = pSource[1];
1866     V.vector4_u32[2] = pSource[2];
1867     V.vector4_u32[3] = pSource[3];
1868
1869     return V;
1870
1871 #elif defined(_XM_SSE_INTRINSICS_)
1872
1873     XMASSERT(pSource);
1874     XMASSERT(((UINT_PTR)pSource & 0xF) == 0);
1875
1876     __m128i V = _mm_load_si128( (const __m128i*)pSource );
1877     return reinterpret_cast<__m128 *>(&V)[0];
1878
1879 #else // _XM_VMX128_INTRINSICS_
1880 #endif // _XM_VMX128_INTRINSICS_
1881 }
1882
1883 //------------------------------------------------------------------------------
1884
1885 XMFINLINE XMVECTOR XMLoadFloat4
1886 (
1887     CONST XMFLOAT4* pSource
1888 )
1889 {
1890 #if defined(_XM_NO_INTRINSICS_)
1891     XMVECTOR V;
1892     XMASSERT(pSource);
1893
1894     ((UINT *)(&V.vector4_f32[0]))[0] = ((const UINT *)(&pSource->x))[0];
1895     ((UINT *)(&V.vector4_f32[1]))[0] = ((const UINT *)(&pSource->y))[0];
1896     ((UINT *)(&V.vector4_f32[2]))[0] = ((const UINT *)(&pSource->z))[0];
1897     ((UINT *)(&V.vector4_f32[3]))[0] = ((const UINT *)(&pSource->w))[0];
1898     return V;
1899 #elif defined(_XM_SSE_INTRINSICS_)
1900     XMASSERT(pSource);
1901
1902     return _mm_loadu_ps( &pSource->x );
1903 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
1904 #endif // _XM_VMX128_INTRINSICS_
1905 }
1906
1907 //------------------------------------------------------------------------------
1908
1909 XMFINLINE XMVECTOR XMLoadFloat4A
1910 (
1911     CONST XMFLOAT4A* pSource
1912 )
1913 {
1914 #if defined(_XM_NO_INTRINSICS_)
1915
1916     XMVECTOR V;
1917
1918     XMASSERT(pSource);
1919     XMASSERT(((UINT_PTR)pSource & 0xF) == 0);
1920
1921     V.vector4_f32[0] = pSource->x;
1922     V.vector4_f32[1] = pSource->y;
1923     V.vector4_f32[2] = pSource->z;
1924     V.vector4_f32[3] = pSource->w;
1925
1926     return V;
1927
1928 #elif defined(_XM_SSE_INTRINSICS_)
1929
1930     XMASSERT(pSource);
1931     XMASSERT(((UINT_PTR)pSource & 0xF) == 0);
1932
1933     return _mm_load_ps( &pSource->x );
1934
1935 #else // _XM_VMX128_INTRINSICS_
1936 #endif // _XM_VMX128_INTRINSICS_
1937 }
1938
1939 //------------------------------------------------------------------------------
1940
1941 XMFINLINE XMVECTOR XMLoadHalf4
1942 (
1943     CONST XMHALF4* pSource
1944 )
1945 {
1946 #if defined(_XM_NO_INTRINSICS_)
1947     XMASSERT(pSource);
1948     {
1949     XMVECTOR vResult = {
1950         XMConvertHalfToFloat(pSource->x),
1951         XMConvertHalfToFloat(pSource->y),
1952         XMConvertHalfToFloat(pSource->z),
1953         XMConvertHalfToFloat(pSource->w)
1954     };
1955     return vResult;
1956     }
1957 #elif defined(_XM_SSE_INTRINSICS_)
1958     XMASSERT(pSource);
1959     XMVECTOR vResult = {
1960         XMConvertHalfToFloat(pSource->x),
1961         XMConvertHalfToFloat(pSource->y),
1962         XMConvertHalfToFloat(pSource->z),
1963         XMConvertHalfToFloat(pSource->w)
1964     };
1965     return vResult;
1966 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
1967 #endif // _XM_VMX128_INTRINSICS_
1968 }
1969
1970 //------------------------------------------------------------------------------
1971
1972 XMFINLINE XMVECTOR XMLoadShortN4
1973 (
1974     CONST XMSHORTN4* pSource
1975 )
1976 {
1977 #if defined(_XM_NO_INTRINSICS_)
1978     XMASSERT(pSource);
1979     {
1980     XMVECTOR vResult = {
1981         (pSource->x == -32768) ? -1.f : ((FLOAT)pSource->x * (1.0f/32767.0f)),
1982         (pSource->y == -32768) ? -1.f : ((FLOAT)pSource->y * (1.0f/32767.0f)),
1983         (pSource->z == -32768) ? -1.f : ((FLOAT)pSource->z * (1.0f/32767.0f)),
1984         (pSource->w == -32768) ? -1.f : ((FLOAT)pSource->w * (1.0f/32767.0f))
1985     };
1986     return vResult;
1987     }
1988 #elif defined(_XM_SSE_INTRINSICS_)
1989     XMASSERT(pSource);
1990     // Splat the color in all four entries (x,z,y,w)
1991     __m128d vIntd = _mm_load1_pd(reinterpret_cast<const double *>(&pSource->x));
1992     // Shift x&0ffff,z&0xffff,y&0xffff0000,w&0xffff0000
1993     __m128 vTemp = _mm_and_ps(reinterpret_cast<const __m128 *>(&vIntd)[0],g_XMMaskX16Y16Z16W16);
1994     // x and z are unsigned! Flip the bits to convert the order to signed
1995     vTemp = _mm_xor_ps(vTemp,g_XMFlipX16Y16Z16W16);
1996     // Convert to floating point numbers
1997     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
1998     // x and z - 0x8000 to complete the conversion
1999     vTemp = _mm_add_ps(vTemp,g_XMFixX16Y16Z16W16);
2000     // Convert to -1.0f - 1.0f
2001     vTemp = _mm_mul_ps(vTemp,g_XMNormalizeX16Y16Z16W16);
2002     // Very important! The entries are x,z,y,w, flip it to x,y,z,w
2003     vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(3,1,2,0));
2004     // Clamp result (for case of -32768)
2005     return _mm_max_ps( vTemp, g_XMNegativeOne );
2006 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2007 #endif // _XM_VMX128_INTRINSICS_
2008 }
2009
2010 //------------------------------------------------------------------------------
2011
2012 XMFINLINE XMVECTOR XMLoadShort4
2013 (
2014     CONST XMSHORT4* pSource
2015 )
2016 {
2017 #if defined(_XM_NO_INTRINSICS_)
2018
2019     XMVECTOR V;
2020
2021     XMASSERT(pSource);
2022
2023     V.vector4_f32[0] = (FLOAT)pSource->x;
2024     V.vector4_f32[1] = (FLOAT)pSource->y;
2025     V.vector4_f32[2] = (FLOAT)pSource->z;
2026     V.vector4_f32[3] = (FLOAT)pSource->w;
2027
2028     return V;
2029
2030 #elif defined(_XM_SSE_INTRINSICS_)
2031     XMASSERT(pSource);
2032     // Splat the color in all four entries (x,z,y,w)
2033     __m128d vIntd = _mm_load1_pd(reinterpret_cast<const double *>(&pSource->x));
2034     // Shift x&0ffff,z&0xffff,y&0xffff0000,w&0xffff0000
2035     __m128 vTemp = _mm_and_ps(reinterpret_cast<const __m128 *>(&vIntd)[0],g_XMMaskX16Y16Z16W16);
2036     // x and z are unsigned! Flip the bits to convert the order to signed
2037     vTemp = _mm_xor_ps(vTemp,g_XMFlipX16Y16Z16W16);
2038     // Convert to floating point numbers
2039     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2040     // x and z - 0x8000 to complete the conversion
2041     vTemp = _mm_add_ps(vTemp,g_XMFixX16Y16Z16W16);
2042     // Fix y and w because they are 65536 too large
2043     vTemp = _mm_mul_ps(vTemp,g_XMFixupY16W16);
2044     // Very important! The entries are x,z,y,w, flip it to x,y,z,w
2045     return _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(3,1,2,0));
2046 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2047 #endif // _XM_VMX128_INTRINSICS_
2048 }
2049
2050 //------------------------------------------------------------------------------
2051
2052 XMFINLINE XMVECTOR XMLoadUShortN4
2053 (
2054     CONST XMUSHORTN4* pSource
2055 )
2056 {
2057 #if defined(_XM_NO_INTRINSICS_)
2058
2059     XMVECTOR V;
2060
2061     XMASSERT(pSource);
2062
2063     V.vector4_f32[0] = (FLOAT)pSource->x / 65535.0f;
2064     V.vector4_f32[1] = (FLOAT)pSource->y / 65535.0f;
2065     V.vector4_f32[2] = (FLOAT)pSource->z / 65535.0f;
2066     V.vector4_f32[3] = (FLOAT)pSource->w / 65535.0f;
2067
2068     return V;
2069
2070 #elif defined(_XM_SSE_INTRINSICS_)
2071     XMASSERT(pSource);
2072     static const XMVECTORF32 FixupY16W16 = {1.0f/65535.0f,1.0f/65535.0f,1.0f/(65535.0f*65536.0f),1.0f/(65535.0f*65536.0f)};
2073     static const XMVECTORF32 FixaddY16W16  = {0,0,32768.0f*65536.0f,32768.0f*65536.0f};
2074     XMASSERT(pSource);
2075     // Splat the color in all four entries (x,z,y,w)
2076     __m128d vIntd = _mm_load1_pd(reinterpret_cast<const double *>(&pSource->x));
2077     // Shift x&0ffff,z&0xffff,y&0xffff0000,w&0xffff0000
2078     __m128 vTemp = _mm_and_ps(reinterpret_cast<const __m128 *>(&vIntd)[0],g_XMMaskX16Y16Z16W16);
2079     // y and w are signed! Flip the bits to convert the order to unsigned
2080     vTemp = _mm_xor_ps(vTemp,g_XMFlipZW);
2081     // Convert to floating point numbers
2082     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2083     // y and w + 0x8000 to complete the conversion
2084     vTemp = _mm_add_ps(vTemp,FixaddY16W16);
2085     // Fix y and w because they are 65536 too large
2086     vTemp = _mm_mul_ps(vTemp,FixupY16W16);
2087     // Very important! The entries are x,z,y,w, flip it to x,y,z,w
2088     return _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(3,1,2,0));
2089 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2090 #endif // _XM_VMX128_INTRINSICS_
2091 }
2092
2093 //------------------------------------------------------------------------------
2094
2095 XMFINLINE XMVECTOR XMLoadUShort4
2096 (
2097     CONST XMUSHORT4* pSource
2098 )
2099 {
2100 #if defined(_XM_NO_INTRINSICS_)
2101
2102     XMVECTOR V;
2103
2104     XMASSERT(pSource);
2105
2106     V.vector4_f32[0] = (FLOAT)pSource->x;
2107     V.vector4_f32[1] = (FLOAT)pSource->y;
2108     V.vector4_f32[2] = (FLOAT)pSource->z;
2109     V.vector4_f32[3] = (FLOAT)pSource->w;
2110
2111     return V;
2112
2113 #elif defined(_XM_SSE_INTRINSICS_)
2114     XMASSERT(pSource);
2115     static const XMVECTORF32 FixaddY16W16  = {0,0,32768.0f,32768.0f};
2116     XMASSERT(pSource);
2117     // Splat the color in all four entries (x,z,y,w)
2118     __m128d vIntd = _mm_load1_pd(reinterpret_cast<const double *>(&pSource->x));
2119     // Shift x&0ffff,z&0xffff,y&0xffff0000,w&0xffff0000
2120     __m128 vTemp = _mm_and_ps(reinterpret_cast<const __m128 *>(&vIntd)[0],g_XMMaskX16Y16Z16W16);
2121     // y and w are signed! Flip the bits to convert the order to unsigned
2122     vTemp = _mm_xor_ps(vTemp,g_XMFlipZW);
2123     // Convert to floating point numbers
2124     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2125     // Fix y and w because they are 65536 too large
2126     vTemp = _mm_mul_ps(vTemp,g_XMFixupY16W16);
2127     // y and w + 0x8000 to complete the conversion
2128     vTemp = _mm_add_ps(vTemp,FixaddY16W16);
2129     // Very important! The entries are x,z,y,w, flip it to x,y,z,w
2130     return _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(3,1,2,0));
2131 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2132 #endif // _XM_VMX128_INTRINSICS_
2133 }
2134
2135 //------------------------------------------------------------------------------
2136
2137 XMFINLINE XMVECTOR XMLoadXIcoN4
2138 (
2139     CONST XMXICON4* pSource
2140 )
2141 {
2142 #if defined(_XM_NO_INTRINSICS_)
2143
2144     XMVECTOR          V;
2145     UINT              Element;
2146     static CONST UINT SignExtend[] = {0x00000000, 0xFFF00000};
2147
2148     XMASSERT(pSource);
2149     XMASSERT((pSource->v & 0xFFFFFull) != 0x80000ull);
2150     XMASSERT(((pSource->v >> 20) & 0xFFFFFull) != 0x80000ull);
2151     XMASSERT(((pSource->v >> 40) & 0xFFFFFull) != 0x80000ull);
2152
2153     Element = (UINT)(pSource->v & 0xFFFFF);
2154     V.vector4_f32[0] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]) / 524287.0f;
2155     Element = (UINT)((pSource->v >> 20) & 0xFFFFF);
2156     V.vector4_f32[1] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]) / 524287.0f;
2157     Element = (UINT)((pSource->v >> 40) & 0xFFFFF);
2158     V.vector4_f32[2] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]) / 524287.0f;
2159     V.vector4_f32[3] = (FLOAT)(pSource->v >> 60) / 15.0f;
2160
2161     return V;
2162
2163 #elif defined(_XM_SSE_INTRINSICS_)
2164     XMASSERT((pSource->v & 0xFFFFFull) != 0x80000ull);
2165     XMASSERT(((pSource->v >> 20) & 0xFFFFFull) != 0x80000ull);
2166     XMASSERT(((pSource->v >> 40) & 0xFFFFFull) != 0x80000ull);
2167     static const XMVECTORF32 LoadXIcoN4Mul = {1.0f/524287.0f,1.0f/(524287.0f*4096.0f),1.0f/524287.0f,1.0f/(15.0f*4096.0f*65536.0f)};
2168     XMASSERT(pSource);
2169     // Grab the 64 bit structure
2170     __m128d vResultd = _mm_load_sd(reinterpret_cast<const double *>(&pSource->v));
2171     // By shifting down 8 bits, y and z are in seperate 32 bit elements
2172     __m128i vResulti = _mm_srli_si128(reinterpret_cast<const __m128i *>(&vResultd)[0],8/8);
2173     // vResultd has x and w, vResulti has y and z, merge into one as x,w,y,z
2174     XMVECTOR vTemp = _mm_shuffle_ps(reinterpret_cast<const __m128 *>(&vResultd)[0],reinterpret_cast<const __m128 *>(&vResulti)[0],_MM_SHUFFLE(1,0,1,0));
2175     // Fix the entries to x,y,z,w
2176     vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,3,2,0));
2177     // Mask x,y,z and w
2178     vTemp = _mm_and_ps(vTemp,g_XMMaskIco4);
2179     // x and z are unsigned! Flip the bits to convert the order to signed
2180     vTemp = _mm_xor_ps(vTemp,g_XMXorXIco4);
2181     // Convert to floating point numbers
2182     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2183     // x and z - 0x80 to complete the conversion
2184     vTemp = _mm_add_ps(vTemp,g_XMAddXIco4);
2185     // Fix y and w because they are too large
2186     vTemp = _mm_mul_ps(vTemp,LoadXIcoN4Mul);
2187     return vTemp;
2188 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2189 #endif // _XM_VMX128_INTRINSICS_
2190 }
2191
2192 //------------------------------------------------------------------------------
2193
2194 XMFINLINE XMVECTOR XMLoadXIco4
2195 (
2196     CONST XMXICO4* pSource
2197 )
2198 {
2199 #if defined(_XM_NO_INTRINSICS_)
2200
2201     XMVECTOR          V;
2202     UINT              Element;
2203     static CONST UINT SignExtend[] = {0x00000000, 0xFFF00000};
2204
2205     XMASSERT(pSource);
2206     XMASSERT((pSource->v & 0xFFFFFull) != 0x80000ull);
2207     XMASSERT(((pSource->v >> 20) & 0xFFFFFull) != 0x80000ull);
2208     XMASSERT(((pSource->v >> 40) & 0xFFFFFull) != 0x80000ull);
2209
2210     Element = (UINT)(pSource->v & 0xFFFFF);
2211     V.vector4_f32[0] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]);
2212     Element = (UINT)((pSource->v >> 20) & 0xFFFFF);
2213     V.vector4_f32[1] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]);
2214     Element = (UINT)((pSource->v >> 40) & 0xFFFFF);
2215     V.vector4_f32[2] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]);
2216     V.vector4_f32[3] = (FLOAT)(pSource->v >> 60);
2217
2218     return V;
2219
2220 #elif defined(_XM_SSE_INTRINSICS_)
2221     XMASSERT((pSource->v & 0xFFFFFull) != 0x80000ull);
2222     XMASSERT(((pSource->v >> 20) & 0xFFFFFull) != 0x80000ull);
2223     XMASSERT(((pSource->v >> 40) & 0xFFFFFull) != 0x80000ull);
2224     XMASSERT(pSource);
2225     // Grab the 64 bit structure
2226     __m128d vResultd = _mm_load_sd(reinterpret_cast<const double *>(&pSource->v));
2227     // By shifting down 8 bits, y and z are in seperate 32 bit elements
2228     __m128i vResulti = _mm_srli_si128(reinterpret_cast<const __m128i *>(&vResultd)[0],8/8);
2229     // vResultd has x and w, vResulti has y and z, merge into one as x,w,y,z
2230     XMVECTOR vTemp = _mm_shuffle_ps(reinterpret_cast<const __m128 *>(&vResultd)[0],reinterpret_cast<const __m128 *>(&vResulti)[0],_MM_SHUFFLE(1,0,1,0));
2231     // Fix the entries to x,y,z,w
2232     vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,3,2,0));
2233     // Mask x,y,z and w
2234     vTemp = _mm_and_ps(vTemp,g_XMMaskIco4);
2235     // x and z are unsigned! Flip the bits to convert the order to signed
2236     vTemp = _mm_xor_ps(vTemp,g_XMXorXIco4);
2237     // Convert to floating point numbers
2238     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2239     // x and z - 0x80 to complete the conversion
2240     vTemp = _mm_add_ps(vTemp,g_XMAddXIco4);
2241     // Fix y and w because they are too large
2242     vTemp = _mm_mul_ps(vTemp,g_XMMulIco4);
2243     return vTemp;
2244 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2245 #endif // _XM_VMX128_INTRINSICS_
2246 }
2247
2248 //------------------------------------------------------------------------------
2249
2250 XMFINLINE XMVECTOR XMLoadUIcoN4
2251 (
2252     CONST XMUICON4* pSource
2253 )
2254 {
2255 #if defined(_XM_NO_INTRINSICS_)
2256
2257     XMVECTOR V;
2258
2259     XMASSERT(pSource);
2260
2261     V.vector4_f32[0] = (FLOAT)(pSource->v & 0xFFFFF) / 1048575.0f;
2262     V.vector4_f32[1] = (FLOAT)((pSource->v >> 20) & 0xFFFFF) / 1048575.0f;
2263     V.vector4_f32[2] = (FLOAT)((pSource->v >> 40) & 0xFFFFF) / 1048575.0f;
2264     V.vector4_f32[3] = (FLOAT)(pSource->v >> 60) / 15.0f;
2265
2266     return V;
2267
2268 #elif defined(_XM_SSE_INTRINSICS_)
2269     static const XMVECTORF32 LoadUIcoN4Mul = {1.0f/1048575.0f,1.0f/(1048575.0f*4096.0f),1.0f/1048575.0f,1.0f/(15.0f*4096.0f*65536.0f)};
2270     XMASSERT(pSource);
2271     // Grab the 64 bit structure
2272     __m128d vResultd = _mm_load_sd(reinterpret_cast<const double *>(&pSource->v));
2273     // By shifting down 8 bits, y and z are in seperate 32 bit elements
2274     __m128i vResulti = _mm_srli_si128(reinterpret_cast<const __m128i *>(&vResultd)[0],8/8);
2275     // vResultd has x and w, vResulti has y and z, merge into one as x,w,y,z
2276     XMVECTOR vTemp = _mm_shuffle_ps(reinterpret_cast<const __m128 *>(&vResultd)[0],reinterpret_cast<const __m128 *>(&vResulti)[0],_MM_SHUFFLE(1,0,1,0));
2277     // Fix the entries to x,y,z,w
2278     vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,3,2,0));
2279     // Mask x,y,z and w
2280     vTemp = _mm_and_ps(vTemp,g_XMMaskIco4);
2281     // x and z are unsigned! Flip the bits to convert the order to signed
2282     vTemp = _mm_xor_ps(vTemp,g_XMFlipYW);
2283     // Convert to floating point numbers
2284     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2285     // x and z - 0x80 to complete the conversion
2286     vTemp = _mm_add_ps(vTemp,g_XMAddUIco4);
2287     // Fix y and w because they are too large
2288     vTemp = _mm_mul_ps(vTemp,LoadUIcoN4Mul);
2289     return vTemp;
2290 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2291 #endif // _XM_VMX128_INTRINSICS_
2292 }
2293
2294 //------------------------------------------------------------------------------
2295
2296 XMFINLINE XMVECTOR XMLoadUIco4
2297 (
2298     CONST XMUICO4* pSource
2299 )
2300 {
2301 #if defined(_XM_NO_INTRINSICS_)
2302
2303     XMVECTOR V;
2304
2305     XMASSERT(pSource);
2306
2307     V.vector4_f32[0] = (FLOAT)(pSource->v & 0xFFFFF);
2308     V.vector4_f32[1] = (FLOAT)((pSource->v >> 20) & 0xFFFFF);
2309     V.vector4_f32[2] = (FLOAT)((pSource->v >> 40) & 0xFFFFF);
2310     V.vector4_f32[3] = (FLOAT)(pSource->v >> 60);
2311
2312     return V;
2313
2314 #elif defined(_XM_SSE_INTRINSICS_)
2315     XMASSERT(pSource);
2316     // Grab the 64 bit structure
2317     __m128d vResultd = _mm_load_sd(reinterpret_cast<const double *>(&pSource->v));
2318     // By shifting down 8 bits, y and z are in seperate 32 bit elements
2319     __m128i vResulti = _mm_srli_si128(reinterpret_cast<const __m128i *>(&vResultd)[0],8/8);
2320     // vResultd has x and w, vResulti has y and z, merge into one as x,w,y,z
2321     XMVECTOR vTemp = _mm_shuffle_ps(reinterpret_cast<const __m128 *>(&vResultd)[0],reinterpret_cast<const __m128 *>(&vResulti)[0],_MM_SHUFFLE(1,0,1,0));
2322     // Fix the entries to x,y,z,w
2323     vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,3,2,0));
2324     // Mask x,y,z and w
2325     vTemp = _mm_and_ps(vTemp,g_XMMaskIco4);
2326     // x and z are unsigned! Flip the bits to convert the order to signed
2327     vTemp = _mm_xor_ps(vTemp,g_XMFlipYW);
2328     // Convert to floating point numbers
2329     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2330     // x and z - 0x80 to complete the conversion
2331     vTemp = _mm_add_ps(vTemp,g_XMAddUIco4);
2332     // Fix y and w because they are too large
2333     vTemp = _mm_mul_ps(vTemp,g_XMMulIco4);
2334     return vTemp;
2335 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2336 #endif // _XM_VMX128_INTRINSICS_
2337 }
2338
2339 //------------------------------------------------------------------------------
2340
2341 XMFINLINE XMVECTOR XMLoadIcoN4
2342 (
2343     CONST XMICON4* pSource
2344 )
2345 {
2346 #if defined(_XM_NO_INTRINSICS_)
2347
2348     XMVECTOR          V;
2349     UINT              Element;
2350     static CONST UINT SignExtend[] = {0x00000000, 0xFFF00000};
2351     static CONST UINT SignExtendW[] = {0x00000000, 0xFFFFFFF0};
2352
2353     XMASSERT(pSource);
2354
2355     Element = (UINT)(pSource->v & 0xFFFFF);
2356     V.vector4_f32[0] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]) / 524287.0f;
2357     Element = (UINT)((pSource->v >> 20) & 0xFFFFF);
2358     V.vector4_f32[1] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]) / 524287.0f;
2359     Element = (UINT)((pSource->v >> 40) & 0xFFFFF);
2360     V.vector4_f32[2] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]) / 524287.0f;
2361     Element = (UINT)(pSource->v >> 60);
2362     V.vector4_f32[3] = (FLOAT)(INT)(Element | SignExtendW[Element >> 3]) / 7.0f;
2363
2364     return V;
2365
2366 #elif defined(_XM_SSE_INTRINSICS_)
2367     static const XMVECTORF32 LoadIcoN4Mul = {1.0f/524287.0f,1.0f/(524287.0f*4096.0f),1.0f/524287.0f,1.0f/(7.0f*4096.0f*65536.0f)};
2368     XMASSERT(pSource);
2369     // Grab the 64 bit structure
2370     __m128d vResultd = _mm_load_sd(reinterpret_cast<const double *>(&pSource->v));
2371     // By shifting down 8 bits, y and z are in seperate 32 bit elements
2372     __m128i vResulti = _mm_srli_si128(reinterpret_cast<const __m128i *>(&vResultd)[0],8/8);
2373     // vResultd has x and w, vResulti has y and z, merge into one as x,w,y,z
2374     XMVECTOR vTemp = _mm_shuffle_ps(reinterpret_cast<const __m128 *>(&vResultd)[0],reinterpret_cast<const __m128 *>(&vResulti)[0],_MM_SHUFFLE(1,0,1,0));
2375     // Fix the entries to x,y,z,w
2376     vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,3,2,0));
2377     // Mask x,y,z and w
2378     vTemp = _mm_and_ps(vTemp,g_XMMaskIco4);
2379     // x and z are unsigned! Flip the bits to convert the order to signed
2380     vTemp = _mm_xor_ps(vTemp,g_XMXorIco4);
2381     // Convert to floating point numbers
2382     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2383     // x and z - 0x80 to complete the conversion
2384     vTemp = _mm_add_ps(vTemp,g_XMAddIco4);
2385     // Fix y and w because they are too large
2386     vTemp = _mm_mul_ps(vTemp,LoadIcoN4Mul);
2387     return vTemp;
2388 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2389 #endif // _XM_VMX128_INTRINSICS_
2390 }
2391
2392 //------------------------------------------------------------------------------
2393
2394 XMFINLINE XMVECTOR XMLoadIco4
2395 (
2396     CONST XMICO4* pSource
2397 )
2398 {
2399 #if defined(_XM_NO_INTRINSICS_)
2400
2401     XMVECTOR          V;
2402     UINT              Element;
2403     static CONST UINT SignExtend[] = {0x00000000, 0xFFF00000};
2404     static CONST UINT SignExtendW[] = {0x00000000, 0xFFFFFFF0};
2405
2406     XMASSERT(pSource);
2407
2408     Element = (UINT)(pSource->v & 0xFFFFF);
2409     V.vector4_f32[0] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]);
2410     Element = (UINT)((pSource->v >> 20) & 0xFFFFF);
2411     V.vector4_f32[1] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]);
2412     Element = (UINT)((pSource->v >> 40) & 0xFFFFF);
2413     V.vector4_f32[2] = (FLOAT)(INT)(Element | SignExtend[Element >> 19]);
2414     Element = (UINT)(pSource->v >> 60);
2415     V.vector4_f32[3] = (FLOAT)(INT)(Element | SignExtendW[Element >> 3]);
2416
2417     return V;
2418
2419 #elif defined(_XM_SSE_INTRINSICS_)
2420     XMASSERT(pSource);
2421     // Grab the 64 bit structure
2422     __m128d vResultd = _mm_load_sd(reinterpret_cast<const double *>(&pSource->v));
2423     // By shifting down 8 bits, y and z are in seperate 32 bit elements
2424     __m128i vResulti = _mm_srli_si128(reinterpret_cast<const __m128i *>(&vResultd)[0],8/8);
2425     // vResultd has x and w, vResulti has y and z, merge into one as x,w,y,z
2426     XMVECTOR vTemp = _mm_shuffle_ps(reinterpret_cast<const __m128 *>(&vResultd)[0],reinterpret_cast<const __m128 *>(&vResulti)[0],_MM_SHUFFLE(1,0,1,0));
2427     // Fix the entries to x,y,z,w
2428     vTemp = _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(1,3,2,0));
2429     // Mask x,y,z and w
2430     vTemp = _mm_and_ps(vTemp,g_XMMaskIco4);
2431     // x and z are unsigned! Flip the bits to convert the order to signed
2432     vTemp = _mm_xor_ps(vTemp,g_XMXorIco4);
2433     // Convert to floating point numbers
2434     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2435     // x and z - 0x80 to complete the conversion
2436     vTemp = _mm_add_ps(vTemp,g_XMAddIco4);
2437     // Fix y and w because they are too large
2438     vTemp = _mm_mul_ps(vTemp,g_XMMulIco4);
2439     return vTemp;
2440 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2441 #endif // _XM_VMX128_INTRINSICS_
2442 }
2443
2444
2445 //------------------------------------------------------------------------------
2446
2447 XMFINLINE XMVECTOR XMLoadXDecN4
2448 (
2449     CONST XMXDECN4* pSource
2450 )
2451 {
2452 #if defined(_XM_NO_INTRINSICS_)
2453     XMVECTOR V;
2454     UINT Element;
2455     static CONST UINT SignExtend[] = {0x00000000, 0xFFFFFC00};
2456
2457     XMASSERT(pSource);
2458     XMASSERT((pSource->v & 0x3FF) != 0x200);
2459     XMASSERT(((pSource->v >> 10) & 0x3FF) != 0x200);
2460     XMASSERT(((pSource->v >> 20) & 0x3FF) != 0x200);
2461
2462     Element = pSource->v & 0x3FF;
2463     V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]) / 511.0f;
2464     Element = (pSource->v >> 10) & 0x3FF;
2465     V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]) / 511.0f;
2466     Element = (pSource->v >> 20) & 0x3FF;
2467     V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]) / 511.0f;
2468     V.vector4_f32[3] = (FLOAT)(pSource->v >> 30) / 3.0f;
2469
2470     return V;
2471
2472 #elif defined(_XM_SSE_INTRINSICS_)
2473     XMASSERT(pSource);
2474     // Splat the color in all four entries
2475     __m128 vTemp = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
2476     // Shift R&0xFF0000, G&0xFF00, B&0xFF, A&0xFF000000
2477     vTemp = _mm_and_ps(vTemp,g_XMMaskA2B10G10R10);
2478     // a is unsigned! Flip the bit to convert the order to signed
2479     vTemp = _mm_xor_ps(vTemp,g_XMFlipA2B10G10R10);
2480     // Convert to floating point numbers
2481     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2482     // RGB + 0, A + 0x80000000.f to undo the signed order.
2483     vTemp = _mm_add_ps(vTemp,g_XMFixAA2B10G10R10);
2484     // Convert 0-255 to 0.0f-1.0f
2485     return _mm_mul_ps(vTemp,g_XMNormalizeA2B10G10R10);
2486 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2487 #endif // _XM_VMX128_INTRINSICS_
2488 }
2489
2490 //------------------------------------------------------------------------------
2491
2492 XMFINLINE XMVECTOR XMLoadXDec4
2493 (
2494     CONST XMXDEC4* pSource
2495 )
2496 {
2497 #if defined(_XM_NO_INTRINSICS_)
2498
2499     XMVECTOR          V;
2500     UINT              Element;
2501     static CONST UINT SignExtend[] = {0x00000000, 0xFFFFFC00};
2502
2503     XMASSERT(pSource);
2504     XMASSERT((pSource->v & 0x3FF) != 0x200);
2505     XMASSERT(((pSource->v >> 10) & 0x3FF) != 0x200);
2506     XMASSERT(((pSource->v >> 20) & 0x3FF) != 0x200);
2507
2508     Element = pSource->v & 0x3FF;
2509     V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]);
2510     Element = (pSource->v >> 10) & 0x3FF;
2511     V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]);
2512     Element = (pSource->v >> 20) & 0x3FF;
2513     V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]);
2514     V.vector4_f32[3] = (FLOAT)(pSource->v >> 30);
2515
2516     return V;
2517
2518 #elif defined(_XM_SSE_INTRINSICS_)
2519     XMASSERT((pSource->v & 0x3FF) != 0x200);
2520     XMASSERT(((pSource->v >> 10) & 0x3FF) != 0x200);
2521     XMASSERT(((pSource->v >> 20) & 0x3FF) != 0x200);
2522     static const XMVECTORI32 XDec4Xor = {0x200, 0x200<<10, 0x200<<20, 0x80000000};
2523     static const XMVECTORF32 XDec4Add = {-512.0f,-512.0f*1024.0f,-512.0f*1024.0f*1024.0f,32768*65536.0f};
2524     XMASSERT(pSource);
2525     // Splat the color in all four entries
2526     XMVECTOR vTemp = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
2527     // Shift R&0xFF0000, G&0xFF00, B&0xFF, A&0xFF000000
2528     vTemp = _mm_and_ps(vTemp,g_XMMaskDec4);
2529     // a is unsigned! Flip the bit to convert the order to signed
2530     vTemp = _mm_xor_ps(vTemp,XDec4Xor);
2531     // Convert to floating point numbers
2532     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2533     // RGB + 0, A + 0x80000000.f to undo the signed order.
2534     vTemp = _mm_add_ps(vTemp,XDec4Add);
2535     // Convert 0-255 to 0.0f-1.0f
2536     vTemp = _mm_mul_ps(vTemp,g_XMMulDec4);
2537     return vTemp;
2538 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2539 #endif // _XM_VMX128_INTRINSICS_
2540 }
2541
2542 //------------------------------------------------------------------------------
2543
2544 XMFINLINE XMVECTOR XMLoadUDecN4
2545 (
2546     CONST XMUDECN4* pSource
2547 )
2548 {
2549 #if defined(_XM_NO_INTRINSICS_)
2550
2551     XMVECTOR          V;
2552     UINT              Element;
2553
2554     XMASSERT(pSource);
2555
2556     Element = pSource->v & 0x3FF;
2557     V.vector4_f32[0] = (FLOAT)Element / 1023.0f;
2558     Element = (pSource->v >> 10) & 0x3FF;
2559     V.vector4_f32[1] = (FLOAT)Element / 1023.0f;
2560     Element = (pSource->v >> 20) & 0x3FF;
2561     V.vector4_f32[2] = (FLOAT)Element / 1023.0f;
2562     V.vector4_f32[3] = (FLOAT)(pSource->v >> 30) / 3.0f;
2563
2564     return V;
2565
2566 #elif defined(_XM_SSE_INTRINSICS_)
2567     XMASSERT(pSource);
2568     static const XMVECTORF32 UDecN4Mul = {1.0f/1023.0f,1.0f/(1023.0f*1024.0f),1.0f/(1023.0f*1024.0f*1024.0f),1.0f/(3.0f*1024.0f*1024.0f*1024.0f)};
2569     // Splat the color in all four entries
2570     XMVECTOR vTemp = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
2571     // Shift R&0xFF0000, G&0xFF00, B&0xFF, A&0xFF000000
2572     vTemp = _mm_and_ps(vTemp,g_XMMaskDec4);
2573     // a is unsigned! Flip the bit to convert the order to signed
2574     vTemp = _mm_xor_ps(vTemp,g_XMFlipW);
2575     // Convert to floating point numbers
2576     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2577     // RGB + 0, A + 0x80000000.f to undo the signed order.
2578     vTemp = _mm_add_ps(vTemp,g_XMAddUDec4);
2579     // Convert 0-255 to 0.0f-1.0f
2580     vTemp = _mm_mul_ps(vTemp,UDecN4Mul);
2581     return vTemp;
2582 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2583 #endif // _XM_VMX128_INTRINSICS_
2584 }
2585
2586 //------------------------------------------------------------------------------
2587
2588 XMFINLINE XMVECTOR XMLoadUDec4
2589 (
2590     CONST XMUDEC4* pSource
2591 )
2592 {
2593 #if defined(_XM_NO_INTRINSICS_)
2594
2595     XMVECTOR          V;
2596     UINT              Element;
2597
2598     XMASSERT(pSource);
2599
2600     Element = pSource->v & 0x3FF;
2601     V.vector4_f32[0] = (FLOAT)Element;
2602     Element = (pSource->v >> 10) & 0x3FF;
2603     V.vector4_f32[1] = (FLOAT)Element;
2604     Element = (pSource->v >> 20) & 0x3FF;
2605     V.vector4_f32[2] = (FLOAT)Element;
2606     V.vector4_f32[3] = (FLOAT)(pSource->v >> 30);
2607
2608     return V;
2609
2610 #elif defined(_XM_SSE_INTRINSICS_)
2611     XMASSERT(pSource);
2612     // Splat the color in all four entries
2613     XMVECTOR vTemp = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
2614     // Shift R&0xFF0000, G&0xFF00, B&0xFF, A&0xFF000000
2615     vTemp = _mm_and_ps(vTemp,g_XMMaskDec4);
2616     // a is unsigned! Flip the bit to convert the order to signed
2617     vTemp = _mm_xor_ps(vTemp,g_XMFlipW);
2618     // Convert to floating point numbers
2619     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2620     // RGB + 0, A + 0x80000000.f to undo the signed order.
2621     vTemp = _mm_add_ps(vTemp,g_XMAddUDec4);
2622     // Convert 0-255 to 0.0f-1.0f
2623     vTemp = _mm_mul_ps(vTemp,g_XMMulDec4);
2624     return vTemp;
2625 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2626 #endif // _XM_VMX128_INTRINSICS_
2627 }
2628
2629 //------------------------------------------------------------------------------
2630
2631 XMFINLINE XMVECTOR XMLoadDecN4
2632 (
2633     CONST XMDECN4* pSource
2634 )
2635 {
2636 #if defined(_XM_NO_INTRINSICS_)
2637
2638     XMVECTOR          V;
2639     UINT              Element;
2640     static CONST UINT SignExtend[] = {0x00000000, 0xFFFFFC00};
2641     static CONST UINT SignExtendW[] = {0x00000000, 0xFFFFFFFC};
2642
2643     XMASSERT(pSource);
2644     XMASSERT((pSource->v & 0x3FF) != 0x200);
2645     XMASSERT(((pSource->v >> 10) & 0x3FF) != 0x200);
2646     XMASSERT(((pSource->v >> 20) & 0x3FF) != 0x200);
2647     XMASSERT(((pSource->v >> 30) & 0x3) != 0x2);
2648
2649     Element = pSource->v & 0x3FF;
2650     V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]) / 511.0f;
2651     Element = (pSource->v >> 10) & 0x3FF;
2652     V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]) / 511.0f;
2653     Element = (pSource->v >> 20) & 0x3FF;
2654     V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]) / 511.0f;
2655     Element = pSource->v >> 30;
2656     V.vector4_f32[3] = (FLOAT)(SHORT)(Element | SignExtendW[Element >> 1]);
2657
2658     return V;
2659
2660 #elif defined(_XM_SSE_INTRINSICS_)
2661     XMASSERT(pSource);
2662     XMASSERT((pSource->v & 0x3FF) != 0x200);
2663     XMASSERT(((pSource->v >> 10) & 0x3FF) != 0x200);
2664     XMASSERT(((pSource->v >> 20) & 0x3FF) != 0x200);
2665     XMASSERT(((pSource->v >> 30) & 0x3) != 0x2);
2666     static const XMVECTORF32 DecN4Mul = {1.0f/511.0f,1.0f/(511.0f*1024.0f),1.0f/(511.0f*1024.0f*1024.0f),1.0f/(1024.0f*1024.0f*1024.0f)};
2667     // Splat the color in all four entries
2668     XMVECTOR vTemp = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
2669     // Shift R&0xFF0000, G&0xFF00, B&0xFF, A&0xFF000000
2670     vTemp = _mm_and_ps(vTemp,g_XMMaskDec4);
2671     // a is unsigned! Flip the bit to convert the order to signed
2672     vTemp = _mm_xor_ps(vTemp,g_XMXorDec4);
2673     // Convert to floating point numbers
2674     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2675     // RGB + 0, A + 0x80000000.f to undo the signed order.
2676     vTemp = _mm_add_ps(vTemp,g_XMAddDec4);
2677     // Convert 0-255 to 0.0f-1.0f
2678     vTemp = _mm_mul_ps(vTemp,DecN4Mul);
2679     return vTemp;
2680 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2681 #endif // _XM_VMX128_INTRINSICS_
2682 }
2683
2684 //------------------------------------------------------------------------------
2685
2686 XMFINLINE XMVECTOR XMLoadDec4
2687 (
2688     CONST XMDEC4* pSource
2689 )
2690 {
2691 #if defined(_XM_NO_INTRINSICS_)
2692
2693     XMVECTOR          V;
2694     UINT              Element;
2695     static CONST UINT SignExtend[] = {0x00000000, 0xFFFFFC00};
2696     static CONST UINT SignExtendW[] = {0x00000000, 0xFFFFFFFC};
2697
2698     XMASSERT(pSource);
2699     XMASSERT((pSource->v & 0x3FF) != 0x200);
2700     XMASSERT(((pSource->v >> 10) & 0x3FF) != 0x200);
2701     XMASSERT(((pSource->v >> 20) & 0x3FF) != 0x200);
2702     XMASSERT(((pSource->v >> 30) & 0x3) != 0x2);
2703
2704     Element = pSource->v & 0x3FF;
2705     V.vector4_f32[0] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]);
2706     Element = (pSource->v >> 10) & 0x3FF;
2707     V.vector4_f32[1] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]);
2708     Element = (pSource->v >> 20) & 0x3FF;
2709     V.vector4_f32[2] = (FLOAT)(SHORT)(Element | SignExtend[Element >> 9]);
2710     Element = pSource->v >> 30;
2711     V.vector4_f32[3] = (FLOAT)(SHORT)(Element | SignExtendW[Element >> 1]);
2712
2713     return V;
2714
2715 #elif defined(_XM_SSE_INTRINSICS_)
2716     XMASSERT((pSource->v & 0x3FF) != 0x200);
2717     XMASSERT(((pSource->v >> 10) & 0x3FF) != 0x200);
2718     XMASSERT(((pSource->v >> 20) & 0x3FF) != 0x200);
2719     XMASSERT(((pSource->v >> 30) & 0x3) != 0x2);
2720     XMASSERT(pSource);
2721     // Splat the color in all four entries
2722     XMVECTOR vTemp = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
2723     // Shift R&0xFF0000, G&0xFF00, B&0xFF, A&0xFF000000
2724     vTemp = _mm_and_ps(vTemp,g_XMMaskDec4);
2725     // a is unsigned! Flip the bit to convert the order to signed
2726     vTemp = _mm_xor_ps(vTemp,g_XMXorDec4);
2727     // Convert to floating point numbers
2728     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2729     // RGB + 0, A + 0x80000000.f to undo the signed order.
2730     vTemp = _mm_add_ps(vTemp,g_XMAddDec4);
2731     // Convert 0-255 to 0.0f-1.0f
2732     vTemp = _mm_mul_ps(vTemp,g_XMMulDec4);
2733     return vTemp;
2734 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2735 #endif // _XM_VMX128_INTRINSICS_
2736 }
2737
2738 //------------------------------------------------------------------------------
2739
2740 XMFINLINE XMVECTOR XMLoadUByteN4
2741 (
2742     CONST XMUBYTEN4* pSource
2743 )
2744 {
2745 #if defined(_XM_NO_INTRINSICS_)
2746
2747     XMVECTOR V;
2748
2749     XMASSERT(pSource);
2750
2751     V.vector4_f32[0] = (FLOAT)pSource->x / 255.0f;
2752     V.vector4_f32[1] = (FLOAT)pSource->y / 255.0f;
2753     V.vector4_f32[2] = (FLOAT)pSource->z / 255.0f;
2754     V.vector4_f32[3] = (FLOAT)pSource->w / 255.0f;
2755
2756     return V;
2757
2758 #elif defined(_XM_SSE_INTRINSICS_)
2759     static const XMVECTORF32 LoadUByteN4Mul = {1.0f/255.0f,1.0f/(255.0f*256.0f),1.0f/(255.0f*65536.0f),1.0f/(255.0f*65536.0f*256.0f)};
2760     XMASSERT(pSource);
2761     // Splat the color in all four entries (x,z,y,w)
2762     XMVECTOR vTemp = _mm_load1_ps(reinterpret_cast<const float *>(&pSource->x));
2763     // Mask x&0ff,y&0xff00,z&0xff0000,w&0xff000000
2764     vTemp = _mm_and_ps(vTemp,g_XMMaskByte4);
2765     // w is signed! Flip the bits to convert the order to unsigned
2766     vTemp = _mm_xor_ps(vTemp,g_XMFlipW);
2767     // Convert to floating point numbers
2768     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2769     // w + 0x80 to complete the conversion
2770     vTemp = _mm_add_ps(vTemp,g_XMAddUDec4);
2771     // Fix y, z and w because they are too large
2772     vTemp = _mm_mul_ps(vTemp,LoadUByteN4Mul);
2773     return vTemp;
2774 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2775 #endif // _XM_VMX128_INTRINSICS_
2776 }
2777
2778 //------------------------------------------------------------------------------
2779
2780 XMFINLINE XMVECTOR XMLoadUByte4
2781 (
2782     CONST XMUBYTE4* pSource
2783 )
2784 {
2785 #if defined(_XM_NO_INTRINSICS_)
2786
2787     XMVECTOR V;
2788
2789     XMASSERT(pSource);
2790
2791     V.vector4_f32[0] = (FLOAT)pSource->x;
2792     V.vector4_f32[1] = (FLOAT)pSource->y;
2793     V.vector4_f32[2] = (FLOAT)pSource->z;
2794     V.vector4_f32[3] = (FLOAT)pSource->w;
2795
2796     return V;
2797
2798 #elif defined(_XM_SSE_INTRINSICS_)
2799     static const XMVECTORF32 LoadUByte4Mul = {1.0f,1.0f/256.0f,1.0f/65536.0f,1.0f/(65536.0f*256.0f)};
2800     XMASSERT(pSource);
2801     // Splat the color in all four entries (x,z,y,w)
2802     XMVECTOR vTemp = _mm_load1_ps(reinterpret_cast<const float *>(&pSource->x));
2803     // Mask x&0ff,y&0xff00,z&0xff0000,w&0xff000000
2804     vTemp = _mm_and_ps(vTemp,g_XMMaskByte4);
2805     // w is signed! Flip the bits to convert the order to unsigned
2806     vTemp = _mm_xor_ps(vTemp,g_XMFlipW);
2807     // Convert to floating point numbers
2808     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2809     // w + 0x80 to complete the conversion
2810     vTemp = _mm_add_ps(vTemp,g_XMAddUDec4);
2811     // Fix y, z and w because they are too large
2812     vTemp = _mm_mul_ps(vTemp,LoadUByte4Mul);
2813     return vTemp;
2814 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2815 #endif // _XM_VMX128_INTRINSICS_
2816 }
2817
2818 //------------------------------------------------------------------------------
2819
2820 XMFINLINE XMVECTOR XMLoadByteN4
2821 (
2822     CONST XMBYTEN4* pSource
2823 )
2824 {
2825 #if defined(_XM_NO_INTRINSICS_)
2826
2827     XMVECTOR V;
2828
2829     XMASSERT(pSource);
2830
2831     V.vector4_f32[0] = (pSource->x == -128) ? -1.f : ((FLOAT)pSource->x / 127.0f);
2832     V.vector4_f32[1] = (pSource->y == -128) ? -1.f : ((FLOAT)pSource->y / 127.0f);
2833     V.vector4_f32[2] = (pSource->z == -128) ? -1.f : ((FLOAT)pSource->z / 127.0f);
2834     V.vector4_f32[3] = (pSource->w == -128) ? -1.f : ((FLOAT)pSource->w / 127.0f);
2835
2836     return V;
2837
2838 #elif defined(_XM_SSE_INTRINSICS_)
2839     static const XMVECTORF32 LoadByteN4Mul = {1.0f/127.0f,1.0f/(127.0f*256.0f),1.0f/(127.0f*65536.0f),1.0f/(127.0f*65536.0f*256.0f)};
2840     XMASSERT(pSource);
2841     // Splat the color in all four entries (x,z,y,w)
2842     XMVECTOR vTemp = _mm_load1_ps(reinterpret_cast<const float *>(&pSource->x));
2843     // Mask x&0ff,y&0xff00,z&0xff0000,w&0xff000000
2844     vTemp = _mm_and_ps(vTemp,g_XMMaskByte4);
2845     // x,y and z are unsigned! Flip the bits to convert the order to signed
2846     vTemp = _mm_xor_ps(vTemp,g_XMXorByte4);
2847     // Convert to floating point numbers
2848     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2849     // x, y and z - 0x80 to complete the conversion
2850     vTemp = _mm_add_ps(vTemp,g_XMAddByte4);
2851     // Fix y, z and w because they are too large
2852     vTemp = _mm_mul_ps(vTemp,LoadByteN4Mul);
2853     // Clamp result (for case of -128)
2854     return _mm_max_ps( vTemp, g_XMNegativeOne );
2855 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2856 #endif // _XM_VMX128_INTRINSICS_
2857 }
2858
2859 //------------------------------------------------------------------------------
2860
2861 XMFINLINE XMVECTOR XMLoadByte4
2862 (
2863     CONST XMBYTE4* pSource
2864 )
2865 {
2866 #if defined(_XM_NO_INTRINSICS_)
2867
2868     XMVECTOR V;
2869
2870     XMASSERT(pSource);
2871
2872     V.vector4_f32[0] = (FLOAT)pSource->x;
2873     V.vector4_f32[1] = (FLOAT)pSource->y;
2874     V.vector4_f32[2] = (FLOAT)pSource->z;
2875     V.vector4_f32[3] = (FLOAT)pSource->w;
2876
2877     return V;
2878
2879 #elif defined(_XM_SSE_INTRINSICS_)
2880     static const XMVECTORF32 LoadByte4Mul = {1.0f,1.0f/256.0f,1.0f/65536.0f,1.0f/(65536.0f*256.0f)};
2881     XMASSERT(pSource);
2882     // Splat the color in all four entries (x,z,y,w)
2883     XMVECTOR vTemp = _mm_load1_ps(reinterpret_cast<const float *>(&pSource->x));
2884     // Mask x&0ff,y&0xff00,z&0xff0000,w&0xff000000
2885     vTemp = _mm_and_ps(vTemp,g_XMMaskByte4);
2886     // x,y and z are unsigned! Flip the bits to convert the order to signed
2887     vTemp = _mm_xor_ps(vTemp,g_XMXorByte4);
2888     // Convert to floating point numbers
2889     vTemp = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vTemp)[0]);
2890     // x, y and z - 0x80 to complete the conversion
2891     vTemp = _mm_add_ps(vTemp,g_XMAddByte4);
2892     // Fix y, z and w because they are too large
2893     vTemp = _mm_mul_ps(vTemp,LoadByte4Mul);
2894     return vTemp;
2895 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
2896 #endif // _XM_VMX128_INTRINSICS_
2897 }
2898
2899 //------------------------------------------------------------------------------
2900
2901 XMFINLINE XMVECTOR XMLoadUNibble4
2902 (
2903      CONST XMUNIBBLE4* pSource
2904 )
2905 {
2906 #if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
2907     static const XMVECTORI32 UNibble4And = {0xF,0xF0,0xF00,0xF000};
2908     static const XMVECTORF32 UNibble4Mul = {1.0f,1.0f/16.f,1.0f/256.f,1.0f/4096.f};
2909     XMASSERT(pSource);
2910     // Get the 32 bit value and splat it
2911     XMVECTOR vResult = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
2912     // Mask off x, y and z
2913     vResult = _mm_and_ps(vResult,UNibble4And);
2914     // Convert to float
2915     vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vResult)[0]);
2916     // Normalize x, y, and z
2917     vResult = _mm_mul_ps(vResult,UNibble4Mul);
2918     return vResult;
2919 #else
2920     XMVECTOR          V;
2921     UINT              Element;
2922
2923     XMASSERT(pSource);
2924
2925     Element = pSource->v & 0xF;
2926     V.vector4_f32[0] = (FLOAT)Element;
2927     Element = (pSource->v >> 4) & 0xF;
2928     V.vector4_f32[1] = (FLOAT)Element;
2929     Element = (pSource->v >> 8) & 0xF;
2930     V.vector4_f32[2] = (FLOAT)Element;
2931     Element = (pSource->v >> 12) & 0xF;
2932     V.vector4_f32[3] = (FLOAT)Element;
2933
2934     return V;
2935 #endif // !_XM_SSE_INTRISICS_
2936 }
2937
2938 //------------------------------------------------------------------------------
2939
2940 XMFINLINE XMVECTOR XMLoadU555
2941 (
2942      CONST XMU555* pSource
2943 )
2944 {
2945 #if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
2946     static const XMVECTORI32 U555And = {0x1F,0x1F<<5,0x1F<<10,0x8000};
2947     static const XMVECTORF32 U555Mul = {1.0f,1.0f/32.f,1.0f/1024.f,1.0f/32768.f};
2948     XMASSERT(pSource);
2949     // Get the 32 bit value and splat it
2950     XMVECTOR vResult = _mm_load_ps1(reinterpret_cast<const float *>(&pSource->v));
2951     // Mask off x, y and z
2952     vResult = _mm_and_ps(vResult,U555And);
2953     // Convert to float
2954     vResult = _mm_cvtepi32_ps(reinterpret_cast<const __m128i *>(&vResult)[0]);
2955     // Normalize x, y, and z
2956     vResult = _mm_mul_ps(vResult,U555Mul);
2957     return vResult;
2958 #else
2959     XMVECTOR          V;
2960     UINT              Element;
2961
2962     XMASSERT(pSource);
2963
2964     Element = pSource->v & 0x1F;
2965     V.vector4_f32[0] = (FLOAT)Element;
2966     Element = (pSource->v >> 5) & 0x1F;
2967     V.vector4_f32[1] = (FLOAT)Element;
2968     Element = (pSource->v >> 10) & 0x1F;
2969     V.vector4_f32[2] = (FLOAT)Element;
2970     Element = (pSource->v >> 15) & 0x1;
2971     V.vector4_f32[3] = (FLOAT)Element;
2972
2973     return V;
2974 #endif // !_XM_SSE_INTRISICS_
2975 }
2976
2977 //------------------------------------------------------------------------------
2978
2979 XMFINLINE XMVECTOR XMLoadColor
2980 (
2981     CONST XMCOLOR* pSource
2982 )
2983 {
2984 #if defined(_XM_NO_INTRINSICS_)
2985     XMASSERT(pSource);
2986     {
2987     // INT -> Float conversions are done in one instruction.
2988     // UINT -> Float calls a runtime function. Keep in INT
2989     INT iColor = (INT)(pSource->c);
2990     XMVECTOR vColor = {
2991         (FLOAT)((iColor >> 16) & 0xFF) * (1.0f/255.0f),
2992         (FLOAT)((iColor >> 8) & 0xFF) * (1.0f/255.0f),
2993         (FLOAT)(iColor & 0xFF) * (1.0f/255.0f),
2994         (FLOAT)((iColor >> 24) & 0xFF) * (1.0f/255.0f)
2995     };
2996     return vColor;
2997     }
2998 #elif defined(_XM_SSE_INTRINSICS_)
2999     XMASSERT(pSource);
3000     // Splat the color in all four entries
3001     __m128i vInt = _mm_set1_epi32(pSource->c);
3002     // Shift R&0xFF0000, G&0xFF00, B&0xFF, A&0xFF000000
3003     vInt = _mm_and_si128(vInt,g_XMMaskA8R8G8B8);
3004     // a is unsigned! Flip the bit to convert the order to signed
3005     vInt = _mm_xor_si128(vInt,g_XMFlipA8R8G8B8);
3006     // Convert to floating point numbers
3007     XMVECTOR vTemp = _mm_cvtepi32_ps(vInt);
3008     // RGB + 0, A + 0x80000000.f to undo the signed order.
3009     vTemp = _mm_add_ps(vTemp,g_XMFixAA8R8G8B8);
3010     // Convert 0-255 to 0.0f-1.0f
3011     return _mm_mul_ps(vTemp,g_XMNormalizeA8R8G8B8);
3012 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
3013 #endif // _XM_VMX128_INTRINSICS_
3014 }
3015
3016 //------------------------------------------------------------------------------
3017
3018 XMFINLINE XMMATRIX XMLoadFloat3x3
3019 (
3020     CONST XMFLOAT3X3* pSource
3021 )
3022 {
3023 #if defined(_XM_NO_INTRINSICS_)
3024
3025     XMMATRIX M;
3026
3027     XMASSERT(pSource);
3028
3029     M.r[0].vector4_f32[0] = pSource->m[0][0];
3030     M.r[0].vector4_f32[1] = pSource->m[0][1];
3031     M.r[0].vector4_f32[2] = pSource->m[0][2];
3032     M.r[0].vector4_f32[3] = 0.0f;
3033
3034     M.r[1].vector4_f32[0] = pSource->m[1][0];
3035     M.r[1].vector4_f32[1] = pSource->m[1][1];
3036     M.r[1].vector4_f32[2] = pSource->m[1][2];
3037     M.r[1].vector4_f32[3] = 0.0f;
3038
3039     M.r[2].vector4_f32[0] = pSource->m[2][0];
3040     M.r[2].vector4_f32[1] = pSource->m[2][1];
3041     M.r[2].vector4_f32[2] = pSource->m[2][2];
3042     M.r[2].vector4_f32[3] = 0.0f;
3043
3044     M.r[3].vector4_f32[0] = 0.0f;
3045     M.r[3].vector4_f32[1] = 0.0f;
3046     M.r[3].vector4_f32[2] = 0.0f;
3047     M.r[3].vector4_f32[3] = 1.0f;
3048
3049     return M;
3050
3051 #elif defined(_XM_SSE_INTRINSICS_)
3052     XMMATRIX M;
3053     XMVECTOR V1, V2, V3, Z, T1, T2, T3, T4, T5;
3054
3055     Z = _mm_setzero_ps();
3056
3057     XMASSERT(pSource);
3058
3059     V1 = _mm_loadu_ps( &pSource->m[0][0] );
3060     V2 = _mm_loadu_ps( &pSource->m[1][1] );
3061     V3 = _mm_load_ss( &pSource->m[2][2] );
3062
3063     T1 = _mm_unpackhi_ps( V1, Z );
3064     T2 = _mm_unpacklo_ps( V2, Z );
3065     T3 = _mm_shuffle_ps( V3, T2, _MM_SHUFFLE( 0, 1, 0, 0 ) );
3066     T4 = _mm_movehl_ps( T2, T3 );
3067     T5 = _mm_movehl_ps( Z, T1 );  
3068
3069     M.r[0] = _mm_movelh_ps( V1, T1 );
3070     M.r[1] = _mm_add_ps( T4, T5 );
3071     M.r[2] = _mm_shuffle_ps( V2, V3, _MM_SHUFFLE(1, 0, 3, 2) );
3072     M.r[3] = g_XMIdentityR3;
3073
3074     return M;
3075 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
3076 #endif // _XM_VMX128_INTRINSICS_
3077 }
3078
3079 //------------------------------------------------------------------------------
3080
3081 XMFINLINE XMMATRIX XMLoadFloat4x3
3082 (
3083     CONST XMFLOAT4X3* pSource
3084 )
3085 {
3086 #if defined(_XM_NO_INTRINSICS_)
3087     XMMATRIX M;
3088     XMASSERT(pSource);
3089
3090     ((UINT *)(&M.r[0].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[0][0]))[0];
3091     ((UINT *)(&M.r[0].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[0][1]))[0];
3092     ((UINT *)(&M.r[0].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[0][2]))[0];
3093     M.r[0].vector4_f32[3] = 0.0f;
3094
3095     ((UINT *)(&M.r[1].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[1][0]))[0];
3096     ((UINT *)(&M.r[1].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[1][1]))[0];
3097     ((UINT *)(&M.r[1].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[1][2]))[0];
3098     M.r[1].vector4_f32[3] = 0.0f;
3099
3100     ((UINT *)(&M.r[2].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[2][0]))[0];
3101     ((UINT *)(&M.r[2].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[2][1]))[0];
3102     ((UINT *)(&M.r[2].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[2][2]))[0];
3103     M.r[2].vector4_f32[3] = 0.0f;
3104
3105     ((UINT *)(&M.r[3].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[3][0]))[0];
3106     ((UINT *)(&M.r[3].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[3][1]))[0];
3107     ((UINT *)(&M.r[3].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[3][2]))[0];
3108     M.r[3].vector4_f32[3] = 1.0f;
3109
3110     return M;
3111
3112 #elif defined(_XM_SSE_INTRINSICS_)
3113     XMASSERT(pSource);
3114     // Use unaligned load instructions to 
3115     // load the 12 floats
3116     // vTemp1 = x1,y1,z1,x2
3117     XMVECTOR vTemp1 = _mm_loadu_ps(&pSource->m[0][0]);
3118     // vTemp2 = y2,z2,x3,y3
3119     XMVECTOR vTemp2 = _mm_loadu_ps(&pSource->m[1][1]);
3120     // vTemp4 = z3,x4,y4,z4
3121     XMVECTOR vTemp4 = _mm_loadu_ps(&pSource->m[2][2]);
3122     // vTemp3 = x3,y3,z3,z3
3123     XMVECTOR vTemp3 = _mm_shuffle_ps(vTemp2,vTemp4,_MM_SHUFFLE(0,0,3,2));
3124     // vTemp2 = y2,z2,x2,x2
3125     vTemp2 = _mm_shuffle_ps(vTemp2,vTemp1,_MM_SHUFFLE(3,3,1,0));
3126     // vTemp2 = x2,y2,z2,z2
3127     vTemp2 = _mm_shuffle_ps(vTemp2,vTemp2,_MM_SHUFFLE(1,1,0,2));
3128     // vTemp1 = x1,y1,z1,0
3129     vTemp1 = _mm_and_ps(vTemp1,g_XMMask3);
3130     // vTemp2 = x2,y2,z2,0
3131     vTemp2 = _mm_and_ps(vTemp2,g_XMMask3);
3132     // vTemp3 = x3,y3,z3,0
3133     vTemp3 = _mm_and_ps(vTemp3,g_XMMask3);
3134     // vTemp4i = x4,y4,z4,0
3135     __m128i vTemp4i = _mm_srli_si128(reinterpret_cast<const __m128i *>(&vTemp4)[0],32/8);
3136     // vTemp4i = x4,y4,z4,1.0f
3137     vTemp4i = _mm_or_si128(vTemp4i,g_XMIdentityR3);
3138     XMMATRIX M(vTemp1,
3139             vTemp2,
3140             vTemp3,
3141             reinterpret_cast<const __m128 *>(&vTemp4i)[0]);
3142     return M;
3143 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
3144 #endif // _XM_VMX128_INTRINSICS_
3145 }
3146
3147 //------------------------------------------------------------------------------
3148
3149 XMFINLINE XMMATRIX XMLoadFloat4x3A
3150 (
3151     CONST XMFLOAT4X3A* pSource
3152 )
3153 {
3154 #if defined(_XM_NO_INTRINSICS_)
3155
3156     XMMATRIX M;
3157
3158     XMASSERT(pSource);
3159     XMASSERT(((UINT_PTR)pSource & 0xF) == 0);
3160
3161     M.r[0].vector4_f32[0] = pSource->m[0][0];
3162     M.r[0].vector4_f32[1] = pSource->m[0][1];
3163     M.r[0].vector4_f32[2] = pSource->m[0][2];
3164     M.r[0].vector4_f32[3] = 0.0f;
3165
3166     M.r[1].vector4_f32[0] = pSource->m[1][0];
3167     M.r[1].vector4_f32[1] = pSource->m[1][1];
3168     M.r[1].vector4_f32[2] = pSource->m[1][2];
3169     M.r[1].vector4_f32[3] = 0.0f;
3170
3171     M.r[2].vector4_f32[0] = pSource->m[2][0];
3172     M.r[2].vector4_f32[1] = pSource->m[2][1];
3173     M.r[2].vector4_f32[2] = pSource->m[2][2];
3174     M.r[2].vector4_f32[3] = 0.0f;
3175
3176     M.r[3].vector4_f32[0] = pSource->m[3][0];
3177     M.r[3].vector4_f32[1] = pSource->m[3][1];
3178     M.r[3].vector4_f32[2] = pSource->m[3][2];
3179     M.r[3].vector4_f32[3] = 1.0f;
3180
3181     return M;
3182
3183 #elif defined(_XM_SSE_INTRINSICS_)
3184     XMASSERT(pSource);
3185     // Use aligned load instructions to 
3186     // load the 12 floats
3187     // vTemp1 = x1,y1,z1,x2
3188     XMVECTOR vTemp1 = _mm_load_ps(&pSource->m[0][0]);
3189     // vTemp2 = y2,z2,x3,y3
3190     XMVECTOR vTemp2 = _mm_load_ps(&pSource->m[1][1]);
3191     // vTemp4 = z3,x4,y4,z4
3192     XMVECTOR vTemp4 = _mm_load_ps(&pSource->m[2][2]);
3193     // vTemp3 = x3,y3,z3,z3
3194     XMVECTOR vTemp3 = _mm_shuffle_ps(vTemp2,vTemp4,_MM_SHUFFLE(0,0,3,2));
3195     // vTemp2 = y2,z2,x2,x2
3196     vTemp2 = _mm_shuffle_ps(vTemp2,vTemp1,_MM_SHUFFLE(3,3,1,0));
3197     // vTemp2 = x2,y2,z2,z2
3198     vTemp2 = _mm_shuffle_ps(vTemp2,vTemp2,_MM_SHUFFLE(1,1,0,2));
3199     // vTemp1 = x1,y1,z1,0
3200     vTemp1 = _mm_and_ps(vTemp1,g_XMMask3);
3201     // vTemp2 = x2,y2,z2,0
3202     vTemp2 = _mm_and_ps(vTemp2,g_XMMask3);
3203     // vTemp3 = x3,y3,z3,0
3204     vTemp3 = _mm_and_ps(vTemp3,g_XMMask3);
3205     // vTemp4i = x4,y4,z4,0
3206     __m128i vTemp4i = _mm_srli_si128(reinterpret_cast<const __m128i *>(&vTemp4)[0],32/8);
3207     // vTemp4i = x4,y4,z4,1.0f
3208     vTemp4i = _mm_or_si128(vTemp4i,g_XMIdentityR3);
3209     XMMATRIX M(vTemp1,
3210             vTemp2,
3211             vTemp3,
3212             reinterpret_cast<const __m128 *>(&vTemp4i)[0]);
3213     return M;
3214 #else // _XM_VMX128_INTRINSICS_
3215 #endif // _XM_VMX128_INTRINSICS_
3216 }
3217
3218 //------------------------------------------------------------------------------
3219
3220 XMFINLINE XMMATRIX XMLoadFloat4x4
3221 (
3222     CONST XMFLOAT4X4* pSource
3223 )
3224 {
3225 #if defined(_XM_NO_INTRINSICS_)
3226     XMMATRIX M;
3227     XMASSERT(pSource);
3228
3229     ((UINT *)(&M.r[0].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[0][0]))[0];
3230     ((UINT *)(&M.r[0].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[0][1]))[0];
3231     ((UINT *)(&M.r[0].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[0][2]))[0];
3232     ((UINT *)(&M.r[0].vector4_f32[3]))[0] = ((const UINT *)(&pSource->m[0][3]))[0];
3233
3234     ((UINT *)(&M.r[1].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[1][0]))[0];
3235     ((UINT *)(&M.r[1].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[1][1]))[0];
3236     ((UINT *)(&M.r[1].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[1][2]))[0];
3237     ((UINT *)(&M.r[1].vector4_f32[3]))[0] = ((const UINT *)(&pSource->m[1][3]))[0];
3238
3239     ((UINT *)(&M.r[2].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[2][0]))[0];
3240     ((UINT *)(&M.r[2].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[2][1]))[0];
3241     ((UINT *)(&M.r[2].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[2][2]))[0];
3242     ((UINT *)(&M.r[2].vector4_f32[3]))[0] = ((const UINT *)(&pSource->m[2][3]))[0];
3243
3244     ((UINT *)(&M.r[3].vector4_f32[0]))[0] = ((const UINT *)(&pSource->m[3][0]))[0];
3245     ((UINT *)(&M.r[3].vector4_f32[1]))[0] = ((const UINT *)(&pSource->m[3][1]))[0];
3246     ((UINT *)(&M.r[3].vector4_f32[2]))[0] = ((const UINT *)(&pSource->m[3][2]))[0];
3247     ((UINT *)(&M.r[3].vector4_f32[3]))[0] = ((const UINT *)(&pSource->m[3][3]))[0];
3248
3249     return M;
3250
3251 #elif defined(_XM_SSE_INTRINSICS_)
3252     XMASSERT(pSource);
3253     XMMATRIX M;
3254
3255     M.r[0] = _mm_loadu_ps( &pSource->_11 );
3256     M.r[1] = _mm_loadu_ps( &pSource->_21 );
3257     M.r[2] = _mm_loadu_ps( &pSource->_31 );
3258     M.r[3] = _mm_loadu_ps( &pSource->_41 );
3259
3260     return M;
3261 #elif defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
3262 #endif // _XM_VMX128_INTRINSICS_
3263 }
3264
3265 //------------------------------------------------------------------------------
3266
3267 XMFINLINE XMMATRIX XMLoadFloat4x4A
3268 (
3269     CONST XMFLOAT4X4A* pSource
3270 )
3271 {
3272 #if defined(_XM_NO_INTRINSICS_)
3273
3274     XMMATRIX M;
3275
3276     XMASSERT(pSource);
3277     XMASSERT(((UINT_PTR)pSource & 0xF) == 0);
3278
3279     M.r[0].vector4_f32[0] = pSource->m[0][0];
3280     M.r[0].vector4_f32[1] = pSource->m[0][1];
3281     M.r[0].vector4_f32[2] = pSource->m[0][2];
3282     M.r[0].vector4_f32[3] = pSource->m[0][3];
3283
3284     M.r[1].vector4_f32[0] = pSource->m[1][0];
3285     M.r[1].vector4_f32[1] = pSource->m[1][1];
3286     M.r[1].vector4_f32[2] = pSource->m[1][2];
3287     M.r[1].vector4_f32[3] = pSource->m[1][3];
3288
3289     M.r[2].vector4_f32[0] = pSource->m[2][0];
3290     M.r[2].vector4_f32[1] = pSource->m[2][1];
3291     M.r[2].vector4_f32[2] = pSource->m[2][2];
3292     M.r[2].vector4_f32[3] = pSource->m[2][3];
3293
3294     M.r[3].vector4_f32[0] = pSource->m[3][0];
3295     M.r[3].vector4_f32[1] = pSource->m[3][1];
3296     M.r[3].vector4_f32[2] = pSource->m[3][2];
3297     M.r[3].vector4_f32[3] = pSource->m[3][3];
3298
3299     return M;
3300
3301 #elif defined(_XM_SSE_INTRINSICS_)
3302     XMMATRIX M;
3303
3304     XMASSERT(pSource);
3305
3306     M.r[0] = _mm_load_ps( &pSource->_11 );
3307     M.r[1] = _mm_load_ps( &pSource->_21 );
3308     M.r[2] = _mm_load_ps( &pSource->_31 );
3309     M.r[3] = _mm_load_ps( &pSource->_41 );
3310
3311     return M;
3312 #else // _XM_VMX128_INTRINSICS_
3313 #endif // _XM_VMX128_INTRINSICS_
3314 }
3315
3316 /****************************************************************************
3317  *
3318  * Vector and matrix store operations
3319  *
3320  ****************************************************************************/
3321
3322 XMFINLINE VOID XMStoreInt
3323 (
3324     UINT*    pDestination,
3325     FXMVECTOR V
3326 )
3327 {
3328 #if defined(_XM_NO_INTRINSICS_)
3329
3330     XMASSERT(pDestination);
3331     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3332
3333     *pDestination = XMVectorGetIntX( V );
3334
3335 #elif defined(_XM_SSE_INTRINSICS_)
3336     XMASSERT(pDestination);
3337     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3338
3339     _mm_store_ss( (float*)pDestination, V );
3340 #else // _XM_VMX128_INTRINSICS_
3341 #endif // _XM_VMX128_INTRINSICS_
3342 }
3343
3344 //------------------------------------------------------------------------------
3345
3346 XMFINLINE VOID XMStoreFloat
3347 (
3348     FLOAT*    pDestination,
3349     FXMVECTOR V
3350 )
3351 {
3352 #if defined(_XM_NO_INTRINSICS_)
3353
3354     XMASSERT(pDestination);
3355     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3356
3357     *pDestination = XMVectorGetX( V );
3358
3359 #elif defined(_XM_SSE_INTRINSICS_)
3360     XMASSERT(pDestination);
3361     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3362
3363     _mm_store_ss( pDestination, V );
3364 #else // _XM_VMX128_INTRINSICS_
3365 #endif // _XM_VMX128_INTRINSICS_
3366 }
3367
3368 //------------------------------------------------------------------------------
3369
3370 XMFINLINE VOID XMStoreInt2
3371 (
3372     UINT*    pDestination, 
3373     FXMVECTOR V
3374 )
3375 {
3376 #if defined(_XM_NO_INTRINSICS_)
3377
3378     XMASSERT(pDestination);
3379     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3380
3381     pDestination[0] = V.vector4_u32[0];
3382     pDestination[1] = V.vector4_u32[1];
3383
3384 #elif defined(_XM_SSE_INTRINSICS_)
3385     XMASSERT(pDestination);
3386     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3387
3388     XMVECTOR T = _mm_shuffle_ps( V, V, _MM_SHUFFLE( 1, 1, 1, 1 ) );
3389     _mm_store_ss( (float*)&pDestination[0], V );
3390     _mm_store_ss( (float*)&pDestination[1], T );
3391 #else // _XM_VMX128_INTRINSICS_
3392 #endif // _XM_VMX128_INTRINSICS_
3393 }
3394
3395 //------------------------------------------------------------------------------
3396
3397 XMFINLINE VOID XMStoreSInt2
3398 (
3399     XMINT2* pDestination,
3400     FXMVECTOR V
3401 )
3402 {
3403 #if defined(_XM_NO_INTRINSICS_)
3404
3405     XMASSERT(pDestination);
3406     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3407
3408     pDestination->x = (INT)V.vector4_f32[0];
3409     pDestination->y = (INT)V.vector4_f32[1];
3410
3411 #elif defined(_XM_SSE_INTRINSICS_)
3412     XMASSERT(pDestination);
3413     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3414
3415     // In case of positive overflow, detect it
3416     XMVECTOR vOverflow = _mm_cmpgt_ps(V,g_XMMaxInt);
3417     // Float to int conversion
3418     __m128i vResulti = _mm_cvttps_epi32(V);
3419     // If there was positive overflow, set to 0x7FFFFFFF
3420     XMVECTOR vResult = _mm_and_ps(vOverflow,g_XMAbsMask);
3421     vOverflow = _mm_andnot_ps(vOverflow,reinterpret_cast<const __m128 *>(&vResulti)[0]);
3422     vOverflow = _mm_or_ps(vOverflow,vResult);
3423     // Write two ints
3424     XMVECTOR T = _mm_shuffle_ps( vOverflow, vOverflow, _MM_SHUFFLE( 1, 1, 1, 1 ) );
3425     _mm_store_ss( (float*)&pDestination->x, vOverflow );
3426     _mm_store_ss( (float*)&pDestination->y, T );
3427 #else // _XM_VMX128_INTRINSICS_
3428 #endif // _XM_VMX128_INTRINSICS_
3429 }
3430
3431 //------------------------------------------------------------------------------
3432
3433 XMFINLINE VOID XMStoreUInt2
3434 (
3435     XMUINT2* pDestination,
3436     FXMVECTOR V
3437 )
3438 {
3439 #if defined(_XM_NO_INTRINSICS_)
3440
3441     XMASSERT(pDestination);
3442     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3443
3444     pDestination->x = (UINT)V.vector4_f32[0];
3445     pDestination->y = (UINT)V.vector4_f32[1];
3446
3447 #elif defined(_XM_SSE_INTRINSICS_)
3448     XMASSERT(pDestination);
3449     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3450
3451     // Clamp to >=0
3452     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
3453     // Any numbers that are too big, set to 0xFFFFFFFFU
3454     XMVECTOR vOverflow = _mm_cmpgt_ps(vResult,g_XMMaxUInt);
3455     XMVECTOR vValue = g_XMUnsignedFix;
3456     // Too large for a signed integer?
3457     XMVECTOR vMask = _mm_cmpge_ps(vResult,vValue);
3458     // Zero for number's lower than 0x80000000, 32768.0f*65536.0f otherwise
3459     vValue = _mm_and_ps(vValue,vMask);
3460     // Perform fixup only on numbers too large (Keeps low bit precision)
3461     vResult = _mm_sub_ps(vResult,vValue);
3462     __m128i vResulti = _mm_cvttps_epi32(vResult);
3463     // Convert from signed to unsigned pnly if greater than 0x80000000
3464     vMask = _mm_and_ps(vMask,g_XMNegativeZero);
3465     vResult = _mm_xor_ps(reinterpret_cast<const __m128 *>(&vResulti)[0],vMask);
3466     // On those that are too large, set to 0xFFFFFFFF
3467     vResult = _mm_or_ps(vResult,vOverflow);
3468     // Write two uints
3469     XMVECTOR T = _mm_shuffle_ps( vResult, vResult, _MM_SHUFFLE( 1, 1, 1, 1 ) );
3470     _mm_store_ss( (float*)&pDestination->x, vResult );
3471     _mm_store_ss( (float*)&pDestination->y, T );
3472 #else // _XM_VMX128_INTRINSICS_
3473 #endif // _XM_VMX128_INTRINSICS_
3474 }
3475
3476 //------------------------------------------------------------------------------
3477
3478 XMFINLINE VOID XMStoreInt2A
3479 (
3480     UINT*    pDestination, 
3481     FXMVECTOR V
3482 )
3483 {
3484 #if defined(_XM_NO_INTRINSICS_)
3485
3486     XMASSERT(pDestination);
3487     XMASSERT(((UINT_PTR)pDestination & 0xF) == 0);
3488
3489     pDestination[0] = V.vector4_u32[0];
3490     pDestination[1] = V.vector4_u32[1];
3491
3492 #elif defined(_XM_SSE_INTRINSICS_)
3493
3494     XMASSERT(pDestination);
3495     XMASSERT(((UINT_PTR)pDestination & 0xF) == 0);
3496
3497     _mm_storel_epi64( (__m128i*)pDestination, reinterpret_cast<const __m128i *>(&V)[0] );
3498
3499 #else // _XM_VMX128_INTRINSICS_
3500 #endif // _XM_VMX128_INTRINSICS_
3501 }
3502
3503 //------------------------------------------------------------------------------
3504
3505 XMFINLINE VOID XMStoreFloat2
3506 (
3507     XMFLOAT2* pDestination, 
3508     FXMVECTOR  V
3509 )
3510 {
3511 #if defined(_XM_NO_INTRINSICS_)
3512
3513     XMASSERT(pDestination);
3514     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3515
3516     pDestination->x = V.vector4_f32[0];
3517     pDestination->y = V.vector4_f32[1];
3518
3519 #elif defined(_XM_SSE_INTRINSICS_)
3520     XMASSERT(pDestination);
3521     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3522
3523     XMVECTOR T = _mm_shuffle_ps( V, V, _MM_SHUFFLE( 1, 1, 1, 1 ) );
3524     _mm_store_ss( &pDestination->x, V );
3525     _mm_store_ss( &pDestination->y, T );
3526 #else // _XM_VMX128_INTRINSICS_
3527 #endif // _XM_VMX128_INTRINSICS_
3528 }
3529
3530 //------------------------------------------------------------------------------
3531
3532 XMFINLINE VOID XMStoreFloat2A
3533 (
3534     XMFLOAT2A*   pDestination, 
3535     FXMVECTOR     V
3536 )
3537 {
3538 #if defined(_XM_NO_INTRINSICS_)
3539
3540     XMASSERT(pDestination);
3541     XMASSERT(((UINT_PTR)pDestination & 0xF) == 0);
3542
3543     pDestination->x = V.vector4_f32[0];
3544     pDestination->y = V.vector4_f32[1];
3545
3546 #elif defined(_XM_SSE_INTRINSICS_)
3547
3548     XMASSERT(pDestination);
3549     XMASSERT(((UINT_PTR)pDestination & 0xF) == 0);
3550
3551     _mm_storel_epi64( (__m128i*)pDestination, reinterpret_cast<const __m128i *>(&V)[0] );
3552
3553 #else // _XM_VMX128_INTRINSICS_
3554 #endif // _XM_VMX128_INTRINSICS_
3555 }
3556
3557 //------------------------------------------------------------------------------
3558
3559 XMFINLINE VOID XMStoreHalf2
3560 (
3561     XMHALF2* pDestination, 
3562     FXMVECTOR V
3563 )
3564 {
3565 #if defined(_XM_NO_INTRINSICS_)
3566
3567     XMASSERT(pDestination);
3568
3569     pDestination->x = XMConvertFloatToHalf(V.vector4_f32[0]);
3570     pDestination->y = XMConvertFloatToHalf(V.vector4_f32[1]);
3571
3572 #elif defined(_XM_SSE_INTRINSICS_)
3573     XMASSERT(pDestination);
3574     pDestination->x = XMConvertFloatToHalf(XMVectorGetX(V));
3575     pDestination->y = XMConvertFloatToHalf(XMVectorGetY(V));
3576 #else // _XM_VMX128_INTRINSICS_
3577 #endif // _XM_VMX128_INTRINSICS_
3578 }
3579
3580 //------------------------------------------------------------------------------
3581
3582 XMFINLINE VOID XMStoreShortN2
3583 (
3584     XMSHORTN2* pDestination, 
3585     FXMVECTOR   V
3586 )
3587 {
3588 #if defined(_XM_NO_INTRINSICS_)
3589
3590     XMVECTOR N;
3591     static CONST XMVECTORF32  Scale = {32767.0f, 32767.0f, 32767.0f, 32767.0f};
3592
3593     XMASSERT(pDestination);
3594
3595     N = XMVectorClamp(V, g_XMNegativeOne.v, g_XMOne.v);
3596     N = XMVectorMultiply(N, Scale.v);
3597     N = XMVectorRound(N);
3598
3599     pDestination->x = (SHORT)N.vector4_f32[0];
3600     pDestination->y = (SHORT)N.vector4_f32[1];
3601
3602 #elif defined(_XM_SSE_INTRINSICS_)
3603     XMASSERT(pDestination);
3604     static CONST XMVECTORF32 Scale = {32767.0f, 32767.0f, 32767.0f, 32767.0f};
3605
3606     XMVECTOR vResult = _mm_max_ps(V,g_XMNegativeOne);
3607     vResult = _mm_min_ps(vResult,g_XMOne);
3608     vResult = _mm_mul_ps(vResult,Scale);
3609     __m128i vResulti = _mm_cvtps_epi32(vResult);
3610     vResulti = _mm_packs_epi32(vResulti,vResulti);
3611     _mm_store_ss(reinterpret_cast<float *>(&pDestination->x),reinterpret_cast<const __m128 *>(&vResulti)[0]);
3612 #else // _XM_VMX128_INTRINSICS_
3613 #endif // _XM_VMX128_INTRINSICS_
3614 }
3615
3616 //------------------------------------------------------------------------------
3617
3618 XMFINLINE VOID XMStoreShort2
3619 (
3620     XMSHORT2* pDestination, 
3621     FXMVECTOR  V
3622 )
3623 {
3624 #if defined(_XM_NO_INTRINSICS_)
3625
3626     XMVECTOR               N;
3627     static CONST XMVECTOR  Min = {-32767.0f, -32767.0f, -32767.0f, -32767.0f};
3628     static CONST XMVECTOR  Max = {32767.0f, 32767.0f, 32767.0f, 32767.0f};
3629
3630     XMASSERT(pDestination);
3631
3632     N = XMVectorClamp(V, Min, Max);
3633     N = XMVectorRound(N);
3634
3635     pDestination->x = (SHORT)N.vector4_f32[0];
3636     pDestination->y = (SHORT)N.vector4_f32[1];
3637
3638 #elif defined(_XM_SSE_INTRINSICS_)
3639     XMASSERT(pDestination);
3640     static CONST XMVECTORF32 Min = {-32767.0f, -32767.0f, -32767.0f, -32767.0f};
3641     static CONST XMVECTORF32 Max = {32767.0f, 32767.0f, 32767.0f, 32767.0f};
3642     // Bounds check
3643     XMVECTOR vResult = _mm_max_ps(V,Min);
3644     vResult = _mm_min_ps(vResult,Max);
3645      // Convert to int with rounding
3646     __m128i vInt = _mm_cvtps_epi32(vResult);
3647     // Pack the ints into shorts
3648     vInt = _mm_packs_epi32(vInt,vInt);
3649     _mm_store_ss(reinterpret_cast<float *>(&pDestination->x),reinterpret_cast<const __m128 *>(&vInt)[0]);
3650 #else // _XM_VMX128_INTRINSICS_
3651 #endif // _XM_VMX128_INTRINSICS_
3652 }
3653
3654 //------------------------------------------------------------------------------
3655
3656 XMFINLINE VOID XMStoreUShortN2
3657 (
3658     XMUSHORTN2* pDestination, 
3659     FXMVECTOR    V
3660 )
3661 {
3662 #if defined(_XM_NO_INTRINSICS_)
3663
3664     XMVECTOR               N;
3665     static CONST XMVECTORF32  Scale = {65535.0f, 65535.0f, 65535.0f, 65535.0f};
3666
3667     XMASSERT(pDestination);
3668
3669     N = XMVectorSaturate(V);
3670     N = XMVectorMultiplyAdd(N, Scale.v, g_XMOneHalf.v);
3671     N = XMVectorTruncate(N);
3672
3673     pDestination->x = (SHORT)N.vector4_f32[0];
3674     pDestination->y = (SHORT)N.vector4_f32[1];
3675
3676 #elif defined(_XM_SSE_INTRINSICS_)
3677     XMASSERT(pDestination);
3678     static CONST XMVECTORF32 Scale = {65535.0f, 65535.0f, 65535.0f, 65535.0f};
3679     // Bounds check
3680     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
3681     vResult = _mm_min_ps(vResult,g_XMOne);
3682     vResult = _mm_mul_ps(vResult,Scale);
3683      // Convert to int with rounding
3684     __m128i vInt = _mm_cvtps_epi32(vResult);
3685     // Since the SSE pack instruction clamps using signed rules,
3686     // manually extract the values to store them to memory
3687     pDestination->x = static_cast<SHORT>(_mm_extract_epi16(vInt,0));
3688     pDestination->y = static_cast<SHORT>(_mm_extract_epi16(vInt,2));
3689 #else // _XM_VMX128_INTRINSICS_
3690 #endif // _XM_VMX128_INTRINSICS_
3691 }
3692
3693 //------------------------------------------------------------------------------
3694
3695 XMFINLINE VOID XMStoreUShort2
3696 (
3697     XMUSHORT2* pDestination, 
3698     FXMVECTOR   V
3699 )
3700 {
3701 #if defined(_XM_NO_INTRINSICS_)
3702
3703     XMVECTOR               N;
3704     static CONST XMVECTOR  Max = {65535.0f, 65535.0f, 65535.0f, 65535.0f};
3705
3706     XMASSERT(pDestination);
3707
3708     N = XMVectorClamp(V, XMVectorZero(), Max);
3709     N = XMVectorRound(N);
3710
3711     pDestination->x = (SHORT)N.vector4_f32[0];
3712     pDestination->y = (SHORT)N.vector4_f32[1];
3713
3714 #elif defined(_XM_SSE_INTRINSICS_)
3715     XMASSERT(pDestination);
3716     static CONST XMVECTORF32  Max = {65535.0f, 65535.0f, 65535.0f, 65535.0f};
3717     // Bounds check
3718     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
3719     vResult = _mm_min_ps(vResult,Max);
3720      // Convert to int with rounding
3721     __m128i vInt = _mm_cvtps_epi32(vResult);
3722     // Since the SSE pack instruction clamps using signed rules,
3723     // manually extract the values to store them to memory
3724     pDestination->x = static_cast<SHORT>(_mm_extract_epi16(vInt,0));
3725     pDestination->y = static_cast<SHORT>(_mm_extract_epi16(vInt,2));
3726 #else // _XM_VMX128_INTRINSICS_
3727 #endif // _XM_VMX128_INTRINSICS_
3728 }
3729
3730 //------------------------------------------------------------------------------
3731
3732 XMFINLINE VOID XMStoreByteN2
3733 (
3734     XMBYTEN2* pDestination, 
3735     FXMVECTOR   V
3736 )
3737 {
3738     XMVECTOR N;
3739     XMFLOAT4A tmp;
3740     static CONST XMVECTORF32  Scale = {127.0f, 127.0f, 127.0f, 127.0f};
3741
3742     XMASSERT(pDestination);
3743
3744     N = XMVectorClamp(V, g_XMNegativeOne.v, g_XMOne.v);
3745     N = XMVectorMultiply(N, Scale.v);
3746     N = XMVectorRound(N);
3747
3748     XMStoreFloat4A( &tmp, N );
3749
3750     pDestination->x = (CHAR)tmp.x;
3751     pDestination->y = (CHAR)tmp.y;
3752 }
3753
3754 //------------------------------------------------------------------------------
3755
3756 XMFINLINE VOID XMStoreByte2
3757 (
3758     XMBYTE2* pDestination, 
3759     FXMVECTOR  V
3760 )
3761 {
3762     XMVECTOR               N;
3763     XMFLOAT4A              tmp;
3764     static CONST XMVECTOR  Min = {-127.0f, -127.0f, -127.0f, -127.0f};
3765     static CONST XMVECTOR  Max = {127.0f, 127.0f, 127.0f, 127.0f};
3766
3767     XMASSERT(pDestination);
3768
3769     N = XMVectorClamp(V, Min, Max);
3770     N = XMVectorRound(N);
3771
3772     XMStoreFloat4A( &tmp, N );
3773
3774     pDestination->x = (CHAR)tmp.x;
3775     pDestination->y = (CHAR)tmp.y;
3776 }
3777
3778 //------------------------------------------------------------------------------
3779
3780 XMFINLINE VOID XMStoreUByteN2
3781 (
3782     XMUBYTEN2* pDestination, 
3783     FXMVECTOR    V
3784 )
3785 {
3786     XMVECTOR               N;
3787     XMFLOAT4A              tmp;
3788     static CONST XMVECTORF32  Scale = {255.0f, 255.0f, 255.0f, 255.0f};
3789
3790     XMASSERT(pDestination);
3791
3792     N = XMVectorSaturate(V);
3793     N = XMVectorMultiplyAdd(N, Scale.v, g_XMOneHalf.v);
3794     N = XMVectorTruncate(N);
3795
3796     XMStoreFloat4A( &tmp, N );
3797
3798     pDestination->x = (BYTE)tmp.x;
3799     pDestination->y = (BYTE)tmp.y;
3800 }
3801
3802 //------------------------------------------------------------------------------
3803
3804 XMFINLINE VOID XMStoreUByte2
3805 (
3806     XMUBYTE2* pDestination, 
3807     FXMVECTOR   V
3808 )
3809 {
3810     XMVECTOR               N;
3811     static CONST XMVECTOR  Max = {255.0f, 255.0f, 255.0f, 255.0f};
3812     XMFLOAT4A              tmp;
3813
3814     XMASSERT(pDestination);
3815
3816     N = XMVectorClamp(V, XMVectorZero(), Max);
3817     N = XMVectorRound(N);
3818
3819     XMStoreFloat4A( &tmp, N );
3820
3821     pDestination->x = (BYTE)tmp.x;
3822     pDestination->y = (BYTE)tmp.y;
3823 }
3824
3825 //------------------------------------------------------------------------------
3826
3827 XMFINLINE VOID XMStoreInt3
3828 (
3829     UINT*    pDestination, 
3830     FXMVECTOR V
3831 )
3832 {
3833 #if defined(_XM_NO_INTRINSICS_)
3834
3835     XMASSERT(pDestination);
3836     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3837
3838     pDestination[0] = V.vector4_u32[0];
3839     pDestination[1] = V.vector4_u32[1];
3840     pDestination[2] = V.vector4_u32[2];
3841
3842 #elif defined(_XM_SSE_INTRINSICS_)
3843
3844     XMASSERT(pDestination);
3845     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3846
3847     XMVECTOR T1 = _mm_shuffle_ps(V,V,_MM_SHUFFLE(1,1,1,1));
3848     XMVECTOR T2 = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,2,2,2));
3849     _mm_store_ss( (float*)pDestination, V );
3850     _mm_store_ss( (float*)&pDestination[1], T1 );
3851     _mm_store_ss( (float*)&pDestination[2], T2 );
3852
3853 #else // _XM_VMX128_INTRINSICS_
3854 #endif // _XM_VMX128_INTRINSICS_
3855 }
3856
3857 //------------------------------------------------------------------------------
3858
3859 XMFINLINE VOID XMStoreSInt3
3860 (
3861     XMINT3* pDestination,
3862     FXMVECTOR V
3863 )
3864 {
3865 #if defined(_XM_NO_INTRINSICS_)
3866
3867     XMASSERT(pDestination);
3868     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3869
3870     pDestination->x = (INT)V.vector4_f32[0];
3871     pDestination->y = (INT)V.vector4_f32[1];
3872     pDestination->z = (INT)V.vector4_f32[2];
3873
3874 #elif defined(_XM_SSE_INTRINSICS_)
3875
3876     XMASSERT(pDestination);
3877     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3878
3879     // In case of positive overflow, detect it
3880     XMVECTOR vOverflow = _mm_cmpgt_ps(V,g_XMMaxInt);
3881     // Float to int conversion
3882     __m128i vResulti = _mm_cvttps_epi32(V);
3883     // If there was positive overflow, set to 0x7FFFFFFF
3884     XMVECTOR vResult = _mm_and_ps(vOverflow,g_XMAbsMask);
3885     vOverflow = _mm_andnot_ps(vOverflow,reinterpret_cast<const __m128 *>(&vResulti)[0]);
3886     vOverflow = _mm_or_ps(vOverflow,vResult);
3887     // Write 3 uints
3888     XMVECTOR T1 = _mm_shuffle_ps(vOverflow,vOverflow,_MM_SHUFFLE(1,1,1,1));
3889     XMVECTOR T2 = _mm_shuffle_ps(vOverflow,vOverflow,_MM_SHUFFLE(2,2,2,2));
3890     _mm_store_ss( (float*)&pDestination->x, vOverflow );
3891     _mm_store_ss( (float*)&pDestination->y, T1 );
3892     _mm_store_ss( (float*)&pDestination->z, T2 );
3893
3894 #else // _XM_VMX128_INTRINSICS_
3895 #endif // _XM_VMX128_INTRINSICS_
3896 }
3897
3898 //------------------------------------------------------------------------------
3899
3900 XMFINLINE VOID XMStoreUInt3
3901 (
3902     XMUINT3* pDestination,
3903     FXMVECTOR V
3904 )
3905 {
3906 #if defined(_XM_NO_INTRINSICS_)
3907
3908     XMASSERT(pDestination);
3909     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3910
3911     pDestination->x = (UINT)V.vector4_f32[0];
3912     pDestination->y = (UINT)V.vector4_f32[1];
3913     pDestination->z = (UINT)V.vector4_f32[2];
3914
3915 #elif defined(_XM_SSE_INTRINSICS_)
3916
3917     XMASSERT(pDestination);
3918     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3919
3920     // Clamp to >=0
3921     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
3922     // Any numbers that are too big, set to 0xFFFFFFFFU
3923     XMVECTOR vOverflow = _mm_cmpgt_ps(vResult,g_XMMaxUInt);
3924     XMVECTOR vValue = g_XMUnsignedFix;
3925     // Too large for a signed integer?
3926     XMVECTOR vMask = _mm_cmpge_ps(vResult,vValue);
3927     // Zero for number's lower than 0x80000000, 32768.0f*65536.0f otherwise
3928     vValue = _mm_and_ps(vValue,vMask);
3929     // Perform fixup only on numbers too large (Keeps low bit precision)
3930     vResult = _mm_sub_ps(vResult,vValue);
3931     __m128i vResulti = _mm_cvttps_epi32(vResult);
3932     // Convert from signed to unsigned pnly if greater than 0x80000000
3933     vMask = _mm_and_ps(vMask,g_XMNegativeZero);
3934     vResult = _mm_xor_ps(reinterpret_cast<const __m128 *>(&vResulti)[0],vMask);
3935     // On those that are too large, set to 0xFFFFFFFF
3936     vResult = _mm_or_ps(vResult,vOverflow);
3937     // Write 3 uints
3938     XMVECTOR T1 = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(1,1,1,1));
3939     XMVECTOR T2 = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(2,2,2,2));
3940     _mm_store_ss( (float*)&pDestination->x, vResult );
3941     _mm_store_ss( (float*)&pDestination->y, T1 );
3942     _mm_store_ss( (float*)&pDestination->z, T2 );
3943
3944 #else // _XM_VMX128_INTRINSICS_
3945 #endif // _XM_VMX128_INTRINSICS_
3946 }
3947
3948 //------------------------------------------------------------------------------
3949
3950 XMFINLINE VOID XMStoreInt3A
3951 (
3952     UINT*    pDestination, 
3953     FXMVECTOR V
3954 )
3955 {
3956 #if defined(_XM_NO_INTRINSICS_)
3957
3958     XMASSERT(pDestination);
3959     XMASSERT(((UINT_PTR)pDestination & 0xF) == 0);
3960
3961     pDestination[0] = V.vector4_u32[0];
3962     pDestination[1] = V.vector4_u32[1];
3963     pDestination[2] = V.vector4_u32[2];
3964
3965 #elif defined(_XM_SSE_INTRINSICS_)
3966
3967     XMASSERT(pDestination);
3968     XMASSERT(((UINT_PTR)pDestination & 0xF) == 0);
3969
3970     XMVECTOR T = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,2,2,2));
3971     _mm_storel_epi64( (__m128i*)pDestination, reinterpret_cast<const __m128i *>(&V)[0] );
3972     _mm_store_ss( (float*)&pDestination[2], T );
3973
3974 #else // _XM_VMX128_INTRINSICS_
3975 #endif // _XM_VMX128_INTRINSICS_
3976 }
3977
3978 //------------------------------------------------------------------------------
3979
3980 XMFINLINE VOID XMStoreFloat3
3981 (
3982     XMFLOAT3* pDestination, 
3983     FXMVECTOR V
3984 )
3985 {
3986 #if defined(_XM_NO_INTRINSICS_)
3987
3988     XMASSERT(pDestination);
3989     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3990
3991     pDestination->x = V.vector4_f32[0];
3992     pDestination->y = V.vector4_f32[1];
3993     pDestination->z = V.vector4_f32[2];
3994
3995 #elif defined(_XM_SSE_INTRINSICS_)
3996
3997     XMASSERT(pDestination);
3998     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
3999
4000     XMVECTOR T1 = _mm_shuffle_ps(V,V,_MM_SHUFFLE(1,1,1,1));
4001     XMVECTOR T2 = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,2,2,2));
4002     _mm_store_ss( &pDestination->x, V );
4003     _mm_store_ss( &pDestination->y, T1 );
4004     _mm_store_ss( &pDestination->z, T2 );
4005
4006 #else // _XM_VMX128_INTRINSICS_
4007 #endif // _XM_VMX128_INTRINSICS_
4008 }
4009
4010 //------------------------------------------------------------------------------
4011
4012 XMFINLINE VOID XMStoreFloat3A
4013 (
4014     XMFLOAT3A*   pDestination, 
4015     FXMVECTOR     V
4016 )
4017 {
4018 #if defined(_XM_NO_INTRINSICS_)
4019
4020     XMASSERT(pDestination);
4021     XMASSERT(((UINT_PTR)pDestination & 0xF) == 0);
4022
4023     pDestination->x = V.vector4_f32[0];
4024     pDestination->y = V.vector4_f32[1];
4025     pDestination->z = V.vector4_f32[2];
4026
4027 #elif defined(_XM_SSE_INTRINSICS_)
4028
4029     XMASSERT(pDestination);
4030     XMASSERT(((UINT_PTR)pDestination & 0xF) == 0);
4031
4032     XMVECTOR T = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,2,2,2));
4033     _mm_storel_epi64( (__m128i*)pDestination, reinterpret_cast<const __m128i *>(&V)[0] );
4034     _mm_store_ss( &pDestination->z, T );
4035
4036 #else // _XM_VMX128_INTRINSICS_
4037 #endif // _XM_VMX128_INTRINSICS_
4038 }
4039
4040 //------------------------------------------------------------------------------
4041
4042 XMFINLINE VOID XMStoreUHenDN3
4043 (
4044     XMUHENDN3* pDestination, 
4045     FXMVECTOR   V
4046 )
4047 {
4048 #if defined(_XM_NO_INTRINSICS_)
4049
4050     XMVECTOR               N;
4051     static CONST XMVECTORF32  Scale = {2047.0f, 2047.0f, 1023.0f, 0.0f};
4052
4053     XMASSERT(pDestination);
4054
4055     N = XMVectorSaturate(V);
4056     N = XMVectorMultiply(N, Scale.v);
4057
4058     pDestination->v = (((UINT)N.vector4_f32[2] & 0x3FF) << 22) |
4059                       (((UINT)N.vector4_f32[1] & 0x7FF) << 11) |
4060                       (((UINT)N.vector4_f32[0] & 0x7FF));
4061
4062 #elif defined(_XM_SSE_INTRINSICS_)
4063     XMASSERT(pDestination);
4064     static const XMVECTORF32 ScaleUHenDN3 = {2047.0f, 2047.0f*2048.0f,1023.0f*(2048.0f*2048.0f)/2.0f,1.0f};
4065     static const XMVECTORI32 MaskUHenDN3 = {0x7FF,0x7FF<<11,0x3FF<<(22-1),0};
4066     // Clamp to bounds
4067     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
4068     vResult = _mm_min_ps(vResult,g_XMOne);
4069     // Scale by multiplication
4070     vResult = _mm_mul_ps(vResult,ScaleUHenDN3);
4071     // Convert to int
4072     __m128i vResulti = _mm_cvttps_epi32(vResult);
4073     // Mask off any fraction
4074     vResulti = _mm_and_si128(vResulti,MaskUHenDN3);
4075     // Do a horizontal or of 3 entries
4076     __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(0,3,2,1));
4077     // i = x|y
4078     vResulti = _mm_or_si128(vResulti,vResulti2);
4079     // Move Z to the x position
4080     vResulti2 = _mm_shuffle_epi32(vResulti2,_MM_SHUFFLE(0,3,2,1));
4081     // Add Z to itself to perform a single bit left shift
4082     vResulti2 = _mm_add_epi32(vResulti2,vResulti2);
4083     // i = x|y|z
4084     vResulti = _mm_or_si128(vResulti,vResulti2);
4085     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
4086 #else // _XM_VMX128_INTRINSICS_
4087 #endif // _XM_VMX128_INTRINSICS_
4088 }
4089
4090 //------------------------------------------------------------------------------
4091
4092 XMFINLINE VOID XMStoreUHenD3
4093 (
4094     XMUHEND3* pDestination, 
4095     FXMVECTOR  V
4096 )
4097 {
4098 #if defined(_XM_NO_INTRINSICS_)
4099
4100     XMVECTOR               N;
4101     static CONST XMVECTOR  Max = {2047.0f, 2047.0f, 1023.0f, 0.0f};
4102
4103     XMASSERT(pDestination);
4104
4105     N = XMVectorClamp(V, XMVectorZero(), Max);
4106
4107     pDestination->v = (((UINT)N.vector4_f32[2] & 0x3FF) << 22) |
4108                       (((UINT)N.vector4_f32[1] & 0x7FF) << 11) |
4109                       (((UINT)N.vector4_f32[0] & 0x7FF));
4110
4111 #elif defined(_XM_SSE_INTRINSICS_)
4112     XMASSERT(pDestination);
4113     static const XMVECTORF32 MaxUHenD3 = { 2047.0f, 2047.0f, 1023.0f, 1.0f};
4114     static const XMVECTORF32 ScaleUHenD3 = {1.0f, 2048.0f,(2048.0f*2048.0f)/2.0f,1.0f};
4115     static const XMVECTORI32 MaskUHenD3 = {0x7FF,0x7FF<<11,0x3FF<<(22-1),0};
4116     // Clamp to bounds
4117     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
4118     vResult = _mm_min_ps(vResult,MaxUHenD3);
4119     // Scale by multiplication
4120     vResult = _mm_mul_ps(vResult,ScaleUHenD3);
4121     // Convert to int
4122     __m128i vResulti = _mm_cvttps_epi32(vResult);
4123     // Mask off any fraction
4124     vResulti = _mm_and_si128(vResulti,MaskUHenD3);
4125     // Do a horizontal or of 3 entries
4126     __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(0,3,2,1));
4127     // i = x|y
4128     vResulti = _mm_or_si128(vResulti,vResulti2);
4129     // Move Z to the x position
4130     vResulti2 = _mm_shuffle_epi32(vResulti2,_MM_SHUFFLE(0,3,2,1));
4131     // Add Z to itself to perform a single bit left shift
4132     vResulti2 = _mm_add_epi32(vResulti2,vResulti2);
4133     // i = x|y|z
4134     vResulti = _mm_or_si128(vResulti,vResulti2);
4135     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
4136 #else // _XM_VMX128_INTRINSICS_
4137 #endif // _XM_VMX128_INTRINSICS_
4138 }
4139
4140 //------------------------------------------------------------------------------
4141
4142 XMFINLINE VOID XMStoreHenDN3
4143 (
4144     XMHENDN3* pDestination, 
4145     FXMVECTOR V
4146 )
4147 {
4148 #if defined(_XM_NO_INTRINSICS_)
4149
4150     XMVECTOR               N;
4151     static CONST XMVECTORF32  Scale = {1023.0f, 1023.0f, 511.0f, 1.0f};
4152
4153     XMASSERT(pDestination);
4154
4155     N = XMVectorClamp(V, g_XMNegativeOne.v, g_XMOne.v);
4156     N = XMVectorMultiply(N, Scale.v);
4157
4158     pDestination->v = (((INT)N.vector4_f32[2] & 0x3FF) << 22) |
4159                       (((INT)N.vector4_f32[1] & 0x7FF) << 11) |
4160                       (((INT)N.vector4_f32[0] & 0x7FF));
4161
4162 #elif defined(_XM_SSE_INTRINSICS_)
4163     XMASSERT(pDestination);
4164     static const XMVECTORF32 ScaleHenDN3 = {1023.0f, 1023.0f*2048.0f,511.0f*(2048.0f*2048.0f),1.0f};
4165     // Clamp to bounds
4166     XMVECTOR vResult = _mm_max_ps(V,g_XMNegativeOne);
4167     vResult = _mm_min_ps(vResult,g_XMOne);
4168     // Scale by multiplication
4169     vResult = _mm_mul_ps(vResult,ScaleHenDN3);
4170     // Convert to int
4171     __m128i vResulti = _mm_cvttps_epi32(vResult);
4172     // Mask off any fraction
4173     vResulti = _mm_and_si128(vResulti,g_XMMaskHenD3);
4174     // Do a horizontal or of all 4 entries
4175     vResult = _mm_shuffle_ps(reinterpret_cast<const __m128 *>(&vResulti)[0],reinterpret_cast<const __m128 *>(&vResulti)[0],_MM_SHUFFLE(0,3,2,1));
4176     vResulti = _mm_or_si128(vResulti,reinterpret_cast<const __m128i *>(&vResult)[0]);
4177     vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1));
4178     vResulti = _mm_or_si128(vResulti,reinterpret_cast<const __m128i *>(&vResult)[0]);
4179     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
4180 #else // _XM_VMX128_INTRINSICS_
4181 #endif // _XM_VMX128_INTRINSICS_
4182 }
4183
4184 //------------------------------------------------------------------------------
4185
4186 XMFINLINE VOID XMStoreHenD3
4187 (
4188     XMHEND3* pDestination, 
4189     FXMVECTOR V
4190 )
4191 {
4192 #if defined(_XM_NO_INTRINSICS_)
4193
4194     XMVECTOR               N;
4195     static CONST XMVECTOR  Min = {-1023.0f, -1023.0f, -511.0f, -1.0f};
4196     static CONST XMVECTOR  Max = {1023.0f, 1023.0f, 511.0f, 1.0f};
4197
4198     XMASSERT(pDestination);
4199
4200     N = XMVectorClamp(V, Min, Max);
4201
4202     pDestination->v = (((INT)N.vector4_f32[2] & 0x3FF) << 22) |
4203                       (((INT)N.vector4_f32[1] & 0x7FF) << 11) |
4204                       (((INT)N.vector4_f32[0] & 0x7FF));
4205
4206 #elif defined(_XM_SSE_INTRINSICS_)
4207     XMASSERT(pDestination);
4208     static const XMVECTORF32 MinHenD3 = {-1023.0f,-1023.0f,-511.0f,-1.0f};
4209     static const XMVECTORF32 MaxHenD3 = { 1023.0f, 1023.0f, 511.0f, 1.0f};
4210     static const XMVECTORF32 ScaleHenD3 = {1.0f, 2048.0f,(2048.0f*2048.0f),1.0f};
4211     // Clamp to bounds
4212     XMVECTOR vResult = _mm_max_ps(V,MinHenD3);
4213     vResult = _mm_min_ps(vResult,MaxHenD3);
4214     // Scale by multiplication
4215     vResult = _mm_mul_ps(vResult,ScaleHenD3);
4216     // Convert to int
4217     __m128i vResulti = _mm_cvttps_epi32(vResult);
4218     // Mask off any fraction
4219     vResulti = _mm_and_si128(vResulti,g_XMMaskHenD3);
4220     // Do a horizontal or of all 4 entries
4221     vResult = _mm_shuffle_ps(reinterpret_cast<const __m128 *>(&vResulti)[0],reinterpret_cast<const __m128 *>(&vResulti)[0],_MM_SHUFFLE(0,3,2,1));
4222     vResulti = _mm_or_si128(vResulti,reinterpret_cast<const __m128i *>(&vResult)[0]);
4223     vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1));
4224     vResulti = _mm_or_si128(vResulti,reinterpret_cast<const __m128i *>(&vResult)[0]);
4225     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
4226 #else // _XM_VMX128_INTRINSICS_
4227 #endif // _XM_VMX128_INTRINSICS_
4228 }
4229
4230 //------------------------------------------------------------------------------
4231
4232 XMFINLINE VOID XMStoreUDHenN3
4233 (
4234     XMUDHENN3* pDestination, 
4235     FXMVECTOR   V
4236 )
4237 {
4238 #if defined(_XM_NO_INTRINSICS_)
4239
4240     XMVECTOR               N;
4241     static CONST XMVECTORF32  Scale = {1023.0f, 2047.0f, 2047.0f, 0.0f};
4242
4243     XMASSERT(pDestination);
4244
4245     N = XMVectorSaturate(V);
4246     N = XMVectorMultiply(N, Scale.v);
4247
4248     pDestination->v = (((UINT)N.vector4_f32[2] & 0x7FF) << 21) |
4249                       (((UINT)N.vector4_f32[1] & 0x7FF) << 10) |
4250                       (((UINT)N.vector4_f32[0] & 0x3FF));
4251
4252 #elif defined(_XM_SSE_INTRINSICS_)
4253     XMASSERT(pDestination);
4254     static const XMVECTORF32 ScaleUDHenN3 = {1023.0f,2047.0f*1024.0f,2047.0f*(1024.0f*2048.0f)/2.0f,1.0f};
4255     static const XMVECTORI32 MaskUDHenN3 = {0x3FF,0x7FF<<10,0x7FF<<(21-1),0};
4256     // Clamp to bounds
4257     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
4258     vResult = _mm_min_ps(vResult,g_XMOne);
4259     // Scale by multiplication
4260     vResult = _mm_mul_ps(vResult,ScaleUDHenN3);
4261     // Convert to int
4262     __m128i vResulti = _mm_cvttps_epi32(vResult);
4263     // Mask off any fraction
4264     vResulti = _mm_and_si128(vResulti,MaskUDHenN3);
4265     // Do a horizontal or of 3 entries
4266     __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(0,3,2,1));
4267     // i = x|y
4268     vResulti = _mm_or_si128(vResulti,vResulti2);
4269     // Move Z to the x position
4270     vResulti2 = _mm_shuffle_epi32(vResulti2,_MM_SHUFFLE(0,3,2,1));
4271     // Add Z to itself to perform a single bit left shift
4272     vResulti2 = _mm_add_epi32(vResulti2,vResulti2);
4273     // i = x|y|z
4274     vResulti = _mm_or_si128(vResulti,vResulti2);
4275     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
4276 #else // _XM_VMX128_INTRINSICS_
4277 #endif // _XM_VMX128_INTRINSICS_
4278 }
4279
4280 //------------------------------------------------------------------------------
4281
4282 XMFINLINE VOID XMStoreUDHen3
4283 (
4284     XMUDHEN3* pDestination, 
4285     FXMVECTOR  V
4286 )
4287 {
4288 #if defined(_XM_NO_INTRINSICS_)
4289
4290     XMVECTOR               N;
4291     static CONST XMVECTOR  Max = {1023.0f, 2047.0f, 2047.0f, 0.0f};
4292
4293     XMASSERT(pDestination);
4294
4295     N = XMVectorClamp(V, XMVectorZero(), Max);
4296
4297     pDestination->v = (((UINT)N.vector4_f32[2] & 0x7FF) << 21) |
4298                       (((UINT)N.vector4_f32[1] & 0x7FF) << 10) |
4299                       (((UINT)N.vector4_f32[0] & 0x3FF));
4300
4301 #elif defined(_XM_SSE_INTRINSICS_)
4302     XMASSERT(pDestination);
4303     static const XMVECTORF32 MaxUDHen3 = { 1023.0f, 2047.0f, 2047.0f, 1.0f};
4304     static const XMVECTORF32 ScaleUDHen3 = {1.0f, 1024.0f,(1024.0f*2048.0f)/2.0f,1.0f};
4305     static const XMVECTORI32 MaskUDHen3 = {0x3FF,0x7FF<<10,0x7FF<<(21-1),0};
4306     // Clamp to bounds
4307     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
4308     vResult = _mm_min_ps(vResult,MaxUDHen3);
4309     // Scale by multiplication
4310     vResult = _mm_mul_ps(vResult,ScaleUDHen3);
4311     // Convert to int
4312     __m128i vResulti = _mm_cvttps_epi32(vResult);
4313     // Mask off any fraction
4314     vResulti = _mm_and_si128(vResulti,MaskUDHen3);
4315     // Do a horizontal or of 3 entries
4316     __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(0,3,2,1));
4317     // i = x|y
4318     vResulti = _mm_or_si128(vResulti,vResulti2);
4319     // Move Z to the x position
4320     vResulti2 = _mm_shuffle_epi32(vResulti2,_MM_SHUFFLE(0,3,2,1));
4321     // Add Z to itself to perform a single bit left shift
4322     vResulti2 = _mm_add_epi32(vResulti2,vResulti2);
4323     // i = x|y|z
4324     vResulti = _mm_or_si128(vResulti,vResulti2);
4325     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
4326 #else // _XM_VMX128_INTRINSICS_
4327 #endif // _XM_VMX128_INTRINSICS_
4328 }
4329
4330 //------------------------------------------------------------------------------
4331
4332 XMFINLINE VOID XMStoreDHenN3
4333 (
4334     XMDHENN3* pDestination, 
4335     FXMVECTOR V
4336 )
4337 {
4338 #if defined(_XM_NO_INTRINSICS_)
4339
4340     XMVECTOR               N;
4341     static CONST XMVECTORF32  Scale = {511.0f, 1023.0f, 1023.0f, 1.0f};
4342
4343     XMASSERT(pDestination);
4344
4345     N = XMVectorClamp(V, g_XMNegativeOne.v, g_XMOne.v);
4346     N = XMVectorMultiply(N, Scale.v);
4347
4348     pDestination->v = (((INT)N.vector4_f32[2] & 0x7FF) << 21) |
4349                       (((INT)N.vector4_f32[1] & 0x7FF) << 10) |
4350                       (((INT)N.vector4_f32[0] & 0x3FF));
4351
4352 #elif defined(_XM_SSE_INTRINSICS_)
4353     XMASSERT(pDestination);
4354     static const XMVECTORF32 ScaleDHenN3 = {511.0f, 1023.0f*1024.0f,1023.0f*(1024.0f*2048.0f),1.0f};
4355     // Clamp to bounds
4356     XMVECTOR vResult = _mm_max_ps(V,g_XMNegativeOne);
4357     vResult = _mm_min_ps(vResult,g_XMOne);
4358     // Scale by multiplication
4359     vResult = _mm_mul_ps(vResult,ScaleDHenN3);
4360     // Convert to int
4361     __m128i vResulti = _mm_cvttps_epi32(vResult);
4362     // Mask off any fraction
4363     vResulti = _mm_and_si128(vResulti,g_XMMaskDHen3);
4364     // Do a horizontal or of all 4 entries
4365     vResult = _mm_shuffle_ps(reinterpret_cast<const __m128 *>(&vResulti)[0],reinterpret_cast<const __m128 *>(&vResulti)[0],_MM_SHUFFLE(0,3,2,1));
4366     vResulti = _mm_or_si128(vResulti,reinterpret_cast<const __m128i *>(&vResult)[0]);
4367     vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1));
4368     vResulti = _mm_or_si128(vResulti,reinterpret_cast<const __m128i *>(&vResult)[0]);
4369     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
4370 #else // _XM_VMX128_INTRINSICS_
4371 #endif // _XM_VMX128_INTRINSICS_
4372 }
4373
4374 //------------------------------------------------------------------------------
4375
4376 XMFINLINE VOID XMStoreDHen3
4377 (
4378     XMDHEN3* pDestination, 
4379     FXMVECTOR V
4380 )
4381 {
4382 #if defined(_XM_NO_INTRINSICS_)
4383
4384     XMVECTOR               N;
4385     static CONST XMVECTOR  Min = {-511.0f, -1023.0f, -1023.0f, -1.0f};
4386     static CONST XMVECTOR  Max = {511.0f, 1023.0f, 1023.0f, 1.0f};
4387
4388     XMASSERT(pDestination);
4389
4390     N = XMVectorClamp(V, Min, Max);
4391
4392     pDestination->v = (((INT)N.vector4_f32[2] & 0x7FF) << 21) |
4393                       (((INT)N.vector4_f32[1] & 0x7FF) << 10) |
4394                       (((INT)N.vector4_f32[0] & 0x3FF));
4395
4396 #elif defined(_XM_SSE_INTRINSICS_)
4397     XMASSERT(pDestination);
4398     static const XMVECTORF32 MinDHen3 = {-511.0f,-1023.0f,-1023.0f,-1.0f};
4399     static const XMVECTORF32 MaxDHen3 = { 511.0f, 1023.0f, 1023.0f, 1.0f};
4400     static const XMVECTORF32 ScaleDHen3 = {1.0f, 1024.0f,(1024.0f*2048.0f),1.0f};
4401     // Clamp to bounds
4402     XMVECTOR vResult = _mm_max_ps(V,MinDHen3);
4403     vResult = _mm_min_ps(vResult,MaxDHen3);
4404     // Scale by multiplication
4405     vResult = _mm_mul_ps(vResult,ScaleDHen3);
4406     // Convert to int
4407     __m128i vResulti = _mm_cvttps_epi32(vResult);
4408     // Mask off any fraction
4409     vResulti = _mm_and_si128(vResulti,g_XMMaskDHen3);
4410     // Do a horizontal or of all 4 entries
4411     vResult = _mm_shuffle_ps(reinterpret_cast<const __m128 *>(&vResulti)[0],reinterpret_cast<const __m128 *>(&vResulti)[0],_MM_SHUFFLE(0,3,2,1));
4412     vResulti = _mm_or_si128(vResulti,reinterpret_cast<const __m128i *>(&vResult)[0]);
4413     vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1));
4414     vResulti = _mm_or_si128(vResulti,reinterpret_cast<const __m128i *>(&vResult)[0]);
4415     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
4416 #else // _XM_VMX128_INTRINSICS_
4417 #endif // _XM_VMX128_INTRINSICS_
4418 }
4419
4420 //------------------------------------------------------------------------------
4421
4422 XMFINLINE VOID XMStoreU565
4423 (
4424     XMU565* pDestination,
4425     FXMVECTOR V
4426 )
4427 {
4428 #if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
4429     XMASSERT(pDestination);
4430     static CONST XMVECTORF32  Max = {31.0f, 63.0f, 31.0f, 0.0f};
4431     // Bounds check
4432     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
4433     vResult = _mm_min_ps(vResult,Max);
4434      // Convert to int with rounding
4435     __m128i vInt = _mm_cvtps_epi32(vResult);
4436     // No SSE operations will write to 16-bit values, so we have to extract them manually
4437     USHORT x = static_cast<USHORT>(_mm_extract_epi16(vInt,0));
4438     USHORT y = static_cast<USHORT>(_mm_extract_epi16(vInt,2));
4439     USHORT z = static_cast<USHORT>(_mm_extract_epi16(vInt,4));
4440     pDestination->v = ((z & 0x1F) << 11) |
4441                       ((y & 0x3F) << 5) |
4442                       ((x & 0x1F));
4443 #else
4444     XMVECTOR               N;
4445     static CONST XMVECTORF32  Max = {31.0f, 63.0f, 31.0f, 0.0f};
4446
4447     XMASSERT(pDestination);
4448
4449     N = XMVectorClamp(V, XMVectorZero(), Max.v);
4450     N = XMVectorRound(N);
4451
4452     pDestination->v = (((USHORT)N.vector4_f32[2] & 0x1F) << 11) |
4453                       (((USHORT)N.vector4_f32[1] & 0x3F) << 5) |
4454                       (((USHORT)N.vector4_f32[0] & 0x1F));
4455 #endif !_XM_SSE_INTRINSICS_
4456 }
4457
4458 //------------------------------------------------------------------------------
4459
4460 XMFINLINE VOID XMStoreFloat3PK
4461 (
4462     XMFLOAT3PK* pDestination,
4463     FXMVECTOR V
4464 )
4465 {
4466     _DECLSPEC_ALIGN_16_ UINT IValue[4];
4467     UINT I, Sign, j;
4468     UINT Result[3];
4469
4470     XMASSERT(pDestination);
4471
4472     XMStoreFloat3A( (XMFLOAT3A*)&IValue, V );
4473
4474     // X & Y Channels (5-bit exponent, 6-bit mantissa)
4475     for(j=0; j < 2; ++j)
4476     {
4477         Sign = IValue[j] & 0x80000000;
4478         I = IValue[j] & 0x7FFFFFFF;
4479
4480         if ((I & 0x7F800000) == 0x7F800000)
4481         {
4482             // INF or NAN
4483             Result[j] = 0x7c0;
4484             if (( I & 0x7FFFFF ) != 0)
4485             {
4486                 Result[j] = 0x7c0 | (((I>>17)|(I>11)|(I>>6)|(I))&0x3f);
4487             }
4488             else if ( Sign )
4489             {
4490                 // -INF is clamped to 0 since 3PK is positive only
4491                 Result[j] = 0;
4492             }
4493         }
4494         else if ( Sign )
4495         {
4496             // 3PK is positive only, so clamp to zero
4497             Result[j] = 0;
4498         }
4499         else if (I > 0x477E0000U)
4500         {
4501             // The number is too large to be represented as a float11, set to max
4502             Result[j] = 0x7BF;
4503         }
4504         else
4505         {
4506             if (I < 0x38800000U)
4507             {
4508                 // The number is too small to be represented as a normalized float11
4509                 // Convert it to a denormalized value.
4510                 UINT Shift = 113U - (I >> 23U);
4511                 I = (0x800000U | (I & 0x7FFFFFU)) >> Shift;
4512             }
4513             else
4514             {
4515                 // Rebias the exponent to represent the value as a normalized float11
4516                 I += 0xC8000000U;
4517             }
4518      
4519             Result[j] = ((I + 0xFFFFU + ((I >> 17U) & 1U)) >> 17U)&0x7ffU;
4520         }
4521     }
4522
4523     // Z Channel (5-bit exponent, 5-bit mantissa)
4524     Sign = IValue[2] & 0x80000000;
4525     I = IValue[2] & 0x7FFFFFFF;
4526
4527     if ((I & 0x7F800000) == 0x7F800000)
4528     {
4529         // INF or NAN
4530         Result[2] = 0x3e0;
4531         if ( I & 0x7FFFFF )
4532         {
4533             Result[2] = 0x3e0 | (((I>>18)|(I>13)|(I>>3)|(I))&0x1f);
4534         }
4535         else if ( Sign )
4536         {
4537             // -INF is clamped to 0 since 3PK is positive only
4538             Result[2] = 0;
4539         }
4540     }
4541     else if ( Sign )
4542     {
4543         // 3PK is positive only, so clamp to zero
4544         Result[2] = 0;
4545     }
4546     else if (I > 0x477C0000U)
4547     {
4548         // The number is too large to be represented as a float10, set to max
4549         Result[2] = 0x3df;
4550     }
4551     else
4552     {
4553         if (I < 0x38800000U)
4554         {
4555             // The number is too small to be represented as a normalized float10
4556             // Convert it to a denormalized value.
4557             UINT Shift = 113U - (I >> 23U);
4558             I = (0x800000U | (I & 0x7FFFFFU)) >> Shift;
4559         }
4560         else
4561         {
4562             // Rebias the exponent to represent the value as a normalized float10
4563             I += 0xC8000000U;
4564         }
4565      
4566         Result[2] = ((I + 0x1FFFFU + ((I >> 18U) & 1U)) >> 18U)&0x3ffU;
4567     }
4568
4569     // Pack Result into memory
4570     pDestination->v = (Result[0] & 0x7ff)
4571                       | ( (Result[1] & 0x7ff) << 11 )
4572                       | ( (Result[2] & 0x3ff) << 22 );
4573 }
4574
4575
4576 //------------------------------------------------------------------------------
4577
4578 XMFINLINE VOID XMStoreFloat3SE
4579 (
4580     XMFLOAT3SE* pDestination,
4581     FXMVECTOR V
4582 )
4583 {
4584     _DECLSPEC_ALIGN_16_ UINT IValue[4];
4585     UINT I, Sign, j, T;
4586     UINT Frac[3];
4587     UINT Exp[3];
4588     
4589
4590     XMASSERT(pDestination);
4591
4592     XMStoreFloat3A( (XMFLOAT3A*)&IValue, V );
4593
4594     // X, Y, Z Channels (5-bit exponent, 9-bit mantissa)
4595     for(j=0; j < 3; ++j)
4596     {
4597         Sign = IValue[j] & 0x80000000;
4598         I = IValue[j] & 0x7FFFFFFF;
4599
4600         if ((I & 0x7F800000) == 0x7F800000)
4601         {
4602             // INF or NAN
4603             Exp[j] = 0x1f;
4604             if (( I & 0x7FFFFF ) != 0)
4605             {
4606                 Frac[j] = ((I>>14)|(I>5)|(I))&0x1ff;
4607             }
4608             else if ( Sign )
4609             {
4610                 // -INF is clamped to 0 since 3SE is positive only
4611                 Exp[j] = Frac[j] = 0;
4612             }
4613         }
4614         else if ( Sign )
4615         {
4616             // 3SE is positive only, so clamp to zero
4617             Exp[j] = Frac[j] = 0;
4618         }
4619         else if (I > 0x477FC000U)
4620         {
4621             // The number is too large, set to max
4622             Exp[j] = 0x1e;
4623             Frac[j] = 0x1ff;
4624         }
4625         else
4626         {
4627             if (I < 0x38800000U)
4628             {
4629                 // The number is too small to be represented as a normalized float11
4630                 // Convert it to a denormalized value.
4631                 UINT Shift = 113U - (I >> 23U);
4632                 I = (0x800000U | (I & 0x7FFFFFU)) >> Shift;
4633             }
4634             else
4635             {
4636                 // Rebias the exponent to represent the value as a normalized float11
4637                 I += 0xC8000000U;
4638             }
4639      
4640             T = ((I + 0x1FFFU + ((I >> 14U) & 1U)) >> 14U)&0x3fffU;
4641
4642             Exp[j] = (T & 0x3E00) >> 9;
4643             Frac[j] = T & 0x1ff;
4644         }
4645     }
4646
4647     // Adjust to a shared exponent
4648     T = XMMax( Exp[0], XMMax( Exp[1], Exp[2] ) );
4649
4650     Frac[0] = Frac[0] >> (T - Exp[0]);
4651     Frac[1] = Frac[1] >> (T - Exp[1]);
4652     Frac[2] = Frac[2] >> (T - Exp[2]);
4653
4654     // Store packed into memory
4655     pDestination->xm = Frac[0];
4656     pDestination->ym = Frac[1];
4657     pDestination->zm = Frac[2];
4658     pDestination->e = T;
4659 }
4660
4661 //------------------------------------------------------------------------------
4662
4663 XMFINLINE VOID XMStoreInt4
4664 (
4665     UINT*    pDestination, 
4666     FXMVECTOR V
4667 )
4668 {
4669 #if defined(_XM_NO_INTRINSICS_)
4670
4671     XMASSERT(pDestination);
4672
4673     pDestination[0] = V.vector4_u32[0];
4674     pDestination[1] = V.vector4_u32[1];
4675     pDestination[2] = V.vector4_u32[2];
4676     pDestination[3] = V.vector4_u32[3];
4677
4678 #elif defined(_XM_SSE_INTRINSICS_)
4679     XMASSERT(pDestination);
4680     
4681     _mm_storeu_si128( (__m128i*)pDestination, reinterpret_cast<const __m128i *>(&V)[0] );
4682
4683 #else // _XM_VMX128_INTRINSICS_
4684 #endif // _XM_VMX128_INTRINSICS_
4685 }
4686
4687 //------------------------------------------------------------------------------
4688
4689 XMFINLINE VOID XMStoreInt4A
4690 (
4691     UINT*    pDestination, 
4692     FXMVECTOR V
4693 )
4694 {
4695 #if defined(_XM_NO_INTRINSICS_)
4696
4697     XMASSERT(pDestination);
4698     XMASSERT(((UINT_PTR)pDestination & 0xF) == 0);
4699
4700     pDestination[0] = V.vector4_u32[0];
4701     pDestination[1] = V.vector4_u32[1];
4702     pDestination[2] = V.vector4_u32[2];
4703     pDestination[3] = V.vector4_u32[3];
4704
4705 #elif defined(_XM_SSE_INTRINSICS_)
4706     XMASSERT(pDestination);
4707     XMASSERT(((UINT_PTR)pDestination & 0xF) == 0);
4708
4709     _mm_store_si128( (__m128i*)pDestination, reinterpret_cast<const __m128i *>(&V)[0] );
4710
4711 #else // _XM_VMX128_INTRINSICS_
4712 #endif // _XM_VMX128_INTRINSICS_
4713 }
4714
4715 //------------------------------------------------------------------------------
4716
4717 XMFINLINE VOID XMStoreSInt4
4718 (
4719     XMINT4* pDestination,
4720     FXMVECTOR V
4721 )
4722 {
4723 #if defined(_XM_NO_INTRINSICS_)
4724
4725     XMASSERT(pDestination);
4726
4727     pDestination->x = (INT)V.vector4_f32[0];
4728     pDestination->y = (INT)V.vector4_f32[1];
4729     pDestination->z = (INT)V.vector4_f32[2];
4730     pDestination->w = (INT)V.vector4_f32[3];
4731
4732 #elif defined(_XM_SSE_INTRINSICS_)
4733     XMASSERT(pDestination);
4734     
4735     // In case of positive overflow, detect it
4736     XMVECTOR vOverflow = _mm_cmpgt_ps(V,g_XMMaxInt);
4737     // Float to int conversion
4738     __m128i vResulti = _mm_cvttps_epi32(V);
4739     // If there was positive overflow, set to 0x7FFFFFFF
4740     XMVECTOR vResult = _mm_and_ps(vOverflow,g_XMAbsMask);
4741     vOverflow = _mm_andnot_ps(vOverflow,reinterpret_cast<const __m128 *>(&vResulti)[0]);
4742     vOverflow = _mm_or_ps(vOverflow,vResult);
4743     _mm_storeu_si128( (__m128i*)pDestination, reinterpret_cast<const __m128i *>(&vOverflow)[0] );
4744
4745 #else // _XM_VMX128_INTRINSICS_
4746 #endif // _XM_VMX128_INTRINSICS_
4747 }
4748
4749 //------------------------------------------------------------------------------
4750
4751 XMFINLINE VOID XMStoreUInt4
4752 (
4753     XMUINT4* pDestination,
4754     FXMVECTOR V
4755 )
4756 {
4757 #if defined(_XM_NO_INTRINSICS_)
4758
4759     XMASSERT(pDestination);
4760
4761     pDestination->x = (UINT)V.vector4_f32[0];
4762     pDestination->y = (UINT)V.vector4_f32[1];
4763     pDestination->z = (UINT)V.vector4_f32[2];
4764     pDestination->w = (UINT)V.vector4_f32[3];
4765
4766 #elif defined(_XM_SSE_INTRINSICS_)
4767     XMASSERT(pDestination);
4768
4769     // Clamp to >=0
4770     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
4771     // Any numbers that are too big, set to 0xFFFFFFFFU
4772     XMVECTOR vOverflow = _mm_cmpgt_ps(vResult,g_XMMaxUInt);
4773     XMVECTOR vValue = g_XMUnsignedFix;
4774     // Too large for a signed integer?
4775     XMVECTOR vMask = _mm_cmpge_ps(vResult,vValue);
4776     // Zero for number's lower than 0x80000000, 32768.0f*65536.0f otherwise
4777     vValue = _mm_and_ps(vValue,vMask);
4778     // Perform fixup only on numbers too large (Keeps low bit precision)
4779     vResult = _mm_sub_ps(vResult,vValue);
4780     __m128i vResulti = _mm_cvttps_epi32(vResult);
4781     // Convert from signed to unsigned pnly if greater than 0x80000000
4782     vMask = _mm_and_ps(vMask,g_XMNegativeZero);
4783     vResult = _mm_xor_ps(reinterpret_cast<const __m128 *>(&vResulti)[0],vMask);
4784     // On those that are too large, set to 0xFFFFFFFF
4785     vResult = _mm_or_ps(vResult,vOverflow);
4786     _mm_storeu_si128( (__m128i*)pDestination, reinterpret_cast<const __m128i *>(&vResult)[0] );
4787
4788 #else // _XM_VMX128_INTRINSICS_
4789 #endif // _XM_VMX128_INTRINSICS_
4790 }
4791
4792 //------------------------------------------------------------------------------
4793
4794 XMFINLINE VOID XMStoreInt4NC
4795 (
4796     UINT*    pDestination, 
4797     FXMVECTOR V
4798 )
4799 {
4800 #if defined(_XM_NO_INTRINSICS_)
4801
4802     XMASSERT(pDestination);
4803     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
4804     
4805     pDestination[0] = V.vector4_u32[0];
4806     pDestination[1] = V.vector4_u32[1];
4807     pDestination[2] = V.vector4_u32[2];
4808     pDestination[3] = V.vector4_u32[3];
4809
4810 #elif defined(_XM_SSE_INTRINSICS_)
4811     XMASSERT(pDestination);
4812     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
4813     
4814     _mm_storeu_si128( (__m128i*)pDestination, reinterpret_cast<const __m128i *>(&V)[0] );
4815
4816 #else // _XM_VMX128_INTRINSICS_
4817 #endif // _XM_VMX128_INTRINSICS_
4818 }
4819
4820 //------------------------------------------------------------------------------
4821
4822 XMFINLINE VOID XMStoreFloat4
4823 (
4824     XMFLOAT4* pDestination, 
4825     FXMVECTOR  V
4826 )
4827 {
4828 #if defined(_XM_NO_INTRINSICS_)
4829
4830     XMASSERT(pDestination);
4831     
4832     pDestination->x = V.vector4_f32[0];
4833     pDestination->y = V.vector4_f32[1];
4834     pDestination->z = V.vector4_f32[2];
4835     pDestination->w = V.vector4_f32[3];
4836
4837 #elif defined(_XM_SSE_INTRINSICS_)
4838     XMASSERT(pDestination);
4839     
4840     _mm_storeu_ps( &pDestination->x, V );
4841
4842 #else // _XM_VMX128_INTRINSICS_
4843 #endif // _XM_VMX128_INTRINSICS_
4844 }
4845
4846 //------------------------------------------------------------------------------
4847
4848 XMFINLINE VOID XMStoreFloat4A
4849 (
4850     XMFLOAT4A*   pDestination, 
4851     FXMVECTOR     V
4852 )
4853 {
4854 #if defined(_XM_NO_INTRINSICS_)
4855
4856     XMASSERT(pDestination);
4857     XMASSERT(((UINT_PTR)pDestination & 0xF) == 0);
4858
4859     pDestination->x = V.vector4_f32[0];
4860     pDestination->y = V.vector4_f32[1];
4861     pDestination->z = V.vector4_f32[2];
4862     pDestination->w = V.vector4_f32[3];
4863
4864 #elif defined(_XM_SSE_INTRINSICS_)
4865     XMASSERT(pDestination);
4866     XMASSERT(((UINT_PTR)pDestination & 0xF) == 0);
4867
4868     _mm_store_ps( &pDestination->x, V );
4869 #else // _XM_VMX128_INTRINSICS_
4870 #endif // _XM_VMX128_INTRINSICS_
4871 }
4872
4873 //------------------------------------------------------------------------------
4874
4875 XMFINLINE VOID XMStoreFloat4NC
4876 (
4877     XMFLOAT4* pDestination, 
4878     FXMVECTOR  V
4879 )
4880 {
4881 #if defined(_XM_NO_INTRINSICS_)
4882
4883     XMASSERT(pDestination);
4884     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
4885     
4886     pDestination->x = V.vector4_f32[0];
4887     pDestination->y = V.vector4_f32[1];
4888     pDestination->z = V.vector4_f32[2];
4889     pDestination->w = V.vector4_f32[3];
4890
4891 #elif defined(_XM_SSE_INTRINSICS_)
4892     XMASSERT(pDestination);
4893     XMASSERT(((UINT_PTR)pDestination & 3) == 0);
4894     
4895     _mm_storeu_ps( &pDestination->x, V );
4896
4897 #else // _XM_VMX128_INTRINSICS_
4898 #endif // _XM_VMX128_INTRINSICS_
4899 }
4900
4901 //------------------------------------------------------------------------------
4902
4903 XMFINLINE VOID XMStoreHalf4
4904 (
4905     XMHALF4* pDestination, 
4906     FXMVECTOR V
4907 )
4908 {
4909 #if defined(_XM_NO_INTRINSICS_) 
4910
4911     XMASSERT(pDestination);
4912
4913     pDestination->x = XMConvertFloatToHalf(V.vector4_f32[0]);
4914     pDestination->y = XMConvertFloatToHalf(V.vector4_f32[1]);
4915     pDestination->z = XMConvertFloatToHalf(V.vector4_f32[2]);
4916     pDestination->w = XMConvertFloatToHalf(V.vector4_f32[3]);
4917
4918 #elif defined(_XM_SSE_INTRINSICS_)
4919     XMASSERT(pDestination);
4920     pDestination->x = XMConvertFloatToHalf(XMVectorGetX(V));
4921     pDestination->y = XMConvertFloatToHalf(XMVectorGetY(V));
4922     pDestination->z = XMConvertFloatToHalf(XMVectorGetZ(V));
4923     pDestination->w = XMConvertFloatToHalf(XMVectorGetW(V));
4924 #else // _XM_VMX128_INTRINSICS_
4925 #endif // _XM_VMX128_INTRINSICS_
4926 }
4927
4928 //------------------------------------------------------------------------------
4929
4930 XMFINLINE VOID XMStoreShortN4
4931 (
4932     XMSHORTN4* pDestination, 
4933     FXMVECTOR   V
4934 )
4935 {
4936 #if defined(_XM_NO_INTRINSICS_)
4937
4938     XMVECTOR               N;
4939     static CONST XMVECTORF32  Scale = {32767.0f, 32767.0f, 32767.0f, 32767.0f};
4940
4941     XMASSERT(pDestination);
4942
4943     N = XMVectorClamp(V, g_XMNegativeOne.v, g_XMOne.v);
4944     N = XMVectorMultiply(N, Scale.v);
4945     N = XMVectorRound(N);
4946
4947     pDestination->x = (SHORT)N.vector4_f32[0];
4948     pDestination->y = (SHORT)N.vector4_f32[1];
4949     pDestination->z = (SHORT)N.vector4_f32[2];
4950     pDestination->w = (SHORT)N.vector4_f32[3];
4951
4952 #elif defined(_XM_SSE_INTRINSICS_)
4953     XMASSERT(pDestination);
4954     static CONST XMVECTORF32 Scale = {32767.0f, 32767.0f, 32767.0f, 32767.0f};
4955
4956     XMVECTOR vResult = _mm_max_ps(V,g_XMNegativeOne);
4957     vResult = _mm_min_ps(vResult,g_XMOne);
4958     vResult = _mm_mul_ps(vResult,Scale);
4959     __m128i vResulti = _mm_cvtps_epi32(vResult);
4960     vResulti = _mm_packs_epi32(vResulti,vResulti);
4961     _mm_store_sd(reinterpret_cast<double *>(&pDestination->x),reinterpret_cast<const __m128d *>(&vResulti)[0]);
4962 #else // _XM_VMX128_INTRINSICS_
4963 #endif // _XM_VMX128_INTRINSICS_
4964 }
4965
4966 //------------------------------------------------------------------------------
4967
4968 XMFINLINE VOID XMStoreShort4
4969 (
4970     XMSHORT4* pDestination, 
4971     FXMVECTOR  V
4972 )
4973 {
4974 #if defined(_XM_NO_INTRINSICS_)
4975
4976     XMVECTOR               N;
4977     static CONST XMVECTOR  Min = {-32767.0f, -32767.0f, -32767.0f, -32767.0f};
4978     static CONST XMVECTOR  Max = {32767.0f, 32767.0f, 32767.0f, 32767.0f};
4979
4980     XMASSERT(pDestination);
4981
4982     N = XMVectorClamp(V, Min, Max);
4983     N = XMVectorRound(N);
4984
4985     pDestination->x = (SHORT)N.vector4_f32[0];
4986     pDestination->y = (SHORT)N.vector4_f32[1];
4987     pDestination->z = (SHORT)N.vector4_f32[2];
4988     pDestination->w = (SHORT)N.vector4_f32[3];
4989
4990 #elif defined(_XM_SSE_INTRINSICS_)
4991     XMASSERT(pDestination);
4992     static CONST XMVECTORF32 Min = {-32767.0f, -32767.0f, -32767.0f, -32767.0f};
4993     static CONST XMVECTORF32  Max = {32767.0f, 32767.0f, 32767.0f, 32767.0f};
4994     // Bounds check
4995     XMVECTOR vResult = _mm_max_ps(V,Min);
4996     vResult = _mm_min_ps(vResult,Max);
4997      // Convert to int with rounding
4998     __m128i vInt = _mm_cvtps_epi32(vResult);
4999     // Pack the ints into shorts
5000     vInt = _mm_packs_epi32(vInt,vInt);
5001     _mm_store_sd(reinterpret_cast<double *>(&pDestination->x),reinterpret_cast<const __m128d *>(&vInt)[0]);
5002 #else // _XM_VMX128_INTRINSICS_
5003 #endif // _XM_VMX128_INTRINSICS_
5004 }
5005
5006 //------------------------------------------------------------------------------
5007
5008 XMFINLINE VOID XMStoreUShortN4
5009 (
5010     XMUSHORTN4* pDestination, 
5011     FXMVECTOR    V
5012 )
5013 {
5014 #if defined(_XM_NO_INTRINSICS_)
5015
5016     XMVECTOR               N;
5017     static CONST XMVECTORF32  Scale = {65535.0f, 65535.0f, 65535.0f, 65535.0f};
5018
5019     XMASSERT(pDestination);
5020
5021     N = XMVectorSaturate(V);
5022     N = XMVectorMultiplyAdd(N, Scale.v, g_XMOneHalf.v);
5023     N = XMVectorTruncate(N);
5024
5025     pDestination->x = (SHORT)N.vector4_f32[0];
5026     pDestination->y = (SHORT)N.vector4_f32[1];
5027     pDestination->z = (SHORT)N.vector4_f32[2];
5028     pDestination->w = (SHORT)N.vector4_f32[3];
5029
5030 #elif defined(_XM_SSE_INTRINSICS_)
5031     XMASSERT(pDestination);
5032     static CONST XMVECTORF32 Scale = {65535.0f, 65535.0f, 65535.0f, 65535.0f};
5033     // Bounds check
5034     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
5035     vResult = _mm_min_ps(vResult,g_XMOne);
5036     vResult = _mm_mul_ps(vResult,Scale);
5037     // Convert to int with rounding
5038     __m128i vInt = _mm_cvtps_epi32(vResult);
5039     // Since the SSE pack instruction clamps using signed rules,
5040     // manually extract the values to store them to memory
5041     pDestination->x = static_cast<SHORT>(_mm_extract_epi16(vInt,0));
5042     pDestination->y = static_cast<SHORT>(_mm_extract_epi16(vInt,2));
5043     pDestination->z = static_cast<SHORT>(_mm_extract_epi16(vInt,4));
5044     pDestination->w = static_cast<SHORT>(_mm_extract_epi16(vInt,6));
5045 #else // _XM_VMX128_INTRINSICS_
5046 #endif // _XM_VMX128_INTRINSICS_
5047 }
5048
5049 //------------------------------------------------------------------------------
5050
5051 XMFINLINE VOID XMStoreUShort4
5052 (
5053     XMUSHORT4* pDestination, 
5054     FXMVECTOR   V
5055 )
5056 {
5057 #if defined(_XM_NO_INTRINSICS_)
5058
5059     XMVECTOR               N;
5060     static CONST XMVECTOR  Max = {65535.0f, 65535.0f, 65535.0f, 65535.0f};
5061
5062     XMASSERT(pDestination);
5063
5064     N = XMVectorClamp(V, XMVectorZero(), Max);
5065     N = XMVectorRound(N);
5066
5067     pDestination->x = (SHORT)N.vector4_f32[0];
5068     pDestination->y = (SHORT)N.vector4_f32[1];
5069     pDestination->z = (SHORT)N.vector4_f32[2];
5070     pDestination->w = (SHORT)N.vector4_f32[3];
5071
5072 #elif defined(_XM_SSE_INTRINSICS_)
5073     XMASSERT(pDestination);
5074     static CONST XMVECTORF32  Max = {65535.0f, 65535.0f, 65535.0f, 65535.0f};
5075     // Bounds check
5076     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
5077     vResult = _mm_min_ps(vResult,Max);
5078      // Convert to int with rounding
5079     __m128i vInt = _mm_cvtps_epi32(vResult);
5080     // Since the SSE pack instruction clamps using signed rules,
5081     // manually extract the values to store them to memory
5082     pDestination->x = static_cast<SHORT>(_mm_extract_epi16(vInt,0));
5083     pDestination->y = static_cast<SHORT>(_mm_extract_epi16(vInt,2));
5084     pDestination->z = static_cast<SHORT>(_mm_extract_epi16(vInt,4));
5085     pDestination->w = static_cast<SHORT>(_mm_extract_epi16(vInt,6));
5086 #else // _XM_VMX128_INTRINSICS_
5087 #endif // _XM_VMX128_INTRINSICS_
5088 }
5089
5090 //------------------------------------------------------------------------------
5091
5092 XMFINLINE VOID XMStoreXIcoN4
5093 (
5094     XMXICON4*  pDestination, 
5095     FXMVECTOR   V
5096 )
5097 {
5098 #if defined(_XM_NO_INTRINSICS_)
5099
5100     XMVECTOR               N;
5101     static CONST XMVECTORF32  Min = {-1.0f, -1.0f, -1.0f, 0.0f};
5102     static CONST XMVECTORF32  Scale = {524287.0f, 524287.0f, 524287.0f, 15.0f};
5103
5104     XMASSERT(pDestination);
5105
5106     N = XMVectorClamp(V, Min.v, g_XMOne.v);
5107     N = XMVectorMultiply(N, Scale.v);
5108     N = XMVectorRound(N);
5109
5110     pDestination->v = ((UINT64)N.vector4_f32[3] << 60) |
5111                        (((INT64)N.vector4_f32[2] & 0xFFFFF) << 40) |
5112                        (((INT64)N.vector4_f32[1] & 0xFFFFF) << 20) |
5113                        (((INT64)N.vector4_f32[0] & 0xFFFFF));
5114
5115 #elif defined(_XM_SSE_INTRINSICS_)
5116     XMASSERT(pDestination);
5117     // Note: Masks are x,w,y and z
5118     static const XMVECTORF32 MinXIcoN4 = {-1.0f, 0.0f,-1.0f,-1.0f};
5119     static const XMVECTORF32 ScaleXIcoN4 = {524287.0f,15.0f*4096.0f*65536.0f*0.5f,524287.0f*4096.0f,524287.0f};
5120     static const XMVECTORI32 MaskXIcoN4 = {0xFFFFF,0xF<<((60-32)-1),0xFFFFF000,0xFFFFF};
5121
5122     // Clamp to bounds
5123     XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,1,3,0));
5124     vResult = _mm_max_ps(vResult,MinXIcoN4);
5125     vResult = _mm_min_ps(vResult,g_XMOne);
5126     // Scale by multiplication
5127     vResult = _mm_mul_ps(vResult,ScaleXIcoN4);
5128     // Convert to integer (w is unsigned)
5129     __m128i vResulti = _mm_cvttps_epi32(vResult);
5130     // Mask off unused bits
5131     vResulti = _mm_and_si128(vResulti,MaskXIcoN4);
5132     // Isolate Y
5133     __m128i vResulti2 = _mm_and_si128(vResulti,g_XMMaskY);
5134     // Double Y (Really W) to fixup for unsigned conversion
5135     vResulti = _mm_add_epi32(vResulti,vResulti2);
5136     // Shift y and z to straddle the 32-bit boundary
5137     vResulti2 = _mm_srli_si128(vResulti,(64+12)/8);
5138     // Shift it into place
5139     vResulti2 = _mm_slli_si128(vResulti2,20/8);
5140     // i = x|y<<20|z<<40|w<<60
5141     vResulti = _mm_or_si128(vResulti,vResulti2);
5142     _mm_store_sd(reinterpret_cast<double *>(&pDestination->v),reinterpret_cast<const __m128d *>(&vResulti)[0]);
5143 #else // _XM_VMX128_INTRINSICS_
5144 #endif // _XM_VMX128_INTRINSICS_
5145 }
5146
5147 //------------------------------------------------------------------------------
5148
5149 XMFINLINE VOID XMStoreXIco4
5150 (
5151     XMXICO4*  pDestination, 
5152     FXMVECTOR  V
5153 )
5154 {
5155 #if defined(_XM_NO_INTRINSICS_)
5156
5157     XMVECTOR N;
5158     static CONST XMVECTORF32 Min = {-524287.0f, -524287.0f, -524287.0f, 0.0f};
5159     static CONST XMVECTORF32 Max = {524287.0f, 524287.0f, 524287.0f, 15.0f};
5160
5161     XMASSERT(pDestination);
5162     N = XMVectorClamp(V, Min.v, Max.v);
5163     pDestination->v = ((UINT64)N.vector4_f32[3] << 60) |
5164                        (((INT64)N.vector4_f32[2] & 0xFFFFF) << 40) |
5165                        (((INT64)N.vector4_f32[1] & 0xFFFFF) << 20) |
5166                        (((INT64)N.vector4_f32[0] & 0xFFFFF));
5167
5168 #elif defined(_XM_SSE_INTRINSICS_)
5169     XMASSERT(pDestination);
5170     // Note: Masks are x,w,y and z
5171     static const XMVECTORF32 MinXIco4 = {-524287.0f, 0.0f,-524287.0f,-524287.0f};
5172     static const XMVECTORF32 MaxXIco4 = { 524287.0f,15.0f, 524287.0f, 524287.0f};
5173     static const XMVECTORF32 ScaleXIco4 = {1.0f,4096.0f*65536.0f*0.5f,4096.0f,1.0f};
5174     static const XMVECTORI32 MaskXIco4 = {0xFFFFF,0xF<<((60-1)-32),0xFFFFF000,0xFFFFF};
5175     // Clamp to bounds
5176     XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,1,3,0));
5177     vResult = _mm_max_ps(vResult,MinXIco4);
5178     vResult = _mm_min_ps(vResult,MaxXIco4);
5179     // Scale by multiplication
5180     vResult = _mm_mul_ps(vResult,ScaleXIco4);
5181     // Convert to int
5182     __m128i vResulti = _mm_cvttps_epi32(vResult);
5183     // Mask off any fraction
5184     vResulti = _mm_and_si128(vResulti,MaskXIco4);
5185     // Isolate Y
5186     __m128i vResulti2 = _mm_and_si128(vResulti,g_XMMaskY);
5187     // Double Y (Really W) to fixup for unsigned conversion
5188     vResulti = _mm_add_epi32(vResulti,vResulti2);
5189     // Shift y and z to straddle the 32-bit boundary
5190     vResulti2 = _mm_srli_si128(vResulti,(64+12)/8);
5191     // Shift it into place
5192     vResulti2 = _mm_slli_si128(vResulti2,20/8);
5193     // i = x|y<<20|z<<40|w<<60
5194     vResulti = _mm_or_si128(vResulti,vResulti2);
5195     _mm_store_sd(reinterpret_cast<double *>(&pDestination->v),reinterpret_cast<const __m128d *>(&vResulti)[0]);
5196 #else // _XM_VMX128_INTRINSICS_
5197 #endif // _XM_VMX128_INTRINSICS_
5198 }
5199
5200 //------------------------------------------------------------------------------
5201
5202 XMFINLINE VOID XMStoreUIcoN4
5203 (
5204     XMUICON4*  pDestination, 
5205     FXMVECTOR   V
5206 )
5207 {
5208     #define XM_URange       ((FLOAT)(1 << 20))
5209     #define XM_URangeDiv2   ((FLOAT)(1 << 19))
5210     #define XM_UMaxXYZ      ((FLOAT)((1 << 20) - 1))
5211     #define XM_UMaxW        ((FLOAT)((1 << 4) - 1))
5212     #define XM_ScaleXYZ     (-(FLOAT)((1 << 20) - 1) / XM_PACK_FACTOR)
5213     #define XM_ScaleW       (-(FLOAT)((1 << 4) - 1) / XM_PACK_FACTOR)
5214     #define XM_Scale        (-1.0f / XM_PACK_FACTOR)
5215     #define XM_Offset       (3.0f)
5216
5217 #if defined(_XM_NO_INTRINSICS_)
5218
5219     XMVECTOR               N;
5220     static CONST XMVECTORF32 Scale = {1048575.0f, 1048575.0f, 1048575.0f, 15.0f};
5221
5222     XMASSERT(pDestination);
5223
5224     N = XMVectorSaturate(V);
5225     N = XMVectorMultiplyAdd(N, Scale.v, g_XMOneHalf.v);
5226
5227     pDestination->v = ((UINT64)N.vector4_f32[3] << 60) |
5228                        (((UINT64)N.vector4_f32[2] & 0xFFFFF) << 40) |
5229                        (((UINT64)N.vector4_f32[1] & 0xFFFFF) << 20) |
5230                        (((UINT64)N.vector4_f32[0] & 0xFFFFF));
5231
5232 #elif defined(_XM_SSE_INTRINSICS_)
5233     XMASSERT(pDestination);
5234     // Note: Masks are x,w,y and z
5235     static const XMVECTORF32 ScaleUIcoN4 = {1048575.0f,15.0f*4096.0f*65536.0f,1048575.0f*4096.0f,1048575.0f};
5236     static const XMVECTORI32 MaskUIcoN4 = {0xFFFFF,0xF<<(60-32),0xFFFFF000,0xFFFFF};
5237     static const XMVECTORF32 AddUIcoN4 = {0.0f,-32768.0f*65536.0f,-32768.0f*65536.0f,0.0f};
5238     // Clamp to bounds
5239     XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,1,3,0));
5240     vResult = _mm_max_ps(vResult,g_XMZero);
5241     vResult = _mm_min_ps(vResult,g_XMOne);
5242     // Scale by multiplication
5243     vResult = _mm_mul_ps(vResult,ScaleUIcoN4);
5244     // Adjust for unsigned entries
5245     vResult = _mm_add_ps(vResult,AddUIcoN4);
5246     // Convert to int
5247     __m128i vResulti = _mm_cvttps_epi32(vResult);
5248     // Fix the signs on the unsigned entries
5249     vResulti = _mm_xor_si128(vResulti,g_XMFlipYZ);
5250     // Mask off any fraction
5251     vResulti = _mm_and_si128(vResulti,MaskUIcoN4);
5252     // Shift y and z to straddle the 32-bit boundary
5253     __m128i vResulti2 = _mm_srli_si128(vResulti,(64+12)/8);
5254     // Shift it into place
5255     vResulti2 = _mm_slli_si128(vResulti2,20/8);
5256     // i = x|y<<20|z<<40|w<<60
5257     vResulti = _mm_or_si128(vResulti,vResulti2);
5258     _mm_store_sd(reinterpret_cast<double *>(&pDestination->v),reinterpret_cast<const __m128d *>(&vResulti)[0]);
5259 #else // _XM_VMX128_INTRINSICS_
5260 #endif // _XM_VMX128_INTRINSICS_
5261
5262     #undef XM_URange
5263     #undef XM_URangeDiv2
5264     #undef XM_UMaxXYZ
5265     #undef XM_UMaxW
5266     #undef XM_ScaleXYZ
5267     #undef XM_ScaleW
5268     #undef XM_Scale
5269     #undef XM_Offset
5270 }
5271
5272 //------------------------------------------------------------------------------
5273
5274 XMFINLINE VOID XMStoreUIco4
5275 (
5276     XMUICO4*  pDestination, 
5277     FXMVECTOR  V
5278 )
5279 {
5280     #define XM_Scale        (-1.0f / XM_PACK_FACTOR)
5281     #define XM_URange       ((FLOAT)(1 << 20))
5282     #define XM_URangeDiv2   ((FLOAT)(1 << 19))
5283
5284 #if defined(_XM_NO_INTRINSICS_)
5285
5286     XMVECTOR               N;
5287     static CONST XMVECTOR  Max = {1048575.0f, 1048575.0f, 1048575.0f, 15.0f};
5288
5289     XMASSERT(pDestination);
5290
5291     N = XMVectorClamp(V, XMVectorZero(), Max);
5292     N = XMVectorRound(N);
5293
5294     pDestination->v = ((UINT64)N.vector4_f32[3] << 60) |
5295                        (((UINT64)N.vector4_f32[2] & 0xFFFFF) << 40) |
5296                        (((UINT64)N.vector4_f32[1] & 0xFFFFF) << 20) |
5297                        (((UINT64)N.vector4_f32[0] & 0xFFFFF));
5298
5299 #elif defined(_XM_SSE_INTRINSICS_)
5300     XMASSERT(pDestination);
5301     // Note: Masks are x,w,y and z
5302     static const XMVECTORF32 MaxUIco4 = { 1048575.0f, 15.0f, 1048575.0f, 1048575.0f};
5303     static const XMVECTORF32 ScaleUIco4 = {1.0f,4096.0f*65536.0f,4096.0f,1.0f};
5304     static const XMVECTORI32 MaskUIco4 = {0xFFFFF,0xF<<(60-32),0xFFFFF000,0xFFFFF};
5305     static const XMVECTORF32 AddUIco4 = {0.0f,-32768.0f*65536.0f,-32768.0f*65536.0f,0.0f};
5306     // Clamp to bounds
5307     XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,1,3,0));
5308     vResult = _mm_max_ps(vResult,g_XMZero);
5309     vResult = _mm_min_ps(vResult,MaxUIco4);
5310     // Scale by multiplication
5311     vResult = _mm_mul_ps(vResult,ScaleUIco4);
5312     vResult = _mm_add_ps(vResult,AddUIco4);
5313     // Convert to int
5314     __m128i vResulti = _mm_cvttps_epi32(vResult);
5315     vResulti = _mm_xor_si128(vResulti,g_XMFlipYZ);
5316     // Mask off any fraction
5317     vResulti = _mm_and_si128(vResulti,MaskUIco4);
5318     // Shift y and z to straddle the 32-bit boundary
5319     __m128i vResulti2 = _mm_srli_si128(vResulti,(64+12)/8);
5320     // Shift it into place
5321     vResulti2 = _mm_slli_si128(vResulti2,20/8);
5322     // i = x|y<<20|z<<40|w<<60
5323     vResulti = _mm_or_si128(vResulti,vResulti2);
5324     _mm_store_sd(reinterpret_cast<double *>(&pDestination->v),reinterpret_cast<const __m128d *>(&vResulti)[0]);
5325 #else // _XM_VMX128_INTRINSICS_
5326 #endif // _XM_VMX128_INTRINSICS_
5327
5328     #undef XM_Scale
5329     #undef XM_URange
5330     #undef XM_URangeDiv2
5331 }
5332
5333 //------------------------------------------------------------------------------
5334
5335 XMFINLINE VOID XMStoreIcoN4
5336 (
5337     XMICON4*  pDestination, 
5338     FXMVECTOR  V
5339 )
5340 {
5341     #define XM_Scale    (-1.0f / XM_PACK_FACTOR)
5342     #define XM_URange   ((FLOAT)(1 << 4))
5343     #define XM_Offset   (3.0f)
5344     #define XM_UMaxXYZ  ((FLOAT)((1 << (20 - 1)) - 1))
5345     #define XM_UMaxW    ((FLOAT)((1 << (4 - 1)) - 1))
5346
5347 #if defined(_XM_NO_INTRINSICS_)
5348
5349     XMVECTOR               N;
5350     static CONST XMVECTORF32  Scale = {524287.0f, 524287.0f, 524287.0f, 7.0f};
5351
5352     XMASSERT(pDestination);
5353
5354     N = XMVectorClamp(V, g_XMNegativeOne.v, g_XMOne.v);
5355     N = XMVectorMultiplyAdd(N, Scale.v, g_XMNegativeZero.v);
5356     N = XMVectorRound(N);
5357
5358     pDestination->v = ((UINT64)N.vector4_f32[3] << 60) |
5359                        (((UINT64)N.vector4_f32[2] & 0xFFFFF) << 40) |
5360                        (((UINT64)N.vector4_f32[1] & 0xFFFFF) << 20) |
5361                        (((UINT64)N.vector4_f32[0] & 0xFFFFF));
5362
5363 #elif defined(_XM_SSE_INTRINSICS_)
5364     XMASSERT(pDestination);
5365     // Note: Masks are x,w,y and z
5366     static const XMVECTORF32 ScaleIcoN4 = {524287.0f,7.0f*4096.0f*65536.0f,524287.0f*4096.0f,524287.0f};
5367     static const XMVECTORI32 MaskIcoN4 = {0xFFFFF,0xF<<(60-32),0xFFFFF000,0xFFFFF};
5368     // Clamp to bounds
5369     XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,1,3,0));
5370     vResult = _mm_max_ps(vResult,g_XMNegativeOne);
5371     vResult = _mm_min_ps(vResult,g_XMOne);
5372     // Scale by multiplication
5373     vResult = _mm_mul_ps(vResult,ScaleIcoN4);
5374     // Convert to int
5375     __m128i vResulti = _mm_cvttps_epi32(vResult);
5376     // Mask off any fraction
5377     vResulti = _mm_and_si128(vResulti,MaskIcoN4);
5378     // Shift y and z to straddle the 32-bit boundary
5379     __m128i vResulti2 = _mm_srli_si128(vResulti,(64+12)/8);
5380     // Shift it into place
5381     vResulti2 = _mm_slli_si128(vResulti2,20/8);
5382     // i = x|y<<20|z<<40|w<<60
5383     vResulti = _mm_or_si128(vResulti,vResulti2);
5384     _mm_store_sd(reinterpret_cast<double *>(&pDestination->v),reinterpret_cast<const __m128d *>(&vResulti)[0]);
5385 #else // _XM_VMX128_INTRINSICS_
5386 #endif // _XM_VMX128_INTRINSICS_
5387
5388     #undef XM_Scale
5389     #undef XM_URange
5390     #undef XM_Offset
5391     #undef XM_UMaxXYZ
5392     #undef XM_UMaxW
5393 }
5394
5395 //------------------------------------------------------------------------------
5396
5397 XMFINLINE VOID XMStoreIco4
5398 (
5399     XMICO4*  pDestination, 
5400     FXMVECTOR V
5401 )
5402 {
5403     #define XM_Scale    (-1.0f / XM_PACK_FACTOR)
5404     #define XM_URange   ((FLOAT)(1 << 4))
5405     #define XM_Offset   (3.0f)
5406
5407 #if defined(_XM_NO_INTRINSICS_)
5408
5409     XMVECTOR               N;
5410     static CONST XMVECTOR  Min = {-524287.0f, -524287.0f, -524287.0f, -7.0f};
5411     static CONST XMVECTOR  Max = {524287.0f, 524287.0f, 524287.0f, 7.0f};
5412
5413     XMASSERT(pDestination);
5414
5415     N = XMVectorClamp(V, Min, Max);
5416     N = XMVectorRound(N);
5417
5418     pDestination->v = ((INT64)N.vector4_f32[3] << 60) |
5419                        (((INT64)N.vector4_f32[2] & 0xFFFFF) << 40) |
5420                        (((INT64)N.vector4_f32[1] & 0xFFFFF) << 20) |
5421                        (((INT64)N.vector4_f32[0] & 0xFFFFF));
5422
5423 #elif defined(_XM_SSE_INTRINSICS_)
5424     XMASSERT(pDestination);
5425     // Note: Masks are x,w,y and z
5426     static const XMVECTORF32 MinIco4 = {-524287.0f,-7.0f,-524287.0f,-524287.0f};
5427     static const XMVECTORF32 MaxIco4 = { 524287.0f, 7.0f, 524287.0f, 524287.0f};
5428     static const XMVECTORF32 ScaleIco4 = {1.0f,4096.0f*65536.0f,4096.0f,1.0f};
5429     static const XMVECTORI32 MaskIco4 = {0xFFFFF,0xF<<(60-32),0xFFFFF000,0xFFFFF};
5430     // Clamp to bounds
5431     XMVECTOR vResult = _mm_shuffle_ps(V,V,_MM_SHUFFLE(2,1,3,0));
5432     vResult = _mm_max_ps(vResult,MinIco4);
5433     vResult = _mm_min_ps(vResult,MaxIco4);
5434     // Scale by multiplication
5435     vResult = _mm_mul_ps(vResult,ScaleIco4);
5436     // Convert to int
5437     __m128i vResulti = _mm_cvttps_epi32(vResult);
5438     // Mask off any fraction
5439     vResulti = _mm_and_si128(vResulti,MaskIco4);
5440     // Shift y and z to straddle the 32-bit boundary
5441     __m128i vResulti2 = _mm_srli_si128(vResulti,(64+12)/8);
5442     // Shift it into place
5443     vResulti2 = _mm_slli_si128(vResulti2,20/8);
5444     // i = x|y<<20|z<<40|w<<60
5445     vResulti = _mm_or_si128(vResulti,vResulti2);
5446     _mm_store_sd(reinterpret_cast<double *>(&pDestination->v),reinterpret_cast<const __m128d *>(&vResulti)[0]);
5447 #else // _XM_VMX128_INTRINSICS_
5448 #endif // _XM_VMX128_INTRINSICS_
5449
5450     #undef XM_Scale
5451     #undef XM_URange
5452     #undef XM_Offset
5453 }
5454
5455 //------------------------------------------------------------------------------
5456
5457 XMFINLINE VOID XMStoreXDecN4
5458 (
5459     XMXDECN4* pDestination, 
5460     FXMVECTOR  V
5461 )
5462 {
5463 #if defined(_XM_NO_INTRINSICS_)
5464
5465     XMVECTOR               N;
5466     static CONST XMVECTORF32  Min = {-1.0f, -1.0f, -1.0f, 0.0f};
5467     static CONST XMVECTORF32  Scale = {511.0f, 511.0f, 511.0f, 3.0f};
5468
5469     XMASSERT(pDestination);
5470
5471     N = XMVectorClamp(V, Min.v, g_XMOne.v);
5472     N = XMVectorMultiply(N, Scale.v);
5473     N = XMVectorRound(N);
5474
5475     pDestination->v = ((UINT)N.vector4_f32[3] << 30) |
5476                        (((INT)N.vector4_f32[2] & 0x3FF) << 20) |
5477                        (((INT)N.vector4_f32[1] & 0x3FF) << 10) |
5478                        (((INT)N.vector4_f32[0] & 0x3FF));
5479
5480 #elif defined(_XM_SSE_INTRINSICS_)
5481     static const XMVECTORF32 Min = {-1.0f, -1.0f, -1.0f, 0.0f};
5482     static const XMVECTORF32 Scale = {511.0f, 511.0f*1024.0f, 511.0f*1048576.0f,3.0f*536870912.0f};
5483     static const XMVECTORI32 ScaleMask = {0x3FF,0x3FF<<10,0x3FF<<20,0x3<<29};
5484     XMASSERT(pDestination);
5485     XMVECTOR vResult = _mm_max_ps(V,Min);
5486     vResult = _mm_min_ps(vResult,g_XMOne);
5487     // Scale by multiplication
5488     vResult = _mm_mul_ps(vResult,Scale);
5489     // Convert to int (W is unsigned)
5490     __m128i vResulti = _mm_cvtps_epi32(vResult);
5491     // Mask off any fraction
5492     vResulti = _mm_and_si128(vResulti,ScaleMask);
5493     // To fix W, add itself to shift it up to <<30 instead of <<29
5494     __m128i vResultw = _mm_and_si128(vResulti,g_XMMaskW);
5495     vResulti = _mm_add_epi32(vResulti,vResultw);
5496     // Do a horizontal or of all 4 entries
5497     vResult = _mm_shuffle_ps(reinterpret_cast<const __m128 *>(&vResulti)[0],reinterpret_cast<const __m128 *>(&vResulti)[0],_MM_SHUFFLE(0,3,2,1));
5498     vResulti = _mm_or_si128(vResulti,reinterpret_cast<const __m128i *>(&vResult)[0]);
5499     vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1));
5500     vResulti = _mm_or_si128(vResulti,reinterpret_cast<const __m128i *>(&vResult)[0]);
5501     vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(0,3,2,1));
5502     vResulti = _mm_or_si128(vResulti,reinterpret_cast<const __m128i *>(&vResult)[0]);
5503     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
5504 #else // _XM_VMX128_INTRINSICS_
5505 #endif // _XM_VMX128_INTRINSICS_
5506 }
5507
5508 //------------------------------------------------------------------------------
5509
5510 XMFINLINE VOID XMStoreXDec4
5511 (
5512     XMXDEC4* pDestination, 
5513     FXMVECTOR  V
5514 )
5515 {
5516 #if defined(_XM_NO_INTRINSICS_)
5517
5518     XMVECTOR               N;
5519     static CONST XMVECTOR  Min = {-511.0f, -511.0f, -511.0f, 0.0f};
5520     static CONST XMVECTOR  Max = {511.0f, 511.0f, 511.0f, 3.0f};
5521
5522     XMASSERT(pDestination);
5523
5524     N = XMVectorClamp(V, Min, Max);
5525
5526     pDestination->v = ((UINT)N.vector4_f32[3] << 30) |
5527                        (((INT)N.vector4_f32[2] & 0x3FF) << 20) |
5528                        (((INT)N.vector4_f32[1] & 0x3FF) << 10) |
5529                        (((INT)N.vector4_f32[0] & 0x3FF));
5530
5531 #elif defined(_XM_SSE_INTRINSICS_)
5532     XMASSERT(pDestination);
5533     static const XMVECTORF32 MinXDec4 = {-511.0f,-511.0f,-511.0f, 0.0f};
5534     static const XMVECTORF32 MaxXDec4 = { 511.0f, 511.0f, 511.0f, 3.0f};
5535     static const XMVECTORF32 ScaleXDec4 = {1.0f,1024.0f/2.0f,1024.0f*1024.0f,1024.0f*1024.0f*1024.0f/2.0f};
5536     static const XMVECTORI32 MaskXDec4= {0x3FF,0x3FF<<(10-1),0x3FF<<20,0x3<<(30-1)};
5537     // Clamp to bounds
5538     XMVECTOR vResult = _mm_max_ps(V,MinXDec4);
5539     vResult = _mm_min_ps(vResult,MaxXDec4);
5540     // Scale by multiplication
5541     vResult = _mm_mul_ps(vResult,ScaleXDec4);
5542     // Convert to int
5543     __m128i vResulti = _mm_cvttps_epi32(vResult);
5544     // Mask off any fraction
5545     vResulti = _mm_and_si128(vResulti,MaskXDec4);
5546     // Do a horizontal or of 4 entries
5547     __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2));
5548     // x = x|z, y = y|w
5549     vResulti = _mm_or_si128(vResulti,vResulti2);
5550     // Move Z to the x position
5551     vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1));
5552     // Perform a single bit left shift on y|w
5553     vResulti2 = _mm_add_epi32(vResulti2,vResulti2);
5554     // i = x|y|z|w
5555     vResulti = _mm_or_si128(vResulti,vResulti2);
5556     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
5557 #else // _XM_VMX128_INTRINSICS_
5558 #endif // _XM_VMX128_INTRINSICS_
5559 }
5560
5561 //------------------------------------------------------------------------------
5562
5563 XMFINLINE VOID XMStoreUDecN4
5564 (
5565     XMUDECN4* pDestination, 
5566     FXMVECTOR  V
5567 )
5568 {
5569 #if defined(_XM_NO_INTRINSICS_)
5570
5571     XMVECTOR               N;
5572     static CONST XMVECTORF32  Scale = {1023.0f, 1023.0f, 1023.0f, 3.0f};
5573
5574     XMASSERT(pDestination);
5575
5576     N = XMVectorSaturate(V);
5577     N = XMVectorMultiply(N, Scale.v);
5578
5579     pDestination->v = ((UINT)N.vector4_f32[3] << 30) |
5580                        (((UINT)N.vector4_f32[2] & 0x3FF) << 20) |
5581                        (((UINT)N.vector4_f32[1] & 0x3FF) << 10) |
5582                        (((UINT)N.vector4_f32[0] & 0x3FF));
5583
5584 #elif defined(_XM_SSE_INTRINSICS_)
5585     XMASSERT(pDestination);
5586     static const XMVECTORF32 ScaleUDecN4 = {1023.0f,1023.0f*1024.0f*0.5f,1023.0f*1024.0f*1024.0f,3.0f*1024.0f*1024.0f*1024.0f*0.5f};
5587     static const XMVECTORI32 MaskUDecN4= {0x3FF,0x3FF<<(10-1),0x3FF<<20,0x3<<(30-1)};
5588     // Clamp to bounds
5589     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
5590     vResult = _mm_min_ps(vResult,g_XMOne);
5591     // Scale by multiplication
5592     vResult = _mm_mul_ps(vResult,ScaleUDecN4);
5593     // Convert to int
5594     __m128i vResulti = _mm_cvttps_epi32(vResult);
5595     // Mask off any fraction
5596     vResulti = _mm_and_si128(vResulti,MaskUDecN4);
5597     // Do a horizontal or of 4 entries
5598     __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2));
5599     // x = x|z, y = y|w
5600     vResulti = _mm_or_si128(vResulti,vResulti2);
5601     // Move Z to the x position
5602     vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1));
5603     // Perform a left shift by one bit on y|w
5604     vResulti2 = _mm_add_epi32(vResulti2,vResulti2);
5605     // i = x|y|z|w
5606     vResulti = _mm_or_si128(vResulti,vResulti2);
5607     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
5608 #else // _XM_VMX128_INTRINSICS_
5609 #endif // _XM_VMX128_INTRINSICS_
5610 }
5611
5612 //------------------------------------------------------------------------------
5613
5614 XMFINLINE VOID XMStoreUDec4
5615 (
5616     XMUDEC4* pDestination, 
5617     FXMVECTOR  V
5618 )
5619 {
5620 #if defined(_XM_NO_INTRINSICS_)
5621
5622     XMVECTOR               N;
5623     static CONST XMVECTOR  Max = {1023.0f, 1023.0f, 1023.0f, 3.0f};
5624
5625     XMASSERT(pDestination);
5626
5627     N = XMVectorClamp(V, XMVectorZero(), Max);
5628
5629     pDestination->v = ((UINT)N.vector4_f32[3] << 30) |
5630                        (((UINT)N.vector4_f32[2] & 0x3FF) << 20) |
5631                        (((UINT)N.vector4_f32[1] & 0x3FF) << 10) |
5632                        (((UINT)N.vector4_f32[0] & 0x3FF));
5633
5634 #elif defined(_XM_SSE_INTRINSICS_)
5635     XMASSERT(pDestination);
5636     static const XMVECTORF32 MaxUDec4 = { 1023.0f, 1023.0f, 1023.0f, 3.0f};
5637     static const XMVECTORF32 ScaleUDec4 = {1.0f,1024.0f/2.0f,1024.0f*1024.0f,1024.0f*1024.0f*1024.0f/2.0f};
5638     static const XMVECTORI32 MaskUDec4= {0x3FF,0x3FF<<(10-1),0x3FF<<20,0x3<<(30-1)};
5639     // Clamp to bounds
5640     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
5641     vResult = _mm_min_ps(vResult,MaxUDec4);
5642     // Scale by multiplication
5643     vResult = _mm_mul_ps(vResult,ScaleUDec4);
5644     // Convert to int
5645     __m128i vResulti = _mm_cvttps_epi32(vResult);
5646     // Mask off any fraction
5647     vResulti = _mm_and_si128(vResulti,MaskUDec4);
5648     // Do a horizontal or of 4 entries
5649     __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2));
5650     // x = x|z, y = y|w
5651     vResulti = _mm_or_si128(vResulti,vResulti2);
5652     // Move Z to the x position
5653     vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1));
5654     // Perform a left shift by one bit on y|w
5655     vResulti2 = _mm_add_epi32(vResulti2,vResulti2);
5656     // i = x|y|z|w
5657     vResulti = _mm_or_si128(vResulti,vResulti2);
5658     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
5659 #else // _XM_VMX128_INTRINSICS_
5660 #endif // _XM_VMX128_INTRINSICS_
5661 }
5662
5663 //------------------------------------------------------------------------------
5664
5665 XMFINLINE VOID XMStoreDecN4
5666 (
5667     XMDECN4* pDestination, 
5668     FXMVECTOR V
5669 )
5670 {
5671 #if defined(_XM_NO_INTRINSICS_)
5672
5673     XMVECTOR               N;
5674     static CONST XMVECTORF32  Scale = {511.0f, 511.0f, 511.0f, 1.0f};
5675
5676     XMASSERT(pDestination);
5677
5678     N = XMVectorClamp(V, g_XMNegativeOne.v, g_XMOne.v);
5679     N = XMVectorMultiply(N, Scale.v);
5680
5681     pDestination->v = ((INT)N.vector4_f32[3] << 30) |
5682                        (((INT)N.vector4_f32[2] & 0x3FF) << 20) |
5683                        (((INT)N.vector4_f32[1] & 0x3FF) << 10) |
5684                        (((INT)N.vector4_f32[0] & 0x3FF));
5685
5686 #elif defined(_XM_SSE_INTRINSICS_)
5687     XMASSERT(pDestination);
5688     static const XMVECTORF32 ScaleDecN4 = {511.0f,511.0f*1024.0f,511.0f*1024.0f*1024.0f,1.0f*1024.0f*1024.0f*1024.0f};
5689     static const XMVECTORI32 MaskDecN4= {0x3FF,0x3FF<<10,0x3FF<<20,0x3<<30};
5690     // Clamp to bounds
5691     XMVECTOR vResult = _mm_max_ps(V,g_XMNegativeOne);
5692     vResult = _mm_min_ps(vResult,g_XMOne);
5693     // Scale by multiplication
5694     vResult = _mm_mul_ps(vResult,ScaleDecN4);
5695     // Convert to int
5696     __m128i vResulti = _mm_cvttps_epi32(vResult);
5697     // Mask off any fraction
5698     vResulti = _mm_and_si128(vResulti,MaskDecN4);
5699     // Do a horizontal or of 4 entries
5700     __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2));
5701     // x = x|z, y = y|w
5702     vResulti = _mm_or_si128(vResulti,vResulti2);
5703     // Move Z to the x position
5704     vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1));
5705     // i = x|y|z|w
5706     vResulti = _mm_or_si128(vResulti,vResulti2);
5707     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
5708 #else // _XM_VMX128_INTRINSICS_
5709 #endif // _XM_VMX128_INTRINSICS_
5710 }
5711
5712 //------------------------------------------------------------------------------
5713
5714 XMFINLINE VOID XMStoreDec4
5715 (
5716     XMDEC4*  pDestination, 
5717     FXMVECTOR V
5718 )
5719 {
5720 #if defined(_XM_NO_INTRINSICS_)
5721
5722     XMVECTOR               N;
5723     static CONST XMVECTOR  Min = {-511.0f, -511.0f, -511.0f, -1.0f};
5724     static CONST XMVECTOR  Max = {511.0f, 511.0f, 511.0f, 1.0f};
5725
5726     XMASSERT(pDestination);
5727
5728     N = XMVectorClamp(V, Min, Max);
5729
5730     pDestination->v = ((INT)N.vector4_f32[3] << 30) |
5731                        (((INT)N.vector4_f32[2] & 0x3FF) << 20) |
5732                        (((INT)N.vector4_f32[1] & 0x3FF) << 10) |
5733                        (((INT)N.vector4_f32[0] & 0x3FF));
5734
5735 #elif defined(_XM_SSE_INTRINSICS_)
5736     XMASSERT(pDestination);
5737     static const XMVECTORF32 MinDec4 = {-511.0f,-511.0f,-511.0f,-1.0f};
5738     static const XMVECTORF32 MaxDec4 = { 511.0f, 511.0f, 511.0f, 1.0f};
5739     static const XMVECTORF32 ScaleDec4 = {1.0f,1024.0f,1024.0f*1024.0f,1024.0f*1024.0f*1024.0f};
5740     static const XMVECTORI32 MaskDec4= {0x3FF,0x3FF<<10,0x3FF<<20,0x3<<30};
5741     // Clamp to bounds
5742     XMVECTOR vResult = _mm_max_ps(V,MinDec4);
5743     vResult = _mm_min_ps(vResult,MaxDec4);
5744     // Scale by multiplication
5745     vResult = _mm_mul_ps(vResult,ScaleDec4);
5746     // Convert to int
5747     __m128i vResulti = _mm_cvttps_epi32(vResult);
5748     // Mask off any fraction
5749     vResulti = _mm_and_si128(vResulti,MaskDec4);
5750     // Do a horizontal or of 4 entries
5751     __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2));
5752     // x = x|z, y = y|w
5753     vResulti = _mm_or_si128(vResulti,vResulti2);
5754     // Move Z to the x position
5755     vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1));
5756     // i = x|y|z|w
5757     vResulti = _mm_or_si128(vResulti,vResulti2);
5758     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
5759 #else // _XM_VMX128_INTRINSICS_
5760 #endif // _XM_VMX128_INTRINSICS_
5761 }
5762
5763 //------------------------------------------------------------------------------
5764
5765 XMFINLINE VOID XMStoreUByteN4
5766 (
5767     XMUBYTEN4* pDestination, 
5768     FXMVECTOR V
5769 )
5770 {
5771 #if defined(_XM_NO_INTRINSICS_)
5772
5773     XMVECTOR               N;
5774     static CONST XMVECTORF32  Scale = {255.0f, 255.0f, 255.0f, 255.0f};
5775
5776     XMASSERT(pDestination);
5777
5778     N = XMVectorSaturate(V);
5779     N = XMVectorMultiply(N, Scale.v);
5780     N = XMVectorRound(N);
5781
5782     pDestination->x = (BYTE)N.vector4_f32[0];
5783     pDestination->y = (BYTE)N.vector4_f32[1];
5784     pDestination->z = (BYTE)N.vector4_f32[2];
5785     pDestination->w = (BYTE)N.vector4_f32[3];
5786
5787 #elif defined(_XM_SSE_INTRINSICS_)
5788     XMASSERT(pDestination);
5789     static const XMVECTORF32 ScaleUByteN4 = {255.0f,255.0f*256.0f*0.5f,255.0f*256.0f*256.0f,255.0f*256.0f*256.0f*256.0f*0.5f};
5790     static const XMVECTORI32 MaskUByteN4 = {0xFF,0xFF<<(8-1),0xFF<<16,0xFF<<(24-1)};
5791     // Clamp to bounds
5792     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
5793     vResult = _mm_min_ps(vResult,g_XMOne);
5794     // Scale by multiplication
5795     vResult = _mm_mul_ps(vResult,ScaleUByteN4);
5796     // Convert to int
5797     __m128i vResulti = _mm_cvttps_epi32(vResult);
5798     // Mask off any fraction
5799     vResulti = _mm_and_si128(vResulti,MaskUByteN4);
5800     // Do a horizontal or of 4 entries
5801     __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2));
5802     // x = x|z, y = y|w
5803     vResulti = _mm_or_si128(vResulti,vResulti2);
5804     // Move Z to the x position
5805     vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1));
5806     // Perform a single bit left shift to fix y|w 
5807     vResulti2 = _mm_add_epi32(vResulti2,vResulti2);
5808     // i = x|y|z|w
5809     vResulti = _mm_or_si128(vResulti,vResulti2);
5810     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
5811 #else // _XM_VMX128_INTRINSICS_
5812 #endif // _XM_VMX128_INTRINSICS_
5813 }
5814
5815 //------------------------------------------------------------------------------
5816
5817 XMFINLINE VOID XMStoreUByte4
5818 (
5819     XMUBYTE4* pDestination, 
5820     FXMVECTOR  V
5821 )
5822 {
5823 #if defined(_XM_NO_INTRINSICS_)
5824
5825     XMVECTOR               N;
5826     static CONST XMVECTOR  Max = {255.0f, 255.0f, 255.0f, 255.0f};
5827
5828     XMASSERT(pDestination);
5829
5830     N = XMVectorClamp(V, XMVectorZero(), Max);
5831     N = XMVectorRound(N);
5832
5833     pDestination->x = (BYTE)N.vector4_f32[0];
5834     pDestination->y = (BYTE)N.vector4_f32[1];
5835     pDestination->z = (BYTE)N.vector4_f32[2];
5836     pDestination->w = (BYTE)N.vector4_f32[3];
5837
5838 #elif defined(_XM_SSE_INTRINSICS_)
5839     XMASSERT(pDestination);
5840     static const XMVECTORF32 MaxUByte4 = { 255.0f, 255.0f, 255.0f, 255.0f};
5841     static const XMVECTORF32 ScaleUByte4 = {1.0f,256.0f*0.5f,256.0f*256.0f,256.0f*256.0f*256.0f*0.5f};
5842     static const XMVECTORI32 MaskUByte4 = {0xFF,0xFF<<(8-1),0xFF<<16,0xFF<<(24-1)};
5843     // Clamp to bounds
5844     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
5845     vResult = _mm_min_ps(vResult,MaxUByte4);
5846     // Scale by multiplication
5847     vResult = _mm_mul_ps(vResult,ScaleUByte4);
5848     // Convert to int
5849     __m128i vResulti = _mm_cvttps_epi32(vResult);
5850     // Mask off any fraction
5851     vResulti = _mm_and_si128(vResulti,MaskUByte4);
5852     // Do a horizontal or of 4 entries
5853     __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2));
5854     // x = x|z, y = y|w
5855     vResulti = _mm_or_si128(vResulti,vResulti2);
5856     // Move Z to the x position
5857     vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1));
5858     // Perform a single bit left shift to fix y|w 
5859     vResulti2 = _mm_add_epi32(vResulti2,vResulti2);
5860     // i = x|y|z|w
5861     vResulti = _mm_or_si128(vResulti,vResulti2);
5862     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
5863 #else // _XM_VMX128_INTRINSICS_
5864 #endif // _XM_VMX128_INTRINSICS_
5865 }
5866
5867 //------------------------------------------------------------------------------
5868
5869 XMFINLINE VOID XMStoreByteN4
5870 (
5871     XMBYTEN4* pDestination, 
5872     FXMVECTOR  V
5873 )
5874 {
5875 #if defined(_XM_NO_INTRINSICS_)
5876
5877     XMVECTOR               N;
5878     static CONST XMVECTORF32  Scale = {127.0f, 127.0f, 127.0f, 127.0f};
5879
5880     XMASSERT(pDestination);
5881
5882     N = XMVectorClamp(V, g_XMNegativeOne.v, g_XMOne.v);
5883     N = XMVectorMultiply(V, Scale.v);
5884     N = XMVectorRound(N);
5885
5886     pDestination->x = (CHAR)N.vector4_f32[0];
5887     pDestination->y = (CHAR)N.vector4_f32[1];
5888     pDestination->z = (CHAR)N.vector4_f32[2];
5889     pDestination->w = (CHAR)N.vector4_f32[3];
5890
5891 #elif defined(_XM_SSE_INTRINSICS_)
5892     XMASSERT(pDestination);
5893     static const XMVECTORF32 ScaleByteN4 = {127.0f,127.0f*256.0f,127.0f*256.0f*256.0f,127.0f*256.0f*256.0f*256.0f};
5894     static const XMVECTORI32 MaskByteN4 = {0xFF,0xFF<<8,0xFF<<16,0xFF<<24};
5895     // Clamp to bounds
5896     XMVECTOR vResult = _mm_max_ps(V,g_XMNegativeOne);
5897     vResult = _mm_min_ps(vResult,g_XMOne);
5898     // Scale by multiplication
5899     vResult = _mm_mul_ps(vResult,ScaleByteN4);
5900     // Convert to int
5901     __m128i vResulti = _mm_cvttps_epi32(vResult);
5902     // Mask off any fraction
5903     vResulti = _mm_and_si128(vResulti,MaskByteN4);
5904     // Do a horizontal or of 4 entries
5905     __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2));
5906     // x = x|z, y = y|w
5907     vResulti = _mm_or_si128(vResulti,vResulti2);
5908     // Move Z to the x position
5909     vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1));
5910     // i = x|y|z|w
5911     vResulti = _mm_or_si128(vResulti,vResulti2);
5912     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
5913 #else // _XM_VMX128_INTRINSICS_
5914 #endif // _XM_VMX128_INTRINSICS_
5915 }
5916
5917 //------------------------------------------------------------------------------
5918
5919 XMFINLINE VOID XMStoreByte4
5920 (
5921     XMBYTE4*  pDestination, 
5922     FXMVECTOR  V
5923 )
5924 {
5925 #if defined(_XM_NO_INTRINSICS_)
5926
5927     XMVECTOR               N;
5928     static CONST XMVECTOR  Min = {-127.0f, -127.0f, -127.0f, -127.0f};
5929     static CONST XMVECTOR  Max = {127.0f, 127.0f, 127.0f, 127.0f};
5930
5931     XMASSERT(pDestination);
5932
5933     N = XMVectorClamp(V, Min, Max);
5934     N = XMVectorRound(N);
5935
5936     pDestination->x = (CHAR)N.vector4_f32[0];
5937     pDestination->y = (CHAR)N.vector4_f32[1];
5938     pDestination->z = (CHAR)N.vector4_f32[2];
5939     pDestination->w = (CHAR)N.vector4_f32[3];
5940
5941 #elif defined(_XM_SSE_INTRINSICS_)
5942     XMASSERT(pDestination);
5943     static const XMVECTORF32 MinByte4 = {-127.0f,-127.0f,-127.0f,-127.0f};
5944     static const XMVECTORF32 MaxByte4 = { 127.0f, 127.0f, 127.0f, 127.0f};
5945     static const XMVECTORF32 ScaleByte4 = {1.0f,256.0f,256.0f*256.0f,256.0f*256.0f*256.0f};
5946     static const XMVECTORI32 MaskByte4 = {0xFF,0xFF<<8,0xFF<<16,0xFF<<24};
5947     // Clamp to bounds
5948     XMVECTOR vResult = _mm_max_ps(V,MinByte4);
5949     vResult = _mm_min_ps(vResult,MaxByte4);
5950     // Scale by multiplication
5951     vResult = _mm_mul_ps(vResult,ScaleByte4);
5952     // Convert to int
5953     __m128i vResulti = _mm_cvttps_epi32(vResult);
5954     // Mask off any fraction
5955     vResulti = _mm_and_si128(vResulti,MaskByte4);
5956     // Do a horizontal or of 4 entries
5957     __m128i vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(3,2,3,2));
5958     // x = x|z, y = y|w
5959     vResulti = _mm_or_si128(vResulti,vResulti2);
5960     // Move Z to the x position
5961     vResulti2 = _mm_shuffle_epi32(vResulti,_MM_SHUFFLE(1,1,1,1));
5962     // i = x|y|z|w
5963     vResulti = _mm_or_si128(vResulti,vResulti2);
5964     _mm_store_ss(reinterpret_cast<float *>(&pDestination->v),reinterpret_cast<const __m128 *>(&vResulti)[0]);
5965 #else // _XM_VMX128_INTRINSICS_
5966 #endif // _XM_VMX128_INTRINSICS_
5967 }
5968
5969 //------------------------------------------------------------------------------
5970
5971 XMFINLINE VOID XMStoreUNibble4
5972 (
5973      XMUNIBBLE4* pDestination,
5974      FXMVECTOR V
5975 )
5976 {
5977 #if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
5978     XMASSERT(pDestination);
5979     static CONST XMVECTORF32  Max = {15.0f,15.0f,15.0f,15.0f};
5980     // Bounds check
5981     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
5982     vResult = _mm_min_ps(vResult,Max);
5983      // Convert to int with rounding
5984     __m128i vInt = _mm_cvtps_epi32(vResult);
5985     // No SSE operations will write to 16-bit values, so we have to extract them manually
5986     USHORT x = static_cast<USHORT>(_mm_extract_epi16(vInt,0));
5987     USHORT y = static_cast<USHORT>(_mm_extract_epi16(vInt,2));
5988     USHORT z = static_cast<USHORT>(_mm_extract_epi16(vInt,4));
5989     USHORT w = static_cast<USHORT>(_mm_extract_epi16(vInt,6));
5990     pDestination->v = ((w & 0xF) << 12) |
5991                       ((z & 0xF) << 8) |
5992                       ((y & 0xF) << 4) |
5993                       ((x & 0xF));
5994 #else
5995     XMVECTOR               N;
5996     static CONST XMVECTORF32  Max = {15.0f,15.0f,15.0f,15.0f};
5997
5998     XMASSERT(pDestination);
5999
6000     N = XMVectorClamp(V, XMVectorZero(), Max.v);
6001     N = XMVectorRound(N);
6002
6003     pDestination->v = (((USHORT)N.vector4_f32[3] & 0xF) << 12) |
6004                       (((USHORT)N.vector4_f32[2] & 0xF) << 8) |
6005                       (((USHORT)N.vector4_f32[1] & 0xF) << 4) |
6006                       (((USHORT)N.vector4_f32[0] & 0xF));
6007 #endif !_XM_SSE_INTRINSICS_
6008 }
6009
6010 //------------------------------------------------------------------------------
6011
6012 XMFINLINE VOID XMStoreU555(
6013      XMU555* pDestination,
6014      FXMVECTOR V
6015 )
6016 {
6017 #if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
6018     XMASSERT(pDestination);
6019     static CONST XMVECTORF32  Max = {31.0f, 31.0f, 31.0f, 1.0f};
6020     // Bounds check
6021     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
6022     vResult = _mm_min_ps(vResult,Max);
6023      // Convert to int with rounding
6024     __m128i vInt = _mm_cvtps_epi32(vResult);
6025     // No SSE operations will write to 16-bit values, so we have to extract them manually
6026     USHORT x = static_cast<USHORT>(_mm_extract_epi16(vInt,0));
6027     USHORT y = static_cast<USHORT>(_mm_extract_epi16(vInt,2));
6028     USHORT z = static_cast<USHORT>(_mm_extract_epi16(vInt,4));
6029     USHORT w = static_cast<USHORT>(_mm_extract_epi16(vInt,6));
6030     pDestination->v = ((w) ? 0x8000 : 0) |
6031                       ((z & 0x1F) << 10) |
6032                       ((y & 0x1F) << 5) |
6033                       ((x & 0x1F));
6034 #else
6035     XMVECTOR               N;
6036     static CONST XMVECTORF32  Max = {31.0f, 31.0f, 31.0f, 1.0f};
6037
6038     XMASSERT(pDestination);
6039
6040     N = XMVectorClamp(V, XMVectorZero(), Max.v);
6041     N = XMVectorRound(N);
6042
6043     pDestination->v = ((N.vector4_f32[3] > 0.f) ? 0x8000 : 0) |
6044                       (((USHORT)N.vector4_f32[2] & 0x1F) << 10) |
6045                       (((USHORT)N.vector4_f32[1] & 0x1F) << 5) |
6046                       (((USHORT)N.vector4_f32[0] & 0x1F));
6047 #endif !_XM_SSE_INTRINSICS_
6048 }
6049
6050 //------------------------------------------------------------------------------
6051
6052 XMFINLINE VOID XMStoreColor
6053 (
6054     XMCOLOR* pDestination, 
6055     FXMVECTOR V
6056 )
6057 {
6058 #if defined(_XM_NO_INTRINSICS_)
6059
6060     XMVECTOR               N;
6061     static CONST XMVECTORF32  Scale = {255.0f, 255.0f, 255.0f, 255.0f};
6062
6063     XMASSERT(pDestination);
6064
6065     N = XMVectorSaturate(V);
6066     N = XMVectorMultiply(N, Scale.v);
6067     N = XMVectorRound(N);
6068
6069     pDestination->c = ((UINT)N.vector4_f32[3] << 24) |
6070                       ((UINT)N.vector4_f32[0] << 16) |
6071                       ((UINT)N.vector4_f32[1] <<  8) |
6072                       ((UINT)N.vector4_f32[2]);
6073
6074 #elif defined(_XM_SSE_INTRINSICS_)
6075     XMASSERT(pDestination);
6076     static CONST XMVECTORF32  Scale = {255.0f,255.0f,255.0f,255.0f};
6077     // Set <0 to 0
6078     XMVECTOR vResult = _mm_max_ps(V,g_XMZero);
6079     // Set>1 to 1
6080     vResult = _mm_min_ps(vResult,g_XMOne);
6081     // Convert to 0-255
6082     vResult = _mm_mul_ps(vResult,Scale);
6083     // Shuffle RGBA to ARGB
6084     vResult = _mm_shuffle_ps(vResult,vResult,_MM_SHUFFLE(3,0,1,2));
6085     // Convert to int 
6086     __m128i vInt = _mm_cvtps_epi32(vResult);
6087     // Mash to shorts
6088     vInt = _mm_packs_epi32(vInt,vInt);
6089     // Mash to bytes
6090     vInt = _mm_packus_epi16(vInt,vInt);
6091     // Store the color
6092     _mm_store_ss(reinterpret_cast<float *>(&pDestination->c),reinterpret_cast<__m128 *>(&vInt)[0]);
6093 #else // _XM_VMX128_INTRINSICS_
6094 #endif // _XM_VMX128_INTRINSICS_
6095 }
6096
6097 //------------------------------------------------------------------------------
6098
6099 XMFINLINE VOID XMStoreFloat3x3
6100 (
6101     XMFLOAT3X3* pDestination, 
6102     CXMMATRIX   M
6103 )
6104 {
6105 #if defined(_XM_NO_INTRINSICS_) || defined(XM_NO_MISALIGNED_VECTOR_ACCESS) || defined(_XM_SSE_INTRINSICS_)
6106
6107     XMStoreFloat3x3NC(pDestination, M);
6108
6109 #else // _XM_VMX128_INTRINSICS_
6110 #endif // _XM_VMX128_INTRINSICS_
6111 }
6112
6113 //------------------------------------------------------------------------------
6114
6115 XMFINLINE VOID XMStoreFloat3x3NC
6116 (
6117     XMFLOAT3X3* pDestination, 
6118     CXMMATRIX M
6119 )
6120 {
6121 #if defined(_XM_NO_INTRINSICS_)
6122
6123     XMASSERT(pDestination);
6124
6125     pDestination->m[0][0] = M.r[0].vector4_f32[0];
6126     pDestination->m[0][1] = M.r[0].vector4_f32[1];
6127     pDestination->m[0][2] = M.r[0].vector4_f32[2];
6128
6129     pDestination->m[1][0] = M.r[1].vector4_f32[0];
6130     pDestination->m[1][1] = M.r[1].vector4_f32[1];
6131     pDestination->m[1][2] = M.r[1].vector4_f32[2];
6132
6133     pDestination->m[2][0] = M.r[2].vector4_f32[0];
6134     pDestination->m[2][1] = M.r[2].vector4_f32[1];
6135     pDestination->m[2][2] = M.r[2].vector4_f32[2];
6136
6137 #elif defined(_XM_SSE_INTRINSICS_)
6138     XMASSERT(pDestination);
6139     XMVECTOR vTemp1 = M.r[0];
6140     XMVECTOR vTemp2 = M.r[1];
6141     XMVECTOR vTemp3 = M.r[2];
6142     XMVECTOR vWork = _mm_shuffle_ps(vTemp1,vTemp2,_MM_SHUFFLE(0,0,2,2));
6143     vTemp1 = _mm_shuffle_ps(vTemp1,vWork,_MM_SHUFFLE(2,0,1,0));
6144     _mm_storeu_ps(&pDestination->m[0][0],vTemp1);
6145     vTemp2 = _mm_shuffle_ps(vTemp2,vTemp3,_MM_SHUFFLE(1,0,2,1));
6146     _mm_storeu_ps(&pDestination->m[1][1],vTemp2);
6147     vTemp3 = _mm_shuffle_ps(vTemp3,vTemp3,_MM_SHUFFLE(2,2,2,2));
6148     _mm_store_ss(&pDestination->m[2][2],vTemp3);
6149 #else // _XM_VMX128_INTRINSICS_
6150 #endif // _XM_VMX128_INTRINSICS_
6151 }
6152
6153 //------------------------------------------------------------------------------
6154
6155 XMFINLINE VOID XMStoreFloat4x3
6156 (
6157     XMFLOAT4X3* pDestination, 
6158     CXMMATRIX M
6159 )
6160 {
6161 #if defined(_XM_NO_INTRINSICS_) || defined(XM_NO_MISALIGNED_VECTOR_ACCESS) || defined(_XM_SSE_INTRINSICS_)
6162
6163     XMStoreFloat4x3NC(pDestination, M);
6164
6165 #else // _XM_VMX128_INTRINSICS_
6166 #endif // _XM_VMX128_INTRINSICS_
6167 }
6168
6169 //------------------------------------------------------------------------------
6170
6171 XMFINLINE VOID XMStoreFloat4x3A
6172 (
6173     XMFLOAT4X3A*        pDestination, 
6174     CXMMATRIX           M
6175 )
6176 {
6177 #if defined(_XM_NO_INTRINSICS_)
6178
6179     XMASSERT(pDestination);
6180     XMASSERT(((UINT_PTR)pDestination & 0xF) == 0);
6181
6182     pDestination->m[0][0] = M.r[0].vector4_f32[0];
6183     pDestination->m[0][1] = M.r[0].vector4_f32[1];
6184     pDestination->m[0][2] = M.r[0].vector4_f32[2];
6185
6186     pDestination->m[1][0] = M.r[1].vector4_f32[0];
6187     pDestination->m[1][1] = M.r[1].vector4_f32[1];
6188     pDestination->m[1][2] = M.r[1].vector4_f32[2];
6189
6190     pDestination->m[2][0] = M.r[2].vector4_f32[0];
6191     pDestination->m[2][1] = M.r[2].vector4_f32[1];
6192     pDestination->m[2][2] = M.r[2].vector4_f32[2];
6193
6194     pDestination->m[3][0] = M.r[3].vector4_f32[0];
6195     pDestination->m[3][1] = M.r[3].vector4_f32[1];
6196     pDestination->m[3][2] = M.r[3].vector4_f32[2];
6197
6198 #elif defined(_XM_SSE_INTRINSICS_)
6199     XMASSERT(pDestination);
6200     XMASSERT(((UINT_PTR)pDestination & 0xF) == 0);
6201     // x1,y1,z1,w1
6202     XMVECTOR vTemp1 = M.r[0];
6203     // x2,y2,z2,w2
6204     XMVECTOR vTemp2 = M.r[1];
6205     // x3,y3,z3,w3
6206     XMVECTOR vTemp3 = M.r[2];
6207     // x4,y4,z4,w4
6208     XMVECTOR vTemp4 = M.r[3];
6209     // z1,z1,x2,y2
6210     XMVECTOR vTemp = _mm_shuffle_ps(vTemp1,vTemp2,_MM_SHUFFLE(1,0,2,2));
6211     // y2,z2,x3,y3 (Final)
6212     vTemp2 = _mm_shuffle_ps(vTemp2,vTemp3,_MM_SHUFFLE(1,0,2,1));
6213     // x1,y1,z1,x2 (Final)
6214     vTemp1 = _mm_shuffle_ps(vTemp1,vTemp,_MM_SHUFFLE(2,0,1,0));
6215     // z3,z3,x4,x4
6216     vTemp3 = _mm_shuffle_ps(vTemp3,vTemp4,_MM_SHUFFLE(0,0,2,2));
6217     // z3,x4,y4,z4 (Final)
6218     vTemp3 = _mm_shuffle_ps(vTemp3,vTemp4,_MM_SHUFFLE(2,1,2,0));
6219     // Store in 3 operations
6220     _mm_store_ps(&pDestination->m[0][0],vTemp1);
6221     _mm_store_ps(&pDestination->m[1][1],vTemp2);
6222     _mm_store_ps(&pDestination->m[2][2],vTemp3);
6223 #else // _XM_VMX128_INTRINSICS_
6224 #endif // _XM_VMX128_INTRINSICS_
6225 }
6226
6227 //------------------------------------------------------------------------------
6228
6229 XMFINLINE VOID XMStoreFloat4x3NC
6230 (
6231     XMFLOAT4X3* pDestination, 
6232     CXMMATRIX M
6233 )
6234 {
6235 #if defined(_XM_NO_INTRINSICS_)
6236
6237     XMASSERT(pDestination);
6238
6239     pDestination->m[0][0] = M.r[0].vector4_f32[0];
6240     pDestination->m[0][1] = M.r[0].vector4_f32[1];
6241     pDestination->m[0][2] = M.r[0].vector4_f32[2];
6242
6243     pDestination->m[1][0] = M.r[1].vector4_f32[0];
6244     pDestination->m[1][1] = M.r[1].vector4_f32[1];
6245     pDestination->m[1][2] = M.r[1].vector4_f32[2];
6246
6247     pDestination->m[2][0] = M.r[2].vector4_f32[0];
6248     pDestination->m[2][1] = M.r[2].vector4_f32[1];
6249     pDestination->m[2][2] = M.r[2].vector4_f32[2];
6250
6251     pDestination->m[3][0] = M.r[3].vector4_f32[0];
6252     pDestination->m[3][1] = M.r[3].vector4_f32[1];
6253     pDestination->m[3][2] = M.r[3].vector4_f32[2];
6254
6255 #elif defined(_XM_SSE_INTRINSICS_)
6256     XMASSERT(pDestination);
6257     XMVECTOR vTemp1 = M.r[0];
6258     XMVECTOR vTemp2 = M.r[1];
6259     XMVECTOR vTemp3 = M.r[2];
6260     XMVECTOR vTemp4 = M.r[3];
6261     XMVECTOR vTemp2x = _mm_shuffle_ps(vTemp2,vTemp3,_MM_SHUFFLE(1,0,2,1));
6262     vTemp2 = _mm_shuffle_ps(vTemp2,vTemp1,_MM_SHUFFLE(2,2,0,0));
6263     vTemp1 = _mm_shuffle_ps(vTemp1,vTemp2,_MM_SHUFFLE(0,2,1,0));
6264     vTemp3 = _mm_shuffle_ps(vTemp3,vTemp4,_MM_SHUFFLE(0,0,2,2));
6265     vTemp3 = _mm_shuffle_ps(vTemp3,vTemp4,_MM_SHUFFLE(2,1,2,0));
6266     _mm_storeu_ps(&pDestination->m[0][0],vTemp1);
6267     _mm_storeu_ps(&pDestination->m[1][1],vTemp2x);
6268     _mm_storeu_ps(&pDestination->m[2][2],vTemp3);
6269 #else // _XM_VMX128_INTRINSICS_
6270 #endif // _XM_VMX128_INTRINSICS_
6271 }
6272
6273 //------------------------------------------------------------------------------
6274
6275 XMFINLINE VOID XMStoreFloat4x4
6276 (
6277     XMFLOAT4X4* pDestination, 
6278     CXMMATRIX M
6279 )
6280 {
6281 #if defined(_XM_NO_INTRINSICS_) || defined(XM_NO_MISALIGNED_VECTOR_ACCESS)
6282
6283     XMStoreFloat4x4NC(pDestination, M);
6284
6285 #elif defined(_XM_SSE_INTRINSICS_)
6286     XMASSERT(pDestination);
6287
6288     _mm_storeu_ps( &pDestination->_11, M.r[0] );
6289     _mm_storeu_ps( &pDestination->_21, M.r[1] );
6290     _mm_storeu_ps( &pDestination->_31, M.r[2] );
6291     _mm_storeu_ps( &pDestination->_41, M.r[3] );
6292 #else // _XM_VMX128_INTRINSICS_
6293 #endif // _XM_VMX128_INTRINSICS_
6294 }
6295
6296 //------------------------------------------------------------------------------
6297
6298 XMFINLINE VOID XMStoreFloat4x4A
6299 (
6300     XMFLOAT4X4A*        pDestination, 
6301     CXMMATRIX           M
6302 )
6303 {
6304 #if defined(_XM_NO_INTRINSICS_)
6305
6306     XMASSERT(pDestination);
6307     XMASSERT(((UINT_PTR)pDestination & 0xF) == 0);
6308
6309     pDestination->m[0][0] = M.r[0].vector4_f32[0];
6310     pDestination->m[0][1] = M.r[0].vector4_f32[1];
6311     pDestination->m[0][2] = M.r[0].vector4_f32[2];
6312     pDestination->m[0][3] = M.r[0].vector4_f32[3];
6313
6314     pDestination->m[1][0] = M.r[1].vector4_f32[0];
6315     pDestination->m[1][1] = M.r[1].vector4_f32[1];
6316     pDestination->m[1][2] = M.r[1].vector4_f32[2];
6317     pDestination->m[1][3] = M.r[1].vector4_f32[3];
6318
6319     pDestination->m[2][0] = M.r[2].vector4_f32[0];
6320     pDestination->m[2][1] = M.r[2].vector4_f32[1];
6321     pDestination->m[2][2] = M.r[2].vector4_f32[2];
6322     pDestination->m[2][3] = M.r[2].vector4_f32[3];
6323
6324     pDestination->m[3][0] = M.r[3].vector4_f32[0];
6325     pDestination->m[3][1] = M.r[3].vector4_f32[1];
6326     pDestination->m[3][2] = M.r[3].vector4_f32[2];
6327     pDestination->m[3][3] = M.r[3].vector4_f32[3];
6328
6329 #elif defined(_XM_SSE_INTRINSICS_)
6330     XMASSERT(pDestination);
6331
6332     _mm_store_ps( &pDestination->_11, M.r[0] );
6333     _mm_store_ps( &pDestination->_21, M.r[1] );
6334     _mm_store_ps( &pDestination->_31, M.r[2] );
6335     _mm_store_ps( &pDestination->_41, M.r[3] );
6336 #else // _XM_VMX128_INTRINSICS_
6337 #endif // _XM_VMX128_INTRINSICS_
6338 }
6339
6340 //------------------------------------------------------------------------------
6341
6342 XMFINLINE VOID XMStoreFloat4x4NC
6343 (
6344     XMFLOAT4X4* pDestination, 
6345     CXMMATRIX M
6346 )
6347 {
6348 #if defined(_XM_NO_INTRINSICS_)
6349
6350     XMASSERT(pDestination);
6351
6352     pDestination->m[0][0] = M.r[0].vector4_f32[0];
6353     pDestination->m[0][1] = M.r[0].vector4_f32[1];
6354     pDestination->m[0][2] = M.r[0].vector4_f32[2];
6355     pDestination->m[0][3] = M.r[0].vector4_f32[3];
6356
6357     pDestination->m[1][0] = M.r[1].vector4_f32[0];
6358     pDestination->m[1][1] = M.r[1].vector4_f32[1];
6359     pDestination->m[1][2] = M.r[1].vector4_f32[2];
6360     pDestination->m[1][3] = M.r[1].vector4_f32[3];
6361
6362     pDestination->m[2][0] = M.r[2].vector4_f32[0];
6363     pDestination->m[2][1] = M.r[2].vector4_f32[1];
6364     pDestination->m[2][2] = M.r[2].vector4_f32[2];
6365     pDestination->m[2][3] = M.r[2].vector4_f32[3];
6366
6367     pDestination->m[3][0] = M.r[3].vector4_f32[0];
6368     pDestination->m[3][1] = M.r[3].vector4_f32[1];
6369     pDestination->m[3][2] = M.r[3].vector4_f32[2];
6370     pDestination->m[3][3] = M.r[3].vector4_f32[3];
6371
6372 #elif defined(_XM_SSE_INTRINSICS_)
6373     XMASSERT(pDestination);
6374     _mm_storeu_ps(&pDestination->m[0][0],M.r[0]);
6375     _mm_storeu_ps(&pDestination->m[1][0],M.r[1]);
6376     _mm_storeu_ps(&pDestination->m[2][0],M.r[2]);
6377     _mm_storeu_ps(&pDestination->m[3][0],M.r[3]);
6378 #else // _XM_VMX128_INTRINSICS_
6379 #endif // _XM_VMX128_INTRINSICS_
6380 }
6381
6382 #endif // __XNAMATHCONVERT_INL__
6383