sse/floatInVec.h

Go to the documentation of this file.
00001 /*
00002    Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.
00003    All rights reserved.
00004 
00005    Redistribution and use in source and binary forms,
00006    with or without modification, are permitted provided that the
00007    following conditions are met:
00008     * Redistributions of source code must retain the above copyright
00009       notice, this list of conditions and the following disclaimer.
00010     * Redistributions in binary form must reproduce the above copyright
00011       notice, this list of conditions and the following disclaimer in the
00012       documentation and/or other materials provided with the distribution.
00013     * Neither the name of the Sony Computer Entertainment Inc nor the names
00014       of its contributors may be used to endorse or promote products derived
00015       from this software without specific prior written permission.
00016 
00017    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027    POSSIBILITY OF SUCH DAMAGE.
00028 */
00029 
00030 #ifndef _FLOATINVEC_H
00031 #define _FLOATINVEC_H
00032 
00033 #include <math.h>
00034 #include <xmmintrin.h>
00035 
00036 namespace Vectormath {
00037 
00038 class boolInVec;
00039 
00040 //--------------------------------------------------------------------------------------------------
00041 // floatInVec class
00042 //
00043 
00044 class floatInVec
00045 {
00046     private:
00047         __m128 mData;
00048 
00049     public:
00050         inline floatInVec(__m128 vec);
00051 
00052         inline floatInVec() {}
00053 
00054         // matches standard type conversions
00055         //
00056         inline floatInVec(const boolInVec &vec);
00057 
00058         // construct from a slot of __m128
00059         //
00060         inline floatInVec(__m128 vec, int slot);
00061         
00062         // explicit cast from float
00063         //
00064         explicit inline floatInVec(float scalar);
00065 
00066 #ifdef _VECTORMATH_NO_SCALAR_CAST
00067         // explicit cast to float
00068         // 
00069         inline float getAsFloat() const;
00070 #else
00071         // implicit cast to float
00072         //
00073         inline operator float() const;
00074 #endif
00075 
00076         // get vector data
00077         // float value is splatted across all word slots of vector
00078         //
00079         inline __m128 get128() const;
00080 
00081         // operators
00082         // 
00083         inline const floatInVec operator ++ (int);
00084         inline const floatInVec operator -- (int);
00085         inline floatInVec& operator ++ ();
00086         inline floatInVec& operator -- ();
00087         inline const floatInVec operator - () const;
00088         inline floatInVec& operator = (const floatInVec &vec);
00089         inline floatInVec& operator *= (const floatInVec &vec);
00090         inline floatInVec& operator /= (const floatInVec &vec);
00091         inline floatInVec& operator += (const floatInVec &vec);
00092         inline floatInVec& operator -= (const floatInVec &vec);
00093 
00094         // friend functions
00095         //
00096         friend inline const floatInVec operator * (const floatInVec &vec0, const floatInVec &vec1);
00097         friend inline const floatInVec operator / (const floatInVec &vec0, const floatInVec &vec1);
00098         friend inline const floatInVec operator + (const floatInVec &vec0, const floatInVec &vec1);
00099         friend inline const floatInVec operator - (const floatInVec &vec0, const floatInVec &vec1);
00100         friend inline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, boolInVec select_vec1);
00101 };
00102 
00103 //--------------------------------------------------------------------------------------------------
00104 // floatInVec functions
00105 //
00106 
00107 // operators
00108 // 
00109 inline const floatInVec operator * (const floatInVec &vec0, const floatInVec &vec1);
00110 inline const floatInVec operator / (const floatInVec &vec0, const floatInVec &vec1);
00111 inline const floatInVec operator + (const floatInVec &vec0, const floatInVec &vec1);
00112 inline const floatInVec operator - (const floatInVec &vec0, const floatInVec &vec1);
00113 inline const boolInVec operator < (const floatInVec &vec0, const floatInVec &vec1);
00114 inline const boolInVec operator <= (const floatInVec &vec0, const floatInVec &vec1);
00115 inline const boolInVec operator > (const floatInVec &vec0, const floatInVec &vec1);
00116 inline const boolInVec operator >= (const floatInVec &vec0, const floatInVec &vec1);
00117 inline const boolInVec operator == (const floatInVec &vec0, const floatInVec &vec1);
00118 inline const boolInVec operator != (const floatInVec &vec0, const floatInVec &vec1);
00119 
00120 // select between vec0 and vec1 using boolInVec.
00121 // false selects vec0, true selects vec1
00122 //
00123 inline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, const boolInVec &select_vec1);
00124 
00125 } // namespace Vectormath
00126 
00127 //--------------------------------------------------------------------------------------------------
00128 // floatInVec implementation
00129 //
00130 
00131 #include "boolInVec.h"
00132 
00133 namespace Vectormath {
00134 
00135 inline
00136 floatInVec::floatInVec(__m128 vec)
00137 {
00138     mData = vec;
00139 }
00140 
00141 inline
00142 floatInVec::floatInVec(const boolInVec &vec)
00143 {
00144         mData = vec_sel(_mm_setzero_ps(), _mm_set1_ps(1.0f), vec.get128());
00145 }
00146 
00147 inline
00148 floatInVec::floatInVec(__m128 vec, int slot)
00149 {
00150         SSEFloat v;
00151         v.m128 = vec;
00152         mData = _mm_set1_ps(v.f[slot]);
00153 }
00154 
00155 inline
00156 floatInVec::floatInVec(float scalar)
00157 {
00158         mData = _mm_set1_ps(scalar);
00159 }
00160 
00161 #ifdef _VECTORMATH_NO_SCALAR_CAST
00162 inline
00163 float
00164 floatInVec::getAsFloat() const
00165 #else
00166 inline
00167 floatInVec::operator float() const
00168 #endif
00169 {
00170     return *((float *)&mData);
00171 }
00172 
00173 inline
00174 __m128
00175 floatInVec::get128() const
00176 {
00177     return mData;
00178 }
00179 
00180 inline
00181 const floatInVec
00182 floatInVec::operator ++ (int)
00183 {
00184     __m128 olddata = mData;
00185     operator ++();
00186     return floatInVec(olddata);
00187 }
00188 
00189 inline
00190 const floatInVec
00191 floatInVec::operator -- (int)
00192 {
00193     __m128 olddata = mData;
00194     operator --();
00195     return floatInVec(olddata);
00196 }
00197 
00198 inline
00199 floatInVec&
00200 floatInVec::operator ++ ()
00201 {
00202     *this += floatInVec(_mm_set1_ps(1.0f));
00203     return *this;
00204 }
00205 
00206 inline
00207 floatInVec&
00208 floatInVec::operator -- ()
00209 {
00210     *this -= floatInVec(_mm_set1_ps(1.0f));
00211     return *this;
00212 }
00213 
00214 inline
00215 const floatInVec
00216 floatInVec::operator - () const
00217 {
00218     return floatInVec(_mm_sub_ps(_mm_setzero_ps(), mData));
00219 }
00220 
00221 inline
00222 floatInVec&
00223 floatInVec::operator = (const floatInVec &vec)
00224 {
00225     mData = vec.mData;
00226     return *this;
00227 }
00228 
00229 inline
00230 floatInVec&
00231 floatInVec::operator *= (const floatInVec &vec)
00232 {
00233     *this = *this * vec;
00234     return *this;
00235 }
00236 
00237 inline
00238 floatInVec&
00239 floatInVec::operator /= (const floatInVec &vec)
00240 {
00241     *this = *this / vec;
00242     return *this;
00243 }
00244 
00245 inline
00246 floatInVec&
00247 floatInVec::operator += (const floatInVec &vec)
00248 {
00249     *this = *this + vec;
00250     return *this;
00251 }
00252 
00253 inline
00254 floatInVec&
00255 floatInVec::operator -= (const floatInVec &vec)
00256 {
00257     *this = *this - vec;
00258     return *this;
00259 }
00260 
00261 inline
00262 const floatInVec
00263 operator * (const floatInVec &vec0, const floatInVec &vec1)
00264 {
00265     return floatInVec(_mm_mul_ps(vec0.get128(), vec1.get128()));
00266 }
00267 
00268 inline
00269 const floatInVec
00270 operator / (const floatInVec &num, const floatInVec &den)
00271 {
00272     return floatInVec(_mm_div_ps(num.get128(), den.get128()));
00273 }
00274 
00275 inline
00276 const floatInVec
00277 operator + (const floatInVec &vec0, const floatInVec &vec1)
00278 {
00279     return floatInVec(_mm_add_ps(vec0.get128(), vec1.get128()));
00280 }
00281 
00282 inline
00283 const floatInVec
00284 operator - (const floatInVec &vec0, const floatInVec &vec1)
00285 {
00286     return floatInVec(_mm_sub_ps(vec0.get128(), vec1.get128()));
00287 }
00288 
00289 inline
00290 const boolInVec
00291 operator < (const floatInVec &vec0, const floatInVec &vec1)
00292 {
00293     return boolInVec(_mm_cmpgt_ps(vec1.get128(), vec0.get128()));
00294 }
00295 
00296 inline
00297 const boolInVec
00298 operator <= (const floatInVec &vec0, const floatInVec &vec1)
00299 {
00300     return boolInVec(_mm_cmpge_ps(vec1.get128(), vec0.get128()));
00301 }
00302 
00303 inline
00304 const boolInVec
00305 operator > (const floatInVec &vec0, const floatInVec &vec1)
00306 {
00307     return boolInVec(_mm_cmpgt_ps(vec0.get128(), vec1.get128()));
00308 }
00309 
00310 inline
00311 const boolInVec
00312 operator >= (const floatInVec &vec0, const floatInVec &vec1)
00313 {
00314     return boolInVec(_mm_cmpge_ps(vec0.get128(), vec1.get128()));
00315 }
00316 
00317 inline
00318 const boolInVec
00319 operator == (const floatInVec &vec0, const floatInVec &vec1)
00320 {
00321     return boolInVec(_mm_cmpeq_ps(vec0.get128(), vec1.get128()));
00322 }
00323 
00324 inline
00325 const boolInVec
00326 operator != (const floatInVec &vec0, const floatInVec &vec1)
00327 {
00328     return boolInVec(_mm_cmpneq_ps(vec0.get128(), vec1.get128()));
00329 }
00330     
00331 inline
00332 const floatInVec
00333 select(const floatInVec &vec0, const floatInVec &vec1, const boolInVec &select_vec1)
00334 {
00335     return floatInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128()));
00336 }
00337 
00338 } // namespace Vectormath
00339 
00340 #endif // floatInVec_h