up to 0.9.41
This commit is contained in:
parent
de1e368a46
commit
e4ad6f45b9
|
@ -115,9 +115,18 @@
|
|||
[NO] drivers/main : nothing useful
|
||||
[NO] mednafen : nothing useful
|
||||
[OK] psx/cdc : loadstate, type change
|
||||
[OK] psx/cpu : type change, loadstate tweak. ATTN: note about GTE_StateAction
|
||||
[OK] psx/cpu : type change, loadstate tweak. ignore GTE_StateAction.
|
||||
[OK] psx/gpu : big update to loadstate, maybe missing things before
|
||||
[NO] psx/input/* : loadstate buffer sanity, not used for us
|
||||
[OK] psx/mdec : PixelBufferReadOffset fixes
|
||||
[OK] psx/psx : event_time initial value
|
||||
[OK] psx/spu : loadstate sanity, decided to accept it here
|
||||
[OK] psx/spu : loadstate sanity, decided to accept it here
|
||||
0.9.39-2 -> 0.9.41
|
||||
[OK] math_ops : major revisions
|
||||
[NO] mednafen : nothing useful, but check interlace init
|
||||
[OK] psx/cpu : remove PS_CPU_EMULATE_ICACHE? ok..
|
||||
[NO] psx/frontio : AMCT stuff
|
||||
[NO] psx/gpu : render parameters stuff
|
||||
[NO] psx/input/dualshocK : AMCT stuff
|
||||
[NO] psx/psx : render parameters stuff
|
||||
[OK] tests : pasted over and whittled down
|
|
@ -11,6 +11,9 @@
|
|||
#define SIZEOF_LONG sizeof(long)
|
||||
#define SIZEOF_LONG_LONG sizeof(long long)
|
||||
#define SIZEOF_OFF_T sizeof(void*)
|
||||
#define SIZEOF_PTRDIFF_T sizeof(void*)
|
||||
#define SIZEOF_SIZE_T sizeof(size_t)
|
||||
#define SIZEOF_VOID_P sizeof(void*)
|
||||
typedef __int64 s64;
|
||||
typedef __int32 s32;
|
||||
typedef __int16 s16;
|
||||
|
|
|
@ -1,7 +1,46 @@
|
|||
/******************************************************************************/
|
||||
/* Mednafen - Multi-system Emulator */
|
||||
/******************************************************************************/
|
||||
/* endian.h:
|
||||
** Copyright (C) 2006-2016 Mednafen Team
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or
|
||||
** modify it under the terms of the GNU General Public License
|
||||
** as published by the Free Software Foundation; either version 2
|
||||
** of the License, or (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MDFN_ENDIAN_H
|
||||
#define __MDFN_ENDIAN_H
|
||||
|
||||
#pragma warning(once : 4519)
|
||||
void Endian_A16_Swap(void *src, uint32 nelements);
|
||||
void Endian_A32_Swap(void *src, uint32 nelements);
|
||||
void Endian_A64_Swap(void *src, uint32 nelements);
|
||||
|
||||
void Endian_A16_NE_LE(void *src, uint32 nelements);
|
||||
void Endian_A32_NE_LE(void *src, uint32 nelements);
|
||||
void Endian_A64_NE_LE(void *src, uint32 nelements);
|
||||
|
||||
void Endian_A16_NE_BE(void *src, uint32 nelements);
|
||||
void Endian_A32_NE_BE(void *src, uint32 nelements);
|
||||
void Endian_A64_NE_BE(void *src, uint32 nelements);
|
||||
|
||||
void Endian_V_NE_LE(void* p, size_t len);
|
||||
void Endian_V_NE_BE(void* p, size_t len);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
static INLINE uint32 BitsExtract(const uint8* ptr, const size_t bit_offset, const size_t bit_count)
|
||||
{
|
||||
uint32 ret = 0;
|
||||
|
@ -41,21 +80,6 @@ static INLINE void BitsIntract(uint8* ptr, const size_t bit_offset, const size_t
|
|||
this is being done).
|
||||
*/
|
||||
|
||||
void Endian_A16_Swap(void *src, uint32 nelements);
|
||||
void Endian_A32_Swap(void *src, uint32 nelements);
|
||||
void Endian_A64_Swap(void *src, uint32 nelements);
|
||||
|
||||
void Endian_A16_NE_LE(void *src, uint32 nelements);
|
||||
void Endian_A32_NE_LE(void *src, uint32 nelements);
|
||||
void Endian_A64_NE_LE(void *src, uint32 nelements);
|
||||
|
||||
void Endian_A16_NE_BE(void *src, uint32 nelements);
|
||||
void Endian_A32_NE_BE(void *src, uint32 nelements);
|
||||
void Endian_A64_NE_BE(void *src, uint32 nelements);
|
||||
|
||||
void Endian_V_NE_LE(void *src, uint32 bytesize);
|
||||
void Endian_V_NE_BE(void *src, uint32 bytesize);
|
||||
|
||||
static INLINE uint16 MDFN_bswap16(uint16 v)
|
||||
{
|
||||
return (v << 8) | (v >> 8);
|
||||
|
@ -68,9 +92,7 @@ static INLINE uint32 MDFN_bswap32(uint32 v)
|
|||
|
||||
static INLINE uint64 MDFN_bswap64(uint64 v)
|
||||
{
|
||||
//octoshock edit
|
||||
//return (v << 56) | (v >> 56) | ((v & 0xFF00) << 40) | ((v >> 40) & 0xFF00) | ((uint64)MDFN_bswap32(v >> 16) << 16);
|
||||
return (v << 56) | (v >> 56) | ((v & 0xFF00) << 40) | ((v >> 40) & 0xFF00) | ((uint64)MDFN_bswap32(((uint32)v) >> 16) << 16);
|
||||
return (v << 56) | (v >> 56) | ((v & 0xFF00) << 40) | ((v >> 40) & 0xFF00) | ((uint64)MDFN_bswap32(v >> 16) << 16);
|
||||
}
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
|
@ -94,11 +116,11 @@ static INLINE T MDFN_deXsb(const void* ptr)
|
|||
static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Gummy penguins.");
|
||||
|
||||
if(sizeof(T) == 8)
|
||||
return (T)MDFN_bswap64(tmp);
|
||||
return MDFN_bswap64(tmp);
|
||||
else if(sizeof(T) == 4)
|
||||
return (T)MDFN_bswap32(tmp);
|
||||
return MDFN_bswap32(tmp);
|
||||
else if(sizeof(T) == 2)
|
||||
return (T)MDFN_bswap16(tmp);
|
||||
return MDFN_bswap16(tmp);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
|
@ -130,8 +152,9 @@ static INLINE uint16 MDFN_de16lsb(const void* ptr)
|
|||
|
||||
static INLINE uint32 MDFN_de24lsb(const void* ptr)
|
||||
{
|
||||
const uint8* morp = (const uint8*)ptr;
|
||||
return(morp[0]|(morp[1]<<8)|(morp[2]<<16));
|
||||
const uint8* ptr_u8 = (const uint8*)ptr;
|
||||
|
||||
return (ptr_u8[0] << 0) | (ptr_u8[1] << 8) | (ptr_u8[2] << 16);
|
||||
}
|
||||
|
||||
template<bool aligned = false>
|
||||
|
@ -163,8 +186,9 @@ static INLINE uint16 MDFN_de16msb(const void* ptr)
|
|||
|
||||
static INLINE uint32 MDFN_de24msb(const void* ptr)
|
||||
{
|
||||
const uint8* morp = (const uint8*)ptr;
|
||||
return((morp[2]<<0)|(morp[1]<<8)|(morp[0]<<16));
|
||||
const uint8* ptr_u8 = (const uint8*)ptr;
|
||||
|
||||
return (ptr_u8[0] << 16) | (ptr_u8[1] << 8) | (ptr_u8[2] << 0);
|
||||
}
|
||||
|
||||
template<bool aligned = false>
|
||||
|
@ -201,11 +225,11 @@ static INLINE void MDFN_enXsb(void* ptr, T value)
|
|||
static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Gummy penguins.");
|
||||
|
||||
if(sizeof(T) == 8)
|
||||
tmp = (T)MDFN_bswap64(value);
|
||||
tmp = MDFN_bswap64(value);
|
||||
else if(sizeof(T) == 4)
|
||||
tmp = (T)MDFN_bswap32(value);
|
||||
tmp = MDFN_bswap32(value);
|
||||
else if(sizeof(T) == 2)
|
||||
tmp = (T)MDFN_bswap16(value);
|
||||
tmp = MDFN_bswap16(value);
|
||||
}
|
||||
|
||||
memcpy(MDFN_ASSUME_ALIGNED(ptr, (aligned ? sizeof(T) : 1)), &tmp, sizeof(T));
|
||||
|
@ -237,11 +261,11 @@ static INLINE void MDFN_en16lsb(void* ptr, uint16 value)
|
|||
|
||||
static INLINE void MDFN_en24lsb(void* ptr, uint32 value)
|
||||
{
|
||||
uint8* morp = (uint8*)ptr;
|
||||
uint8* ptr_u8 = (uint8*)ptr;
|
||||
|
||||
morp[0] = value;
|
||||
morp[1] = value >> 8;
|
||||
morp[2] = value >> 16;
|
||||
ptr_u8[0] = value >> 0;
|
||||
ptr_u8[1] = value >> 8;
|
||||
ptr_u8[2] = value >> 16;
|
||||
}
|
||||
|
||||
template<bool aligned = false>
|
||||
|
@ -274,11 +298,11 @@ static INLINE void MDFN_en16msb(void* ptr, uint16 value)
|
|||
|
||||
static INLINE void MDFN_en24msb(void* ptr, uint32 value)
|
||||
{
|
||||
uint8* morp = (uint8*)ptr;
|
||||
uint8* ptr_u8 = (uint8*)ptr;
|
||||
|
||||
morp[0] = value;
|
||||
morp[1] = value >> 8;
|
||||
morp[2] = value >> 16;
|
||||
ptr_u8[0] = value >> 16;
|
||||
ptr_u8[1] = value >> 8;
|
||||
ptr_u8[2] = value >> 0;
|
||||
}
|
||||
|
||||
template<bool aligned = false>
|
||||
|
@ -293,4 +317,178 @@ static INLINE void MDFN_en64msb(void* ptr, uint64 value)
|
|||
MDFN_enmsb<uint64, aligned>(ptr, value);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
template<typename T, typename BT>
|
||||
static INLINE uint8* ne16_ptr_be(BT* const base, const size_t byte_offset)
|
||||
{
|
||||
#ifdef MSB_FIRST
|
||||
return (uint8*)base + (byte_offset &~ (sizeof(T) - 1));
|
||||
#else
|
||||
return (uint8*)base + (((byte_offset &~ (sizeof(T) - 1)) ^ (2 - std::min<size_t>(2, sizeof(T)))));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static INLINE void ne16_wbo_be(uint16* const base, const size_t byte_offset, const T value)
|
||||
{
|
||||
uint8* const ptr = ne16_ptr_be<T>(base, byte_offset);
|
||||
|
||||
static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size");
|
||||
|
||||
if(sizeof(T) == 4)
|
||||
{
|
||||
uint16* const ptr16 = (uint16*)ptr;
|
||||
|
||||
ptr16[0] = value >> 16;
|
||||
ptr16[1] = value;
|
||||
}
|
||||
else
|
||||
*(T*)ptr = value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static INLINE T ne16_rbo_be(const uint16* const base, const size_t byte_offset)
|
||||
{
|
||||
uint8* const ptr = ne16_ptr_be<T>(base, byte_offset);
|
||||
|
||||
static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size");
|
||||
|
||||
if(sizeof(T) == 4)
|
||||
{
|
||||
uint16* const ptr16 = (uint16*)ptr;
|
||||
T tmp;
|
||||
|
||||
tmp = ptr16[0] << 16;
|
||||
tmp |= ptr16[1];
|
||||
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
return *(T*)ptr;
|
||||
}
|
||||
|
||||
template<typename T, bool IsWrite>
|
||||
static INLINE void ne16_rwbo_be(uint16* const base, const size_t byte_offset, T* value)
|
||||
{
|
||||
if(IsWrite)
|
||||
ne16_wbo_be<T>(base, byte_offset, *value);
|
||||
else
|
||||
*value = ne16_rbo_be<T>(base, byte_offset);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
template<typename T, typename BT>
|
||||
static INLINE uint8* ne16_ptr_le(BT* const base, const size_t byte_offset)
|
||||
{
|
||||
#ifdef LSB_FIRST
|
||||
return (uint8*)base + (byte_offset &~ (sizeof(T) - 1));
|
||||
#else
|
||||
return (uint8*)base + (((byte_offset &~ (sizeof(T) - 1)) ^ (2 - std::min<size_t>(2, sizeof(T)))));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static INLINE void ne16_wbo_le(uint16* const base, const size_t byte_offset, const T value)
|
||||
{
|
||||
uint8* const ptr = ne16_ptr_le<T>(base, byte_offset);
|
||||
|
||||
static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size");
|
||||
|
||||
if(sizeof(T) == 4)
|
||||
{
|
||||
uint16* const ptr16 = (uint16*)ptr;
|
||||
|
||||
ptr16[0] = value;
|
||||
ptr16[1] = value >> 16;
|
||||
}
|
||||
else
|
||||
*(T*)ptr = value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static INLINE T ne16_rbo_le(const uint16* const base, const size_t byte_offset)
|
||||
{
|
||||
uint8* const ptr = ne16_ptr_le<T>(base, byte_offset);
|
||||
|
||||
static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size");
|
||||
|
||||
if(sizeof(T) == 4)
|
||||
{
|
||||
uint16* const ptr16 = (uint16*)ptr;
|
||||
T tmp;
|
||||
|
||||
tmp = ptr16[0];
|
||||
tmp |= ptr16[1] << 16;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
return *(T*)ptr;
|
||||
}
|
||||
|
||||
|
||||
template<typename T, bool IsWrite>
|
||||
static INLINE void ne16_rwbo_le(uint16* const base, const size_t byte_offset, T* value)
|
||||
{
|
||||
if(IsWrite)
|
||||
ne16_wbo_le<T>(base, byte_offset, *value);
|
||||
else
|
||||
*value = ne16_rbo_le<T>(base, byte_offset);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
template<typename T>
|
||||
static INLINE uint8* ne64_ptr_be(uint64* const base, const size_t byte_offset)
|
||||
{
|
||||
#ifdef MSB_FIRST
|
||||
return (uint8*)base + (byte_offset &~ (sizeof(T) - 1));
|
||||
#else
|
||||
return (uint8*)base + (((byte_offset &~ (sizeof(T) - 1)) ^ (8 - sizeof(T))));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static INLINE void ne64_wbo_be(uint64* const base, const size_t byte_offset, const T value)
|
||||
{
|
||||
uint8* const ptr = ne64_ptr_be<T>(base, byte_offset);
|
||||
|
||||
static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Unsupported type size");
|
||||
|
||||
memcpy(MDFN_ASSUME_ALIGNED(ptr, sizeof(T)), &value, sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static INLINE T ne64_rbo_be(uint64* const base, const size_t byte_offset)
|
||||
{
|
||||
uint8* const ptr = ne64_ptr_be<T>(base, byte_offset);
|
||||
T ret;
|
||||
|
||||
static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size");
|
||||
|
||||
memcpy(&ret, MDFN_ASSUME_ALIGNED(ptr, sizeof(T)), sizeof(T));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T, bool IsWrite>
|
||||
static INLINE void ne64_rwbo_be(uint64* const base, const size_t byte_offset, T* value)
|
||||
{
|
||||
if(IsWrite)
|
||||
ne64_wbo_be<T>(base, byte_offset, *value);
|
||||
else
|
||||
*value = ne64_rbo_be<T>(base, byte_offset);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,162 +1,233 @@
|
|||
#pragma once
|
||||
/******************************************************************************/
|
||||
/* Mednafen - Multi-system Emulator */
|
||||
/******************************************************************************/
|
||||
/* math_ops.h:
|
||||
** Copyright (C) 2007-2016 Mednafen Team
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or
|
||||
** modify it under the terms of the GNU General Public License
|
||||
** as published by the Free Software Foundation; either version 2
|
||||
** of the License, or (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <intrin.h>
|
||||
/*
|
||||
** Some ideas from:
|
||||
** blargg
|
||||
** http://graphics.stanford.edu/~seander/bithacks.html
|
||||
*/
|
||||
|
||||
//
|
||||
// Result is defined for all possible inputs(including 0).
|
||||
//
|
||||
static INLINE unsigned MDFN_lzcount32(uint32 v)
|
||||
#ifndef __MDFN_MATH_OPS_H
|
||||
#define __MDFN_MATH_OPS_H
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
static INLINE unsigned MDFN_lzcount16_0UD(uint16 v)
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER)
|
||||
return v ? __builtin_clz(v) : 32;
|
||||
#elif defined(_MSC_VER) && defined(_WIN64)
|
||||
return 15 ^ 31 ^ __builtin_clz(v);
|
||||
#elif defined(_MSC_VER)
|
||||
unsigned long idx;
|
||||
|
||||
if(!v)
|
||||
return 32;
|
||||
|
||||
_BitScanReverse(&idx, v);
|
||||
|
||||
return 31 - idx;
|
||||
return 15 ^ idx;
|
||||
#else
|
||||
unsigned ret = 0;
|
||||
unsigned tmp;
|
||||
|
||||
if(!v)
|
||||
return(32);
|
||||
|
||||
if(!(v & 0xFFFF0000))
|
||||
{
|
||||
v <<= 16;
|
||||
ret += 16;
|
||||
}
|
||||
|
||||
if(!(v & 0xFF000000))
|
||||
{
|
||||
v <<= 8;
|
||||
ret += 8;
|
||||
}
|
||||
|
||||
if(!(v & 0xF0000000))
|
||||
{
|
||||
v <<= 4;
|
||||
ret += 4;
|
||||
}
|
||||
|
||||
if(!(v & 0xC0000000))
|
||||
{
|
||||
v <<= 2;
|
||||
ret += 2;
|
||||
}
|
||||
|
||||
if(!(v & 0x80000000))
|
||||
{
|
||||
v <<= 1;
|
||||
ret += 1;
|
||||
}
|
||||
tmp = !(v & 0xFF00) << 3; v <<= tmp; ret += tmp;
|
||||
tmp = !(v & 0xF000) << 2; v <<= tmp; ret += tmp;
|
||||
tmp = !(v & 0xC000) << 1; v <<= tmp; ret += tmp;
|
||||
tmp = !(v & 0x8000) << 0; ret += tmp;
|
||||
|
||||
return(ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE unsigned MDFN_lzcount32_0UD(uint32 v)
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER)
|
||||
return __builtin_clz(v);
|
||||
#elif defined(_MSC_VER)
|
||||
unsigned long idx;
|
||||
|
||||
_BitScanReverse(&idx, v);
|
||||
|
||||
return 31 ^ idx;
|
||||
#else
|
||||
unsigned ret = 0;
|
||||
unsigned tmp;
|
||||
|
||||
tmp = !(v & 0xFFFF0000) << 4; v <<= tmp; ret += tmp;
|
||||
tmp = !(v & 0xFF000000) << 3; v <<= tmp; ret += tmp;
|
||||
tmp = !(v & 0xF0000000) << 2; v <<= tmp; ret += tmp;
|
||||
tmp = !(v & 0xC0000000) << 1; v <<= tmp; ret += tmp;
|
||||
tmp = !(v & 0x80000000) << 0; ret += tmp;
|
||||
|
||||
return(ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE unsigned MDFN_lzcount64_0UD(uint64 v)
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER)
|
||||
return __builtin_clzll(v);
|
||||
#elif defined(_MSC_VER)
|
||||
#if defined(_WIN64)
|
||||
unsigned long idx;
|
||||
_BitScanReverse64(&idx, v);
|
||||
return 63 ^ idx;
|
||||
#else
|
||||
unsigned long idx0;
|
||||
unsigned long idx1;
|
||||
|
||||
_BitScanReverse(&idx1, v >> 0);
|
||||
idx1 -= 32;
|
||||
if(!_BitScanReverse(&idx0, v >> 32))
|
||||
idx0 = idx1;
|
||||
|
||||
idx0 += 32;
|
||||
|
||||
return 63 ^ idx0;
|
||||
#endif
|
||||
#else
|
||||
unsigned ret = 0;
|
||||
unsigned tmp;
|
||||
|
||||
tmp = !(v & 0xFFFFFFFF00000000ULL) << 5; v <<= tmp; ret += tmp;
|
||||
tmp = !(v & 0xFFFF000000000000ULL) << 4; v <<= tmp; ret += tmp;
|
||||
tmp = !(v & 0xFF00000000000000ULL) << 3; v <<= tmp; ret += tmp;
|
||||
tmp = !(v & 0xF000000000000000ULL) << 2; v <<= tmp; ret += tmp;
|
||||
tmp = !(v & 0xC000000000000000ULL) << 1; v <<= tmp; ret += tmp;
|
||||
tmp = !(v & 0x8000000000000000ULL) << 0; ret += tmp;
|
||||
|
||||
return(ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE unsigned MDFN_tzcount16_0UD(uint16 v)
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER)
|
||||
return __builtin_ctz(v);
|
||||
#elif defined(_MSC_VER)
|
||||
unsigned long idx;
|
||||
|
||||
_BitScanForward(&idx, v);
|
||||
|
||||
return idx;
|
||||
#else
|
||||
unsigned ret = 0;
|
||||
unsigned tmp;
|
||||
|
||||
tmp = !( (uint8)v) << 3; v >>= tmp; ret += tmp;
|
||||
tmp = !(v & 0x000F) << 2; v >>= tmp; ret += tmp;
|
||||
tmp = !(v & 0x0003) << 1; v >>= tmp; ret += tmp;
|
||||
tmp = !(v & 0x0001) << 0; ret += tmp;
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE unsigned MDFN_tzcount32_0UD(uint32 v)
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER)
|
||||
return __builtin_ctz(v);
|
||||
#elif defined(_MSC_VER)
|
||||
unsigned long idx;
|
||||
|
||||
_BitScanForward(&idx, v);
|
||||
|
||||
return idx;
|
||||
#else
|
||||
unsigned ret = 0;
|
||||
unsigned tmp;
|
||||
|
||||
tmp = !((uint16)v) << 4; v >>= tmp; ret += tmp;
|
||||
tmp = !( (uint8)v) << 3; v >>= tmp; ret += tmp;
|
||||
tmp = !(v & 0x000F) << 2; v >>= tmp; ret += tmp;
|
||||
tmp = !(v & 0x0003) << 1; v >>= tmp; ret += tmp;
|
||||
tmp = !(v & 0x0001) << 0; ret += tmp;
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE unsigned MDFN_tzcount64_0UD(uint64 v)
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER)
|
||||
return __builtin_ctzll(v);
|
||||
#elif defined(_MSC_VER)
|
||||
#if defined(_WIN64)
|
||||
unsigned long idx;
|
||||
_BitScanForward64(&idx, v);
|
||||
return idx;
|
||||
#else
|
||||
unsigned long idx0, idx1;
|
||||
|
||||
_BitScanForward(&idx1, v >> 32);
|
||||
idx1 += 32;
|
||||
if(!_BitScanForward(&idx0, v))
|
||||
idx0 = idx1;
|
||||
|
||||
return idx0;
|
||||
#endif
|
||||
#else
|
||||
unsigned ret = 0;
|
||||
unsigned tmp;
|
||||
|
||||
tmp = !((uint32)v) << 5; v >>= tmp; ret += tmp;
|
||||
tmp = !((uint16)v) << 4; v >>= tmp; ret += tmp;
|
||||
tmp = !( (uint8)v) << 3; v >>= tmp; ret += tmp;
|
||||
tmp = !(v & 0x000F) << 2; v >>= tmp; ret += tmp;
|
||||
tmp = !(v & 0x0003) << 1; v >>= tmp; ret += tmp;
|
||||
tmp = !(v & 0x0001) << 0; ret += tmp;
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Result is defined for all possible inputs(including 0).
|
||||
//
|
||||
static INLINE unsigned MDFN_lzcount64(uint64 v)
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER)
|
||||
return v ? __builtin_clzll(v) : 64;
|
||||
#elif defined(_MSC_VER) && defined(_WIN64)
|
||||
unsigned long idx;
|
||||
static INLINE unsigned MDFN_lzcount16(uint16 v) { return !v ? 16 : MDFN_lzcount16_0UD(v); }
|
||||
static INLINE unsigned MDFN_lzcount32(uint32 v) { return !v ? 32 : MDFN_lzcount32_0UD(v); }
|
||||
static INLINE unsigned MDFN_lzcount64(uint64 v) { return !v ? 64 : MDFN_lzcount64_0UD(v); }
|
||||
|
||||
if(!v)
|
||||
return 64;
|
||||
static INLINE unsigned MDFN_tzcount16(uint16 v) { return !v ? 16 : MDFN_tzcount16_0UD(v); }
|
||||
static INLINE unsigned MDFN_tzcount32(uint32 v) { return !v ? 32 : MDFN_tzcount32_0UD(v); }
|
||||
static INLINE unsigned MDFN_tzcount64(uint64 v) { return !v ? 64 : MDFN_tzcount64_0UD(v); }
|
||||
|
||||
_BitScanReverse64(&idx, v);
|
||||
static INLINE unsigned MDFN_log2(uint32 v) { return 31 ^ MDFN_lzcount32_0UD(v | 1); }
|
||||
static INLINE unsigned MDFN_log2(uint64 v) { return 63 ^ MDFN_lzcount64_0UD(v | 1); }
|
||||
|
||||
return 63 - idx;
|
||||
#else
|
||||
unsigned ret = 0;
|
||||
static INLINE unsigned MDFN_log2(int32 v) { return MDFN_log2((uint32)v); }
|
||||
static INLINE unsigned MDFN_log2(int64 v) { return MDFN_log2((uint64)v); }
|
||||
|
||||
if(!(v & 0xFFFFFFFFFFFFFFFFULL))
|
||||
return(64);
|
||||
// Rounds up to the nearest power of 2(treats input as unsigned to a degree, but be aware of integer promotion rules).
|
||||
// Returns 0 on overflow.
|
||||
static INLINE uint64 round_up_pow2(uint32 v) { uint64 tmp = (uint64)1 << MDFN_log2(v); return tmp << (tmp < v); }
|
||||
static INLINE uint64 round_up_pow2(uint64 v) { uint64 tmp = (uint64)1 << MDFN_log2(v); return tmp << (tmp < v); }
|
||||
|
||||
if(!(v & 0xFFFFFFFF00000000ULL))
|
||||
{
|
||||
v <<= 32;
|
||||
ret += 32;
|
||||
}
|
||||
static INLINE uint64 round_up_pow2(int32 v) { return round_up_pow2((uint32)v); }
|
||||
static INLINE uint64 round_up_pow2(int64 v) { return round_up_pow2((uint64)v); }
|
||||
|
||||
if(!(v & 0xFFFF000000000000ULL))
|
||||
{
|
||||
v <<= 16;
|
||||
ret += 16;
|
||||
}
|
||||
// Rounds to the nearest power of 2(treats input as unsigned to a degree, but be aware of integer promotion rules).
|
||||
static INLINE uint64 round_nearest_pow2(uint32 v, bool round_half_up = true) { uint64 tmp = (uint64)1 << MDFN_log2(v); return tmp << (v && (((v - tmp) << 1) >= (tmp + !round_half_up))); }
|
||||
static INLINE uint64 round_nearest_pow2(uint64 v, bool round_half_up = true) { uint64 tmp = (uint64)1 << MDFN_log2(v); return tmp << (v && (((v - tmp) << 1) >= (tmp + !round_half_up))); }
|
||||
|
||||
if(!(v & 0xFF00000000000000ULL))
|
||||
{
|
||||
v <<= 8;
|
||||
ret += 8;
|
||||
}
|
||||
|
||||
if(!(v & 0xF000000000000000ULL))
|
||||
{
|
||||
v <<= 4;
|
||||
ret += 4;
|
||||
}
|
||||
|
||||
if(!(v & 0xC000000000000000ULL))
|
||||
{
|
||||
v <<= 2;
|
||||
ret += 2;
|
||||
}
|
||||
|
||||
if(!(v & 0x8000000000000000ULL))
|
||||
{
|
||||
v <<= 1;
|
||||
ret += 1;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Source: http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
||||
// Rounds up to the nearest power of 2.
|
||||
static INLINE uint64 round_up_pow2(uint64 v)
|
||||
{
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
v |= v >> 32;
|
||||
v++;
|
||||
|
||||
v += (v == 0);
|
||||
|
||||
return(v);
|
||||
}
|
||||
|
||||
static INLINE uint32 uilog2(uint32 v)
|
||||
{
|
||||
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
|
||||
|
||||
static const uint32 MultiplyDeBruijnBitPosition[32] =
|
||||
{
|
||||
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
|
||||
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
|
||||
};
|
||||
|
||||
v |= v >> 1; // first round down to one less than a power of 2
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
|
||||
return MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];
|
||||
}
|
||||
static INLINE uint64 round_nearest_pow2(int32 v, bool round_half_up = true) { return round_nearest_pow2((uint32)v, round_half_up); }
|
||||
static INLINE uint64 round_nearest_pow2(int64 v, bool round_half_up = true) { return round_nearest_pow2((uint64)v, round_half_up); }
|
||||
|
||||
// Some compilers' optimizers and some platforms might fubar the generated code from these macros,
|
||||
// so some tests are run in...tests.cpp
|
||||
|
@ -203,3 +274,5 @@ template<typename T, typename U, typename V> static INLINE void clamp(T *val, U
|
|||
*val = maximum;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2806,8 +2806,6 @@ SYNCFUNC(PS_CPU)
|
|||
|
||||
NSS(ScratchRAM.data8);
|
||||
|
||||
//ZERO - REMINDER - GTE_StateAction was here. is it important?
|
||||
|
||||
if(isReader)
|
||||
{
|
||||
ReadAbsorbWhich &= 0x1F;
|
||||
|
|
|
@ -64,8 +64,6 @@
|
|||
namespace MDFN_IEN_PSX
|
||||
{
|
||||
|
||||
#define PS_CPU_EMULATE_ICACHE 1
|
||||
|
||||
class PS_CPU
|
||||
{
|
||||
public:
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,6 +2,7 @@
|
|||
#define __MDFN_TESTS_H
|
||||
|
||||
bool MDFN_RunMathTests(void);
|
||||
void MDFN_RunExceptionTests(const unsigned thread_count, const unsigned thread_delay);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue