Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre_src_v1-9-0/OgreMain/include/asm_math.h @ 148

Last change on this file since 148 was 148, checked in by patricwi, 6 years ago

Added new dependencies for ogre1.9 and cegui0.8

File size: 8.1 KB
Line 
1#ifndef __asm_math_H__
2#define __asm_math_H__
3
4#include "OgrePrerequisites.h"
5#include "OgrePlatformInformation.h"
6
7#if  OGRE_COMPILER == OGRE_COMPILER_MSVC
8#  pragma warning (push)
9// disable "instruction may be inaccurate on some Pentiums"
10#  pragma warning (disable : 4725)
11#endif
12namespace Ogre
13{
14
15/*=============================================================================
16 ASM math routines posted by davepermen et al on flipcode forums
17=============================================================================*/
18const float pi = 4.0f * atan( 1.0f );
19const float half_pi = 0.5f * pi;
20
21/*=============================================================================
22        NO EXPLICIT RETURN REQUIRED FROM THESE METHODS!!
23=============================================================================*/
24#if  OGRE_COMPILER == OGRE_COMPILER_MSVC && OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86
25#       pragma warning( push )
26#       pragma warning( disable: 4035 )
27#endif
28
29float asm_arccos( float r ) {
30    // return half_pi + arctan( r / -sqr( 1.f - r * r ) );
31       
32#if  OGRE_COMPILER == OGRE_COMPILER_MSVC &&  OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86
33
34    float asm_one = 1.f;
35    float asm_half_pi = half_pi;
36    __asm {
37        fld r // r0 = r
38        fld r // r1 = r0, r0 = r
39        fmul r // r0 = r0 * r
40        fsubr asm_one // r0 = r0 - 1.f
41        fsqrt // r0 = sqrtf( r0 )
42        fchs // r0 = - r0
43        fdiv // r0 = r1 / r0
44        fld1 // {{ r0 = atan( r0 )
45        fpatan // }}
46        fadd asm_half_pi // r0 = r0 + pi / 2
47    } // returns r0
48
49#else
50
51        return float( acos( r ) );
52
53#endif
54}
55
56float asm_arcsin( float r ) {
57    // return arctan( r / sqr( 1.f - r * r ) );
58
59#if  OGRE_COMPILER == OGRE_COMPILER_MSVC &&  OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86
60
61    const float asm_one = 1.f;
62    __asm {
63        fld r // r0 = r
64        fld r // r1 = r0, r0 = r
65        fmul r // r0 = r0 * r
66        fsubr asm_one // r0 = r0 - 1.f
67        fsqrt // r0 = sqrtf( r0 )
68        fdiv // r0 = r1 / r0
69        fld1 // {{ r0 = atan( r0 )
70        fpatan // }}
71    } // returns r0
72
73#else
74
75        return float( asin( r ) );
76
77#endif
78
79}
80
81float asm_arctan( float r ) {
82
83#if  OGRE_COMPILER == OGRE_COMPILER_MSVC &&  OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86
84
85    __asm {
86        fld r // r0 = r
87        fld1 // {{ r0 = atan( r0 )
88        fpatan // }}
89    } // returns r0
90
91#else
92
93        return float( atan( r ) );
94
95#endif
96
97}
98
99float asm_sin( float r ) {
100
101#if  OGRE_COMPILER == OGRE_COMPILER_MSVC &&  OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86
102
103    __asm {
104        fld r // r0 = r
105        fsin // r0 = sinf( r0 )
106    } // returns r0
107
108#else
109
110        return sin( r );
111
112#endif
113
114}
115
116float asm_cos( float r ) {
117
118#if  OGRE_COMPILER == OGRE_COMPILER_MSVC &&  OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86
119
120    __asm {
121        fld r // r0 = r
122        fcos // r0 = cosf( r0 )
123    } // returns r0
124
125#else
126       
127        return cos( r );
128
129#endif
130}
131
132float asm_tan( float r ) {
133
134#if  OGRE_COMPILER == OGRE_COMPILER_MSVC &&  OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86
135
136    // return sin( r ) / cos( r );
137    __asm {
138        fld r // r0 = r
139        fsin // r0 = sinf( r0 )
140        fld r // r1 = r0, r0 = r
141        fcos // r0 = cosf( r0 )
142        fdiv // r0 = r1 / r0
143    } // returns r0
144
145#else
146       
147        return tan( r );
148
149#endif
150}
151
152// returns a for a * a = r
153float asm_sqrt( float r )
154{
155#if  OGRE_COMPILER == OGRE_COMPILER_MSVC &&  OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86
156
157    __asm {
158        fld r // r0 = r
159        fsqrt // r0 = sqrtf( r0 )
160    } // returns r0
161
162#else
163
164        return sqrt( r );
165
166#endif
167}
168
169// returns 1 / a for a * a = r
170// -- Use this for Vector normalisation!!!
171float asm_rsq( float r )
172{
173#if  OGRE_COMPILER == OGRE_COMPILER_MSVC &&  OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86
174
175    __asm {
176        fld1 // r0 = 1.f
177        fld r // r1 = r0, r0 = r
178        fsqrt // r0 = sqrtf( r0 )
179        fdiv // r0 = r1 / r0
180    } // returns r0
181
182#else
183
184        return 1. / sqrt( r );
185
186#endif
187}
188
189// returns 1 / a for a * a = r
190// Another version
191float apx_rsq( float r ) {
192
193#if  OGRE_COMPILER == OGRE_COMPILER_MSVC &&  OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86
194
195    const float asm_dot5 = 0.5f;
196    const float asm_1dot5 = 1.5f;
197
198    __asm {
199        fld r // r0 = r
200        fmul asm_dot5 // r0 = r0 * .5f
201        mov eax, r // eax = r
202        shr eax, 0x1 // eax = eax >> 1
203        neg eax // eax = -eax
204        add eax, 0x5F400000 // eax = eax & MAGICAL NUMBER
205        mov r, eax // r = eax
206        fmul r // r0 = r0 * r
207        fmul r // r0 = r0 * r
208        fsubr asm_1dot5 // r0 = 1.5f - r0
209        fmul r // r0 = r0 * r
210    } // returns r0
211
212#else
213
214        return 1. / sqrt( r );
215
216#endif
217}
218
219/* very MS-specific, commented out for now
220   Finally the best InvSqrt implementation?
221   Use for vector normalisation instead of 1/length() * x,y,z
222*/
223#if  OGRE_COMPILER == OGRE_COMPILER_MSVC &&  OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86
224
225__declspec(naked) float __fastcall InvSqrt(float fValue)
226{
227    __asm
228    {
229        mov        eax, 0be6eb508h
230        mov        dword ptr[esp-12],03fc00000h
231        sub        eax, dword ptr[esp + 4]
232        sub        dword ptr[esp+4], 800000h
233        shr        eax, 1
234        mov        dword ptr[esp -  8], eax
235
236        fld        dword ptr[esp -  8]
237        fmul    st, st
238        fld        dword ptr[esp -  8]
239        fxch    st(1)
240        fmul    dword ptr[esp +  4]
241        fld        dword ptr[esp - 12]
242        fld        st(0)
243        fsub    st,st(2)
244
245        fld        st(1)
246        fxch    st(1)
247        fmul    st(3),st
248        fmul    st(3),st
249        fmulp    st(4),st
250        fsub    st,st(2)
251
252        fmul    st(2),st
253        fmul    st(3),st
254        fmulp    st(2),st
255        fxch    st(1)
256        fsubp    st(1),st
257
258        fmulp    st(1), st
259        ret 4
260    }
261}
262
263#endif
264
265// returns a random number
266FORCEINLINE float asm_rand()
267{
268
269#if  OGRE_COMPILER == OGRE_COMPILER_MSVC &&  OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86
270  #if 0
271    #if OGRE_COMP_VER >= 1300
272
273        static unsigned __int64 q = time( NULL );
274
275        _asm {
276                movq mm0, q
277
278                // do the magic MMX thing
279                pshufw mm1, mm0, 0x1E
280                paddd mm0, mm1
281
282                // move to integer memory location and free MMX
283                movq q, mm0
284                emms
285        }
286
287        return float( q );
288    #endif
289  #else
290    // VC6 does not support pshufw
291    return float( rand() );
292  #endif
293#else
294    // GCC etc
295
296        return float( rand() );
297
298#endif
299}
300
301// returns the maximum random number
302FORCEINLINE float asm_rand_max()
303{
304
305#if  OGRE_COMPILER == OGRE_COMPILER_MSVC &&  OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86
306  #if 0
307    #if OGRE_COMP_VER >= 1300
308
309        return (std::numeric_limits< unsigned __int64 >::max)();
310        return 9223372036854775807.0f;
311    #endif
312  #else
313    // VC6 does not support unsigned __int64
314    return float( RAND_MAX );
315  #endif
316
317#else
318    // GCC etc
319        return float( RAND_MAX );
320
321#endif
322}
323
324// returns log2( r ) / log2( e )
325float asm_ln( float r ) {   
326
327#if  OGRE_COMPILER == OGRE_COMPILER_MSVC &&  OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86
328
329    const float asm_1_div_log2_e = .693147180559f;
330    const float asm_neg1_div_3 = -.33333333333333333333333333333f;
331    const float asm_neg2_div_3 = -.66666666666666666666666666667f;
332    const float asm_2 = 2.f;
333
334    int log_2 = 0;
335
336    __asm {
337        // log_2 = ( ( r >> 0x17 ) & 0xFF ) - 0x80;
338        mov eax, r
339        sar eax, 0x17
340        and eax, 0xFF
341        sub eax, 0x80
342        mov log_2, eax
343
344        // r = ( r & 0x807fffff ) + 0x3f800000;
345        mov ebx, r
346        and ebx, 0x807FFFFF
347        add ebx, 0x3F800000
348        mov r, ebx
349
350        // r = ( asm_neg1_div_3 * r + asm_2 ) * r + asm_neg2_div_3;   // (1)
351        fld r
352        fmul asm_neg1_div_3
353        fadd asm_2
354        fmul r
355        fadd asm_neg2_div_3
356        fild log_2
357        fadd
358        fmul asm_1_div_log2_e
359    }
360
361#else
362
363        return log( r );
364
365#endif
366}
367
368#if  OGRE_COMPILER == OGRE_COMPILER_MSVC &&  OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86
369#       pragma warning( pop )
370#endif
371} // namespace
372
373#if  OGRE_COMPILER == OGRE_COMPILER_MSVC
374#  pragma warning (pop)
375#endif
376
377#endif
Note: See TracBrowser for help on using the repository browser.