mirror of
https://github.com/libretro/mame2016-libretro.git
synced 2024-11-27 02:30:46 +00:00
Update libco
This commit is contained in:
parent
bcff804632
commit
01058613a0
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2010-2018 The RetroArch team
|
||||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (libco.h).
|
||||
|
128
src/osd/retro/libretro-common/libco/aarch64.c
Normal file
128
src/osd/retro/libretro-common/libco/aarch64.c
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
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 __APPLE__
|
||||
#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
|
@ -25,51 +25,56 @@ static void (*co_swap)(cothread_t, cothread_t) = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* ABI: Win64 */
|
||||
/* On windows handle is allocated by malloc and there it's guaranteed to
|
||||
have at least 16-byte alignment. Hence we don't need to align
|
||||
it in order to use movaps. */
|
||||
static unsigned char co_swap_function[] = {
|
||||
0x48, 0x89, 0x22, /* mov [rdx],rsp */
|
||||
0x48, 0x8b, 0x21, /* mov rsp,[rcx] */
|
||||
0x58, /* pop rax */
|
||||
0x48, 0x89, 0x6a, 0x08, /* mov [rdx+0x8],rbp */
|
||||
0x48, 0x89, 0x72, 0x10, /* mov [rdx+0x10],rsi */
|
||||
0x48, 0x89, 0x7a, 0x18, /* mov [rdx+0x18],rdi */
|
||||
0x48, 0x89, 0x5a, 0x20, /* mov [rdx+0x20],rbx */
|
||||
0x4c, 0x89, 0x62, 0x28, /* mov [rdx+0x28],r12 */
|
||||
0x4c, 0x89, 0x6a, 0x30, /* mov [rdx+0x30],r13 */
|
||||
0x4c, 0x89, 0x72, 0x38, /* mov [rdx+0x38],r14 */
|
||||
0x4c, 0x89, 0x7a, 0x40, /* mov [rdx+0x40],r15 */
|
||||
0x48, 0x81, 0xc2, 0x80, 0x00, 0x00, 0x00, /* add rdx,0x80 */
|
||||
0x48, 0x83, 0xe2, 0xf0, /* and rdx,-0x10 */
|
||||
0x0f, 0x29, 0x32, /* movaps [rdx],xmm6 */
|
||||
0x0f, 0x29, 0x7a, 0x10, /* movaps [rdx+0x10],xmm7 */
|
||||
0x44, 0x0f, 0x29, 0x42, 0x20, /* movaps [rdx+0x20],xmm8 */
|
||||
0x44, 0x0f, 0x29, 0x4a, 0x30, /* movaps [rdx+0x30],xmm9 */
|
||||
0x44, 0x0f, 0x29, 0x52, 0x40, /* movaps [rdx+0x40],xmm10 */
|
||||
0x44, 0x0f, 0x29, 0x5a, 0x50, /* movaps [rdx+0x50],xmm11 */
|
||||
0x44, 0x0f, 0x29, 0x62, 0x60, /* movaps [rdx+0x60],xmm12 */
|
||||
0x44, 0x0f, 0x29, 0x6a, 0x70, /* movaps [rdx+0x70],xmm13 */
|
||||
0x44, 0x0f, 0x29, 0xb2, 0x80, 0x00, 0x00, 0x00, /* movaps [rdx+0x80],xmm14 */
|
||||
0x44, 0x0f, 0x29, 0xba, 0x90, 0x00, 0x00, 0x00, /* movaps [rdx+0x90],xmm15 */
|
||||
0x48, 0x8b, 0x69, 0x08, /* mov rbp,[rcx+0x8] */
|
||||
0x48, 0x8b, 0x71, 0x10, /* mov rsi,[rcx+0x10] */
|
||||
0x48, 0x8b, 0x79, 0x18, /* mov rdi,[rcx+0x18] */
|
||||
0x48, 0x8b, 0x59, 0x20, /* mov rbx,[rcx+0x20] */
|
||||
0x4c, 0x8b, 0x61, 0x28, /* mov r12,[rcx+0x28] */
|
||||
0x4c, 0x8b, 0x69, 0x30, /* mov r13,[rcx+0x30] */
|
||||
0x4c, 0x8b, 0x71, 0x38, /* mov r14,[rcx+0x38] */
|
||||
0x4c, 0x8b, 0x79, 0x40, /* mov r15,[rcx+0x40] */
|
||||
0x48, 0x81, 0xc1, 0x80, 0x00, 0x00, 0x00, /* add rcx,0x80 */
|
||||
0x48, 0x83, 0xe1, 0xf0, /* and rcx,-0x10 */
|
||||
0x0f, 0x29, 0x31, /* movaps [rcx],xmm6 */
|
||||
0x0f, 0x29, 0x79, 0x10, /* movaps [rcx+0x10],xmm7 */
|
||||
0x44, 0x0f, 0x29, 0x41, 0x20, /* movaps [rcx+0x20],xmm8 */
|
||||
0x44, 0x0f, 0x29, 0x49, 0x30, /* movaps [rcx+0x30],xmm9 */
|
||||
0x44, 0x0f, 0x29, 0x51, 0x40, /* movaps [rcx+0x40],xmm10 */
|
||||
0x44, 0x0f, 0x29, 0x59, 0x50, /* movaps [rcx+0x50],xmm11 */
|
||||
0x44, 0x0f, 0x29, 0x61, 0x60, /* movaps [rcx+0x60],xmm12 */
|
||||
0x44, 0x0f, 0x29, 0x69, 0x70, /* movaps [rcx+0x70],xmm13 */
|
||||
0x44, 0x0f, 0x29, 0xb1, 0x80, 0x00, 0x00, 0x00, /* movaps [rcx+0x80],xmm14 */
|
||||
0x44, 0x0f, 0x29, 0xb9, 0x90, 0x00, 0x00, 0x00, /* movaps [rcx+0x90],xmm15 */
|
||||
0xff, 0xe0, /* jmp rax */
|
||||
0x48, 0x89, 0x22, /* mov [rdx],rsp */
|
||||
0x48, 0x8b, 0x21, /* mov rsp,[rcx] */
|
||||
0x58, /* pop rax */
|
||||
0x48, 0x89, 0x6a, 0x08, /* mov [rdx+ 8],rbp */
|
||||
0x48, 0x89, 0x72, 0x10, /* mov [rdx+16],rsi */
|
||||
0x48, 0x89, 0x7a, 0x18, /* mov [rdx+24],rdi */
|
||||
0x48, 0x89, 0x5a, 0x20, /* mov [rdx+32],rbx */
|
||||
0x4c, 0x89, 0x62, 0x28, /* mov [rdx+40],r12 */
|
||||
0x4c, 0x89, 0x6a, 0x30, /* mov [rdx+48],r13 */
|
||||
0x4c, 0x89, 0x72, 0x38, /* mov [rdx+56],r14 */
|
||||
0x4c, 0x89, 0x7a, 0x40, /* mov [rdx+64],r15 */
|
||||
#if !defined(LIBCO_NO_SSE)
|
||||
0x0f, 0x29, 0x72, 0x50, /* movaps [rdx+ 80],xmm6 */
|
||||
0x0f, 0x29, 0x7a, 0x60, /* movaps [rdx+ 96],xmm7 */
|
||||
0x44, 0x0f, 0x29, 0x42, 0x70, /* movaps [rdx+112],xmm8 */
|
||||
0x48, 0x83, 0xc2, 0x70, /* add rdx,112 */
|
||||
0x44, 0x0f, 0x29, 0x4a, 0x10, /* movaps [rdx+ 16],xmm9 */
|
||||
0x44, 0x0f, 0x29, 0x52, 0x20, /* movaps [rdx+ 32],xmm10 */
|
||||
0x44, 0x0f, 0x29, 0x5a, 0x30, /* movaps [rdx+ 48],xmm11 */
|
||||
0x44, 0x0f, 0x29, 0x62, 0x40, /* movaps [rdx+ 64],xmm12 */
|
||||
0x44, 0x0f, 0x29, 0x6a, 0x50, /* movaps [rdx+ 80],xmm13 */
|
||||
0x44, 0x0f, 0x29, 0x72, 0x60, /* movaps [rdx+ 96],xmm14 */
|
||||
0x44, 0x0f, 0x29, 0x7a, 0x70, /* movaps [rdx+112],xmm15 */
|
||||
#endif
|
||||
0x48, 0x8b, 0x69, 0x08, /* mov rbp,[rcx+ 8] */
|
||||
0x48, 0x8b, 0x71, 0x10, /* mov rsi,[rcx+16] */
|
||||
0x48, 0x8b, 0x79, 0x18, /* mov rdi,[rcx+24] */
|
||||
0x48, 0x8b, 0x59, 0x20, /* mov rbx,[rcx+32] */
|
||||
0x4c, 0x8b, 0x61, 0x28, /* mov r12,[rcx+40] */
|
||||
0x4c, 0x8b, 0x69, 0x30, /* mov r13,[rcx+48] */
|
||||
0x4c, 0x8b, 0x71, 0x38, /* mov r14,[rcx+56] */
|
||||
0x4c, 0x8b, 0x79, 0x40, /* mov r15,[rcx+64] */
|
||||
#if !defined(LIBCO_NO_SSE)
|
||||
0x0f, 0x28, 0x71, 0x50, /* movaps xmm6, [rcx+ 80] */
|
||||
0x0f, 0x28, 0x79, 0x60, /* movaps xmm7, [rcx+ 96] */
|
||||
0x44, 0x0f, 0x28, 0x41, 0x70, /* movaps xmm8, [rcx+112] */
|
||||
0x48, 0x83, 0xc1, 0x70, /* add rcx,112 */
|
||||
0x44, 0x0f, 0x28, 0x49, 0x10, /* movaps xmm9, [rcx+ 16] */
|
||||
0x44, 0x0f, 0x28, 0x51, 0x20, /* movaps xmm10,[rcx+ 32] */
|
||||
0x44, 0x0f, 0x28, 0x59, 0x30, /* movaps xmm11,[rcx+ 48] */
|
||||
0x44, 0x0f, 0x28, 0x61, 0x40, /* movaps xmm12,[rcx+ 64] */
|
||||
0x44, 0x0f, 0x28, 0x69, 0x50, /* movaps xmm13,[rcx+ 80] */
|
||||
0x44, 0x0f, 0x28, 0x71, 0x60, /* movaps xmm14,[rcx+ 96] */
|
||||
0x44, 0x0f, 0x28, 0x79, 0x70, /* movaps xmm15,[rcx+112] */
|
||||
#endif
|
||||
0xff, 0xe0, /* jmp rax */
|
||||
};
|
||||
|
||||
#include <windows.h>
|
||||
@ -146,6 +151,15 @@ cothread_t co_create(unsigned int size, void (*entrypoint)(void))
|
||||
size += 512; /* allocate additional space for storage */
|
||||
size &= ~15; /* align stack to 16-byte boundary */
|
||||
|
||||
#ifdef __GENODE__
|
||||
if((handle = (cothread_t)genode_alloc_secondary_stack(size)))
|
||||
{
|
||||
long long *p = (long long*)((char*)handle); /* OS returns top of stack */
|
||||
*--p = (long long)crash; /* crash if entrypoint returns */
|
||||
*--p = (long long)entrypoint; /* start of function */
|
||||
*(long long*)handle = (long long)p; /* stack pointer */
|
||||
}
|
||||
#else
|
||||
if((handle = (cothread_t)malloc(size)))
|
||||
{
|
||||
long long *p = (long long*)((char*)handle + size); /* seek to top of stack */
|
||||
@ -153,13 +167,18 @@ cothread_t co_create(unsigned int size, void (*entrypoint)(void))
|
||||
*--p = (long long)entrypoint; /* start of function */
|
||||
*(long long*)handle = (long long)p; /* stack pointer */
|
||||
}
|
||||
#endif
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void co_delete(cothread_t handle)
|
||||
{
|
||||
#ifdef __GENODE__
|
||||
genode_free_secondary_stack(handle);
|
||||
#else
|
||||
free(handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CO_USE_INLINE_ASM
|
||||
|
@ -104,4 +104,3 @@ void co_switch(cothread_t handle)
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
29
src/osd/retro/libretro-common/libco/genode.cpp
Normal file
29
src/osd/retro/libretro-common/libco/genode.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
libco.genode_secondary_stack (2018-09-15)
|
||||
author: Emery Hemingway
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
/* Genode include */
|
||||
#include <base/thread.h>
|
||||
|
||||
/* Libco include */
|
||||
#include <libco.h>
|
||||
|
||||
extern "C"
|
||||
void *genode_alloc_secondary_stack(unsigned long stack_size)
|
||||
{
|
||||
try {
|
||||
return Genode::Thread::myself()->alloc_secondary_stack("libco", stack_size); }
|
||||
catch (...) {
|
||||
Genode::error("libco: failed to allocate ", stack_size, " byte secondary stack");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extern "C"
|
||||
void genode_free_secondary_stack(void *stack)
|
||||
{
|
||||
Genode::Thread::myself()->free_secondary_stack(stack);
|
||||
}
|
@ -4,6 +4,11 @@
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
#ifdef __GENODE__
|
||||
void *genode_alloc_secondary_stack(unsigned long stack_size);
|
||||
void genode_free_secondary_stack(void *stack);
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER
|
||||
#include <Windows.h>
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
||||
@ -24,6 +29,10 @@
|
||||
#include "ppc.c"
|
||||
#elif defined(__aarch64__)
|
||||
#include "aarch64.c"
|
||||
#elif defined(PS2)
|
||||
#include "ps2.c"
|
||||
#elif defined(PSP)
|
||||
#include "psp1.c"
|
||||
#elif defined VITA
|
||||
#include "scefiber.c"
|
||||
#elif defined(__ARM_EABI__) || defined(__arm__)
|
||||
|
66
src/osd/retro/libretro-common/libco/ps2.c
Normal file
66
src/osd/retro/libretro-common/libco/ps2.c
Normal file
@ -0,0 +1,66 @@
|
||||
#define LIBCO_C
|
||||
#include "libco.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <kernel.h>
|
||||
|
||||
/* Since cothread_t is a void pointer it must contain an address. We can't return a reference to a local variable
|
||||
* because it would go out of scope, so we create a static variable instead so we can return a reference to it.
|
||||
*/
|
||||
static int32_t active_thread_id = -1;
|
||||
extern void *_gp;
|
||||
|
||||
cothread_t co_active()
|
||||
{
|
||||
active_thread_id = GetThreadId();
|
||||
return &active_thread_id;
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int size, void (*entrypoint)(void))
|
||||
{
|
||||
/* Similar scenario as with active_thread_id except there will only be one active_thread_id while there could be many
|
||||
* new threads each with their own handle, so we create them on the heap instead and delete them manually when they're
|
||||
* no longer needed in co_delete().
|
||||
*/
|
||||
cothread_t handle = malloc(sizeof(cothread_t));
|
||||
ee_thread_t thread;
|
||||
|
||||
// u8 threadStack[size/8] __attribute__ ((aligned(16)));
|
||||
void *threadStack = (void *)malloc(size);
|
||||
|
||||
if ( threadStack== NULL)
|
||||
{
|
||||
printf("libco: ERROR: creating threadStack\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
thread.stack_size = size;
|
||||
thread.gp_reg = &_gp;
|
||||
thread.func = (void *)entrypoint;
|
||||
thread.stack = threadStack;
|
||||
thread.option = 0;
|
||||
thread.initial_priority = 1;
|
||||
|
||||
int32_t new_thread_id = CreateThread(&thread);
|
||||
if (new_thread_id < 0)
|
||||
printf("libco: ERROR: creating thread\n");
|
||||
|
||||
StartThread(new_thread_id, NULL);
|
||||
*(uint32_t *)handle = new_thread_id;
|
||||
return handle;
|
||||
}
|
||||
|
||||
void co_delete(cothread_t handle)
|
||||
{
|
||||
TerminateThread(*(uint32_t *)handle);
|
||||
DeleteThread(*(uint32_t *)handle);
|
||||
free(handle);
|
||||
}
|
||||
|
||||
void co_switch(cothread_t handle)
|
||||
{
|
||||
WakeupThread(*(uint32_t *)handle);
|
||||
/* Sleep the currently active thread so the new thread can start */
|
||||
SleepThread();
|
||||
}
|
55
src/osd/retro/libretro-common/libco/ps3.S
Normal file
55
src/osd/retro/libretro-common/libco/ps3.S
Normal file
@ -0,0 +1,55 @@
|
||||
.globl .co_swap_asm
|
||||
.globl co_swap_asm
|
||||
.type .co_swap_asm, @function
|
||||
.type co_swap_asm, @function
|
||||
.co_swap_asm:
|
||||
co_swap_asm:
|
||||
mfcr 8
|
||||
std 1,40(4)
|
||||
mflr 9
|
||||
std 14,72(4)
|
||||
std 15,80(4)
|
||||
std 16,88(4)
|
||||
std 17,96(4)
|
||||
std 18,104(4)
|
||||
std 19,112(4)
|
||||
std 20,120(4)
|
||||
std 21,128(4)
|
||||
std 22,136(4)
|
||||
std 23,144(4)
|
||||
std 24,152(4)
|
||||
std 25,160(4)
|
||||
std 26,168(4)
|
||||
std 27,176(4)
|
||||
std 28,184(4)
|
||||
std 29,192(4)
|
||||
std 30,200(4)
|
||||
std 31,208(4)
|
||||
std 9,32(4)
|
||||
ld 7,32(3)
|
||||
ld 1,40(3)
|
||||
bl swap
|
||||
trap
|
||||
swap: stw 8,48(4)
|
||||
lwz 6,48(3)
|
||||
mtctr 7
|
||||
ld 14,72(3)
|
||||
ld 15,80(3)
|
||||
ld 16,88(3)
|
||||
ld 17,96(3)
|
||||
ld 18,104(3)
|
||||
ld 19,112(3)
|
||||
ld 20,120(3)
|
||||
ld 21,128(3)
|
||||
ld 22,136(3)
|
||||
ld 23,144(3)
|
||||
ld 24,152(3)
|
||||
ld 25,160(3)
|
||||
ld 26,168(3)
|
||||
ld 27,176(3)
|
||||
ld 28,184(3)
|
||||
ld 29,192(3)
|
||||
ld 30,200(3)
|
||||
ld 31,208(3)
|
||||
mtcr 6
|
||||
bctr
|
41
src/osd/retro/libretro-common/libco/psp1.c
Normal file
41
src/osd/retro/libretro-common/libco/psp1.c
Normal file
@ -0,0 +1,41 @@
|
||||
#define LIBCO_C
|
||||
#include "libco.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <pspthreadman.h>
|
||||
|
||||
typedef void (*entrypoint_t)(void);
|
||||
|
||||
cothread_t co_active()
|
||||
{
|
||||
return (void *) sceKernelGetThreadId();
|
||||
}
|
||||
|
||||
static int thread_wrap(unsigned int argc, void *argp)
|
||||
{
|
||||
entrypoint_t entrypoint = *(entrypoint_t *) argp;
|
||||
sceKernelSleepThread();
|
||||
entrypoint();
|
||||
return 0;
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int size, void (*entrypoint)(void))
|
||||
{
|
||||
SceUID new_thread_id = sceKernelCreateThread("cothread", thread_wrap, 0x12, size, 0, NULL);
|
||||
sceKernelStartThread(new_thread_id, sizeof (entrypoint), &entrypoint);
|
||||
return (void *) new_thread_id;
|
||||
}
|
||||
|
||||
void co_delete(cothread_t handle)
|
||||
{
|
||||
SceUID id = (SceUID) handle;
|
||||
sceKernelTerminateDeleteThread(id);
|
||||
}
|
||||
|
||||
void co_switch(cothread_t handle)
|
||||
{
|
||||
SceUID id = (SceUID) handle;
|
||||
sceKernelWakeupThread(id);
|
||||
/* Sleep the currently active thread so the new thread can start */
|
||||
sceKernelSleepThread();
|
||||
}
|
113
src/osd/retro/libretro-common/libco/psp2.c
Normal file
113
src/osd/retro/libretro-common/libco/psp2.c
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
libco.arm (2015-06-18)
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
#define LIBCO_C
|
||||
#include "libco.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <psp2/kernel/sysmem.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FOUR_KB_ALIGN(x) align(x, 12)
|
||||
#define MB_ALIGN(x) align(x, 20)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline int align(int x, int n)
|
||||
{
|
||||
return (((x >> n) + 1) << n);
|
||||
}
|
||||
|
||||
static thread_local unsigned long co_active_buffer[64];
|
||||
static thread_local cothread_t co_active_handle = 0;
|
||||
static void(*co_swap)(cothread_t, cothread_t) = 0;
|
||||
static int block;
|
||||
static uint32_t co_swap_function[] = {
|
||||
0xe8a16ff0, /* stmia r1!, {r4-r11,sp,lr} */
|
||||
0xe8b0aff0, /* ldmia r0!, {r4-r11,sp,pc} */
|
||||
0xe12fff1e, /* bx lr */
|
||||
};
|
||||
|
||||
static void co_init(void)
|
||||
{
|
||||
int ret;
|
||||
void *base;
|
||||
|
||||
block = sceKernelAllocMemBlockForVM("libco",
|
||||
MB_ALIGN(FOUR_KB_ALIGN(sizeof co_swap_function)));
|
||||
if (block < 0)
|
||||
return;
|
||||
|
||||
/* get base address */
|
||||
ret = sceKernelGetMemBlockBase(block, &base);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
/* set domain to be writable by user */
|
||||
ret = sceKernelOpenVMDomain();
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
memcpy(base, co_swap_function, sizeof co_swap_function);
|
||||
|
||||
/* set domain back to read-only */
|
||||
ret = sceKernelCloseVMDomain();
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
/* flush icache */
|
||||
ret = sceKernelSyncVMDomain(block, base,
|
||||
MB_ALIGN(FOUR_KB_ALIGN(sizeof co_swap_function)));
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
co_swap = (void(*)(cothread_t, cothread_t))base;
|
||||
}
|
||||
|
||||
cothread_t co_active(void)
|
||||
{
|
||||
if (!co_active_handle) co_active_handle = &co_active_buffer;
|
||||
return co_active_handle;
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int size, void(*entrypoint)(void))
|
||||
{
|
||||
unsigned long* handle = 0;
|
||||
if (!co_swap)
|
||||
co_init();
|
||||
if (!co_active_handle) co_active_handle = &co_active_buffer;
|
||||
size += 256;
|
||||
size &= ~15;
|
||||
|
||||
if ((handle = (unsigned long*)malloc(size)))
|
||||
{
|
||||
unsigned long* p = (unsigned long*)((unsigned char*)handle + size);
|
||||
handle[8] = (unsigned long)p;
|
||||
handle[9] = (unsigned long)entrypoint;
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void co_delete(cothread_t handle)
|
||||
{
|
||||
free(handle);
|
||||
sceKernelFreeMemBlock(block);
|
||||
}
|
||||
|
||||
void co_switch(cothread_t handle)
|
||||
{
|
||||
cothread_t co_previous_handle = co_active_handle;
|
||||
co_swap(co_active_handle = handle, co_previous_handle);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
96
src/osd/retro/libretro-common/libco/scefiber.c
Normal file
96
src/osd/retro/libretro-common/libco/scefiber.c
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
libco.win (2016-09-06)
|
||||
authors: frangarcj
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
#define LIBCO_C
|
||||
#include <libco.h>
|
||||
#include <stdlib.h>
|
||||
#include <psp2/sysmodule.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static thread_local cothread_t co_active_ = 0;
|
||||
|
||||
typedef struct SceFiber {
|
||||
char reserved[128];
|
||||
} SceFiber __attribute__( ( aligned ( 8 ) ) ) ;
|
||||
|
||||
int32_t _sceFiberInitializeImpl(SceFiber* fiber, char* name, void* entry, uint32_t argOnInitialize, void* addrContext, int32_t sizeContext, void* params);
|
||||
|
||||
int32_t sceFiberFinalize(SceFiber* fiber);
|
||||
|
||||
int32_t sceFiberRun(SceFiber* fiber, uint32_t argOnRunTo, uint32_t* argOnRun);
|
||||
|
||||
int32_t sceFiberSwitch(SceFiber* fiber, uint32_t argOnRunTo, uint32_t* argOnRun);
|
||||
|
||||
int32_t sceFiberReturnToThread(uint32_t argOnReturn, uint32_t* argOnRun);
|
||||
|
||||
static void co_thunk(uint32_t argOnInitialize, uint32_t argOnRun)
|
||||
{
|
||||
((void (*)(void))argOnInitialize)();
|
||||
}
|
||||
|
||||
cothread_t co_active(void)
|
||||
{
|
||||
if(!co_active_)
|
||||
{
|
||||
sceSysmoduleLoadModule(SCE_SYSMODULE_FIBER);
|
||||
co_active_ = (cothread_t)1;
|
||||
}
|
||||
return co_active_;
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int heapsize, void (*coentry)(void))
|
||||
{
|
||||
SceFiber* tailFiber = malloc(sizeof(SceFiber));
|
||||
char * m_contextBuffer = malloc(sizeof(char)*heapsize);
|
||||
if(!co_active_)
|
||||
{
|
||||
sceSysmoduleLoadModule(SCE_SYSMODULE_FIBER);
|
||||
co_active_ = (cothread_t)1;
|
||||
}
|
||||
|
||||
//_sceFiberInitializeImpl
|
||||
int ret = _sceFiberInitializeImpl(tailFiber, "tailFiber", co_thunk, (uint32_t)coentry, (void*) m_contextBuffer, heapsize, NULL);
|
||||
if(ret==0){
|
||||
return (cothread_t)tailFiber;
|
||||
}else{
|
||||
return (cothread_t)ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void co_delete(cothread_t cothread)
|
||||
{
|
||||
if(cothread == (cothread_t)1){
|
||||
return;
|
||||
}
|
||||
sceFiberFinalize((SceFiber*)cothread);
|
||||
}
|
||||
|
||||
void co_switch(cothread_t cothread)
|
||||
{
|
||||
|
||||
uint32_t argOnReturn = 0;
|
||||
if(cothread == (cothread_t)1){
|
||||
co_active_ = cothread;
|
||||
sceFiberReturnToThread(0, NULL);
|
||||
}else{
|
||||
SceFiber* theFiber = (SceFiber*)cothread;
|
||||
if(co_active_ == (cothread_t)1){
|
||||
co_active_ = cothread;
|
||||
sceFiberRun(theFiber, 0, &argOnReturn);
|
||||
}else{
|
||||
co_active_ = cothread;
|
||||
sceFiberSwitch(theFiber, 0, &argOnReturn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user