Tested with qemu-system-riscv64 and Ubuntu as the guest OS.
このコミットが含まれているのは:
コミット
e369049d0a
|
@ -21,6 +21,8 @@
|
|||
#include "ppc64v2.c"
|
||||
#elif defined(_ARCH_PPC) && !defined(__LITTLE_ENDIAN__)
|
||||
#include "ppc.c"
|
||||
#elif defined(__riscv)
|
||||
#include "riscv.c"
|
||||
#elif defined(_WIN32)
|
||||
#include "fiber.c"
|
||||
#else
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
#define LIBCO_C
|
||||
#include "libco.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static thread_local uint64_t co_active_buffer[64];
|
||||
static thread_local cothread_t co_active_handle = 0;
|
||||
|
||||
#if __riscv_xlen == 32
|
||||
#define I_STORE "sw"
|
||||
#define I_LOAD "lw"
|
||||
#elif __riscv_xlen == 64
|
||||
#define I_STORE "sd"
|
||||
#define I_LOAD "ld"
|
||||
#else
|
||||
#error Unsupported RISC-V XLEN
|
||||
#endif
|
||||
|
||||
#if !defined(__riscv_flen)
|
||||
#define F_STORE "#"
|
||||
#define F_LOAD "#"
|
||||
#elif __riscv_flen == 32
|
||||
#define F_STORE "fsw"
|
||||
#define F_LOAD "flw"
|
||||
#elif __riscv_flen == 64
|
||||
#define F_STORE "fsd"
|
||||
#define F_LOAD "fld"
|
||||
#else
|
||||
#error Unsupported RISC-V FLEN
|
||||
#endif
|
||||
|
||||
__attribute__((naked))
|
||||
static void co_swap(cothread_t active, cothread_t previous) {
|
||||
__asm__(
|
||||
I_STORE " ra, 0 *8(a1)\n"
|
||||
I_STORE " sp, 1 *8(a1)\n"
|
||||
I_STORE " s0, 2 *8(a1)\n"
|
||||
I_STORE " s1, 3 *8(a1)\n"
|
||||
I_STORE " s2, 4 *8(a1)\n"
|
||||
I_STORE " s3, 5 *8(a1)\n"
|
||||
I_STORE " s4, 6 *8(a1)\n"
|
||||
I_STORE " s5, 7 *8(a1)\n"
|
||||
I_STORE " s6, 8 *8(a1)\n"
|
||||
I_STORE " s7, 9 *8(a1)\n"
|
||||
I_STORE " s8, 10*8(a1)\n"
|
||||
I_STORE " s9, 11*8(a1)\n"
|
||||
I_STORE " s10, 12*8(a1)\n"
|
||||
I_STORE " s11, 13*8(a1)\n"
|
||||
|
||||
F_STORE " fs0, 14*8(a1)\n"
|
||||
F_STORE " fs1, 15*8(a1)\n"
|
||||
F_STORE " fs2, 16*8(a1)\n"
|
||||
F_STORE " fs3, 17*8(a1)\n"
|
||||
F_STORE " fs4, 18*8(a1)\n"
|
||||
F_STORE " fs5, 19*8(a1)\n"
|
||||
F_STORE " fs6, 20*8(a1)\n"
|
||||
F_STORE " fs7, 21*8(a1)\n"
|
||||
F_STORE " fs8, 22*8(a1)\n"
|
||||
F_STORE " fs9, 23*8(a1)\n"
|
||||
F_STORE " fs10, 24*8(a1)\n"
|
||||
F_STORE " fs11, 25*8(a1)\n"
|
||||
|
||||
I_LOAD " ra, 0 *8(a0)\n"
|
||||
I_LOAD " sp, 1 *8(a0)\n"
|
||||
I_LOAD " s0, 2 *8(a0)\n"
|
||||
I_LOAD " s1, 3 *8(a0)\n"
|
||||
I_LOAD " s2, 4 *8(a0)\n"
|
||||
I_LOAD " s3, 5 *8(a0)\n"
|
||||
I_LOAD " s4, 6 *8(a0)\n"
|
||||
I_LOAD " s5, 7 *8(a0)\n"
|
||||
I_LOAD " s6, 8 *8(a0)\n"
|
||||
I_LOAD " s7, 9 *8(a0)\n"
|
||||
I_LOAD " s8, 10*8(a0)\n"
|
||||
I_LOAD " s9, 11*8(a0)\n"
|
||||
I_LOAD " s10, 12*8(a0)\n"
|
||||
I_LOAD " s11, 13*8(a0)\n"
|
||||
|
||||
F_LOAD " fs0, 14*8(a0)\n"
|
||||
F_LOAD " fs1, 15*8(a0)\n"
|
||||
F_LOAD " fs2, 16*8(a0)\n"
|
||||
F_LOAD " fs3, 17*8(a0)\n"
|
||||
F_LOAD " fs4, 18*8(a0)\n"
|
||||
F_LOAD " fs5, 19*8(a0)\n"
|
||||
F_LOAD " fs6, 20*8(a0)\n"
|
||||
F_LOAD " fs7, 21*8(a0)\n"
|
||||
F_LOAD " fs8, 22*8(a0)\n"
|
||||
F_LOAD " fs9, 23*8(a0)\n"
|
||||
F_LOAD " fs10, 24*8(a0)\n"
|
||||
F_LOAD " fs11, 25*8(a0)\n"
|
||||
|
||||
"ret\n"
|
||||
);
|
||||
}
|
||||
|
||||
static void co_entrypoint(cothread_t handle) {
|
||||
uint64_t* buffer = (uint64_t*)handle;
|
||||
void (*entrypoint)(void) = (void (*)(void))(uintptr_t)buffer[3];
|
||||
entrypoint();
|
||||
abort(); /* called only if cothread_t entrypoint returns */
|
||||
}
|
||||
|
||||
cothread_t co_active() {
|
||||
if(!co_active_handle) co_active_handle = &co_active_buffer;
|
||||
return co_active_handle;
|
||||
}
|
||||
|
||||
cothread_t co_derive(void* memory, unsigned int size, void (*entrypoint)(void)) {
|
||||
uint64_t* handle;
|
||||
if(!co_active_handle) co_active_handle = &co_active_buffer;
|
||||
|
||||
if(handle = (uint64_t*)memory) {
|
||||
unsigned int offset = (size & ~15);
|
||||
uint64_t* p = (uint64_t*)((uint8_t*)handle + offset);
|
||||
*(uintptr_t*)&handle[0] = (uintptr_t)co_entrypoint; /* ra (return address) */
|
||||
*(uintptr_t*)&handle[1] = (uintptr_t)p; /* sp (stack pointer) */
|
||||
*(uintptr_t*)&handle[2] = (uintptr_t)p; /* s0 (frame pointer) */
|
||||
*(uintptr_t*)&handle[3] = (uintptr_t)entrypoint; /* s1 (entry point) */
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
|
||||
void* memory = malloc(size);
|
||||
if(!memory) return (cothread_t)0;
|
||||
return co_derive(memory, size, entrypoint);
|
||||
}
|
||||
|
||||
void co_delete(cothread_t handle) {
|
||||
free(handle);
|
||||
}
|
||||
|
||||
void co_switch(cothread_t handle) {
|
||||
cothread_t co_previous_handle = co_active_handle;
|
||||
co_swap(co_active_handle = handle, co_previous_handle);
|
||||
}
|
||||
|
||||
int co_serializable() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -101,6 +101,10 @@ else
|
|||
machine := arm32
|
||||
else ifneq ($(filter powerpc64-% powerpc64le-%,$(machine_str)),)
|
||||
machine := ppc64
|
||||
else ifneq ($(filter riscv64-%,$(machine_str)),)
|
||||
machine := rv64
|
||||
else ifneq ($(filter riscv32-%,$(machine_str)),)
|
||||
machine := rv32
|
||||
endif
|
||||
|
||||
# detect clang with msvc target
|
||||
|
|
|
@ -188,6 +188,8 @@ namespace nall {
|
|||
static constexpr bool arm32 = 0;
|
||||
static constexpr bool ppc64 = 0;
|
||||
static constexpr bool ppc32 = 0;
|
||||
static constexpr bool rv64 = 0;
|
||||
static constexpr bool rv32 = 0;
|
||||
};
|
||||
#elif defined(__amd64__) || defined(_M_AMD64)
|
||||
#define ARCHITECTURE_AMD64
|
||||
|
@ -201,6 +203,8 @@ namespace nall {
|
|||
static constexpr bool arm32 = 0;
|
||||
static constexpr bool ppc64 = 0;
|
||||
static constexpr bool ppc32 = 0;
|
||||
static constexpr bool rv64 = 0;
|
||||
static constexpr bool rv32 = 0;
|
||||
};
|
||||
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||
#define ARCHITECTURE_ARM64
|
||||
|
@ -214,6 +218,8 @@ namespace nall {
|
|||
static constexpr bool arm32 = 0;
|
||||
static constexpr bool ppc64 = 0;
|
||||
static constexpr bool ppc32 = 0;
|
||||
static constexpr bool rv64 = 0;
|
||||
static constexpr bool rv32 = 0;
|
||||
};
|
||||
#elif defined(__arm__)
|
||||
#define ARCHITECTURE_ARM32
|
||||
|
@ -224,6 +230,8 @@ namespace nall {
|
|||
static constexpr bool arm32 = 1;
|
||||
static constexpr bool ppc64 = 0;
|
||||
static constexpr bool ppc32 = 0;
|
||||
static constexpr bool rv64 = 0;
|
||||
static constexpr bool rv32 = 0;
|
||||
};
|
||||
#elif defined(__ppc64__) || defined(_ARCH_PPC64)
|
||||
#define ARCHITECTURE_PPC64
|
||||
|
@ -234,6 +242,8 @@ namespace nall {
|
|||
static constexpr bool arm32 = 0;
|
||||
static constexpr bool ppc64 = 1;
|
||||
static constexpr bool ppc32 = 0;
|
||||
static constexpr bool rv64 = 0;
|
||||
static constexpr bool rv32 = 0;
|
||||
};
|
||||
#elif defined(__ppc__) || defined(_ARCH_PPC) || defined(_M_PPC)
|
||||
#define ARCHITECTURE_PPC32
|
||||
|
@ -244,6 +254,32 @@ namespace nall {
|
|||
static constexpr bool arm32 = 0;
|
||||
static constexpr bool ppc64 = 0;
|
||||
static constexpr bool ppc32 = 1;
|
||||
static constexpr bool rv64 = 0;
|
||||
static constexpr bool rv32 = 0;
|
||||
};
|
||||
#elif defined(__riscv) && __riscv_xlen == 64
|
||||
#define ARCHITECTURE_RV64
|
||||
struct Architecture {
|
||||
static constexpr bool x86 = 0;
|
||||
static constexpr bool amd64 = 0;
|
||||
static constexpr bool arm64 = 0;
|
||||
static constexpr bool arm32 = 0;
|
||||
static constexpr bool ppc64 = 0;
|
||||
static constexpr bool ppc32 = 0;
|
||||
static constexpr bool rv64 = 1;
|
||||
static constexpr bool rv32 = 0;
|
||||
};
|
||||
#elif defined(__riscv) && __riscv_xlen == 32
|
||||
#define ARCHITECTURE_RV32
|
||||
struct Architecture {
|
||||
static constexpr bool x86 = 0;
|
||||
static constexpr bool amd64 = 0;
|
||||
static constexpr bool arm64 = 0;
|
||||
static constexpr bool arm32 = 0;
|
||||
static constexpr bool ppc64 = 0;
|
||||
static constexpr bool ppc32 = 0;
|
||||
static constexpr bool rv64 = 0;
|
||||
static constexpr bool rv32 = 1;
|
||||
};
|
||||
#else
|
||||
#error "unable to detect architecture"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#if defined(SLJIT)
|
||||
namespace nall::recompiler {
|
||||
struct generic {
|
||||
static constexpr bool supported = Architecture::amd64 | Architecture::arm64 | Architecture::ppc64;
|
||||
static constexpr bool supported = Architecture::amd64 | Architecture::arm64 | Architecture::ppc64 | Architecture::rv64;
|
||||
|
||||
bump_allocator& allocator;
|
||||
sljit_compiler* compiler = nullptr;
|
||||
|
|
読み込み中…
新しいイシューから参照