mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-14 13:00:41 +02:00
IR: remove pair from cpuid
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
1 parent
feaa1af1a8
commit
74f341bc0e
4 files changed
+26
-23
No files matched your search
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"],
|
||||
|
||||
@@ -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<uint64_t>(ConstantCPUIDResult.ebx) << 32) | ConstantCPUIDResult.eax;
|
||||
uint64_t ResultsUpper = (static_cast<uint64_t>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user