From 56ac1c3f4b5ea1f1f5ceb6f6652910bf383fb944 Mon Sep 17 00:00:00 2001 From: "Herman S." <429230+has207@users.noreply.github.com> Date: Sun, 15 Mar 2026 22:06:55 +0900 Subject: [PATCH] [CPU] Replace x86 SSE intrinsics with portable code in Value::Permute --- src/xenia/cpu/hir/value.cc | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/xenia/cpu/hir/value.cc b/src/xenia/cpu/hir/value.cc index c1538e705..1255510a9 100644 --- a/src/xenia/cpu/hir/value.cc +++ b/src/xenia/cpu/hir/value.cc @@ -869,17 +869,20 @@ void Value::Permute(Value* src1, Value* src2, TypeName type) { perm.u8[i * 2] = v * 2; perm.u8[i * 2 + 1] = v * 2 + 1; } - auto lod = [](const vec128_t& v) { - return _mm_loadu_si128((const __m128i*)&v); - }; - auto sto = [](vec128_t& v, __m128i x) { - return _mm_storeu_si128((__m128i*)&v, x); + // Shuffle bytes: for each byte in perm, select from src + // (equivalent to _mm_shuffle_epi8) + auto shuffle_bytes = [](const vec128_t& src, const vec128_t& idx, + vec128_t& out) { + for (int i = 0; i < 16; i++) { + uint8_t sel = idx.u8[i]; + out.u8[i] = (sel & 0x80) ? 0 : src.u8[sel & 0xF]; + } }; - __m128i xmm1 = lod(src1->constant.v128); - __m128i xmm2 = lod(src2->constant.v128); - xmm1 = _mm_shuffle_epi8(xmm1, lod(perm)); - xmm2 = _mm_shuffle_epi8(xmm2, lod(perm)); + vec128_t shuf1, shuf2; + shuffle_bytes(src1->constant.v128, perm, shuf1); + shuffle_bytes(src2->constant.v128, perm, shuf2); + uint8_t mask = 0; for (int i = 0; i < 8; i++) { if (perm_ctrl.i16[i] == 0) { @@ -887,15 +890,15 @@ void Value::Permute(Value* src1, Value* src2, TypeName type) { } } - vec128_t unp_mask = vec128b(0); + // Blend: select from shuf1 where mask bit is set, shuf2 otherwise for (int i = 0; i < 8; i++) { if (mask & (1 << i)) { - unp_mask.u16[i] = 0xFFFF; + constant.v128.u16[i] = shuf1.u16[i]; + } else { + constant.v128.u16[i] = shuf2.u16[i]; } } - sto(constant.v128, _mm_blendv_epi8(xmm1, xmm2, lod(unp_mask))); - } else { assert_unhandled_case(type); }