From 5eea68d6c60ab69023196ade3e56e880bc37d438 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Fri, 10 Nov 2023 19:28:35 -0400 Subject: [PATCH] IR: Support predicated Neg i.e. cneg. will be used for x87 hell op Signed-off-by: Alyssa Rosenzweig --- .../Interface/Core/JIT/Arm64/ALUOps.cpp | 65 ++++++++++--------- FEXCore/Source/Interface/IR/IR.json | 8 ++- 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp index d9ce8dd61..76a610222 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp @@ -193,6 +193,36 @@ DEF_OP(RmifNZCV) { rmif(GetReg(Op->Src.ID()).X(), Op->Rotate, Op->Mask); } +ARMEmitter::Condition MapSelectCC(IR::CondClassType Cond) { + switch (Cond.Val) { + case FEXCore::IR::COND_ANDZ: + case FEXCore::IR::COND_EQ: return ARMEmitter::Condition::CC_EQ; + case FEXCore::IR::COND_ANDNZ: + case FEXCore::IR::COND_NEQ: return ARMEmitter::Condition::CC_NE; + case FEXCore::IR::COND_SGE: return ARMEmitter::Condition::CC_GE; + case FEXCore::IR::COND_SLT: return ARMEmitter::Condition::CC_LT; + case FEXCore::IR::COND_SGT: return ARMEmitter::Condition::CC_GT; + case FEXCore::IR::COND_SLE: return ARMEmitter::Condition::CC_LE; + case FEXCore::IR::COND_UGE: return ARMEmitter::Condition::CC_CS; + case FEXCore::IR::COND_ULT: return ARMEmitter::Condition::CC_CC; + case FEXCore::IR::COND_UGT: return ARMEmitter::Condition::CC_HI; + case FEXCore::IR::COND_ULE: return ARMEmitter::Condition::CC_LS; + case FEXCore::IR::COND_FLU: return ARMEmitter::Condition::CC_LT; + case FEXCore::IR::COND_FGE: return ARMEmitter::Condition::CC_GE; + case FEXCore::IR::COND_FLEU:return ARMEmitter::Condition::CC_LE; + case FEXCore::IR::COND_FGT: return ARMEmitter::Condition::CC_GT; + case FEXCore::IR::COND_FU: return ARMEmitter::Condition::CC_VS; + case FEXCore::IR::COND_FNU: return ARMEmitter::Condition::CC_VC; + case FEXCore::IR::COND_VS: + case FEXCore::IR::COND_VC: + case FEXCore::IR::COND_MI: return ARMEmitter::Condition::CC_MI; + case FEXCore::IR::COND_PL: return ARMEmitter::Condition::CC_PL; + default: + LOGMAN_MSG_A_FMT("Unsupported compare type"); + return ARMEmitter::Condition::CC_NV; + } +} + DEF_OP(Neg) { auto Op = IROp->C(); const uint8_t OpSize = IROp->Size; @@ -200,7 +230,10 @@ DEF_OP(Neg) { LOGMAN_THROW_AA_FMT(OpSize == 4 || OpSize == 8, "Unsupported {} size: {}", __func__, OpSize); const auto EmitSize = OpSize == 8 ? ARMEmitter::Size::i64Bit : ARMEmitter::Size::i32Bit; - neg(EmitSize, GetReg(Node), GetReg(Op->Src.ID())); + if (Op->Cond == FEXCore::IR::COND_AL) + neg(EmitSize, GetReg(Node), GetReg(Op->Src.ID())); + else + cneg(EmitSize, GetReg(Node), GetReg(Op->Src.ID()), MapSelectCC(Op->Cond)); } DEF_OP(Abs) { @@ -1270,36 +1303,6 @@ DEF_OP(Sbfe) { sbfx(EmitSize, Dst, Src, Op->lsb, Op->Width); } -ARMEmitter::Condition MapSelectCC(IR::CondClassType Cond) { - switch (Cond.Val) { - case FEXCore::IR::COND_ANDZ: - case FEXCore::IR::COND_EQ: return ARMEmitter::Condition::CC_EQ; - case FEXCore::IR::COND_ANDNZ: - case FEXCore::IR::COND_NEQ: return ARMEmitter::Condition::CC_NE; - case FEXCore::IR::COND_SGE: return ARMEmitter::Condition::CC_GE; - case FEXCore::IR::COND_SLT: return ARMEmitter::Condition::CC_LT; - case FEXCore::IR::COND_SGT: return ARMEmitter::Condition::CC_GT; - case FEXCore::IR::COND_SLE: return ARMEmitter::Condition::CC_LE; - case FEXCore::IR::COND_UGE: return ARMEmitter::Condition::CC_CS; - case FEXCore::IR::COND_ULT: return ARMEmitter::Condition::CC_CC; - case FEXCore::IR::COND_UGT: return ARMEmitter::Condition::CC_HI; - case FEXCore::IR::COND_ULE: return ARMEmitter::Condition::CC_LS; - case FEXCore::IR::COND_FLU: return ARMEmitter::Condition::CC_LT; - case FEXCore::IR::COND_FGE: return ARMEmitter::Condition::CC_GE; - case FEXCore::IR::COND_FLEU:return ARMEmitter::Condition::CC_LE; - case FEXCore::IR::COND_FGT: return ARMEmitter::Condition::CC_GT; - case FEXCore::IR::COND_FU: return ARMEmitter::Condition::CC_VS; - case FEXCore::IR::COND_FNU: return ARMEmitter::Condition::CC_VC; - case FEXCore::IR::COND_VS: - case FEXCore::IR::COND_VC: - case FEXCore::IR::COND_MI: return ARMEmitter::Condition::CC_MI; - case FEXCore::IR::COND_PL: return ARMEmitter::Condition::CC_PL; - default: - LOGMAN_MSG_A_FMT("Unsupported compare type"); - return ARMEmitter::Condition::CC_NV; - } -} - DEF_OP(Select) { auto Op = IROp->C(); const uint8_t OpSize = IROp->Size; diff --git a/FEXCore/Source/Interface/IR/IR.json b/FEXCore/Source/Interface/IR/IR.json index fbc25f690..175d38de9 100644 --- a/FEXCore/Source/Interface/IR/IR.json +++ b/FEXCore/Source/Interface/IR/IR.json @@ -77,6 +77,8 @@ "constexpr uint8_t COND_FU = 20 /* float unordred */", "constexpr uint8_t COND_FNU = 21 /* float not unordred */", + "constexpr uint8_t COND_AL = 32 /* always */", + "constexpr FEXCore::IR::RegisterClassType GPRClass {0}", "constexpr FEXCore::IR::RegisterClassType GPRFixedClass {1}", "constexpr FEXCore::IR::RegisterClassType FPRClass {2}", @@ -865,9 +867,9 @@ "DestSize": "8" }, - "GPR = Neg OpSize:#Size, GPR:$Src": { - "Desc": ["Integer negation", - "Dest = -Src", + "GPR = Neg OpSize:#Size, GPR:$Src, CondClass:$Cond{{COND_AL}}": { + "Desc": ["Integer negation, with optional predication", + "Dest = Cond ? -Src : Src", "Will truncate to 64 or 32bits" ], "DestSize": "Size",