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