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

Workaround for fiber-unsafe optimizations on clang/gcc + Bumped CI clang version to 15 #982

Merged
merged 6 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ env:

jobs:
build-ubuntu:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: "Checkout repo"
uses: actions/checkout@v3
Expand Down Expand Up @@ -53,7 +53,7 @@ jobs:
- name: "Install system dependencies"
run: |
sudo apt update -qq
sudo apt install -y clang-12 cmake freeglut3-dev libgcrypt20-dev libglm-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev libudev-dev nasm ninja-build
sudo apt install -y clang-15 cmake freeglut3-dev libgcrypt20-dev libglm-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev libudev-dev nasm ninja-build

- name: "Bootstrap vcpkg"
run: |
Expand All @@ -75,7 +75,7 @@ jobs:

- name: "cmake"
run: |
cmake -S . -B build ${{ env.BUILD_FLAGS }} -DCMAKE_BUILD_TYPE=${{ env.BUILD_MODE }} -DPORTABLE=OFF -DCMAKE_C_COMPILER=/usr/bin/clang-12 -DCMAKE_CXX_COMPILER=/usr/bin/clang++-12 -G Ninja -DCMAKE_MAKE_PROGRAM=/usr/bin/ninja
cmake -S . -B build ${{ env.BUILD_FLAGS }} -DCMAKE_BUILD_TYPE=${{ env.BUILD_MODE }} -DPORTABLE=OFF -DCMAKE_C_COMPILER=/usr/bin/clang-15 -DCMAKE_CXX_COMPILER=/usr/bin/clang++-15 -G Ninja -DCMAKE_MAKE_PROGRAM=/usr/bin/ninja

- name: "Build Cemu"
run: |
Expand All @@ -93,7 +93,7 @@ jobs:
path: ./bin/Cemu

build-appimage:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
needs: build-ubuntu
steps:
- name: Checkout Upstream Repo
Expand All @@ -107,7 +107,7 @@ jobs:
- name: "Install system dependencies"
run: |
sudo apt update -qq
sudo apt install -y clang-12 cmake freeglut3-dev libgcrypt20-dev libglm-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev nasm ninja-build appstream
sudo apt install -y clang-15 cmake freeglut3-dev libgcrypt20-dev libglm-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev nasm ninja-build appstream

- name: "Build AppImage"
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/deploy_experimental_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
experimentalversion: ${{ github.run_number }}
deploy:
name: Deploy experimental release
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
needs: call-release-build
steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -72,7 +72,7 @@ jobs:
ls ./bin/
cp -R ./bin ./${{ env.CEMU_FOLDER_NAME }}
mv cemu-bin-linux-x64/Cemu ./${{ env.CEMU_FOLDER_NAME }}/Cemu
zip -9 -r upload/cemu-${{ env.CEMU_VERSION }}-ubuntu-20.04-x64.zip ${{ env.CEMU_FOLDER_NAME }}
zip -9 -r upload/cemu-${{ env.CEMU_VERSION }}-ubuntu-22.04-x64.zip ${{ env.CEMU_FOLDER_NAME }}
rm -r ./${{ env.CEMU_FOLDER_NAME }}

- name: Create release from macos-bin
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
.idea/

build/
cmake-build-*-*/
cmake-build-*/
out/
.cache/
bin/Cemu_*
Expand Down
12 changes: 6 additions & 6 deletions BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ Any other IDE should also work as long as it has CMake and MSVC support. CLion a

## Linux

To compile Cemu, a recent enough compiler and STL with C++20 support is required! clang-12 or higher is what we recommend.
To compile Cemu, a recent enough compiler and STL with C++20 support is required! clang-15 or higher is what we recommend.

### Installing dependencies

#### For Ubuntu and derivatives:
`sudo apt install -y cmake curl freeglut3-dev git libgcrypt20-dev libglm-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev nasm ninja-build`
`sudo apt install -y cmake curl clang-15 freeglut3-dev git libgcrypt20-dev libglm-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev nasm ninja-build`

*Additionally, for Ubuntu 22.04 only:*
- `sudo apt install -y clang-12`
- At step 3 while building, use
`cmake -S . -B build -DCMAKE_BUILD_TYPE=release -DCMAKE_C_COMPILER=/usr/bin/clang-12 -DCMAKE_CXX_COMPILER=/usr/bin/clang++-12 -G Ninja -DCMAKE_MAKE_PROGRAM=/usr/bin/ninja`
You may also need to install `libusb-1.0-0-dev` as a workaround for an issue with the vcpkg hidapi package.

