From 842e22915caa367e20f8ee6f8d66c0da3cabc78c Mon Sep 17 00:00:00 2001 From: LC Date: Mon, 13 Jul 2026 11:46:56 -0400 Subject: [PATCH] VectorOps: Simplify SVE 256-bit VOrn with BSL2N Lets us shave off an instruction and also avoid using a temporary register in some cases. We can also tweak our worst case that requires a predicate to eliminate the temporary as well. We can also expand our cmpps cases, so that we can reflect the BSL2N usages in instcountci. --- .../Source/Interface/Core/JIT/VectorOps.cpp | 13 +- unittests/InstructionCountCI/VEX_map1.json | 325 ++++++++++++++++++ 2 files changed, 335 insertions(+), 3 deletions(-) diff --git a/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp b/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp index c491e3445..7df9dd630 100644 --- a/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp @@ -1139,9 +1139,16 @@ DEF_OP(VOrn) { const auto Vector2 = GetVReg(Op->Vector2); if (HostSupportsSVE256 && Is256Bit) { - const auto Pred = PRED_TMP_32B.Merging(); - not_(ARMEmitter::SubRegSize::i8Bit, VTMP1.Z(), Pred, Vector2.Z()); - orr(Dst.Z(), Vector1.Z(), VTMP1.Z()); + if (Dst == Vector1) { + bsl2n(Dst.Z(), Dst.Z(), Vector2.Z(), Dst.Z()); + } else if (Dst == Vector2) { + const auto Pred = PRED_TMP_32B.Merging(); + not_(ARMEmitter::SubRegSize::i8Bit, Dst.Z(), Pred, Dst.Z()); + orr(Dst.Z(), Vector1.Z(), Dst.Z()); + } else { + movprfx(Dst.Z(), Vector1.Z()); + bsl2n(Dst.Z(), Dst.Z(), Vector2.Z(), Vector1.Z()); + } } else if (Is128Bit) { orn(Dst.Q(), Vector1.Q(), Vector2.Q()); } else { diff --git a/unittests/InstructionCountCI/VEX_map1.json b/unittests/InstructionCountCI/VEX_map1.json index fe85757a3..22be82446 100644 --- a/unittests/InstructionCountCI/VEX_map1.json +++ b/unittests/InstructionCountCI/VEX_map1.json @@ -1719,6 +1719,331 @@ "orr z16.s, p0/m, z16.s, z0.s" ] }, + "vcmpps ymm0, ymm1, ymm2, 0x08": { + "ExpectedInstructionCount": 15, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmeq p0.s, p7/z, z17.s, z17.s", + "not z0.s, p0/m, z17.s", + "movprfx z2.s, p0/z, z17.s", + "orr z2.s, p0/m, z2.s, z0.s", + "fcmeq p0.s, p7/z, z18.s, z18.s", + "not z0.s, p0/m, z18.s", + "movprfx z3.s, p0/z, z18.s", + "orr z3.s, p0/m, z3.s, z0.s", + "and z2.d, z2.d, z3.d", + "fcmeq p0.s, p7/z, z17.s, z18.s", + "not z0.s, p0/m, z17.s", + "movprfx z3.s, p0/z, z17.s", + "orr z3.s, p0/m, z3.s, z0.s", + "movprfx z16, z3", + "bsl2n z16.d, z16.d, z2.d, z3.d" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x09": { + "ExpectedInstructionCount": 5, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmge p0.s, p7/z, z17.s, z18.s", + "not z0.s, p0/m, z17.s", + "movprfx z2.s, p0/z, z17.s", + "orr z2.s, p0/m, z2.s, z0.s", + "not z16.b, p7/m, z2.b" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x0A": { + "ExpectedInstructionCount": 5, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmgt p0.s, p7/z, z17.s, z18.s", + "not z0.s, p0/m, z17.s", + "movprfx z2.s, p0/z, z17.s", + "orr z2.s, p0/m, z2.s, z0.s", + "not z16.b, p7/m, z2.b" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x0B": { + "ExpectedInstructionCount": 1, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "movi v16.2d, #0x0" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x0C": { + "ExpectedInstructionCount": 14, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmeq p0.s, p7/z, z17.s, z17.s", + "not z0.s, p0/m, z17.s", + "movprfx z2.s, p0/z, z17.s", + "orr z2.s, p0/m, z2.s, z0.s", + "fcmeq p0.s, p7/z, z18.s, z18.s", + "not z0.s, p0/m, z18.s", + "movprfx z3.s, p0/z, z18.s", + "orr z3.s, p0/m, z3.s, z0.s", + "fcmeq p0.s, p7/z, z17.s, z18.s", + "not z0.s, p0/m, z17.s", + "movprfx z4.s, p0/z, z17.s", + "orr z4.s, p0/m, z4.s, z0.s", + "bic z2.d, z2.d, z4.d", + "and z16.d, z2.d, z3.d" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x0D": { + "ExpectedInstructionCount": 4, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmge p0.s, p7/z, z17.s, z18.s", + "not z0.s, p0/m, z17.s", + "movprfx z16.s, p0/z, z17.s", + "orr z16.s, p0/m, z16.s, z0.s" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x0E": { + "ExpectedInstructionCount": 4, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmgt p0.s, p7/z, z17.s, z18.s", + "not z0.s, p0/m, z17.s", + "movprfx z16.s, p0/z, z17.s", + "orr z16.s, p0/m, z16.s, z0.s" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x0F": { + "ExpectedInstructionCount": 1, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "mov z16.b, #-1" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x10": { + "ExpectedInstructionCount": 4, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmeq p0.s, p7/z, z17.s, z18.s", + "not z0.s, p0/m, z17.s", + "movprfx z16.s, p0/z, z17.s", + "orr z16.s, p0/m, z16.s, z0.s" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x11": { + "ExpectedInstructionCount": 4, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmgt p0.s, p7/z, z18.s, z17.s", + "not z0.s, p0/m, z18.s", + "movprfx z16.s, p0/z, z18.s", + "orr z16.s, p0/m, z16.s, z0.s" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x12": { + "ExpectedInstructionCount": 4, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmge p0.s, p7/z, z18.s, z17.s", + "not z0.s, p0/m, z18.s", + "movprfx z16.s, p0/z, z18.s", + "orr z16.s, p0/m, z16.s, z0.s" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x13": { + "ExpectedInstructionCount": 4, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmuo p0.s, p7/z, z17.s, z18.s", + "not z0.s, p0/m, z17.s", + "movprfx z16.s, p0/z, z17.s", + "orr z16.s, p0/m, z16.s, z0.s" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x14": { + "ExpectedInstructionCount": 4, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmne p0.s, p7/z, z17.s, z18.s", + "not z0.s, p0/m, z17.s", + "movprfx z16.s, p0/z, z17.s", + "orr z16.s, p0/m, z16.s, z0.s" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x15": { + "ExpectedInstructionCount": 5, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmgt p0.s, p7/z, z18.s, z17.s", + "not z0.s, p0/m, z18.s", + "movprfx z2.s, p0/z, z18.s", + "orr z2.s, p0/m, z2.s, z0.s", + "not z16.b, p7/m, z2.b" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x16": { + "ExpectedInstructionCount": 5, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmge p0.s, p7/z, z18.s, z17.s", + "not z0.s, p0/m, z18.s", + "movprfx z2.s, p0/z, z18.s", + "orr z2.s, p0/m, z2.s, z0.s", + "not z16.b, p7/m, z2.b" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x17": { + "ExpectedInstructionCount": 5, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmuo p0.s, p7/z, z17.s, z18.s", + "not p0.b, p7/z, p0.b", + "not z0.s, p0/m, z17.s", + "movprfx z16.s, p0/z, z17.s", + "orr z16.s, p0/m, z16.s, z0.s" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x18": { + "ExpectedInstructionCount": 15, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmeq p0.s, p7/z, z17.s, z17.s", + "not z0.s, p0/m, z17.s", + "movprfx z2.s, p0/z, z17.s", + "orr z2.s, p0/m, z2.s, z0.s", + "fcmeq p0.s, p7/z, z18.s, z18.s", + "not z0.s, p0/m, z18.s", + "movprfx z3.s, p0/z, z18.s", + "orr z3.s, p0/m, z3.s, z0.s", + "and z2.d, z2.d, z3.d", + "fcmeq p0.s, p7/z, z17.s, z18.s", + "not z0.s, p0/m, z17.s", + "movprfx z3.s, p0/z, z17.s", + "orr z3.s, p0/m, z3.s, z0.s", + "movprfx z16, z3", + "bsl2n z16.d, z16.d, z2.d, z3.d" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x19": { + "ExpectedInstructionCount": 5, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmge p0.s, p7/z, z17.s, z18.s", + "not z0.s, p0/m, z17.s", + "movprfx z2.s, p0/z, z17.s", + "orr z2.s, p0/m, z2.s, z0.s", + "not z16.b, p7/m, z2.b" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x1A": { + "ExpectedInstructionCount": 5, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmgt p0.s, p7/z, z17.s, z18.s", + "not z0.s, p0/m, z17.s", + "movprfx z2.s, p0/z, z17.s", + "orr z2.s, p0/m, z2.s, z0.s", + "not z16.b, p7/m, z2.b" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x1B": { + "ExpectedInstructionCount": 1, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "movi v16.2d, #0x0" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x1C": { + "ExpectedInstructionCount": 14, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmeq p0.s, p7/z, z17.s, z17.s", + "not z0.s, p0/m, z17.s", + "movprfx z2.s, p0/z, z17.s", + "orr z2.s, p0/m, z2.s, z0.s", + "fcmeq p0.s, p7/z, z18.s, z18.s", + "not z0.s, p0/m, z18.s", + "movprfx z3.s, p0/z, z18.s", + "orr z3.s, p0/m, z3.s, z0.s", + "fcmeq p0.s, p7/z, z17.s, z18.s", + "not z0.s, p0/m, z17.s", + "movprfx z4.s, p0/z, z17.s", + "orr z4.s, p0/m, z4.s, z0.s", + "bic z2.d, z2.d, z4.d", + "and z16.d, z2.d, z3.d" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x1D": { + "ExpectedInstructionCount": 4, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmge p0.s, p7/z, z17.s, z18.s", + "not z0.s, p0/m, z17.s", + "movprfx z16.s, p0/z, z17.s", + "orr z16.s, p0/m, z16.s, z0.s" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x1E": { + "ExpectedInstructionCount": 4, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "fcmgt p0.s, p7/z, z17.s, z18.s", + "not z0.s, p0/m, z17.s", + "movprfx z16.s, p0/z, z17.s", + "orr z16.s, p0/m, z16.s, z0.s" + ] + }, + "vcmpps ymm0, ymm1, ymm2, 0x1F": { + "ExpectedInstructionCount": 1, + "Comment": [ + "Map 1 0b00 0xC2 256-bit" + ], + "ExpectedArm64ASM": [ + "mov z16.b, #-1" + ] + }, "vcmppd xmm0, xmm1, xmm2, 0x00": { "ExpectedInstructionCount": 1, "Comment": [