IR: remove pair from cpuid

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
Alyssa Rosenzweig committed 2024-08-14 09:37:06 -04:00
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) {
+4 -6
View File
@@ -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);
}
}
}