MCPcopy Create free account
hub / github.com/FEX-Emu/FEX / DEF_OP

Function DEF_OP

FEXCore/Source/Interface/Core/JIT/ConversionOps.cpp:12–85  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

10
11namespace FEXCore::CPU {
12DEF_OP(VInsGPR) {
13 const auto Op = IROp->C<IR::IROp_VInsGPR>();
14 const auto OpSize = IROp->Size;
15
16 const auto DestIdx = Op->DestIdx;
17 const auto ElementSize = Op->Header.ElementSize;
18 const auto Is256Bit = OpSize == IR::OpSize::i256Bit;
19 LOGMAN_THROW_A_FMT(!Is256Bit || HostSupportsSVE256, "Need SVE256 support in order to use {} with 256-bit operation", __func__);
20
21 const auto SubEmitSize = ConvertSubRegSize8(IROp);
22 const auto ElementsPer128Bit = IR::NumElements(IR::OpSize::i128Bit, ElementSize);
23
24 const auto Dst = GetVReg(Node);
25 const auto DestVector = GetVReg(Op->DestVector);
26 const auto Src = GetReg(Op->Src);
27
28 if (HostSupportsSVE256 && Is256Bit) {
29 const auto ElementSizeBits = IR::OpSizeAsBits(ElementSize);
30 const auto Offset = ElementSizeBits * DestIdx;
31
32 const auto SSEBitSize = Core::CPUState::XMM_SSE_REG_SIZE * 8;
33 const auto InUpperLane = Offset >= SSEBitSize;
34
35 // This is going to be a little gross. Pls forgive me.
36 // Since SVE has the whole vector length agnostic programming
37 // thing going on, we can't exactly freely insert entries into
38 // arbitrary locations in the vector.
39 //
40 // SVE *does* have INSR, however this only shifts the entire
41 // vector to the left by an element size and inserts a value
42 // at the beginning of the vector. Not *quite* what we need.
43 // (though INSR *is* very useful for other things).
44 //
45 // The idea is (in the case of the upper lane), move the upper
46 // lane down, insert into it and recombine with the lower lane.
47 //
48 // In the case of the lower lane, insert and then recombine with
49 // the upper lane.
50
51 if (InUpperLane) {
52 // Move the upper lane down for the insertion.
53 const auto CompactPred = ARMEmitter::PReg::p0;
54 not_(CompactPred, PRED_TMP_32B.Zeroing(), PRED_TMP_16B);
55 compact(ARMEmitter::SubRegSize::i64Bit, VTMP1.Z(), CompactPred, DestVector.Z());
56 }
57
58 // Put data in place for destructive SPLICE below.
59 mov(Dst.Z(), DestVector.Z());
60
61 // Inserts the GPR value into the given V register.
62 // Also automatically adjusts the index in the case of using the
63 // moved upper lane.
64 const auto Insert = [&](const ARMEmitter::VRegister& reg, int index) {
65 if (InUpperLane) {
66 index -= ElementsPer128Bit;
67 }
68 ins(SubEmitSize, reg, index, Src);
69 };

Callers

nothing calls this directly

Calls 10

NumElementsFunction · 0.85
OpSizeAsBitsFunction · 0.85
OpSizeToSizeFunction · 0.85
ZeroingMethod · 0.80
ZMethod · 0.80
QMethod · 0.80
SMethod · 0.80
DMethod · 0.80
HMethod · 0.80
MergingMethod · 0.80

Tested by

no test coverage detected