diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp index 0ac2c04e9..d04b7c1f4 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp @@ -427,10 +427,11 @@ DEF_OP(CPUID) { PopDynamicRegsAndLR(); // Results are in x0, x1 - // Results want to be in a i64v2 vector - auto Dst = GetRegPair(Node); - mov(ARMEmitter::Size::i64Bit, Dst.first, TMP1); - mov(ARMEmitter::Size::i64Bit, Dst.second, TMP2); + // Results want to be 4xi32 scalars + mov(ARMEmitter::Size::i32Bit, GetReg(Op->OutEAX.ID()), TMP1); + mov(ARMEmitter::Size::i32Bit, GetReg(Op->OutECX.ID()), TMP2); + ubfx(ARMEmitter::Size::i64Bit, GetReg(Op->OutEBX.ID()), TMP1, 32, 32); + ubfx(ARMEmitter::Size::i64Bit, GetReg(Op->OutEDX.ID()), TMP2, 32, 32); } DEF_OP(XGetBV) { diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index c0405dbc4..d548429ee 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -1417,13 +1417,17 @@ void OpDispatchBuilder::CPUIDOp(OpcodeArgs) { Ref Src = LoadSource_WithOpSize(GPRClass, Op, Op->Src[0], GPRSize, Op->Flags); Ref Leaf = LoadGPRRegister(X86State::REG_RCX); - auto Res = _CPUID(Src, Leaf); - auto [Result_Lower, Result_Upper] = ExtractPair(OpSize::i64Bit, Res); + Ref RAX = _AllocateGPR(false); + Ref RBX = _AllocateGPR(false); + Ref RCX = _AllocateGPR(false); + Ref RDX = _AllocateGPR(false); - StoreGPRRegister(X86State::REG_RAX, _Bfe(OpSize::i64Bit, 32, 0, Result_Lower)); - StoreGPRRegister(X86State::REG_RBX, _Bfe(OpSize::i64Bit, 32, 32, Result_Lower)); - StoreGPRRegister(X86State::REG_RDX, _Bfe(OpSize::i64Bit, 32, 32, Result_Upper)); - StoreGPRRegister(X86State::REG_RCX, _Bfe(OpSize::i64Bit, 32, 0, Result_Upper)); + _CPUID(Src, Leaf, RAX, RBX, RCX, RDX); + + StoreGPRRegister(X86State::REG_RAX, RAX); + StoreGPRRegister(X86State::REG_RBX, RBX); + StoreGPRRegister(X86State::REG_RCX, RCX); + StoreGPRRegister(X86State::REG_RDX, RDX); } uint32_t OpDispatchBuilder::LoadConstantShift(X86Tables::DecodedOp Op, bool Is1Bit) { diff --git a/FEXCore/Source/Interface/IR/IR.json b/FEXCore/Source/Interface/IR/IR.json index 144cb566f..dc2a3ba8a 100644 --- a/FEXCore/Source/Interface/IR/IR.json +++ b/FEXCore/Source/Interface/IR/IR.json @@ -331,12 +331,10 @@ "HasSideEffects": true }, - "GPRPair = CPUID GPR:$Function, GPR:$Leaf": { - "Desc": ["Calls in to the CPUID handler function to return emulated CPUID", - "Returns a 128bit GPR pair that fits emulated EAX, EBX, EDX, ECX respectively" - ], - "DestSize": "16", - "NumElements": "2" + "GPR:$EAX, GPR:$EBX, GPR:$ECX, GPR:$EDX = CPUID GPR:$Function, GPR:$Leaf": { + "Desc": ["Calls in to the CPUID handler function to return emulated CPUID"], + "DestSize": "4", + "HasSideEffects": true }, "GPR:$EAX, GPR:$EDX = XGetBV GPR:$Function": { "Desc": ["Calls in to the XCR handler function to return emulated XCR"], diff --git a/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp b/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp index 89f4fda29..c00971e9c 100644 --- a/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp +++ b/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp @@ -483,14 +483,14 @@ void ConstProp::ConstantPropagation(IREmitter* IREmit, const IRListView& Current // If the CPUID needs a constant leaf to be optimized then this can't work if we didn't const-prop the leaf register. if (!(SupportsConstant.NeedsLeaf == CPUIDEmu::NeedsLeafConstant::NEEDSLEAFCONSTANT && !IsConstantLeaf)) { // Calculate the constant data and replace all uses. - // DCE will remove the CPUID IR operation. - const auto ConstantCPUIDResult = CPUID->RunFunction(ConstantFunction, ConstantLeaf); - uint64_t ResultsLower = (static_cast(ConstantCPUIDResult.ebx) << 32) | ConstantCPUIDResult.eax; - uint64_t ResultsUpper = (static_cast(ConstantCPUIDResult.edx) << 32) | ConstantCPUIDResult.ecx; + const auto Result = CPUID->RunFunction(ConstantFunction, ConstantLeaf); + IREmit->SetWriteCursor(CodeNode); - auto ElementPair = IREmit->_CreateElementPair(IR::OpSize::i128Bit, IREmit->_Constant(ResultsLower), IREmit->_Constant(ResultsUpper)); - // Replace all CPUID uses with this inline one - IREmit->ReplaceAllUsesWith(CodeNode, ElementPair); + IREmit->ReplaceAllUsesWith(CurrentIR.GetNode(Op->OutEAX), IREmit->_Constant(Result.eax)); + IREmit->ReplaceAllUsesWith(CurrentIR.GetNode(Op->OutEBX), IREmit->_Constant(Result.ebx)); + IREmit->ReplaceAllUsesWith(CurrentIR.GetNode(Op->OutECX), IREmit->_Constant(Result.ecx)); + IREmit->ReplaceAllUsesWith(CurrentIR.GetNode(Op->OutEDX), IREmit->_Constant(Result.edx)); + IREmit->Remove(CodeNode); } } }