At step 3 while building, use:
`cmake -S . -B build -DCMAKE_BUILD_TYPE=release -DCMAKE_C_COMPILER=/usr/bin/clang-15 -DCMAKE_CXX_COMPILER=/usr/bin/clang++-15 -G Ninja -DCMAKE_MAKE_PROGRAM=/usr/bin/ninja`

#### For Arch and derivatives:
`sudo pacman -S --needed base-devel clang cmake freeglut git glm gtk3 libgcrypt libpulse libsecret linux-headers llvm nasm ninja systemd unzip zip`
Expand Down
2 changes: 0 additions & 2 deletions generate_vs_solution.bat

This file was deleted.

3 changes: 2 additions & 1 deletion src/Cafe/HW/Espresso/Debugger/Debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,8 @@ void debugger_handleSingleStepException(uint64 dr6)
}
if (catchBP)
{
debugger_createCodeBreakpoint(ppcInterpreterCurrentInstance->instructionPointer + 4, DEBUGGER_BP_T_ONE_SHOT);
PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance();
debugger_createCodeBreakpoint(hCPU->instructionPointer + 4, DEBUGGER_BP_T_ONE_SHOT);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/Cafe/HW/Espresso/Debugger/GDBStub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -959,8 +959,9 @@ void GDBServer::HandleAccessException(uint64 dr6)

if (!response.empty())
{
PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance();
cemuLog_logDebug(LogType::Force, "Received matching breakpoint exception: {}", response);
auto nextInstructions = findNextInstruction(ppcInterpreterCurrentInstance->instructionPointer, ppcInterpreterCurrentInstance->spr.LR, ppcInterpreterCurrentInstance->spr.CTR);
auto nextInstructions = findNextInstruction(hCPU->instructionPointer, hCPU->spr.LR, hCPU->spr.CTR);
for (MPTR nextInstr : nextInstructions)
{
auto bpIt = m_patchedInstructions.find(nextInstr);
Expand Down
19 changes: 12 additions & 7 deletions src/Cafe/HW/Espresso/Interpreter/PPCInterpreterMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
thread_local PPCInterpreter_t* ppcInterpreterCurrentInstance;

// main thread instruction counter and timing
volatile uint64 ppcMainThreadCycleCounter = 0;
uint64 ppcMainThreadDECCycleValue = 0; // value that was set to dec register
uint64 ppcMainThreadDECCycleStart = 0; // at which cycle the dec register was set, if == 0 -> dec is 0
uint64 ppcCyclesSince2000 = 0;
Expand All @@ -29,11 +28,16 @@ PPCInterpreter_t* PPCInterpreter_createInstance(unsigned int Entrypoint)
return pData;
}

PPCInterpreter_t* PPCInterpreter_getCurrentInstance()
TLS_WORKAROUND_NOINLINE PPCInterpreter_t* PPCInterpreter_getCurrentInstance()
{
return ppcInterpreterCurrentInstance;
}

TLS_WORKAROUND_NOINLINE void PPCInterpreter_setCurrentInstance(PPCInterpreter_t* hCPU)
{
ppcInterpreterCurrentInstance = hCPU;
}

uint64 PPCInterpreter_getMainCoreCycleCounter()
{
return PPCTimer_getFromRDTSC();
Expand Down Expand Up @@ -78,24 +82,25 @@ uint32 PPCInterpreter_getCoreIndex(PPCInterpreter_t* hCPU)

uint32 PPCInterpreter_getCurrentCoreIndex()
{
return ppcInterpreterCurrentInstance->spr.UPIR;
return PPCInterpreter_getCurrentInstance()->spr.UPIR;
};

uint8* PPCInterpreterGetStackPointer()
{
return memory_getPointerFromVirtualOffset(ppcInterpreterCurrentInstance->gpr[1]);
return memory_getPointerFromVirtualOffset(PPCInterpreter_getCurrentInstance()->gpr[1]);
}

uint8* PPCInterpreterGetAndModifyStackPointer(sint32 offset)
{
uint8* result = memory_getPointerFromVirtualOffset(ppcInterpreterCurrentInstance->gpr[1] - offset);
ppcInterpreterCurrentInstance->gpr[1] -= offset;
PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance();
uint8* result = memory_getPointerFromVirtualOffset(hCPU->gpr[1] - offset);
hCPU->gpr[1] -= offset;
return result;
}

void PPCInterpreterModifyStackPointer(sint32 offset)
{
ppcInterpreterCurrentInstance->gpr[1] -= offset;
PPCInterpreter_getCurrentInstance()->gpr[1] -= offset;
}

uint32 RPLLoader_MakePPCCallable(void(*ppcCallableExport)(PPCInterpreter_t* hCPU));
Expand Down
15 changes: 8 additions & 7 deletions src/Cafe/HW/Espresso/PPCCallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,20 @@ uint32 PPCCoreCallback(MPTR function, PPCCoreCallbackData_t& data, T currentArg,
{
cemu_assert_debug(data.gprCount <= 8);
cemu_assert_debug(data.floatCount <= 8);
PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance();
if constexpr (std::is_pointer_v<T>)
{
ppcInterpreterCurrentInstance->gpr[3 + data.gprCount] = MEMPTR(currentArg).GetMPTR();
hCPU->gpr[3 + data.gprCount] = MEMPTR(currentArg).GetMPTR();
data.gprCount++;
}
else if constexpr (std::is_base_of_v<MEMPTRBase, std::remove_reference_t<T>>)
{
ppcInterpreterCurrentInstance->gpr[3 + data.gprCount] = currentArg.GetMPTR();
hCPU->gpr[3 + data.gprCount] = currentArg.GetMPTR();
data.gprCount++;
}
else if constexpr (std::is_reference_v<T>)
{
ppcInterpreterCurrentInstance->gpr[3 + data.gprCount] = MEMPTR(&currentArg).GetMPTR();
hCPU->gpr[3 + data.gprCount] = MEMPTR(&currentArg).GetMPTR();
data.gprCount++;
}
else if constexpr(std::is_enum_v<T>)
Expand All @@ -40,19 +41,19 @@ uint32 PPCCoreCallback(MPTR function, PPCCoreCallbackData_t& data, T currentArg,
}
else if constexpr (std::is_floating_point_v<T>)
{
ppcInterpreterCurrentInstance->fpr[1 + data.floatCount].fpr = (double)currentArg;
hCPU->fpr[1 + data.floatCount].fpr = (double)currentArg;
data.floatCount++;
}
else if constexpr (std::is_integral_v<T> && sizeof(T) == sizeof(uint64))
{
ppcInterpreterCurrentInstance->gpr[3 + data.gprCount] = (uint32)(currentArg >> 32); // high
ppcInterpreterCurrentInstance->gpr[3 + data.gprCount + 1] = (uint32)currentArg; // low
hCPU->gpr[3 + data.gprCount] = (uint32)(currentArg >> 32); // high
hCPU->gpr[3 + data.gprCount + 1] = (uint32)currentArg; // low

data.gprCount += 2;
}
else
{
ppcInterpreterCurrentInstance->gpr[3 + data.gprCount] = (uint32)currentArg;
hCPU->gpr[3 + data.gprCount] = (uint32)currentArg;
data.gprCount++;
}

Expand Down
19 changes: 11 additions & 8 deletions src/Cafe/HW/Espresso/PPCScheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,24 @@ uint32 ppcThreadQuantum = 45000; // execute 45000 instructions before thread res

void PPCInterpreter_relinquishTimeslice()
{
if( ppcInterpreterCurrentInstance->remainingCycles >= 0 )
PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance();
if( hCPU->remainingCycles >= 0 )
{
ppcInterpreterCurrentInstance->skippedCycles = ppcInterpreterCurrentInstance->remainingCycles + 1;
ppcInterpreterCurrentInstance->remainingCycles = -1;
hCPU->skippedCycles = hCPU->remainingCycles + 1;
hCPU->remainingCycles = -1;
}
}

void PPCCore_boostQuantum(sint32 numCycles)
{
ppcInterpreterCurrentInstance->remainingCycles += numCycles;
PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance();
hCPU->remainingCycles += numCycles;
}

void PPCCore_deboostQuantum(sint32 numCycles)
{
ppcInterpreterCurrentInstance->remainingCycles -= numCycles;
PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance();
hCPU->remainingCycles -= numCycles;
}

namespace coreinit
Expand All @@ -36,7 +39,7 @@ namespace coreinit
void PPCCore_switchToScheduler()
{
cemu_assert_debug(__OSHasSchedulerLock() == false); // scheduler lock must not be hold past thread time slice
cemu_assert_debug(ppcInterpreterCurrentInstance->coreInterruptMask != 0 || CafeSystem::GetForegroundTitleId() == 0x000500001019e600);
cemu_assert_debug(PPCInterpreter_getCurrentInstance()->coreInterruptMask != 0 || CafeSystem::GetForegroundTitleId() == 0x000500001019e600);
__OSLockScheduler();
coreinit::__OSThreadSwitchToNext();
__OSUnlockScheduler();
Expand All @@ -45,7 +48,7 @@ void PPCCore_switchToScheduler()
void PPCCore_switchToSchedulerWithLock()
{
cemu_assert_debug(__OSHasSchedulerLock() == true); // scheduler lock must be hold
cemu_assert_debug(ppcInterpreterCurrentInstance->coreInterruptMask != 0 || CafeSystem::GetForegroundTitleId() == 0x000500001019e600);
cemu_assert_debug(PPCInterpreter_getCurrentInstance()->coreInterruptMask != 0 || CafeSystem::GetForegroundTitleId() == 0x000500001019e600);
coreinit::__OSThreadSwitchToNext();
}

Expand All @@ -58,7 +61,7 @@ void _PPCCore_callbackExit(PPCInterpreter_t* hCPU)
PPCInterpreter_t* PPCCore_executeCallbackInternal(uint32 functionMPTR)
{
cemu_assert_debug(functionMPTR != 0);
PPCInterpreter_t* hCPU = ppcInterpreterCurrentInstance;
PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance();
// remember LR and instruction pointer
uint32 lr = hCPU->spr.LR;
uint32 ip = hCPU->instructionPointer;
Expand Down
2 changes: 1 addition & 1 deletion src/Cafe/HW/Espresso/PPCSchedulerLLE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ void PPCCoreLLE_startSingleCoreScheduler(uint32 entrypoint)
for (uint32 coreIndex = 0; coreIndex < 3; coreIndex++)
{
PPCInterpreter_t* hCPU = cpuContext->cores+coreIndex;
ppcInterpreterCurrentInstance = hCPU;
PPCInterpreter_setCurrentInstance(hCPU);
if (coreIndex == 1)
{
// check SCR core 1 enable bit
Expand Down
3 changes: 1 addition & 2 deletions src/Cafe/HW/Espresso/PPCState.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ static uint64 PPCInterpreter_getCallParamU64(PPCInterpreter_t* hCPU, uint32 inde

PPCInterpreter_t* PPCInterpreter_createInstance(unsigned int Entrypoint);
PPCInterpreter_t* PPCInterpreter_getCurrentInstance();
void PPCInterpreter_setCurrentInstance(PPCInterpreter_t* hCPU);

uint64 PPCInterpreter_getMainCoreCycleCounter();

Expand Down Expand Up @@ -192,7 +193,6 @@ uint32 PPCInterpreter_getCurrentCoreIndex();
void PPCInterpreter_setDEC(PPCInterpreter_t* hCPU, uint32 newValue);

// timing for main processor
extern volatile uint64 ppcMainThreadCycleCounter;
extern uint64 ppcCyclesSince2000; // on init this is set to the cycles that passed since 1.1.2000
extern uint64 ppcCyclesSince2000TimerClock; // on init this is set to the cycles that passed since 1.1.2000 / 20
extern uint64 ppcCyclesSince2000_UTC;
Expand All @@ -213,7 +213,6 @@ void PPCTimer_start();
// core info and control
extern uint32 ppcThreadQuantum;

extern thread_local PPCInterpreter_t *ppcInterpreterCurrentInstance;
uint8* PPCInterpreterGetAndModifyStackPointer(sint32 offset);
uint8* PPCInterpreterGetStackPointer();
void PPCInterpreterModifyStackPointer(sint32 offset);
Expand Down
4 changes: 2 additions & 2 deletions src/Cafe/HW/Espresso/Recompiler/PPCRecompilerX64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ void* ATTR_MS_ABI PPCRecompiler_virtualHLE(PPCInterpreter_t* hCPU, uint32 hleFun
hCPU->remainingCycles -= 500; // let subtract about 500 cycles for each HLE call
hCPU->gpr[3] = 0;
PPCInterpreter_nextInstruction(hCPU);
return ppcInterpreterCurrentInstance;
return hCPU;
}
else
{
Expand All @@ -109,7 +109,7 @@ void* ATTR_MS_ABI PPCRecompiler_virtualHLE(PPCInterpreter_t* hCPU, uint32 hleFun
hleCall(hCPU);
}
hCPU->rspTemp = prevRSPTemp;
return ppcInterpreterCurrentInstance;
return PPCInterpreter_getCurrentInstance();
}

void ATTR_MS_ABI PPCRecompiler_getTBL(PPCInterpreter_t* hCPU, uint32 gprIndex)
Expand Down
2 changes: 1 addition & 1 deletion src/Cafe/IOSU/legacy/iosu_ioctl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ sint32 iosuIoctl_pushAndWait(uint32 ioctlHandle, ioQueueEntry_t* ioQueueEntry)
}
__OSLockScheduler();
ioctlMutex.lock();
ioQueueEntry->ppcThread = coreinitThread_getCurrentThreadDepr(ppcInterpreterCurrentInstance);
ioQueueEntry->ppcThread = coreinitThread_getCurrentThreadDepr(PPCInterpreter_getCurrentInstance());

_ioctlRingbuffer[ioctlHandle].Push(ioQueueEntry);
ioctlMutex.unlock();
Expand Down
2 changes: 1 addition & 1 deletion src/Cafe/OS/common/OSUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class cafeExportParamWrapper
}
else if constexpr (std::is_floating_point_v<T>)
{
v = (T)ppcInterpreterCurrentInstance->fpr[1 + fprIndex].fpr;
v = (T)hCPU->fpr[1 + fprIndex].fpr;
fprIndex++;
}
else
Expand Down
4 changes: 2 additions & 2 deletions src/Cafe/OS/libs/coreinit/coreinit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ namespace coreinit
{
sint32 OSGetCoreId()
{
return PPCInterpreter_getCoreIndex(ppcInterpreterCurrentInstance);
return PPCInterpreter_getCoreIndex(PPCInterpreter_getCurrentInstance());
}

uint32 OSGetCoreCount()
Expand Down Expand Up @@ -239,7 +239,7 @@ namespace coreinit

uint32 OSGetStackPointer()
{
return ppcInterpreterCurrentInstance->gpr[1];
return PPCInterpreter_getCurrentInstance()->gpr[1];
}

void coreinitExport_ENVGetEnvironmentVariable(PPCInterpreter_t* hCPU)
Expand Down
2 changes: 1 addition & 1 deletion src/Cafe/OS/libs/coreinit/coreinit_FS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ namespace coreinit
while (OSSendMessage(ioMsgQueue, &fsCmdBlockBody->asyncResult.msgUnion.osMsg, 0) == 0)
{
cemuLog_log(LogType::Force, "FS driver: Failed to add message to result queue. Retrying...");
if (ppcInterpreterCurrentInstance)
if (PPCInterpreter_getCurrentInstance())
PPCCore_switchToScheduler();
else
std::this_thread::sleep_for(std::chrono::milliseconds(10));
Expand Down
9 changes: 5 additions & 4 deletions src/Cafe/OS/libs/coreinit/coreinit_Init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,11 @@ void CafeInit()
}
}
// setup UGQR
ppcInterpreterCurrentInstance->spr.UGQR[0 + 2] = 0x00040004;
ppcInterpreterCurrentInstance->spr.UGQR[0 + 3] = 0x00050005;
ppcInterpreterCurrentInstance->spr.UGQR[0 + 4] = 0x00060006;
ppcInterpreterCurrentInstance->spr.UGQR[0 + 5] = 0x00070007;
PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance();
hCPU->spr.UGQR[0 + 2] = 0x00040004;
hCPU->spr.UGQR[0 + 3] = 0x00050005;
hCPU->spr.UGQR[0 + 4] = 0x00060006;
hCPU->spr.UGQR[0 + 5] = 0x00070007;
coreinit::InitForegroundBucket();
coreinit::InitSysHeap();
}
Expand Down
Loading