libretro-common: incorporate latest cpu_features (and merge with prior commit). rogerman please check.

This commit is contained in:
zeromus 2016-11-27 14:36:58 -06:00
parent 41e9b1680e
commit 3e10928bf5
3 changed files with 94 additions and 14 deletions

View File

@ -73,6 +73,16 @@
#include <ogc/lwp_watchdog.h>
#endif
#ifdef WIIU
#include <coreinit/time.h>
#include "wiiu/system/wiiu.h"
#endif
#if defined(_3DS)
#include <3ds/svc.h>
#include <3ds/os.h>
#endif
/* iOS/OSX specific. Lacks clock_gettime(), so implement it. */
#ifdef __MACH__
#include <sys/time.h>
@ -85,9 +95,8 @@
#define CLOCK_REALTIME 0
#endif
#if (__MAC_OS_X_VERSION_MAX_ALLOWED < 101200) && (__IPHONE_OS_VERSION_MAX_ALLOWED < 100000)
// this function is part of macOS 10.12 and iOS 10 now
static int clock_gettime(int clk_ik, struct timespec *t)
/* this function is part of iOS 10 now */
static int ra_clock_gettime(int clk_ik, struct timespec *t)
{
struct timeval now;
int rv = gettimeofday(&now, NULL);
@ -98,8 +107,13 @@ static int clock_gettime(int clk_ik, struct timespec *t)
return 0;
}
#endif
#if defined(__MACH__) && (__MAC_OS_X_VERSION_MAX_ALLOWED < 101200) && (__IPHONE_OS_VERSION_MAX_ALLOWED < 100000)
#else
#define ra_clock_gettime clock_gettime
#endif
#ifdef EMSCRIPTEN
#include <emscripten.h>
#endif
@ -136,8 +150,8 @@ retro_perf_tick_t cpu_features_get_perf_counter(void)
tv_usec = (long)(system_time.wMilliseconds * 1000);
time_ticks = (1000000 * tv_sec + tv_usec);
#elif defined(__linux__) || defined(__QNX__) || defined(__MACH__)
struct timespec tv;
if (clock_gettime(CLOCK_MONOTONIC, &tv) == 0)
struct timespec tv = {0};
if (ra_clock_gettime(CLOCK_MONOTONIC, &tv) == 0)
time_ticks = (retro_perf_tick_t)tv.tv_sec * 1000000000 +
(retro_perf_tick_t)tv.tv_nsec;
@ -153,10 +167,14 @@ retro_perf_tick_t cpu_features_get_perf_counter(void)
time_ticks = __mftb();
#elif defined(GEKKO)
time_ticks = gettime();
#elif defined(PSP) || defined(VITA)
sceRtcGetCurrentTick(&time_ticks);
#elif defined(PSP)
sceRtcGetCurrentTick((uint64_t*)&time_ticks);
#elif defined(VITA)
sceRtcGetCurrentTick((SceRtcTick*)&time_ticks);
#elif defined(_3DS)
time_ticks = svcGetSystemTick();
#elif defined(WIIU)
time_ticks = OSGetSystemTime();
#elif defined(__mips__)
struct timeval tv;
gettimeofday(&tv,NULL);
@ -192,7 +210,7 @@ retro_time_t cpu_features_get_time_usec(void)
return ticks_to_microsecs(gettime());
#elif defined(_POSIX_MONOTONIC_CLOCK) || defined(__QNX__) || defined(ANDROID) || defined(__MACH__)
struct timespec tv = {0};
if (clock_gettime(CLOCK_MONOTONIC, &tv) < 0)
if (ra_clock_gettime(CLOCK_MONOTONIC, &tv) < 0)
return 0;
return tv.tv_sec * INT64_C(1000000) + (tv.tv_nsec + 500) / 1000;
#elif defined(EMSCRIPTEN)
@ -205,6 +223,8 @@ retro_time_t cpu_features_get_time_usec(void)
return osGetTime() * 1000;
#elif defined(VITA)
return sceKernelGetProcessTimeWide();
#elif defined(WIIU)
return ticks_to_us(OSGetSystemTime());
#else
#error "Your platform does not have a timer function implemented in cpu_features_get_time_usec(). Cannot continue."
#endif
@ -271,7 +291,7 @@ static uint64_t xgetbv_x86(uint32_t idx)
}
#endif
#if defined(__ARM_NEON__)
#if defined(__ARM_NEON__)
static void arm_enable_runfast_mode(void)
{
/* RunFast mode. Enables flush-to-zero and some
@ -448,6 +468,8 @@ unsigned cpu_features_get_core_amount(void)
return 4;
#elif defined(_3DS)
return 1;
#elif defined(WIIU)
return 3;
#elif defined(_SC_NPROCESSORS_ONLN)
/* Linux, most UNIX-likes. */
long ret = sysconf(_SC_NPROCESSORS_ONLN);
@ -513,7 +535,7 @@ uint64_t cpu_features_get(void)
{
int flags[4];
int vendor_shuffle[3];
char vendor[13] = {0};
char vendor[13];
size_t len = 0;
uint64_t cpu_flags = 0;
uint64_t cpu = 0;
@ -542,6 +564,12 @@ uint64_t cpu_features_get(void)
cpu |= RETRO_SIMD_MMXEXT;
}
len = sizeof(size_t);
if (sysctlbyname("hw.optional.floatingpoint", NULL, &len, NULL, 0) == 0)
{
cpu |= RETRO_SIMD_CMOV;
}
len = sizeof(size_t);
if (sysctlbyname("hw.optional.sse", NULL, &len, NULL, 0) == 0)
cpu |= RETRO_SIMD_SSE;
@ -593,6 +621,8 @@ uint64_t cpu_features_get(void)
vendor_shuffle[0] = flags[1];
vendor_shuffle[1] = flags[3];
vendor_shuffle[2] = flags[2];
vendor[0] = '\0';
memcpy(vendor, vendor_shuffle, sizeof(vendor_shuffle));
/* printf("[CPUID]: Vendor: %s\n", vendor); */
@ -608,6 +638,9 @@ uint64_t cpu_features_get(void)
x86_cpuid(1, flags);
if (flags[3] & (1 << 15))
cpu |= RETRO_SIMD_CMOV;
if (flags[3] & (1 << 23))
cpu |= RETRO_SIMD_MMX;
@ -682,6 +715,15 @@ uint64_t cpu_features_get(void)
if (check_arm_cpu_feature("vfpv4"))
cpu |= RETRO_SIMD_VFPV4;
if (check_arm_cpu_feature("asimd"))
{
cpu |= RETRO_SIMD_ASIMD;
#ifdef __ARM_NEON__
cpu |= RETRO_SIMD_NEON;
arm_enable_runfast_mode();
#endif
}
#if 0
check_arm_cpu_feature("swp");
check_arm_cpu_feature("half");
@ -726,6 +768,7 @@ uint64_t cpu_features_get(void)
if (cpu & RETRO_SIMD_VMX128) strlcat(buf, " VMX128", sizeof(buf));
if (cpu & RETRO_SIMD_VFPU) strlcat(buf, " VFPU", sizeof(buf));
if (cpu & RETRO_SIMD_PS) strlcat(buf, " PS", sizeof(buf));
if (cpu & RETRO_SIMD_ASIMD) strlcat(buf, " ASIMD", sizeof(buf));
return cpu;
}

