mirror of
https://github.com/Pecusx/libretro-atari800.git
synced 2026-05-20 22:33:22 +02:00
Update libretro-common
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2010-2016 The RetroArch team
|
/* Copyright (C) 2010-2018 The RetroArch team
|
||||||
*
|
*
|
||||||
* ---------------------------------------------------------------------------------------
|
* ---------------------------------------------------------------------------------------
|
||||||
* The following license statement only applies to this file (libco.h).
|
* The following license statement only applies to this file (libco.h).
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
libco.aarch64 (2017-06-26)
|
||||||
|
author: webgeek1234
|
||||||
|
license: public domain
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LIBCO_C
|
||||||
|
#include "libco.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifndef IOS
|
||||||
|
#include <malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static thread_local uint64_t co_active_buffer[64];
|
||||||
|
static thread_local cothread_t co_active_handle;
|
||||||
|
|
||||||
|
asm (
|
||||||
|
".globl co_switch_aarch64\n"
|
||||||
|
".globl _co_switch_aarch64\n"
|
||||||
|
"co_switch_aarch64:\n"
|
||||||
|
"_co_switch_aarch64:\n"
|
||||||
|
" stp x8, x9, [x1]\n"
|
||||||
|
" stp x10, x11, [x1, #16]\n"
|
||||||
|
" stp x12, x13, [x1, #32]\n"
|
||||||
|
" stp x14, x15, [x1, #48]\n"
|
||||||
|
" str x19, [x1, #72]\n"
|
||||||
|
" stp x20, x21, [x1, #80]\n"
|
||||||
|
" stp x22, x23, [x1, #96]\n"
|
||||||
|
" stp x24, x25, [x1, #112]\n"
|
||||||
|
" stp x26, x27, [x1, #128]\n"
|
||||||
|
" stp x28, x29, [x1, #144]\n"
|
||||||
|
" mov x16, sp\n"
|
||||||
|
" stp x16, x30, [x1, #160]\n"
|
||||||
|
|
||||||
|
" ldp x8, x9, [x0]\n"
|
||||||
|
" ldp x10, x11, [x0, #16]\n"
|
||||||
|
" ldp x12, x13, [x0, #32]\n"
|
||||||
|
" ldp x14, x15, [x0, #48]\n"
|
||||||
|
" ldr x19, [x0, #72]\n"
|
||||||
|
" ldp x20, x21, [x0, #80]\n"
|
||||||
|
" ldp x22, x23, [x0, #96]\n"
|
||||||
|
" ldp x24, x25, [x0, #112]\n"
|
||||||
|
" ldp x26, x27, [x0, #128]\n"
|
||||||
|
" ldp x28, x29, [x0, #144]\n"
|
||||||
|
" ldp x16, x17, [x0, #160]\n"
|
||||||
|
" mov sp, x16\n"
|
||||||
|
" br x17\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
/* ASM */
|
||||||
|
void co_switch_aarch64(cothread_t handle, cothread_t current);
|
||||||
|
|
||||||
|
static void crash(void)
|
||||||
|
{
|
||||||
|
/* Called only if cothread_t entrypoint returns. */
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
cothread_t co_create(unsigned int size, void (*entrypoint)(void))
|
||||||
|
{
|
||||||
|
size = (size + 1023) & ~1023;
|
||||||
|
cothread_t handle = 0;
|
||||||
|
#if HAVE_POSIX_MEMALIGN >= 1
|
||||||
|
if (posix_memalign(&handle, 1024, size + 512) < 0)
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
handle = memalign(1024, size + 512);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!handle)
|
||||||
|
return handle;
|
||||||
|
|
||||||
|
uint64_t *ptr = (uint64_t*)handle;
|
||||||
|
/* Non-volatiles. */
|
||||||
|
ptr[0] = 0; /* x8 */
|
||||||
|
ptr[1] = 0; /* x9 */
|
||||||
|
ptr[2] = 0; /* x10 */
|
||||||
|
ptr[3] = 0; /* x11 */
|
||||||
|
ptr[4] = 0; /* x12 */
|
||||||
|
ptr[5] = 0; /* x13 */
|
||||||
|
ptr[6] = 0; /* x14 */
|
||||||
|
ptr[7] = 0; /* x15 */
|
||||||
|
ptr[8] = 0; /* padding */
|
||||||
|
ptr[9] = 0; /* x19 */
|
||||||
|
ptr[10] = 0; /* x20 */
|
||||||
|
ptr[11] = 0; /* x21 */
|
||||||
|
ptr[12] = 0; /* x22 */
|
||||||
|
ptr[13] = 0; /* x23 */
|
||||||
|
ptr[14] = 0; /* x24 */
|
||||||
|
ptr[15] = 0; /* x25 */
|
||||||
|
ptr[16] = 0; /* x26 */
|
||||||
|
ptr[17] = 0; /* x27 */
|
||||||
|
ptr[18] = 0; /* x28 */
|
||||||
|
ptr[20] = (uintptr_t)ptr + size + 512 - 16; /* x30, stack pointer */
|
||||||
|
ptr[19] = ptr[20]; /* x29, frame pointer */
|
||||||
|
ptr[21] = (uintptr_t)entrypoint; /* PC (link register x31 gets saved here). */
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
cothread_t co_active(void)
|
||||||
|
{
|
||||||
|
if (!co_active_handle)
|
||||||
|
co_active_handle = co_active_buffer;
|
||||||
|
return co_active_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void co_delete(cothread_t handle)
|
||||||
|
{
|
||||||
|
free(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void co_switch(cothread_t handle)
|
||||||
|
{
|
||||||
|
cothread_t co_previous_handle = co_active();
|
||||||
|
co_switch_aarch64(co_active_handle = handle, co_previous_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ static unsigned char co_swap_function[] = {
|
|||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
void co_init(void)
|
static void co_init(void)
|
||||||
{
|
{
|
||||||
DWORD old_privileges;
|
DWORD old_privileges;
|
||||||
VirtualProtect(co_swap_function,
|
VirtualProtect(co_swap_function,
|
||||||
@@ -105,7 +105,7 @@ static unsigned char co_swap_function[] = {
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
void co_init(void)
|
static void co_init(void)
|
||||||
{
|
{
|
||||||
unsigned long long addr = (unsigned long long)co_swap_function;
|
unsigned long long addr = (unsigned long long)co_swap_function;
|
||||||
unsigned long long base = addr - (addr % sysconf(_SC_PAGESIZE));
|
unsigned long long base = addr - (addr % sysconf(_SC_PAGESIZE));
|
||||||
@@ -113,7 +113,7 @@ void co_init(void)
|
|||||||
mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC);
|
mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void co_init(void) {}
|
static void co_init(void) {}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ extern "C" {
|
|||||||
static thread_local uint32_t co_active_buffer[64];
|
static thread_local uint32_t co_active_buffer[64];
|
||||||
static thread_local cothread_t co_active_handle;
|
static thread_local cothread_t co_active_handle;
|
||||||
|
|
||||||
asm (
|
__asm__ (
|
||||||
#if defined(__thumb2__)
|
#if defined(__thumb2__)
|
||||||
".thumb\n"
|
".thumb\n"
|
||||||
".align 2\n"
|
".align 2\n"
|
||||||
@@ -44,7 +44,7 @@ asm (
|
|||||||
".globl co_switch_arm\n"
|
".globl co_switch_arm\n"
|
||||||
".globl _co_switch_arm\n"
|
".globl _co_switch_arm\n"
|
||||||
"co_switch_arm:\n"
|
"co_switch_arm:\n"
|
||||||
"_co_switch_arm:\n"
|
"_co_switch_arm:\n"
|
||||||
" stmia r1!, {r4, r5, r6, r7, r8, r9, r10, r11, sp, lr}\n"
|
" stmia r1!, {r4, r5, r6, r7, r8, r9, r10, r11, sp, lr}\n"
|
||||||
" ldmia r0!, {r4, r5, r6, r7, r8, r9, r10, r11, sp, pc}\n"
|
" ldmia r0!, {r4, r5, r6, r7, r8, r9, r10, r11, sp, pc}\n"
|
||||||
#endif
|
#endif
|
||||||
@@ -53,12 +53,6 @@ asm (
|
|||||||
/* ASM */
|
/* ASM */
|
||||||
void co_switch_arm(cothread_t handle, cothread_t current);
|
void co_switch_arm(cothread_t handle, cothread_t current);
|
||||||
|
|
||||||
static void crash(void)
|
|
||||||
{
|
|
||||||
/* Called only if cothread_t entrypoint returns. */
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
cothread_t co_create(unsigned int size, void (*entrypoint)(void))
|
cothread_t co_create(unsigned int size, void (*entrypoint)(void))
|
||||||
{
|
{
|
||||||
size = (size + 1023) & ~1023;
|
size = (size + 1023) & ~1023;
|
||||||
|
|||||||
@@ -26,7 +26,11 @@ cothread_t co_active(void)
|
|||||||
{
|
{
|
||||||
if(!co_active_)
|
if(!co_active_)
|
||||||
{
|
{
|
||||||
|
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
||||||
|
ConvertThreadToFiberEx(0, FIBER_FLAG_FLOAT_SWITCH);
|
||||||
|
#else
|
||||||
ConvertThreadToFiber(0);
|
ConvertThreadToFiber(0);
|
||||||
|
#endif
|
||||||
co_active_ = GetCurrentFiber();
|
co_active_ = GetCurrentFiber();
|
||||||
}
|
}
|
||||||
return co_active_;
|
return co_active_;
|
||||||
@@ -36,10 +40,19 @@ cothread_t co_create(unsigned int heapsize, void (*coentry)(void))
|
|||||||
{
|
{
|
||||||
if(!co_active_)
|
if(!co_active_)
|
||||||
{
|
{
|
||||||
|
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
||||||
|
ConvertThreadToFiberEx(0, FIBER_FLAG_FLOAT_SWITCH);
|
||||||
|
#else
|
||||||
ConvertThreadToFiber(0);
|
ConvertThreadToFiber(0);
|
||||||
|
#endif
|
||||||
co_active_ = GetCurrentFiber();
|
co_active_ = GetCurrentFiber();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
||||||
|
return (cothread_t)CreateFiberEx(heapsize, heapsize, FIBER_FLAG_FLOAT_SWITCH, co_thunk, (void*)coentry);
|
||||||
|
#else
|
||||||
return (cothread_t)CreateFiber(heapsize, co_thunk, (void*)coentry);
|
return (cothread_t)CreateFiber(heapsize, co_thunk, (void*)coentry);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void co_delete(cothread_t cothread)
|
void co_delete(cothread_t cothread)
|
||||||
|
|||||||
@@ -4,20 +4,33 @@
|
|||||||
license: public domain
|
license: public domain
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(__GNUC__) && defined(__i386__) || (defined(_MSC_VER) && defined(_M_IX86))
|
#if defined _MSC_VER
|
||||||
#include "x86.c"
|
#include <Windows.h>
|
||||||
#elif defined(__GNUC__) && defined(__amd64__) || (defined(_MSC_VER) && defined(_M_AMD64))
|
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
||||||
#include "amd64.c"
|
#include "fiber.c"
|
||||||
#elif defined(__GNUC__) && defined(_ARCH_PPC)
|
#elif defined _M_IX86
|
||||||
#include "ppc.c"
|
#include "x86.c"
|
||||||
#elif defined(VITA)
|
#elif defined _M_AMD64
|
||||||
#include "scefiber.c"
|
#include "amd64.c"
|
||||||
#elif defined(__GNUC__) && (defined(__ARM_EABI__) || defined(__arm__))
|
#else
|
||||||
#include "armeabi.c"
|
#include "fiber.c"
|
||||||
#elif defined(__GNUC__)
|
#endif
|
||||||
#include "sjlj.c"
|
#elif defined __GNUC__
|
||||||
#elif defined(_MSC_VER)
|
#if defined __i386__
|
||||||
#include "fiber.c"
|
#include "x86.c"
|
||||||
|
#elif defined __amd64__
|
||||||
|
#include "amd64.c"
|
||||||
|
#elif defined _ARCH_PPC
|
||||||
|
#include "ppc.c"
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
#include "aarch64.c"
|
||||||
|
#elif defined VITA
|
||||||
|
#include "scefiber.c"
|
||||||
|
#elif defined(__ARM_EABI__) || defined(__arm__)
|
||||||
|
#include "armeabi.c"
|
||||||
|
#else
|
||||||
|
#include "sjlj.c"
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#error "libco: unsupported processor, compiler or operating system"
|
#error "libco: unsupported processor, compiler or operating system"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ or are directly to function */
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Swap code is in ppc.S */
|
/* Swap code is in ppc.S */
|
||||||
void co_swap_asm( cothread_t, cothread_t );
|
void co_swap_asm( cothread_t, cothread_t );
|
||||||
#define CO_SWAP_ASM( x, y ) co_swap_asm( x, y )
|
#define CO_SWAP_ASM( x, y ) co_swap_asm( x, y )
|
||||||
@@ -285,15 +285,15 @@ static const uint32_t libco_ppc_code [] = {
|
|||||||
static uint32_t* co_create_( unsigned size, uintptr_t entry )
|
static uint32_t* co_create_( unsigned size, uintptr_t entry )
|
||||||
{
|
{
|
||||||
uint32_t* t = (uint32_t*) malloc( size );
|
uint32_t* t = (uint32_t*) malloc( size );
|
||||||
|
|
||||||
(void) entry;
|
(void) entry;
|
||||||
|
|
||||||
#if LIBCO_PPCDESC
|
#if LIBCO_PPCDESC
|
||||||
if ( t )
|
if ( t )
|
||||||
{
|
{
|
||||||
/* Copy entry's descriptor */
|
/* Copy entry's descriptor */
|
||||||
memcpy( t, (void*) entry, sizeof (void*) * 3 );
|
memcpy( t, (void*) entry, sizeof (void*) * 3 );
|
||||||
|
|
||||||
/* Set function pointer to swap routine */
|
/* Set function pointer to swap routine */
|
||||||
#ifdef LIBCO_PPC_ASM
|
#ifdef LIBCO_PPC_ASM
|
||||||
*(const void**) t = *(void**) &co_swap_asm;
|
*(const void**) t = *(void**) &co_swap_asm;
|
||||||
@@ -302,7 +302,7 @@ static uint32_t* co_create_( unsigned size, uintptr_t entry )
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,38 +310,38 @@ cothread_t co_create( unsigned int size, void (*entry_)( void ) )
|
|||||||
{
|
{
|
||||||
uintptr_t entry = (uintptr_t) entry_;
|
uintptr_t entry = (uintptr_t) entry_;
|
||||||
uint32_t* t = NULL;
|
uint32_t* t = NULL;
|
||||||
|
|
||||||
/* Be sure main thread was successfully allocated */
|
/* Be sure main thread was successfully allocated */
|
||||||
if ( co_active() )
|
if ( co_active() )
|
||||||
{
|
{
|
||||||
size += state_size + above_stack + stack_align;
|
size += state_size + above_stack + stack_align;
|
||||||
t = co_create_( size, entry );
|
t = co_create_( size, entry );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( t )
|
if ( t )
|
||||||
{
|
{
|
||||||
uintptr_t sp;
|
uintptr_t sp;
|
||||||
int shift;
|
int shift;
|
||||||
|
|
||||||
/* Save current registers into new thread, so that any special ones will
|
/* Save current registers into new thread, so that any special ones will
|
||||||
have proper values when thread is begun */
|
have proper values when thread is begun */
|
||||||
CO_SWAP_ASM( t, t );
|
CO_SWAP_ASM( t, t );
|
||||||
|
|
||||||
#if LIBCO_PPCDESC
|
#if LIBCO_PPCDESC
|
||||||
/* Get real address */
|
/* Get real address */
|
||||||
entry = (uintptr_t) *(void**) entry;
|
entry = (uintptr_t) *(void**) entry;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Put stack near end of block, and align */
|
/* Put stack near end of block, and align */
|
||||||
sp = (uintptr_t) t + size - above_stack;
|
sp = (uintptr_t) t + size - above_stack;
|
||||||
sp -= sp % stack_align;
|
sp -= sp % stack_align;
|
||||||
|
|
||||||
/* On PPC32, we save and restore GPRs as 32 bits. For PPC64, we
|
/* On PPC32, we save and restore GPRs as 32 bits. For PPC64, we
|
||||||
save and restore them as 64 bits, regardless of the size the ABI
|
save and restore them as 64 bits, regardless of the size the ABI
|
||||||
uses. So, we manually write pointers at the proper size. We always
|
uses. So, we manually write pointers at the proper size. We always
|
||||||
save and restore at the same address, and since PPC is big-endian,
|
save and restore at the same address, and since PPC is big-endian,
|
||||||
we must put the low byte first on PPC32. */
|
we must put the low byte first on PPC32. */
|
||||||
|
|
||||||
/* If uintptr_t is 32 bits, >>32 is undefined behavior, so we do two shifts
|
/* If uintptr_t is 32 bits, >>32 is undefined behavior, so we do two shifts
|
||||||
and don't have to care how many bits uintptr_t is. */
|
and don't have to care how many bits uintptr_t is. */
|
||||||
#if LIBCO_PPC64
|
#if LIBCO_PPC64
|
||||||
@@ -349,15 +349,15 @@ cothread_t co_create( unsigned int size, void (*entry_)( void ) )
|
|||||||
#else
|
#else
|
||||||
shift = 0;
|
shift = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set up so entry will be called on next swap */
|
/* Set up so entry will be called on next swap */
|
||||||
t [8] = (uint32_t) (entry >> shift >> shift);
|
t [8] = (uint32_t) (entry >> shift >> shift);
|
||||||
t [9] = (uint32_t) entry;
|
t [9] = (uint32_t) entry;
|
||||||
|
|
||||||
t [10] = (uint32_t) (sp >> shift >> shift);
|
t [10] = (uint32_t) (sp >> shift >> shift);
|
||||||
t [11] = (uint32_t) sp;
|
t [11] = (uint32_t) sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ extern "C" {
|
|||||||
0xe12fff1e, /* bx lr */
|
0xe12fff1e, /* bx lr */
|
||||||
};
|
};
|
||||||
|
|
||||||
void co_init()
|
static void co_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
void *base;
|
void *base;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ int32_t sceFiberSwitch(SceFiber* fiber, uint32_t argOnRunTo, uint32_t* argOnRun)
|
|||||||
|
|
||||||
int32_t sceFiberReturnToThread(uint32_t argOnReturn, uint32_t* argOnRun);
|
int32_t sceFiberReturnToThread(uint32_t argOnReturn, uint32_t* argOnRun);
|
||||||
|
|
||||||
void co_thunk(uint32_t argOnInitialize, uint32_t argOnRun)
|
static void co_thunk(uint32_t argOnInitialize, uint32_t argOnRun)
|
||||||
{
|
{
|
||||||
((void (*)(void))argOnInitialize)();
|
((void (*)(void))argOnInitialize)();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ static unsigned char co_swap_function[] = {
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
void co_init(void)
|
static void co_init(void)
|
||||||
{
|
{
|
||||||
DWORD old_privileges;
|
DWORD old_privileges;
|
||||||
VirtualProtect(co_swap_function,
|
VirtualProtect(co_swap_function,
|
||||||
@@ -54,7 +54,7 @@ void co_init(void)
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
void co_init(void)
|
static void co_init(void)
|
||||||
{
|
{
|
||||||
unsigned long addr = (unsigned long)co_swap_function;
|
unsigned long addr = (unsigned long)co_swap_function;
|
||||||
unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE));
|
unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE));
|
||||||
|
|||||||
Reference in New Issue
Block a user