Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows ARM support #545

Open
basharast opened this issue Feb 24, 2022 · 3 comments
Open

Windows ARM support #545

basharast opened this issue Feb 24, 2022 · 3 comments
Labels
enhancement New feature or request

Comments

@basharast
Copy link

basharast commented Feb 24, 2022

Hi,
I just want to know if it's possible to compile flycast libretro core for ARM32 (specifically for UWP)
Interpreter worked fine (partially because some games has textures issue) but it's almost stable
Dynarec was not possible because the arm32 code is for linux only if FEAT_SHREC = DYNAREC_JIT,
the only way I was able to compile is to activate the below options FEAT_SHREC = DYNAREC_CPP:

#if defined(TARGET_NO_JIT)
#define FEAT_SHREC DYNAREC_CPP
#define FEAT_AREC DYNAREC_NONE
#define FEAT_DSPREC DYNAREC_NONE
#endif

but I got black screen only (no crash happening)
I just need to know if there is any possible chance to get the dynarec working on UWP ARM32

Many thanks for your support.

@flyinghead
Copy link
Owner

I haven't looked at arm32 or arm64 on UWP at all so I don't know the extent of changes required to support them. I would think it's more complex than just setting some #define and certainly requires some additional code.

@flyinghead flyinghead added the enhancement New feature or request label Feb 24, 2022
@flyinghead flyinghead changed the title Dynarec support for libretro ARM32 Windows ARM support May 1, 2022
@Wunkolo
Copy link

Wunkolo commented Dec 30, 2022

Been trying to get a build going to get some scope for what it takes to do this.
There are some OS-specific things that have to be done around oslib.h and unwind_info.cpp and other such things now that there is a Windows-ARM platform to anticipate.

#ifdef _WIN64
#ifdef __MINGW64__
struct _RUNTIME_FUNCTION;
typedef struct _RUNTIME_FUNCTION RUNTIME_FUNCTION;
#else
+ #ifdef _M_ARM64 
+ struct _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY;
+ typedef struct _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY RUNTIME_FUNCTION;
+ #else
struct _IMAGE_RUNTIME_FUNCTION_ENTRY;
typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY RUNTIME_FUNCTION;
#endif
#endif
+ #endif

Because RUNTIME_FUNCTION is different on ARM64:

typedef struct _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY {
    DWORD BeginAddress;
    union {
        DWORD UnwindData;
        struct {
            DWORD Flag : 2;
            DWORD FunctionLength : 11;
            DWORD RegF : 3;
            DWORD RegI : 4;
            DWORD H : 1;
            DWORD CR : 2;
            DWORD FrameSize : 9;
        } DUMMYSTRUCTNAME;
    } DUMMYUNIONNAME;
} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY, * PIMAGE_ARM64_RUNTIME_FUNCTION_ENTRY;

some functions like UnwindInfo::end will have to be adjusted to some of these changes like the lack of EndAddress.

size_t UnwindInfo::end(u32 offset, ptrdiff_t rwRxOffset)
{
u8 *endAddr = startAddr + offset;
if ((uintptr_t)endAddr & 3)
offset += 4 - ((uintptr_t)endAddr & 3);
u8 *unwindInfo = startAddr + offset;
memcpy(unwindInfo, &codes[0], codes.size() * sizeof(u16));
RUNTIME_FUNCTION *table = (RUNTIME_FUNCTION *)(unwindInfo + codes.size() * sizeof(u16));
table[0].BeginAddress = 0;
table[0].EndAddress = (DWORD)(endAddr - startAddr);
#ifndef __MINGW64__
table[0].UnwindInfoAddress = (DWORD)(unwindInfo - startAddr);
#else
table[0].UnwindData = (DWORD)(unwindInfo - startAddr);
#endif
bool result = RtlAddFunctionTable(table, 1, (DWORD64)startAddr);
tables.push_back(table);
DEBUG_LOG(DYNAREC, "RtlAddFunctionTable %p sz %d rc %d tables: %d", startAddr, table[0].EndAddress, result, (u32)tables.size());
return (unwindInfo + codes.size() * sizeof(u16) + sizeof(RUNTIME_FUNCTION)) - endAddr;
}

@flyinghead
Copy link
Owner

flyinghead commented Jan 8, 2023

Dynamic unwind information isn't absolutely needed to get a first build working. This is just needed to be able to throw exceptions through dynarec blocks. (There's no unwind info on arm32 for example.)

The main reason there's no build yet is that I don't have a hardware platform to test with.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants