mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-14 08:00:50 +02:00
OpcodeDispatcher: eliminate xblock live for rcl
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
1 parent
1f3843ccad
commit
7de29749be
1 file changed
+21
-13
@@ -2603,19 +2603,19 @@ void OpDispatchBuilder::RCLOp(OpcodeArgs) {
|
||||
CalculateDeferredFlags();
|
||||
|
||||
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags, {.AllowUpperGarbage = true});
|
||||
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.AllowUpperGarbage = true});
|
||||
const auto OpSize = OpSizeFromSrc(Op);
|
||||
|
||||
// Res = Src << Shift
|
||||
OrderedNode *Res = _Lshl(OpSize, Dest, Src);
|
||||
auto CF = GetRFLAG(FEXCore::X86State::RFLAG_CF_RAW_LOC);
|
||||
|
||||
uint64_t Const;
|
||||
if (IsValueConstant(WrapNode(Src), &Const)) {
|
||||
Const &= Mask;
|
||||
if (!Const)
|
||||
return;
|
||||
|
||||
// Res = Src << Shift
|
||||
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.AllowUpperGarbage = true});
|
||||
OrderedNode *Res = _Lshl(OpSize, Dest, Src);
|
||||
auto CF = GetRFLAG(FEXCore::X86State::RFLAG_CF_RAW_LOC);
|
||||
|
||||
InvalidateDeferredFlags();
|
||||
|
||||
// Res |= (Src << (Size - Shift + 1));
|
||||
@@ -2640,20 +2640,28 @@ void OpDispatchBuilder::RCLOp(OpcodeArgs) {
|
||||
}
|
||||
|
||||
OrderedNode *SrcMasked = _And(OpSize, Src, _Constant(Size, Mask));
|
||||
CalculateFlags_ShiftVariable(SrcMasked, [this, CF, Op, Size, OpSize, SrcMasked, Dest, &Res](){
|
||||
// Res |= (SrcMasked >> (Size - Shift + 1)), expressed as
|
||||
// Res | ((SrcMasked >> (-Shift)) >> 1), since Size - Shift = -Shift mod
|
||||
// Size.
|
||||
auto NegSrc = _Neg(OpSize, SrcMasked);
|
||||
Calculate_ShiftVariable(SrcMasked, [this, Op, Size, OpSize](){
|
||||
// Rematerialized to avoid crossblock liveness
|
||||
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags, {.AllowUpperGarbage = true});
|
||||
|
||||
// Res = Src << Shift
|
||||
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.AllowUpperGarbage = true});
|
||||
OrderedNode *Res = _Lshl(OpSize, Dest, Src);
|
||||
auto CF = GetRFLAG(FEXCore::X86State::RFLAG_CF_RAW_LOC);
|
||||
|
||||
// Res |= (Dest >> (Size - Shift + 1)), expressed as
|
||||
// Res | ((Dest >> (-Shift)) >> 1), since Size - Shift = -Shift mod
|
||||
// Size. The shift aborbs the masking.
|
||||
auto NegSrc = _Neg(OpSize, Src);
|
||||
Res = _Orlshr(OpSize, Res, _Lshr(OpSize, Dest, NegSrc), 1);
|
||||
|
||||
// Our new CF will be bit (Shift - 1) of the source
|
||||
auto NewCF = _Lshr(OpSize, Dest, NegSrc);
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_CF_RAW_LOC>(NewCF, 0, true);
|
||||
|
||||
// Since Shift != 0 we can inject the CF
|
||||
OrderedNode *CFShl = _Sub(OpSize, SrcMasked, _Constant(Size, 1));
|
||||
auto TmpCF = _Lshl(OpSize::i64Bit, CF, CFShl);
|
||||
// Since Shift != 0 we can inject the CF. Shift absorbs the masking.
|
||||
OrderedNode *CFShl = _Sub(OpSize, Src, _Constant(Size, 1));
|
||||
auto TmpCF = _Lshl(OpSize, CF, CFShl);
|
||||
Res = _Or(OpSize, Res, TmpCF);
|
||||
|
||||
// OF is the top two MSBs XOR'd together
|
||||
|
||||
Reference in new issue
Block a user