softfloatwrapper.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 497 行 · 第 1/2 页
CPP
497 行
// avoid invalid memory access: must return a 16-bytes value from a 10-byte type
// do it this way, by declaring the 16-byte on the stack
long double holder;
// And use that space for the result using the softfloat memory bit pattern equivalence property
*reinterpret_cast<floatx80*>(&holder) = SF_PREPEND(_to_floatx80)(value);
return holder;
}
// big endian needs address modification, but for what architecture?
#elif __FLOAT_WORD_ORDER == 4321
#warning You are using a completely UNTESTED new architecture. Please check that the 16-byte long double containing a 10-byte float is properly aligned in memory so that softfloat may correctly read the bit pattern. If this works for you, remove this warning and please consider sending a patch!
static inline SF_TYPE
convert_from_float(const long double a_float) {
return SF_APPEND(floatx80_to_)(*reinterpret_cast<const floatx80*>(reinterpret_cast<const char*>(&a_float)+6));
}
static inline long double convert_to_float(SF_TYPE value) {
// avoid invalid memory access: must return a 12-bytes value from a 10-byte type
// do it this way, by declaring the 12-byte on the stack
long double holder;
// And use that space for the result using the softfloat memory bit pattern equivalence property
*reinterpret_cast<floatx80*>(reinterpret_cast<const char*>(&holder)+6) = SF_PREPEND(_to_floatx80)(value);
return holder;
}
#else
#error Unknown byte order
#endif
};
#define STREFLOP_X87DENORMAL_NATIVE_OPS_FLOAT(native_type) \
template<> SoftFloatWrapper<N_SPECIALIZED>::SoftFloatWrapper(const native_type f) { \
value<SF_TYPE>() = FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED>& SoftFloatWrapper<N_SPECIALIZED>::operator=(const native_type f) { \
value<SF_TYPE>() = FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f); \
return *this; \
} \
template<> SoftFloatWrapper<N_SPECIALIZED>::operator native_type() const { \
return FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_to_float(value<SF_TYPE>()); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED>& SoftFloatWrapper<N_SPECIALIZED>::operator+=(const native_type f) { \
value<SF_TYPE>() = SF_PREPEND(_add)(value<SF_TYPE>(), FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f)); \
return *this; \
} \
template<> SoftFloatWrapper<N_SPECIALIZED>& SoftFloatWrapper<N_SPECIALIZED>::operator-=(const native_type f) { \
value<SF_TYPE>() = SF_PREPEND(_sub)(value<SF_TYPE>(), FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f)); \
return *this; \
} \
template<> SoftFloatWrapper<N_SPECIALIZED>& SoftFloatWrapper<N_SPECIALIZED>::operator*=(const native_type f) { \
value<SF_TYPE>() = SF_PREPEND(_mul)(value<SF_TYPE>(), FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f)); \
return *this; \
} \
template<> SoftFloatWrapper<N_SPECIALIZED>& SoftFloatWrapper<N_SPECIALIZED>::operator/=(const native_type f) { \
value<SF_TYPE>() = SF_PREPEND(_div)(value<SF_TYPE>(), FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f)); \
return *this; \
} \
template<> bool SoftFloatWrapper<N_SPECIALIZED>::operator==(const native_type f) const { \
return SF_PREPEND(_eq)(value<SF_TYPE>(), FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f)); \
} \
template<> bool SoftFloatWrapper<N_SPECIALIZED>::operator!=(const native_type f) const { \
return !SF_PREPEND(_eq)(value<SF_TYPE>(), FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f)); \
} \
template<> bool SoftFloatWrapper<N_SPECIALIZED>::operator<(const native_type f) const { \
return SF_PREPEND(_lt)(value<SF_TYPE>(), FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f)); \
} \
template<> bool SoftFloatWrapper<N_SPECIALIZED>::operator<=(const native_type f) const { \
return SF_PREPEND(_le)(value<SF_TYPE>(), FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f)); \
} \
template<> bool SoftFloatWrapper<N_SPECIALIZED>::operator>(const native_type f) const { \
return SF_PREPEND(_lt)(FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f), value<SF_TYPE>()); \
} \
template<> bool SoftFloatWrapper<N_SPECIALIZED>::operator>=(const native_type f) const { \
return SF_PREPEND(_le)(FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f), value<SF_TYPE>()); \
}
STREFLOP_X87DENORMAL_NATIVE_OPS_INT(char)
STREFLOP_X87DENORMAL_NATIVE_OPS_INT(unsigned char)
STREFLOP_X87DENORMAL_NATIVE_OPS_INT(short)
STREFLOP_X87DENORMAL_NATIVE_OPS_INT(unsigned short)
STREFLOP_X87DENORMAL_NATIVE_OPS_INT(int)
STREFLOP_X87DENORMAL_NATIVE_OPS_INT(unsigned int)
STREFLOP_X87DENORMAL_NATIVE_OPS_INT(long)
STREFLOP_X87DENORMAL_NATIVE_OPS_INT(unsigned long)
STREFLOP_X87DENORMAL_NATIVE_OPS_INT(long long)
STREFLOP_X87DENORMAL_NATIVE_OPS_INT(unsigned long long)
STREFLOP_X87DENORMAL_NATIVE_OPS_FLOAT(float)
STREFLOP_X87DENORMAL_NATIVE_OPS_FLOAT(double)
STREFLOP_X87DENORMAL_NATIVE_OPS_FLOAT(long double)
/// binary operators
/// use dummy argument factories to distinguish from integer conversion and avoid creating temporary object
template<> SoftFloatWrapper<N_SPECIALIZED> operator+(const SoftFloatWrapper<N_SPECIALIZED>& f1, const SoftFloatWrapper<N_SPECIALIZED>& f2) {
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_add)(f1.value<SF_TYPE>(), f2.value<SF_TYPE>()), true);
}
template<> SoftFloatWrapper<N_SPECIALIZED> operator-(const SoftFloatWrapper<N_SPECIALIZED>& f1, const SoftFloatWrapper<N_SPECIALIZED>& f2) {
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_sub)(f1.value<SF_TYPE>(), f2.value<SF_TYPE>()), true);
}
template<> SoftFloatWrapper<N_SPECIALIZED> operator*(const SoftFloatWrapper<N_SPECIALIZED>& f1, const SoftFloatWrapper<N_SPECIALIZED>& f2) {
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_mul)(f1.value<SF_TYPE>(), f2.value<SF_TYPE>()), true);
}
template<> SoftFloatWrapper<N_SPECIALIZED> operator/(const SoftFloatWrapper<N_SPECIALIZED>& f1, const SoftFloatWrapper<N_SPECIALIZED>& f2) {
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_div)(f1.value<SF_TYPE>(), f2.value<SF_TYPE>()), true);
}
#define STREFLOP_X87DENORMAL_BINARY_OPS_INT(native_type) \
template<> SoftFloatWrapper<N_SPECIALIZED> operator+(const SoftFloatWrapper<N_SPECIALIZED>& f1, const native_type f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_add)(f1.value<SF_TYPE>(), IntConverter< N_SPECIALIZED, native_type, (sizeof(native_type)>4) >::convert_from_int(f2)), true); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED> operator-(const SoftFloatWrapper<N_SPECIALIZED>& f1, const native_type f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_sub)(f1.value<SF_TYPE>(), IntConverter< N_SPECIALIZED, native_type, (sizeof(native_type)>4) >::convert_from_int(f2)), true); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED> operator*(const SoftFloatWrapper<N_SPECIALIZED>& f1, const native_type f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_mul)(f1.value<SF_TYPE>(), IntConverter< N_SPECIALIZED, native_type, (sizeof(native_type)>4) >::convert_from_int(f2)), true); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED> operator/(const SoftFloatWrapper<N_SPECIALIZED>& f1, const native_type f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_div)(f1.value<SF_TYPE>(), IntConverter< N_SPECIALIZED, native_type, (sizeof(native_type)>4) >::convert_from_int(f2)), true); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED> operator+(const native_type f1, const SoftFloatWrapper<N_SPECIALIZED>& f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_add)(IntConverter< N_SPECIALIZED, native_type, (sizeof(native_type)>4) >::convert_from_int(f1), f2.value<SF_TYPE>()), true); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED> operator-(const native_type f1, const SoftFloatWrapper<N_SPECIALIZED>& f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_sub)(IntConverter< N_SPECIALIZED, native_type, (sizeof(native_type)>4) >::convert_from_int(f1), f2.value<SF_TYPE>()), true); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED> operator*(const native_type f1, const SoftFloatWrapper<N_SPECIALIZED>& f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_mul)(IntConverter< N_SPECIALIZED, native_type, (sizeof(native_type)>4) >::convert_from_int(f1), f2.value<SF_TYPE>()), true); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED> operator/(const native_type f1, const SoftFloatWrapper<N_SPECIALIZED>& f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_div)(IntConverter< N_SPECIALIZED, native_type, (sizeof(native_type)>4) >::convert_from_int(f1), f2.value<SF_TYPE>()), true); \
} \
template<> bool operator==(const native_type value, const SoftFloatWrapper<N_SPECIALIZED>& f) { \
return SF_PREPEND(_eq)(IntConverter< N_SPECIALIZED, native_type, (sizeof(native_type)>4) >::convert_from_int(value), f.value<SF_TYPE>()); \
} \
template<> bool operator!=(const native_type value, const SoftFloatWrapper<N_SPECIALIZED>& f) { \
return !SF_PREPEND(_eq)(IntConverter< N_SPECIALIZED, native_type, (sizeof(native_type)>4) >::convert_from_int(value), f.value<SF_TYPE>()); \
} \
template<> bool operator<(const native_type value, const SoftFloatWrapper<N_SPECIALIZED>& f) { \
return SF_PREPEND(_lt)(IntConverter< N_SPECIALIZED, native_type, (sizeof(native_type)>4) >::convert_from_int(value), f.value<SF_TYPE>()); \
} \
template<> bool operator<=(const native_type value, const SoftFloatWrapper<N_SPECIALIZED>& f) { \
return SF_PREPEND(_le)(IntConverter< N_SPECIALIZED, native_type, (sizeof(native_type)>4) >::convert_from_int(value), f.value<SF_TYPE>()); \
} \
template<> bool operator>(const native_type value, const SoftFloatWrapper<N_SPECIALIZED>& f) { \
return SF_PREPEND(_lt)(f.value<SF_TYPE>(), IntConverter< N_SPECIALIZED, native_type, (sizeof(native_type)>4) >::convert_from_int(value)); \
} \
template<> bool operator>=(const native_type value, const SoftFloatWrapper<N_SPECIALIZED>& f) { \
return SF_PREPEND(_le)(f.value<SF_TYPE>(), IntConverter< N_SPECIALIZED, native_type, (sizeof(native_type)>4) >::convert_from_int(value)); \
}
#define STREFLOP_X87DENORMAL_BINARY_OPS_FLOAT(native_type) \
template<> SoftFloatWrapper<N_SPECIALIZED> operator+(const SoftFloatWrapper<N_SPECIALIZED>& f1, const native_type f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_add)(f1.value<SF_TYPE>(), FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f2)), true); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED> operator-(const SoftFloatWrapper<N_SPECIALIZED>& f1, const native_type f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_sub)(f1.value<SF_TYPE>(), FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f2)), true); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED> operator*(const SoftFloatWrapper<N_SPECIALIZED>& f1, const native_type f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_mul)(f1.value<SF_TYPE>(), FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f2)), true); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED> operator/(const SoftFloatWrapper<N_SPECIALIZED>& f1, const native_type f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_div)(f1.value<SF_TYPE>(), FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f2)), true); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED> operator+(const native_type f1, const SoftFloatWrapper<N_SPECIALIZED>& f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_add)(FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f1), f2.value<SF_TYPE>()), true); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED> operator-(const native_type f1, const SoftFloatWrapper<N_SPECIALIZED>& f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_sub)(FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f1), f2.value<SF_TYPE>()), true); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED> operator*(const native_type f1, const SoftFloatWrapper<N_SPECIALIZED>& f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_mul)(FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f1), f2.value<SF_TYPE>()), true); \
} \
template<> SoftFloatWrapper<N_SPECIALIZED> operator/(const native_type f1, const SoftFloatWrapper<N_SPECIALIZED>& f2) { \
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_div)(FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(f1), f2.value<SF_TYPE>()), true); \
} \
template<> bool operator==(const native_type value, const SoftFloatWrapper<N_SPECIALIZED>& f) { \
return SF_PREPEND(_eq)(FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(value), f.value<SF_TYPE>()); \
} \
template<> bool operator!=(const native_type value, const SoftFloatWrapper<N_SPECIALIZED>& f) { \
return !SF_PREPEND(_eq)(FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(value), f.value<SF_TYPE>()); \
} \
template<> bool operator<(const native_type value, const SoftFloatWrapper<N_SPECIALIZED>& f) { \
return SF_PREPEND(_lt)(FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(value), f.value<SF_TYPE>()); \
} \
template<> bool operator<=(const native_type value, const SoftFloatWrapper<N_SPECIALIZED>& f) { \
return SF_PREPEND(_le)(FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(value), f.value<SF_TYPE>()); \
} \
template<> bool operator>(const native_type value, const SoftFloatWrapper<N_SPECIALIZED>& f) { \
return SF_PREPEND(_lt)(f.value<SF_TYPE>(), FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(value)); \
} \
template<> bool operator>=(const native_type value, const SoftFloatWrapper<N_SPECIALIZED>& f) { \
return SF_PREPEND(_le)(f.value<SF_TYPE>(), FloatConverter< N_SPECIALIZED, native_type, sizeof(native_type)>::convert_from_float(value)); \
}
STREFLOP_X87DENORMAL_BINARY_OPS_INT(char)
STREFLOP_X87DENORMAL_BINARY_OPS_INT(unsigned char)
STREFLOP_X87DENORMAL_BINARY_OPS_INT(short)
STREFLOP_X87DENORMAL_BINARY_OPS_INT(unsigned short)
STREFLOP_X87DENORMAL_BINARY_OPS_INT(int)
STREFLOP_X87DENORMAL_BINARY_OPS_INT(unsigned int)
STREFLOP_X87DENORMAL_BINARY_OPS_INT(long)
STREFLOP_X87DENORMAL_BINARY_OPS_INT(unsigned long)
STREFLOP_X87DENORMAL_BINARY_OPS_INT(long long)
STREFLOP_X87DENORMAL_BINARY_OPS_INT(unsigned long long)
STREFLOP_X87DENORMAL_BINARY_OPS_FLOAT(float)
STREFLOP_X87DENORMAL_BINARY_OPS_FLOAT(double)
STREFLOP_X87DENORMAL_BINARY_OPS_FLOAT(long double)
/// Unary operators
template<> SoftFloatWrapper<N_SPECIALIZED> operator-(const SoftFloatWrapper<N_SPECIALIZED>& f) {
// We could do it right here by flipping the bit sign
// However, there is the exceptions handling and such, so...
return SoftFloatWrapper<N_SPECIALIZED>(SF_PREPEND(_sub)(SF_APPEND(int32_to_)(0), f.value<SF_TYPE>()), true);
}
template<> SoftFloatWrapper<N_SPECIALIZED> operator+(const SoftFloatWrapper<N_SPECIALIZED>& f) {
return f; // makes a copy
}
template<> SoftFloatWrapper<N_SPECIALIZED>::SoftFloatWrapper(const SoftFloatWrapper<32>& f) {
value<SF_TYPE>() = SF_APPEND(float32_to_)(f.value<float32>());
}
template<> SoftFloatWrapper<N_SPECIALIZED>& SoftFloatWrapper<N_SPECIALIZED>::operator=(const SoftFloatWrapper<32>& f) {
value<SF_TYPE>() = SF_APPEND(float32_to_)(f.value<float32>());
return *this;
}
template<> SoftFloatWrapper<N_SPECIALIZED>::SoftFloatWrapper(const SoftFloatWrapper<64>& f) {
value<SF_TYPE>() = SF_APPEND(float64_to_)(f.value<float64>());
}
template<> SoftFloatWrapper<N_SPECIALIZED>& SoftFloatWrapper<N_SPECIALIZED>::operator=(const SoftFloatWrapper<64>& f) {
value<SF_TYPE>() = SF_APPEND(float64_to_)(f.value<float64>());
return *this;
}
template<> SoftFloatWrapper<N_SPECIALIZED>::SoftFloatWrapper(const SoftFloatWrapper<96>& f) {
value<SF_TYPE>() = SF_APPEND(floatx80_to_)(f.value<floatx80>());
}
template<> SoftFloatWrapper<N_SPECIALIZED>& SoftFloatWrapper<N_SPECIALIZED>::operator=(const SoftFloatWrapper<96>& f) {
value<SF_TYPE>() = SF_APPEND(floatx80_to_)(f.value<floatx80>());
return *this;
}
} // end of namespace
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?