Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
opcodeqsqrt.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2000 by Andrew Zabolotny (Intel version)
3  Copyright (C) 2002 by Matthew Reda <reda@mac.com> (PowerPC version)
4  Fast computation of sqrt(x) and 1/sqrt(x)
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public
17  License along with this library; if not, write to the Free
18  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20 
21 // Uncomment the following line to define CS_NO_QSQRT if you experience
22 // mysterious problems with CS which you think are related to this
23 // version of sqrt not behaving properly. If you find something like
24 // that I'd like to be notified of this so we can make sure this really
25 // is the problem.
26 //#define CS_NO_QSQRT
27 
28 #ifndef __QSQRT_H__
29 #define __QSQRT_H__
30 
31 
32 #if (!defined (CS_NO_QSQRT)) && defined (CS_PROCESSOR_X86) && defined (CS_COMPILER_GCC)
33 #include "Stdafx.h"
34 /*
35  NB: Single-precision floating-point format (32 bits):
36  SEEEEEEE.EMMMMMMM.MMMMMMMM.MMMMMMMM
37  S: Sign (0 - positive, 1 - negative)
38  E: Exponent (plus 127, 8 bits)
39  M: Mantissa (23 bits)
40 */
41 
51 static inline float qsqrt (float x)
52 {
53  float ret;
54 
55 // Original C++ formulae:
56 // float tmp = x;
57 // *((unsigned *)&tmp) = (0xbe6f0000 - *((unsigned *)&tmp)) >> 1;
58 // double h = x * 0.5;
59 // double a = tmp;
60 // a *= 1.5 - a * a * h;
61 // a *= 1.5 - a * a * h;
62 // return a * x;
63 
64  __asm__ (
65  "flds %1\n" // x
66  "movl $0xbe6f0000,%%eax\n"
67  "subl %1,%%eax\n"
68  "shrl $1,%%eax\n"
69  "movl %%eax,%1\n"
70  "flds %2\n" // x 0.5
71  "fmul %%st(1)\n" // x h
72  "flds %3\n" // x h 1.5
73  "flds %1\n" // x h 1.5 a
74  "fld %%st\n" // x h 1.5 a a
75  "fmul %%st\n" // x h 1.5 a a*a
76  "fmul %%st(3)\n" // x h 1.5 a a*a*h
77  "fsubr %%st(2)\n" // x h 1.5 a 1.5-a*a*h
78  "fmulp %%st(1)\n" // x h 1.5 a
79  "fld %%st\n" // x h 1.5 a a
80  "fmul %%st\n" // x h 1.5 a a*a
81  "fmulp %%st(3)\n" // x a*a*h 1.5 a
82  "fxch\n" // x a*a*h a 1.5
83  "fsubp %%st,%%st(2)\n" // x 1.5-a*a*h a
84  "fmulp %%st(1)\n" // x a
85  "fmulp %%st(1)\n" // a
86  : "=&t" (ret), "+m" (x) : "m" (0.5F), "m" (1.5F)
87  : "eax", "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)"
88  );
89  return ret;
90 }
91 
99 static inline float qisqrt (float x)
100 {
101  float ret;
102  __asm__ (
103  "flds %1\n" // x
104  "movl $0xbe6f0000,%%eax\n"
105  "subl %1,%%eax\n"
106  "shrl $1,%%eax\n"
107  "movl %%eax,%1\n"
108  "flds %2\n" // x 0.5
109  "fmulp %%st(1)\n" // h
110  "flds %3\n" // h 1.5
111  "flds %1\n" // h 1.5 a
112  "fld %%st\n" // h 1.5 a a
113  "fmul %%st\n" // h 1.5 a a*a
114  "fmul %%st(3)\n" // h 1.5 a a*a*h
115  "fsubr %%st(2)\n" // h 1.5 a 1.5-a*a*h
116  "fmulp %%st(1)\n" // h 1.5 a
117  "fld %%st\n" // h 1.5 a a
118  "fmul %%st\n" // h 1.5 a a*a
119  "fmulp %%st(3)\n" // a*a*h 1.5 a
120  "fxch\n" // a*a*h a 1.5
121  "fsubp %%st,%%st(2)\n" // 1.5-a*a*h a
122  "fmulp %%st(1)\n" // a
123  : "=t" (ret), "+m" (x) : "m" (0.5F), "m" (1.5F)
124  : "eax", "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)"
125  );
126  return ret;
127 }
128 
129 #elif (!defined (CS_NO_QSQRT)) && defined (PROC_POWERPC) && defined (CS_COMPILER_GCC)
130 
138 static inline float qsqrt(float x)
139 {
140  float y0 = 0.0;
141 
142  if (x != 0.0)
143  {
144  float x0 = x * 0.5f;
145 
146  asm ("frsqrte %0,%1" : "=f" (y0) : "f" (x));
147 
148  y0 = y0 * (1.5f - x0 * y0 * y0);
149  y0 = (y0 * (1.5f - x0 * y0 * y0)) * x;
150  };
151 
152  return y0;
153 };
154 
159 static inline float qisqrt(float x)
160 {
161  float x0 = x * 0.5f;
162  float y0;
163  asm ("frsqrte %0,%1" : "=f" (y0) : "f" (x));
164 
165  y0 = y0 * (1.5f - x0 * y0 * y0);
166  y0 = y0 * (1.5f - x0 * y0 * y0);
167 
168  return y0;
169 };
170 
171 #else
172 
173 #include <math.h>
174 #define qsqrt(x) sqrt(x)
175 #define qisqrt(x) (1.0/sqrt(x))
176 
177 #endif
178 
179 #endif // __QSQRT_H__