mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-24 02:00:47 +02:00
Implements the new IR ops in the CPU backends
This commit is contained in:
1 parent
4692a761b6
commit
8ea266e10f
4 files changed
+197
No files matched your search
@@ -304,7 +304,33 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IR::OP_VEXTRACTELEMENT: {
|
||||
auto Op = IROp->C<IR::IROp_VExtractElement>();
|
||||
LogMan::Throw::A(Op->RegisterSize <= 16, "OpSize is too large for VExtractToGPR: %d", OpSize);
|
||||
if (Op->RegisterSize == 16) {
|
||||
__uint128_t SourceMask = (1ULL << (Op->ElementSize * 8)) - 1;
|
||||
uint64_t Shift = Op->ElementSize * Op->Index * 8;
|
||||
if (Op->ElementSize == 8)
|
||||
SourceMask = ~0ULL;
|
||||
|
||||
__uint128_t Src = *GetSrc<__uint128_t*>(Op->Header.Args[0]);
|
||||
Src >>= Shift;
|
||||
Src &= SourceMask;
|
||||
memcpy(GDP, &Src, Op->ElementSize);
|
||||
}
|
||||
else {
|
||||
uint64_t SourceMask = (1ULL << (Op->ElementSize * 8)) - 1;
|
||||
uint64_t Shift = Op->ElementSize * Op->Index * 8;
|
||||
if (Op->ElementSize == 8)
|
||||
SourceMask = ~0ULL;
|
||||
|
||||
uint64_t Src = *GetSrc<uint64_t*>(Op->Header.Args[0]);
|
||||
Src >>= Shift;
|
||||
Src &= SourceMask;
|
||||
GD = Src;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IR::OP_CONSTANT: {
|
||||
auto Op = IROp->C<IR::IROp_Constant>();
|
||||
GD = Op->Constant;
|
||||
@@ -2813,6 +2839,44 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
memcpy(GDP, Tmp, Op->RegisterSize);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VINSSCALARELEMENT: {
|
||||
auto Op = IROp->C<IR::IROp_VInsScalarElement>();
|
||||
void *Src1 = GetSrc<void*>(Op->Header.Args[0]);
|
||||
void *Src2 = GetSrc<void*>(Op->Header.Args[1]);
|
||||
uint8_t Tmp[16];
|
||||
|
||||
// Copy src1 in to dest
|
||||
memcpy(Tmp, Src1, Op->RegisterSize);
|
||||
switch (Op->ElementSize) {
|
||||
case 1: {
|
||||
auto *Dst_d = reinterpret_cast<uint8_t*>(Tmp);
|
||||
auto Src2_d = *reinterpret_cast<uint8_t*>(Src2);
|
||||
Dst_d[Op->DestIdx] = Src2_d;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
auto *Dst_d = reinterpret_cast<uint16_t*>(Tmp);
|
||||
auto Src2_d = *reinterpret_cast<uint16_t*>(Src2);
|
||||
Dst_d[Op->DestIdx] = Src2_d;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
auto *Dst_d = reinterpret_cast<uint32_t*>(Tmp);
|
||||
auto Src2_d = *reinterpret_cast<uint32_t*>(Src2);
|
||||
Dst_d[Op->DestIdx] = Src2_d;
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
auto *Dst_d = reinterpret_cast<uint64_t*>(Tmp);
|
||||
auto Src2_d = *reinterpret_cast<uint64_t*>(Src2);
|
||||
Dst_d[Op->DestIdx] = Src2_d;
|
||||
break;
|
||||
}
|
||||
default: LogMan::Msg::A("Unknown Element Size: %d", Op->ElementSize); break;
|
||||
};
|
||||
memcpy(GDP, Tmp, Op->RegisterSize);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VCMPEQ: {
|
||||
auto Op = IROp->C<IR::IROp_VCMPEQ>();
|
||||
void *Src1 = GetSrc<void*>(Op->Header.Args[0]);
|
||||
|
||||
@@ -530,6 +530,25 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IR::OP_VEXTRACTELEMENT: {
|
||||
auto Op = IROp->C<IR::IROp_VExtractElement>();
|
||||
switch (OpSize) {
|
||||
case 1:
|
||||
mov(GetDst(Node).B(), GetSrc(Op->Header.Args[0].ID()).V16B(), Op->Index);
|
||||
break;
|
||||
case 2:
|
||||
mov(GetDst(Node).H(), GetSrc(Op->Header.Args[0].ID()).V8H(), Op->Index);
|
||||
break;
|
||||
case 4:
|
||||
mov(GetDst(Node).S(), GetSrc(Op->Header.Args[0].ID()).V4S(), Op->Index);
|
||||
break;
|
||||
case 8:
|
||||
mov(GetDst(Node).D(), GetSrc(Op->Header.Args[0].ID()).V2D(), Op->Index);
|
||||
break;
|
||||
default: LogMan::Msg::A("Unhandled ExtractElementSize: %d", OpSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IR::OP_JUMP: {
|
||||
auto Op = IROp->C<IR::IROp_Jump>();
|
||||
|
||||
@@ -2042,6 +2061,31 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
|
||||
mov(GetDst(Node), VTMP1);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VINSSCALARELEMENT: {
|
||||
auto Op = IROp->C<IR::IROp_VInsScalarElement>();
|
||||
mov(VTMP1, GetSrc(Op->Header.Args[0].ID()));
|
||||
switch (Op->ElementSize) {
|
||||
case 1: {
|
||||
mov(VTMP1.V16B(), Op->DestIdx, GetSrc(Op->Header.Args[1].ID()).V16B(), 0);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
mov(VTMP1.V8H(), Op->DestIdx, GetSrc(Op->Header.Args[1].ID()).V8H(), 0);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
mov(VTMP1.V4S(), Op->DestIdx, GetSrc(Op->Header.Args[1].ID()).V4S(), 0);
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
mov(VTMP1.V2D(), Op->DestIdx, GetSrc(Op->Header.Args[1].ID()).V2D(), 0);
|
||||
break;
|
||||
}
|
||||
default: LogMan::Msg::A("Unknown Element Size: %d", Op->ElementSize); break;
|
||||
}
|
||||
mov(GetDst(Node), VTMP1);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VNOT: {
|
||||
auto Op = IROp->C<IR::IROp_VNot>();
|
||||
mvn(GetDst(Node).V16B(), GetSrc(Op->Header.Args[0].ID()).V16B());
|
||||
|
||||
@@ -2000,6 +2000,70 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
|
||||
movapd(GetDst(Node), xmm15);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VINSSCALARELEMENT: {
|
||||
auto Op = IROp->C<IR::IROp_VInsScalarElement>();
|
||||
movapd(xmm15, GetSrc(Op->Header.Args[0].ID()));
|
||||
|
||||
// Dst_d[Op->DestIdx] = Src2_d[Op->SrcIdx];
|
||||
|
||||
// pextrq reg64/mem64, xmm, imm
|
||||
// pinsrq xmm, reg64/mem64, imm8
|
||||
switch (Op->ElementSize) {
|
||||
case 1: {
|
||||
pextrb(eax, GetSrc(Op->Header.Args[1].ID()), 0);
|
||||
pinsrb(xmm15, eax, Op->DestIdx);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
pextrw(eax, GetSrc(Op->Header.Args[1].ID()), 0);
|
||||
pinsrw(xmm15, eax, Op->DestIdx);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
pextrd(eax, GetSrc(Op->Header.Args[1].ID()), 0);
|
||||
pinsrd(xmm15, eax, Op->DestIdx);
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
pextrq(rax, GetSrc(Op->Header.Args[1].ID()), 0);
|
||||
pinsrq(xmm15, rax, Op->DestIdx);
|
||||
break;
|
||||
}
|
||||
default: LogMan::Msg::A("Unknown Element Size: %d", Op->ElementSize); break;
|
||||
}
|
||||
|
||||
movapd(GetDst(Node), xmm15);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VEXTRACTELEMENT: {
|
||||
auto Op = IROp->C<IR::IROp_VExtractElement>();
|
||||
|
||||
switch (Op->ElementSize) {
|
||||
case 1: {
|
||||
pextrb(eax, GetSrc(Op->Header.Args[1].ID()), Op->Index);
|
||||
pinsrb(GetDst(Node), eax, 0);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
pextrw(eax, GetSrc(Op->Header.Args[1].ID()), Op->Index);
|
||||
pinsrw(GetDst(Node), eax, 0);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
pextrd(eax, GetSrc(Op->Header.Args[1].ID()), Op->Index);
|
||||
pinsrd(GetDst(Node), eax, 0);
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
pextrq(rax, GetSrc(Op->Header.Args[1].ID()), Op->Index);
|
||||
pinsrq(GetDst(Node), rax, 0);
|
||||
break;
|
||||
}
|
||||
default: LogMan::Msg::A("Unknown Element Size: %d", Op->ElementSize); break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case IR::OP_VADD: {
|
||||
auto Op = IROp->C<IR::IROp_VAdd>();
|
||||
switch (Op->ElementSize) {
|
||||
|
||||
@@ -1818,6 +1818,17 @@ void LLVMJITCore::HandleIR(FEXCore::IR::IRListView<true> const *IR, IR::NodeWrap
|
||||
SetDest(*WrapperOp, Result);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VEXTRACTELEMENT: {
|
||||
auto Op = IROp->C<IR::IROp_VExtractElement>();
|
||||
auto Src = GetSrc(Op->Header.Args[0]);
|
||||
|
||||
// Cast to the type we want
|
||||
Src = CastVectorToType(Src, true, Op->RegisterSize, Op->ElementSize);
|
||||
|
||||
auto Result = JITState.IRBuilder->CreateExtractElement(Src, JITState.IRBuilder->getInt32(Op->Index));
|
||||
SetDest(*WrapperOp, Result);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VINSGPR: {
|
||||
auto Op = IROp->C<IR::IROp_VInsGPR>();
|
||||
auto Src1 = GetSrc(Op->Header.Args[0]);
|
||||
@@ -2511,6 +2522,20 @@ void LLVMJITCore::HandleIR(FEXCore::IR::IRListView<true> const *IR, IR::NodeWrap
|
||||
SetDest(*WrapperOp, Result);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VINSSCALARELEMENT: {
|
||||
auto Op = IROp->C<IR::IROp_VInsScalarElement>();
|
||||
auto Src1 = GetSrc(Op->Header.Args[0]);
|
||||
auto Src2 = GetSrc(Op->Header.Args[1]);
|
||||
|
||||
// Cast to the type we want
|
||||
Src1 = CastVectorToType(Src1, true, Op->RegisterSize, Op->ElementSize);
|
||||
Src2 = CastScalarToType(Src2, true, Op->RegisterSize, Op->ElementSize);
|
||||
|
||||
// Extract our source index
|
||||
auto Result = JITState.IRBuilder->CreateInsertElement(Src1, Src2, JITState.IRBuilder->getInt32(Op->DestIdx));
|
||||
SetDest(*WrapperOp, Result);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VECTOR_UTOF: {
|
||||
auto Op = IROp->C<IR::IROp_Vector_UToF>();
|
||||
auto Src = GetSrc(Op->Header.Args[0]);
|
||||
|
||||
Reference in new issue
Block a user