Fix clang warnings / move some plat code into poly.

This commit is contained in:
Ben Vanik
2014-07-10 22:51:27 -07:00
parent 7daa85179c
commit 9031d5f4a4
41 changed files with 347 additions and 218 deletions

25
src/poly/cxx_compat.h Normal file
View File

@@ -0,0 +1,25 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef POLY_POLY_CXX_COMPAT_H_
#define POLY_POLY_CXX_COMPAT_H_
// C++11 thread local storage.
// http://en.cppreference.com/w/cpp/language/storage_duration
#if XE_COMPILER_MSVC
// VC++2014 may have this.
#define thread_local __declspec(thread)
#elif XE_LIKE_OSX
// Clang supports it on OSX but the runtime doesn't.
#define thread_local __thread
#endif // XE_COMPILER_MSVC
namespace poly {} // namespace poly
#endif // POLY_POLY_CXX_COMPAT_H_

104
src/poly/math.h Normal file
View File

@@ -0,0 +1,104 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef POLY_MATH_H_
#define POLY_MATH_H_
#include <xmmintrin.h>
#include <cstdint>
#include <cstring>
namespace poly {
// lzcnt instruction, typed for integers of all sizes.
// The number of leading zero bits in the value parameter. If value is zero, the
// return value is the size of the input operand (8, 16, 32, or 64). If the most
// significant bit of value is one, the return value is zero.
#if XE_COMPILER_MSVC
uint8_t lzcnt(uint8_t v) { return static_cast<uint8_t>(__lzcnt16(v) - 8); }
uint8_t lzcnt(uint16_t v) { return static_cast<uint8_t>(__lzcnt16(v)); }
uint8_t lzcnt(uint32_t v) { return static_cast<uint8_t>(__lzcnt(v)); }
uint8_t lzcnt(uint64_t v) { return static_cast<uint8_t>(__lzcnt64(v)); }
#else
uint8_t lzcnt(uint8_t v) { return static_cast<uint8_t>(__builtin_clzs(v) - 8); }
uint8_t lzcnt(uint16_t v) { return static_cast<uint8_t>(__builtin_clzs(v)); }
uint8_t lzcnt(uint32_t v) { return static_cast<uint8_t>(__builtin_clz(v)); }
uint8_t lzcnt(uint64_t v) { return static_cast<uint8_t>(__builtin_clzll(v)); }
#endif // XE_COMPILER_MSVC
uint8_t lzcnt(int8_t v) { return lzcnt(static_cast<uint8_t>(v)); }
uint8_t lzcnt(int16_t v) { return lzcnt(static_cast<uint16_t>(v)); }
uint8_t lzcnt(int32_t v) { return lzcnt(static_cast<uint32_t>(v)); }
uint8_t lzcnt(int64_t v) { return lzcnt(static_cast<uint64_t>(v)); }
// BitScanForward (bsf).
// Search the value from least significant bit (LSB) to the most significant bit
// (MSB) for a set bit (1).
// Returns false if no bits are set and the output index is invalid.
#if XE_COMPILER_MSVC
bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index) {
return _BitScanForward(out_first_set_index, v) != 0;
}
bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index) {
return _BitScanForward64(out_first_set_index, v) != 0;
}
#else
bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index) {
int i = ffs(v);
*out_first_set_index = i;
return i != 0;
}
bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index) {
int i = ffsll(v);
*out_first_set_index = i;
return i != 0;
}
#endif // XE_COMPILER_MSVC
bool bit_scan_forward(int32_t v, uint32_t* out_first_set_index) {
return bit_scan_forward(static_cast<uint32_t>(v), out_first_set_index);
}
bool bit_scan_forward(int64_t v, uint32_t* out_first_set_index) {
return bit_scan_forward(static_cast<uint64_t>(v), out_first_set_index);
}
// Utilities for SSE values.
template <int N>
float m128_f32(const __m128& v) {
float ret;
_mm_store_ss(&ret, _mm_shuffle_ps(v, v, _MM_SHUFFLE(N, N, N, N)));
return ret;
}
template <int N>
int32_t m128_i32(const __m128& v) {
union {
float f;
int32_t i;
} ret;
_mm_store_ss(&ret.f, _mm_shuffle_ps(v, v, _MM_SHUFFLE(N, N, N, N)));
return ret.i;
}
template <int N>
double m128_f64(const __m128& v) {
double ret;
_mm_store_sd(&ret, _mm_shuffle_ps(v, v, _MM_SHUFFLE(N, N, N, N)));
return ret;
}
template <int N>
int64_t m128_i64(const __m128& v) {
union {
double f;
int64_t i;
} ret;
_mm_store_sd(&ret.f, _mm_shuffle_ps(v, v, _MM_SHUFFLE(N, N, N, N)));
return ret.i;
}
} // namespace poly
#endif // POLY_MATH_H_

View File

@@ -10,6 +10,9 @@
#ifndef POLY_POLY_H_
#define POLY_POLY_H_
#include <poly/cxx_compat.h>
#include <poly/math.h>
namespace poly {} // namespace poly
#endif // POLY_POLY_H_

View File

@@ -1,6 +1,8 @@
# Copyright 2014 Ben Vanik. All Rights Reserved.
{
'sources': [
'cxx_compat.h',
'math.h',
'poly-private.h',
'poly.cc',
'poly.h',