Skip to content

Commit

Permalink
Update libco
Browse files Browse the repository at this point in the history
inactive123 committed Apr 6, 2022
1 parent 8861888 commit 4c293f3
Showing 7 changed files with 218 additions and 47 deletions.
2 changes: 1 addition & 1 deletion core/libretro-common/include/libco.h
Original file line number Diff line number Diff line change
@@ -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).
2 changes: 1 addition & 1 deletion core/libretro-common/libco/aarch64.c
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
#include <string.h>
#include <stdint.h>

#ifndef IOS
#ifndef __APPLE__
#include <malloc.h>
#endif

93 changes: 49 additions & 44 deletions core/libretro-common/libco/amd64.c
Original file line number Diff line number Diff line change
@@ -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>
6 changes: 5 additions & 1 deletion core/libretro-common/libco/libco.c
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ void genode_free_secondary_stack(void *stack);
#endif

#if defined _MSC_VER
#include <windows.h>
#include <Windows.h>
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
#include "fiber.c"
#elif defined _M_IX86
@@ -29,6 +29,10 @@ void genode_free_secondary_stack(void *stack);
#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 changes: 66 additions & 0 deletions core/libretro-common/libco/ps2.c
Original file line number Diff line number Diff line change
@@ -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 changes: 55 additions & 0 deletions core/libretro-common/libco/ps3.S
Original file line number Diff line number Diff line change
@@ -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 changes: 41 additions & 0 deletions core/libretro-common/libco/psp1.c
Original file line number Diff line number Diff line change
@@ -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();
}

0 comments on commit 4c293f3

Please sign in to comment.