diff --git a/FEXCore/Source/Interface/Core/Core.cpp b/FEXCore/Source/Interface/Core/Core.cpp index 5123baee2..678903790 100644 --- a/FEXCore/Source/Interface/Core/Core.cpp +++ b/FEXCore/Source/Interface/Core/Core.cpp @@ -577,10 +577,11 @@ ContextImpl::GenerateIR(FEXCore::Core::InternalThreadState* Thread, uint64_t Gue } if (Config.SMCChecks == FEXCore::Config::CONFIG_SMC_FULL || Block.ForceFullSMCDetection) { - auto ExistingCodePtr = reinterpret_cast(Block.Entry + BlockInstructionsLength); - - auto CodeChanged = Thread->OpDispatcher->_ValidateCode(ExistingCodePtr[0], ExistingCodePtr[1], - (uintptr_t)ExistingCodePtr - GuestRIP, DecodedInfo->InstSize); + auto ExistingCodePtr = reinterpret_cast(Block.Entry + BlockInstructionsLength); + auto InstAddressReg = Thread->OpDispatcher->_EntrypointOffset(GPRSize, InstAddress - GuestRIP); + std::array CodeOriginal; + memcpy(CodeOriginal.data(), ExistingCodePtr, DecodedInfo->InstSize); + auto CodeChanged = Thread->OpDispatcher->_ValidateCode(CodeOriginal, InstAddressReg, DecodedInfo->InstSize); auto InvalidateCodeCond = Thread->OpDispatcher->CondJump(CodeChanged); diff --git a/FEXCore/Source/Interface/Core/JIT/BranchOps.cpp b/FEXCore/Source/Interface/Core/JIT/BranchOps.cpp index 6cb731ad5..1c4f94d0b 100644 --- a/FEXCore/Source/Interface/Core/JIT/BranchOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/BranchOps.cpp @@ -437,48 +437,50 @@ DEF_OP(Thunk) { DEF_OP(ValidateCode) { auto Op = IROp->C(); - const auto* OldCode = (const uint8_t*)&Op->CodeOriginalLow; + auto OldCode = Op->CodeOriginal.data(); + auto Base = GetReg(Op->Header.Args[0]).X(); int len = Op->CodeLength; - int idx = 0; - - LoadConstant(ARMEmitter::Size::i64Bit, GetReg(Node), 0); - LoadConstant(ARMEmitter::Size::i64Bit, TMP1, Entry + Op->Offset); - LoadConstant(ARMEmitter::Size::i64Bit, TMP2, 1); + int Offset = 0; + ARMEmitter::ForwardLabel Fail; const auto Dst = GetReg(Node); - while (len >= 8) { - ldr(ARMEmitter::XReg::x2, TMP1, idx); - LoadConstant(ARMEmitter::Size::i64Bit, TMP4, *(const uint64_t*)(OldCode + idx)); - cmp(ARMEmitter::Size::i64Bit, TMP3, TMP4); - csel(ARMEmitter::Size::i64Bit, Dst, Dst, TMP2, ARMEmitter::Condition::CC_EQ); - len -= 8; - idx += 8; - } - while (len >= 4) { - ldr(ARMEmitter::WReg::w2, TMP1, idx); - LoadConstant(ARMEmitter::Size::i64Bit, TMP4, *(const uint32_t*)(OldCode + idx)); - cmp(ARMEmitter::Size::i32Bit, TMP3, TMP4); - csel(ARMEmitter::Size::i64Bit, Dst, Dst, TMP2, ARMEmitter::Condition::CC_EQ); - len -= 4; - idx += 4; - } - while (len >= 2) { - ldrh(TMP3, TMP1, idx); - LoadConstant(ARMEmitter::Size::i64Bit, TMP4, *(const uint16_t*)(OldCode + idx)); - cmp(ARMEmitter::Size::i32Bit, TMP3, TMP4); - csel(ARMEmitter::Size::i64Bit, Dst, Dst, TMP2, ARMEmitter::Condition::CC_EQ); - len -= 2; - idx += 2; - } - while (len >= 1) { - ldrb(TMP3, TMP1, idx); - LoadConstant(ARMEmitter::Size::i64Bit, TMP4, *(const uint8_t*)(OldCode + idx)); - cmp(ARMEmitter::Size::i32Bit, TMP3, TMP4); - csel(ARMEmitter::Size::i64Bit, Dst, Dst, TMP2, ARMEmitter::Condition::CC_EQ); - len -= 1; - idx += 1; - } + auto EmitCheck = [&](size_t Size, auto&& LoadData) { + while (len >= Size) { + LoadData(); + sub(ARMEmitter::Size::i64Bit, TMP1, TMP1, TMP2); + cbnz(ARMEmitter::Size::i64Bit, TMP1, &Fail); + len -= Size; + Offset += Size; + } + }; + + EmitCheck(8, [&]() { + ldr(TMP1, Base, Offset); + LoadConstant(ARMEmitter::Size::i64Bit, TMP2, *(const uint64_t*)(OldCode + Offset)); + }); + + EmitCheck(4, [&]() { + ldr(TMP1.W(), Base, Offset); + LoadConstant(ARMEmitter::Size::i32Bit, TMP2, *(const uint32_t*)(OldCode + Offset)); + }); + + EmitCheck(2, [&]() { + ldrh(TMP1.W(), Base, Offset); + LoadConstant(ARMEmitter::Size::i32Bit, TMP2, *(const uint16_t*)(OldCode + Offset)); + }); + + EmitCheck(1, [&]() { + ldrb(TMP1.W(), Base, Offset); + LoadConstant(ARMEmitter::Size::i32Bit, TMP2, *(const uint8_t*)(OldCode + Offset)); + }); + + ARMEmitter::ForwardLabel End; + LoadConstant(ARMEmitter::Size::i32Bit, Dst, 0); + b(&End); + Bind(&Fail); + LoadConstant(ARMEmitter::Size::i32Bit, Dst, 1); + Bind(&End); } DEF_OP(ThreadRemoveCodeEntry) { diff --git a/FEXCore/Source/Interface/IR/IR.json b/FEXCore/Source/Interface/IR/IR.json index 6bd59d1f5..1e741b492 100644 --- a/FEXCore/Source/Interface/IR/IR.json +++ b/FEXCore/Source/Interface/IR/IR.json @@ -159,7 +159,8 @@ "NamedVectorConstant": "FEXCore::IR::NamedVectorConstant", "IndexNamedVectorConstant": "FEXCore::IR::IndexNamedVectorConstant", "ShiftType": "FEXCore::IR::ShiftType", - "BranchHint": "FEXCore::IR::BranchHint" + "BranchHint": "FEXCore::IR::BranchHint", + "Array16": "std::array" }, "Ops": { "Misc": { @@ -200,10 +201,9 @@ "HasSideEffects": true }, - "GPR = ValidateCode u64:$CodeOriginalLow, u64:$CodeOriginalhigh, i64:$Offset, u8:$CodeLength": { + "GPR = ValidateCode Array16:$CodeOriginal, GPR:$Address, u8:$CodeLength": { "HasSideEffects": true, "HasDest": true, - "ImplicitFlagClobber": true, "DestSize": "OpSize::i64Bit" }, diff --git a/FEXCore/Source/Interface/IR/IRDumper.cpp b/FEXCore/Source/Interface/IR/IRDumper.cpp index e583153e2..d7ef2b3d6 100644 --- a/FEXCore/Source/Interface/IR/IRDumper.cpp +++ b/FEXCore/Source/Interface/IR/IRDumper.cpp @@ -274,6 +274,10 @@ static void PrintArg(fextl::stringstream* out, const IRListView*, FEXCore::IR::B } } +static void PrintArg(fextl::stringstream* out, const IRListView*, const std::array& Arg) { + *out << fextl::fmt::format("{:02x}", fmt::join(Arg, "")); +} + void Dump(fextl::stringstream* out, const IRListView* IR) { auto HeaderOp = IR->GetHeader();