xref: /reactos/dll/opengl/mesa/mmath.c (revision 7eead935)
1 /* $Id: mmath.c,v 1.3 1997/07/24 01:23:16 brianp Exp $ */
2 
3 /*
4  * Mesa 3-D graphics library
5  * Version:  2.4
6  * Copyright (C) 1995-1997  Brian Paul
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 
24 /*
25  * $Log: mmath.c,v $
26  * Revision 1.3  1997/07/24 01:23:16  brianp
27  * changed precompiled header symbol from PCH to PC_HEADER
28  *
29  * Revision 1.2  1997/05/28 03:25:43  brianp
30  * added precompiled header (PCH) support
31  *
32  * Revision 1.1  1997/05/01 01:41:54  brianp
33  * Initial revision
34  *
35  */
36 
37 
38 #ifdef PC_HEADER
39 #include "all.h"
40 #else
41 #include "GL/gl.h"
42 #include "mmath.h"
43 #endif
44 
45 
46 
47 /*
48  * A High Speed, Low Precision Square Root
49  * by Paul Lalonde and Robert Dawson
50  * from "Graphics Gems", Academic Press, 1990
51  */
52 
53 /*
54  * SPARC implementation of a fast square root by table
55  * lookup.
56  * SPARC floating point format is as follows:
57  *
58  * BIT 31 	30 	23 	22 	0
59  *     sign	exponent	mantissa
60  */
61 static short sqrttab[0x100];    /* declare table of square roots */
62 
63 static void init_sqrt(void)
64 {
65 #ifdef FAST_MATH
66    unsigned short i;
67    float f;
68    unsigned int *fi = (unsigned int *)&f;
69                                 /* to access the bits of a float in  */
70                                 /* C quickly we must misuse pointers */
71 
72    for(i=0; i<= 0x7f; i++) {
73       *fi = 0;
74 
75       /*
76        * Build a float with the bit pattern i as mantissa
77        * and an exponent of 0, stored as 127
78        */
79 
80       *fi = (i << 16) | (127 << 23);
81       f = sqrt(f);
82 
83       /*
84        * Take the square root then strip the first 7 bits of
85        * the mantissa into the table
86        */
87 
88       sqrttab[i] = (*fi & 0x7fffff) >> 16;
89 
90       /*
91        * Repeat the process, this time with an exponent of
92        * 1, stored as 128
93        */
94 
95       *fi = 0;
96       *fi = (i << 16) | (128 << 23);
97       f = sqrt(f);
98       sqrttab[i+0x80] = (*fi & 0x7fffff) >> 16;
99    }
100 #endif /*FAST_MATH*/
101 }
102 
103 
104 float gl_sqrt( float x )
105 {
106 #ifdef FAST_MATH
107    unsigned int *num = (unsigned int *)&x;
108                                 /* to access the bits of a float in C
109                                  * we must misuse pointers */
110 
111    short e;                     /* the exponent */
112    if (x == 0.0F) return 0.0F;  /* check for square root of 0 */
113    e = (*num >> 23) - 127;      /* get the exponent - on a SPARC the */
114                                 /* exponent is stored with 127 added */
115    *num &= 0x7fffff;            /* leave only the mantissa */
116    if (e & 0x01) *num |= 0x800000;
117                                 /* the exponent is odd so we have to */
118                                 /* look it up in the second half of  */
119                                 /* the lookup table, so we set the   */
120                                 /* high bit                                */
121    e >>= 1;                     /* divide the exponent by two */
122                                 /* note that in C the shift */
123                                 /* operators are sign preserving */
124                                 /* for signed operands */
125    /* Do the table lookup, based on the quaternary mantissa,
126     * then reconstruct the result back into a float
127     */
128    *num = ((sqrttab[*num >> 16]) << 16) | ((e + 127) << 23);
129    return x;
130 #else
131    return sqrt(x);
132 #endif
133 }
134 
135 
136 
137 /*
138  * Initialize tables, etc for fast math functions.
139  */
140 void gl_init_math(void)
141 {
142    static GLboolean initialized = GL_FALSE;
143 
144    if (!initialized) {
145       init_sqrt();
146 
147 
148       initialized = GL_TRUE;
149    }
150 }
151