IR: introduce POP operation

rmw on a source, kind of terrible.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
Alyssa Rosenzweig 2024-08-11 09:11:38 -04:00
parent bc0927b7b1
commit 200c6c054f
3 changed files with 58 additions and 0 deletions

View File

@ -6,6 +6,7 @@ $end_info$
*/
#include "FEXCore/Core/X86Enums.h"
#include "FEXCore/Utils/LogManager.h"
#include "Interface/Context/Context.h"
#include "Interface/Core/CPUID.h"
#include "Interface/Core/JIT/Arm64/JITClass.h"
@ -1361,6 +1362,37 @@ DEF_OP(Push) {
}
}
DEF_OP(Pop) {
const auto Op = IROp->C<IR::IROp_Pop>();
const auto Addr = GetReg(Op->InoutAddr.ID());
const auto Dst = GetReg(Op->OutValue.ID());
LOGMAN_THROW_A_FMT(Dst != Addr, "Invalid");
switch (Op->Size) {
case 1: {
ldrb<ARMEmitter::IndexType::POST>(Dst.W(), Addr, Op->Size);
break;
}
case 2: {
ldrh<ARMEmitter::IndexType::POST>(Dst.W(), Addr, Op->Size);
break;
}
case 4: {
ldr<ARMEmitter::IndexType::POST>(Dst.W(), Addr, Op->Size);
break;
}
case 8: {
ldr<ARMEmitter::IndexType::POST>(Dst.X(), Addr, Op->Size);
break;
}
default: {
LOGMAN_MSG_A_FMT("Unhandled {} size: {}", __func__, Op->Size);
break;
}
}
}
DEF_OP(StoreMem) {
const auto Op = IROp->C<IR::IROp_StoreMem>();
const auto OpSize = IROp->Size;

View File

@ -15,6 +15,16 @@ DEF_OP(Copy) {
mov(ARMEmitter::Size::i64Bit, GetReg(Node), GetReg(Op->Source.ID()));
}
DEF_OP(RMWHandle) {
auto Op = IROp->C<IR::IROp_RMWHandle>();
auto Dest = GetReg(Node);
auto Src = GetReg(Op->Value.ID());
if (Dest != Src) {
mov(ARMEmitter::Size::i64Bit, Dest, Src);
}
}
DEF_OP(Swap1) {
auto Op = IROp->C<IR::IROp_Swap1>();
auto A = GetReg(Op->A.ID()), B = GetReg(Op->B.ID());

View File

@ -581,6 +581,22 @@
"HasSideEffects": true,
"DestSize": "Size"
},
"GPR = RMWHandle GPR:$Value": {
"Desc": [
"This is a special move that indicates the result will be poisoned by a non-SSA instruction writing to its result.",
"In effect, it serves to prevent invalid optimizations with non-SSA instructions."
],
"HasSideEffects": true,
"TiedSource": 0
},
"GPR:$Addr, GPR:$Value = Pop u8:$Size, GPR:$Addr": {
"Desc": [
"Pops a value from the address, updating the new pointer after incrementing.",
"The address is incremented by the size via an RMW source/destintaion."
],
"HasSideEffects": true,
"DestSize": "Size"
},
"GPR = MemSet i1:$IsAtomic, u8:$Size, GPR:$Prefix, GPR:$Addr, GPR:$Value, GPR:$Length, GPR:$Direction": {
"Desc": ["Duplicates behaviour of x86 STOS repeat",
"Returns the final address that gets generated without the prefix appended."