Fixing a bunch of alloy clang issues.

This commit is contained in:
Ben Vanik
2014-07-12 21:52:33 -07:00
parent 9b78dd977b
commit 7ee79318e8
13 changed files with 157 additions and 56 deletions

View File

@@ -70,7 +70,7 @@ namespace poly {
poly_assert((expr) != nullptr || !message)
#define assert_unhandled_case(variable) \
assert_always("unhandled switch("## #variable##") case")
assert_always("unhandled switch(" #variable ") case")
} // namespace poly

View File

@@ -15,32 +15,35 @@
#include <poly/config.h>
#include <poly/platform.h>
#if XE_LIKE_OSX
#include <libkern/OSAtomic.h>
#endif // XE_LIKE_OSX
namespace poly {
// These functions are modeled off of the Apple OSAtomic routines
// http://developer.apple.com/library/mac/#documentation/DriversKernelHardware/Reference/libkern_ref/OSAtomic_h/
#if XE_LIKE_OSX
#include <libkern/OSAtomic.h>
inline int32_t atomic_inc(volatile int32_t* value) {
return OSAtomicIncrement32Barrier(reinterpret_cast<volatile LONG*>(value));
return OSAtomicIncrement32Barrier(reinterpret_cast<volatile int32_t*>(value));
}
inline int32_t atomic_dec(volatile int32_t* value) {
return OSAtomicDecrement32Barrier(reinterpret_cast<volatile LONG*>(value));
return OSAtomicDecrement32Barrier(reinterpret_cast<volatile int32_t*>(value));
}
inline int32_t atomic_exchange(int32_t new_value, volatile int32_t* value) {
//
return OSAtomicCompareAndSwap32Barrier(*value, new_value, value);
}
inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) {
//
return OSAtomicCompareAndSwap64Barrier(*value, new_value, value);
}
inline int32_t atomic_cas(int32_t old_value, int32_t new_value,
volatile int32_t* value) {
return OSAtomicCompareAndSwap32Barrier(
old_value, new_value, reinterpret_cast<volatile LONG*>(value));
old_value, new_value, reinterpret_cast<volatile int32_t*>(value));
}
#elif XE_LIKE_WIN32
@@ -77,10 +80,10 @@ inline int32_t atomic_dec(volatile int32_t* value) {
}
inline int32_t atomic_exchange(int32_t new_value, volatile int32_t* value) {
//
return __sync_val_compare_and_swap(*value, value, new_value);
}
inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) {
//
return __sync_val_compare_and_swap(*value, value, new_value);
}
inline int32_t atomic_cas(int32_t old_value, int32_t new_value,

69
src/poly/math.cc Normal file
View File

@@ -0,0 +1,69 @@
/**
******************************************************************************
* 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. *
******************************************************************************
*/
#include <poly/math.h>
namespace poly {
// TODO(benvanik): replace with alternate implementation.
// XMConvertFloatToHalf
// Copyright (c) Microsoft Corporation. All rights reserved.
uint16_t float_to_half(float value) {
uint32_t Result;
uint32_t IValue = ((uint32_t *)(&value))[0];
uint32_t Sign = (IValue & 0x80000000U) >> 16U;
IValue = IValue & 0x7FFFFFFFU; // Hack off the sign
if (IValue > 0x47FFEFFFU) {
// The number is too large to be represented as a half. Saturate to
// infinity.
Result = 0x7FFFU;
} else {
if (IValue < 0x38800000U) {
// The number is too small to be represented as a normalized half.
// Convert it to a denormalized value.
uint32_t Shift = 113U - (IValue >> 23U);
IValue = (0x800000U | (IValue & 0x7FFFFFU)) >> Shift;
} else {
// Rebias the exponent to represent the value as a normalized half.
IValue += 0xC8000000U;
}
Result = ((IValue + 0x0FFFU + ((IValue >> 13U) & 1U)) >> 13U) & 0x7FFFU;
}
return (uint16_t)(Result | Sign);
}
// TODO(benvanik): replace with alternate implementation.
// XMConvertHalfToFloat
// Copyright (c) Microsoft Corporation. All rights reserved.
float half_to_float(uint16_t value) {
uint32_t Mantissa = (uint32_t)(value & 0x03FF);
uint32_t Exponent;
if ((value & 0x7C00) != 0) {
// The value is normalized
Exponent = (uint32_t)((value >> 10) & 0x1F);
} else if (Mantissa != 0) {
// The value is denormalized
// Normalize the value in the resulting float
Exponent = 1;
do {
Exponent--;
Mantissa <<= 1;
} while ((Mantissa & 0x0400) == 0);
Mantissa &= 0x03FF;
} else {
// The value is zero
Exponent = (uint32_t)-112;
}
uint32_t Result = ((value & 0x8000) << 16) | // Sign
((Exponent + 112) << 23) | // Exponent
(Mantissa << 13); // Mantissa
return *(float *)&Result;
}
} // namespace poly

View File

@@ -25,6 +25,7 @@ namespace poly {
// 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
#if 1
inline uint8_t lzcnt(uint8_t v) {
return static_cast<uint8_t>(__lzcnt16(v) - 8);
}
@@ -32,6 +33,32 @@ inline uint8_t lzcnt(uint16_t v) { return static_cast<uint8_t>(__lzcnt16(v)); }
inline uint8_t lzcnt(uint32_t v) { return static_cast<uint8_t>(__lzcnt(v)); }
inline uint8_t lzcnt(uint64_t v) { return static_cast<uint8_t>(__lzcnt64(v)); }
#else
inline uint8_t lzcnt(uint8_t v) {
DWORD index;
DWORD mask = v;
BOOLEAN is_nonzero = _BitScanReverse(&index, mask);
return static_cast<uint8_t>(is_nonzero ? int8_t(index - 24) ^ 0x7 : 8);
}
inline uint8_t lzcnt(uint16_t v) {
DWORD index;
DWORD mask = v;
BOOLEAN is_nonzero = _BitScanReverse(&index, mask);
return static_cast<uint8_t>(is_nonzero ? int8_t(index - 16) ^ 0xF : 16);
}
inline uint8_t lzcnt(uint32_t v) {
DWORD index;
DWORD mask = v;
BOOLEAN is_nonzero = _BitScanReverse(&index, mask);
return static_cast<uint8_t>(is_nonzero ? int8_t(index) ^ 0x1F : 32);
}
inline uint8_t lzcnt(uint64_t v) {
DWORD index;
DWORD64 mask = v;
BOOLEAN is_nonzero = _BitScanReverse64(&index, mask);
return static_cast<uint8_t>(is_nonzero ? int8_t(index) ^ 0x3F : 64);
}
#endif // LZCNT supported
#else
inline uint8_t lzcnt(uint8_t v) {
return static_cast<uint8_t>(__builtin_clzs(v) - 8);
}
@@ -121,6 +148,9 @@ int64_t m128_i64(const __m128& v) {
return m128_i64<N>(_mm_castps_pd(v));
}
uint16_t float_to_half(float value);
float half_to_float(uint16_t value);
} // namespace poly
#endif // POLY_MATH_H_

View File

@@ -5,6 +5,7 @@
'atomic.h',
'config.h',
'cxx_compat.h',
'math.cc',
'math.h',
'platform.h',
'poly-private.h',

View File

@@ -18,6 +18,9 @@
namespace poly {
namespace threading {
// Gets the current high-perforance tick count.
uint64_t ticks();
// Gets a stable thread-specific ID, but may not be. Use for informative
// purposes only.
uint32_t current_thread_id();

View File

@@ -9,12 +9,16 @@
#include <poly/threading.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <pthread.h>
#include <time.h>
namespace poly {
namespace threading {
uint64_t ticks() { return mach_absolute_time(); }
uint32_t current_thread_id() {
mach_port_t tid = pthread_mach_thread_np(pthread_self());
return static_cast<uint32_t>(tid);

View File

@@ -14,6 +14,15 @@
namespace poly {
namespace threading {
uint64_t ticks() {
LARGE_INTEGER counter;
uint64_t time = 0;
if (QueryPerformanceCounter(&counter)) {
time = counter.QuadPart;
}
return time;
}
uint32_t current_thread_id() {
return static_cast<uint32_t>(GetCurrentThreadId());
}