Skip to content

Commit

Permalink
more uses of migration helper
Browse files Browse the repository at this point in the history
  • Loading branch information
pmatos committed Jul 17, 2024
1 parent ac8e645 commit 3b36e0b
Showing 1 changed file with 27 additions and 35 deletions.
62 changes: 27 additions & 35 deletions FEXCore/Source/Interface/IR/Passes/x87StackOptimizationPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,7 @@ void X87StackOptimization::HandleUnop(IROps Op64, bool VFOp64, IROps Op80) {
void X87StackOptimization::HandleBinopValue(IROps Op64, bool VFOp64, IROps Op80, uint8_t DestStackOffset, bool MarkDestValid,
uint8_t StackOffset, Ref ValueNode, bool Reverse) {
LOGMAN_THROW_A_FMT(!Reverse || VFOp64, "There are no reverse operations using non VFOp64 ops");
const auto& [Valid, StackMember] = StackData.top(StackOffset);
MigrateToSlowPathIf(Valid != StackSlot::VALID);
auto StackMember = MigrateToSlowPath_IfInvalid(StackOffset);

if (SlowPath) {
// Load the current value from the x87 fpu stack
Expand Down Expand Up @@ -421,36 +420,35 @@ void X87StackOptimization::HandleBinopValue(IROps Op64, bool VFOp64, IROps Op80,
Ref Node = {};
if (ReducedPrecisionMode) {
if (Reverse) {
DeriveOp(Node, Op64, IREmit->_VFAdd(8, 8, ValueNode, StackMember.StackDataNode));
DeriveOp(Node, Op64, IREmit->_VFAdd(8, 8, ValueNode, StackMember->StackDataNode));
} else {
DeriveOp(Node, Op64, IREmit->_VFAdd(8, 8, StackMember.StackDataNode, ValueNode));
DeriveOp(Node, Op64, IREmit->_VFAdd(8, 8, StackMember->StackDataNode, ValueNode));
}
} else {
if (Reverse) {
DeriveOp(Node, Op80, IREmit->_F80Add(ValueNode, StackMember.StackDataNode));
DeriveOp(Node, Op80, IREmit->_F80Add(ValueNode, StackMember->StackDataNode));
} else {
DeriveOp(Node, Op80, IREmit->_F80Add(StackMember.StackDataNode, ValueNode));
DeriveOp(Node, Op80, IREmit->_F80Add(StackMember->StackDataNode, ValueNode));
}
}
// Store it in the stack
StackData.setTop(StackMemberInfo {.SourceDataSize = StackMember.SourceDataSize,
StackData.setTop(StackMemberInfo {.SourceDataSize = StackMember->SourceDataSize,
.SourceDataNode = nullptr,
.StackDataNode = Node,
.InterpretAsFloat = StackMember.InterpretAsFloat},
.InterpretAsFloat = StackMember->InterpretAsFloat},
DestStackOffset);
}
}

void X87StackOptimization::HandleBinopStack(IROps Op64, bool VFOp64, IROps Op80, uint8_t DestStackOffset, uint8_t StackOffset1,
uint8_t StackOffset2, bool Reverse) {
const auto& [Valid, StackMember] = StackData.top(StackOffset2);
MigrateToSlowPathIf(Valid != StackSlot::VALID);
auto StackMember = MigrateToSlowPath_IfInvalid(StackOffset2);

if (SlowPath) {
Ref StackNode = LoadStackValueAtOffset_Slow(StackOffset2);
HandleBinopValue(Op64, VFOp64, Op80, DestStackOffset, StackOffset2 != DestStackOffset, StackOffset1, StackNode, Reverse);
} else {
HandleBinopValue(Op64, VFOp64, Op80, DestStackOffset, StackOffset2 != DestStackOffset, StackOffset1, StackMember.StackDataNode, Reverse);
HandleBinopValue(Op64, VFOp64, Op80, DestStackOffset, StackOffset2 != DestStackOffset, StackOffset1, StackMember->StackDataNode, Reverse);
}
}

Expand Down Expand Up @@ -743,27 +741,25 @@ void X87StackOptimization::Run(IREmitter* Emit) {
// Miscellaneous Ops
// These are handled on a case-by-case basis
case OP_F80SINCOSSTACK: {
const auto& [Valid, StackMember] = StackData.top();

MigrateToSlowPathIf(Valid != StackSlot::VALID);
auto StackMember = MigrateToSlowPath_IfInvalid();

// Grab st0
Ref st0 {};
Ref St0 {};
if (SlowPath) {
st0 = LoadStackValueAtTop_Slow();
St0 = LoadStackValueAtTop_Slow();
} else {
st0 = StackMember.StackDataNode;
St0 = StackMember->StackDataNode;
}

// Calc values
Ref SinValue {};
Ref CosValue {};
if (ReducedPrecisionMode) {
SinValue = IREmit->_F64SIN(st0);
CosValue = IREmit->_F64COS(st0);
SinValue = IREmit->_F64SIN(St0);
CosValue = IREmit->_F64COS(St0);
} else {
SinValue = IREmit->_F80SIN(st0);
CosValue = IREmit->_F80COS(st0);
SinValue = IREmit->_F80SIN(St0);
CosValue = IREmit->_F80COS(St0);
}

// Push values
Expand All @@ -773,9 +769,9 @@ void X87StackOptimization::Run(IREmitter* Emit) {
StoreStackValueAtTop_Slow(CosValue, true);
} else {
StackData.setTop(StackMemberInfo {
.SourceDataSize = StackMember.SourceDataSize, .SourceDataNode = nullptr, .StackDataNode = SinValue, .InterpretAsFloat = true});
.SourceDataSize = StackMember->SourceDataSize, .SourceDataNode = nullptr, .StackDataNode = SinValue, .InterpretAsFloat = true});
StackData.push(StackMemberInfo {
.SourceDataSize = StackMember.SourceDataSize, .SourceDataNode = nullptr, .StackDataNode = CosValue, .InterpretAsFloat = true});
.SourceDataSize = StackMember->SourceDataSize, .SourceDataNode = nullptr, .StackDataNode = CosValue, .InterpretAsFloat = true});
}
IREmit->Remove(CodeNode);
break;
Expand Down Expand Up @@ -841,15 +837,14 @@ void X87StackOptimization::Run(IREmitter* Emit) {
case OP_COPYPUSHSTACK: {
const auto* Op = IROp->C<IROp_CopyPushStack>();
auto Offset = Op->StackLocation;
const auto& [Valid, Value] = StackData.top(Offset);
MigrateToSlowPathIf(Valid != StackSlot::VALID);
auto StackMember = MigrateToSlowPath_IfInvalid(Offset);

if (SlowPath) {
Ref st0 = LoadStackValueAtOffset_Slow(Offset);
Ref St0 = LoadStackValueAtOffset_Slow(Offset);
UpdateTopForPush_Slow();
StoreStackValueAtTop_Slow(st0);
StoreStackValueAtTop_Slow(St0);
} else {
StackData.push(StackMemberInfo(Value));
StackData.push(*StackMember);
}
IREmit->Remove(CodeNode);
break;
Expand All @@ -858,14 +853,13 @@ void X87StackOptimization::Run(IREmitter* Emit) {
case OP_READSTACKVALUE: {
const auto* Op = IROp->C<IROp_ReadStackValue>();
auto Offset = Op->StackLocation;
const auto& [Valid, Value] = StackData.top(Offset);
MigrateToSlowPathIf(Valid != StackSlot::VALID);
auto StackMember = MigrateToSlowPath_IfInvalid(Offset);

Ref NewValue {};
if (SlowPath) {
NewValue = LoadStackValueAtOffset_Slow(Offset);
} else {
NewValue = StackData.top(Offset).second.StackDataNode;
NewValue = StackMember->StackDataNode;
}

IREmit->ReplaceUsesWithAfter(CodeNode, NewValue, CodeNode);
Expand All @@ -877,15 +871,13 @@ void X87StackOptimization::Run(IREmitter* Emit) {
// Returns 0 if value is valid and 1 otherwise.
const auto* Op = IROp->C<IROp_StackValidTag>();
auto Offset = Op->StackLocation;
const auto& [Valid, Value] = StackData.top(Offset);
MigrateToSlowPathIf(Valid != StackSlot::VALID);
auto StackMember = MigrateToSlowPath_IfInvalid(Offset);

Ref Tag {};

if (SlowPath) {
Tag = GetX87ValidTag_Slow(Offset);
} else {
Tag = StackData.top(Offset).first == StackSlot::VALID ? GetConstant(1) : GetConstant(0);
Tag = StackMember ? GetConstant(1) : GetConstant(0);
}

IREmit->ReplaceUsesWithAfter(CodeNode, Tag, CodeNode);
Expand Down

0 comments on commit 3b36e0b

Please sign in to comment.