From 0a164428fa59cc857eb2bedf6cdd1124e278e4b8 Mon Sep 17 00:00:00 2001
From: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Date: Thu, 25 Jan 2024 18:10:04 -0400
Subject: [PATCH] OpcodeDispatcher: eliminate select in RCR

the nzcv clobber I actually came ofr

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
---
 FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp
index d6c5bfc0a..3bf880506 100644
--- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp
+++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp
@@ -2477,15 +2477,13 @@ void OpDispatchBuilder::RCROp(OpcodeArgs) {
 
   OrderedNode *SrcMasked = _And(OpSize, Src, _Constant(Size, Mask));
   CalculateFlags_ShiftVariable(SrcMasked, [this, CF, Op, Size, OpSize, SrcMasked, Dest, &Res](){
-    auto Zero = _Constant(Size, 0);
     auto One = _Constant(Size, 1);
 
     // Res |= (SrcMasked << (Size - Shift + 1));
-    OrderedNode *SrcMaskedShl = _Sub(OpSize, _Constant(Size, Size + 1), SrcMasked);
-    auto TmpHigher = _Lshl(OpSize, Dest, SrcMaskedShl);
-
-    auto CompareResult = _Select(FEXCore::IR::COND_UGT, SrcMasked, One, TmpHigher, Zero);
-    Res = _Or(OpSize, Res, CompareResult);
+    // Expressed as Res | ((SrcMasked << (Size - Shift)) << 1) to get correct
+    // behaviour for Shift without clobbering NZCV.
+    OrderedNode *SrcMaskedShl = _Sub(OpSize, _Constant(Size, Size), SrcMasked);
+    Res = _Orlshl(OpSize, Res, _Lshl(OpSize, Dest, SrcMaskedShl), 1);
 
     // Our new CF will be bit (Shift - 1) of the source. this is hoisted up to
     // avoid the need to copy the source.