View File

@ -43,15 +43,17 @@ retro_perf_tick_t cpu_features_get_perf_counter(void);
/**
* cpu_features_get_time_usec:
*
* Gets time in microseconds. *
* Returns: time in microseconds.
* Gets time in microseconds, from an undefined epoch.
* The epoch may change between computers or across reboots.
*
* Returns: time in microseconds
**/
retro_time_t cpu_features_get_time_usec(void);
/**
* cpu_features_get:
*
* Gets CPU features..
* Gets CPU features.
*
* Returns: bitmask of all CPU features available.
**/

View File

@ -244,6 +244,7 @@ enum retro_language
RETRO_LANGUAGE_CHINESE_SIMPLIFIED = 11,
RETRO_LANGUAGE_ESPERANTO = 12,
RETRO_LANGUAGE_POLISH = 13,
RETRO_LANGUAGE_VIETNAMESE = 14,
RETRO_LANGUAGE_LAST,
/* Ensure sizeof(enum) == sizeof(int) */
@ -976,6 +977,37 @@ struct retro_hw_render_context_negotiation_interface
* so it will be used after SET_HW_RENDER, but before the context_reset callback.
*/
/* Serialized state is incomplete in some way. Set if serialization is
* usable in typical end-user cases but should not be relied upon to
* implement frame-sensitive frontend features such as netplay or
* rerecording. */
#define RETRO_SERIALIZATION_QUIRK_INCOMPLETE (1 << 0)
/* The core must spend some time initializing before serialization is
* supported. retro_serialize() will initially fail; retro_unserialize()
* and retro_serialize_size() may or may not work correctly either. */
#define RETRO_SERIALIZATION_QUIRK_MUST_INITIALIZE (1 << 1)
/* Serialization size may change within a session. */
#define RETRO_SERIALIZATION_QUIRK_CORE_VARIABLE_SIZE (1 << 2)
/* Set by the frontend to acknowledge that it supports variable-sized
* states. */
#define RETRO_SERIALIZATION_QUIRK_FRONT_VARIABLE_SIZE (1 << 3)
/* Serialized state can only be loaded during the same session. */
#define RETRO_SERIALIZATION_QUIRK_SINGLE_SESSION (1 << 4)
/* Serialized state cannot be loaded on an architecture with a different
* endianness from the one it was saved on. */
#define RETRO_SERIALIZATION_QUIRK_ENDIAN_DEPENDENT (1 << 5)
/* Serialized state cannot be loaded on a different platform from the one it
* was saved on for reasons other than endianness, such as word size
* dependence */
#define RETRO_SERIALIZATION_QUIRK_PLATFORM_DEPENDENT (1 << 6)
#define RETRO_ENVIRONMENT_SET_SERIALIZATION_QUIRKS 44
/* uint64_t * --
* Sets quirk flags associated with serialization. The frontend will zero any flags it doesn't
* recognize or support. Should be set in either retro_init or retro_load_game, but not both.
*/
#define RETRO_MEMDESC_CONST (1 << 0) /* The frontend will never change this memory area once retro_load_game has returned. */
#define RETRO_MEMDESC_BIGENDIAN (1 << 1) /* The memory area contains big endian data. Default is little endian. */
#define RETRO_MEMDESC_ALIGN_2 (1 << 16) /* All memory access in this area is aligned to their own size, or 2, whichever is smaller. */
@ -1284,6 +1316,8 @@ struct retro_log_callback
#define RETRO_SIMD_VFPV4 (1 << 17)
#define RETRO_SIMD_POPCNT (1 << 18)
#define RETRO_SIMD_MOVBE (1 << 19)
#define RETRO_SIMD_CMOV (1 << 20)
#define RETRO_SIMD_ASIMD (1 << 21)
typedef uint64_t retro_perf_tick_t;
typedef int64_t retro_time_t;
@ -1657,7 +1691,8 @@ struct retro_hw_render_callback
* be providing preallocated framebuffers. */
retro_hw_get_current_framebuffer_t get_current_framebuffer;
/* Set by frontend. */
/* Set by frontend.
* Can return all relevant functions, including glClear on Windows. */
retro_hw_get_proc_address_t get_proc_address;
/* Set if render buffers should have depth component attached.