diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/ConversionOps.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/ConversionOps.cpp index aac5053bc..db433a798 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/ConversionOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/ConversionOps.cpp @@ -355,6 +355,24 @@ DEF_OP(Vector_FToF) { } } +DEF_OP(Vector_FToF2) { + const auto Op = IROp->C(); + + const auto ElementSize = Op->Header.ElementSize; + const auto SubEmitSize = ConvertSubRegSize248(IROp); + + const auto Dst = GetVReg(Node); + const auto Vector = GetVReg(Op->Vector.ID()); + + if (ElementSize > Op->SrcElementSize) { + LOGMAN_THROW_AA_FMT(Op->SrcElementSize == (ElementSize >> 1), "IR invariant"); + fcvtl2(SubEmitSize, Dst.D(), Vector.D()); + } else { + LOGMAN_THROW_AA_FMT(Op->SrcElementSize == (ElementSize << 1), "IR invariant"); + fcvtn2(SubEmitSize, Dst.D(), Vector.D()); + } +} + DEF_OP(Vector_FToI) { const auto Op = IROp->C(); const auto OpSize = IROp->Size; diff --git a/FEXCore/Source/Interface/IR/IR.json b/FEXCore/Source/Interface/IR/IR.json index 03904018e..70586ecbc 100644 --- a/FEXCore/Source/Interface/IR/IR.json +++ b/FEXCore/Source/Interface/IR/IR.json @@ -2314,6 +2314,18 @@ "DestSize": "RegisterSize", "NumElements": "RegisterSize / DestElementSize" }, + + "FPR = Vector_FToF2 u8:#RegisterSize, u8:#DestElementSize, FPR:$Vector, u8:$SrcElementSize": { + "Desc": [ + "Vector op: Converts float from source element size to destination size (fp32<->fp64)", + "Selecting from the high half of the register." + ], + "DestSize": "RegisterSize", + "NumElements": "RegisterSize / DestElementSize", + "EmitValidation": [ + "RegisterSize != FEXCore::IR::OpSize::i256Bit && \"What does 256-bit mean in this context?\"" + ] + }, "FPR = Vector_FToI u8:#RegisterSize, u8:#ElementSize, FPR:$Vector, RoundType:$Round": { "Desc": ["Vector op: Rounds float to integral", "Rounding mode determined by argument"