diff --git a/Source/Interface/Core/Interpreter/InterpreterCore.cpp b/Source/Interface/Core/Interpreter/InterpreterCore.cpp index ad7a2b0c7..7119c8af8 100644 --- a/Source/Interface/Core/Interpreter/InterpreterCore.cpp +++ b/Source/Interface/Core/Interpreter/InterpreterCore.cpp @@ -268,6 +268,39 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) { memcpy(GDP, GetSrc(Op->Header.Args[0]), 16); break; } + case IR::OP_VCASTFROMGPR: { + auto Op = IROp->C(); + memcpy(GDP, GetSrc(Op->Header.Args[0]), Op->ElementSize); + break; + } + case IR::OP_VEXTRACTTOGPR: { + auto Op = IROp->C(); + 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->Idx * 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->Idx * 8; + if (Op->ElementSize == 8) + SourceMask = ~0ULL; + + uint64_t Src = *GetSrc(Op->Header.Args[0]); + Src >>= Shift; + Src &= SourceMask; + GD = Src; + } + break; + } + case IR::OP_CONSTANT: { auto Op = IROp->C(); GD = Op->Constant; diff --git a/Source/Interface/Core/JIT/x86_64/JIT.cpp b/Source/Interface/Core/JIT/x86_64/JIT.cpp index bcdff60e6..a517c9dd0 100644 --- a/Source/Interface/Core/JIT/x86_64/JIT.cpp +++ b/Source/Interface/Core/JIT/x86_64/JIT.cpp @@ -1261,6 +1261,38 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView const mov (GetDst(Node), rax); break; } + + case IR::OP_VEXTRACTTOGPR: { + auto Op = IROp->C(); + 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(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), Op->Idx); + break; + } + case 2: { + pextrw(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), Op->Idx); + break; + } + case 4: { + pextrd(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), Op->Idx); + break; + } + case 8: { + pextrq(GetDst(Node), GetSrc(Op->Header.Args[0].ID()), Op->Idx); + break; + } + default: LogMan::Msg::A("Unknown Element Size: %d", Op->ElementSize); break; + } + + break; + } + case IR::OP_PRINT: { auto Op = IROp->C(); @@ -1444,6 +1476,27 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView const movaps(GetDst(Node), GetSrc(Op->Header.Args[0].ID())); break; } + case IR::OP_VCASTFROMGPR: { + auto Op = IROp->C(); + switch (Op->ElementSize) { + case 1: + movzx(rax, GetSrc(Op->Header.Args[0].ID())); + vmovq(GetDst(Node), rax); + break; + case 2: + movzx(rax, GetSrc(Op->Header.Args[0].ID())); + vmovq(GetDst(Node), rax); + break; + case 4: + vmovd(GetDst(Node), GetSrc(Op->Header.Args[0].ID()).cvt32()); + break; + case 8: + vmovq(GetDst(Node), GetSrc(Op->Header.Args[0].ID()).cvt64()); + break; + default: LogMan::Msg::A("Unknown castGPR element size: %d", Op->ElementSize); + } + break; + } case IR::OP_VCMPEQ: { auto Op = IROp->C(); LogMan::Throw::A(Op->RegisterSize == 16, "Can't handle register size of: %d", Op->RegisterSize); diff --git a/Source/Interface/Core/LLVMJIT/LLVMCore.cpp b/Source/Interface/Core/LLVMJIT/LLVMCore.cpp index b9e29d22f..25e46a9e5 100644 --- a/Source/Interface/Core/LLVMJIT/LLVMCore.cpp +++ b/Source/Interface/Core/LLVMJIT/LLVMCore.cpp @@ -1433,6 +1433,16 @@ void LLVMJITCore::HandleIR(FEXCore::IR::IRListView const *IR, IR::NodeWrap SetDest(*WrapperOp, BSwap(Src)); break; } + case IR::OP_VCASTFROMGPR: { + auto Op = IROp->C(); + LogMan::Throw::A(OpSize <= 16, "Can't handle a vector of size: %d", OpSize); + auto Src = GetSrc(Op->Header.Args[0]); + + auto Result = JITState.IRBuilder->CreateVectorSplat(Op->RegisterSize / Op->ElementSize, Src); + SetDest(*WrapperOp, Result); + break; + } + case IR::OP_CREATEVECTOR2: { auto Op = IROp->C(); LogMan::Throw::A(OpSize <= 16, "Can't handle a vector of size: %d", OpSize); @@ -1582,7 +1592,32 @@ void LLVMJITCore::HandleIR(FEXCore::IR::IRListView const *IR, IR::NodeWrap SetDest(*WrapperOp, Result); break; } + case IR::OP_VSLI: { + auto Op = IROp->C(); + auto Src = GetSrc(Op->Header.Args[0]); + // Cast to the type we want + Src = CastToOpaqueStructure(Src, Type::getIntNTy(*Con, Src->getType()->getPrimitiveSizeInBits())); + + // Now we will do a lshr -> + auto Result = JITState.IRBuilder->CreateShl(Src, JITState.IRBuilder->getIntN(Src->getType()->getPrimitiveSizeInBits(), Op->ByteShift * 8)); + + SetDest(*WrapperOp, Result); + break; + } + case IR::OP_VSRI: { + auto Op = IROp->C(); + auto Src = GetSrc(Op->Header.Args[0]); + + // Cast to the type we want + Src = CastToOpaqueStructure(Src, Type::getIntNTy(*Con, Src->getType()->getPrimitiveSizeInBits())); + + // Now we will do a lshr -> + auto Result = JITState.IRBuilder->CreateLShr(Src, JITState.IRBuilder->getIntN(Src->getType()->getPrimitiveSizeInBits(), Op->ByteShift * 8)); + + SetDest(*WrapperOp, Result); + break; + } case IR::OP_VCMPEQ: { auto Op = IROp->C(); auto Src1 = GetSrc(Op->Header.Args[0]); diff --git a/Source/Interface/Core/OpcodeDispatcher.h b/Source/Interface/Core/OpcodeDispatcher.h index e13439150..aad112cb5 100644 --- a/Source/Interface/Core/OpcodeDispatcher.h +++ b/Source/Interface/Core/OpcodeDispatcher.h @@ -288,6 +288,13 @@ public: IRPair _VSRI(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, uint8_t ByteShift) { return _VSRI(ssa0, RegisterSize, ElementSize, ByteShift); } + IRPair _VCastFromGPR(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0) { + return _VCastFromGPR(ssa0, RegisterSize, ElementSize); + } + IRPair _VExtractToGPR(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, uint8_t Index) { + return _VExtractToGPR(ssa0, RegisterSize, ElementSize, Index); + } + IRPair _Jump() { return _Jump(InvalidNode); } diff --git a/Source/Interface/IR/IR.json b/Source/Interface/IR/IR.json index 12af5d7ce..5871a3e5b 100644 --- a/Source/Interface/IR/IR.json +++ b/Source/Interface/IR/IR.json @@ -381,6 +381,17 @@ "SSAArgs": "3" }, + "VExtractToGPR": { + "HasDest": true, + "SSAArgs": "1", + "DestSize": "ElementSize", + "Args": [ + "uint8_t", "RegisterSize", + "uint8_t", "ElementSize", + "uint8_t", "Idx" + ] + }, + "Print": { "SSAArgs": "1" }, @@ -588,6 +599,15 @@ "SSAArgs": "1" }, + "VCastFromGPR": { + "HasDest": true, + "SSAArgs": "1", + "Args": [ + "uint8_t", "RegisterSize", + "uint8_t", "ElementSize" + ] + }, + "Last": { "Last": true, "Args": []