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
init_sqrt(void)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
gl_sqrt(float x)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 */
gl_init_math(void)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