Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

634 lines
17 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) Microsoft Corporation, 1997.
  4. //
  5. // d3dflt.h
  6. //
  7. // Floating-point constants and operations on FP values.
  8. //
  9. //----------------------------------------------------------------------------
  10. #ifndef _D3DFLT_H_
  11. #define _D3DFLT_H_
  12. #include <math.h>
  13. #include <float.h>
  14. #ifdef __cplusplus
  15. extern "C" {
  16. #endif
  17. typedef union tagFLOATINT32
  18. {
  19. FLOAT f;
  20. INT32 i;
  21. UINT32 u;
  22. } FLOATINT32, *PFLOATINT32;
  23. //
  24. // Type-forcing macros to access FP as integer and vice-versa.
  25. // ATTENTION - VC5's optimizer turns these macros into ftol sometimes,
  26. // completely breaking them.
  27. // Using FLOATINT32 works around the problem but is not as flexible,
  28. // so the old code is kept around for the time when the compiler is fixed.
  29. // Note that pointer casting with FLOATINT32 fails just as the direct
  30. // pointer casting does, so it's not a remedy.
  31. //
  32. // Use these macros with extreme care.
  33. //
  34. #define ASFLOAT(i) (*(FLOAT *)&(i))
  35. #define ASINT32(f) (*(INT32 *)&(f))
  36. #define ASUINT32(f) (*(UINT32 *)&(f))
  37. //
  38. // FP constants.
  39. //
  40. // Powers of two for snap values. These should not be used in code.
  41. #define CONST_TWOPOW0 1
  42. #define CONST_TWOPOW1 2
  43. #define CONST_TWOPOW2 4
  44. #define CONST_TWOPOW3 8
  45. #define CONST_TWOPOW4 16
  46. #define CONST_TWOPOW5 32
  47. #define CONST_TWOPOW6 64
  48. #define CONST_TWOPOW7 128
  49. #define CONST_TWOPOW8 256
  50. #define CONST_TWOPOW9 512
  51. #define CONST_TWOPOW10 1024
  52. #define CONST_TWOPOW11 2048
  53. #define CONST_TWOPOW12 4096
  54. #define CONST_TWOPOW13 8192
  55. #define CONST_TWOPOW14 16384
  56. #define CONST_TWOPOW15 32768
  57. #define CONST_TWOPOW16 65536
  58. #define CONST_TWOPOW17 131072
  59. #define CONST_TWOPOW18 262144
  60. #define CONST_TWOPOW19 524288
  61. #define CONST_TWOPOW20 1048576
  62. #define CONST_TWOPOW21 2097152
  63. #define CONST_TWOPOW22 4194304
  64. #define CONST_TWOPOW23 8388608
  65. #define CONST_TWOPOW24 16777216
  66. #define CONST_TWOPOW25 33554432
  67. #define CONST_TWOPOW26 67108864
  68. #define CONST_TWOPOW27 134217728
  69. #define CONST_TWOPOW28 268435456
  70. #define CONST_TWOPOW29 536870912
  71. #define CONST_TWOPOW30 1073741824
  72. #define CONST_TWOPOW31 2147483648
  73. #define CONST_TWOPOW32 4294967296
  74. #define CONST_TWOPOW33 8589934592
  75. #define CONST_TWOPOW34 17179869184
  76. #define CONST_TWOPOW35 34359738368
  77. #define CONST_TWOPOW36 68719476736
  78. #define CONST_TWOPOW37 137438953472
  79. #define CONST_TWOPOW38 274877906944
  80. #define CONST_TWOPOW39 549755813888
  81. #define CONST_TWOPOW40 1099511627776
  82. #define CONST_TWOPOW41 2199023255552
  83. #define CONST_TWOPOW42 4398046511104
  84. #define CONST_TWOPOW43 8796093022208
  85. #define CONST_TWOPOW44 17592186044416
  86. #define CONST_TWOPOW45 35184372088832
  87. #define CONST_TWOPOW46 70368744177664
  88. #define CONST_TWOPOW47 140737488355328
  89. #define CONST_TWOPOW48 281474976710656
  90. #define CONST_TWOPOW49 562949953421312
  91. #define CONST_TWOPOW50 1125899906842624
  92. #define CONST_TWOPOW51 2251799813685248
  93. #define CONST_TWOPOW52 4503599627370496
  94. #define FLOAT_TWOPOW0 ((FLOAT)(CONST_TWOPOW0))
  95. #define FLOAT_TWOPOW1 ((FLOAT)(CONST_TWOPOW1))
  96. #define FLOAT_TWOPOW2 ((FLOAT)(CONST_TWOPOW2))
  97. #define FLOAT_TWOPOW3 ((FLOAT)(CONST_TWOPOW3))
  98. #define FLOAT_TWOPOW4 ((FLOAT)(CONST_TWOPOW4))
  99. #define FLOAT_TWOPOW5 ((FLOAT)(CONST_TWOPOW5))
  100. #define FLOAT_TWOPOW6 ((FLOAT)(CONST_TWOPOW6))
  101. #define FLOAT_TWOPOW7 ((FLOAT)(CONST_TWOPOW7))
  102. #define FLOAT_TWOPOW8 ((FLOAT)(CONST_TWOPOW8))
  103. #define FLOAT_TWOPOW9 ((FLOAT)(CONST_TWOPOW9))
  104. #define FLOAT_TWOPOW10 ((FLOAT)(CONST_TWOPOW10))
  105. #define FLOAT_TWOPOW11 ((FLOAT)(CONST_TWOPOW11))
  106. #define FLOAT_TWOPOW12 ((FLOAT)(CONST_TWOPOW12))
  107. #define FLOAT_TWOPOW13 ((FLOAT)(CONST_TWOPOW13))
  108. #define FLOAT_TWOPOW14 ((FLOAT)(CONST_TWOPOW14))
  109. #define FLOAT_TWOPOW15 ((FLOAT)(CONST_TWOPOW15))
  110. #define FLOAT_TWOPOW16 ((FLOAT)(CONST_TWOPOW16))
  111. #define FLOAT_TWOPOW17 ((FLOAT)(CONST_TWOPOW17))
  112. #define FLOAT_TWOPOW18 ((FLOAT)(CONST_TWOPOW18))
  113. #define FLOAT_TWOPOW19 ((FLOAT)(CONST_TWOPOW19))
  114. #define FLOAT_TWOPOW20 ((FLOAT)(CONST_TWOPOW20))
  115. #define FLOAT_TWOPOW21 ((FLOAT)(CONST_TWOPOW21))
  116. #define FLOAT_TWOPOW22 ((FLOAT)(CONST_TWOPOW22))
  117. #define FLOAT_TWOPOW23 ((FLOAT)(CONST_TWOPOW23))
  118. #define FLOAT_TWOPOW24 ((FLOAT)(CONST_TWOPOW24))
  119. #define FLOAT_TWOPOW25 ((FLOAT)(CONST_TWOPOW25))
  120. #define FLOAT_TWOPOW26 ((FLOAT)(CONST_TWOPOW26))
  121. #define FLOAT_TWOPOW27 ((FLOAT)(CONST_TWOPOW27))
  122. #define FLOAT_TWOPOW28 ((FLOAT)(CONST_TWOPOW28))
  123. #define FLOAT_TWOPOW29 ((FLOAT)(CONST_TWOPOW29))
  124. #define FLOAT_TWOPOW30 ((FLOAT)(CONST_TWOPOW30))
  125. #define FLOAT_TWOPOW31 ((FLOAT)(CONST_TWOPOW31))
  126. #define FLOAT_TWOPOW32 ((FLOAT)(CONST_TWOPOW32))
  127. #define FLOAT_TWOPOW33 ((FLOAT)(CONST_TWOPOW33))
  128. #define FLOAT_TWOPOW34 ((FLOAT)(CONST_TWOPOW34))
  129. #define FLOAT_TWOPOW35 ((FLOAT)(CONST_TWOPOW35))
  130. #define FLOAT_TWOPOW36 ((FLOAT)(CONST_TWOPOW36))
  131. #define FLOAT_TWOPOW37 ((FLOAT)(CONST_TWOPOW37))
  132. #define FLOAT_TWOPOW38 ((FLOAT)(CONST_TWOPOW38))
  133. #define FLOAT_TWOPOW39 ((FLOAT)(CONST_TWOPOW39))
  134. #define FLOAT_TWOPOW40 ((FLOAT)(CONST_TWOPOW40))
  135. #define FLOAT_TWOPOW41 ((FLOAT)(CONST_TWOPOW41))
  136. #define FLOAT_TWOPOW42 ((FLOAT)(CONST_TWOPOW42))
  137. #define FLOAT_TWOPOW43 ((FLOAT)(CONST_TWOPOW43))
  138. #define FLOAT_TWOPOW44 ((FLOAT)(CONST_TWOPOW44))
  139. #define FLOAT_TWOPOW45 ((FLOAT)(CONST_TWOPOW45))
  140. #define FLOAT_TWOPOW46 ((FLOAT)(CONST_TWOPOW46))
  141. #define FLOAT_TWOPOW47 ((FLOAT)(CONST_TWOPOW47))
  142. #define FLOAT_TWOPOW48 ((FLOAT)(CONST_TWOPOW48))
  143. #define FLOAT_TWOPOW49 ((FLOAT)(CONST_TWOPOW49))
  144. #define FLOAT_TWOPOW50 ((FLOAT)(CONST_TWOPOW50))
  145. #define FLOAT_TWOPOW51 ((FLOAT)(CONST_TWOPOW51))
  146. #define FLOAT_TWOPOW52 ((FLOAT)(CONST_TWOPOW52))
  147. // Values that are smaller than the named value by the smallest
  148. // representable amount. Since this depends on the type used
  149. // there is no CONST form.
  150. #define FLOAT_NEARTWOPOW31 ((FLOAT)2147483583)
  151. #define FLOAT_NEARTWOPOW32 ((FLOAT)4294967167)
  152. // Value close enough to zero to consider zero. This can't be too small
  153. // but it can't be too large. In other words, it's picked by guessing.
  154. #define FLOAT_NEARZERO (1e-5f)
  155. // General FP constants.
  156. #define FLOAT_E ((FLOAT)2.7182818284590452354)
  157. // Integer value of first exponent bit in a float. Provides a scaling factor
  158. // for exponent values extracted directly from float representation.
  159. #define FLOAT_EXPSCALE ((FLOAT)0x00800000)
  160. // Integer representation of 1.0f.
  161. #define INT32_FLOAT_ONE 0x3f800000
  162. #ifdef _X86_
  163. // All FP values are loaded from memory so declare them all as global
  164. // variables.
  165. extern FLOAT g_fE;
  166. extern FLOAT g_fZero;
  167. extern FLOAT g_fNearZero;
  168. extern FLOAT g_fHalf;
  169. extern FLOAT g_fp95;
  170. extern FLOAT g_fOne;
  171. extern FLOAT g_fOneMinusEps;
  172. extern FLOAT g_fExpScale;
  173. extern FLOAT g_fOoExpScale;
  174. extern FLOAT g_f255oTwoPow15;
  175. extern FLOAT g_fOo255;
  176. extern FLOAT g_fOo256;
  177. extern FLOAT g_fTwoPow7;
  178. extern FLOAT g_fTwoPow8;
  179. extern FLOAT g_fTwoPow11;
  180. extern FLOAT g_fTwoPow15;
  181. extern FLOAT g_fOoTwoPow15;
  182. extern FLOAT g_fTwoPow16;
  183. extern FLOAT g_fOoTwoPow16;
  184. extern FLOAT g_fTwoPow20;
  185. extern FLOAT g_fOoTwoPow20;
  186. extern FLOAT g_fTwoPow27;
  187. extern FLOAT g_fOoTwoPow27;
  188. extern FLOAT g_fTwoPow30;
  189. extern FLOAT g_fTwoPow31;
  190. extern FLOAT g_fNearTwoPow31;
  191. extern FLOAT g_fOoTwoPow31;
  192. extern FLOAT g_fOoNearTwoPow31;
  193. extern FLOAT g_fTwoPow32;
  194. extern FLOAT g_fNearTwoPow32;
  195. extern FLOAT g_fTwoPow39;
  196. extern FLOAT g_fTwoPow47;
  197. #else
  198. // Leave FP values as constants.
  199. #define g_fE FLOAT_E
  200. #define g_fNearZero FLOAT_NEARZERO
  201. #define g_fZero (0.0f)
  202. #define g_fHalf (0.5f)
  203. #define g_fp95 (0.95f)
  204. #define g_fOne (1.0f)
  205. #define g_fOneMinusEps (1.0f - FLT_EPSILON)
  206. #define g_fExpScale FLOAT_EXPSCALE
  207. #define g_fOoExpScale ((FLOAT)(1.0 / (double)FLOAT_EXPSCALE))
  208. #define g_f255oTwoPow15 ((FLOAT)(255.0 / (double)CONST_TWOPOW15))
  209. #define g_fOo255 ((FLOAT)(1.0 / 255.0))
  210. #define g_fOo256 ((FLOAT)(1.0 / 256.0))
  211. #define g_fTwoPow7 FLOAT_TWOPOW7
  212. #define g_fTwoPow8 FLOAT_TWOPOW8
  213. #define g_fTwoPow11 FLOAT_TWOPOW11
  214. #define g_fTwoPow15 FLOAT_TWOPOW15
  215. #define g_fOoTwoPow15 ((FLOAT)(1.0 / (double)CONST_TWOPOW15))
  216. #define g_fTwoPow16 FLOAT_TWOPOW16
  217. #define g_fOoTwoPow16 ((FLOAT)(1.0 / (double)CONST_TWOPOW16))
  218. #define g_fTwoPow20 FLOAT_TWOPOW20
  219. #define g_fOoTwoPow20 ((FLOAT)(1.0 / (double)CONST_TWOPOW20))
  220. #define g_fTwoPow27 FLOAT_TWOPOW27
  221. #define g_fOoTwoPow27 ((FLOAT)(1.0 / (double)CONST_TWOPOW27))
  222. #define g_fTwoPow30 FLOAT_TWOPOW30
  223. #define g_fTwoPow31 FLOAT_TWOPOW31
  224. #define g_fNearTwoPow31 FLOAT_NEARTWOPOW31
  225. #define g_fOoTwoPow31 ((FLOAT)(1.0 / (double)CONST_TWOPOW31))
  226. #define g_fOoNearTwoPow31 ((FLOAT)(1.0 / ((double)FLOAT_NEARTWOPOW31)))
  227. #define g_fTwoPow32 FLOAT_TWOPOW32
  228. #define g_fNearTwoPow32 FLOAT_NEARTWOPOW32
  229. #define g_fTwoPow39 FLOAT_TWOPOW39
  230. #define g_fTwoPow47 FLOAT_TWOPOW47
  231. #endif // _X86_
  232. //
  233. // Conversion tables.
  234. //
  235. // Takes an unsigned byte to a float in [0.0, 1.0]. 257'th entry is
  236. // also one to allow overflow.
  237. extern FLOAT g_fUInt8ToFloat[257];
  238. // Floating-point pinning values for float-int conversion.
  239. extern double g_dSnap[33];
  240. //
  241. // x86 FP control for optimized FTOI and single-precision divides.
  242. //
  243. #ifdef _X86_
  244. #define FPU_GET_MODE(uMode) \
  245. __asm fnstcw WORD PTR uMode
  246. #define FPU_SET_MODE(uMode) \
  247. __asm fldcw WORD PTR uMode
  248. #define FPU_SAFE_SET_MODE(uMode) \
  249. __asm fnclex \
  250. __asm fldcw WORD PTR uMode
  251. #define FPU_MODE_CHOP_ROUND(uMode) \
  252. ((uMode) | 0xc00)
  253. #define FPU_MODE_LOW_PRECISION(uMode) \
  254. ((uMode) & 0xfcff)
  255. #define FPU_MODE_MASK_EXCEPTIONS(uMode) \
  256. ((uMode) | 0x3f)
  257. #if DBG
  258. #define ASSERT_CHOP_ROUND() \
  259. { \
  260. WORD cw; \
  261. __asm fnstcw cw \
  262. DDASSERT((cw & 0xc00) == 0xc00); \
  263. }
  264. #else
  265. #define ASSERT_CHOP_ROUND()
  266. #endif // DBG
  267. #else
  268. // Initialize with zero to avoid use-before-set errors.
  269. #define FPU_GET_MODE(uMode) \
  270. ((uMode) = 0)
  271. #define FPU_SET_MODE(uMode)
  272. #define FPU_SAFE_SET_MODE(uMode)
  273. #define FPU_MODE_CHOP_ROUND(uMode) 0
  274. #define FPU_MODE_LOW_PRECISION(uMode) 0
  275. #define FPU_MODE_MASK_EXCEPTIONS(uMode) 0
  276. #define ASSERT_CHOP_ROUND()
  277. #endif // _X86_
  278. //
  279. // Single-precision FP functions.
  280. // May produce invalid results for exceptional or denormal values.
  281. // ATTENTION - Alpha exposes float math routines and they may be a small win.
  282. //
  283. #define COSF(fV) ((FLOAT)cos((double)(fV)))
  284. #define SINF(fV) ((FLOAT)sin((double)(fV)))
  285. #define SQRTF(fV) ((FLOAT)sqrt((double)(fV)))
  286. #define POWF(fV, fE) ((FLOAT)pow((double)(fV), (double)(fE)))
  287. // Approximate log and power functions using Jim Blinn's CG&A technique.
  288. // Only work for positive values.
  289. #ifdef POINTER_CASTING
  290. __inline FLOAT
  291. APPXLG2F(FLOAT f)
  292. {
  293. return (FLOAT)(ASINT32(f) - INT32_FLOAT_ONE) * g_fOoExpScale;
  294. }
  295. __inline FLOAT
  296. APPXPOW2F(FLOAT f)
  297. {
  298. INT32 i = (INT32)(f * g_fExpScale) + INT32_FLOAT_ONE;
  299. return ASFLOAT(i);
  300. }
  301. __inline FLOAT
  302. APPXINVF(FLOAT f)
  303. {
  304. INT32 i = (INT32_FLOAT_ONE << 1) - ASINT32(f);
  305. return ASFLOAT(i);
  306. }
  307. __inline FLOAT
  308. APPXSQRTF(FLOAT f)
  309. {
  310. INT32 i = (ASINT32(f) >> 1) + (INT32_FLOAT_ONE >> 1);
  311. return ASFLOAT(i);
  312. }
  313. __inline FLOAT
  314. APPXISQRTF(FLOAT f)
  315. {
  316. INT32 i = INT32_FLOAT_ONE + (INT32_FLOAT_ONE >> 1) - (ASINT32(f) >> 1);
  317. return ASFLOAT(i);
  318. }
  319. __inline FLOAT
  320. APPXPOWF(FLOAT f, FLOAT exp)
  321. {
  322. INT32 i = (INT32)(exp * (ASINT32(f) - INT32_FLOAT_ONE)) + INT32_FLOAT_ONE;
  323. return ASFLOAT(i);
  324. }
  325. #else
  326. __inline FLOAT
  327. APPXLG2F(FLOAT f)
  328. {
  329. FLOATINT32 fi;
  330. fi.f = f;
  331. return (FLOAT)(fi.i - INT32_FLOAT_ONE) * g_fOoExpScale;
  332. }
  333. __inline FLOAT
  334. APPXPOW2F(FLOAT f)
  335. {
  336. FLOATINT32 fi;
  337. fi.i = (INT32)(f * g_fExpScale) + INT32_FLOAT_ONE;
  338. return fi.f;
  339. }
  340. __inline FLOAT
  341. APPXINVF(FLOAT f)
  342. {
  343. FLOATINT32 fi;
  344. fi.f = f;
  345. fi.i = (INT32_FLOAT_ONE << 1) - fi.i;
  346. return fi.f;
  347. }
  348. __inline FLOAT
  349. APPXSQRTF(FLOAT f)
  350. {
  351. FLOATINT32 fi;
  352. fi.f = f;
  353. fi.i = (fi.i >> 1) + (INT32_FLOAT_ONE >> 1);
  354. return fi.f;
  355. }
  356. __inline FLOAT
  357. APPXISQRTF(FLOAT f)
  358. {
  359. FLOATINT32 fi;
  360. fi.f = f;
  361. fi.i = INT32_FLOAT_ONE + (INT32_FLOAT_ONE >> 1) - (fi.i >> 1);
  362. return fi.f;
  363. }
  364. __inline FLOAT
  365. APPXPOWF(FLOAT f, FLOAT exp)
  366. {
  367. FLOATINT32 fi;
  368. fi.f = f;
  369. fi.i = (INT32)(exp * (fi.i - INT32_FLOAT_ONE)) + INT32_FLOAT_ONE;
  370. return fi.f;
  371. }
  372. #endif
  373. #ifdef _X86_
  374. // Uses a table
  375. float __fastcall TableInvSqrt(float value);
  376. // Uses Jim Blinn's floating point trick
  377. float __fastcall JBInvSqrt(float value);
  378. #define ISQRTF(fV) TableInvSqrt(fV);
  379. #ifdef POINTER_CASTING
  380. // Strip sign bit in integer.
  381. __inline FLOAT
  382. ABSF(FLOAT f)
  383. {
  384. UINT32 i = ASUINT32(f) & 0x7fffffff;
  385. return ASFLOAT(i);
  386. }
  387. // Toggle sign bit in integer.
  388. __inline FLOAT
  389. NEGF(FLOAT f)
  390. {
  391. UINT32 i = ASUINT32(f) ^ 0x80000000;
  392. return ASFLOAT(i);
  393. }
  394. #else
  395. // Strip sign bit in integer.
  396. __inline FLOAT
  397. ABSF(FLOAT f)
  398. {
  399. FLOATINT32 fi;
  400. fi.f = f;
  401. fi.u &= 0x7fffffff;
  402. return fi.f;
  403. }
  404. // Toggle sign bit in integer.
  405. __inline FLOAT
  406. NEGF(FLOAT f)
  407. {
  408. FLOATINT32 fi;
  409. fi.f = f;
  410. fi.u ^= 0x80000000;
  411. return fi.f;
  412. }
  413. #endif // POINTER_CASTING
  414. // Requires chop rounding.
  415. __inline INT32
  416. SCALED_FRACTION(FLOAT f)
  417. {
  418. LARGE_INTEGER i;
  419. __asm
  420. {
  421. fld f
  422. fmul g_fTwoPow31
  423. fistp i
  424. }
  425. return i.LowPart;
  426. }
  427. // Requires chop rounding.
  428. __inline INT
  429. FTOI(FLOAT f)
  430. {
  431. LARGE_INTEGER i;
  432. __asm
  433. {
  434. fld f
  435. fistp i
  436. }
  437. return i.LowPart;
  438. }
  439. // Requires chop rounding.
  440. #define ICEILF(f) (FLOAT_LEZ(f) ? FTOI(f) : FTOI((f) + g_fOneMinusEps))
  441. #define CEILF(f) ((FLOAT)ICEILF(f))
  442. #define IFLOORF(f) (FLOAT_LTZ(f) ? FTOI((f) - g_fOneMinusEps) : FTOI(f))
  443. #define FLOORF(f) ((FLOAT)IFLOORF(f))
  444. #else // _X86_
  445. #define ISQRTF(fV) (1.0f / (FLOAT)sqrt((double)(fV)))
  446. #define ABSF(f) ((FLOAT)fabs((double)(f)))
  447. #define NEGF(f) (-(f))
  448. #define SCALED_FRACTION(f) ((INT32)((f) * g_fTwoPow31))
  449. #define FTOI(f) ((INT)(f))
  450. #define CEILF(f) ((FLOAT)ceil((double)(f)))
  451. #define ICEILF(f) ((INT)CEILF(f))
  452. #define FLOORF(f) ((FLOAT)floor((double)(f)))
  453. #define IFLOORF(f) ((INT)FLOORF(f))
  454. #endif // _X86_
  455. //
  456. // Overlapped divide support.
  457. //
  458. #ifdef _X86_
  459. // Starts a divide directly from memory. Result field is provided for
  460. // compatibility with non-x86 code that does the divide immediately.
  461. #define FLD_BEGIN_DIVIDE(Num, Den, Res) { __asm fld Num __asm fdiv Den }
  462. #define FLD_BEGIN_IDIVIDE(Num, Den, Res) { __asm fld Num __asm fidiv Den }
  463. // Store a divide result directly to memory.
  464. #define FSTP_END_DIVIDE(Res) { __asm fstp Res }
  465. #else // _X86_
  466. #define FLD_BEGIN_DIVIDE(Num, Den, Res) ((Res) = (Num) / (Den))
  467. #define FLD_BEGIN_IDIVIDE(Num, Den, Res) ((Res) = (Num) / (FLOAT)(Den))
  468. #define FSTP_END_DIVIDE(Res)
  469. #endif // _X86_
  470. //
  471. // Specialized FP comparison functions.
  472. //
  473. // On the x86, it's faster to do compares with an integer cast
  474. // than it is to do the fcom.
  475. //
  476. // The zero operations work for all normalized FP numbers, -0 included.
  477. //
  478. #ifdef _X86_
  479. #define FLOAT_CMP_POS(fa, op, fb) (ASINT32(fa) op ASINT32(fb))
  480. #define FLOAT_CMP_PONE(flt, op) (ASINT32(flt) op INT32_FLOAT_ONE)
  481. #ifdef POINTER_CASTING
  482. #define FLOAT_GTZ(flt) (ASINT32(flt) > 0)
  483. #define FLOAT_LTZ(flt) (ASUINT32(flt) > 0x80000000)
  484. #define FLOAT_GEZ(flt) (ASUINT32(flt) <= 0x80000000)
  485. #define FLOAT_LEZ(flt) (ASINT32(flt) <= 0)
  486. #define FLOAT_EQZ(flt) ((ASUINT32(flt) & 0x7fffffff) == 0)
  487. #define FLOAT_NEZ(flt) ((ASUINT32(flt) & 0x7fffffff) != 0)
  488. #else
  489. __inline int FLOAT_GTZ(FLOAT f)
  490. {
  491. FLOATINT32 fi;
  492. fi.f = f;
  493. return fi.i > 0;
  494. }
  495. __inline int FLOAT_LTZ(FLOAT f)
  496. {
  497. FLOATINT32 fi;
  498. fi.f = f;
  499. return fi.u > 0x80000000;
  500. }
  501. __inline int FLOAT_GEZ(FLOAT f)
  502. {
  503. FLOATINT32 fi;
  504. fi.f = f;
  505. return fi.u <= 0x80000000;
  506. }
  507. __inline int FLOAT_LEZ(FLOAT f)
  508. {
  509. FLOATINT32 fi;
  510. fi.f = f;
  511. return fi.i <= 0;
  512. }
  513. __inline int FLOAT_EQZ(FLOAT f)
  514. {
  515. FLOATINT32 fi;
  516. fi.f = f;
  517. return (fi.u & 0x7fffffff) == 0;
  518. }
  519. __inline int FLOAT_NEZ(FLOAT f)
  520. {
  521. FLOATINT32 fi;
  522. fi.f = f;
  523. return (fi.u & 0x7fffffff) != 0;
  524. }
  525. #endif // POINTER_CASTING
  526. #else
  527. #define FLOAT_GTZ(flt) ((flt) > g_fZero)
  528. #define FLOAT_LTZ(flt) ((flt) < g_fZero)
  529. #define FLOAT_GEZ(flt) ((flt) >= g_fZero)
  530. #define FLOAT_LEZ(flt) ((flt) <= g_fZero)
  531. #define FLOAT_EQZ(flt) ((flt) == g_fZero)
  532. #define FLOAT_NEZ(flt) ((flt) != g_fZero)
  533. #define FLOAT_CMP_POS(fa, op, fb) ((fa) op (fb))
  534. #define FLOAT_CMP_PONE(flt, op) ((flt) op g_fOne)
  535. #endif // _X86_
  536. #ifdef __cplusplus
  537. }
  538. #endif
  539. #endif // #ifndef _D3DFLT_H_